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                 mChildren.erase(iter);
00193         
00194                 joint->mXform.setParent(NULL);
00195                 joint->mParent = NULL;
00196                 joint->touch();
00197         }
00198 }
00199 
00200 
00201 //--------------------------------------------------------------------
00202 // removeAllChildren()
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 // getPosition()
00221 //--------------------------------------------------------------------
00222 const LLVector3& LLJoint::getPosition()
00223 {
00224         return mXform.getPosition();
00225 }
00226 
00227 
00228 //--------------------------------------------------------------------
00229 // setPosition()
00230 //--------------------------------------------------------------------
00231 void LLJoint::setPosition( const LLVector3& pos )
00232 {
00233 //      if (mXform.getPosition() != pos)
00234         {
00235                 mXform.setPosition(pos);
00236                 touch(MATRIX_DIRTY | POSITION_DIRTY);
00237         }
00238 }
00239 
00240 
00241 //--------------------------------------------------------------------
00242 // getWorldPosition()
00243 //--------------------------------------------------------------------
00244 LLVector3 LLJoint::getWorldPosition()
00245 {
00246         updateWorldPRSParent();
00247         return mXform.getWorldPosition();
00248 }
00249 
00250 //-----------------------------------------------------------------------------
00251 // getLastWorldPosition()
00252 //-----------------------------------------------------------------------------
00253 LLVector3 LLJoint::getLastWorldPosition()
00254 {
00255         return mXform.getWorldPosition();
00256 }
00257 
00258 
00259 //--------------------------------------------------------------------
00260 // setWorldPosition()
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 // mXform.getRotation()
00290 //--------------------------------------------------------------------
00291 const LLQuaternion& LLJoint::getRotation()
00292 {
00293         return mXform.getRotation();
00294 }
00295 
00296 
00297 //--------------------------------------------------------------------
00298 // setRotation()
00299 //--------------------------------------------------------------------
00300 void LLJoint::setRotation( const LLQuaternion& rot )
00301 {
00302         if (rot.isFinite())
00303         {
00304         //      if (mXform.getRotation() != rot)
00305                 {
00306                         mXform.setRotation(rot);
00307                         touch(MATRIX_DIRTY | ROTATION_DIRTY);
00308                 }
00309         }
00310 }
00311 
00312 
00313 //--------------------------------------------------------------------
00314 // getWorldRotation()
00315 //--------------------------------------------------------------------
00316 LLQuaternion LLJoint::getWorldRotation()
00317 {
00318         updateWorldPRSParent();
00319 
00320         return mXform.getWorldRotation();
00321 }
00322 
00323 //-----------------------------------------------------------------------------
00324 // getLastWorldRotation()
00325 //-----------------------------------------------------------------------------
00326 LLQuaternion LLJoint::getLastWorldRotation()
00327 {
00328         return mXform.getWorldRotation();
00329 }
00330 
00331 //--------------------------------------------------------------------
00332 // setWorldRotation()
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 // getScale()
00359 //--------------------------------------------------------------------
00360 const LLVector3& LLJoint::getScale()
00361 {
00362         return mXform.getScale();
00363 }
00364 
00365 //--------------------------------------------------------------------
00366 // setScale()
00367 //--------------------------------------------------------------------
00368 void LLJoint::setScale( const LLVector3& scale )
00369 {
00370 //      if (mXform.getScale() != scale)
00371         {
00372                 mXform.setScale(scale);
00373                 touch();
00374         }
00375 
00376 }
00377 
00378 
00379 
00380 //--------------------------------------------------------------------
00381 // getWorldMatrix()
00382 //--------------------------------------------------------------------
00383 const LLMatrix4 &LLJoint::getWorldMatrix()
00384 {
00385         updateWorldMatrixParent();
00386 
00387         return mXform.getWorldMatrix();
00388 }
00389 
00390 
00391 //--------------------------------------------------------------------
00392 // setWorldMatrix()
00393 //--------------------------------------------------------------------
00394 void LLJoint::setWorldMatrix( const LLMatrix4& mat )
00395 {
00396 llinfos << "WARNING: LLJoint::setWorldMatrix() not correctly implemented yet" << llendl;
00397         // extract global translation
00398         LLVector3 trans(        mat.mMatrix[VW][VX],
00399                                                 mat.mMatrix[VW][VY],
00400                                                 mat.mMatrix[VW][VZ] );
00401 
00402         // extract global rotation
00403         LLQuaternion rot( mat );
00404 
00405         setWorldPosition( trans );
00406         setWorldRotation( rot );
00407 }
00408 
00409 //-----------------------------------------------------------------------------
00410 // updateWorldMatrixParent()
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 // updateWorldPRSParent()
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 // updateWorldMatrixChildren()
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 // updateWorldMatrix()
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 // getSkinOffset()
00477 //--------------------------------------------------------------------
00478 const LLVector3 &LLJoint::getSkinOffset()
00479 {
00480         return mSkinOffset;
00481 }
00482 
00483 
00484 //--------------------------------------------------------------------
00485 // setSkinOffset()
00486 //--------------------------------------------------------------------
00487 void LLJoint::setSkinOffset( const LLVector3& offset )
00488 {
00489         mSkinOffset = offset;
00490 }
00491 
00492 
00493 //-----------------------------------------------------------------------------
00494 // clampRotation()
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                         // only care about first animatable child
00509                         break;
00510                 }
00511         }
00512 
00513         // 2003.03.26 - This code was just using up cpu cycles. AB
00514 
00515 //      LLVector3 old_axis = main_axis * old_rot;
00516 //      LLVector3 new_axis = main_axis * new_rot;
00517 
00518 //      for (S32 i = 0; i < mConstraintSilhouette.count() - 1; i++)
00519 //      {
00520 //              LLVector3 vert1 = mConstraintSilhouette[i];
00521 //              LLVector3 vert2 = mConstraintSilhouette[i + 1];
00522 
00523                 // figure out how to clamp rotation to line on 3-sphere
00524 
00525 //      }
00526 }
00527 
00528 // End

Generated on Fri May 16 08:31:57 2008 for SecondLife by  doxygen 1.5.5