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