llpolymesh.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:35k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llpolymesh.cpp
  3.  * @brief Implementation of LLPolyMesh class
  4.  *
  5.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2001-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. //-----------------------------------------------------------------------------
  33. // Header Files
  34. //-----------------------------------------------------------------------------
  35. #include "llviewerprecompiledheaders.h"
  36. #include "llpolymesh.h"
  37. #include "llviewercontrol.h"
  38. #include "llxmltree.h"
  39. #include "llvoavatar.h"
  40. #include "llwearable.h"
  41. #include "lldir.h"
  42. #include "llvolume.h"
  43. #include "llendianswizzle.h"
  44. #include "llfasttimer.h"
  45. #define HEADER_ASCII "Linden Mesh 1.0"
  46. #define HEADER_BINARY "Linden Binary Mesh 1.0"
  47. extern LLControlGroup gSavedSettings; // read only
  48. //-----------------------------------------------------------------------------
  49. // Global table of loaded LLPolyMeshes
  50. //-----------------------------------------------------------------------------
  51. LLPolyMesh::LLPolyMeshSharedDataTable LLPolyMesh::sGlobalSharedMeshList;
  52. //-----------------------------------------------------------------------------
  53. // LLPolyMeshSharedData()
  54. //-----------------------------------------------------------------------------
  55. LLPolyMeshSharedData::LLPolyMeshSharedData()
  56. {
  57. mNumVertices = 0;
  58. mBaseCoords = NULL;
  59. mBaseNormals = NULL;
  60. mBaseBinormals = NULL;
  61. mTexCoords = NULL;
  62. mDetailTexCoords = NULL;
  63. mWeights = NULL;
  64. mHasWeights = FALSE;
  65. mHasDetailTexCoords = FALSE;
  66. mNumFaces = 0;
  67. mFaces = NULL;
  68. mNumJointNames = 0;
  69. mJointNames = NULL;
  70. mTriangleIndices = NULL;
  71. mNumTriangleIndices = 0;
  72. mReferenceData = NULL;
  73. mLastIndexOffset = -1;
  74. }
  75. //-----------------------------------------------------------------------------
  76. // ~LLPolyMeshSharedData()
  77. //-----------------------------------------------------------------------------
  78. LLPolyMeshSharedData::~LLPolyMeshSharedData()
  79. {
  80. freeMeshData();
  81. for_each(mMorphData.begin(), mMorphData.end(), DeletePointer());
  82. mMorphData.clear();
  83. }
  84. //-----------------------------------------------------------------------------
  85. // setupLOD()
  86. //-----------------------------------------------------------------------------
  87. void LLPolyMeshSharedData::setupLOD(LLPolyMeshSharedData* reference_data)
  88. {
  89. mReferenceData = reference_data;
  90. if (reference_data)
  91. {
  92. mBaseCoords = reference_data->mBaseCoords;
  93. mBaseNormals = reference_data->mBaseNormals;
  94. mBaseBinormals = reference_data->mBaseBinormals;
  95. mTexCoords = reference_data->mTexCoords;
  96. mDetailTexCoords = reference_data->mDetailTexCoords;
  97. mWeights = reference_data->mWeights;
  98. mHasWeights = reference_data->mHasWeights;
  99. mHasDetailTexCoords = reference_data->mHasDetailTexCoords;
  100. }
  101. }
  102. //-----------------------------------------------------------------------------
  103. // LLPolyMeshSharedData::freeMeshData()
  104. //-----------------------------------------------------------------------------
  105. void LLPolyMeshSharedData::freeMeshData()
  106. {
  107. if (!mReferenceData)
  108. {
  109. mNumVertices = 0;
  110. delete [] mBaseCoords;
  111. mBaseCoords = NULL;
  112. delete [] mBaseNormals;
  113. mBaseNormals = NULL;
  114. delete [] mBaseBinormals;
  115. mBaseBinormals = NULL;
  116. delete [] mTexCoords;
  117. mTexCoords = NULL;
  118. delete [] mDetailTexCoords;
  119. mDetailTexCoords = NULL;
  120. delete [] mWeights;
  121. mWeights = NULL;
  122. }
  123. mNumFaces = 0;
  124. delete [] mFaces;
  125. mFaces = NULL;
  126. mNumJointNames = 0;
  127. delete [] mJointNames;
  128. mJointNames = NULL;
  129. delete [] mTriangleIndices;
  130. mTriangleIndices = NULL;
  131. // mVertFaceMap.deleteAllData();
  132. }
  133. // compate_int is used by the qsort function to sort the index array
  134. int compare_int(const void *a, const void *b);
  135. //-----------------------------------------------------------------------------
  136. // genIndices()
  137. //-----------------------------------------------------------------------------
  138. void LLPolyMeshSharedData::genIndices(S32 index_offset)
  139. {
  140. if (index_offset == mLastIndexOffset)
  141. {
  142. return;
  143. }
  144. delete []mTriangleIndices;
  145. mTriangleIndices = new U32[mNumTriangleIndices];
  146. S32 cur_index = 0;
  147. for (S32 i = 0; i < mNumFaces; i++)
  148. {
  149. mTriangleIndices[cur_index] = mFaces[i][0] + index_offset;
  150. cur_index++;
  151. mTriangleIndices[cur_index] = mFaces[i][1] + index_offset;
  152. cur_index++;
  153. mTriangleIndices[cur_index] = mFaces[i][2] + index_offset;
  154. cur_index++;
  155. }
  156. mLastIndexOffset = index_offset;
  157. }
  158. //--------------------------------------------------------------------
  159. // LLPolyMeshSharedData::getNumKB()
  160. //--------------------------------------------------------------------
  161. U32 LLPolyMeshSharedData::getNumKB()
  162. {
  163. U32 num_kb = sizeof(LLPolyMesh);
  164. if (!isLOD())
  165. {
  166. num_kb += mNumVertices *
  167. ( sizeof(LLVector3) + // coords
  168. sizeof(LLVector3) + // normals
  169. sizeof(LLVector2) ); // texCoords
  170. }
  171. if (mHasDetailTexCoords && !isLOD())
  172. {
  173. num_kb += mNumVertices * sizeof(LLVector2); // detailTexCoords
  174. }
  175. if (mHasWeights && !isLOD())
  176. {
  177. num_kb += mNumVertices * sizeof(float); // weights
  178. }
  179. num_kb += mNumFaces * sizeof(LLPolyFace); // faces
  180. num_kb /= 1024;
  181. return num_kb;
  182. }
  183. //-----------------------------------------------------------------------------
  184. // LLPolyMeshSharedData::allocateVertexData()
  185. //-----------------------------------------------------------------------------
  186. BOOL LLPolyMeshSharedData::allocateVertexData( U32 numVertices )
  187. {
  188. U32 i;
  189. mBaseCoords = new LLVector3[ numVertices ];
  190. mBaseNormals = new LLVector3[ numVertices ];
  191. mBaseBinormals = new LLVector3[ numVertices ];
  192. mTexCoords = new LLVector2[ numVertices ];
  193. mDetailTexCoords = new LLVector2[ numVertices ];
  194. mWeights = new F32[ numVertices ];
  195. for (i = 0; i < numVertices; i++)
  196. {
  197. mWeights[i] = 0.f;
  198. }
  199. mNumVertices = numVertices;
  200. return TRUE;
  201. }
  202. //-----------------------------------------------------------------------------
  203. // LLPolyMeshSharedData::allocateFaceData()
  204. //-----------------------------------------------------------------------------
  205. BOOL LLPolyMeshSharedData::allocateFaceData( U32 numFaces )
  206. {
  207. mFaces = new LLPolyFace[ numFaces ];
  208. mNumFaces = numFaces;
  209. mNumTriangleIndices = mNumFaces * 3;
  210. return TRUE;
  211. }
  212. //-----------------------------------------------------------------------------
  213. // LLPolyMeshSharedData::allocateJointNames()
  214. //-----------------------------------------------------------------------------
  215. BOOL LLPolyMeshSharedData::allocateJointNames( U32 numJointNames )
  216. {
  217. mJointNames = new std::string[ numJointNames ];
  218. mNumJointNames = numJointNames;
  219. return TRUE;
  220. }
  221. //--------------------------------------------------------------------
  222. // LLPolyMeshSharedData::loadMesh()
  223. //--------------------------------------------------------------------
  224. BOOL LLPolyMeshSharedData::loadMesh( const std::string& fileName )
  225. {
  226. //-------------------------------------------------------------------------
  227. // Open the file
  228. //-------------------------------------------------------------------------
  229. if(fileName.empty())
  230. {
  231. llerrs << "Filename is Empty!" << llendl;
  232. return FALSE;
  233. }
  234. LLFILE* fp = LLFile::fopen(fileName, "rb"); /*Flawfinder: ignore*/
  235. if (!fp)
  236. {
  237. llerrs << "can't open: " << fileName << llendl;
  238. return FALSE;
  239. }
  240. //-------------------------------------------------------------------------
  241. // Read a chunk
  242. //-------------------------------------------------------------------------
  243. char header[128]; /*Flawfinder: ignore*/
  244. if (fread(header, sizeof(char), 128, fp) != 128)
  245. {
  246. llwarns << "Short read" << llendl;
  247. }
  248. //-------------------------------------------------------------------------
  249. // Check for proper binary header
  250. //-------------------------------------------------------------------------
  251. BOOL status = FALSE;
  252. if ( strncmp(header, HEADER_BINARY, strlen(HEADER_BINARY)) == 0 ) /*Flawfinder: ignore*/
  253. {
  254. lldebugs << "Loading " << fileName << llendl;
  255. //----------------------------------------------------------------
  256. // File Header (seek past it)
  257. //----------------------------------------------------------------
  258. fseek(fp, 24, SEEK_SET);
  259. //----------------------------------------------------------------
  260. // HasWeights
  261. //----------------------------------------------------------------
  262. U8 hasWeights;
  263. size_t numRead = fread(&hasWeights, sizeof(U8), 1, fp);
  264. if (numRead != 1)
  265. {
  266. llerrs << "can't read HasWeights flag from " << fileName << llendl;
  267. return FALSE;
  268. }
  269. if (!isLOD())
  270. {
  271. mHasWeights = (hasWeights==0) ? FALSE : TRUE;
  272. }
  273. //----------------------------------------------------------------
  274. // HasDetailTexCoords
  275. //----------------------------------------------------------------
  276. U8 hasDetailTexCoords;
  277. numRead = fread(&hasDetailTexCoords, sizeof(U8), 1, fp);
  278. if (numRead != 1)
  279. {
  280. llerrs << "can't read HasDetailTexCoords flag from " << fileName << llendl;
  281. return FALSE;
  282. }
  283. //----------------------------------------------------------------
  284. // Position
  285. //----------------------------------------------------------------
  286. LLVector3 position;
  287. numRead = fread(position.mV, sizeof(float), 3, fp);
  288. llendianswizzle(position.mV, sizeof(float), 3);
  289. if (numRead != 3)
  290. {
  291. llerrs << "can't read Position from " << fileName << llendl;
  292. return FALSE;
  293. }
  294. setPosition( position );
  295. //----------------------------------------------------------------
  296. // Rotation
  297. //----------------------------------------------------------------
  298. LLVector3 rotationAngles;
  299. numRead = fread(rotationAngles.mV, sizeof(float), 3, fp);
  300. llendianswizzle(rotationAngles.mV, sizeof(float), 3);
  301. if (numRead != 3)
  302. {
  303. llerrs << "can't read RotationAngles from " << fileName << llendl;
  304. return FALSE;
  305. }
  306. U8 rotationOrder;
  307. numRead = fread(&rotationOrder, sizeof(U8), 1, fp);
  308. if (numRead != 1)
  309. {
  310. llerrs << "can't read RotationOrder from " << fileName << llendl;
  311. return FALSE;
  312. }
  313. rotationOrder = 0;
  314. setRotation( mayaQ( rotationAngles.mV[0],
  315. rotationAngles.mV[1],
  316. rotationAngles.mV[2],
  317. (LLQuaternion::Order)rotationOrder ) );
  318. //----------------------------------------------------------------
  319. // Scale
  320. //----------------------------------------------------------------
  321. LLVector3 scale;
  322. numRead = fread(scale.mV, sizeof(float), 3, fp);
  323. llendianswizzle(scale.mV, sizeof(float), 3);
  324. if (numRead != 3)
  325. {
  326. llerrs << "can't read Scale from " << fileName << llendl;
  327. return FALSE;
  328. }
  329. setScale( scale );
  330. //-------------------------------------------------------------------------
  331. // Release any existing mesh geometry
  332. //-------------------------------------------------------------------------
  333. freeMeshData();
  334. U16 numVertices = 0;
  335. //----------------------------------------------------------------
  336. // NumVertices
  337. //----------------------------------------------------------------
  338. if (!isLOD())
  339. {
  340. numRead = fread(&numVertices, sizeof(U16), 1, fp);
  341. llendianswizzle(&numVertices, sizeof(U16), 1);
  342. if (numRead != 1)
  343. {
  344. llerrs << "can't read NumVertices from " << fileName << llendl;
  345. return FALSE;
  346. }
  347. allocateVertexData( numVertices );
  348. //----------------------------------------------------------------
  349. // Coords
  350. //----------------------------------------------------------------
  351. numRead = fread(mBaseCoords, 3*sizeof(float), numVertices, fp);
  352. llendianswizzle(mBaseCoords, sizeof(float), 3*numVertices);
  353. if (numRead != numVertices)
  354. {
  355. llerrs << "can't read Coordinates from " << fileName << llendl;
  356. return FALSE;
  357. }
  358. //----------------------------------------------------------------
  359. // Normals
  360. //----------------------------------------------------------------
  361. numRead = fread(mBaseNormals, 3*sizeof(float), numVertices, fp);
  362. llendianswizzle(mBaseNormals, sizeof(float), 3*numVertices);
  363. if (numRead != numVertices)
  364. {
  365. llerrs << " can't read Normals from " << fileName << llendl;
  366. return FALSE;
  367. }
  368. //----------------------------------------------------------------
  369. // Binormals
  370. //----------------------------------------------------------------
  371. numRead = fread(mBaseBinormals, 3*sizeof(float), numVertices, fp);
  372. llendianswizzle(mBaseBinormals, sizeof(float), 3*numVertices);
  373. if (numRead != numVertices)
  374. {
  375. llerrs << " can't read Binormals from " << fileName << llendl;
  376. return FALSE;
  377. }
  378. //----------------------------------------------------------------
  379. // TexCoords
  380. //----------------------------------------------------------------
  381. numRead = fread(mTexCoords, 2*sizeof(float), numVertices, fp);
  382. llendianswizzle(mTexCoords, sizeof(float), 2*numVertices);
  383. if (numRead != numVertices)
  384. {
  385. llerrs << "can't read TexCoords from " << fileName << llendl;
  386. return FALSE;
  387. }
  388. //----------------------------------------------------------------
  389. // DetailTexCoords
  390. //----------------------------------------------------------------
  391. if (mHasDetailTexCoords)
  392. {
  393. numRead = fread(mDetailTexCoords, 2*sizeof(float), numVertices, fp);
  394. llendianswizzle(mDetailTexCoords, sizeof(float), 2*numVertices);
  395. if (numRead != numVertices)
  396. {
  397. llerrs << "can't read DetailTexCoords from " << fileName << llendl;
  398. return FALSE;
  399. }
  400. }
  401. //----------------------------------------------------------------
  402. // Weights
  403. //----------------------------------------------------------------
  404. if (mHasWeights)
  405. {
  406. numRead = fread(mWeights, sizeof(float), numVertices, fp);
  407. llendianswizzle(mWeights, sizeof(float), numVertices);
  408. if (numRead != numVertices)
  409. {
  410. llerrs << "can't read Weights from " << fileName << llendl;
  411. return FALSE;
  412. }
  413. }
  414. }
  415. //----------------------------------------------------------------
  416. // NumFaces
  417. //----------------------------------------------------------------
  418. U16 numFaces;
  419. numRead = fread(&numFaces, sizeof(U16), 1, fp);
  420. llendianswizzle(&numFaces, sizeof(U16), 1);
  421. if (numRead != 1)
  422. {
  423. llerrs << "can't read NumFaces from " << fileName << llendl;
  424. return FALSE;
  425. }
  426. allocateFaceData( numFaces );
  427. //----------------------------------------------------------------
  428. // Faces
  429. //----------------------------------------------------------------
  430. U32 i;
  431. U32 numTris = 0;
  432. for (i = 0; i < numFaces; i++)
  433. {
  434. S16 face[3];
  435. numRead = fread(face, sizeof(U16), 3, fp);
  436. llendianswizzle(face, sizeof(U16), 3);
  437. if (numRead != 3)
  438. {
  439. llerrs << "can't read Face[" << i << "] from " << fileName << llendl;
  440. return FALSE;
  441. }
  442. if (mReferenceData)
  443. {
  444. llassert(face[0] < mReferenceData->mNumVertices);
  445. llassert(face[1] < mReferenceData->mNumVertices);
  446. llassert(face[2] < mReferenceData->mNumVertices);
  447. }
  448. if (isLOD())
  449. {
  450. // store largest index in case of LODs
  451. for (S32 j = 0; j < 3; j++)
  452. {
  453. if (face[j] > mNumVertices - 1)
  454. {
  455. mNumVertices = face[j] + 1;
  456. }
  457. }
  458. }
  459. mFaces[i][0] = face[0];
  460. mFaces[i][1] = face[1];
  461. mFaces[i][2] = face[2];
  462. // S32 j;
  463. // for(j = 0; j < 3; j++)
  464. // {
  465. // LLDynamicArray<S32> *face_list = mVertFaceMap.getIfThere(face[j]);
  466. // if (!face_list)
  467. // {
  468. // face_list = new LLDynamicArray<S32>;
  469. // mVertFaceMap.addData(face[j], face_list);
  470. // }
  471. // face_list->put(i);
  472. // }
  473. numTris++;
  474. }
  475. lldebugs << "verts: " << numVertices 
  476. << ", faces: "   << numFaces
  477. << ", tris: "    << numTris
  478. << llendl;
  479. //----------------------------------------------------------------
  480. // NumSkinJoints
  481. //----------------------------------------------------------------
  482. if (!isLOD())
  483. {
  484. U16 numSkinJoints = 0;
  485. if ( mHasWeights )
  486. {
  487. numRead = fread(&numSkinJoints, sizeof(U16), 1, fp);
  488. llendianswizzle(&numSkinJoints, sizeof(U16), 1);
  489. if (numRead != 1)
  490. {
  491. llerrs << "can't read NumSkinJoints from " << fileName << llendl;
  492. return FALSE;
  493. }
  494. allocateJointNames( numSkinJoints );
  495. }
  496. //----------------------------------------------------------------
  497. // SkinJoints
  498. //----------------------------------------------------------------
  499. for (i=0; i < numSkinJoints; i++)
  500. {
  501. char jointName[64+1];
  502. numRead = fread(jointName, sizeof(jointName)-1, 1, fp);
  503. jointName[sizeof(jointName)-1] = ''; // ensure nul-termination
  504. if (numRead != 1)
  505. {
  506. llerrs << "can't read Skin[" << i << "].Name from " << fileName << llendl;
  507. return FALSE;
  508. }
  509. std::string *jn = &mJointNames[i];
  510. *jn = jointName;
  511. }
  512. //-------------------------------------------------------------------------
  513. // look for morph section
  514. //-------------------------------------------------------------------------
  515. char morphName[64+1];
  516. morphName[sizeof(morphName)-1] = ''; // ensure nul-termination
  517. while(fread(&morphName, sizeof(char), 64, fp) == 64)
  518. {
  519. if (!strcmp(morphName, "End Morphs"))
  520. {
  521. // we reached the end of the morphs
  522. break;
  523. }
  524. LLPolyMorphData* morph_data = new LLPolyMorphData(std::string(morphName));
  525. BOOL result = morph_data->loadBinary(fp, this);
  526. if (!result)
  527. {
  528. delete morph_data;
  529. continue;
  530. }
  531. mMorphData.insert(morph_data);
  532. }
  533. S32 numRemaps;
  534. if (fread(&numRemaps, sizeof(S32), 1, fp) == 1)
  535. {
  536. llendianswizzle(&numRemaps, sizeof(S32), 1);
  537. for (S32 i = 0; i < numRemaps; i++)
  538. {
  539. S32 remapSrc;
  540. S32 remapDst;
  541. if (fread(&remapSrc, sizeof(S32), 1, fp) != 1)
  542. {
  543. llerrs << "can't read source vertex in vertex remap data" << llendl;
  544. break;
  545. }
  546. if (fread(&remapDst, sizeof(S32), 1, fp) != 1)
  547. {
  548. llerrs << "can't read destination vertex in vertex remap data" << llendl;
  549. break;
  550. }
  551. llendianswizzle(&remapSrc, sizeof(S32), 1);
  552. llendianswizzle(&remapDst, sizeof(S32), 1);
  553. mSharedVerts[remapSrc] = remapDst;
  554. }
  555. }
  556. }
  557. status = TRUE;
  558. }
  559. else
  560. {
  561. llerrs << "invalid mesh file header: " << fileName << llendl;
  562. status = FALSE;
  563. }
  564. if (0 == mNumJointNames)
  565. {
  566. allocateJointNames(1);
  567. }
  568. fclose( fp );
  569. return status;
  570. }
  571. //-----------------------------------------------------------------------------
  572. // getSharedVert()
  573. //-----------------------------------------------------------------------------
  574. const S32 *LLPolyMeshSharedData::getSharedVert(S32 vert)
  575. {
  576. if (mSharedVerts.count(vert) > 0)
  577. {
  578. return &mSharedVerts[vert];
  579. }
  580. return NULL;
  581. }
  582. //-----------------------------------------------------------------------------
  583. // getUV()
  584. //-----------------------------------------------------------------------------
  585. const LLVector2 &LLPolyMeshSharedData::getUVs(U32 index)
  586. {
  587. // TODO: convert all index variables to S32
  588. llassert((S32)index < mNumVertices);
  589. return mTexCoords[index];
  590. }
  591. //-----------------------------------------------------------------------------
  592. // LLPolyMesh()
  593. //-----------------------------------------------------------------------------
  594. LLPolyMesh::LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_mesh)
  595. {
  596. LLMemType mt(LLMemType::MTYPE_AVATAR_MESH);
  597. llassert(shared_data);
  598. mSharedData = shared_data;
  599. mReferenceMesh = reference_mesh;
  600. mAvatarp = NULL;
  601. mVertexData = NULL;
  602. mCurVertexCount = 0;
  603. mFaceIndexCount = 0;
  604. mFaceIndexOffset = 0;
  605. mFaceVertexCount = 0;
  606. mFaceVertexOffset = 0;
  607. if (shared_data->isLOD() && reference_mesh)
  608. {
  609. mCoords = reference_mesh->mCoords;
  610. mNormals = reference_mesh->mNormals;
  611. mScaledNormals = reference_mesh->mScaledNormals;
  612. mBinormals = reference_mesh->mBinormals;
  613. mScaledBinormals = reference_mesh->mScaledBinormals;
  614. mTexCoords = reference_mesh->mTexCoords;
  615. mClothingWeights = reference_mesh->mClothingWeights;
  616. }
  617. else
  618. {
  619. #if 1 // Allocate memory without initializing every vector
  620. // NOTE: This makes asusmptions about the size of LLVector[234]
  621. int nverts = mSharedData->mNumVertices;
  622. int nfloats = nverts * (3*5 + 2 + 4);
  623. mVertexData = new F32[nfloats];
  624. int offset = 0;
  625. mCoords =  (LLVector3*)(mVertexData + offset); offset += 3*nverts;
  626. mNormals =  (LLVector3*)(mVertexData + offset); offset += 3*nverts;
  627. mScaledNormals =  (LLVector3*)(mVertexData + offset); offset += 3*nverts;
  628. mBinormals =  (LLVector3*)(mVertexData + offset); offset += 3*nverts;
  629. mScaledBinormals =  (LLVector3*)(mVertexData + offset); offset += 3*nverts;
  630. mTexCoords =  (LLVector2*)(mVertexData + offset); offset += 2*nverts;
  631. mClothingWeights =  (LLVector4*)(mVertexData + offset); offset += 4*nverts;
  632. #else
  633. mCoords = new LLVector3[mSharedData->mNumVertices];
  634. mNormals = new LLVector3[mSharedData->mNumVertices];
  635. mScaledNormals = new LLVector3[mSharedData->mNumVertices];
  636. mBinormals = new LLVector3[mSharedData->mNumVertices];
  637. mScaledBinormals = new LLVector3[mSharedData->mNumVertices];
  638. mTexCoords = new LLVector2[mSharedData->mNumVertices];
  639. mClothingWeights = new LLVector4[mSharedData->mNumVertices];
  640. memset(mClothingWeights, 0, sizeof(LLVector4) * mSharedData->mNumVertices);
  641. #endif
  642. initializeForMorph();
  643. }
  644. }
  645. //-----------------------------------------------------------------------------
  646. // ~LLPolyMesh()
  647. //-----------------------------------------------------------------------------
  648. LLPolyMesh::~LLPolyMesh()
  649. {
  650. S32 i;
  651. for (i = 0; i < mJointRenderData.count(); i++)
  652. {
  653. delete mJointRenderData[i];
  654. mJointRenderData[i] = NULL;
  655. }
  656. #if 0 // These are now allocated as one big uninitialized chunk
  657. delete [] mCoords;
  658. delete [] mNormals;
  659. delete [] mScaledNormals;
  660. delete [] mBinormals;
  661. delete [] mScaledBinormals;
  662. delete [] mClothingWeights;
  663. delete [] mTexCoords;
  664. #else
  665. delete [] mVertexData;
  666. #endif
  667. }
  668. //-----------------------------------------------------------------------------
  669. // LLPolyMesh::getMesh()
  670. //-----------------------------------------------------------------------------
  671. LLPolyMesh *LLPolyMesh::getMesh(const std::string &name, LLPolyMesh* reference_mesh)
  672. {
  673. //-------------------------------------------------------------------------
  674. // search for an existing mesh by this name
  675. //-------------------------------------------------------------------------
  676. LLPolyMeshSharedData* meshSharedData = get_if_there(sGlobalSharedMeshList, name, (LLPolyMeshSharedData*)NULL);
  677. if (meshSharedData)
  678. {
  679. // llinfos << "Polymesh " << name << " found in global mesh table." << llendl;
  680. LLPolyMesh *poly_mesh = new LLPolyMesh(meshSharedData, reference_mesh);
  681. return poly_mesh;
  682. }
  683. //-------------------------------------------------------------------------
  684. // if not found, create a new one, add it to the list
  685. //-------------------------------------------------------------------------
  686. std::string full_path;
  687. full_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,name);
  688. LLPolyMeshSharedData *mesh_data = new LLPolyMeshSharedData();
  689. if (reference_mesh)
  690. {
  691. mesh_data->setupLOD(reference_mesh->getSharedData());
  692. }
  693. if ( ! mesh_data->loadMesh( full_path ) )
  694. {
  695. delete mesh_data;
  696. return NULL;
  697. }
  698. LLPolyMesh *poly_mesh = new LLPolyMesh(mesh_data, reference_mesh);
  699. // llinfos << "Polymesh " << name << " added to global mesh table." << llendl;
  700. sGlobalSharedMeshList[name] = poly_mesh->mSharedData;
  701. return poly_mesh;
  702. }
  703. //-----------------------------------------------------------------------------
  704. // LLPolyMesh::freeAllMeshes()
  705. //-----------------------------------------------------------------------------
  706. void LLPolyMesh::freeAllMeshes()
  707. {
  708. // delete each item in the global lists
  709. for_each(sGlobalSharedMeshList.begin(), sGlobalSharedMeshList.end(), DeletePairedPointer());
  710. sGlobalSharedMeshList.clear();
  711. }
  712. LLPolyMeshSharedData *LLPolyMesh::getSharedData() const
  713. {
  714. return mSharedData;
  715. }
  716. //--------------------------------------------------------------------
  717. // LLPolyMesh::dumpDiagInfo()
  718. //--------------------------------------------------------------------
  719. void LLPolyMesh::dumpDiagInfo()
  720. {
  721. // keep track of totals
  722. U32 total_verts = 0;
  723. U32 total_faces = 0;
  724. U32 total_kb = 0;
  725. std::string buf;
  726. llinfos << "-----------------------------------------------------" << llendl;
  727. llinfos << "       Global PolyMesh Table (DEBUG only)" << llendl;
  728. llinfos << "   Verts    Faces  Mem(KB) Name" << llendl;
  729. llinfos << "-----------------------------------------------------" << llendl;
  730. // print each loaded mesh, and it's memory usage
  731. for(LLPolyMeshSharedDataTable::iterator iter = sGlobalSharedMeshList.begin();
  732. iter != sGlobalSharedMeshList.end(); ++iter)
  733. {
  734. const std::string& mesh_name = iter->first;
  735. LLPolyMeshSharedData* mesh = iter->second;
  736. S32 num_verts = mesh->mNumVertices;
  737. S32 num_faces = mesh->mNumFaces;
  738. U32 num_kb = mesh->getNumKB();
  739. buf = llformat("%8d %8d %8d %s", num_verts, num_faces, num_kb, mesh_name.c_str());
  740. llinfos << buf << llendl;
  741. total_verts += num_verts;
  742. total_faces += num_faces;
  743. total_kb += num_kb;
  744. }
  745. llinfos << "-----------------------------------------------------" << llendl;
  746. buf = llformat("%8d %8d %8d TOTAL", total_verts, total_faces, total_kb );
  747. llinfos << buf << llendl;
  748. llinfos << "-----------------------------------------------------" << llendl;
  749. }
  750. //-----------------------------------------------------------------------------
  751. // getWritableCoords()
  752. //-----------------------------------------------------------------------------
  753. LLVector3 *LLPolyMesh::getWritableCoords()
  754. {
  755. return mCoords;
  756. }
  757. //-----------------------------------------------------------------------------
  758. // getWritableNormals()
  759. //-----------------------------------------------------------------------------
  760. LLVector3 *LLPolyMesh::getWritableNormals()
  761. {
  762. return mNormals;
  763. }
  764. //-----------------------------------------------------------------------------
  765. // getWritableBinormals()
  766. //-----------------------------------------------------------------------------
  767. LLVector3 *LLPolyMesh::getWritableBinormals()
  768. {
  769. return mBinormals;
  770. }
  771. //-----------------------------------------------------------------------------
  772. // getWritableClothingWeights()
  773. //-----------------------------------------------------------------------------
  774. LLVector4 *LLPolyMesh::getWritableClothingWeights()
  775. {
  776. return mClothingWeights;
  777. }
  778. //-----------------------------------------------------------------------------
  779. // getWritableTexCoords()
  780. //-----------------------------------------------------------------------------
  781. LLVector2 *LLPolyMesh::getWritableTexCoords()
  782. {
  783. return mTexCoords;
  784. }
  785. //-----------------------------------------------------------------------------
  786. // getScaledNormals()
  787. //-----------------------------------------------------------------------------
  788. LLVector3 *LLPolyMesh::getScaledNormals()
  789. {
  790. return mScaledNormals;
  791. }
  792. //-----------------------------------------------------------------------------
  793. // getScaledBinormals()
  794. //-----------------------------------------------------------------------------
  795. LLVector3 *LLPolyMesh::getScaledBinormals()
  796. {
  797. return mScaledBinormals;
  798. }
  799. //-----------------------------------------------------------------------------
  800. // initializeForMorph()
  801. //-----------------------------------------------------------------------------
  802. void LLPolyMesh::initializeForMorph()
  803. {
  804. if (!mSharedData)
  805. return;
  806. memcpy(mCoords, mSharedData->mBaseCoords, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
  807. memcpy(mNormals, mSharedData->mBaseNormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
  808. memcpy(mScaledNormals, mSharedData->mBaseNormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
  809. memcpy(mBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
  810. memcpy(mScaledBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
  811. memcpy(mTexCoords, mSharedData->mTexCoords, sizeof(LLVector2) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
  812. memset(mClothingWeights, 0, sizeof(LLVector4) * mSharedData->mNumVertices);
  813. }
  814. //-----------------------------------------------------------------------------
  815. // getMorphData()
  816. //-----------------------------------------------------------------------------
  817. LLPolyMorphData* LLPolyMesh::getMorphData(const std::string& morph_name)
  818. {
  819. if (!mSharedData)
  820. return NULL;
  821. for (LLPolyMeshSharedData::morphdata_list_t::iterator iter = mSharedData->mMorphData.begin();
  822.  iter != mSharedData->mMorphData.end(); ++iter)
  823. {
  824. LLPolyMorphData *morph_data = *iter;
  825. if (morph_data->getName() == morph_name)
  826. {
  827. return morph_data;
  828. }
  829. }
  830. return NULL;
  831. }
  832. //-----------------------------------------------------------------------------
  833. // removeMorphData()
  834. //-----------------------------------------------------------------------------
  835. // // erasing but not deleting seems bad, but fortunately we don't actually use this...
  836. // void LLPolyMesh::removeMorphData(LLPolyMorphData *morph_target)
  837. // {
  838. //  if (!mSharedData)
  839. //  return;
  840. //  mSharedData->mMorphData.erase(morph_target);
  841. // }
  842. //-----------------------------------------------------------------------------
  843. // deleteAllMorphData()
  844. //-----------------------------------------------------------------------------
  845. // void LLPolyMesh::deleteAllMorphData()
  846. // {
  847. //  if (!mSharedData)
  848. //  return;
  849. //  for_each(mSharedData->mMorphData.begin(), mSharedData->mMorphData.end(), DeletePointer());
  850. //  mSharedData->mMorphData.clear();
  851. // }
  852. //-----------------------------------------------------------------------------
  853. // getWritableWeights()
  854. //-----------------------------------------------------------------------------
  855. F32* LLPolyMesh::getWritableWeights() const
  856. {
  857. return mSharedData->mWeights;
  858. }
  859. //-----------------------------------------------------------------------------
  860. // LLPolySkeletalDistortionInfo()
  861. //-----------------------------------------------------------------------------
  862. LLPolySkeletalDistortionInfo::LLPolySkeletalDistortionInfo()
  863. {
  864. }
  865. BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node)
  866. {
  867. llassert( node->hasName( "param" ) && node->getChildByName( "param_skeleton" ) );
  868. if (!LLViewerVisualParamInfo::parseXml(node))
  869. return FALSE;
  870. LLXmlTreeNode* skeletalParam = node->getChildByName("param_skeleton");
  871. if (NULL == skeletalParam)
  872. {
  873. llwarns << "Failed to getChildByName("param_skeleton")"
  874. << llendl;
  875. return FALSE;
  876. }
  877. for( LLXmlTreeNode* bone = skeletalParam->getFirstChild(); bone; bone = skeletalParam->getNextChild() )
  878. {
  879. if (bone->hasName("bone"))
  880. {
  881. std::string name;
  882. LLVector3 scale;
  883. LLVector3 pos;
  884. BOOL haspos = FALSE;
  885. static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
  886. if (!bone->getFastAttributeString(name_string, name))
  887. {
  888. llwarns << "No bone name specified for skeletal param." << llendl;
  889. continue;
  890. }
  891. static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
  892. if (!bone->getFastAttributeVector3(scale_string, scale))
  893. {
  894. llwarns << "No scale specified for bone " << name << "." << llendl;
  895. continue;
  896. }
  897. // optional offset deformation (translation)
  898. static LLStdStringHandle offset_string = LLXmlTree::addAttributeString("offset");
  899. if (bone->getFastAttributeVector3(offset_string, pos))
  900. {
  901. haspos = TRUE;
  902. }
  903. mBoneInfoList.push_back(LLPolySkeletalBoneInfo(name, scale, pos, haspos));
  904. }
  905. else
  906. {
  907. llwarns << "Unrecognized element " << bone->getName() << " in skeletal distortion" << llendl;
  908. continue;
  909. }
  910. }
  911. return TRUE;
  912. }
  913. //-----------------------------------------------------------------------------
  914. // LLPolySkeletalDistortion()
  915. //-----------------------------------------------------------------------------
  916. LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLVOAvatar *avatarp)
  917. {
  918. mAvatar = avatarp;
  919. mDefaultVec.setVec(0.001f, 0.001f, 0.001f);
  920. }
  921. //-----------------------------------------------------------------------------
  922. // ~LLPolySkeletalDistortion()
  923. //-----------------------------------------------------------------------------
  924. LLPolySkeletalDistortion::~LLPolySkeletalDistortion()
  925. {
  926. }
  927. BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)
  928. {
  929. llassert(mInfo == NULL);
  930. if (info->mID < 0)
  931. return FALSE;
  932. mInfo = info;
  933. mID = info->mID;
  934. setWeight(getDefaultWeight(), FALSE );
  935. LLPolySkeletalDistortionInfo::bone_info_list_t::iterator iter;
  936. for (iter = getInfo()->mBoneInfoList.begin(); iter != getInfo()->mBoneInfoList.end(); iter++)
  937. {
  938. LLPolySkeletalBoneInfo *bone_info = &(*iter);
  939. LLJoint* joint = mAvatar->getJoint(bone_info->mBoneName);
  940. if (!joint)
  941. {
  942. llwarns << "Joint " << bone_info->mBoneName << " not found." << llendl;
  943. continue;
  944. }
  945. if (mJointScales.find(joint) != mJointScales.end())
  946. {
  947. llwarns << "Scale deformation already supplied for joint " << joint->getName() << "." << llendl;
  948. }
  949. // store it
  950. mJointScales[joint] = bone_info->mScaleDeformation;
  951. // apply to children that need to inherit it
  952. for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin();
  953.  iter != joint->mChildren.end(); ++iter)
  954. {
  955. LLViewerJoint* child_joint = (LLViewerJoint*)(*iter);
  956. if (child_joint->inheritScale())
  957. {
  958. LLVector3 childDeformation = LLVector3(child_joint->getScale());
  959. childDeformation.scaleVec(bone_info->mScaleDeformation);
  960. mJointScales[child_joint] = childDeformation;
  961. }
  962. }
  963. if (bone_info->mHasPositionDeformation)
  964. {
  965. if (mJointOffsets.find(joint) != mJointOffsets.end())
  966. {
  967. llwarns << "Offset deformation already supplied for joint " << joint->getName() << "." << llendl;
  968. }
  969. mJointOffsets[joint] = bone_info->mPositionDeformation;
  970. }
  971. }
  972. return TRUE;
  973. }
  974. /*virtual*/ LLViewerVisualParam* LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const
  975. {
  976. LLPolySkeletalDistortion *new_param = new LLPolySkeletalDistortion(mAvatar);
  977. *new_param = *this;
  978. return new_param;
  979. }
  980. //-----------------------------------------------------------------------------
  981. // apply()
  982. //-----------------------------------------------------------------------------
  983. void LLPolySkeletalDistortion::apply( ESex avatar_sex )
  984. {
  985. F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight();
  986. LLJoint* joint;
  987. joint_vec_map_t::iterator iter;
  988. for (iter = mJointScales.begin();
  989.  iter != mJointScales.end();
  990.  iter++)
  991. {
  992. joint = iter->first;
  993. LLVector3 newScale = joint->getScale();
  994. LLVector3 scaleDelta = iter->second;
  995. newScale = newScale + (effective_weight * scaleDelta) - (mLastWeight * scaleDelta);
  996. joint->setScale(newScale);
  997. }
  998. for (iter = mJointOffsets.begin();
  999.  iter != mJointOffsets.end();
  1000.  iter++)
  1001. {
  1002. joint = iter->first;
  1003. LLVector3 newPosition = joint->getPosition();
  1004. LLVector3 positionDelta = iter->second;
  1005. newPosition = newPosition + (effective_weight * positionDelta) - (mLastWeight * positionDelta);
  1006. joint->setPosition(newPosition);
  1007. }
  1008. if (mLastWeight != mCurWeight && !mIsAnimating)
  1009. {
  1010. mAvatar->setSkeletonSerialNum(mAvatar->getSkeletonSerialNum() + 1);
  1011. }
  1012. mLastWeight = mCurWeight;
  1013. }
  1014. // End