llviewerjointmesh_sse2.cpp

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

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