llpose.cpp

Go to the documentation of this file.
00001 
00032 //-----------------------------------------------------------------------------
00033 // Header Files
00034 //-----------------------------------------------------------------------------
00035 #include "linden_common.h"
00036 
00037 #include "llpose.h"
00038 
00039 #include "llmotion.h"
00040 #include "llmath.h"
00041 #include "llstl.h"
00042 
00043 //-----------------------------------------------------------------------------
00044 // Static
00045 //-----------------------------------------------------------------------------
00046 
00047 //-----------------------------------------------------------------------------
00048 // LLPose
00049 //-----------------------------------------------------------------------------
00050 LLPose::~LLPose()
00051 {
00052 }
00053 
00054 //-----------------------------------------------------------------------------
00055 // getFirstJointState()
00056 //-----------------------------------------------------------------------------
00057 LLJointState *LLPose::getFirstJointState()
00058 {
00059         mListIter = mJointMap.begin();
00060         if (mListIter == mJointMap.end())
00061         {
00062                 return NULL;
00063         }
00064         else
00065         {
00066                 return mListIter->second;
00067         }
00068 }
00069 
00070 //-----------------------------------------------------------------------------
00071 // getNextJointState()
00072 //-----------------------------------------------------------------------------
00073 LLJointState *LLPose::getNextJointState()
00074 {
00075         mListIter++;
00076         if (mListIter == mJointMap.end())
00077         {
00078                 return NULL;
00079         }
00080         else
00081         {
00082                 return mListIter->second;
00083         }
00084 }
00085 
00086 //-----------------------------------------------------------------------------
00087 // addJointState()
00088 //-----------------------------------------------------------------------------
00089 BOOL LLPose::addJointState(LLJointState *jointState)
00090 {
00091         if (mJointMap.find(jointState->getJoint()->getName()) == mJointMap.end())
00092         {
00093                 mJointMap[jointState->getJoint()->getName()] = jointState;
00094         }
00095         return TRUE;
00096 }
00097 
00098 //-----------------------------------------------------------------------------
00099 // removeJointState()
00100 //-----------------------------------------------------------------------------
00101 BOOL LLPose::removeJointState(LLJointState *jointState)
00102 {
00103         mJointMap.erase(jointState->getJoint()->getName());
00104         return TRUE;
00105 }
00106 
00107 //-----------------------------------------------------------------------------
00108 // removeAllJointStates()
00109 //-----------------------------------------------------------------------------
00110 BOOL LLPose::removeAllJointStates()
00111 {
00112         mJointMap.clear();
00113         return TRUE;
00114 }
00115 
00116 //-----------------------------------------------------------------------------
00117 // findJointState()
00118 //-----------------------------------------------------------------------------
00119 LLJointState* LLPose::findJointState(LLJoint *joint)
00120 {
00121         joint_map_iterator iter = mJointMap.find(joint->getName());
00122 
00123         if (iter == mJointMap.end())
00124         {
00125                 return NULL;
00126         }
00127         else
00128         {
00129                 return iter->second;
00130         }
00131 }
00132 
00133 //-----------------------------------------------------------------------------
00134 // findJointState()
00135 //-----------------------------------------------------------------------------
00136 LLJointState* LLPose::findJointState(const std::string &name)
00137 {
00138         joint_map_iterator iter = mJointMap.find(name);
00139 
00140         if (iter == mJointMap.end())
00141         {
00142                 return NULL;
00143         }
00144         else
00145         {
00146                 return iter->second;
00147         }
00148 }
00149 
00150 //-----------------------------------------------------------------------------
00151 // setWeight()
00152 //-----------------------------------------------------------------------------
00153 void LLPose::setWeight(F32 weight)
00154 {
00155         joint_map_iterator iter;
00156         for(iter = mJointMap.begin(); 
00157                 iter != mJointMap.end();
00158                 ++iter)
00159         {
00160                 iter->second->setWeight(weight);
00161         }
00162         mWeight = weight;
00163 }
00164 
00165 //-----------------------------------------------------------------------------
00166 // getWeight()
00167 //-----------------------------------------------------------------------------
00168 F32 LLPose::getWeight() const
00169 {
00170         return mWeight;
00171 }
00172 
00173 //-----------------------------------------------------------------------------
00174 // getNumJointStates()
00175 //-----------------------------------------------------------------------------
00176 S32 LLPose::getNumJointStates() const
00177 {
00178         return (S32)mJointMap.size();
00179 }
00180 
00181 //-----------------------------------------------------------------------------
00182 // LLJointStateBlender
00183 //-----------------------------------------------------------------------------
00184 
00185 LLJointStateBlender::LLJointStateBlender()
00186 {
00187         for(S32 i = 0; i < JSB_NUM_JOINT_STATES; i++)
00188         {
00189                 mJointStates[i] = NULL;
00190                 mPriorities[i] = S32_MIN;
00191         }
00192 }
00193 
00194 LLJointStateBlender::~LLJointStateBlender()
00195 {
00196         
00197 }
00198 
00199 //-----------------------------------------------------------------------------
00200 // addJointState()
00201 //-----------------------------------------------------------------------------
00202 BOOL LLJointStateBlender::addJointState(LLJointState *joint_state, S32 priority, BOOL additive_blend)
00203 {
00204         llassert(joint_state);
00205 
00206         if (!joint_state->getJoint())
00207                 // this joint state doesn't point to an actual joint, so we don't care about applying it
00208                 return FALSE;
00209 
00210         for(S32 i = 0; i < JSB_NUM_JOINT_STATES; i++)
00211         {
00212                 if (NULL == mJointStates[i])
00213                 {
00214                         mJointStates[i] = joint_state;
00215                         mPriorities[i] = priority;
00216                         mAdditiveBlends[i] = additive_blend;
00217                         return TRUE;
00218                 } 
00219                 else if (priority > mPriorities[i])
00220                 {
00221                         // we're at a higher priority than the current joint state in this slot
00222                         // so shift everyone over
00223                         // previous joint states (newer motions) with same priority should stay in place
00224                         for (S32 j = JSB_NUM_JOINT_STATES - 1; j > i; j--)
00225                         {
00226                                 mJointStates[j] = mJointStates[j - 1];
00227                                 mPriorities[j] = mPriorities[j - 1];
00228                                 mAdditiveBlends[j] = mAdditiveBlends[j - 1];
00229                         }
00230                         // now store ourselves in this slot
00231                         mJointStates[i] = joint_state;
00232                         mPriorities[i] = priority;
00233                         mAdditiveBlends[i] = additive_blend;
00234                         return TRUE;
00235                 }
00236         }
00237 
00238         return FALSE;
00239 }
00240 
00241 //-----------------------------------------------------------------------------
00242 // blendJointStates()
00243 //-----------------------------------------------------------------------------
00244 void LLJointStateBlender::blendJointStates(BOOL apply_now)
00245 {
00246         // we need at least one joint to blend
00247         // if there is one, it will be in slot zero according to insertion logic
00248         // instead of resetting joint state to default, just leave it unchanged from last frame
00249         if (NULL == mJointStates[0])
00250         {
00251                 return;
00252         }
00253 
00254         LLJoint* target_joint = apply_now ? mJointStates[0]->getJoint() : &mJointCache;
00255 
00256         const S32 POS_WEIGHT = 0;
00257         const S32 ROT_WEIGHT = 1;
00258         const S32 SCALE_WEIGHT = 2;
00259 
00260         F32                             sum_weights[3];
00261         U32                             sum_usage = 0;
00262 
00263         LLVector3               blended_pos = target_joint->getPosition();
00264         LLQuaternion    blended_rot = target_joint->getRotation();
00265         LLVector3               blended_scale = target_joint->getScale();
00266 
00267         LLVector3               added_pos;
00268         LLQuaternion    added_rot;
00269         LLVector3               added_scale;
00270 
00271         //S32                           joint_state_index;
00272 
00273         sum_weights[POS_WEIGHT] = 0.f;
00274         sum_weights[ROT_WEIGHT] = 0.f;
00275         sum_weights[SCALE_WEIGHT] = 0.f;
00276 
00277         for(S32 joint_state_index = 0; 
00278                 joint_state_index < JSB_NUM_JOINT_STATES && mJointStates[joint_state_index] != NULL;
00279                 joint_state_index++)
00280         {
00281                 LLJointState* jsp = mJointStates[joint_state_index];
00282                 U32 current_usage = jsp->getUsage();
00283                 F32 current_weight = jsp->getWeight();
00284 
00285                 if (current_weight == 0.f)
00286                 {
00287                         continue;
00288                 }
00289 
00290                 if (mAdditiveBlends[joint_state_index])
00291                 {
00292                         if(current_usage & LLJointState::POS)
00293                         {
00294                                 F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[POS_WEIGHT]);
00295 
00296                                 // add in pos for this jointstate modulated by weight
00297                                 added_pos += jsp->getPosition() * (new_weight_sum - sum_weights[POS_WEIGHT]);
00298                         }
00299 
00300                         if(current_usage & LLJointState::SCALE)
00301                         {
00302                                 F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[SCALE_WEIGHT]);
00303 
00304                                 // add in scale for this jointstate modulated by weight
00305                                 added_scale += jsp->getScale() * (new_weight_sum - sum_weights[SCALE_WEIGHT]);
00306                         }
00307 
00308                         if (current_usage & LLJointState::ROT)
00309                         {
00310                                 F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[ROT_WEIGHT]);
00311 
00312                                 // add in rotation for this jointstate modulated by weight
00313                                 added_rot = nlerp((new_weight_sum - sum_weights[ROT_WEIGHT]), added_rot, jsp->getRotation()) * added_rot;
00314                         }
00315                 }
00316                 else
00317                 {
00318                         // blend two jointstates together
00319                 
00320                         // blend position
00321                         if(current_usage & LLJointState::POS)
00322                         {
00323                                 if(sum_usage & LLJointState::POS)
00324                                 {
00325                                         F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[POS_WEIGHT]);
00326 
00327                                         // blend positions from both
00328                                         blended_pos = lerp(jsp->getPosition(), blended_pos, sum_weights[POS_WEIGHT] / new_weight_sum);
00329                                         sum_weights[POS_WEIGHT] = new_weight_sum;
00330                                 } 
00331                                 else
00332                                 {
00333                                         // copy position from current
00334                                         blended_pos = jsp->getPosition();
00335                                         sum_weights[POS_WEIGHT] = current_weight;
00336                                 }
00337                         }
00338                         
00339                         // now do scale
00340                         if(current_usage & LLJointState::SCALE)
00341                         {
00342                                 if(sum_usage & LLJointState::SCALE)
00343                                 {
00344                                         F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[SCALE_WEIGHT]);
00345 
00346                                         // blend scales from both
00347                                         blended_scale = lerp(jsp->getScale(), blended_scale, sum_weights[SCALE_WEIGHT] / new_weight_sum);
00348                                         sum_weights[SCALE_WEIGHT] = new_weight_sum;
00349                                 } 
00350                                 else
00351                                 {
00352                                         // copy scale from current
00353                                         blended_scale = jsp->getScale();
00354                                         sum_weights[SCALE_WEIGHT] = current_weight;
00355                                 }
00356                         }
00357 
00358                         // rotation
00359                         if (current_usage & LLJointState::ROT)
00360                         {
00361                                 if(sum_usage & LLJointState::ROT)
00362                                 {
00363                                         F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[ROT_WEIGHT]);
00364 
00365                                         // blend rotations from both
00366                                         blended_rot = nlerp(sum_weights[ROT_WEIGHT] / new_weight_sum, jsp->getRotation(), blended_rot);
00367                                         sum_weights[ROT_WEIGHT] = new_weight_sum;
00368                                 } 
00369                                 else
00370                                 {
00371                                         // copy rotation from current
00372                                         blended_rot = jsp->getRotation();
00373                                         sum_weights[ROT_WEIGHT] = current_weight;
00374                                 }
00375                         }
00376 
00377                         // update resulting usage mask
00378                         sum_usage = sum_usage | current_usage;
00379                 }
00380         }
00381 
00382         // apply blended transforms
00383         target_joint->setPosition(blended_pos);
00384         target_joint->setScale(blended_scale);
00385         target_joint->setRotation(blended_rot);
00386 
00387         // apply additive transforms
00388         target_joint->setPosition(target_joint->getPosition() + added_pos);
00389         target_joint->setScale(target_joint->getScale() + added_scale);
00390         target_joint->setRotation(added_rot * target_joint->getRotation());
00391 
00392         if (apply_now)
00393         {
00394                 // now clear joint states
00395                 for(S32 i = 0; i < JSB_NUM_JOINT_STATES; i++)
00396                 {
00397                         mJointStates[i] = NULL;
00398                 }
00399         }
00400 }
00401 
00402 //-----------------------------------------------------------------------------
00403 // interpolate()
00404 //-----------------------------------------------------------------------------
00405 void LLJointStateBlender::interpolate(F32 u)
00406 {
00407         // only interpolate if we have a joint state
00408         if (!mJointStates[0])
00409         {
00410                 return;
00411         }
00412         LLJoint* target_joint = mJointStates[0]->getJoint();
00413 
00414         if (!target_joint)
00415         {
00416                 return;
00417         }
00418 
00419         target_joint->setPosition(lerp(target_joint->getPosition(), mJointCache.getPosition(), u));
00420         target_joint->setScale(lerp(target_joint->getScale(), mJointCache.getScale(), u));
00421         target_joint->setRotation(nlerp(u, target_joint->getRotation(), mJointCache.getRotation()));
00422 }
00423 
00424 //-----------------------------------------------------------------------------
00425 // clear()
00426 //-----------------------------------------------------------------------------
00427 void LLJointStateBlender::clear()
00428 {
00429         // now clear joint states
00430         for(S32 i = 0; i < JSB_NUM_JOINT_STATES; i++)
00431         {
00432                 mJointStates[i] = NULL;
00433         }
00434 }
00435 
00436 //-----------------------------------------------------------------------------
00437 // resetCachedJoint()
00438 //-----------------------------------------------------------------------------
00439 void LLJointStateBlender::resetCachedJoint()
00440 {
00441         if (!mJointStates[0])
00442         {
00443                 return;
00444         }
00445         LLJoint* source_joint = mJointStates[0]->getJoint();
00446         mJointCache.setPosition(source_joint->getPosition());
00447         mJointCache.setScale(source_joint->getScale());
00448         mJointCache.setRotation(source_joint->getRotation());
00449 }
00450 
00451 //-----------------------------------------------------------------------------
00452 // LLPoseBlender
00453 //-----------------------------------------------------------------------------
00454 
00455 LLPoseBlender::LLPoseBlender()
00456 {
00457 }
00458 
00459 LLPoseBlender::~LLPoseBlender()
00460 {
00461         for_each(mJointStateBlenderPool.begin(), mJointStateBlenderPool.end(), DeletePairedPointer());
00462 }
00463 
00464 //-----------------------------------------------------------------------------
00465 // addMotion()
00466 //-----------------------------------------------------------------------------
00467 BOOL LLPoseBlender::addMotion(LLMotion* motion)
00468 {
00469         LLPose* pose = motion->getPose();
00470 
00471         for(LLJointState *jsp = pose->getFirstJointState(); jsp; jsp = pose->getNextJointState())
00472         {
00473                 LLJoint *jointp = jsp->getJoint();
00474                 LLJointStateBlender* joint_blender;
00475                 if (mJointStateBlenderPool.find(jointp) == mJointStateBlenderPool.end())
00476                 {
00477                         // this is the first time we are animating this joint
00478                         // so create new jointblender and add it to our pool
00479                         joint_blender = new LLJointStateBlender();
00480                         mJointStateBlenderPool[jointp] = joint_blender;
00481                 }
00482                 else
00483                 {
00484                         joint_blender = mJointStateBlenderPool[jointp];
00485                 }
00486 
00487                 if (jsp->getPriority() == LLJoint::USE_MOTION_PRIORITY)
00488                 {
00489                         joint_blender->addJointState(jsp, motion->getPriority(), motion->getBlendType() == LLMotion::ADDITIVE_BLEND);
00490                 }
00491                 else
00492                 {
00493                         joint_blender->addJointState(jsp, jsp->getPriority(), motion->getBlendType() == LLMotion::ADDITIVE_BLEND);
00494                 }
00495 
00496                 // add it to our list of active blenders
00497                 if (std::find(mActiveBlenders.begin(), mActiveBlenders.end(), joint_blender) == mActiveBlenders.end())
00498                 {
00499                         mActiveBlenders.push_front(joint_blender);
00500                 }
00501         }
00502         return TRUE;
00503 }
00504 
00505 //-----------------------------------------------------------------------------
00506 // blendAndApply()
00507 //-----------------------------------------------------------------------------
00508 void LLPoseBlender::blendAndApply()
00509 {
00510         for (blender_list_t::iterator iter = mActiveBlenders.begin();
00511                  iter != mActiveBlenders.end(); ++iter)
00512         {
00513                 LLJointStateBlender* jsbp = *iter;
00514                 jsbp->blendJointStates();
00515         }
00516 
00517         // we're done now so there are no more active blenders for this frame
00518         mActiveBlenders.clear();
00519 }
00520 
00521 //-----------------------------------------------------------------------------
00522 // blendAndCache()
00523 //-----------------------------------------------------------------------------
00524 void LLPoseBlender::blendAndCache(BOOL reset_cached_joints)
00525 {
00526         for (blender_list_t::iterator iter = mActiveBlenders.begin();
00527                  iter != mActiveBlenders.end(); ++iter)
00528         {
00529                 LLJointStateBlender* jsbp = *iter;
00530                 if (reset_cached_joints)
00531                 {
00532                         jsbp->resetCachedJoint();
00533                 }
00534                 jsbp->blendJointStates(FALSE);
00535         }
00536 }
00537 
00538 //-----------------------------------------------------------------------------
00539 // interpolate()
00540 //-----------------------------------------------------------------------------
00541 void LLPoseBlender::interpolate(F32 u)
00542 {
00543         for (blender_list_t::iterator iter = mActiveBlenders.begin();
00544                  iter != mActiveBlenders.end(); ++iter)
00545         {
00546                 LLJointStateBlender* jsbp = *iter;
00547                 jsbp->interpolate(u);
00548         }
00549 }
00550 
00551 //-----------------------------------------------------------------------------
00552 // clearBlenders()
00553 //-----------------------------------------------------------------------------
00554 void LLPoseBlender::clearBlenders()
00555 {
00556         for (blender_list_t::iterator iter = mActiveBlenders.begin();
00557                  iter != mActiveBlenders.end(); ++iter)
00558         {
00559                 LLJointStateBlender* jsbp = *iter;
00560                 jsbp->clear();
00561         }
00562 
00563         mActiveBlenders.clear();
00564 }
00565 

Generated on Thu Jul 1 06:09:01 2010 for Second Life Viewer by  doxygen 1.4.7