diff --git a/indra/llmath/llmatrix3a.inl b/indra/llmath/llmatrix3a.inl index 37819fea3..eaf58319d 100644 --- a/indra/llmath/llmatrix3a.inl +++ b/indra/llmath/llmatrix3a.inl @@ -60,7 +60,7 @@ inline void LLMatrix3a::setTranspose(const LLMatrix3a& src) const LLQuad srcCol1 = src.mColumns[1]; const LLQuad unpacklo = _mm_unpacklo_ps( srcCol0, srcCol1 ); mColumns[0] = _mm_movelh_ps( unpacklo, src.mColumns[2] ); - mColumns[1] = _mm_shuffle_ps( _mm_movehl_ps( srcCol0, unpacklo ), src.mColumns[2], _MM_SHUFFLE(0, 1, 1, 0) ); + mColumns[1] = _mm_shuffle_ps( unpacklo, src.mColumns[2], _MM_SHUFFLE(0, 1, 3, 2) ); mColumns[2] = _mm_shuffle_ps( _mm_unpackhi_ps( srcCol0, srcCol1 ), src.mColumns[2], _MM_SHUFFLE(0, 2, 1, 0) ); } diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h index 27cf5b79f..7fd052291 100644 --- a/indra/llmath/llmatrix4a.h +++ b/indra/llmath/llmatrix4a.h @@ -105,24 +105,42 @@ public: mMatrix[3].setAdd(a.mMatrix[3],d3); } - inline void rotate(const LLVector4a& v, LLVector4a& res) + inline void rotate(const LLVector4a& v, LLVector4a& res) const { - res = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0)); - res.mul(mMatrix[0]); - - LLVector4a y; - y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1)); - y.mul(mMatrix[1]); + LLVector4a x,y,z; - LLVector4a z; + x = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0)); + y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1)); z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2)); + + x.mul(mMatrix[0]); + y.mul(mMatrix[1]); z.mul(mMatrix[2]); - res.add(y); - res.add(z); + x.add(y); + res.setAdd(x,z); + } + + inline void rotate4(const LLVector4a& v, LLVector4a& res) const + { + LLVector4a x,y,z,w; + + x = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0)); + y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1)); + z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2)); + w = _mm_shuffle_ps(v, v, _MM_SHUFFLE(3, 3, 3, 3)); + + x.mul(mMatrix[0]); + y.mul(mMatrix[1]); + z.mul(mMatrix[2]); + w.mul(mMatrix[3]); + + x.add(y); + z.add(w); + res.setAdd(x,z); } - inline void affineTransform(const LLVector4a& v, LLVector4a& res) + inline void affineTransform(const LLVector4a& v, LLVector4a& res) const { LLVector4a x,y,z; diff --git a/indra/newview/llhudrender.cpp b/indra/newview/llhudrender.cpp index 9b8d78113..a41d8c0d4 100644 --- a/indra/newview/llhudrender.cpp +++ b/indra/newview/llhudrender.cpp @@ -54,6 +54,8 @@ void hud_render_utf8text(const std::string &str, const LLVector3 &pos_agent, hud_render_text(wstr, pos_agent, font, style, x_offset, y_offset, color, orthographic); } +int glProjectf(const LLVector3& object, const F32* modelview, const F32* projection, const LLRect& viewport, LLVector3& windowCoordinate); + void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent, const LLFontGL &font, const U8 style, @@ -103,27 +105,15 @@ void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent, //get the render_pos in screen space - F64 winX, winY, winZ; + LLVector3 window_coordinates; + F32& winX = window_coordinates.mV[VX]; + F32& winY = window_coordinates.mV[VY]; + F32& winZ = window_coordinates.mV[VZ]; + const LLRect& world_view_rect = gViewerWindow->getWorldViewRectRaw(); - S32 viewport[4]; - viewport[0] = world_view_rect.mLeft; - viewport[1] = world_view_rect.mBottom; - viewport[2] = world_view_rect.getWidth(); - viewport[3] = world_view_rect.getHeight(); - - F64 mdlv[16]; - F64 proj[16]; - - for (U32 i = 0; i < 16; i++) - { - mdlv[i] = (F64) gGLModelView[i]; - proj[i] = (F64) gGLProjection[i]; - } - gluProject(render_pos.mV[0], render_pos.mV[1], render_pos.mV[2], - mdlv, proj, (GLint*) viewport, - &winX, &winY, &winZ); - + glProjectf(render_pos, gGLModelView, gGLProjection, world_view_rect, window_coordinates); + //fonts all render orthographically, set up projection`` glMatrixMode(GL_PROJECTION); glPushMatrix(); diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index 2089ef3cd..506bf728f 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -471,13 +471,73 @@ void LLViewerCamera::projectScreenToPosAgent(const S32 screen_x, const S32 scree pos_agent->setVec( (F32)x, (F32)y, (F32)z ); } +//Based off of http://www.opengl.org/wiki/GluProject_and_gluUnProject_code +int glProjectf(const LLVector3& object, const F32* modelview, const F32* projection, const LLRect& viewport, LLVector3& windowCoordinate) +{ + const LLVector4a obj_vector(object.mV[VX],object.mV[VY],object.mV[VZ]); + LLVector4a temp_matrix; + + const LLMatrix4a &view_matrix=*(LLMatrix4a*)modelview; + const LLMatrix4a &proj_matrix=*(LLMatrix4a*)projection; + + view_matrix.affineTransform(obj_vector, temp_matrix); + + //Passing temp_matrix as v and res is safe. res not altered until after all other calculations + proj_matrix.rotate4(temp_matrix, temp_matrix); + + if(temp_matrix[VW]==0.0) + return 0; + + temp_matrix.div(temp_matrix[VW]); + + //Map x, y to range 0-1 + temp_matrix.mul(.5f); + temp_matrix.add(.5f); + + //Window coordinates + windowCoordinate[0]=temp_matrix[VX]*viewport.getWidth()+viewport.mLeft; + windowCoordinate[1]=temp_matrix[VY]*viewport.getHeight()+viewport.mBottom; + //This is only correct when glDepthRange(0.0, 1.0) + windowCoordinate[2]=temp_matrix[VZ]; + + return 1; +} + +void MultiplyMatrices4by4OpenGL_FLOAT(LLMatrix4a& dest_matrix, const LLMatrix4a& input_matrix1, const LLMatrix4a& input_matrix2) +{ + input_matrix1.rotate4(input_matrix2.mMatrix[VX],dest_matrix.mMatrix[VX]); + input_matrix1.rotate4(input_matrix2.mMatrix[VY],dest_matrix.mMatrix[VY]); + input_matrix1.rotate4(input_matrix2.mMatrix[VZ],dest_matrix.mMatrix[VZ]); + input_matrix1.rotate4(input_matrix2.mMatrix[VW],dest_matrix.mMatrix[VW]); + + //Those four lines do this: + /* + result[0]=matrix1[0]*matrix2[0]+matrix1[4]*matrix2[1]+matrix1[8]*matrix2[2]+matrix1[12]*matrix2[3]; + result[1]=matrix1[1]*matrix2[0]+matrix1[5]*matrix2[1]+matrix1[9]*matrix2[2]+matrix1[13]*matrix2[3]; + result[2]=matrix1[2]*matrix2[0]+matrix1[6]*matrix2[1]+matrix1[10]*matrix2[2]+matrix1[14]*matrix2[3]; + result[3]=matrix1[3]*matrix2[0]+matrix1[7]*matrix2[1]+matrix1[11]*matrix2[2]+matrix1[15]*matrix2[3]; + result[4]=matrix1[0]*matrix2[4]+matrix1[4]*matrix2[5]+matrix1[8]*matrix2[6]+matrix1[12]*matrix2[7]; + result[5]=matrix1[1]*matrix2[4]+matrix1[5]*matrix2[5]+matrix1[9]*matrix2[6]+matrix1[13]*matrix2[7]; + result[6]=matrix1[2]*matrix2[4]+matrix1[6]*matrix2[5]+matrix1[10]*matrix2[6]+matrix1[14]*matrix2[7]; + result[7]=matrix1[3]*matrix2[4]+matrix1[7]*matrix2[5]+matrix1[11]*matrix2[6]+matrix1[15]*matrix2[7]; + result[8]=matrix1[0]*matrix2[8]+matrix1[4]*matrix2[9]+matrix1[8]*matrix2[10]+matrix1[12]*matrix2[11]; + result[9]=matrix1[1]*matrix2[8]+matrix1[5]*matrix2[9]+matrix1[9]*matrix2[10]+matrix1[13]*matrix2[11]; + result[10]=matrix1[2]*matrix2[8]+matrix1[6]*matrix2[9]+matrix1[10]*matrix2[10]+matrix1[14]*matrix2[11]; + result[11]=matrix1[3]*matrix2[8]+matrix1[7]*matrix2[9]+matrix1[11]*matrix2[10]+matrix1[15]*matrix2[11]; + result[12]=matrix1[0]*matrix2[12]+matrix1[4]*matrix2[13]+matrix1[8]*matrix2[14]+matrix1[12]*matrix2[15]; + result[13]=matrix1[1]*matrix2[12]+matrix1[5]*matrix2[13]+matrix1[9]*matrix2[14]+matrix1[13]*matrix2[15]; + result[14]=matrix1[2]*matrix2[12]+matrix1[6]*matrix2[13]+matrix1[10]*matrix2[14]+matrix1[14]*matrix2[15]; + result[15]=matrix1[3]*matrix2[12]+ matrix1[7]*matrix2[13]+matrix1[11]*matrix2[14]+matrix1[15]*matrix2[15]; + */ +} + // Uses the last GL matrices set in set_perspective to project a point from // the agent's region space to screen coordinates. Returns TRUE if point in within // the current window. BOOL LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoordGL &out_point, const BOOL clamp) const { BOOL in_front = TRUE; - GLdouble x, y, z; // object's window coords, GL-style + LLVector3 window_coordinates; LLVector3 dir_to_point = pos_agent - getOrigin(); dir_to_point /= dir_to_point.magVec(); @@ -495,24 +555,12 @@ BOOL LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoord } const LLRect& world_view_rect = gViewerWindow->getWorldViewRectRaw(); - S32 viewport[4]; - viewport[0] = world_view_rect.mLeft; - viewport[1] = world_view_rect.mBottom; - viewport[2] = world_view_rect.getWidth(); - viewport[3] = world_view_rect.getHeight(); - F64 mdlv[16]; - F64 proj[16]; + if (GL_TRUE == glProjectf(pos_agent, gGLModelView, gGLProjection, world_view_rect, window_coordinates)) + { + F32 &x = window_coordinates.mV[VX]; + F32 &y = window_coordinates.mV[VY]; - for (U32 i = 0; i < 16; i++) - { - mdlv[i] = (F64) gGLModelView[i]; - proj[i] = (F64) gGLProjection[i]; - } - if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ], - mdlv, proj, (GLint*)viewport, - &x, &y, &z)) - { // convert screen coordinates to virtual UI coordinates x /= gViewerWindow->getDisplayScale().mV[VX]; y /= gViewerWindow->getDisplayScale().mV[VY]; @@ -606,27 +654,13 @@ BOOL LLViewerCamera::projectPosAgentToScreenEdge(const LLVector3 &pos_agent, } const LLRect& world_view_rect = gViewerWindow->getWorldViewRectRaw(); - S32 viewport[4]; - viewport[0] = world_view_rect.mLeft; - viewport[1] = world_view_rect.mBottom; - viewport[2] = world_view_rect.getWidth(); - viewport[3] = world_view_rect.getHeight(); - GLdouble x, y, z; // object's window coords, GL-style + LLVector3 window_coordinates; - F64 mdlv[16]; - F64 proj[16]; - - for (U32 i = 0; i < 16; i++) + if (GL_TRUE == glProjectf(pos_agent, gGLModelView, gGLProjection, world_view_rect, window_coordinates)) { - mdlv[i] = (F64) gGLModelView[i]; - proj[i] = (F64) gGLProjection[i]; - } + F32 &x = window_coordinates.mV[VX]; + F32 &y = window_coordinates.mV[VY]; - if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY], - pos_agent.mV[VZ], mdlv, - proj, (GLint*)viewport, - &x, &y, &z)) - { x /= gViewerWindow->getDisplayScale().mV[VX]; y /= gViewerWindow->getDisplayScale().mV[VY]; // should now have the x,y coords of grab_point in screen space