llviewerjointmesh_sse.cpp

Go to the documentation of this file.
00001 
00035 //-----------------------------------------------------------------------------
00036 // Header Files
00037 //-----------------------------------------------------------------------------
00038 
00039 #include "llviewerprecompiledheaders.h"
00040 
00041 #include "llviewerjointmesh.h"
00042 
00043 // project includes
00044 #include "llface.h"
00045 #include "llpolymesh.h"
00046 
00047 // library includes
00048 #include "lldarray.h"
00049 #include "llv4math.h"           // for LL_VECTORIZE
00050 #include "llv4matrix3.h"
00051 #include "llv4matrix4.h"
00052 #include "v3math.h"
00053 
00054 
00055 #if LL_VECTORIZE
00056 
00057 inline void matrix_translate(LLV4Matrix4& m, const LLMatrix4* w, const LLVector3& j)
00058 {
00059         m.mV[VX] = _mm_loadu_ps(w->mMatrix[VX]);
00060         m.mV[VY] = _mm_loadu_ps(w->mMatrix[VY]);
00061         m.mV[VZ] = _mm_loadu_ps(w->mMatrix[VZ]);
00062         m.mV[VW] = _mm_loadu_ps(w->mMatrix[VW]);
00063         m.mV[VW] = _mm_add_ps(m.mV[VW], _mm_mul_ps(_mm_set1_ps(j.mV[VX]), m.mV[VX])); // ( ax * vx ) + vw
00064         m.mV[VW] = _mm_add_ps(m.mV[VW], _mm_mul_ps(_mm_set1_ps(j.mV[VY]), m.mV[VY]));
00065         m.mV[VW] = _mm_add_ps(m.mV[VW], _mm_mul_ps(_mm_set1_ps(j.mV[VZ]), m.mV[VZ]));
00066 }
00067 
00068 // static
00069 void LLViewerJointMesh::updateGeometrySSE(LLFace *face, LLPolyMesh *mesh)
00070 {
00071         // This cannot be a file-level static because it will be initialized
00072         // before main() using SSE code, which will crash on non-SSE processors.
00073         static LLV4Matrix4      sJointMat[32];
00074         LLDynamicArray<LLJointRenderData*>& joint_data = mesh->getReferenceMesh()->mJointRenderData;
00075 
00076         //upload joint pivots/matrices
00077         for(S32 j = 0, jend = joint_data.count(); j < jend ; ++j )
00078         {
00079                 matrix_translate(sJointMat[j], joint_data[j]->mWorldMatrix,
00080                         joint_data[j]->mSkinJoint ?
00081                                 joint_data[j]->mSkinJoint->mRootToJointSkinOffset
00082                                 : joint_data[j+1]->mSkinJoint->mRootToParentJointSkinOffset);
00083         }
00084 
00085         F32                                     weight          = F32_MAX;
00086         LLV4Matrix4                     blend_mat;
00087 
00088         LLStrider<LLVector3> o_vertices;
00089         LLStrider<LLVector3> o_normals;
00090 
00091         LLVertexBuffer *buffer = face->mVertexBuffer;
00092         buffer->getVertexStrider(o_vertices,  mesh->mFaceVertexOffset);
00093         buffer->getNormalStrider(o_normals,   mesh->mFaceVertexOffset);
00094 
00095         const F32*                      weights                 = mesh->getWeights();
00096         const LLVector3*        coords                  = mesh->getCoords();
00097         const LLVector3*        normals                 = mesh->getNormals();
00098         for (U32 index = 0, index_end = mesh->getNumVertices(); index < index_end; ++index)
00099         {
00100                 if( weight != weights[index])
00101                 {
00102                         S32 joint = llfloor(weight = weights[index]);
00103                         blend_mat.lerp(sJointMat[joint], sJointMat[joint+1], weight - joint);
00104                 }
00105                 blend_mat.multiply(coords[index], o_vertices[index]);
00106                 ((LLV4Matrix3)blend_mat).multiply(normals[index], o_normals[index]);
00107         }
00108 }
00109 
00110 #else
00111 
00112 void LLViewerJointMesh::updateGeometrySSE(LLFace *face, LLPolyMesh *mesh)
00113 {
00114         LLViewerJointMesh::updateGeometryVectorized(face, mesh);
00115 }
00116 
00117 #endif

Generated on Thu Jul 1 06:09:28 2010 for Second Life Viewer by  doxygen 1.4.7