lljoint.cpp

Go to the documentation of this file.
00001 
00032 //-----------------------------------------------------------------------------
00033 // Header Files
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 // LLJoint()
00046 // Class Constructor
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 // LLJoint()
00063 // Class Constructor
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 // ~LLJoint()
00084 // Class Destructor
00085 //-----------------------------------------------------------------------------
00086 LLJoint::~LLJoint()
00087 {
00088         if (mParent)
00089         {
00090                 mParent->removeChild( this );
00091         }
00092         removeAllChildren();
00093 }
00094 
00095 
00096 //-----------------------------------------------------------------------------
00097 // setup()
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 // touch()
00110 // Sets all dirty flags for all children, recursively.
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 // getRoot()
00135 //-----------------------------------------------------------------------------
00136 LLJoint *LLJoint::getRoot()
00137 {
00138         if ( getParent() == NULL )
00139         {
00140                 return this;
00141         }
00142         return getParent()->getRoot();
00143 }
00144 
00145 
00146 //-----------------------------------------------------------------------------
00147 // findJoint()
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 // addChild()
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 // removeChild()
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 // removeAllChildren()
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 // getPosition()
00220 //--------------------------------------------------------------------
00221 const LLVector3& LLJoint::getPosition()
00222 {
00223         return mXform.getPosition();
00224 }
00225 
00226 
00227 //--------------------------------------------------------------------
00228 // setPosition()
00229 //--------------------------------------------------------------------
00230 void LLJoint::setPosition( const LLVector3& pos )
00231 {
00232 //      if (mXform.getPosition() != pos)
00233         {
00234                 mXform.setPosition(pos);
00235                 touch(MATRIX_DIRTY | POSITION_DIRTY);
00236         }
00237 }
00238 
00239 
00240 //--------------------------------------------------------------------
00241 // getWorldPosition()
00242 //--------------------------------------------------------------------
00243 LLVector3 LLJoint::getWorldPosition()
00244 {
00245         updateWorldPRSParent();
00246         return mXform.getWorldPosition();
00247 }
00248 
00249 //-----------------------------------------------------------------------------
00250 // getLastWorldPosition()
00251 //-----------------------------------------------------------------------------
00252 LLVector3 LLJoint::getLastWorldPosition()
00253 {
00254         return mXform.getWorldPosition();
00255 }
00256 
00257 
00258 //--------------------------------------------------------------------
00259 // setWorldPosition()
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 // mXform.getRotation()
00289 //--------------------------------------------------------------------
00290 const LLQuaternion& LLJoint::getRotation()
00291 {
00292         return mXform.getRotation();
00293 }
00294 
00295 
00296 //--------------------------------------------------------------------
00297 // setRotation()
00298 //--------------------------------------------------------------------
00299 void LLJoint::setRotation( const LLQuaternion& rot )
00300 {
00301         if (rot.isFinite())
00302         {
00303         //      if (mXform.getRotation() != rot)
00304                 {
00305                         mXform.setRotation(rot);
00306                         touch(MATRIX_DIRTY | ROTATION_DIRTY);
00307                 }
00308         }
00309 }
00310 
00311 
00312 //--------------------------------------------------------------------
00313 // getWorldRotation()
00314 //--------------------------------------------------------------------
00315 LLQuaternion LLJoint::getWorldRotation()
00316 {
00317         updateWorldPRSParent();
00318 
00319         return mXform.getWorldRotation();
00320 }
00321 
00322 //-----------------------------------------------------------------------------
00323 // getLastWorldRotation()
00324 //-----------------------------------------------------------------------------
00325 LLQuaternion LLJoint::getLastWorldRotation()
00326 {
00327         return mXform.getWorldRotation();
00328 }
00329 
00330 //--------------------------------------------------------------------
00331 // setWorldRotation()
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 // getScale()
00358 //--------------------------------------------------------------------
00359 const LLVector3& LLJoint::getScale()
00360 {
00361         return mXform.getScale();
00362 }
00363 
00364 //--------------------------------------------------------------------
00365 // setScale()
00366 //--------------------------------------------------------------------
00367 void LLJoint::setScale( const LLVector3& scale )
00368 {
00369 //      if (mXform.getScale() != scale)
00370         {
00371                 mXform.setScale(scale);
00372                 touch();
00373         }
00374 
00375 }
00376 
00377 
00378 
00379 //--------------------------------------------------------------------
00380 // getWorldMatrix()
00381 //--------------------------------------------------------------------
00382 const LLMatrix4 &LLJoint::getWorldMatrix()
00383 {
00384         updateWorldMatrixParent();
00385 
00386         return mXform.getWorldMatrix();
00387 }
00388 
00389 
00390 //--------------------------------------------------------------------
00391 // setWorldMatrix()
00392 //--------------------------------------------------------------------
00393 void LLJoint::setWorldMatrix( const LLMatrix4& mat )
00394 {
00395 llinfos << "WARNING: LLJoint::setWorldMatrix() not correctly implemented yet" << llendl;
00396         // extract global translation
00397         LLVector3 trans(        mat.mMatrix[VW][VX],
00398                                                 mat.mMatrix[VW][VY],
00399                                                 mat.mMatrix[VW][VZ] );
00400 
00401         // extract global rotation
00402         LLQuaternion rot( mat );
00403 
00404         setWorldPosition( trans );
00405         setWorldRotation( rot );
00406 }
00407 
00408 //-----------------------------------------------------------------------------
00409 // updateWorldMatrixParent()
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 // updateWorldPRSParent()
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 // updateWorldMatrixChildren()
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 // updateWorldMatrix()
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 // getSkinOffset()
00476 //--------------------------------------------------------------------
00477 const LLVector3 &LLJoint::getSkinOffset()
00478 {
00479         return mSkinOffset;
00480 }
00481 
00482 
00483 //--------------------------------------------------------------------
00484 // setSkinOffset()
00485 //--------------------------------------------------------------------
00486 void LLJoint::setSkinOffset( const LLVector3& offset )
00487 {
00488         mSkinOffset = offset;
00489 }
00490 
00491 
00492 //-----------------------------------------------------------------------------
00493 // clampRotation()
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                         // only care about first animatable child
00508                         break;
00509                 }
00510         }
00511 
00512         // 2003.03.26 - This code was just using up cpu cycles. AB
00513 
00514 //      LLVector3 old_axis = main_axis * old_rot;
00515 //      LLVector3 new_axis = main_axis * new_rot;
00516 
00517 //      for (S32 i = 0; i < mConstraintSilhouette.count() - 1; i++)
00518 //      {
00519 //              LLVector3 vert1 = mConstraintSilhouette[i];
00520 //              LLVector3 vert2 = mConstraintSilhouette[i + 1];
00521 
00522                 // figure out how to clamp rotation to line on 3-sphere
00523 
00524 //      }
00525 }
00526 
00527 // End

Generated on Thu Jul 1 06:08:47 2010 for Second Life Viewer by  doxygen 1.4.7