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

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