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 this->mChildren.erase(iter);
00193 }
00194 joint->mXform.setParent(NULL);
00195 joint->mParent = NULL;
00196 joint->touch();
00197 }
00198
00199
00200
00201
00202
00203 void LLJoint::removeAllChildren()
00204 {
00205 for (child_list_t::iterator iter = mChildren.begin();
00206 iter != mChildren.end();)
00207 {
00208 child_list_t::iterator curiter = iter++;
00209 LLJoint* joint = *curiter;
00210 mChildren.erase(curiter);
00211 joint->mXform.setParent(NULL);
00212 joint->mParent = NULL;
00213 joint->touch();
00214 }
00215 }
00216
00217
00218
00219
00220
00221 const LLVector3& LLJoint::getPosition()
00222 {
00223 return mXform.getPosition();
00224 }
00225
00226
00227
00228
00229
00230 void LLJoint::setPosition( const LLVector3& pos )
00231 {
00232
00233 {
00234 mXform.setPosition(pos);
00235 touch(MATRIX_DIRTY | POSITION_DIRTY);
00236 }
00237 }
00238
00239
00240
00241
00242
00243 LLVector3 LLJoint::getWorldPosition()
00244 {
00245 updateWorldPRSParent();
00246 return mXform.getWorldPosition();
00247 }
00248
00249
00250
00251
00252 LLVector3 LLJoint::getLastWorldPosition()
00253 {
00254 return mXform.getWorldPosition();
00255 }
00256
00257
00258
00259
00260
00261 void LLJoint::setWorldPosition( const LLVector3& pos )
00262 {
00263 if (mParent == NULL)
00264 {
00265 this->setPosition( pos );
00266 return;
00267 }
00268
00269 LLMatrix4 temp_matrix = getWorldMatrix();
00270 temp_matrix.mMatrix[VW][VX] = pos.mV[VX];
00271 temp_matrix.mMatrix[VW][VY] = pos.mV[VY];
00272 temp_matrix.mMatrix[VW][VZ] = pos.mV[VZ];
00273
00274 LLMatrix4 parentWorldMatrix = mParent->getWorldMatrix();
00275 LLMatrix4 invParentWorldMatrix = parentWorldMatrix.invert();
00276
00277 temp_matrix *= invParentWorldMatrix;
00278
00279 LLVector3 localPos( temp_matrix.mMatrix[VW][VX],
00280 temp_matrix.mMatrix[VW][VY],
00281 temp_matrix.mMatrix[VW][VZ] );
00282
00283 setPosition( localPos );
00284 }
00285
00286
00287
00288
00289
00290 const LLQuaternion& LLJoint::getRotation()
00291 {
00292 return mXform.getRotation();
00293 }
00294
00295
00296
00297
00298
00299 void LLJoint::setRotation( const LLQuaternion& rot )
00300 {
00301 if (rot.isFinite())
00302 {
00303
00304 {
00305 mXform.setRotation(rot);
00306 touch(MATRIX_DIRTY | ROTATION_DIRTY);
00307 }
00308 }
00309 }
00310
00311
00312
00313
00314
00315 LLQuaternion LLJoint::getWorldRotation()
00316 {
00317 updateWorldPRSParent();
00318
00319 return mXform.getWorldRotation();
00320 }
00321
00322
00323
00324
00325 LLQuaternion LLJoint::getLastWorldRotation()
00326 {
00327 return mXform.getWorldRotation();
00328 }
00329
00330
00331
00332
00333 void LLJoint::setWorldRotation( const LLQuaternion& rot )
00334 {
00335 if (mParent == NULL)
00336 {
00337 this->setRotation( rot );
00338 return;
00339 }
00340
00341 LLMatrix4 temp_mat(rot);
00342
00343 LLMatrix4 parentWorldMatrix = mParent->getWorldMatrix();
00344 parentWorldMatrix.mMatrix[VW][VX] = 0;
00345 parentWorldMatrix.mMatrix[VW][VY] = 0;
00346 parentWorldMatrix.mMatrix[VW][VZ] = 0;
00347
00348 LLMatrix4 invParentWorldMatrix = parentWorldMatrix.invert();
00349
00350 temp_mat *= invParentWorldMatrix;
00351
00352 setRotation(LLQuaternion(temp_mat));
00353 }
00354
00355
00356
00357
00358
00359 const LLVector3& LLJoint::getScale()
00360 {
00361 return mXform.getScale();
00362 }
00363
00364
00365
00366
00367 void LLJoint::setScale( const LLVector3& scale )
00368 {
00369
00370 {
00371 mXform.setScale(scale);
00372 touch();
00373 }
00374
00375 }
00376
00377
00378
00379
00380
00381
00382 const LLMatrix4 &LLJoint::getWorldMatrix()
00383 {
00384 updateWorldMatrixParent();
00385
00386 return mXform.getWorldMatrix();
00387 }
00388
00389
00390
00391
00392
00393 void LLJoint::setWorldMatrix( const LLMatrix4& mat )
00394 {
00395 llinfos << "WARNING: LLJoint::setWorldMatrix() not correctly implemented yet" << llendl;
00396
00397 LLVector3 trans( mat.mMatrix[VW][VX],
00398 mat.mMatrix[VW][VY],
00399 mat.mMatrix[VW][VZ] );
00400
00401
00402 LLQuaternion rot( mat );
00403
00404 setWorldPosition( trans );
00405 setWorldRotation( rot );
00406 }
00407
00408
00409
00410
00411 void LLJoint::updateWorldMatrixParent()
00412 {
00413 if (mDirtyFlags & MATRIX_DIRTY)
00414 {
00415 LLJoint *parent = getParent();
00416 if (parent)
00417 {
00418 parent->updateWorldMatrixParent();
00419 }
00420 updateWorldMatrix();
00421 }
00422 }
00423
00424
00425
00426
00427 void LLJoint::updateWorldPRSParent()
00428 {
00429 if (mDirtyFlags & (ROTATION_DIRTY | POSITION_DIRTY))
00430 {
00431 LLJoint *parent = getParent();
00432 if (parent)
00433 {
00434 parent->updateWorldPRSParent();
00435 }
00436
00437 mXform.update();
00438 mDirtyFlags &= ~(ROTATION_DIRTY | POSITION_DIRTY);
00439 }
00440 }
00441
00442
00443
00444
00445 void LLJoint::updateWorldMatrixChildren()
00446 {
00447 if (!this->mUpdateXform) return;
00448
00449 if (mDirtyFlags & MATRIX_DIRTY)
00450 {
00451 updateWorldMatrix();
00452 }
00453 for (child_list_t::iterator iter = mChildren.begin();
00454 iter != mChildren.end(); ++iter)
00455 {
00456 LLJoint* joint = *iter;
00457 joint->updateWorldMatrixChildren();
00458 }
00459 }
00460
00461
00462
00463
00464 void LLJoint::updateWorldMatrix()
00465 {
00466 if (mDirtyFlags & MATRIX_DIRTY)
00467 {
00468 sNumUpdates++;
00469 mXform.updateMatrix(FALSE);
00470 mDirtyFlags = 0x0;
00471 }
00472 }
00473
00474
00475
00476
00477 const LLVector3 &LLJoint::getSkinOffset()
00478 {
00479 return mSkinOffset;
00480 }
00481
00482
00483
00484
00485
00486 void LLJoint::setSkinOffset( const LLVector3& offset )
00487 {
00488 mSkinOffset = offset;
00489 }
00490
00491
00492
00493
00494
00495 void LLJoint::clampRotation(LLQuaternion old_rot, LLQuaternion new_rot)
00496 {
00497 LLVector3 main_axis(1.f, 0.f, 0.f);
00498
00499 for (child_list_t::iterator iter = mChildren.begin();
00500 iter != mChildren.end(); ++iter)
00501 {
00502 LLJoint* joint = *iter;
00503 if (joint->isAnimatable())
00504 {
00505 main_axis = joint->getPosition();
00506 main_axis.normVec();
00507
00508 break;
00509 }
00510 }
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525 }
00526
00527