diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llpolymesh.cpp | |
parent | README.txt (diff) | |
download | meta-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.cpp | 1136 |
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 | |||
47 | extern LLControlGroup gSavedSettings; // read only | ||
48 | |||
49 | //----------------------------------------------------------------------------- | ||
50 | // Global table of loaded LLPolyMeshes | ||
51 | //----------------------------------------------------------------------------- | ||
52 | LLPolyMesh::LLPolyMeshSharedDataTable LLPolyMesh::sGlobalSharedMeshList; | ||
53 | |||
54 | //----------------------------------------------------------------------------- | ||
55 | // LLPolyMeshSharedData() | ||
56 | //----------------------------------------------------------------------------- | ||
57 | LLPolyMeshSharedData::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 | //----------------------------------------------------------------------------- | ||
86 | LLPolyMeshSharedData::~LLPolyMeshSharedData() | ||
87 | { | ||
88 | freeMeshData(); | ||
89 | mMorphData.deleteAllData(); | ||
90 | } | ||
91 | |||
92 | //----------------------------------------------------------------------------- | ||
93 | // setupLOD() | ||
94 | //----------------------------------------------------------------------------- | ||
95 | void 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 | //----------------------------------------------------------------------------- | ||
115 | void 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 | ||
155 | int compare_int(const void *a, const void *b); | ||
156 | |||
157 | //----------------------------------------------------------------------------- | ||
158 | // genIndices() | ||
159 | //----------------------------------------------------------------------------- | ||
160 | void 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 | //-------------------------------------------------------------------- | ||
187 | U32 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 | //----------------------------------------------------------------------------- | ||
218 | BOOL 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 | //----------------------------------------------------------------------------- | ||
238 | BOOL 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 | //----------------------------------------------------------------------------- | ||
249 | BOOL LLPolyMeshSharedData::allocateJointNames( U32 numJointNames ) | ||
250 | { | ||
251 | mJointNames = new std::string[ numJointNames ]; | ||
252 | mNumJointNames = numJointNames; | ||
253 | return TRUE; | ||
254 | } | ||
255 | |||
256 | //-------------------------------------------------------------------- | ||
257 | // LLPolyMeshSharedData::loadMesh() | ||
258 | //-------------------------------------------------------------------- | ||
259 | BOOL 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 | //----------------------------------------------------------------------------- | ||
626 | const 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 | //----------------------------------------------------------------------------- | ||
638 | const 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 | //----------------------------------------------------------------------------- | ||
649 | LLPolyMesh::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 | //----------------------------------------------------------------------------- | ||
701 | LLPolyMesh::~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 | //----------------------------------------------------------------------------- | ||
726 | LLPolyMesh *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 | //----------------------------------------------------------------------------- | ||
767 | void 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 | |||
786 | LLPolyMeshSharedData *LLPolyMesh::getSharedData() const | ||
787 | { | ||
788 | return mSharedData; | ||
789 | } | ||
790 | |||
791 | |||
792 | //-------------------------------------------------------------------- | ||
793 | // LLPolyMesh::dumpDiagInfo() | ||
794 | //-------------------------------------------------------------------- | ||
795 | void 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 | //----------------------------------------------------------------------------- | ||
838 | const LLVector3 *LLPolyMesh::getCoords() const | ||
839 | { | ||
840 | return mCoords; | ||
841 | } | ||
842 | |||
843 | //----------------------------------------------------------------------------- | ||
844 | // getWritableCoords() | ||
845 | //----------------------------------------------------------------------------- | ||
846 | LLVector3 *LLPolyMesh::getWritableCoords() | ||
847 | { | ||
848 | return mCoords; | ||
849 | } | ||
850 | |||
851 | //----------------------------------------------------------------------------- | ||
852 | // getWritableNormals() | ||
853 | //----------------------------------------------------------------------------- | ||
854 | LLVector3 *LLPolyMesh::getWritableNormals() | ||
855 | { | ||
856 | return mNormals; | ||
857 | } | ||
858 | |||
859 | //----------------------------------------------------------------------------- | ||
860 | // getWritableBinormals() | ||
861 | //----------------------------------------------------------------------------- | ||
862 | LLVector3 *LLPolyMesh::getWritableBinormals() | ||
863 | { | ||
864 | return mBinormals; | ||
865 | } | ||
866 | |||
867 | |||
868 | //----------------------------------------------------------------------------- | ||
869 | // getWritableClothingWeights() | ||
870 | //----------------------------------------------------------------------------- | ||
871 | LLVector4 *LLPolyMesh::getWritableClothingWeights() | ||
872 | { | ||
873 | return mClothingWeights; | ||
874 | } | ||
875 | |||
876 | //----------------------------------------------------------------------------- | ||
877 | // getWritableTexCoords() | ||
878 | //----------------------------------------------------------------------------- | ||
879 | LLVector2 *LLPolyMesh::getWritableTexCoords() | ||
880 | { | ||
881 | return mTexCoords; | ||
882 | } | ||
883 | |||
884 | //----------------------------------------------------------------------------- | ||
885 | // getScaledNormals() | ||
886 | //----------------------------------------------------------------------------- | ||
887 | LLVector3 *LLPolyMesh::getScaledNormals() | ||
888 | { | ||
889 | return mScaledNormals; | ||
890 | } | ||
891 | |||
892 | //----------------------------------------------------------------------------- | ||
893 | // getScaledBinormals() | ||
894 | //----------------------------------------------------------------------------- | ||
895 | LLVector3 *LLPolyMesh::getScaledBinormals() | ||
896 | { | ||
897 | return mScaledBinormals; | ||
898 | } | ||
899 | |||
900 | |||
901 | //----------------------------------------------------------------------------- | ||
902 | // initializeForMorph() | ||
903 | //----------------------------------------------------------------------------- | ||
904 | void 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 | //----------------------------------------------------------------------------- | ||
921 | LLPolyMorphData* 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 | //----------------------------------------------------------------------------- | ||
939 | void LLPolyMesh::removeMorphData(LLPolyMorphData *morph_target) | ||
940 | { | ||
941 | if (!mSharedData) return; | ||
942 | |||
943 | mSharedData->mMorphData.removeData(morph_target); | ||
944 | } | ||
945 | |||
946 | //----------------------------------------------------------------------------- | ||
947 | // deleteAllMorphData() | ||
948 | //----------------------------------------------------------------------------- | ||
949 | void LLPolyMesh::deleteAllMorphData() | ||
950 | { | ||
951 | if (!mSharedData) return; | ||
952 | |||
953 | mSharedData->mMorphData.deleteAllData(); | ||
954 | } | ||
955 | |||
956 | //----------------------------------------------------------------------------- | ||
957 | // getWeights() | ||
958 | //----------------------------------------------------------------------------- | ||
959 | const F32* LLPolyMesh::getWeights() const | ||
960 | { | ||
961 | return mSharedData->mWeights; | ||
962 | } | ||
963 | |||
964 | //----------------------------------------------------------------------------- | ||
965 | // getWritableWeights() | ||
966 | //----------------------------------------------------------------------------- | ||
967 | F32* LLPolyMesh::getWritableWeights() const | ||
968 | { | ||
969 | return mSharedData->mWeights; | ||
970 | } | ||
971 | |||
972 | //----------------------------------------------------------------------------- | ||
973 | // LLPolySkeletalDistortionInfo() | ||
974 | //----------------------------------------------------------------------------- | ||
975 | LLPolySkeletalDistortionInfo::LLPolySkeletalDistortionInfo() | ||
976 | { | ||
977 | } | ||
978 | |||
979 | BOOL 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 | //----------------------------------------------------------------------------- | ||
1031 | LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLVOAvatar *avatarp) | ||
1032 | { | ||
1033 | mAvatar = avatarp; | ||
1034 | mDefaultVec.setVec(0.001f, 0.001f, 0.001f); | ||
1035 | } | ||
1036 | |||
1037 | //----------------------------------------------------------------------------- | ||
1038 | // ~LLPolySkeletalDistortion() | ||
1039 | //----------------------------------------------------------------------------- | ||
1040 | LLPolySkeletalDistortion::~LLPolySkeletalDistortion() | ||
1041 | { | ||
1042 | } | ||
1043 | |||
1044 | BOOL 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 | //----------------------------------------------------------------------------- | ||
1100 | void 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 | ||