aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llviewerjoint.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/llviewerjoint.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 'linden/indra/newview/llviewerjoint.cpp')
-rw-r--r--linden/indra/newview/llviewerjoint.cpp626
1 files changed, 626 insertions, 0 deletions
diff --git a/linden/indra/newview/llviewerjoint.cpp b/linden/indra/newview/llviewerjoint.cpp
new file mode 100644
index 0000000..f8fed01
--- /dev/null
+++ b/linden/indra/newview/llviewerjoint.cpp
@@ -0,0 +1,626 @@
1/**
2 * @file llviewerjoint.cpp
3 * @brief Implementation of LLViewerJoint 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 "llviewerjoint.h"
34
35#include "llgl.h"
36#include "llmath.h"
37#include "llglheaders.h"
38#include "llsphere.h"
39#include "llvoavatar.h"
40#include "pipeline.h"
41
42#define DEFAULT_LOD 0.0f
43
44const S32 MIN_PIXEL_AREA_3PASS_HAIR = 64*64;
45
46//-----------------------------------------------------------------------------
47// Static Data
48//-----------------------------------------------------------------------------
49BOOL LLViewerJoint::sDisableLOD = FALSE;
50
51//-----------------------------------------------------------------------------
52// LLViewerJoint()
53// Class Constructor
54//-----------------------------------------------------------------------------
55LLViewerJoint::LLViewerJoint()
56{
57 mUpdateXform = TRUE;
58 mValid = FALSE;
59 mComponents = SC_JOINT | SC_BONE | SC_AXES;
60 mMinPixelArea = DEFAULT_LOD;
61 mPickName = PN_DEFAULT;
62 mVisible = TRUE;
63}
64
65
66//-----------------------------------------------------------------------------
67// LLViewerJoint()
68// Class Constructor
69//-----------------------------------------------------------------------------
70LLViewerJoint::LLViewerJoint(const std::string &name, LLJoint *parent) :
71 LLJoint(name, parent)
72{
73 mValid = FALSE;
74 mComponents = SC_JOINT | SC_BONE | SC_AXES;
75 mMinPixelArea = DEFAULT_LOD;
76 mPickName = PN_DEFAULT;
77}
78
79
80//-----------------------------------------------------------------------------
81// ~LLViewerJoint()
82// Class Destructor
83//-----------------------------------------------------------------------------
84LLViewerJoint::~LLViewerJoint()
85{
86}
87
88
89//--------------------------------------------------------------------
90// setValid()
91//--------------------------------------------------------------------
92void LLViewerJoint::setValid( BOOL valid, BOOL recursive )
93{
94 //----------------------------------------------------------------
95 // set visibility for this joint
96 //----------------------------------------------------------------
97 mValid = valid;
98
99 //----------------------------------------------------------------
100 // set visibility for children
101 //----------------------------------------------------------------
102 if (recursive)
103 {
104 for ( LLViewerJoint *joint = (LLViewerJoint*)mChildren.getFirstData();
105 joint != NULL;
106 joint = (LLViewerJoint*)mChildren.getNextData() )
107 {
108 joint->setValid(valid, TRUE);
109 }
110 }
111
112}
113
114//--------------------------------------------------------------------
115// renderSkeleton()
116//--------------------------------------------------------------------
117void LLViewerJoint::renderSkeleton(BOOL recursive)
118{
119 F32 nc = 0.57735f;
120
121 //----------------------------------------------------------------
122 // push matrix stack
123 //----------------------------------------------------------------
124 glPushMatrix();
125
126 //----------------------------------------------------------------
127 // render the bone to my parent
128 //----------------------------------------------------------------
129 if (mComponents & SC_BONE)
130 {
131 drawBone();
132 }
133
134 //----------------------------------------------------------------
135 // offset to joint position and
136 // rotate to our orientation
137 //----------------------------------------------------------------
138 glLoadIdentity();
139 glMultMatrixf( &getWorldMatrix().mMatrix[0][0] );
140
141 //----------------------------------------------------------------
142 // render joint axes
143 //----------------------------------------------------------------
144 if (mComponents & SC_AXES)
145 {
146 glBegin(GL_LINES);
147 glColor3f( 1.0f, 0.0f, 0.0f );
148 glVertex3f( 0.0f, 0.0f, 0.0f );
149 glVertex3f( 0.1f, 0.0f, 0.0f );
150
151 glColor3f( 0.0f, 1.0f, 0.0f );
152 glVertex3f( 0.0f, 0.0f, 0.0f );
153 glVertex3f( 0.0f, 0.1f, 0.0f );
154
155 glColor3f( 0.0f, 0.0f, 1.0f );
156 glVertex3f( 0.0f, 0.0f, 0.0f );
157 glVertex3f( 0.0f, 0.0f, 0.1f );
158 glEnd();
159 }
160
161 //----------------------------------------------------------------
162 // render the joint graphic
163 //----------------------------------------------------------------
164 if (mComponents & SC_JOINT)
165 {
166 glColor3f( 1.0f, 1.0f, 0.0f );
167
168 glBegin(GL_TRIANGLES);
169
170 // joint top half
171 glNormal3f(nc, nc, nc);
172 glVertex3f(0.0f, 0.0f, 0.05f);
173 glVertex3f(0.05f, 0.0f, 0.0f);
174 glVertex3f(0.0f, 0.05f, 0.0f);
175
176 glNormal3f(-nc, nc, nc);
177 glVertex3f(0.0f, 0.0f, 0.05f);
178 glVertex3f(0.0f, 0.05f, 0.0f);
179 glVertex3f(-0.05f, 0.0f, 0.0f);
180
181 glNormal3f(-nc, -nc, nc);
182 glVertex3f(0.0f, 0.0f, 0.05f);
183 glVertex3f(-0.05f, 0.0f, 0.0f);
184 glVertex3f(0.0f, -0.05f, 0.0f);
185
186 glNormal3f(nc, -nc, nc);
187 glVertex3f(0.0f, 0.0f, 0.05f);
188 glVertex3f(0.0f, -0.05f, 0.0f);
189 glVertex3f(0.05f, 0.0f, 0.0f);
190
191 // joint bottom half
192 glNormal3f(nc, nc, -nc);
193 glVertex3f(0.0f, 0.0f, -0.05f);
194 glVertex3f(0.0f, 0.05f, 0.0f);
195 glVertex3f(0.05f, 0.0f, 0.0f);
196
197 glNormal3f(-nc, nc, -nc);
198 glVertex3f(0.0f, 0.0f, -0.05f);
199 glVertex3f(-0.05f, 0.0f, 0.0f);
200 glVertex3f(0.0f, 0.05f, 0.0f);
201
202 glNormal3f(-nc, -nc, -nc);
203 glVertex3f(0.0f, 0.0f, -0.05f);
204 glVertex3f(0.0f, -0.05f, 0.0f);
205 glVertex3f(-0.05f, 0.0f, 0.0f);
206
207 glNormal3f(nc, -nc, -nc);
208 glVertex3f(0.0f, 0.0f, -0.05f);
209 glVertex3f(0.05f, 0.0f, 0.0f);
210 glVertex3f(0.0f, -0.05f, 0.0f);
211
212 glEnd();
213 }
214
215 //----------------------------------------------------------------
216 // render children
217 //----------------------------------------------------------------
218 if (recursive)
219 {
220 for ( LLViewerJoint *joint = (LLViewerJoint*)mChildren.getFirstData();
221 joint != NULL;
222 joint = (LLViewerJoint*)mChildren.getNextData() )
223 {
224 joint->renderSkeleton();
225 }
226 }
227
228 //----------------------------------------------------------------
229 // pop matrix stack
230 //----------------------------------------------------------------
231 glPopMatrix();
232}
233
234
235//--------------------------------------------------------------------
236// render()
237//--------------------------------------------------------------------
238U32 LLViewerJoint::render( F32 pixelArea )
239{
240 U32 triangle_count = 0;
241
242 //----------------------------------------------------------------
243 // ignore invisible objects
244 //----------------------------------------------------------------
245 if ( mValid )
246 {
247
248 //----------------------------------------------------------------
249 // if object is transparent, defer it, otherwise
250 // give the joint subclass a chance to draw itself
251 //----------------------------------------------------------------
252 if ( gRenderForSelect )
253 {
254 triangle_count += drawShape( pixelArea );
255 }
256 else if ( isTransparent() )
257 {
258 LLGLEnable blend(GL_BLEND);
259 // Hair and Skirt
260 if ((pixelArea > MIN_PIXEL_AREA_3PASS_HAIR))
261 {
262 // render all three passes
263 LLGLEnable alpha_test(GL_ALPHA_TEST);
264 LLGLDisable cull(GL_CULL_FACE);
265 // first pass renders without writing to the z buffer
266 {
267 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
268 triangle_count += drawShape( pixelArea );
269 }
270 // second pass writes to z buffer only
271 glColorMask(FALSE, FALSE, FALSE, FALSE);
272 {
273 triangle_count += drawShape( pixelArea );
274 }
275 // third past respects z buffer and writes color
276 glColorMask(TRUE, TRUE, TRUE, TRUE);
277 {
278 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
279 triangle_count += drawShape( pixelArea );
280 }
281 }
282 else
283 {
284 LLGLEnable alpha_test(GL_ALPHA_TEST);
285 // Render Inside (no Z buffer write)
286 glCullFace(GL_FRONT);
287 {
288 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
289 triangle_count += drawShape( pixelArea );
290 }
291 // Render Outside (write to the Z buffer)
292 glCullFace(GL_BACK);
293 {
294 triangle_count += drawShape( pixelArea );
295 }
296 }
297 }
298 else
299 {
300 // set up render state
301 LLGLDisable blend(GL_BLEND);
302 LLGLSPipelineAvatar gls_pipeline_avatar;
303 triangle_count += drawShape( pixelArea );
304 }
305 }
306
307 //----------------------------------------------------------------
308 // render children
309 //----------------------------------------------------------------
310 LLViewerJoint *joint;
311 for ( joint = (LLViewerJoint *)mChildren.getFirstData();
312 joint != NULL;
313 joint = (LLViewerJoint *)mChildren.getNextData() )
314 {
315 F32 jointLOD = joint->getLOD();
316 if (pixelArea >= jointLOD || sDisableLOD)
317 {
318 triangle_count += joint->render( pixelArea );
319
320 if (jointLOD != DEFAULT_LOD)
321 {
322 break;
323 }
324 }
325 }
326
327 glColorMask(TRUE, TRUE, TRUE, TRUE);
328 return triangle_count;
329}
330
331
332//--------------------------------------------------------------------
333// drawBone()
334//--------------------------------------------------------------------
335void LLViewerJoint::drawBone()
336{
337 if ( mParent == NULL )
338 return;
339
340 F32 boneSize = 0.02f;
341
342 // rotate to point to child (bone direction)
343 glPushMatrix();
344
345 LLVector3 boneX = getPosition();
346 F32 length = boneX.normVec();
347
348 LLVector3 boneZ(1.0f, 0.0f, 1.0f);
349
350 LLVector3 boneY = boneZ % boneX;
351 boneY.normVec();
352
353 boneZ = boneX % boneY;
354
355 LLMatrix4 rotateMat;
356 rotateMat.setFwdRow( boneX );
357 rotateMat.setLeftRow( boneY );
358 rotateMat.setUpRow( boneZ );
359 glMultMatrixf( &rotateMat.mMatrix[0][0] );
360
361 // render the bone
362 glColor3f( 0.5f, 0.5f, 0.0f );
363
364 glBegin(GL_TRIANGLES);
365
366 glVertex3f( length, 0.0f, 0.0f);
367 glVertex3f( 0.0f, boneSize, 0.0f);
368 glVertex3f( 0.0f, 0.0f, boneSize);
369
370 glVertex3f( length, 0.0f, 0.0f);
371 glVertex3f( 0.0f, 0.0f, -boneSize);
372 glVertex3f( 0.0f, boneSize, 0.0f);
373
374 glVertex3f( length, 0.0f, 0.0f);
375 glVertex3f( 0.0f, -boneSize, 0.0f);
376 glVertex3f( 0.0f, 0.0f, -boneSize);
377
378 glVertex3f( length, 0.0f, 0.0f);
379 glVertex3f( 0.0f, 0.0f, boneSize);
380 glVertex3f( 0.0f, -boneSize, 0.0f);
381
382 glEnd();
383
384 // restore matrix
385 glPopMatrix();
386}
387
388//--------------------------------------------------------------------
389// isTransparent()
390//--------------------------------------------------------------------
391BOOL LLViewerJoint::isTransparent()
392{
393 return FALSE;
394}
395
396//--------------------------------------------------------------------
397// drawShape()
398//--------------------------------------------------------------------
399U32 LLViewerJoint::drawShape( F32 pixelArea )
400{
401 return 0;
402}
403
404//--------------------------------------------------------------------
405// setSkeletonComponents()
406//--------------------------------------------------------------------
407void LLViewerJoint::setSkeletonComponents( U32 comp, BOOL recursive )
408{
409 mComponents = comp;
410 if (recursive)
411 {
412 for ( LLViewerJoint *joint = (LLViewerJoint *)mChildren.getFirstData();
413 joint != NULL;
414 joint = (LLViewerJoint *)mChildren.getNextData() )
415 {
416 joint->setSkeletonComponents(comp, recursive);
417 }
418 }
419}
420
421void LLViewerJoint::updateFaceSizes(U32 &num_vertices, F32 pixel_area)
422{
423 for ( LLViewerJoint *joint = (LLViewerJoint*)mChildren.getFirstData();
424 joint != NULL;
425 joint = (LLViewerJoint*)mChildren.getNextData() )
426 {
427 F32 jointLOD = joint->getLOD();
428 if (pixel_area >= jointLOD || sDisableLOD)
429 {
430 joint->updateFaceSizes(num_vertices, pixel_area);
431
432 if (jointLOD != DEFAULT_LOD)
433 {
434 break;
435 }
436 }
437 }
438}
439
440void LLViewerJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind)
441{
442 for ( LLViewerJoint *joint = (LLViewerJoint*)mChildren.getFirstData();
443 joint != NULL;
444 joint = (LLViewerJoint*)mChildren.getNextData() )
445 {
446 F32 jointLOD = joint->getLOD();
447 if (pixel_area >= jointLOD || sDisableLOD)
448 {
449 joint->updateFaceData(face, pixel_area, damp_wind);
450
451 if (jointLOD != DEFAULT_LOD)
452 {
453 break;
454 }
455 }
456 }
457}
458
459
460BOOL LLViewerJoint::updateLOD(F32 pixel_area, BOOL activate)
461{
462 BOOL lod_changed = FALSE;
463 BOOL found_lod = FALSE;
464
465 for ( LLViewerJoint *joint = (LLViewerJoint*)mChildren.getFirstData();
466 joint != NULL;
467 joint = (LLViewerJoint*)mChildren.getNextData() )
468 {
469 F32 jointLOD = joint->getLOD();
470
471 if (found_lod || jointLOD == DEFAULT_LOD)
472 {
473 // we've already found a joint to enable, so enable the rest as alternatives
474 lod_changed |= joint->updateLOD(pixel_area, TRUE);
475 }
476 else
477 {
478 if (pixel_area >= jointLOD || sDisableLOD)
479 {
480 lod_changed |= joint->updateLOD(pixel_area, TRUE);
481 found_lod = TRUE;
482 }
483 else
484 {
485 lod_changed |= joint->updateLOD(pixel_area, FALSE);
486 }
487 }
488 }
489 return lod_changed;
490}
491
492void LLViewerJoint::dump()
493{
494 for ( LLViewerJoint *joint = (LLViewerJoint*)mChildren.getFirstData();
495 joint != NULL;
496 joint = (LLViewerJoint*)mChildren.getNextData() )
497 {
498 joint->dump();
499 }
500}
501
502void LLViewerJoint::setVisible(BOOL visible, BOOL recursive)
503{
504 mVisible = visible;
505
506 if (recursive)
507 {
508 for ( LLViewerJoint *joint = (LLViewerJoint*)mChildren.getFirstData();
509 joint != NULL;
510 joint = (LLViewerJoint*)mChildren.getNextData() )
511 {
512 joint->setVisible(visible, recursive);
513 }
514 }
515}
516
517void LLViewerJoint::writeCAL3D(apr_file_t* fp)
518{
519 LLVector3 bone_pos = mXform.getPosition();
520 if (mParent)
521 {
522 bone_pos.scaleVec(mParent->getScale());
523 bone_pos *= 100.f;
524 }
525 else
526 {
527 bone_pos.clearVec();
528 }
529
530 LLQuaternion bone_rot;
531
532 S32 num_children = 0;
533 for (LLViewerJoint *joint = (LLViewerJoint*)mChildren.getFirstData();
534 joint != NULL;
535 joint = (LLViewerJoint*)mChildren.getNextData() )
536 {
537 if (joint->mJointNum != -1)
538 {
539 num_children++;
540 }
541 }
542
543 LLJoint* cur_joint = this;
544 LLVector3 rootSkinOffset;
545 if (mParent)
546 {
547 while (cur_joint)
548 {
549 rootSkinOffset -= cur_joint->getSkinOffset();
550 cur_joint = (LLViewerJoint*)cur_joint->getParent();
551 }
552
553 rootSkinOffset *= 100.f;
554 }
555
556 apr_file_printf(fp, " <BONE ID=\"%d\" NAME=\"%s\" NUMCHILDS=\"%d\">\n", mJointNum + 1, mName.c_str(), num_children);
557 apr_file_printf(fp, " <TRANSLATION>%.6f %.6f %.6f</TRANSLATION>\n", bone_pos.mV[VX], bone_pos.mV[VY], bone_pos.mV[VZ]);
558 apr_file_printf(fp, " <ROTATION>%.6f %.6f %.6f %.6f</ROTATION>\n", bone_rot.mQ[VX], bone_rot.mQ[VY], bone_rot.mQ[VZ], bone_rot.mQ[VW]);
559 apr_file_printf(fp, " <LOCALTRANSLATION>%.6f %.6f %.6f</LOCALTRANSLATION>\n", rootSkinOffset.mV[VX], rootSkinOffset.mV[VY], rootSkinOffset.mV[VZ]);
560 apr_file_printf(fp, " <LOCALROTATION>0 0 0 1</LOCALROTATION>\n");
561 apr_file_printf(fp, " <PARENTID>%d</PARENTID>\n", mParent ? mParent->mJointNum + 1 : -1);
562
563 for (LLViewerJoint *joint = (LLViewerJoint*)mChildren.getFirstData();
564 joint != NULL;
565 joint = (LLViewerJoint*)mChildren.getNextData() )
566 {
567 if (joint->mJointNum != -1)
568 {
569 apr_file_printf(fp, " <CHILDID>%d</CHILDID>\n", joint->mJointNum + 1);
570 }
571 }
572 apr_file_printf(fp, " </BONE>\n");
573
574 // recurse
575 for (LLViewerJoint *joint = (LLViewerJoint*)mChildren.getFirstData();
576 joint != NULL;
577 joint = (LLViewerJoint*)mChildren.getNextData() )
578 {
579 if (joint->mJointNum != -1)
580 {
581 joint->writeCAL3D(fp);
582 }
583 }
584
585}
586
587//-----------------------------------------------------------------------------
588// LLViewerJointCollisionVolume()
589//-----------------------------------------------------------------------------
590
591LLViewerJointCollisionVolume::LLViewerJointCollisionVolume()
592{
593 mUpdateXform = FALSE;
594}
595
596LLViewerJointCollisionVolume::LLViewerJointCollisionVolume(const std::string &name, LLJoint *parent) : LLViewerJoint(name, parent)
597{
598
599}
600
601void LLViewerJointCollisionVolume::render()
602{
603 updateWorldMatrix();
604 glMatrixMode(GL_MODELVIEW);
605 glPushMatrix();
606 glMultMatrixf( &mXform.getWorldMatrix().mMatrix[0][0] );
607
608 glColor3f( 0.f, 0.f, 1.f );
609 gSphere.render();
610
611 glPopMatrix();
612}
613
614LLVector3 LLViewerJointCollisionVolume::getVolumePos(LLVector3 &offset)
615{
616 mUpdateXform = TRUE;
617
618 LLVector3 result = offset;
619 result.scaleVec(getScale());
620 result.rotVec(getWorldRotation());
621 result += getWorldPosition();
622
623 return result;
624}
625
626// End