00001
00032
00033
00034
00035 #include "linden_common.h"
00036
00037 #include "lljoint.h"
00038
00039 #include "llmath.h"
00040
00041 S32 LLJoint::sNumUpdates = 0;
00042 S32 LLJoint::sNumTouches = 0;
00043
00044
00045
00046
00047
00048 LLJoint::LLJoint()
00049 {
00050 mName = "unnamed";
00051 mParent = NULL;
00052 mXform.setScaleChildOffset(TRUE);
00053 mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f));
00054 mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY;
00055 mUpdateXform = TRUE;
00056 mJointNum = -1;
00057 touch();
00058 }
00059
00060
00061
00062
00063
00064
00065 LLJoint::LLJoint(const std::string &name, LLJoint *parent)
00066 {
00067 mName = "unnamed";
00068 mParent = NULL;
00069 mXform.setScaleChildOffset(TRUE);
00070 mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f));
00071 mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY;
00072 mJointNum = 0;
00073
00074 setName(name);
00075 if (parent)
00076 {
00077 parent->addChild( this );
00078 }
00079 touch();
00080 }
00081
00082
00083
00084
00085
00086 LLJoint::~LLJoint()
00087 {
00088 if (mParent)
00089 {
00090 mParent->removeChild( this );
00091 }
00092 removeAllChildren();
00093 }
00094
00095
00096
00097
00098
00099 void LLJoint::setup(const std::string &name, LLJoint *parent)
00100 {
00101 setName(name);
00102 if (parent)
00103 {
00104 parent->addChild( this );
00105 }
00106 }
00107
00108
00109
00110
00111
00112 void LLJoint::touch(U32 flags)
00113 {
00114 if ((flags | mDirtyFlags) != mDirtyFlags)
00115 {
00116 sNumTouches++;
00117 mDirtyFlags |= flags;
00118 U32 child_flags = flags;
00119 if (flags & ROTATION_DIRTY)
00120 {
00121 child_flags |= POSITION_DIRTY;
00122 }
00123
00124 for (child_list_t::iterator iter = mChildren.begin();
00125 iter != mChildren.end(); ++iter)
00126 {
00127 LLJoint* joint = *iter;
00128 joint->touch(child_flags);
00129 }
00130 }
00131 }
00132
00133
00134
00135
00136 LLJoint *LLJoint::getRoot()
00137 {
00138 if ( getParent() == NULL )
00139 {
00140 return this;
00141 }
00142 return getParent()->getRoot();
00143 }
00144
00145
00146
00147
00148
00149 LLJoint *LLJoint::findJoint( const std::string &name )
00150 {
00151 if (name == getName())
00152 return this;
00153
00154 for (child_list_t::iterator iter = mChildren.begin();
00155 iter != mChildren.end(); ++iter)
00156 {
00157 LLJoint* joint = *iter;
00158 LLJoint *found = joint->findJoint(name);
00159 if (found)
00160 {
00161 return found;
00162 }
00163 }
00164
00165 return NULL;
00166 }
00167
00168
00169
00170
00171
00172 void LLJoint::addChild(LLJoint* joint)
00173 {
00174 if (joint->mParent)
00175 joint->mParent->removeChild(joint);
00176
00177 mChildren.push_back(joint);
00178 joint->mXform.setParent(&mXform);
00179 joint->mParent = this;
00180 joint->touch();
00181 }
00182
00183
00184
00185
00186
00187 void LLJoint::removeChild(LLJoint* joint)
00188 {
00189 child_list_t::iterator iter = std::find(mChildren.begin(), mChildren.end(), joint);
00190 if (iter != mChildren.end())
00191 {
00192 mChildren.erase(iter);
00193
00194 joint->mXform.setParent(NULL);
00195 joint->mParent = NULL;
00196 joint->touch();
00197 }
00198 }
00199
00200
00201
00202
00203
00204 void LLJoint::removeAllChildren()
00205 {
00206 for (child_list_t::iterator iter = mChildren.begin();
00207 iter != mChildren.end();)
00208 {
00209 child_list_t::iterator curiter = iter++;
00210 LLJoint* joint = *curiter;
00211 mChildren.erase(curiter);
00212 joint->mXform.setParent(NULL);
00213 joint->mParent = NULL;
00214 joint->touch();
00215 }
00216 }
00217
00218
00219
00220
00221
00222 const LLVector3& LLJoint::getPosition()
00223 {
00224 return mXform.getPosition();
00225 }
00226
00227
00228
00229
00230
00231 void LLJoint::setPosition( const LLVector3& pos )
00232 {
00233
00234 {
00235 mXform.setPosition(pos);
00236 touch(MATRIX_DIRTY | POSITION_DIRTY);
00237 }
00238 }
00239
00240
00241
00242
00243
00244 LLVector3 LLJoint::getWorldPosition()
00245 {
00246 updateWorldPRSParent();
00247 return mXform.getWorldPosition();
00248 }
00249
00250
00251
00252
00253 LLVector3 LLJoint::getLastWorldPosition()
00254 {
00255 return mXform.getWorldPosition();
00256 }
00257
00258
00259
00260
00261
00262 void LLJoint::setWorldPosition( const LLVector3& pos )
00263 {
00264 if (mParent == NULL)
00265 {
00266 this->setPosition( pos );
00267 return;
00268 }
00269
00270 LLMatrix4 temp_matrix = getWorldMatrix();
00271 temp_matrix.mMatrix[VW][VX] = pos.mV[VX];
00272 temp_matrix.mMatrix[VW][VY] = pos.mV[VY];
00273 temp_matrix.mMatrix[VW][VZ] = pos.mV[VZ];
00274
00275 LLMatrix4 parentWorldMatrix = mParent->getWorldMatrix();
00276 LLMatrix4 invParentWorldMatrix = parentWorldMatrix.invert();
00277
00278 temp_matrix *= invParentWorldMatrix;
00279
00280 LLVector3 localPos( temp_matrix.mMatrix[VW][VX],
00281 temp_matrix.mMatrix[VW][VY],
00282 temp_matrix.mMatrix[VW][VZ] );
00283
00284 setPosition( localPos );
00285 }
00286
00287
00288
00289
00290
00291 const LLQuaternion& LLJoint::getRotation()
00292 {
00293 return mXform.getRotation();
00294 }
00295
00296
00297
00298
00299
00300 void LLJoint::setRotation( const LLQuaternion& rot )
00301 {
00302 if (rot.isFinite())
00303 {
00304
00305 {
00306 mXform.setRotation(rot);
00307 touch(MATRIX_DIRTY | ROTATION_DIRTY);
00308 }
00309 }
00310 }
00311
00312
00313
00314
00315
00316 LLQuaternion LLJoint::getWorldRotation()
00317 {
00318 updateWorldPRSParent();
00319
00320 return mXform.getWorldRotation();
00321 }
00322
00323
00324
00325
00326 LLQuaternion LLJoint::getLastWorldRotation()
00327 {
00328 return mXform.getWorldRotation();
00329 }
00330
00331
00332
00333
00334 void LLJoint::setWorldRotation( const LLQuaternion& rot )
00335 {
00336 if (mParent == NULL)
00337 {
00338 this->setRotation( rot );
00339 return;
00340 }
00341
00342 LLMatrix4 temp_mat(rot);
00343
00344 LLMatrix4 parentWorldMatrix = mParent->getWorldMatrix();
00345 parentWorldMatrix.mMatrix[VW][VX] = 0;
00346 parentWorldMatrix.mMatrix[VW][VY] = 0;
00347 parentWorldMatrix.mMatrix[VW][VZ] = 0;
00348
00349 LLMatrix4 invParentWorldMatrix = parentWorldMatrix.invert();
00350
00351 temp_mat *= invParentWorldMatrix;
00352
00353 setRotation(LLQuaternion(temp_mat));
00354 }
00355
00356
00357
00358
00359
00360 const LLVector3& LLJoint::getScale()
00361 {
00362 return mXform.getScale();
00363 }
00364
00365
00366
00367
00368 void LLJoint::setScale( const LLVector3& scale )
00369 {
00370
00371 {
00372 mXform.setScale(scale);
00373 touch();
00374 }
00375
00376 }
00377
00378
00379
00380
00381
00382
00383 const LLMatrix4 &LLJoint::getWorldMatrix()
00384 {
00385 updateWorldMatrixParent();
00386
00387 return mXform.getWorldMatrix();
00388 }
00389
00390
00391
00392
00393
00394 void LLJoint::setWorldMatrix( const LLMatrix4& mat )
00395 {
00396 llinfos << "WARNING: LLJoint::setWorldMatrix() not correctly implemented yet" << llendl;
00397
00398 LLVector3 trans( mat.mMatrix[VW][VX],
00399 mat.mMatrix[VW][VY],
00400 mat.mMatrix[VW][VZ] );
00401
00402
00403 LLQuaternion rot( mat );
00404
00405 setWorldPosition( trans );
00406 setWorldRotation( rot );
00407 }
00408
00409
00410
00411
00412 void LLJoint::updateWorldMatrixParent()
00413 {
00414 if (mDirtyFlags & MATRIX_DIRTY)
00415 {
00416 LLJoint *parent = getParent();
00417 if (parent)
00418 {
00419 parent->updateWorldMatrixParent();
00420 }
00421 updateWorldMatrix();
00422 }
00423 }
00424
00425
00426
00427
00428 void LLJoint::updateWorldPRSParent()
00429 {
00430 if (mDirtyFlags & (ROTATION_DIRTY | POSITION_DIRTY))
00431 {
00432 LLJoint *parent = getParent();
00433 if (parent)
00434 {
00435 parent->updateWorldPRSParent();
00436 }
00437
00438 mXform.update();
00439 mDirtyFlags &= ~(ROTATION_DIRTY | POSITION_DIRTY);
00440 }
00441 }
00442
00443
00444
00445
00446 void LLJoint::updateWorldMatrixChildren()
00447 {
00448 if (!this->mUpdateXform) return;
00449
00450 if (mDirtyFlags & MATRIX_DIRTY)
00451 {
00452 updateWorldMatrix();
00453 }
00454 for (child_list_t::iterator iter = mChildren.begin();
00455 iter != mChildren.end(); ++iter)
00456 {
00457 LLJoint* joint = *iter;
00458 joint->updateWorldMatrixChildren();
00459 }
00460 }
00461
00462
00463
00464
00465 void LLJoint::updateWorldMatrix()
00466 {
00467 if (mDirtyFlags & MATRIX_DIRTY)
00468 {
00469 sNumUpdates++;
00470 mXform.updateMatrix(FALSE);
00471 mDirtyFlags = 0x0;
00472 }
00473 }
00474
00475
00476
00477
00478 const LLVector3 &LLJoint::getSkinOffset()
00479 {
00480 return mSkinOffset;
00481 }
00482
00483
00484
00485
00486
00487 void LLJoint::setSkinOffset( const LLVector3& offset )
00488 {
00489 mSkinOffset = offset;
00490 }
00491
00492
00493
00494
00495
00496 void LLJoint::clampRotation(LLQuaternion old_rot, LLQuaternion new_rot)
00497 {
00498 LLVector3 main_axis(1.f, 0.f, 0.f);
00499
00500 for (child_list_t::iterator iter = mChildren.begin();
00501 iter != mChildren.end(); ++iter)
00502 {
00503 LLJoint* joint = *iter;
00504 if (joint->isAnimatable())
00505 {
00506 main_axis = joint->getPosition();
00507 main_axis.normVec();
00508
00509 break;
00510 }
00511 }
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526 }
00527
00528