summaryrefslogtreecommitdiff
path: root/indra/newview/llpolymesh.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llpolymesh.cpp')
-rw-r--r--indra/newview/llpolymesh.cpp1708
1 files changed, 904 insertions, 804 deletions
diff --git a/indra/newview/llpolymesh.cpp b/indra/newview/llpolymesh.cpp
index 363b0b8e9d..450f9b2be7 100644
--- a/indra/newview/llpolymesh.cpp
+++ b/indra/newview/llpolymesh.cpp
@@ -29,7 +29,8 @@
//-----------------------------------------------------------------------------
#include "llviewerprecompiledheaders.h"
-#include "llpolymesh.h"
+#include "llfasttimer.h"
+#include "llmemory.h"
#include "llviewercontrol.h"
#include "llxmltree.h"
@@ -39,12 +40,21 @@
#include "llvolume.h"
#include "llendianswizzle.h"
-#include "llfasttimer.h"
+#include "llpolymesh.h"
#define HEADER_ASCII "Linden Mesh 1.0"
#define HEADER_BINARY "Linden Binary Mesh 1.0"
-extern LLControlGroup gSavedSettings; // read only
+extern LLControlGroup gSavedSettings; // read only
+
+LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data,
+ const std::string &name);
+LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data,
+ const LLVector3 &direction,
+ const std::string &name);
+LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data,
+ F32 scale,
+ const std::string &name);
//-----------------------------------------------------------------------------
// Global table of loaded LLPolyMeshes
@@ -56,28 +66,28 @@ LLPolyMesh::LLPolyMeshSharedDataTable LLPolyMesh::sGlobalSharedMeshList;
//-----------------------------------------------------------------------------
LLPolyMeshSharedData::LLPolyMeshSharedData()
{
- mNumVertices = 0;
- mBaseCoords = NULL;
- mBaseNormals = NULL;
- mBaseBinormals = NULL;
- mTexCoords = NULL;
- mDetailTexCoords = NULL;
- mWeights = NULL;
- mHasWeights = FALSE;
- mHasDetailTexCoords = FALSE;
+ mNumVertices = 0;
+ mBaseCoords = NULL;
+ mBaseNormals = NULL;
+ mBaseBinormals = NULL;
+ mTexCoords = NULL;
+ mDetailTexCoords = NULL;
+ mWeights = NULL;
+ mHasWeights = FALSE;
+ mHasDetailTexCoords = FALSE;
- mNumFaces = 0;
- mFaces = NULL;
+ mNumFaces = 0;
+ mFaces = NULL;
- mNumJointNames = 0;
- mJointNames = NULL;
+ mNumJointNames = 0;
+ mJointNames = NULL;
- mTriangleIndices = NULL;
- mNumTriangleIndices = 0;
+ mTriangleIndices = NULL;
+ mNumTriangleIndices = 0;
- mReferenceData = NULL;
+ mReferenceData = NULL;
- mLastIndexOffset = -1;
+ mLastIndexOffset = -1;
}
//-----------------------------------------------------------------------------
@@ -85,9 +95,9 @@ LLPolyMeshSharedData::LLPolyMeshSharedData()
//-----------------------------------------------------------------------------
LLPolyMeshSharedData::~LLPolyMeshSharedData()
{
- freeMeshData();
- for_each(mMorphData.begin(), mMorphData.end(), DeletePointer());
- mMorphData.clear();
+ freeMeshData();
+ for_each(mMorphData.begin(), mMorphData.end(), DeletePointer());
+ mMorphData.clear();
}
//-----------------------------------------------------------------------------
@@ -95,19 +105,19 @@ LLPolyMeshSharedData::~LLPolyMeshSharedData()
//-----------------------------------------------------------------------------
void LLPolyMeshSharedData::setupLOD(LLPolyMeshSharedData* reference_data)
{
- mReferenceData = reference_data;
-
- if (reference_data)
- {
- mBaseCoords = reference_data->mBaseCoords;
- mBaseNormals = reference_data->mBaseNormals;
- mBaseBinormals = reference_data->mBaseBinormals;
- mTexCoords = reference_data->mTexCoords;
- mDetailTexCoords = reference_data->mDetailTexCoords;
- mWeights = reference_data->mWeights;
- mHasWeights = reference_data->mHasWeights;
- mHasDetailTexCoords = reference_data->mHasDetailTexCoords;
- }
+ mReferenceData = reference_data;
+
+ if (reference_data)
+ {
+ mBaseCoords = reference_data->mBaseCoords;
+ mBaseNormals = reference_data->mBaseNormals;
+ mBaseBinormals = reference_data->mBaseBinormals;
+ mTexCoords = reference_data->mTexCoords;
+ mDetailTexCoords = reference_data->mDetailTexCoords;
+ mWeights = reference_data->mWeights;
+ mHasWeights = reference_data->mHasWeights;
+ mHasDetailTexCoords = reference_data->mHasDetailTexCoords;
+ }
}
//-----------------------------------------------------------------------------
@@ -115,41 +125,41 @@ void LLPolyMeshSharedData::setupLOD(LLPolyMeshSharedData* reference_data)
//-----------------------------------------------------------------------------
void LLPolyMeshSharedData::freeMeshData()
{
- if (!mReferenceData)
- {
- mNumVertices = 0;
+ if (!mReferenceData)
+ {
+ mNumVertices = 0;
- delete [] mBaseCoords;
- mBaseCoords = NULL;
+ delete [] mBaseCoords;
+ mBaseCoords = NULL;
- delete [] mBaseNormals;
- mBaseNormals = NULL;
+ delete [] mBaseNormals;
+ mBaseNormals = NULL;
- delete [] mBaseBinormals;
- mBaseBinormals = NULL;
+ delete [] mBaseBinormals;
+ mBaseBinormals = NULL;
- delete [] mTexCoords;
- mTexCoords = NULL;
+ delete [] mTexCoords;
+ mTexCoords = NULL;
- delete [] mDetailTexCoords;
- mDetailTexCoords = NULL;
+ delete [] mDetailTexCoords;
+ mDetailTexCoords = NULL;
- delete [] mWeights;
- mWeights = NULL;
- }
+ delete [] mWeights;
+ mWeights = NULL;
+ }
- mNumFaces = 0;
- delete [] mFaces;
- mFaces = NULL;
+ mNumFaces = 0;
+ delete [] mFaces;
+ mFaces = NULL;
- mNumJointNames = 0;
- delete [] mJointNames;
- mJointNames = NULL;
+ mNumJointNames = 0;
+ delete [] mJointNames;
+ mJointNames = NULL;
- delete [] mTriangleIndices;
- mTriangleIndices = NULL;
+ delete [] mTriangleIndices;
+ mTriangleIndices = NULL;
-// mVertFaceMap.deleteAllData();
+// mVertFaceMap.deleteAllData();
}
// compate_int is used by the qsort function to sort the index array
@@ -160,26 +170,26 @@ int compare_int(const void *a, const void *b);
//-----------------------------------------------------------------------------
void LLPolyMeshSharedData::genIndices(S32 index_offset)
{
- if (index_offset == mLastIndexOffset)
- {
- return;
- }
-
- delete []mTriangleIndices;
- mTriangleIndices = new U32[mNumTriangleIndices];
-
- S32 cur_index = 0;
- for (S32 i = 0; i < mNumFaces; i++)
- {
- mTriangleIndices[cur_index] = mFaces[i][0] + index_offset;
- cur_index++;
- mTriangleIndices[cur_index] = mFaces[i][1] + index_offset;
- cur_index++;
- mTriangleIndices[cur_index] = mFaces[i][2] + index_offset;
- cur_index++;
- }
-
- mLastIndexOffset = index_offset;
+ if (index_offset == mLastIndexOffset)
+ {
+ return;
+ }
+
+ delete []mTriangleIndices;
+ mTriangleIndices = new U32[mNumTriangleIndices];
+
+ S32 cur_index = 0;
+ for (S32 i = 0; i < mNumFaces; i++)
+ {
+ mTriangleIndices[cur_index] = mFaces[i][0] + index_offset;
+ cur_index++;
+ mTriangleIndices[cur_index] = mFaces[i][1] + index_offset;
+ cur_index++;
+ mTriangleIndices[cur_index] = mFaces[i][2] + index_offset;
+ cur_index++;
+ }
+
+ mLastIndexOffset = index_offset;
}
//--------------------------------------------------------------------
@@ -187,30 +197,30 @@ void LLPolyMeshSharedData::genIndices(S32 index_offset)
//--------------------------------------------------------------------
U32 LLPolyMeshSharedData::getNumKB()
{
- U32 num_kb = sizeof(LLPolyMesh);
-
- if (!isLOD())
- {
- num_kb += mNumVertices *
- ( sizeof(LLVector3) + // coords
- sizeof(LLVector3) + // normals
- sizeof(LLVector2) ); // texCoords
- }
-
- if (mHasDetailTexCoords && !isLOD())
- {
- num_kb += mNumVertices * sizeof(LLVector2); // detailTexCoords
- }
-
- if (mHasWeights && !isLOD())
- {
- num_kb += mNumVertices * sizeof(float); // weights
- }
-
- num_kb += mNumFaces * sizeof(LLPolyFace); // faces
-
- num_kb /= 1024;
- return num_kb;
+ U32 num_kb = sizeof(LLPolyMesh);
+
+ if (!isLOD())
+ {
+ num_kb += mNumVertices *
+ ( sizeof(LLVector3) + // coords
+ sizeof(LLVector3) + // normals
+ sizeof(LLVector2) ); // texCoords
+ }
+
+ if (mHasDetailTexCoords && !isLOD())
+ {
+ num_kb += mNumVertices * sizeof(LLVector2); // detailTexCoords
+ }
+
+ if (mHasWeights && !isLOD())
+ {
+ num_kb += mNumVertices * sizeof(float); // weights
+ }
+
+ num_kb += mNumFaces * sizeof(LLPolyFace); // faces
+
+ num_kb /= 1024;
+ return num_kb;
}
//-----------------------------------------------------------------------------
@@ -218,19 +228,19 @@ U32 LLPolyMeshSharedData::getNumKB()
//-----------------------------------------------------------------------------
BOOL LLPolyMeshSharedData::allocateVertexData( U32 numVertices )
{
- U32 i;
- mBaseCoords = new LLVector3[ numVertices ];
- mBaseNormals = new LLVector3[ numVertices ];
- mBaseBinormals = new LLVector3[ numVertices ];
- mTexCoords = new LLVector2[ numVertices ];
- mDetailTexCoords = new LLVector2[ numVertices ];
- mWeights = new F32[ numVertices ];
- for (i = 0; i < numVertices; i++)
- {
- mWeights[i] = 0.f;
- }
- mNumVertices = numVertices;
- return TRUE;
+ U32 i;
+ mBaseCoords = new LLVector3[ numVertices ];
+ mBaseNormals = new LLVector3[ numVertices ];
+ mBaseBinormals = new LLVector3[ numVertices ];
+ mTexCoords = new LLVector2[ numVertices ];
+ mDetailTexCoords = new LLVector2[ numVertices ];
+ mWeights = new F32[ numVertices ];
+ for (i = 0; i < numVertices; i++)
+ {
+ mWeights[i] = 0.f;
+ }
+ mNumVertices = numVertices;
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -238,10 +248,10 @@ BOOL LLPolyMeshSharedData::allocateVertexData( U32 numVertices )
//-----------------------------------------------------------------------------
BOOL LLPolyMeshSharedData::allocateFaceData( U32 numFaces )
{
- mFaces = new LLPolyFace[ numFaces ];
- mNumFaces = numFaces;
- mNumTriangleIndices = mNumFaces * 3;
- return TRUE;
+ mFaces = new LLPolyFace[ numFaces ];
+ mNumFaces = numFaces;
+ mNumTriangleIndices = mNumFaces * 3;
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -249,9 +259,9 @@ BOOL LLPolyMeshSharedData::allocateFaceData( U32 numFaces )
//-----------------------------------------------------------------------------
BOOL LLPolyMeshSharedData::allocateJointNames( U32 numJointNames )
{
- mJointNames = new std::string[ numJointNames ];
- mNumJointNames = numJointNames;
- return TRUE;
+ mJointNames = new std::string[ numJointNames ];
+ mNumJointNames = numJointNames;
+ return TRUE;
}
//--------------------------------------------------------------------
@@ -259,393 +269,445 @@ BOOL LLPolyMeshSharedData::allocateJointNames( U32 numJointNames )
//--------------------------------------------------------------------
BOOL LLPolyMeshSharedData::loadMesh( const std::string& fileName )
{
- //-------------------------------------------------------------------------
- // Open the file
- //-------------------------------------------------------------------------
- if(fileName.empty())
- {
- llerrs << "Filename is Empty!" << llendl;
- return FALSE;
- }
- LLFILE* fp = LLFile::fopen(fileName, "rb"); /*Flawfinder: ignore*/
- if (!fp)
- {
- llerrs << "can't open: " << fileName << llendl;
- return FALSE;
- }
-
- //-------------------------------------------------------------------------
- // Read a chunk
- //-------------------------------------------------------------------------
- char header[128]; /*Flawfinder: ignore*/
- if (fread(header, sizeof(char), 128, fp) != 128)
- {
- llwarns << "Short read" << llendl;
- }
-
- //-------------------------------------------------------------------------
- // Check for proper binary header
- //-------------------------------------------------------------------------
- BOOL status = FALSE;
- if ( strncmp(header, HEADER_BINARY, strlen(HEADER_BINARY)) == 0 ) /*Flawfinder: ignore*/
- {
- lldebugs << "Loading " << fileName << llendl;
-
- //----------------------------------------------------------------
- // File Header (seek past it)
- //----------------------------------------------------------------
- fseek(fp, 24, SEEK_SET);
-
- //----------------------------------------------------------------
- // HasWeights
- //----------------------------------------------------------------
- U8 hasWeights;
- size_t numRead = fread(&hasWeights, sizeof(U8), 1, fp);
- if (numRead != 1)
- {
- llerrs << "can't read HasWeights flag from " << fileName << llendl;
- return FALSE;
- }
- if (!isLOD())
- {
- mHasWeights = (hasWeights==0) ? FALSE : TRUE;
- }
-
- //----------------------------------------------------------------
- // HasDetailTexCoords
- //----------------------------------------------------------------
- U8 hasDetailTexCoords;
- numRead = fread(&hasDetailTexCoords, sizeof(U8), 1, fp);
- if (numRead != 1)
- {
- llerrs << "can't read HasDetailTexCoords flag from " << fileName << llendl;
- return FALSE;
- }
-
- //----------------------------------------------------------------
- // Position
- //----------------------------------------------------------------
- LLVector3 position;
- numRead = fread(position.mV, sizeof(float), 3, fp);
- llendianswizzle(position.mV, sizeof(float), 3);
- if (numRead != 3)
- {
- llerrs << "can't read Position from " << fileName << llendl;
- return FALSE;
- }
- setPosition( position );
-
- //----------------------------------------------------------------
- // Rotation
- //----------------------------------------------------------------
- LLVector3 rotationAngles;
- numRead = fread(rotationAngles.mV, sizeof(float), 3, fp);
- llendianswizzle(rotationAngles.mV, sizeof(float), 3);
- if (numRead != 3)
- {
- llerrs << "can't read RotationAngles from " << fileName << llendl;
- return FALSE;
- }
-
- U8 rotationOrder;
- numRead = fread(&rotationOrder, sizeof(U8), 1, fp);
-
- if (numRead != 1)
- {
- llerrs << "can't read RotationOrder from " << fileName << llendl;
- return FALSE;
- }
-
- rotationOrder = 0;
-
- setRotation( mayaQ( rotationAngles.mV[0],
- rotationAngles.mV[1],
- rotationAngles.mV[2],
- (LLQuaternion::Order)rotationOrder ) );
-
- //----------------------------------------------------------------
- // Scale
- //----------------------------------------------------------------
- LLVector3 scale;
- numRead = fread(scale.mV, sizeof(float), 3, fp);
- llendianswizzle(scale.mV, sizeof(float), 3);
- if (numRead != 3)
- {
- llerrs << "can't read Scale from " << fileName << llendl;
- return FALSE;
- }
- setScale( scale );
-
- //-------------------------------------------------------------------------
- // Release any existing mesh geometry
- //-------------------------------------------------------------------------
- freeMeshData();
-
- U16 numVertices = 0;
-
- //----------------------------------------------------------------
- // NumVertices
- //----------------------------------------------------------------
- if (!isLOD())
- {
- numRead = fread(&numVertices, sizeof(U16), 1, fp);
- llendianswizzle(&numVertices, sizeof(U16), 1);
- if (numRead != 1)
- {
- llerrs << "can't read NumVertices from " << fileName << llendl;
- return FALSE;
- }
-
- allocateVertexData( numVertices );
-
- //----------------------------------------------------------------
- // Coords
- //----------------------------------------------------------------
- numRead = fread(mBaseCoords, 3*sizeof(float), numVertices, fp);
- llendianswizzle(mBaseCoords, sizeof(float), 3*numVertices);
- if (numRead != numVertices)
- {
- llerrs << "can't read Coordinates from " << fileName << llendl;
- return FALSE;
- }
-
- //----------------------------------------------------------------
- // Normals
- //----------------------------------------------------------------
- numRead = fread(mBaseNormals, 3*sizeof(float), numVertices, fp);
- llendianswizzle(mBaseNormals, sizeof(float), 3*numVertices);
- if (numRead != numVertices)
- {
- llerrs << " can't read Normals from " << fileName << llendl;
- return FALSE;
- }
-
- //----------------------------------------------------------------
- // Binormals
- //----------------------------------------------------------------
- numRead = fread(mBaseBinormals, 3*sizeof(float), numVertices, fp);
- llendianswizzle(mBaseBinormals, sizeof(float), 3*numVertices);
- if (numRead != numVertices)
- {
- llerrs << " can't read Binormals from " << fileName << llendl;
- return FALSE;
- }
-
-
- //----------------------------------------------------------------
- // TexCoords
- //----------------------------------------------------------------
- numRead = fread(mTexCoords, 2*sizeof(float), numVertices, fp);
- llendianswizzle(mTexCoords, sizeof(float), 2*numVertices);
- if (numRead != numVertices)
- {
- llerrs << "can't read TexCoords from " << fileName << llendl;
- return FALSE;
- }
-
- //----------------------------------------------------------------
- // DetailTexCoords
- //----------------------------------------------------------------
- if (mHasDetailTexCoords)
- {
- numRead = fread(mDetailTexCoords, 2*sizeof(float), numVertices, fp);
- llendianswizzle(mDetailTexCoords, sizeof(float), 2*numVertices);
- if (numRead != numVertices)
- {
- llerrs << "can't read DetailTexCoords from " << fileName << llendl;
- return FALSE;
- }
- }
-
- //----------------------------------------------------------------
- // Weights
- //----------------------------------------------------------------
- if (mHasWeights)
- {
- numRead = fread(mWeights, sizeof(float), numVertices, fp);
- llendianswizzle(mWeights, sizeof(float), numVertices);
- if (numRead != numVertices)
- {
- llerrs << "can't read Weights from " << fileName << llendl;
- return FALSE;
- }
- }
- }
-
- //----------------------------------------------------------------
- // NumFaces
- //----------------------------------------------------------------
- U16 numFaces;
- numRead = fread(&numFaces, sizeof(U16), 1, fp);
- llendianswizzle(&numFaces, sizeof(U16), 1);
- if (numRead != 1)
- {
- llerrs << "can't read NumFaces from " << fileName << llendl;
- return FALSE;
- }
- allocateFaceData( numFaces );
-
-
- //----------------------------------------------------------------
- // Faces
- //----------------------------------------------------------------
- U32 i;
- U32 numTris = 0;
- for (i = 0; i < numFaces; i++)
- {
- S16 face[3];
- numRead = fread(face, sizeof(U16), 3, fp);
- llendianswizzle(face, sizeof(U16), 3);
- if (numRead != 3)
- {
- llerrs << "can't read Face[" << i << "] from " << fileName << llendl;
- return FALSE;
- }
- if (mReferenceData)
- {
- llassert(face[0] < mReferenceData->mNumVertices);
- llassert(face[1] < mReferenceData->mNumVertices);
- llassert(face[2] < mReferenceData->mNumVertices);
- }
-
- if (isLOD())
- {
- // store largest index in case of LODs
- for (S32 j = 0; j < 3; j++)
- {
- if (face[j] > mNumVertices - 1)
- {
- mNumVertices = face[j] + 1;
- }
- }
- }
- mFaces[i][0] = face[0];
- mFaces[i][1] = face[1];
- mFaces[i][2] = face[2];
-
-// S32 j;
-// for(j = 0; j < 3; j++)
-// {
-// LLDynamicArray<S32> *face_list = mVertFaceMap.getIfThere(face[j]);
-// if (!face_list)
-// {
-// face_list = new LLDynamicArray<S32>;
-// mVertFaceMap.addData(face[j], face_list);
-// }
-// face_list->put(i);
-// }
-
- numTris++;
- }
-
- lldebugs << "verts: " << numVertices
- << ", faces: " << numFaces
- << ", tris: " << numTris
- << llendl;
-
- //----------------------------------------------------------------
- // NumSkinJoints
- //----------------------------------------------------------------
- if (!isLOD())
- {
- U16 numSkinJoints = 0;
- if ( mHasWeights )
- {
- numRead = fread(&numSkinJoints, sizeof(U16), 1, fp);
- llendianswizzle(&numSkinJoints, sizeof(U16), 1);
- if (numRead != 1)
- {
- llerrs << "can't read NumSkinJoints from " << fileName << llendl;
- return FALSE;
- }
- allocateJointNames( numSkinJoints );
- }
-
- //----------------------------------------------------------------
- // SkinJoints
- //----------------------------------------------------------------
- for (i=0; i < numSkinJoints; i++)
- {
- char jointName[64+1];
- numRead = fread(jointName, sizeof(jointName)-1, 1, fp);
- jointName[sizeof(jointName)-1] = '\0'; // ensure nul-termination
- if (numRead != 1)
- {
- llerrs << "can't read Skin[" << i << "].Name from " << fileName << llendl;
- return FALSE;
- }
-
- std::string *jn = &mJointNames[i];
- *jn = jointName;
- }
-
- //-------------------------------------------------------------------------
- // look for morph section
- //-------------------------------------------------------------------------
- char morphName[64+1];
- morphName[sizeof(morphName)-1] = '\0'; // ensure nul-termination
- while(fread(&morphName, sizeof(char), 64, fp) == 64)
- {
- if (!strcmp(morphName, "End Morphs"))
- {
- // we reached the end of the morphs
- break;
- }
- LLPolyMorphData* morph_data = new LLPolyMorphData(std::string(morphName));
-
- BOOL result = morph_data->loadBinary(fp, this);
-
- if (!result)
- {
- delete morph_data;
- continue;
- }
-
- mMorphData.insert(morph_data);
- }
-
- S32 numRemaps;
- if (fread(&numRemaps, sizeof(S32), 1, fp) == 1)
- {
- llendianswizzle(&numRemaps, sizeof(S32), 1);
- for (S32 i = 0; i < numRemaps; i++)
- {
- S32 remapSrc;
- S32 remapDst;
- if (fread(&remapSrc, sizeof(S32), 1, fp) != 1)
- {
- llerrs << "can't read source vertex in vertex remap data" << llendl;
- break;
- }
- if (fread(&remapDst, sizeof(S32), 1, fp) != 1)
- {
- llerrs << "can't read destination vertex in vertex remap data" << llendl;
- break;
- }
- llendianswizzle(&remapSrc, sizeof(S32), 1);
- llendianswizzle(&remapDst, sizeof(S32), 1);
-
- mSharedVerts[remapSrc] = remapDst;
- }
- }
- }
-
- status = TRUE;
- }
- else
- {
- llerrs << "invalid mesh file header: " << fileName << llendl;
- status = FALSE;
- }
-
- if (0 == mNumJointNames)
- {
- allocateJointNames(1);
- }
-
- fclose( fp );
-
- return status;
+ //-------------------------------------------------------------------------
+ // Open the file
+ //-------------------------------------------------------------------------
+ if(fileName.empty())
+ {
+ llerrs << "Filename is Empty!" << llendl;
+ return FALSE;
+ }
+ LLFILE* fp = LLFile::fopen(fileName, "rb"); /*Flawfinder: ignore*/
+ if (!fp)
+ {
+ llerrs << "can't open: " << fileName << llendl;
+ return FALSE;
+ }
+
+ //-------------------------------------------------------------------------
+ // Read a chunk
+ //-------------------------------------------------------------------------
+ char header[128]; /*Flawfinder: ignore*/
+ if (fread(header, sizeof(char), 128, fp) != 128)
+ {
+ llwarns << "Short read" << llendl;
+ }
+
+ //-------------------------------------------------------------------------
+ // Check for proper binary header
+ //-------------------------------------------------------------------------
+ BOOL status = FALSE;
+ if ( strncmp(header, HEADER_BINARY, strlen(HEADER_BINARY)) == 0 ) /*Flawfinder: ignore*/
+ {
+ lldebugs << "Loading " << fileName << llendl;
+
+ //----------------------------------------------------------------
+ // File Header (seek past it)
+ //----------------------------------------------------------------
+ fseek(fp, 24, SEEK_SET);
+
+ //----------------------------------------------------------------
+ // HasWeights
+ //----------------------------------------------------------------
+ U8 hasWeights;
+ size_t numRead = fread(&hasWeights, sizeof(U8), 1, fp);
+ if (numRead != 1)
+ {
+ llerrs << "can't read HasWeights flag from " << fileName << llendl;
+ return FALSE;
+ }
+ if (!isLOD())
+ {
+ mHasWeights = (hasWeights==0) ? FALSE : TRUE;
+ }
+
+ //----------------------------------------------------------------
+ // HasDetailTexCoords
+ //----------------------------------------------------------------
+ U8 hasDetailTexCoords;
+ numRead = fread(&hasDetailTexCoords, sizeof(U8), 1, fp);
+ if (numRead != 1)
+ {
+ llerrs << "can't read HasDetailTexCoords flag from " << fileName << llendl;
+ return FALSE;
+ }
+
+ //----------------------------------------------------------------
+ // Position
+ //----------------------------------------------------------------
+ LLVector3 position;
+ numRead = fread(position.mV, sizeof(float), 3, fp);
+ llendianswizzle(position.mV, sizeof(float), 3);
+ if (numRead != 3)
+ {
+ llerrs << "can't read Position from " << fileName << llendl;
+ return FALSE;
+ }
+ setPosition( position );
+
+ //----------------------------------------------------------------
+ // Rotation
+ //----------------------------------------------------------------
+ LLVector3 rotationAngles;
+ numRead = fread(rotationAngles.mV, sizeof(float), 3, fp);
+ llendianswizzle(rotationAngles.mV, sizeof(float), 3);
+ if (numRead != 3)
+ {
+ llerrs << "can't read RotationAngles from " << fileName << llendl;
+ return FALSE;
+ }
+
+ U8 rotationOrder;
+ numRead = fread(&rotationOrder, sizeof(U8), 1, fp);
+
+ if (numRead != 1)
+ {
+ llerrs << "can't read RotationOrder from " << fileName << llendl;
+ return FALSE;
+ }
+
+ rotationOrder = 0;
+
+ setRotation( mayaQ( rotationAngles.mV[0],
+ rotationAngles.mV[1],
+ rotationAngles.mV[2],
+ (LLQuaternion::Order)rotationOrder ) );
+
+ //----------------------------------------------------------------
+ // Scale
+ //----------------------------------------------------------------
+ LLVector3 scale;
+ numRead = fread(scale.mV, sizeof(float), 3, fp);
+ llendianswizzle(scale.mV, sizeof(float), 3);
+ if (numRead != 3)
+ {
+ llerrs << "can't read Scale from " << fileName << llendl;
+ return FALSE;
+ }
+ setScale( scale );
+
+ //-------------------------------------------------------------------------
+ // Release any existing mesh geometry
+ //-------------------------------------------------------------------------
+ freeMeshData();
+
+ U16 numVertices = 0;
+
+ //----------------------------------------------------------------
+ // NumVertices
+ //----------------------------------------------------------------
+ if (!isLOD())
+ {
+ numRead = fread(&numVertices, sizeof(U16), 1, fp);
+ llendianswizzle(&numVertices, sizeof(U16), 1);
+ if (numRead != 1)
+ {
+ llerrs << "can't read NumVertices from " << fileName << llendl;
+ return FALSE;
+ }
+
+ allocateVertexData( numVertices );
+
+ //----------------------------------------------------------------
+ // Coords
+ //----------------------------------------------------------------
+ numRead = fread(mBaseCoords, 3*sizeof(float), numVertices, fp);
+ llendianswizzle(mBaseCoords, sizeof(float), 3*numVertices);
+ if (numRead != numVertices)
+ {
+ llerrs << "can't read Coordinates from " << fileName << llendl;
+ return FALSE;
+ }
+
+ //----------------------------------------------------------------
+ // Normals
+ //----------------------------------------------------------------
+ numRead = fread(mBaseNormals, 3*sizeof(float), numVertices, fp);
+ llendianswizzle(mBaseNormals, sizeof(float), 3*numVertices);
+ if (numRead != numVertices)
+ {
+ llerrs << " can't read Normals from " << fileName << llendl;
+ return FALSE;
+ }
+
+ //----------------------------------------------------------------
+ // Binormals
+ //----------------------------------------------------------------
+ numRead = fread(mBaseBinormals, 3*sizeof(float), numVertices, fp);
+ llendianswizzle(mBaseBinormals, sizeof(float), 3*numVertices);
+ if (numRead != numVertices)
+ {
+ llerrs << " can't read Binormals from " << fileName << llendl;
+ return FALSE;
+ }
+
+
+ //----------------------------------------------------------------
+ // TexCoords
+ //----------------------------------------------------------------
+ numRead = fread(mTexCoords, 2*sizeof(float), numVertices, fp);
+ llendianswizzle(mTexCoords, sizeof(float), 2*numVertices);
+ if (numRead != numVertices)
+ {
+ llerrs << "can't read TexCoords from " << fileName << llendl;
+ return FALSE;
+ }
+
+ //----------------------------------------------------------------
+ // DetailTexCoords
+ //----------------------------------------------------------------
+ if (mHasDetailTexCoords)
+ {
+ numRead = fread(mDetailTexCoords, 2*sizeof(float), numVertices, fp);
+ llendianswizzle(mDetailTexCoords, sizeof(float), 2*numVertices);
+ if (numRead != numVertices)
+ {
+ llerrs << "can't read DetailTexCoords from " << fileName << llendl;
+ return FALSE;
+ }
+ }
+
+ //----------------------------------------------------------------
+ // Weights
+ //----------------------------------------------------------------
+ if (mHasWeights)
+ {
+ numRead = fread(mWeights, sizeof(float), numVertices, fp);
+ llendianswizzle(mWeights, sizeof(float), numVertices);
+ if (numRead != numVertices)
+ {
+ llerrs << "can't read Weights from " << fileName << llendl;
+ return FALSE;
+ }
+ }
+ }
+
+ //----------------------------------------------------------------
+ // NumFaces
+ //----------------------------------------------------------------
+ U16 numFaces;
+ numRead = fread(&numFaces, sizeof(U16), 1, fp);
+ llendianswizzle(&numFaces, sizeof(U16), 1);
+ if (numRead != 1)
+ {
+ llerrs << "can't read NumFaces from " << fileName << llendl;
+ return FALSE;
+ }
+ allocateFaceData( numFaces );
+
+
+ //----------------------------------------------------------------
+ // Faces
+ //----------------------------------------------------------------
+ U32 i;
+ U32 numTris = 0;
+ for (i = 0; i < numFaces; i++)
+ {
+ S16 face[3];
+ numRead = fread(face, sizeof(U16), 3, fp);
+ llendianswizzle(face, sizeof(U16), 3);
+ if (numRead != 3)
+ {
+ llerrs << "can't read Face[" << i << "] from " << fileName << llendl;
+ return FALSE;
+ }
+ if (mReferenceData)
+ {
+ llassert(face[0] < mReferenceData->mNumVertices);
+ llassert(face[1] < mReferenceData->mNumVertices);
+ llassert(face[2] < mReferenceData->mNumVertices);
+ }
+
+ if (isLOD())
+ {
+ // store largest index in case of LODs
+ for (S32 j = 0; j < 3; j++)
+ {
+ if (face[j] > mNumVertices - 1)
+ {
+ mNumVertices = face[j] + 1;
+ }
+ }
+ }
+ mFaces[i][0] = face[0];
+ mFaces[i][1] = face[1];
+ mFaces[i][2] = face[2];
+
+// S32 j;
+// for(j = 0; j < 3; j++)
+// {
+// LLDynamicArray<S32> *face_list = mVertFaceMap.getIfThere(face[j]);
+// if (!face_list)
+// {
+// face_list = new LLDynamicArray<S32>;
+// mVertFaceMap.addData(face[j], face_list);
+// }
+// face_list->put(i);
+// }
+
+ numTris++;
+ }
+
+ lldebugs << "verts: " << numVertices
+ << ", faces: " << numFaces
+ << ", tris: " << numTris
+ << llendl;
+
+ //----------------------------------------------------------------
+ // NumSkinJoints
+ //----------------------------------------------------------------
+ if (!isLOD())
+ {
+ U16 numSkinJoints = 0;
+ if ( mHasWeights )
+ {
+ numRead = fread(&numSkinJoints, sizeof(U16), 1, fp);
+ llendianswizzle(&numSkinJoints, sizeof(U16), 1);
+ if (numRead != 1)
+ {
+ llerrs << "can't read NumSkinJoints from " << fileName << llendl;
+ return FALSE;
+ }
+ allocateJointNames( numSkinJoints );
+ }
+
+ //----------------------------------------------------------------
+ // SkinJoints
+ //----------------------------------------------------------------
+ for (i=0; i < numSkinJoints; i++)
+ {
+ char jointName[64+1];
+ numRead = fread(jointName, sizeof(jointName)-1, 1, fp);
+ jointName[sizeof(jointName)-1] = '\0'; // ensure nul-termination
+ if (numRead != 1)
+ {
+ llerrs << "can't read Skin[" << i << "].Name from " << fileName << llendl;
+ return FALSE;
+ }
+
+ std::string *jn = &mJointNames[i];
+ *jn = jointName;
+ }
+
+ //-------------------------------------------------------------------------
+ // look for morph section
+ //-------------------------------------------------------------------------
+ char morphName[64+1];
+ morphName[sizeof(morphName)-1] = '\0'; // ensure nul-termination
+ while(fread(&morphName, sizeof(char), 64, fp) == 64)
+ {
+ if (!strcmp(morphName, "End Morphs"))
+ {
+ // we reached the end of the morphs
+ break;
+ }
+ LLPolyMorphData* morph_data = new LLPolyMorphData(std::string(morphName));
+
+ BOOL result = morph_data->loadBinary(fp, this);
+
+ if (!result)
+ {
+ delete morph_data;
+ continue;
+ }
+
+ mMorphData.insert(morph_data);
+
+ if (!strcmp(morphName, "Breast_Female_Cleavage"))
+ {
+ mMorphData.insert(clone_morph_param_cleavage(morph_data,
+ .75f,
+ "Breast_Physics_LeftRight_Driven"));
+ }
+
+ if (!strcmp(morphName, "Breast_Female_Cleavage"))
+ {
+ mMorphData.insert(clone_morph_param_duplicate(morph_data,
+ "Breast_Physics_InOut_Driven"));
+ }
+ if (!strcmp(morphName, "Breast_Gravity"))
+ {
+ mMorphData.insert(clone_morph_param_duplicate(morph_data,
+ "Breast_Physics_UpDown_Driven"));
+ }
+
+ if (!strcmp(morphName, "Big_Belly_Torso"))
+ {
+ mMorphData.insert(clone_morph_param_direction(morph_data,
+ LLVector3(0,0,0.05f),
+ "Belly_Physics_Torso_UpDown_Driven"));
+ }
+
+ if (!strcmp(morphName, "Big_Belly_Legs"))
+ {
+ mMorphData.insert(clone_morph_param_direction(morph_data,
+ LLVector3(0,0,0.05f),
+ "Belly_Physics_Legs_UpDown_Driven"));
+ }
+
+ if (!strcmp(morphName, "skirt_belly"))
+ {
+ mMorphData.insert(clone_morph_param_direction(morph_data,
+ LLVector3(0,0,0.05f),
+ "Belly_Physics_Skirt_UpDown_Driven"));
+ }
+
+ if (!strcmp(morphName, "Small_Butt"))
+ {
+ mMorphData.insert(clone_morph_param_direction(morph_data,
+ LLVector3(0,0,0.05f),
+ "Butt_Physics_UpDown_Driven"));
+ }
+ if (!strcmp(morphName, "Small_Butt"))
+ {
+ mMorphData.insert(clone_morph_param_direction(morph_data,
+ LLVector3(0,0.03f,0),
+ "Butt_Physics_LeftRight_Driven"));
+ }
+ }
+
+ S32 numRemaps;
+ if (fread(&numRemaps, sizeof(S32), 1, fp) == 1)
+ {
+ llendianswizzle(&numRemaps, sizeof(S32), 1);
+ for (S32 i = 0; i < numRemaps; i++)
+ {
+ S32 remapSrc;
+ S32 remapDst;
+ if (fread(&remapSrc, sizeof(S32), 1, fp) != 1)
+ {
+ llerrs << "can't read source vertex in vertex remap data" << llendl;
+ break;
+ }
+ if (fread(&remapDst, sizeof(S32), 1, fp) != 1)
+ {
+ llerrs << "can't read destination vertex in vertex remap data" << llendl;
+ break;
+ }
+ llendianswizzle(&remapSrc, sizeof(S32), 1);
+ llendianswizzle(&remapDst, sizeof(S32), 1);
+
+ mSharedVerts[remapSrc] = remapDst;
+ }
+ }
+ }
+
+ status = TRUE;
+ }
+ else
+ {
+ llerrs << "invalid mesh file header: " << fileName << llendl;
+ status = FALSE;
+ }
+
+ if (0 == mNumJointNames)
+ {
+ allocateJointNames(1);
+ }
+
+ fclose( fp );
+
+ return status;
}
//-----------------------------------------------------------------------------
@@ -653,11 +715,11 @@ BOOL LLPolyMeshSharedData::loadMesh( const std::string& fileName )
//-----------------------------------------------------------------------------
const S32 *LLPolyMeshSharedData::getSharedVert(S32 vert)
{
- if (mSharedVerts.count(vert) > 0)
- {
- return &mSharedVerts[vert];
- }
- return NULL;
+ if (mSharedVerts.count(vert) > 0)
+ {
+ return &mSharedVerts[vert];
+ }
+ return NULL;
}
//-----------------------------------------------------------------------------
@@ -665,17 +727,17 @@ const S32 *LLPolyMeshSharedData::getSharedVert(S32 vert)
//-----------------------------------------------------------------------------
const LLVector2 &LLPolyMeshSharedData::getUVs(U32 index)
{
- // TODO: convert all index variables to S32
- llassert((S32)index < mNumVertices);
+ // TODO: convert all index variables to S32
+ llassert((S32)index < mNumVertices);
- return mTexCoords[index];
+ return mTexCoords[index];
}
//-----------------------------------------------------------------------------
// LLPolyMesh()
//-----------------------------------------------------------------------------
LLPolyMesh::LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_mesh)
-{
+{
LLMemType mt(LLMemType::MTYPE_AVATAR_MESH);
llassert(shared_data);
@@ -703,29 +765,23 @@ LLPolyMesh::LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_
}
else
{
-#if 1 // Allocate memory without initializing every vector
+ // Allocate memory without initializing every vector
// NOTE: This makes asusmptions about the size of LLVector[234]
int nverts = mSharedData->mNumVertices;
- int nfloats = nverts * (3*5 + 2 + 4);
- mVertexData = new F32[nfloats];
+ int nfloats = nverts * (2*4 + 3*3 + 2 + 4);
+ //use 16 byte aligned vertex data to make LLPolyMesh SSE friendly
+ mVertexData = (F32*) ll_aligned_malloc_16(nfloats*4);
int offset = 0;
- mCoords = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
- mNormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
- mScaledNormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
- mBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
- mScaledBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
- mTexCoords = (LLVector2*)(mVertexData + offset); offset += 2*nverts;
- mClothingWeights = (LLVector4*)(mVertexData + offset); offset += 4*nverts;
-#else
- mCoords = new LLVector3[mSharedData->mNumVertices];
- mNormals = new LLVector3[mSharedData->mNumVertices];
- mScaledNormals = new LLVector3[mSharedData->mNumVertices];
- mBinormals = new LLVector3[mSharedData->mNumVertices];
- mScaledBinormals = new LLVector3[mSharedData->mNumVertices];
- mTexCoords = new LLVector2[mSharedData->mNumVertices];
- mClothingWeights = new LLVector4[mSharedData->mNumVertices];
- memset(mClothingWeights, 0, sizeof(LLVector4) * mSharedData->mNumVertices);
-#endif
+ mCoords = (LLVector4*)(mVertexData + offset); offset += 4*nverts;
+ mNormals = (LLVector4*)(mVertexData + offset); offset += 4*nverts;
+ mClothingWeights = (LLVector4*)(mVertexData + offset); offset += 4*nverts;
+ mTexCoords = (LLVector2*)(mVertexData + offset); offset += 2*nverts;
+
+ // these members don't need to be 16-byte aligned, but the first one might be
+ // read during an aligned memcpy of mTexCoords
+ mScaledNormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
+ mBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
+ mScaledBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
initializeForMorph();
}
}
@@ -736,23 +792,15 @@ LLPolyMesh::LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_
//-----------------------------------------------------------------------------
LLPolyMesh::~LLPolyMesh()
{
- S32 i;
- for (i = 0; i < mJointRenderData.count(); i++)
- {
- delete mJointRenderData[i];
- mJointRenderData[i] = NULL;
- }
-#if 0 // These are now allocated as one big uninitialized chunk
- delete [] mCoords;
- delete [] mNormals;
- delete [] mScaledNormals;
- delete [] mBinormals;
- delete [] mScaledBinormals;
- delete [] mClothingWeights;
- delete [] mTexCoords;
-#else
- delete [] mVertexData;
-#endif
+ S32 i;
+ for (i = 0; i < mJointRenderData.count(); i++)
+ {
+ delete mJointRenderData[i];
+ mJointRenderData[i] = NULL;
+ }
+
+ ll_aligned_free_16(mVertexData);
+
}
@@ -761,40 +809,40 @@ LLPolyMesh::~LLPolyMesh()
//-----------------------------------------------------------------------------
LLPolyMesh *LLPolyMesh::getMesh(const std::string &name, LLPolyMesh* reference_mesh)
{
- //-------------------------------------------------------------------------
- // search for an existing mesh by this name
- //-------------------------------------------------------------------------
- LLPolyMeshSharedData* meshSharedData = get_if_there(sGlobalSharedMeshList, name, (LLPolyMeshSharedData*)NULL);
- if (meshSharedData)
- {
-// llinfos << "Polymesh " << name << " found in global mesh table." << llendl;
- LLPolyMesh *poly_mesh = new LLPolyMesh(meshSharedData, reference_mesh);
- return poly_mesh;
- }
-
- //-------------------------------------------------------------------------
- // if not found, create a new one, add it to the list
- //-------------------------------------------------------------------------
- std::string full_path;
- full_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,name);
-
- LLPolyMeshSharedData *mesh_data = new LLPolyMeshSharedData();
- if (reference_mesh)
- {
- mesh_data->setupLOD(reference_mesh->getSharedData());
- }
- if ( ! mesh_data->loadMesh( full_path ) )
- {
- delete mesh_data;
- return NULL;
- }
-
- LLPolyMesh *poly_mesh = new LLPolyMesh(mesh_data, reference_mesh);
-
-// llinfos << "Polymesh " << name << " added to global mesh table." << llendl;
- sGlobalSharedMeshList[name] = poly_mesh->mSharedData;
-
- return poly_mesh;
+ //-------------------------------------------------------------------------
+ // search for an existing mesh by this name
+ //-------------------------------------------------------------------------
+ LLPolyMeshSharedData* meshSharedData = get_if_there(sGlobalSharedMeshList, name, (LLPolyMeshSharedData*)NULL);
+ if (meshSharedData)
+ {
+// llinfos << "Polymesh " << name << " found in global mesh table." << llendl;
+ LLPolyMesh *poly_mesh = new LLPolyMesh(meshSharedData, reference_mesh);
+ return poly_mesh;
+ }
+
+ //-------------------------------------------------------------------------
+ // if not found, create a new one, add it to the list
+ //-------------------------------------------------------------------------
+ std::string full_path;
+ full_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,name);
+
+ LLPolyMeshSharedData *mesh_data = new LLPolyMeshSharedData();
+ if (reference_mesh)
+ {
+ mesh_data->setupLOD(reference_mesh->getSharedData());
+ }
+ if ( ! mesh_data->loadMesh( full_path ) )
+ {
+ delete mesh_data;
+ return NULL;
+ }
+
+ LLPolyMesh *poly_mesh = new LLPolyMesh(mesh_data, reference_mesh);
+
+// llinfos << "Polymesh " << name << " added to global mesh table." << llendl;
+ sGlobalSharedMeshList[name] = poly_mesh->mSharedData;
+
+ return poly_mesh;
}
//-----------------------------------------------------------------------------
@@ -802,14 +850,14 @@ LLPolyMesh *LLPolyMesh::getMesh(const std::string &name, LLPolyMesh* reference_m
//-----------------------------------------------------------------------------
void LLPolyMesh::freeAllMeshes()
{
- // delete each item in the global lists
- for_each(sGlobalSharedMeshList.begin(), sGlobalSharedMeshList.end(), DeletePairedPointer());
- sGlobalSharedMeshList.clear();
+ // delete each item in the global lists
+ for_each(sGlobalSharedMeshList.begin(), sGlobalSharedMeshList.end(), DeletePairedPointer());
+ sGlobalSharedMeshList.clear();
}
LLPolyMeshSharedData *LLPolyMesh::getSharedData() const
{
- return mSharedData;
+ return mSharedData;
}
@@ -818,57 +866,57 @@ LLPolyMeshSharedData *LLPolyMesh::getSharedData() const
//--------------------------------------------------------------------
void LLPolyMesh::dumpDiagInfo()
{
- // keep track of totals
- U32 total_verts = 0;
- U32 total_faces = 0;
- U32 total_kb = 0;
-
- std::string buf;
-
- llinfos << "-----------------------------------------------------" << llendl;
- llinfos << " Global PolyMesh Table (DEBUG only)" << llendl;
- llinfos << " Verts Faces Mem(KB) Name" << llendl;
- llinfos << "-----------------------------------------------------" << llendl;
-
- // print each loaded mesh, and it's memory usage
- for(LLPolyMeshSharedDataTable::iterator iter = sGlobalSharedMeshList.begin();
- iter != sGlobalSharedMeshList.end(); ++iter)
- {
- const std::string& mesh_name = iter->first;
- LLPolyMeshSharedData* mesh = iter->second;
-
- S32 num_verts = mesh->mNumVertices;
- S32 num_faces = mesh->mNumFaces;
- U32 num_kb = mesh->getNumKB();
-
- buf = llformat("%8d %8d %8d %s", num_verts, num_faces, num_kb, mesh_name.c_str());
- llinfos << buf << llendl;
-
- total_verts += num_verts;
- total_faces += num_faces;
- total_kb += num_kb;
- }
-
- llinfos << "-----------------------------------------------------" << llendl;
- buf = llformat("%8d %8d %8d TOTAL", total_verts, total_faces, total_kb );
- llinfos << buf << llendl;
- llinfos << "-----------------------------------------------------" << llendl;
+ // keep track of totals
+ U32 total_verts = 0;
+ U32 total_faces = 0;
+ U32 total_kb = 0;
+
+ std::string buf;
+
+ llinfos << "-----------------------------------------------------" << llendl;
+ llinfos << " Global PolyMesh Table (DEBUG only)" << llendl;
+ llinfos << " Verts Faces Mem(KB) Name" << llendl;
+ llinfos << "-----------------------------------------------------" << llendl;
+
+ // print each loaded mesh, and it's memory usage
+ for(LLPolyMeshSharedDataTable::iterator iter = sGlobalSharedMeshList.begin();
+ iter != sGlobalSharedMeshList.end(); ++iter)
+ {
+ const std::string& mesh_name = iter->first;
+ LLPolyMeshSharedData* mesh = iter->second;
+
+ S32 num_verts = mesh->mNumVertices;
+ S32 num_faces = mesh->mNumFaces;
+ U32 num_kb = mesh->getNumKB();
+
+ buf = llformat("%8d %8d %8d %s", num_verts, num_faces, num_kb, mesh_name.c_str());
+ llinfos << buf << llendl;
+
+ total_verts += num_verts;
+ total_faces += num_faces;
+ total_kb += num_kb;
+ }
+
+ llinfos << "-----------------------------------------------------" << llendl;
+ buf = llformat("%8d %8d %8d TOTAL", total_verts, total_faces, total_kb );
+ llinfos << buf << llendl;
+ llinfos << "-----------------------------------------------------" << llendl;
}
//-----------------------------------------------------------------------------
// getWritableCoords()
//-----------------------------------------------------------------------------
-LLVector3 *LLPolyMesh::getWritableCoords()
+LLVector4 *LLPolyMesh::getWritableCoords()
{
- return mCoords;
+ return mCoords;
}
//-----------------------------------------------------------------------------
// getWritableNormals()
//-----------------------------------------------------------------------------
-LLVector3 *LLPolyMesh::getWritableNormals()
+LLVector4 *LLPolyMesh::getWritableNormals()
{
- return mNormals;
+ return mNormals;
}
//-----------------------------------------------------------------------------
@@ -876,24 +924,24 @@ LLVector3 *LLPolyMesh::getWritableNormals()
//-----------------------------------------------------------------------------
LLVector3 *LLPolyMesh::getWritableBinormals()
{
- return mBinormals;
+ return mBinormals;
}
//-----------------------------------------------------------------------------
// getWritableClothingWeights()
//-----------------------------------------------------------------------------
-LLVector4 *LLPolyMesh::getWritableClothingWeights()
+LLVector4 *LLPolyMesh::getWritableClothingWeights()
{
- return mClothingWeights;
+ return mClothingWeights;
}
//-----------------------------------------------------------------------------
// getWritableTexCoords()
//-----------------------------------------------------------------------------
-LLVector2 *LLPolyMesh::getWritableTexCoords()
+LLVector2 *LLPolyMesh::getWritableTexCoords()
{
- return mTexCoords;
+ return mTexCoords;
}
//-----------------------------------------------------------------------------
@@ -901,7 +949,7 @@ LLVector2 *LLPolyMesh::getWritableTexCoords()
//-----------------------------------------------------------------------------
LLVector3 *LLPolyMesh::getScaledNormals()
{
- return mScaledNormals;
+ return mScaledNormals;
}
//-----------------------------------------------------------------------------
@@ -909,7 +957,7 @@ LLVector3 *LLPolyMesh::getScaledNormals()
//-----------------------------------------------------------------------------
LLVector3 *LLPolyMesh::getScaledBinormals()
{
- return mScaledBinormals;
+ return mScaledBinormals;
}
@@ -918,11 +966,12 @@ LLVector3 *LLPolyMesh::getScaledBinormals()
//-----------------------------------------------------------------------------
void LLPolyMesh::initializeForMorph()
{
- if (!mSharedData)
- return;
+ for (U32 i = 0; i < mSharedData->mNumVertices; ++i)
+ {
+ mCoords[i] = LLVector4(mSharedData->mBaseCoords[i]);
+ mNormals[i] = LLVector4(mSharedData->mBaseNormals[i]);
+ }
- memcpy(mCoords, mSharedData->mBaseCoords, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
- memcpy(mNormals, mSharedData->mBaseNormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
memcpy(mScaledNormals, mSharedData->mBaseNormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
memcpy(mBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
memcpy(mScaledBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
@@ -933,51 +982,51 @@ void LLPolyMesh::initializeForMorph()
//-----------------------------------------------------------------------------
// getMorphData()
//-----------------------------------------------------------------------------
-LLPolyMorphData* LLPolyMesh::getMorphData(const std::string& morph_name)
+LLPolyMorphData* LLPolyMesh::getMorphData(const std::string& morph_name)
{
- if (!mSharedData)
- return NULL;
- for (LLPolyMeshSharedData::morphdata_list_t::iterator iter = mSharedData->mMorphData.begin();
- iter != mSharedData->mMorphData.end(); ++iter)
- {
- LLPolyMorphData *morph_data = *iter;
- if (morph_data->getName() == morph_name)
- {
- return morph_data;
- }
- }
- return NULL;
+ if (!mSharedData)
+ return NULL;
+ for (LLPolyMeshSharedData::morphdata_list_t::iterator iter = mSharedData->mMorphData.begin();
+ iter != mSharedData->mMorphData.end(); ++iter)
+ {
+ LLPolyMorphData *morph_data = *iter;
+ if (morph_data->getName() == morph_name)
+ {
+ return morph_data;
+ }
+ }
+ return NULL;
}
//-----------------------------------------------------------------------------
// removeMorphData()
//-----------------------------------------------------------------------------
// // erasing but not deleting seems bad, but fortunately we don't actually use this...
-// void LLPolyMesh::removeMorphData(LLPolyMorphData *morph_target)
+// void LLPolyMesh::removeMorphData(LLPolyMorphData *morph_target)
// {
-// if (!mSharedData)
-// return;
-// mSharedData->mMorphData.erase(morph_target);
+// if (!mSharedData)
+// return;
+// mSharedData->mMorphData.erase(morph_target);
// }
//-----------------------------------------------------------------------------
// deleteAllMorphData()
//-----------------------------------------------------------------------------
-// void LLPolyMesh::deleteAllMorphData()
+// void LLPolyMesh::deleteAllMorphData()
// {
-// if (!mSharedData)
-// return;
+// if (!mSharedData)
+// return;
-// for_each(mSharedData->mMorphData.begin(), mSharedData->mMorphData.end(), DeletePointer());
-// mSharedData->mMorphData.clear();
+// for_each(mSharedData->mMorphData.begin(), mSharedData->mMorphData.end(), DeletePointer());
+// mSharedData->mMorphData.clear();
// }
//-----------------------------------------------------------------------------
// getWritableWeights()
//-----------------------------------------------------------------------------
-F32* LLPolyMesh::getWritableWeights() const
+F32* LLPolyMesh::getWritableWeights() const
{
- return mSharedData->mWeights;
+ return mSharedData->mWeights;
}
//-----------------------------------------------------------------------------
@@ -989,58 +1038,58 @@ LLPolySkeletalDistortionInfo::LLPolySkeletalDistortionInfo()
BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node)
{
- llassert( node->hasName( "param" ) && node->getChildByName( "param_skeleton" ) );
-
- if (!LLViewerVisualParamInfo::parseXml(node))
- return FALSE;
-
- LLXmlTreeNode* skeletalParam = node->getChildByName("param_skeleton");
-
- if (NULL == skeletalParam)
- {
- llwarns << "Failed to getChildByName(\"param_skeleton\")"
- << llendl;
- return FALSE;
- }
-
- for( LLXmlTreeNode* bone = skeletalParam->getFirstChild(); bone; bone = skeletalParam->getNextChild() )
- {
- if (bone->hasName("bone"))
- {
- std::string name;
- LLVector3 scale;
- LLVector3 pos;
- BOOL haspos = FALSE;
-
- static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
- if (!bone->getFastAttributeString(name_string, name))
- {
- llwarns << "No bone name specified for skeletal param." << llendl;
- continue;
- }
-
- static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
- if (!bone->getFastAttributeVector3(scale_string, scale))
- {
- llwarns << "No scale specified for bone " << name << "." << llendl;
- continue;
- }
-
- // optional offset deformation (translation)
- static LLStdStringHandle offset_string = LLXmlTree::addAttributeString("offset");
- if (bone->getFastAttributeVector3(offset_string, pos))
- {
- haspos = TRUE;
- }
- mBoneInfoList.push_back(LLPolySkeletalBoneInfo(name, scale, pos, haspos));
- }
- else
- {
- llwarns << "Unrecognized element " << bone->getName() << " in skeletal distortion" << llendl;
- continue;
- }
- }
- return TRUE;
+ llassert( node->hasName( "param" ) && node->getChildByName( "param_skeleton" ) );
+
+ if (!LLViewerVisualParamInfo::parseXml(node))
+ return FALSE;
+
+ LLXmlTreeNode* skeletalParam = node->getChildByName("param_skeleton");
+
+ if (NULL == skeletalParam)
+ {
+ llwarns << "Failed to getChildByName(\"param_skeleton\")"
+ << llendl;
+ return FALSE;
+ }
+
+ for( LLXmlTreeNode* bone = skeletalParam->getFirstChild(); bone; bone = skeletalParam->getNextChild() )
+ {
+ if (bone->hasName("bone"))
+ {
+ std::string name;
+ LLVector3 scale;
+ LLVector3 pos;
+ BOOL haspos = FALSE;
+
+ static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+ if (!bone->getFastAttributeString(name_string, name))
+ {
+ llwarns << "No bone name specified for skeletal param." << llendl;
+ continue;
+ }
+
+ static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
+ if (!bone->getFastAttributeVector3(scale_string, scale))
+ {
+ llwarns << "No scale specified for bone " << name << "." << llendl;
+ continue;
+ }
+
+ // optional offset deformation (translation)
+ static LLStdStringHandle offset_string = LLXmlTree::addAttributeString("offset");
+ if (bone->getFastAttributeVector3(offset_string, pos))
+ {
+ haspos = TRUE;
+ }
+ mBoneInfoList.push_back(LLPolySkeletalBoneInfo(name, scale, pos, haspos));
+ }
+ else
+ {
+ llwarns << "Unrecognized element " << bone->getName() << " in skeletal distortion" << llendl;
+ continue;
+ }
+ }
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -1048,8 +1097,8 @@ BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node)
//-----------------------------------------------------------------------------
LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLVOAvatar *avatarp)
{
- mAvatar = avatarp;
- mDefaultVec.setVec(0.001f, 0.001f, 0.001f);
+ mAvatar = avatarp;
+ mDefaultVec.setVec(0.001f, 0.001f, 0.001f);
}
//-----------------------------------------------------------------------------
@@ -1061,62 +1110,62 @@ LLPolySkeletalDistortion::~LLPolySkeletalDistortion()
BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)
{
- llassert(mInfo == NULL);
- if (info->mID < 0)
- return FALSE;
- mInfo = info;
- mID = info->mID;
- setWeight(getDefaultWeight(), FALSE );
-
- LLPolySkeletalDistortionInfo::bone_info_list_t::iterator iter;
- for (iter = getInfo()->mBoneInfoList.begin(); iter != getInfo()->mBoneInfoList.end(); iter++)
- {
- LLPolySkeletalBoneInfo *bone_info = &(*iter);
- LLJoint* joint = mAvatar->getJoint(bone_info->mBoneName);
- if (!joint)
- {
- llwarns << "Joint " << bone_info->mBoneName << " not found." << llendl;
- continue;
- }
-
- if (mJointScales.find(joint) != mJointScales.end())
- {
- llwarns << "Scale deformation already supplied for joint " << joint->getName() << "." << llendl;
- }
-
- // store it
- mJointScales[joint] = bone_info->mScaleDeformation;
-
- // apply to children that need to inherit it
- for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin();
- iter != joint->mChildren.end(); ++iter)
- {
- LLViewerJoint* child_joint = (LLViewerJoint*)(*iter);
- if (child_joint->inheritScale())
- {
- LLVector3 childDeformation = LLVector3(child_joint->getScale());
- childDeformation.scaleVec(bone_info->mScaleDeformation);
- mJointScales[child_joint] = childDeformation;
- }
- }
-
- if (bone_info->mHasPositionDeformation)
- {
- if (mJointOffsets.find(joint) != mJointOffsets.end())
- {
- llwarns << "Offset deformation already supplied for joint " << joint->getName() << "." << llendl;
- }
- mJointOffsets[joint] = bone_info->mPositionDeformation;
- }
- }
- return TRUE;
+ llassert(mInfo == NULL);
+ if (info->mID < 0)
+ return FALSE;
+ mInfo = info;
+ mID = info->mID;
+ setWeight(getDefaultWeight(), FALSE );
+
+ LLPolySkeletalDistortionInfo::bone_info_list_t::iterator iter;
+ for (iter = getInfo()->mBoneInfoList.begin(); iter != getInfo()->mBoneInfoList.end(); iter++)
+ {
+ LLPolySkeletalBoneInfo *bone_info = &(*iter);
+ LLJoint* joint = mAvatar->getJoint(bone_info->mBoneName);
+ if (!joint)
+ {
+ llwarns << "Joint " << bone_info->mBoneName << " not found." << llendl;
+ continue;
+ }
+
+ if (mJointScales.find(joint) != mJointScales.end())
+ {
+ llwarns << "Scale deformation already supplied for joint " << joint->getName() << "." << llendl;
+ }
+
+ // store it
+ mJointScales[joint] = bone_info->mScaleDeformation;
+
+ // apply to children that need to inherit it
+ for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin();
+ iter != joint->mChildren.end(); ++iter)
+ {
+ LLViewerJoint* child_joint = (LLViewerJoint*)(*iter);
+ if (child_joint->inheritScale())
+ {
+ LLVector3 childDeformation = LLVector3(child_joint->getScale());
+ childDeformation.scaleVec(bone_info->mScaleDeformation);
+ mJointScales[child_joint] = childDeformation;
+ }
+ }
+
+ if (bone_info->mHasPositionDeformation)
+ {
+ if (mJointOffsets.find(joint) != mJointOffsets.end())
+ {
+ llwarns << "Offset deformation already supplied for joint " << joint->getName() << "." << llendl;
+ }
+ mJointOffsets[joint] = bone_info->mPositionDeformation;
+ }
+ }
+ return TRUE;
}
/*virtual*/ LLViewerVisualParam* LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const
{
- LLPolySkeletalDistortion *new_param = new LLPolySkeletalDistortion(mAvatar);
- *new_param = *this;
- return new_param;
+ LLPolySkeletalDistortion *new_param = new LLPolySkeletalDistortion(mAvatar);
+ *new_param = *this;
+ return new_param;
}
//-----------------------------------------------------------------------------
@@ -1124,38 +1173,89 @@ BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)
//-----------------------------------------------------------------------------
void LLPolySkeletalDistortion::apply( ESex avatar_sex )
{
- F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight();
+ F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight();
+
+ LLJoint* joint;
+ joint_vec_map_t::iterator iter;
+
+ for (iter = mJointScales.begin();
+ iter != mJointScales.end();
+ iter++)
+ {
+ joint = iter->first;
+ LLVector3 newScale = joint->getScale();
+ LLVector3 scaleDelta = iter->second;
+ newScale = newScale + (effective_weight * scaleDelta) - (mLastWeight * scaleDelta);
+ joint->setScale(newScale);
+ }
+
+ for (iter = mJointOffsets.begin();
+ iter != mJointOffsets.end();
+ iter++)
+ {
+ joint = iter->first;
+ LLVector3 newPosition = joint->getPosition();
+ LLVector3 positionDelta = iter->second;
+ newPosition = newPosition + (effective_weight * positionDelta) - (mLastWeight * positionDelta);
+ joint->setPosition(newPosition);
+ }
+
+ if (mLastWeight != mCurWeight && !mIsAnimating)
+ {
+ mAvatar->setSkeletonSerialNum(mAvatar->getSkeletonSerialNum() + 1);
+ }
+ mLastWeight = mCurWeight;
+}
- LLJoint* joint;
- joint_vec_map_t::iterator iter;
- for (iter = mJointScales.begin();
- iter != mJointScales.end();
- iter++)
- {
- joint = iter->first;
- LLVector3 newScale = joint->getScale();
- LLVector3 scaleDelta = iter->second;
- newScale = newScale + (effective_weight * scaleDelta) - (mLastWeight * scaleDelta);
- joint->setScale(newScale);
- }
+LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data,
+ const std::string &name)
+{
+ LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
+ cloned_morph_data->mName = name;
+ for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
+ {
+ cloned_morph_data->mCoords[v] = src_data->mCoords[v];
+ cloned_morph_data->mNormals[v] = src_data->mNormals[v];
+ cloned_morph_data->mBinormals[v] = src_data->mBinormals[v];
+ }
+ return cloned_morph_data;
+}
- for (iter = mJointOffsets.begin();
- iter != mJointOffsets.end();
- iter++)
- {
- joint = iter->first;
- LLVector3 newPosition = joint->getPosition();
- LLVector3 positionDelta = iter->second;
- newPosition = newPosition + (effective_weight * positionDelta) - (mLastWeight * positionDelta);
- joint->setPosition(newPosition);
- }
+LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data,
+ const LLVector3 &direction,
+ const std::string &name)
+{
+ LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
+ cloned_morph_data->mName = name;
+ for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
+ {
+ cloned_morph_data->mCoords[v] = direction;
+ cloned_morph_data->mNormals[v] = LLVector3(0,0,0);
+ cloned_morph_data->mBinormals[v] = LLVector3(0,0,0);
+ }
+ return cloned_morph_data;
+}
- if (mLastWeight != mCurWeight && !mIsAnimating)
- {
- mAvatar->setSkeletonSerialNum(mAvatar->getSkeletonSerialNum() + 1);
- }
- mLastWeight = mCurWeight;
+LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data,
+ F32 scale,
+ const std::string &name)
+{
+ LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
+ cloned_morph_data->mName = name;
+ for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
+ {
+ cloned_morph_data->mCoords[v] = src_data->mCoords[v]*scale;
+ cloned_morph_data->mNormals[v] = src_data->mNormals[v]*scale;
+ cloned_morph_data->mBinormals[v] = src_data->mBinormals[v]*scale;
+ if (cloned_morph_data->mCoords[v][1] < 0)
+ {
+ cloned_morph_data->mCoords[v][1] *= -1;
+ cloned_morph_data->mNormals[v][1] *= -1;
+ cloned_morph_data->mBinormals[v][1] *= -1;
+ }
+ }
+ return cloned_morph_data;
}
// End