aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcharacter/lljoint.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/llcharacter/lljoint.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/llcharacter/lljoint.cpp')
-rw-r--r--linden/indra/llcharacter/lljoint.cpp523
1 files changed, 523 insertions, 0 deletions
diff --git a/linden/indra/llcharacter/lljoint.cpp b/linden/indra/llcharacter/lljoint.cpp
new file mode 100644
index 0000000..4ef9835
--- /dev/null
+++ b/linden/indra/llcharacter/lljoint.cpp
@@ -0,0 +1,523 @@
1/**
2 * @file lljoint.cpp
3 * @brief Implementation of LLJoint 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 "linden_common.h"
32
33#include "lljoint.h"
34
35#include "llmath.h"
36
37S32 LLJoint::sNumUpdates = 0;
38S32 LLJoint::sNumTouches = 0;
39
40//-----------------------------------------------------------------------------
41// LLJoint()
42// Class Constructor
43//-----------------------------------------------------------------------------
44LLJoint::LLJoint()
45{
46 mName = "unnamed";
47 mParent = NULL;
48 mXform.setScaleChildOffset(TRUE);
49 mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f));
50 mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY;
51 mUpdateXform = TRUE;
52 mJointNum = -1;
53 touch();
54}
55
56
57//-----------------------------------------------------------------------------
58// LLJoint()
59// Class Constructor
60//-----------------------------------------------------------------------------
61LLJoint::LLJoint(const std::string &name, LLJoint *parent)
62{
63 mName = "unnamed";
64 mParent = NULL;
65 mXform.setScaleChildOffset(TRUE);
66 mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f));
67 mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY;
68 mJointNum = 0;
69
70 setName(name);
71 if (parent)
72 parent->addChild( this );
73
74 touch();
75}
76
77//-----------------------------------------------------------------------------
78// ~LLJoint()
79// Class Destructor
80//-----------------------------------------------------------------------------
81LLJoint::~LLJoint()
82{
83 removeAllChildren();
84}
85
86
87//-----------------------------------------------------------------------------
88// setup()
89//-----------------------------------------------------------------------------
90void LLJoint::setup(const std::string &name, LLJoint *parent)
91{
92 setName(name);
93 if (parent)
94 parent->addChild( this );
95}
96
97//-----------------------------------------------------------------------------
98// touch()
99// Sets all dirty flags for all children, recursively.
100//-----------------------------------------------------------------------------
101void LLJoint::touch(U32 flags)
102{
103 if ((flags | mDirtyFlags) != mDirtyFlags)
104 {
105 sNumTouches++;
106 mDirtyFlags |= flags;
107 U32 child_flags = flags;
108 if (flags & ROTATION_DIRTY)
109 {
110 child_flags |= POSITION_DIRTY;
111 }
112
113 for ( LLJoint *joint = mChildren.getFirstData();
114 joint != NULL;
115 joint = mChildren.getNextData() )
116 {
117 joint->touch(child_flags);
118 }
119 }
120}
121
122//-----------------------------------------------------------------------------
123// getRoot()
124//-----------------------------------------------------------------------------
125LLJoint *LLJoint::getRoot()
126{
127 if ( getParent() == NULL )
128 {
129 return this;
130 }
131 return getParent()->getRoot();
132}
133
134
135//-----------------------------------------------------------------------------
136// findJoint()
137//-----------------------------------------------------------------------------
138LLJoint *LLJoint::findJoint( const std::string &name )
139{
140 if (name == getName())
141 return this;
142
143 for ( LLJoint *j = mChildren.getFirstData();
144 j != NULL;
145 j = mChildren.getNextData() )
146 {
147 LLJoint *found = j->findJoint(name);
148 if (found)
149 return found;
150 }
151
152 return NULL;
153}
154
155
156//--------------------------------------------------------------------
157// addChild()
158//--------------------------------------------------------------------
159void LLJoint::addChild(LLJoint *joint)
160{
161 if (joint->mParent)
162 joint->mParent->removeChild(joint);
163
164 mChildren.addDataAtEnd(joint);
165 joint->mXform.setParent(&mXform);
166 joint->mParent = this;
167 joint->touch();
168}
169
170
171//--------------------------------------------------------------------
172// removeChild()
173//--------------------------------------------------------------------
174void LLJoint::removeChild(LLJoint *joint)
175{
176 this->mChildren.removeData(joint);
177 joint->mXform.setParent(NULL);
178 joint->mParent = NULL;
179 joint->touch();
180}
181
182
183//--------------------------------------------------------------------
184// removeAllChildren()
185//--------------------------------------------------------------------
186void LLJoint::removeAllChildren()
187{
188 for ( LLJoint *joint = mChildren.getFirstData();
189 joint != NULL;
190 joint = mChildren.getNextData() )
191 {
192 removeChild(joint);
193 }
194}
195
196
197//--------------------------------------------------------------------
198// getPosition()
199//--------------------------------------------------------------------
200const LLVector3& LLJoint::getPosition()
201{
202 return mXform.getPosition();
203}
204
205
206//--------------------------------------------------------------------
207// setPosition()
208//--------------------------------------------------------------------
209void LLJoint::setPosition( const LLVector3& pos )
210{
211 mXform.setPosition(pos);
212 touch(MATRIX_DIRTY | POSITION_DIRTY);
213}
214
215
216//--------------------------------------------------------------------
217// getWorldPosition()
218//--------------------------------------------------------------------
219LLVector3 LLJoint::getWorldPosition()
220{
221 updateWorldPRSParent();
222 return mXform.getWorldPosition();
223}
224
225//-----------------------------------------------------------------------------
226// getLastWorldPosition()
227//-----------------------------------------------------------------------------
228LLVector3 LLJoint::getLastWorldPosition()
229{
230 return mXform.getWorldPosition();
231}
232
233
234//--------------------------------------------------------------------
235// setWorldPosition()
236//--------------------------------------------------------------------
237void LLJoint::setWorldPosition( const LLVector3& pos )
238{
239 if (mParent == NULL)
240 {
241 this->setPosition( pos );
242 return;
243 }
244
245 LLMatrix4 temp_matrix = getWorldMatrix();
246 temp_matrix.mMatrix[VW][VX] = pos.mV[VX];
247 temp_matrix.mMatrix[VW][VY] = pos.mV[VY];
248 temp_matrix.mMatrix[VW][VZ] = pos.mV[VZ];
249
250 LLMatrix4 parentWorldMatrix = mParent->getWorldMatrix();
251 LLMatrix4 invParentWorldMatrix = parentWorldMatrix.invert();
252
253 temp_matrix *= invParentWorldMatrix;
254
255 LLVector3 localPos( temp_matrix.mMatrix[VW][VX],
256 temp_matrix.mMatrix[VW][VY],
257 temp_matrix.mMatrix[VW][VZ] );
258
259 setPosition( localPos );
260}
261
262
263//--------------------------------------------------------------------
264// mXform.getRotation()
265//--------------------------------------------------------------------
266const LLQuaternion& LLJoint::getRotation()
267{
268 return mXform.getRotation();
269}
270
271
272//--------------------------------------------------------------------
273// setRotation()
274//--------------------------------------------------------------------
275void LLJoint::setRotation( const LLQuaternion& rot )
276{
277 if (rot.isFinite())
278 {
279 mXform.setRotation(rot);
280 touch(MATRIX_DIRTY | ROTATION_DIRTY);
281 }
282}
283
284
285//--------------------------------------------------------------------
286// getWorldRotation()
287//--------------------------------------------------------------------
288LLQuaternion LLJoint::getWorldRotation()
289{
290 updateWorldPRSParent();
291
292 return mXform.getWorldRotation();
293}
294
295//-----------------------------------------------------------------------------
296// getLastWorldRotation()
297//-----------------------------------------------------------------------------
298LLQuaternion LLJoint::getLastWorldRotation()
299{
300 return mXform.getWorldRotation();
301}
302
303//--------------------------------------------------------------------
304// setWorldRotation()
305//--------------------------------------------------------------------
306void LLJoint::setWorldRotation( const LLQuaternion& rot )
307{
308 if (mParent == NULL)
309 {
310 this->setRotation( rot );
311 return;
312 }
313
314 LLMatrix4 temp_mat(rot);
315
316 LLMatrix4 parentWorldMatrix = mParent->getWorldMatrix();
317 parentWorldMatrix.mMatrix[VW][VX] = 0;
318 parentWorldMatrix.mMatrix[VW][VY] = 0;
319 parentWorldMatrix.mMatrix[VW][VZ] = 0;
320
321 LLMatrix4 invParentWorldMatrix = parentWorldMatrix.invert();
322
323 temp_mat *= invParentWorldMatrix;
324
325 setRotation(LLQuaternion(temp_mat));
326}
327
328
329//--------------------------------------------------------------------
330// getScale()
331//--------------------------------------------------------------------
332const LLVector3& LLJoint::getScale()
333{
334 return mXform.getScale();
335}
336
337//--------------------------------------------------------------------
338// setScale()
339//--------------------------------------------------------------------
340void LLJoint::setScale( const LLVector3& scale )
341{
342 mXform.setScale(scale);
343 touch();
344}
345
346
347
348//--------------------------------------------------------------------
349// getWorldMatrix()
350//--------------------------------------------------------------------
351const LLMatrix4 &LLJoint::getWorldMatrix()
352{
353 updateWorldMatrixParent();
354
355 return mXform.getWorldMatrix();
356}
357
358
359//--------------------------------------------------------------------
360// setWorldMatrix()
361//--------------------------------------------------------------------
362void LLJoint::setWorldMatrix( const LLMatrix4& mat )
363{
364llinfos << "WARNING: LLJoint::setWorldMatrix() not correctly implemented yet" << llendl;
365 // extract global translation
366 LLVector3 trans( mat.mMatrix[VW][VX],
367 mat.mMatrix[VW][VY],
368 mat.mMatrix[VW][VZ] );
369
370 // extract global rotation
371 LLQuaternion rot( mat );
372
373 setWorldPosition( trans );
374 setWorldRotation( rot );
375}
376
377//-----------------------------------------------------------------------------
378// updateWorldMatrixParent()
379//-----------------------------------------------------------------------------
380void LLJoint::updateWorldMatrixParent()
381{
382 if (mDirtyFlags & MATRIX_DIRTY)
383 {
384 LLJoint *parent = getParent();
385 if (parent)
386 {
387 parent->updateWorldMatrixParent();
388 }
389 updateWorldMatrix();
390 }
391}
392
393//-----------------------------------------------------------------------------
394// updateWorldPRSParent()
395//-----------------------------------------------------------------------------
396void LLJoint::updateWorldPRSParent()
397{
398 if (mDirtyFlags & (ROTATION_DIRTY | POSITION_DIRTY))
399 {
400 LLJoint *parent = getParent();
401 if (parent)
402 {
403 parent->updateWorldPRSParent();
404 }
405
406 mXform.update();
407 mDirtyFlags &= ~(ROTATION_DIRTY | POSITION_DIRTY);
408 }
409}
410
411//-----------------------------------------------------------------------------
412// updateWorldMatrixChildren()
413//-----------------------------------------------------------------------------
414void LLJoint::updateWorldMatrixChildren()
415{
416 if (mDirtyFlags & MATRIX_DIRTY)
417 {
418 updateWorldMatrix();
419 }
420 for (LLJoint *child = mChildren.getFirstData(); child; child = mChildren.getNextData())
421 {
422 child->updateWorldMatrixChildren();
423 }
424}
425
426//-----------------------------------------------------------------------------
427// updateWorldMatrix()
428//-----------------------------------------------------------------------------
429void LLJoint::updateWorldMatrix()
430{
431 if (mDirtyFlags & MATRIX_DIRTY)
432 {
433 sNumUpdates++;
434 mXform.updateMatrix(FALSE);
435 mDirtyFlags = 0x0;
436 }
437}
438
439//--------------------------------------------------------------------
440// getSkinOffset()
441//--------------------------------------------------------------------
442const LLVector3 &LLJoint::getSkinOffset()
443{
444 return mSkinOffset;
445}
446
447
448//--------------------------------------------------------------------
449// setSkinOffset()
450//--------------------------------------------------------------------
451void LLJoint::setSkinOffset( const LLVector3& offset )
452{
453 mSkinOffset = offset;
454}
455
456//-----------------------------------------------------------------------------
457// setConstraintSilhouette()
458//-----------------------------------------------------------------------------
459void LLJoint::setConstraintSilhouette(LLDynamicArray<LLVector3>& silhouette)
460{
461 S32 i;
462
463 mConstraintSilhouette.reset();
464 for (i = 0; i < silhouette.count(); i++)
465 {
466 if (i % 2 == 1)
467 {
468 // skip normals
469 continue;
470 }
471 mConstraintSilhouette[i / 2] = silhouette[i];
472 }
473 LLQuaternion inv_parent_rotation = LLQuaternion::DEFAULT;
474
475 if (getParent())
476 {
477 inv_parent_rotation = ~getParent()->getWorldRotation();
478 }
479
480 for (i = 0; i < mConstraintSilhouette.count(); i++)
481 {
482 LLVector3 vert = mConstraintSilhouette[i];
483
484 vert -= getWorldPosition();
485 vert.normVec();
486 vert = vert * inv_parent_rotation;
487 }
488}
489
490//-----------------------------------------------------------------------------
491// clampRotation()
492//-----------------------------------------------------------------------------
493void LLJoint::clampRotation(LLQuaternion old_rot, LLQuaternion new_rot)
494{
495 LLVector3 main_axis(1.f, 0.f, 0.f);
496
497 for (LLJoint* joint = mChildren.getFirstData(); joint; joint = mChildren.getNextData())
498 {
499 if (joint->isAnimatable())
500 {
501 main_axis = joint->getPosition();
502 main_axis.normVec();
503 // only care about first animatable child
504 break;
505 }
506 }
507
508 // 2003.03.26 - This code was just using up cpu cycles. AB
509
510// LLVector3 old_axis = main_axis * old_rot;
511// LLVector3 new_axis = main_axis * new_rot;
512
513// for (S32 i = 0; i < mConstraintSilhouette.count() - 1; i++)
514// {
515// LLVector3 vert1 = mConstraintSilhouette[i];
516// LLVector3 vert2 = mConstraintSilhouette[i + 1];
517
518 // figure out how to clamp rotation to line on 3-sphere
519
520// }
521}
522
523// End