llpolymesh.cpp

Go to the documentation of this file.
00001 
00032 //-----------------------------------------------------------------------------
00033 // Header Files
00034 //-----------------------------------------------------------------------------
00035 #include "llviewerprecompiledheaders.h"
00036 
00037 #include "llpolymesh.h"
00038 
00039 #include "llviewercontrol.h"
00040 #include "llxmltree.h"
00041 #include "llvoavatar.h"
00042 #include "lldir.h"
00043 #include "llvolume.h"
00044 #include "llendianswizzle.h"
00045 
00046 #include "llfasttimer.h"
00047 
00048 #define HEADER_ASCII "Linden Mesh 1.0"
00049 #define HEADER_BINARY "Linden Binary Mesh 1.0"
00050 
00051 extern LLControlGroup gSavedSettings;                           // read only
00052 
00053 //-----------------------------------------------------------------------------
00054 // Global table of loaded LLPolyMeshes
00055 //-----------------------------------------------------------------------------
00056 LLPolyMesh::LLPolyMeshSharedDataTable LLPolyMesh::sGlobalSharedMeshList;
00057 
00058 //-----------------------------------------------------------------------------
00059 // LLPolyMeshSharedData()
00060 //-----------------------------------------------------------------------------
00061 LLPolyMeshSharedData::LLPolyMeshSharedData()
00062 {
00063         mNumVertices = 0;
00064         mBaseCoords = NULL;
00065         mBaseNormals = NULL;
00066         mBaseBinormals = NULL;
00067         mTexCoords = NULL;
00068         mDetailTexCoords = NULL;
00069         mWeights = NULL;
00070         mHasWeights = FALSE;
00071         mHasDetailTexCoords = FALSE;
00072 
00073         mNumFaces = 0;
00074         mFaces = NULL;
00075 
00076         mNumJointNames = 0;
00077         mJointNames = NULL;
00078 
00079         mTriangleIndices = NULL;
00080         mNumTriangleIndices = 0;
00081 
00082         mReferenceData = NULL;
00083 
00084         mLastIndexOffset = -1;
00085 }
00086 
00087 //-----------------------------------------------------------------------------
00088 // ~LLPolyMeshSharedData()
00089 //-----------------------------------------------------------------------------
00090 LLPolyMeshSharedData::~LLPolyMeshSharedData()
00091 {
00092         freeMeshData();
00093         for_each(mMorphData.begin(), mMorphData.end(), DeletePointer());
00094         mMorphData.clear();
00095 }
00096 
00097 //-----------------------------------------------------------------------------
00098 // setupLOD()
00099 //-----------------------------------------------------------------------------
00100 void LLPolyMeshSharedData::setupLOD(LLPolyMeshSharedData* reference_data)
00101 {
00102         mReferenceData = reference_data;
00103 
00104         if (reference_data)
00105         {
00106                 mBaseCoords = reference_data->mBaseCoords;
00107                 mBaseNormals = reference_data->mBaseNormals;
00108                 mBaseBinormals = reference_data->mBaseBinormals;
00109                 mTexCoords = reference_data->mTexCoords;
00110                 mDetailTexCoords = reference_data->mDetailTexCoords;
00111                 mWeights = reference_data->mWeights;
00112                 mHasWeights = reference_data->mHasWeights;
00113                 mHasDetailTexCoords = reference_data->mHasDetailTexCoords;
00114         }
00115 }
00116 
00117 //-----------------------------------------------------------------------------
00118 // LLPolyMeshSharedData::freeMeshData()
00119 //-----------------------------------------------------------------------------
00120 void LLPolyMeshSharedData::freeMeshData()
00121 {
00122         if (!mReferenceData)
00123         {
00124                 mNumVertices = 0;
00125 
00126                 delete [] mBaseCoords;
00127                 mBaseCoords = NULL;
00128 
00129                 delete [] mBaseNormals;
00130                 mBaseNormals = NULL;
00131 
00132                 delete [] mBaseBinormals;
00133                 mBaseBinormals = NULL;
00134 
00135                 delete [] mTexCoords;
00136                 mTexCoords = NULL;
00137 
00138                 delete [] mDetailTexCoords;
00139                 mDetailTexCoords = NULL;
00140 
00141                 delete [] mWeights;
00142                 mWeights = NULL;
00143         }
00144 
00145         mNumFaces = 0;
00146         delete [] mFaces;
00147         mFaces = NULL;
00148 
00149         mNumJointNames = 0;
00150         delete [] mJointNames;
00151         mJointNames = NULL;
00152 
00153         delete [] mTriangleIndices;
00154         mTriangleIndices = NULL;
00155 
00156 //      mVertFaceMap.deleteAllData();
00157 }
00158 
00159 // compate_int is used by the qsort function to sort the index array
00160 int compare_int(const void *a, const void *b);
00161 
00162 //-----------------------------------------------------------------------------
00163 // genIndices()
00164 //-----------------------------------------------------------------------------
00165 void LLPolyMeshSharedData::genIndices(S32 index_offset)
00166 {
00167         if (index_offset == mLastIndexOffset)
00168         {
00169                 return;
00170         }
00171 
00172         delete []mTriangleIndices;
00173         mTriangleIndices = new U32[mNumTriangleIndices];
00174 
00175         S32 cur_index = 0;
00176         for (S32 i = 0; i < mNumFaces; i++)
00177         {
00178                 mTriangleIndices[cur_index] = mFaces[i][0] + index_offset;
00179                 cur_index++;
00180                 mTriangleIndices[cur_index] = mFaces[i][1] + index_offset;
00181                 cur_index++;
00182                 mTriangleIndices[cur_index] = mFaces[i][2] + index_offset;
00183                 cur_index++;
00184         }
00185 
00186         mLastIndexOffset = index_offset;
00187 }
00188 
00189 //--------------------------------------------------------------------
00190 // LLPolyMeshSharedData::getNumKB()
00191 //--------------------------------------------------------------------
00192 U32 LLPolyMeshSharedData::getNumKB()
00193 {
00194         U32 num_kb = sizeof(LLPolyMesh);
00195 
00196         if (!isLOD())
00197         {
00198                 num_kb += mNumVertices *
00199                                         ( sizeof(LLVector3) +   // coords
00200                                         sizeof(LLVector3) +             // normals
00201                                         sizeof(LLVector2) );    // texCoords
00202         }
00203 
00204         if (mHasDetailTexCoords && !isLOD())
00205         {
00206                 num_kb += mNumVertices * sizeof(LLVector2);     // detailTexCoords
00207         }
00208 
00209         if (mHasWeights && !isLOD())
00210         {
00211                 num_kb += mNumVertices * sizeof(float);         // weights
00212         }
00213 
00214         num_kb += mNumFaces * sizeof(LLPolyFace);       // faces
00215 
00216         num_kb /= 1024;
00217         return num_kb;
00218 }
00219 
00220 //-----------------------------------------------------------------------------
00221 // LLPolyMeshSharedData::allocateVertexData()
00222 //-----------------------------------------------------------------------------
00223 BOOL LLPolyMeshSharedData::allocateVertexData( U32 numVertices )
00224 {
00225         U32 i;
00226         mBaseCoords = new LLVector3[ numVertices ];
00227         mBaseNormals = new LLVector3[ numVertices ];
00228         mBaseBinormals = new LLVector3[ numVertices ];
00229         mTexCoords = new LLVector2[ numVertices ];
00230         mDetailTexCoords = new LLVector2[ numVertices ];
00231         mWeights = new F32[ numVertices ];
00232         for (i = 0; i < numVertices; i++)
00233         {
00234                 mWeights[i] = 0.f;
00235         }
00236         mNumVertices = numVertices;
00237         return TRUE;
00238 }
00239 
00240 //-----------------------------------------------------------------------------
00241 // LLPolyMeshSharedData::allocateFaceData()
00242 //-----------------------------------------------------------------------------
00243 BOOL LLPolyMeshSharedData::allocateFaceData( U32 numFaces )
00244 {
00245         mFaces = new LLPolyFace[ numFaces ];
00246         mNumFaces = numFaces;
00247         mNumTriangleIndices = mNumFaces * 3;
00248         return TRUE;
00249 }
00250 
00251 //-----------------------------------------------------------------------------
00252 // LLPolyMeshSharedData::allocateJointNames()
00253 //-----------------------------------------------------------------------------
00254 BOOL LLPolyMeshSharedData::allocateJointNames( U32 numJointNames )
00255 {
00256         mJointNames = new std::string[ numJointNames ];
00257         mNumJointNames = numJointNames;
00258         return TRUE;
00259 }
00260 
00261 //--------------------------------------------------------------------
00262 // LLPolyMeshSharedData::loadMesh()
00263 //--------------------------------------------------------------------
00264 BOOL LLPolyMeshSharedData::loadMesh( const char *fileName )
00265 {
00266         //-------------------------------------------------------------------------
00267         // Open the file
00268         //-------------------------------------------------------------------------
00269         if(!fileName)
00270         {
00271                 llerrs << "Filename is Empty!" << llendl;
00272                 return FALSE;
00273         }
00274         LLFILE* fp = LLFile::fopen(fileName, "rb");                     /*Flawfinder: ignore*/
00275         if (!fp)
00276         {
00277                 llerrs << "can't open: " << fileName << llendl;
00278                 return FALSE;
00279         }
00280 
00281         //-------------------------------------------------------------------------
00282         // Read a chunk
00283         //-------------------------------------------------------------------------
00284         char header[128];               /*Flawfinder: ignore*/
00285         if (fread(header, sizeof(char), 128, fp) != 128)
00286         {
00287                 llwarns << "Short read" << llendl;
00288         }
00289 
00290         //-------------------------------------------------------------------------
00291         // Check for proper binary header
00292         //-------------------------------------------------------------------------
00293         BOOL status = FALSE;
00294         if ( strncmp(header, HEADER_BINARY, strlen(HEADER_BINARY)) == 0 )       /*Flawfinder: ignore*/
00295         {
00296                 lldebugs << "Loading " << fileName << llendl;
00297 
00298                 //----------------------------------------------------------------
00299                 // File Header (seek past it)
00300                 //----------------------------------------------------------------
00301                 fseek(fp, 24, SEEK_SET);
00302 
00303                 //----------------------------------------------------------------
00304                 // HasWeights
00305                 //----------------------------------------------------------------
00306                 U8 hasWeights;
00307                 size_t numRead = fread(&hasWeights, sizeof(U8), 1, fp);
00308                 if (numRead != 1)
00309                 {
00310                         llerrs << "can't read HasWeights flag from " << fileName << llendl;
00311                         return FALSE;
00312                 }
00313                 if (!isLOD())
00314                 {
00315                         mHasWeights = (hasWeights==0) ? FALSE : TRUE;
00316                 }
00317 
00318                 //----------------------------------------------------------------
00319                 // HasDetailTexCoords
00320                 //----------------------------------------------------------------
00321                 U8 hasDetailTexCoords;
00322                 numRead = fread(&hasDetailTexCoords, sizeof(U8), 1, fp);
00323                 if (numRead != 1)
00324                 {
00325                         llerrs << "can't read HasDetailTexCoords flag from " << fileName << llendl;
00326                         return FALSE;
00327                 }
00328 
00329                 //----------------------------------------------------------------
00330                 // Position
00331                 //----------------------------------------------------------------
00332                 LLVector3 position;
00333                 numRead = fread(position.mV, sizeof(float), 3, fp);
00334                 llendianswizzle(position.mV, sizeof(float), 3);
00335                 if (numRead != 3)
00336                 {
00337                         llerrs << "can't read Position from " << fileName << llendl;
00338                         return FALSE;
00339                 }
00340                 setPosition( position );
00341 
00342                 //----------------------------------------------------------------
00343                 // Rotation
00344                 //----------------------------------------------------------------
00345                 LLVector3 rotationAngles;
00346                 numRead = fread(rotationAngles.mV, sizeof(float), 3, fp);
00347                 llendianswizzle(rotationAngles.mV, sizeof(float), 3);
00348                 if (numRead != 3)
00349                 {
00350                         llerrs << "can't read RotationAngles from " << fileName << llendl;
00351                         return FALSE;
00352                 }
00353 
00354                 U8 rotationOrder;
00355                 numRead = fread(&rotationOrder, sizeof(U8), 1, fp);
00356 
00357                 if (numRead != 1)
00358                 {
00359                         llerrs << "can't read RotationOrder from " << fileName << llendl;
00360                         return FALSE;
00361                 }
00362 
00363                 rotationOrder = 0;
00364 
00365                 setRotation( mayaQ(     rotationAngles.mV[0],
00366                                                         rotationAngles.mV[1],
00367                                                         rotationAngles.mV[2],
00368                                                         (LLQuaternion::Order)rotationOrder ) );
00369 
00370                 //----------------------------------------------------------------
00371                 // Scale
00372                 //----------------------------------------------------------------
00373                 LLVector3 scale;
00374                 numRead = fread(scale.mV, sizeof(float), 3, fp);
00375                 llendianswizzle(scale.mV, sizeof(float), 3);
00376                 if (numRead != 3)
00377                 {
00378                         llerrs << "can't read Scale from " << fileName << llendl;
00379                         return FALSE;
00380                 }
00381                 setScale( scale );
00382 
00383                 //-------------------------------------------------------------------------
00384                 // Release any existing mesh geometry
00385                 //-------------------------------------------------------------------------
00386                 freeMeshData();
00387 
00388                 U16 numVertices = 0;
00389 
00390                 //----------------------------------------------------------------
00391                 // NumVertices
00392                 //----------------------------------------------------------------
00393                 if (!isLOD())
00394                 {
00395                         numRead = fread(&numVertices, sizeof(U16), 1, fp);
00396                         llendianswizzle(&numVertices, sizeof(U16), 1);
00397                         if (numRead != 1)
00398                         {
00399                                 llerrs << "can't read NumVertices from " << fileName << llendl;
00400                                 return FALSE;
00401                         }
00402 
00403                         allocateVertexData( numVertices );      
00404 
00405                         //----------------------------------------------------------------
00406                         // Coords
00407                         //----------------------------------------------------------------
00408                         numRead = fread(mBaseCoords, 3*sizeof(float), numVertices, fp);
00409                         llendianswizzle(mBaseCoords, sizeof(float), 3*numVertices);
00410                         if (numRead != numVertices)
00411                         {
00412                                 llerrs << "can't read Coordinates from " << fileName << llendl;
00413                                 return FALSE;
00414                         }
00415 
00416                         //----------------------------------------------------------------
00417                         // Normals
00418                         //----------------------------------------------------------------
00419                         numRead = fread(mBaseNormals, 3*sizeof(float), numVertices, fp);
00420                         llendianswizzle(mBaseNormals, sizeof(float), 3*numVertices);
00421                         if (numRead != numVertices)
00422                         {
00423                                 llerrs << " can't read Normals from " << fileName << llendl;
00424                                 return FALSE;
00425                         }
00426 
00427                         //----------------------------------------------------------------
00428                         // Binormals
00429                         //----------------------------------------------------------------
00430                         numRead = fread(mBaseBinormals, 3*sizeof(float), numVertices, fp);
00431                         llendianswizzle(mBaseBinormals, sizeof(float), 3*numVertices);
00432                         if (numRead != numVertices)
00433                         {
00434                                 llerrs << " can't read Binormals from " << fileName << llendl;
00435                                 return FALSE;
00436                         }
00437 
00438 
00439                         //----------------------------------------------------------------
00440                         // TexCoords
00441                         //----------------------------------------------------------------
00442                         numRead = fread(mTexCoords, 2*sizeof(float), numVertices, fp);
00443                         llendianswizzle(mTexCoords, sizeof(float), 2*numVertices);
00444                         if (numRead != numVertices)
00445                         {
00446                                 llerrs << "can't read TexCoords from " << fileName << llendl;
00447                                 return FALSE;
00448                         }
00449 
00450                         //----------------------------------------------------------------
00451                         // DetailTexCoords
00452                         //----------------------------------------------------------------
00453                         if (mHasDetailTexCoords)
00454                         {
00455                                 numRead = fread(mDetailTexCoords, 2*sizeof(float), numVertices, fp);
00456                                 llendianswizzle(mDetailTexCoords, sizeof(float), 2*numVertices);
00457                                 if (numRead != numVertices)
00458                                 {
00459                                         llerrs << "can't read DetailTexCoords from " << fileName << llendl;
00460                                         return FALSE;
00461                                 }
00462                         }
00463 
00464                         //----------------------------------------------------------------
00465                         // Weights
00466                         //----------------------------------------------------------------
00467                         if (mHasWeights)
00468                         {
00469                                 numRead = fread(mWeights, sizeof(float), numVertices, fp);
00470                                 llendianswizzle(mWeights, sizeof(float), numVertices);
00471                                 if (numRead != numVertices)
00472                                 {
00473                                         llerrs << "can't read Weights from " << fileName << llendl;
00474                                         return FALSE;
00475                                 }
00476                         }
00477                 }
00478 
00479                 //----------------------------------------------------------------
00480                 // NumFaces
00481                 //----------------------------------------------------------------
00482                 U16 numFaces;
00483                 numRead = fread(&numFaces, sizeof(U16), 1, fp);
00484                 llendianswizzle(&numFaces, sizeof(U16), 1);
00485                 if (numRead != 1)
00486                 {
00487                         llerrs << "can't read NumFaces from " << fileName << llendl;
00488                         return FALSE;
00489                 }
00490                 allocateFaceData( numFaces );
00491 
00492 
00493                 //----------------------------------------------------------------
00494                 // Faces
00495                 //----------------------------------------------------------------
00496                 U32 i;
00497                 U32 numTris = 0;
00498                 for (i = 0; i < numFaces; i++)
00499                 {
00500                         S16 face[3];
00501                         numRead = fread(face, sizeof(U16), 3, fp);
00502                         llendianswizzle(face, sizeof(U16), 3);
00503                         if (numRead != 3)
00504                         {
00505                                 llerrs << "can't read Face[" << i << "] from " << fileName << llendl;
00506                                 return FALSE;
00507                         }
00508                         if (mReferenceData)
00509                         {
00510                                 llassert(face[0] < mReferenceData->mNumVertices);
00511                                 llassert(face[1] < mReferenceData->mNumVertices);
00512                                 llassert(face[2] < mReferenceData->mNumVertices);
00513                         }
00514                         
00515                         if (isLOD())
00516                         {
00517                                 // store largest index in case of LODs
00518                                 for (S32 j = 0; j < 3; j++)
00519                                 {
00520                                         if (face[j] > mNumVertices - 1)
00521                                         {
00522                                                 mNumVertices = face[j] + 1;
00523                                         }
00524                                 }
00525                         }
00526                         mFaces[i][0] = face[0];
00527                         mFaces[i][1] = face[1];
00528                         mFaces[i][2] = face[2];
00529 
00530 //                      S32 j;
00531 //                      for(j = 0; j < 3; j++)
00532 //                      {
00533 //                              LLDynamicArray<S32> *face_list = mVertFaceMap.getIfThere(face[j]);
00534 //                              if (!face_list)
00535 //                              {
00536 //                                      face_list = new LLDynamicArray<S32>;
00537 //                                      mVertFaceMap.addData(face[j], face_list);
00538 //                              }
00539 //                              face_list->put(i);
00540 //                      }
00541 
00542                         numTris++;
00543                 }
00544 
00545                 lldebugs << "verts: " << numVertices 
00546                         << ", faces: "   << numFaces
00547                         << ", tris: "    << numTris
00548                         << llendl;
00549 
00550                 //----------------------------------------------------------------
00551                 // NumSkinJoints
00552                 //----------------------------------------------------------------
00553                 if (!isLOD())
00554                 {
00555                         U16 numSkinJoints = 0;
00556                         if ( mHasWeights )
00557                         {
00558                                 numRead = fread(&numSkinJoints, sizeof(U16), 1, fp);
00559                                 llendianswizzle(&numSkinJoints, sizeof(U16), 1);
00560                                 if (numRead != 1)
00561                                 {
00562                                         llerrs << "can't read NumSkinJoints from " << fileName << llendl;
00563                                         return FALSE;
00564                                 }
00565                                 allocateJointNames( numSkinJoints );
00566                         }
00567 
00568                         //----------------------------------------------------------------
00569                         // SkinJoints
00570                         //----------------------------------------------------------------
00571                         for (i=0; i < numSkinJoints; i++)
00572                         {
00573                                 char jointName[64+1];
00574                                 numRead = fread(jointName, sizeof(jointName)-1, 1, fp);
00575                                 jointName[sizeof(jointName)-1] = '\0'; // ensure nul-termination
00576                                 if (numRead != 1)
00577                                 {
00578                                         llerrs << "can't read Skin[" << i << "].Name from " << fileName << llendl;
00579                                         return FALSE;
00580                                 }
00581 
00582                                 std::string *jn = &mJointNames[i];
00583                                 *jn = jointName;
00584                         }
00585 
00586                         //-------------------------------------------------------------------------
00587                         // look for morph section
00588                         //-------------------------------------------------------------------------
00589                         char morphName[64+1];
00590                         morphName[sizeof(morphName)-1] = '\0'; // ensure nul-termination
00591                         while(fread(&morphName, sizeof(char), 64, fp) == 64)
00592                         {
00593                                 if (!strcmp(morphName, "End Morphs"))
00594                                 {
00595                                         // we reached the end of the morphs
00596                                         break;
00597                                 }
00598                                 LLPolyMorphData* morph_data = new LLPolyMorphData(morphName);
00599 
00600                                 BOOL result = morph_data->loadBinary(fp, this);
00601 
00602                                 if (!result)
00603                                 {
00604                                         delete morph_data;
00605                                         continue;
00606                                 }
00607 
00608                                 mMorphData.insert(morph_data);
00609                         }
00610 
00611                         S32 numRemaps;
00612                         if (fread(&numRemaps, sizeof(S32), 1, fp) == 1)
00613                         {
00614                                 llendianswizzle(&numRemaps, sizeof(S32), 1);
00615                                 for (S32 i = 0; i < numRemaps; i++)
00616                                 {
00617                                         S32 remapSrc;
00618                                         S32 remapDst;
00619                                         if (fread(&remapSrc, sizeof(S32), 1, fp) != 1)
00620                                         {
00621                                                 llerrs << "can't read source vertex in vertex remap data" << llendl;
00622                                                 break;
00623                                         }
00624                                         if (fread(&remapDst, sizeof(S32), 1, fp) != 1)
00625                                         {
00626                                                 llerrs << "can't read destination vertex in vertex remap data" << llendl;
00627                                                 break;
00628                                         }
00629                                         llendianswizzle(&remapSrc, sizeof(S32), 1);
00630                                         llendianswizzle(&remapDst, sizeof(S32), 1);
00631 
00632                                         mSharedVerts[remapSrc] = remapDst;
00633                                 }
00634                         }
00635                 }
00636 
00637                 status = TRUE;
00638         }
00639         else
00640         {
00641                 llerrs << "invalid mesh file header: " << fileName << llendl;
00642                 status = FALSE;
00643         }
00644 
00645         if (0 == mNumJointNames)
00646         {
00647                 allocateJointNames(1);
00648         }
00649 
00650         fclose( fp );
00651 
00652         return status;
00653 }
00654 
00655 //-----------------------------------------------------------------------------
00656 // getSharedVert()
00657 //-----------------------------------------------------------------------------
00658 const S32 *LLPolyMeshSharedData::getSharedVert(S32 vert)
00659 {
00660         if (mSharedVerts.count(vert) > 0)
00661         {
00662                 return &mSharedVerts[vert];
00663         }
00664         return NULL;
00665 }
00666 
00667 //-----------------------------------------------------------------------------
00668 // getUV()
00669 //-----------------------------------------------------------------------------
00670 const LLVector2 &LLPolyMeshSharedData::getUVs(U32 index)
00671 {
00672         // TODO: convert all index variables to S32
00673         llassert((S32)index < mNumVertices);
00674 
00675         return mTexCoords[index];
00676 }
00677 
00678 //-----------------------------------------------------------------------------
00679 // LLPolyMesh()
00680 //-----------------------------------------------------------------------------
00681 LLPolyMesh::LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_mesh)
00682 {
00683         llassert(shared_data);
00684 
00685         mSharedData = shared_data;
00686         mReferenceMesh = reference_mesh;
00687         mAvatarp = NULL;
00688         mVertexData = NULL;
00689 
00690         if (shared_data->isLOD() && reference_mesh)
00691         {
00692                 mCoords = reference_mesh->mCoords;
00693                 mNormals = reference_mesh->mNormals;
00694                 mScaledNormals = reference_mesh->mScaledNormals;
00695                 mBinormals = reference_mesh->mBinormals;
00696                 mScaledBinormals = reference_mesh->mScaledBinormals;
00697                 mTexCoords = reference_mesh->mTexCoords;
00698                 mClothingWeights = reference_mesh->mClothingWeights;
00699         }
00700         else
00701         {
00702 #if 1   // Allocate memory without initializing every vector
00703                 // NOTE: This makes asusmptions about the size of LLVector[234]
00704                 int nverts = mSharedData->mNumVertices;
00705                 int nfloats = nverts * (3*5 + 2 + 4);
00706                 mVertexData = new F32[nfloats];
00707                 int offset = 0;
00708                 mCoords =                               (LLVector3*)(mVertexData + offset); offset += 3*nverts;
00709                 mNormals =                              (LLVector3*)(mVertexData + offset); offset += 3*nverts;
00710                 mScaledNormals =                (LLVector3*)(mVertexData + offset); offset += 3*nverts;
00711                 mBinormals =                    (LLVector3*)(mVertexData + offset); offset += 3*nverts;
00712                 mScaledBinormals =              (LLVector3*)(mVertexData + offset); offset += 3*nverts;
00713                 mTexCoords =                    (LLVector2*)(mVertexData + offset); offset += 2*nverts;
00714                 mClothingWeights =      (LLVector4*)(mVertexData + offset); offset += 4*nverts;
00715 #else
00716                 mCoords = new LLVector3[mSharedData->mNumVertices];
00717                 mNormals = new LLVector3[mSharedData->mNumVertices];
00718                 mScaledNormals = new LLVector3[mSharedData->mNumVertices];
00719                 mBinormals = new LLVector3[mSharedData->mNumVertices];
00720                 mScaledBinormals = new LLVector3[mSharedData->mNumVertices];
00721                 mTexCoords = new LLVector2[mSharedData->mNumVertices];
00722                 mClothingWeights = new LLVector4[mSharedData->mNumVertices];
00723                 memset(mClothingWeights, 0, sizeof(LLVector4) * mSharedData->mNumVertices);
00724 #endif
00725                 initializeForMorph();
00726         }
00727 }
00728 
00729 
00730 //-----------------------------------------------------------------------------
00731 // ~LLPolyMesh()
00732 //-----------------------------------------------------------------------------
00733 LLPolyMesh::~LLPolyMesh()
00734 {
00735         S32 i;
00736         for (i = 0; i < mJointRenderData.count(); i++)
00737         {
00738                 delete mJointRenderData[i];
00739                 mJointRenderData[i] = NULL;
00740         }
00741 #if 0 // These are now allocated as one big uninitialized chunk
00742         delete [] mCoords;
00743         delete [] mNormals;
00744         delete [] mScaledNormals;
00745         delete [] mBinormals;
00746         delete [] mScaledBinormals;
00747         delete [] mClothingWeights;
00748         delete [] mTexCoords;
00749 #else
00750         delete [] mVertexData;
00751 #endif
00752 }
00753 
00754 
00755 //-----------------------------------------------------------------------------
00756 // LLPolyMesh::getMesh()
00757 //-----------------------------------------------------------------------------
00758 LLPolyMesh *LLPolyMesh::getMesh(const LLString &name, LLPolyMesh* reference_mesh)
00759 {
00760         //-------------------------------------------------------------------------
00761         // search for an existing mesh by this name
00762         //-------------------------------------------------------------------------
00763         LLPolyMeshSharedData* meshSharedData = get_if_there(sGlobalSharedMeshList, name, (LLPolyMeshSharedData*)NULL);
00764         if (meshSharedData)
00765         {
00766 //              llinfos << "Polymesh " << name << " found in global mesh table." << llendl;
00767                 LLPolyMesh *poly_mesh = new LLPolyMesh(meshSharedData, reference_mesh);
00768                 return poly_mesh;
00769         }
00770 
00771         //-------------------------------------------------------------------------
00772         // if not found, create a new one, add it to the list
00773         //-------------------------------------------------------------------------
00774         char full_path[LL_MAX_PATH];            /*Flawfinder: ignore*/
00775         snprintf(full_path, LL_MAX_PATH, "%s", (gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,name.c_str())).c_str());                       /* Flawfinder: ignore */
00776 
00777         LLPolyMeshSharedData *mesh_data = new LLPolyMeshSharedData();
00778         if (reference_mesh)
00779         {
00780                 mesh_data->setupLOD(reference_mesh->getSharedData());
00781         }
00782         if ( ! mesh_data->loadMesh( full_path ) )
00783         {
00784                 delete mesh_data;
00785                 return NULL;
00786         }
00787 
00788         LLPolyMesh *poly_mesh = new LLPolyMesh(mesh_data, reference_mesh);
00789 
00790 //      llinfos << "Polymesh " << name << " added to global mesh table." << llendl;
00791         sGlobalSharedMeshList[name] = poly_mesh->mSharedData;
00792 
00793         return poly_mesh;
00794 }
00795 
00796 //-----------------------------------------------------------------------------
00797 // LLPolyMesh::freeAllMeshes()
00798 //-----------------------------------------------------------------------------
00799 void LLPolyMesh::freeAllMeshes()
00800 {
00801         // delete each item in the global lists
00802         for_each(sGlobalSharedMeshList.begin(), sGlobalSharedMeshList.end(), DeletePairedPointer());
00803         sGlobalSharedMeshList.clear();
00804 }
00805 
00806 LLPolyMeshSharedData *LLPolyMesh::getSharedData() const
00807 {
00808         return mSharedData;
00809 }
00810 
00811 
00812 //--------------------------------------------------------------------
00813 // LLPolyMesh::dumpDiagInfo()
00814 //--------------------------------------------------------------------
00815 void LLPolyMesh::dumpDiagInfo()
00816 {
00817         // keep track of totals
00818         U32 total_verts = 0;
00819         U32 total_faces = 0;
00820         U32 total_kb = 0;
00821 
00822         std::string buf;
00823 
00824         llinfos << "-----------------------------------------------------" << llendl;
00825         llinfos << "       Global PolyMesh Table (DEBUG only)" << llendl;
00826         llinfos << "   Verts    Faces  Mem(KB) Name" << llendl;
00827         llinfos << "-----------------------------------------------------" << llendl;
00828 
00829         // print each loaded mesh, and it's memory usage
00830         for(LLPolyMeshSharedDataTable::iterator iter = sGlobalSharedMeshList.begin();
00831                 iter != sGlobalSharedMeshList.end(); ++iter)
00832         {
00833                 const std::string& mesh_name = iter->first;
00834                 LLPolyMeshSharedData* mesh = iter->second;
00835 
00836                 S32 num_verts = mesh->mNumVertices;
00837                 S32 num_faces = mesh->mNumFaces;
00838                 U32 num_kb = mesh->getNumKB();
00839 
00840                 buf = llformat("%8d %8d %8d %s", num_verts, num_faces, num_kb, mesh_name.c_str());
00841                 llinfos << buf << llendl;
00842 
00843                 total_verts += num_verts;
00844                 total_faces += num_faces;
00845                 total_kb += num_kb;
00846         }
00847 
00848         llinfos << "-----------------------------------------------------" << llendl;
00849         buf = llformat("%8d %8d %8d TOTAL", total_verts, total_faces, total_kb );
00850         llinfos << buf << llendl;
00851         llinfos << "-----------------------------------------------------" << llendl;
00852 }
00853 
00854 //-----------------------------------------------------------------------------
00855 // getWritableCoords()
00856 //-----------------------------------------------------------------------------
00857 LLVector3 *LLPolyMesh::getWritableCoords()
00858 {
00859         return mCoords;
00860 }
00861 
00862 //-----------------------------------------------------------------------------
00863 // getWritableNormals()
00864 //-----------------------------------------------------------------------------
00865 LLVector3 *LLPolyMesh::getWritableNormals()
00866 {
00867         return mNormals;
00868 }
00869 
00870 //-----------------------------------------------------------------------------
00871 // getWritableBinormals()
00872 //-----------------------------------------------------------------------------
00873 LLVector3 *LLPolyMesh::getWritableBinormals()
00874 {
00875         return mBinormals;
00876 }
00877 
00878 
00879 //-----------------------------------------------------------------------------
00880 // getWritableClothingWeights()
00881 //-----------------------------------------------------------------------------
00882 LLVector4       *LLPolyMesh::getWritableClothingWeights()
00883 {
00884         return mClothingWeights;
00885 }
00886 
00887 //-----------------------------------------------------------------------------
00888 // getWritableTexCoords()
00889 //-----------------------------------------------------------------------------
00890 LLVector2       *LLPolyMesh::getWritableTexCoords()
00891 {
00892         return mTexCoords;
00893 }
00894 
00895 //-----------------------------------------------------------------------------
00896 // getScaledNormals()
00897 //-----------------------------------------------------------------------------
00898 LLVector3 *LLPolyMesh::getScaledNormals()
00899 {
00900         return mScaledNormals;
00901 }
00902 
00903 //-----------------------------------------------------------------------------
00904 // getScaledBinormals()
00905 //-----------------------------------------------------------------------------
00906 LLVector3 *LLPolyMesh::getScaledBinormals()
00907 {
00908         return mScaledBinormals;
00909 }
00910 
00911 
00912 //-----------------------------------------------------------------------------
00913 // initializeForMorph()
00914 //-----------------------------------------------------------------------------
00915 void LLPolyMesh::initializeForMorph()
00916 {
00917         if (!mSharedData)
00918                 return;
00919 
00920         memcpy(mCoords, mSharedData->mBaseCoords, sizeof(LLVector3) * mSharedData->mNumVertices);       /*Flawfinder: ignore*/
00921         memcpy(mNormals, mSharedData->mBaseNormals, sizeof(LLVector3) * mSharedData->mNumVertices);     /*Flawfinder: ignore*/
00922         memcpy(mScaledNormals, mSharedData->mBaseNormals, sizeof(LLVector3) * mSharedData->mNumVertices);       /*Flawfinder: ignore*/
00923         memcpy(mBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
00924         memcpy(mScaledBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices);           /*Flawfinder: ignore*/
00925         memcpy(mTexCoords, mSharedData->mTexCoords, sizeof(LLVector2) * mSharedData->mNumVertices);             /*Flawfinder: ignore*/
00926         memset(mClothingWeights, 0, sizeof(LLVector4) * mSharedData->mNumVertices);
00927 }
00928 
00929 //-----------------------------------------------------------------------------
00930 // getMorphData()
00931 //-----------------------------------------------------------------------------
00932 LLPolyMorphData*        LLPolyMesh::getMorphData(const char *morph_name)
00933 {
00934         if (!mSharedData)
00935                 return NULL;
00936         for (LLPolyMeshSharedData::morphdata_list_t::iterator iter = mSharedData->mMorphData.begin();
00937                  iter != mSharedData->mMorphData.end(); ++iter)
00938         {
00939                 LLPolyMorphData *morph_data = *iter;
00940                 if (!strcmp(morph_data->getName(), morph_name))
00941                 {
00942                         return morph_data;
00943                 }
00944         }
00945         return NULL;
00946 }
00947 
00948 //-----------------------------------------------------------------------------
00949 // removeMorphData()
00950 //-----------------------------------------------------------------------------
00951 // // erasing but not deleting seems bad, but fortunately we don't actually use this...
00952 // void LLPolyMesh::removeMorphData(LLPolyMorphData *morph_target)
00953 // {
00954 //      if (!mSharedData)
00955 //              return;
00956 //      mSharedData->mMorphData.erase(morph_target);
00957 // }
00958 
00959 //-----------------------------------------------------------------------------
00960 // deleteAllMorphData()
00961 //-----------------------------------------------------------------------------
00962 // void LLPolyMesh::deleteAllMorphData()
00963 // {
00964 //      if (!mSharedData)
00965 //              return;
00966 
00967 //      for_each(mSharedData->mMorphData.begin(), mSharedData->mMorphData.end(), DeletePointer());
00968 //      mSharedData->mMorphData.clear();
00969 // }
00970 
00971 //-----------------------------------------------------------------------------
00972 // getWritableWeights()
00973 //-----------------------------------------------------------------------------
00974 F32*    LLPolyMesh::getWritableWeights() const
00975 {
00976         return mSharedData->mWeights;
00977 }
00978 
00979 //-----------------------------------------------------------------------------
00980 // LLPolySkeletalDistortionInfo()
00981 //-----------------------------------------------------------------------------
00982 LLPolySkeletalDistortionInfo::LLPolySkeletalDistortionInfo()
00983 {
00984 }
00985 
00986 BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node)
00987 {
00988         llassert( node->hasName( "param" ) && node->getChildByName( "param_skeleton" ) );
00989         
00990         if (!LLViewerVisualParamInfo::parseXml(node))
00991                 return FALSE;
00992 
00993         LLXmlTreeNode* skeletalParam = node->getChildByName("param_skeleton");
00994 
00995         if (NULL == skeletalParam)
00996         {
00997                 llwarns << "Failed to getChildByName(\"param_skeleton\")"
00998                         << llendl;
00999                 return FALSE;
01000         }
01001 
01002         for( LLXmlTreeNode* bone = skeletalParam->getFirstChild(); bone; bone = skeletalParam->getNextChild() )
01003         {
01004                 if (bone->hasName("bone"))
01005                 {
01006                         LLString name;
01007                         LLVector3 scale;
01008                         LLVector3 pos;
01009                         BOOL haspos = FALSE;
01010                         
01011                         static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
01012                         if (!bone->getFastAttributeString(name_string, name))
01013                         {
01014                                 llwarns << "No bone name specified for skeletal param." << llendl;
01015                                 continue;
01016                         }
01017 
01018                         static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
01019                         if (!bone->getFastAttributeVector3(scale_string, scale))
01020                         {
01021                                 llwarns << "No scale specified for bone " << name << "." << llendl;
01022                                 continue;
01023                         }
01024 
01025                         // optional offset deformation (translation)
01026                         static LLStdStringHandle offset_string = LLXmlTree::addAttributeString("offset");
01027                         if (bone->getFastAttributeVector3(offset_string, pos))
01028                         {
01029                                 haspos = TRUE;
01030                         }
01031                         mBoneInfoList.push_back(LLPolySkeletalBoneInfo(name, scale, pos, haspos));
01032                 }
01033                 else
01034                 {
01035                         llwarns << "Unrecognized element " << bone->getName() << " in skeletal distortion" << llendl;
01036                         continue;
01037                 }
01038         }
01039         return TRUE;
01040 }
01041 
01042 //-----------------------------------------------------------------------------
01043 // LLPolySkeletalDistortion()
01044 //-----------------------------------------------------------------------------
01045 LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLVOAvatar *avatarp)
01046 {
01047         mAvatar = avatarp;
01048         mDefaultVec.setVec(0.001f, 0.001f, 0.001f);
01049 }
01050 
01051 //-----------------------------------------------------------------------------
01052 // ~LLPolySkeletalDistortion()
01053 //-----------------------------------------------------------------------------
01054 LLPolySkeletalDistortion::~LLPolySkeletalDistortion()
01055 {
01056 }
01057 
01058 BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)
01059 {
01060         llassert(mInfo == NULL);
01061         if (info->mID < 0)
01062                 return FALSE;
01063         mInfo = info;
01064         mID = info->mID;
01065         setWeight(getDefaultWeight(), FALSE );
01066 
01067         LLPolySkeletalDistortionInfo::bone_info_list_t::iterator iter;
01068         for (iter = getInfo()->mBoneInfoList.begin(); iter != getInfo()->mBoneInfoList.end(); iter++)
01069         {
01070                 LLPolySkeletalBoneInfo *bone_info = &(*iter);
01071                 LLJoint* joint = mAvatar->getJoint(bone_info->mBoneName);
01072                 if (!joint)
01073                 {
01074                         llwarns << "Joint " << bone_info->mBoneName << " not found." << llendl;
01075                         continue;
01076                 }
01077 
01078                 if (mJointScales.find(joint) != mJointScales.end())
01079                 {
01080                         llwarns << "Scale deformation already supplied for joint " << joint->getName() << "." << llendl;
01081                 }
01082 
01083                 // store it
01084                 mJointScales[joint] = bone_info->mScaleDeformation;
01085 
01086                 // apply to children that need to inherit it
01087                 for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin();
01088                          iter != joint->mChildren.end(); ++iter)
01089                 {
01090                         LLViewerJoint* child_joint = (LLViewerJoint*)(*iter);
01091                         if (child_joint->inheritScale())
01092                         {
01093                                 LLVector3 childDeformation = LLVector3(child_joint->getScale());
01094                                 childDeformation.scaleVec(bone_info->mScaleDeformation);
01095                                 mJointScales[child_joint] = childDeformation;
01096                         }
01097                 }
01098 
01099                 if (bone_info->mHasPositionDeformation)
01100                 {
01101                         if (mJointOffsets.find(joint) != mJointOffsets.end())
01102                         {
01103                                 llwarns << "Offset deformation already supplied for joint " << joint->getName() << "." << llendl;
01104                         }
01105                         mJointOffsets[joint] = bone_info->mPositionDeformation;
01106                 }
01107         }
01108         return TRUE;
01109 }
01110 
01111 //-----------------------------------------------------------------------------
01112 // apply()
01113 //-----------------------------------------------------------------------------
01114 void LLPolySkeletalDistortion::apply( ESex avatar_sex )
01115 {
01116         F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight();
01117 
01118         LLJoint* joint;
01119         joint_vec_map_t::iterator iter;
01120 
01121         for (iter = mJointScales.begin();
01122                  iter != mJointScales.end();
01123                  iter++)
01124         {
01125                 joint = iter->first;
01126                 LLVector3 newScale = joint->getScale();
01127                 LLVector3 scaleDelta = iter->second;
01128                 newScale = newScale + (effective_weight * scaleDelta) - (mLastWeight * scaleDelta);
01129                 joint->setScale(newScale);
01130         }
01131 
01132         for (iter = mJointOffsets.begin();
01133                  iter != mJointOffsets.end();
01134                  iter++)
01135         {
01136                 joint = iter->first;
01137                 LLVector3 newPosition = joint->getPosition();
01138                 LLVector3 positionDelta = iter->second;
01139                 newPosition = newPosition + (effective_weight * positionDelta) - (mLastWeight * positionDelta);
01140                 joint->setPosition(newPosition);
01141         }
01142 
01143         if (mLastWeight != mCurWeight && !mIsAnimating)
01144         {
01145                 mAvatar->setSkeletonSerialNum(mAvatar->getSkeletonSerialNum() + 1);
01146         }
01147         mLastWeight = mCurWeight;
01148 }
01149 
01150 // End

Generated on Fri May 16 08:33:56 2008 for SecondLife by  doxygen 1.5.5