00001
00035
00036
00037
00038
00039 #include "llviewerprecompiledheaders.h"
00040
00041 #include "llviewerjointmesh.h"
00042
00043
00044 #include "llface.h"
00045 #include "llpolymesh.h"
00046
00047
00048 #include "lldarray.h"
00049 #include "llv4math.h"
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]));
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
00069 void LLViewerJointMesh::updateGeometrySSE(LLFace *face, LLPolyMesh *mesh)
00070 {
00071
00072
00073 static LLV4Matrix4 sJointMat[32];
00074 LLDynamicArray<LLJointRenderData*>& joint_data = mesh->getReferenceMesh()->mJointRenderData;
00075
00076
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