00001
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include "llviewerprecompiledheaders.h"
00044
00045 #include "llviewerjointmesh.h"
00046
00047
00048 #include "llface.h"
00049 #include "llpolymesh.h"
00050
00051
00052 #include "lldarray.h"
00053 #include "llstrider.h"
00054 #include "llv4math.h"
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]));
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
00076 void LLViewerJointMesh::updateGeometrySSE2(LLFace *face, LLPolyMesh *mesh)
00077 {
00078
00079
00080 static LLV4Matrix4 sJointMat[32];
00081 LLDynamicArray<LLJointRenderData*>& joint_data = mesh->getReferenceMesh()->mJointRenderData;
00082
00083
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