llmotioncontroller.cpp

Go to the documentation of this file.
00001 
00032 //-----------------------------------------------------------------------------
00033 // Header Files
00034 //-----------------------------------------------------------------------------
00035 #include "linden_common.h"
00036 
00037 #include "llmotioncontroller.h"
00038 #include "llkeyframemotion.h"
00039 #include "llmath.h"
00040 #include "lltimer.h"
00041 #include "llanimationstates.h"
00042 #include "llstl.h"
00043 
00044 const S32 NUM_JOINT_SIGNATURE_STRIDES = LL_CHARACTER_MAX_JOINTS / 4;
00045 const U32 MAX_MOTION_INSTANCES = 32;
00046 
00047 //-----------------------------------------------------------------------------
00048 // Constants and statics
00049 //-----------------------------------------------------------------------------
00050 LLMotionRegistry LLMotionController::sRegistry;
00051 
00052 //-----------------------------------------------------------------------------
00053 // LLMotionTableEntry()
00054 //-----------------------------------------------------------------------------
00055 LLMotionTableEntry::LLMotionTableEntry()
00056 { 
00057         mConstructor = NULL; 
00058         mID.setNull(); 
00059 }
00060 
00061 LLMotionTableEntry::LLMotionTableEntry(LLMotionConstructor constructor, const LLUUID& id)
00062                 : mConstructor(constructor), mID(id)
00063 {
00064 
00065 }
00066 
00067 //-----------------------------------------------------------------------------
00068 // create()
00069 //-----------------------------------------------------------------------------
00070 LLMotion* LLMotionTableEntry::create(const LLUUID &id)
00071 {
00072         LLMotion* motionp = mConstructor(id);
00073 
00074         return motionp;
00075 }
00076 
00077 
00078 //-----------------------------------------------------------------------------
00079 //-----------------------------------------------------------------------------
00080 // LLMotionRegistry class
00081 //-----------------------------------------------------------------------------
00082 //-----------------------------------------------------------------------------
00083 
00084 //-----------------------------------------------------------------------------
00085 // LLMotionRegistry()
00086 // Class Constructor
00087 //-----------------------------------------------------------------------------
00088 LLMotionRegistry::LLMotionRegistry() : mMotionTable(LLMotionTableEntry::uuidEq, LLMotionTableEntry())
00089 {
00090         
00091 }
00092 
00093 
00094 //-----------------------------------------------------------------------------
00095 // ~LLMotionRegistry()
00096 // Class Destructor
00097 //-----------------------------------------------------------------------------
00098 LLMotionRegistry::~LLMotionRegistry()
00099 {
00100         mMotionTable.removeAll();
00101 }
00102 
00103 
00104 //-----------------------------------------------------------------------------
00105 // addMotion()
00106 //-----------------------------------------------------------------------------
00107 BOOL LLMotionRegistry::addMotion( const LLUUID& id, LLMotionConstructor constructor )
00108 {
00109 //      llinfos << "Registering motion: " << name << llendl;
00110         if (!mMotionTable.check(id))
00111         {
00112                 mMotionTable.set(id, LLMotionTableEntry(constructor, id));
00113                 return TRUE;
00114         }
00115         
00116         return FALSE;
00117 }
00118 
00119 //-----------------------------------------------------------------------------
00120 // markBad()
00121 //-----------------------------------------------------------------------------
00122 void LLMotionRegistry::markBad( const LLUUID& id )
00123 {
00124         mMotionTable.set(id, LLMotionTableEntry());
00125 }
00126 
00127 //-----------------------------------------------------------------------------
00128 // createMotion()
00129 //-----------------------------------------------------------------------------
00130 LLMotion *LLMotionRegistry::createMotion( const LLUUID &id )
00131 {
00132         LLMotionTableEntry motion_entry = mMotionTable.get(id);
00133         LLMotion* motion = NULL;
00134 
00135         if ( motion_entry.getID().isNull() )
00136         {
00137                 // *FIX: need to replace with a better default scheme. RN
00138                 motion = LLKeyframeMotion::create(id);
00139         }
00140         else
00141         {
00142                 motion = motion_entry.create(id);
00143         }
00144 
00145         return motion;
00146 }
00147 
00148 //-----------------------------------------------------------------------------
00149 //-----------------------------------------------------------------------------
00150 // LLMotionController class
00151 //-----------------------------------------------------------------------------
00152 //-----------------------------------------------------------------------------
00153 
00154 //-----------------------------------------------------------------------------
00155 // LLMotionController()
00156 // Class Constructor
00157 //-----------------------------------------------------------------------------
00158 LLMotionController::LLMotionController(  )
00159 {
00160         mTime = 0.f;
00161         mTimeOffset = 0.f;
00162         mLastTime = 0.0f;
00163         mHasRunOnce = FALSE;
00164         mPaused = FALSE;
00165         mPauseTime = 0.f;
00166         mTimeStep = 0.f;
00167         mTimeStepCount = 0;
00168         mLastInterp = 0.f;
00169         mTimeFactor = 1.f;
00170 }
00171 
00172 
00173 //-----------------------------------------------------------------------------
00174 // ~LLMotionController()
00175 // Class Destructor
00176 //-----------------------------------------------------------------------------
00177 LLMotionController::~LLMotionController()
00178 {
00179         deleteAllMotions();
00180 }
00181 
00182 //-----------------------------------------------------------------------------
00183 // deleteAllMotions()
00184 //-----------------------------------------------------------------------------
00185 void LLMotionController::deleteAllMotions()
00186 {
00187         mLoadingMotions.clear();
00188         mLoadedMotions.clear();
00189         mActiveMotions.clear();
00190 
00191         for_each(mAllMotions.begin(), mAllMotions.end(), DeletePairedPointer());
00192         mAllMotions.clear();
00193 }
00194 
00195 //-----------------------------------------------------------------------------
00196 // addLoadedMotion()
00197 //-----------------------------------------------------------------------------
00198 void LLMotionController::addLoadedMotion(LLMotion* motionp)
00199 {
00200         std::set<LLUUID> motions_to_kill;
00201 
00202         // gather all inactive, loaded motions
00203         if (mLoadedMotions.size() > MAX_MOTION_INSTANCES)
00204         {
00205                 // too many motions active this frame, kill all blenders
00206                 mPoseBlender.clearBlenders();
00207 
00208                 for (motion_list_t::iterator loaded_motion_it = mLoadedMotions.begin(); 
00209                         loaded_motion_it != mLoadedMotions.end(); 
00210                         ++loaded_motion_it)
00211                 {
00212                         LLMotion* cur_motionp = *loaded_motion_it;
00213                         
00214                         // motion isn't playing, delete it
00215                         if (!isMotionActive(cur_motionp))
00216                         {
00217                                 motions_to_kill.insert(cur_motionp->getID());
00218                         }
00219                 }
00220         }
00221 
00222         // clean up all inactive, loaded motions
00223         for (std::set<LLUUID>::iterator motion_it = motions_to_kill.begin();
00224                 motion_it != motions_to_kill.end();
00225                 ++motion_it)
00226         {
00227                 // look up the motion again by ID to get canonical instance
00228                 // and kill it only if that one is inactive
00229                 LLUUID motion_id = *motion_it;
00230                 LLMotion* motionp = findMotion(motion_id);
00231                 if (motionp && !isMotionActive(motionp))
00232                 {
00233                         removeMotion(motion_id);
00234                 }
00235         }
00236 
00237         // add new motion to loaded list
00238         mLoadedMotions.push_back(motionp);
00239 }
00240 
00241 //-----------------------------------------------------------------------------
00242 // setTimeStep()
00243 //-----------------------------------------------------------------------------
00244 void LLMotionController::setTimeStep(F32 step)
00245 {
00246         mTimeStep = step;
00247 
00248         if (step != 0.f)
00249         {
00250                 // make sure timestamps conform to new quantum
00251                 for (motion_list_t::iterator iter = mActiveMotions.begin();
00252                          iter != mActiveMotions.end(); ++iter)
00253                 {
00254                         LLMotion* motionp = *iter;
00255                         motionp->mActivationTimestamp = (F32)llfloor(motionp->mActivationTimestamp / step) * step;
00256                         BOOL stopped = motionp->isStopped();
00257                         motionp->setStopTime((F32)llfloor(motionp->getStopTime() / step) * step);
00258                         motionp->setStopped(stopped);
00259                         motionp->mSendStopTimestamp = (F32)llfloor(motionp->mSendStopTimestamp / step) * step;
00260                 }
00261         }
00262 }
00263 
00264 //-----------------------------------------------------------------------------
00265 // setTimeFactor()
00266 //-----------------------------------------------------------------------------
00267 void LLMotionController::setTimeFactor(F32 time_factor)
00268 { 
00269         mTimeOffset += mTimer.getElapsedTimeAndResetF32() * mTimeFactor; 
00270         mTimeFactor = time_factor; 
00271 }
00272 
00273 //-----------------------------------------------------------------------------
00274 // setCharacter()
00275 //-----------------------------------------------------------------------------
00276 void LLMotionController::setCharacter(LLCharacter *character)
00277 {
00278         mCharacter = character;
00279 }
00280 
00281 
00282 //-----------------------------------------------------------------------------
00283 // addMotion()
00284 //-----------------------------------------------------------------------------
00285 BOOL LLMotionController::addMotion( const LLUUID& id, LLMotionConstructor constructor )
00286 {
00287         return sRegistry.addMotion(id, constructor);
00288 }
00289 
00290 //-----------------------------------------------------------------------------
00291 // removeMotion()
00292 //-----------------------------------------------------------------------------
00293 void LLMotionController::removeMotion( const LLUUID& id)
00294 {
00295         LLMotion* motionp = findMotion(id);
00296         
00297         removeMotionInstance(motionp);
00298 
00299         mAllMotions.erase(id);
00300 }
00301 
00302 // removes instance of a motion from all runtime structures, but does
00303 // not erase entry by ID, as this could be a duplicate instance
00304 // use removeMotion(id) to remove all references to a given motion by id.
00305 void LLMotionController::removeMotionInstance(LLMotion* motionp)
00306 {
00307         if (motionp)
00308         {
00309                 stopMotionInstance(motionp, TRUE);
00310 
00311                 mLoadingMotions.erase(motionp);
00312                 mLoadedMotions.remove(motionp);
00313                 mActiveMotions.remove(motionp);
00314                 delete motionp;
00315         }
00316 }
00317 
00318 //-----------------------------------------------------------------------------
00319 // createMotion()
00320 //-----------------------------------------------------------------------------
00321 LLMotion* LLMotionController::createMotion( const LLUUID &id )
00322 {
00323         // do we have an instance of this motion for this character?
00324         LLMotion *motion = findMotion(id);
00325 
00326         // if not, we need to create one
00327         if (!motion)
00328         {
00329                 // look up constructor and create it
00330                 motion = sRegistry.createMotion(id);
00331                 if (!motion)
00332                 {
00333                         return NULL;
00334                 }
00335 
00336                 // look up name for default motions
00337                 const char* motion_name = gAnimLibrary.animStateToString(id);
00338                 if (motion_name)
00339                 {
00340                         motion->setName(motion_name);
00341                 }
00342 
00343                 // initialize the new instance
00344                 LLMotion::LLMotionInitStatus stat = motion->onInitialize(mCharacter);
00345                 switch(stat)
00346                 {
00347                 case LLMotion::STATUS_FAILURE:
00348                         llinfos << "Motion " << id << " init failed." << llendl;
00349                         sRegistry.markBad(id);
00350                         delete motion;
00351                         return NULL;
00352                 case LLMotion::STATUS_HOLD:
00353                         mLoadingMotions.insert(motion);
00354                         break;
00355                 case LLMotion::STATUS_SUCCESS:
00356                         // add motion to our list
00357                         addLoadedMotion(motion);
00358                         break;
00359                 default:
00360                         llerrs << "Invalid initialization status" << llendl;
00361                         break;
00362                 }
00363 
00364                 mAllMotions[id] = motion;
00365         }
00366         return motion;
00367 }
00368 
00369 //-----------------------------------------------------------------------------
00370 // startMotion()
00371 //-----------------------------------------------------------------------------
00372 BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset)
00373 {
00374         // do we have an instance of this motion for this character?
00375         LLMotion *motion = findMotion(id);
00376 
00377         // motion that is stopping will be allowed to stop but
00378         // replaced by a new instance of that motion
00379         if (motion
00380                 && motion->canDeprecate()
00381                 && motion->getFadeWeight() > 0.01f // not LOD-ed out
00382                 && (motion->isBlending() || motion->getStopTime() != 0.f))
00383         {
00384                 deprecateMotionInstance(motion);
00385                 // force creation of new instance
00386                 motion = NULL;
00387         }
00388 
00389         // create new motion instance
00390         if (!motion)
00391         {
00392                 motion = createMotion(id);
00393         }
00394 
00395         if (!motion)
00396         {
00397                 return FALSE;
00398         }
00399         //if the motion is already active and allows deprecation, then let it keep playing
00400         else if (motion->canDeprecate() && isMotionActive(motion))
00401         {       
00402                 return TRUE;
00403         }
00404 
00405 //      llinfos << "Starting motion " << name << llendl;
00406         return activateMotionInstance(motion, mTime - start_offset);
00407 }
00408 
00409 
00410 //-----------------------------------------------------------------------------
00411 // stopMotionLocally()
00412 //-----------------------------------------------------------------------------
00413 BOOL LLMotionController::stopMotionLocally(const LLUUID &id, BOOL stop_immediate)
00414 {
00415         // if already inactive, return false
00416         LLMotion *motion = findMotion(id);
00417 
00418         return stopMotionInstance(motion, stop_immediate);
00419 }
00420 
00421 BOOL LLMotionController::stopMotionInstance(LLMotion* motion, BOOL stop_immediate)
00422 {
00423         if (!motion)
00424         {
00425                 return FALSE;
00426         }
00427 
00428         // If on active list, stop it
00429         if (isMotionActive(motion) && !motion->isStopped())
00430         {
00431                 // when using timesteps, set stop time to last frame's time, otherwise grab current timer value
00432                 // *FIX: should investigate this inconsistency...hints of obscure bugs
00433 
00434                 F32 stop_time = (mTimeStep != 0.f || mPaused) ? (mTime) : mTimeOffset + (mTimer.getElapsedTimeF32() * mTimeFactor);
00435                 motion->setStopTime(stop_time);
00436 
00437                 if (stop_immediate)
00438                 {
00439                         deactivateMotionInstance(motion);
00440                 }
00441                 return TRUE;
00442         }
00443         else if (isMotionLoading(motion))
00444         {
00445                 motion->setStopped(TRUE);
00446                 return TRUE;
00447         }
00448 
00449         return FALSE;
00450 }
00451 
00452 
00453 //-----------------------------------------------------------------------------
00454 // updateRegularMotions()
00455 //-----------------------------------------------------------------------------
00456 void LLMotionController::updateRegularMotions()
00457 {
00458         updateMotionsByType(LLMotion::NORMAL_BLEND);
00459 }
00460 
00461 //-----------------------------------------------------------------------------
00462 // updateAdditiveMotions()
00463 //-----------------------------------------------------------------------------
00464 void LLMotionController::updateAdditiveMotions()
00465 {
00466         updateMotionsByType(LLMotion::ADDITIVE_BLEND);
00467 }
00468 
00469 //-----------------------------------------------------------------------------
00470 // resetJointSignatures()
00471 //-----------------------------------------------------------------------------
00472 void LLMotionController::resetJointSignatures()
00473 {
00474         memset(&mJointSignature[0][0], 0, sizeof(U8) * LL_CHARACTER_MAX_JOINTS);
00475         memset(&mJointSignature[1][0], 0, sizeof(U8) * LL_CHARACTER_MAX_JOINTS);
00476 }
00477 
00478 //-----------------------------------------------------------------------------
00479 // updateMotionsByType()
00480 //-----------------------------------------------------------------------------
00481 void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_type)
00482 {
00483         BOOL update_result = TRUE;
00484         U8 last_joint_signature[LL_CHARACTER_MAX_JOINTS];
00485 
00486         memset(&last_joint_signature, 0, sizeof(U8) * LL_CHARACTER_MAX_JOINTS);
00487 
00488         // iterate through active motions in chronological order
00489         for (motion_list_t::iterator iter = mActiveMotions.begin();
00490                  iter != mActiveMotions.end(); )
00491         {
00492                 motion_list_t::iterator curiter = iter++;
00493                 LLMotion* motionp = *curiter;
00494                 if (motionp->getBlendType() != anim_type)
00495                 {
00496                         continue;
00497                 }
00498 
00499                 BOOL update_motion = FALSE;
00500 
00501                 if (motionp->getPose()->getWeight() < 1.f)
00502                 {
00503                         update_motion = TRUE;
00504                 }
00505                 else
00506                 {
00507                         // NUM_JOINT_SIGNATURE_STRIDES should be multiple of 4
00508                         for (S32 i = 0; i < NUM_JOINT_SIGNATURE_STRIDES; i++)
00509                         {
00510                                 U32 *current_signature = (U32*)&(mJointSignature[0][i * 4]);
00511                                 U32 test_signature = *(U32*)&(motionp->mJointSignature[0][i * 4]);
00512                                 
00513                                 if ((*current_signature | test_signature) > (*current_signature))
00514                                 {
00515                                         *current_signature |= test_signature;
00516                                         update_motion = TRUE;
00517                                 }
00518 
00519                                 *((U32*)&last_joint_signature[i * 4]) = *(U32*)&(mJointSignature[1][i * 4]);
00520                                 current_signature = (U32*)&(mJointSignature[1][i * 4]);
00521                                 test_signature = *(U32*)&(motionp->mJointSignature[1][i * 4]);
00522 
00523                                 if ((*current_signature | test_signature) > (*current_signature))
00524                                 {
00525                                         *current_signature |= test_signature;
00526                                         update_motion = TRUE;
00527                                 }
00528                         }
00529                 }
00530 
00531                 if (!update_motion)
00532                 {
00533                         if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration())
00534                         {
00535                                 deactivateMotionInstance(motionp);
00536                         }
00537                         else if (motionp->isStopped() && mTime > motionp->getStopTime())
00538                         {
00539                                 // is this the first iteration in the ease out phase?
00540                                 if (mLastTime <= motionp->getStopTime())
00541                                 {
00542                                         // store residual weight for this motion
00543                                         motionp->mResidualWeight = motionp->getPose()->getWeight();
00544                                 }
00545                         }
00546                         else if (mTime > motionp->mSendStopTimestamp)
00547                         {
00548                                 // notify character of timed stop event on first iteration past sendstoptimestamp
00549                                 // this will only be called when an animation stops itself (runs out of time)
00550                                 if (mLastTime <= motionp->mSendStopTimestamp)
00551                                 {
00552                                         mCharacter->requestStopMotion( motionp );
00553                                         stopMotionInstance(motionp, FALSE);
00554                                 }
00555                         }
00556                         else if (mTime >= motionp->mActivationTimestamp)
00557                         {
00558                                 if (mLastTime < motionp->mActivationTimestamp)
00559                                 {
00560                                         motionp->mResidualWeight = motionp->getPose()->getWeight();
00561                                 }
00562                         }
00563                         continue;
00564                 }
00565 
00566                 LLPose *posep = motionp->getPose();
00567 
00568                 // only filter by LOD after running every animation at least once (to prime the avatar state)
00569                 if (mHasRunOnce && motionp->getMinPixelArea() > mCharacter->getPixelArea())
00570                 {
00571                         motionp->fadeOut();
00572 
00573                         //should we notify the simulator that this motion should be stopped (check even if skipped by LOD logic)
00574                         if (mTime > motionp->mSendStopTimestamp)
00575                         {
00576                                 // notify character of timed stop event on first iteration past sendstoptimestamp
00577                                 // this will only be called when an animation stops itself (runs out of time)
00578                                 if (mLastTime <= motionp->mSendStopTimestamp)
00579                                 {
00580                                         mCharacter->requestStopMotion( motionp );
00581                                         stopMotionInstance(motionp, FALSE);
00582                                 }
00583                         }
00584 
00585                         if (motionp->getFadeWeight() < 0.01f)
00586                         {
00587                                 if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration())
00588                                 {
00589                                         posep->setWeight(0.f);
00590                                         deactivateMotionInstance(motionp);
00591                                 }
00592                                 continue;
00593                         }
00594                 }
00595                 else
00596                 {
00597                         motionp->fadeIn();
00598                 }
00599 
00600                 //**********************
00601                 // MOTION INACTIVE
00602                 //**********************
00603                 if (motionp->isStopped() && mTime > motionp->getStopTime() + motionp->getEaseOutDuration())
00604                 {
00605                         // this motion has gone on too long, deactivate it
00606                         // did we have a chance to stop it?
00607                         if (mLastTime <= motionp->getStopTime())
00608                         {
00609                                 // if not, let's stop it this time through and deactivate it the next
00610 
00611                                 posep->setWeight(motionp->getFadeWeight());
00612                                 motionp->onUpdate(motionp->getStopTime() - motionp->mActivationTimestamp, last_joint_signature);
00613                         }
00614                         else
00615                         {
00616                                 posep->setWeight(0.f);
00617                                 deactivateMotionInstance(motionp);
00618                                 continue;
00619                         }
00620                 }
00621 
00622                 //**********************
00623                 // MOTION EASE OUT
00624                 //**********************
00625                 else if (motionp->isStopped() && mTime > motionp->getStopTime())
00626                 {
00627                         // is this the first iteration in the ease out phase?
00628                         if (mLastTime <= motionp->getStopTime())
00629                         {
00630                                 // store residual weight for this motion
00631                                 motionp->mResidualWeight = motionp->getPose()->getWeight();
00632                         }
00633 
00634                         if (motionp->getEaseOutDuration() == 0.f)
00635                         {
00636                                 posep->setWeight(0.f);
00637                         }
00638                         else
00639                         {
00640                                 posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight * cubic_step(1.f - ((mTime - motionp->getStopTime()) / motionp->getEaseOutDuration())));
00641                         }
00642 
00643                         // perform motion update
00644                         update_result = motionp->onUpdate(mTime - motionp->mActivationTimestamp, last_joint_signature);
00645                 }
00646 
00647                 //**********************
00648                 // MOTION ACTIVE
00649                 //**********************
00650                 else if (mTime > motionp->mActivationTimestamp + motionp->getEaseInDuration())
00651                 {
00652                         posep->setWeight(motionp->getFadeWeight());
00653 
00654                         //should we notify the simulator that this motion should be stopped?
00655                         if (mTime > motionp->mSendStopTimestamp)
00656                         {
00657                                 // notify character of timed stop event on first iteration past sendstoptimestamp
00658                                 // this will only be called when an animation stops itself (runs out of time)
00659                                 if (mLastTime <= motionp->mSendStopTimestamp)
00660                                 {
00661                                         mCharacter->requestStopMotion( motionp );
00662                                         stopMotionInstance(motionp, FALSE);
00663                                 }
00664                         }
00665 
00666                         // perform motion update
00667                         update_result = motionp->onUpdate(mTime - motionp->mActivationTimestamp, last_joint_signature);
00668                 }
00669 
00670                 //**********************
00671                 // MOTION EASE IN
00672                 //**********************
00673                 else if (mTime >= motionp->mActivationTimestamp)
00674                 {
00675                         if (mLastTime < motionp->mActivationTimestamp)
00676                         {
00677                                 motionp->mResidualWeight = motionp->getPose()->getWeight();
00678                         }
00679                         if (motionp->getEaseInDuration() == 0.f)
00680                         {
00681                                 posep->setWeight(motionp->getFadeWeight());
00682                         }
00683                         else
00684                         {
00685                                 // perform motion update
00686                                 posep->setWeight(motionp->getFadeWeight() * motionp->mResidualWeight + (1.f - motionp->mResidualWeight) * cubic_step((mTime - motionp->mActivationTimestamp) / motionp->getEaseInDuration()));
00687                         }
00688                         // perform motion update
00689                         update_result = motionp->onUpdate(mTime - motionp->mActivationTimestamp, last_joint_signature);
00690                 }
00691                 else
00692                 {
00693                         posep->setWeight(0.f);
00694                         update_result = motionp->onUpdate(0.f, last_joint_signature);
00695                 }
00696                 
00697                 // allow motions to deactivate themselves 
00698                 if (!update_result)
00699                 {
00700                         if (!motionp->isStopped() || motionp->getStopTime() > mTime)
00701                         {
00702                                 // animation has stopped itself due to internal logic
00703                                 // propagate this to the network
00704                                 // as not all viewers are guaranteed to have access to the same logic
00705                                 mCharacter->requestStopMotion( motionp );
00706                                 stopMotionInstance(motionp, FALSE);
00707                         }
00708 
00709                 }
00710 
00711                 // even if onupdate returns FALSE, add this motion in to the blend one last time
00712                 mPoseBlender.addMotion(motionp);
00713         }
00714 }
00715 
00716 
00717 //-----------------------------------------------------------------------------
00718 // updateMotion()
00719 //-----------------------------------------------------------------------------
00720 void LLMotionController::updateMotion()
00721 {
00722         BOOL use_quantum = (mTimeStep != 0.f);
00723 
00724         // Update timing info for this time step.
00725         if (!mPaused)
00726         {
00727                 F32 update_time = mTimeOffset + (mTimer.getElapsedTimeF32() * mTimeFactor);
00728                 if (use_quantum)
00729                 {
00730                         F32 time_interval = fmodf(update_time, mTimeStep);
00731 
00732                         // always animate *ahead* of actual time
00733                         S32 quantum_count = llmax(0, llfloor((update_time - time_interval) / mTimeStep)) + 1;
00734                         if (quantum_count == mTimeStepCount)
00735                         {
00736                                 // we're still in same time quantum as before, so just interpolate and exit
00737                                 if (!mPaused)
00738                                 {
00739                                         F32 interp = time_interval / mTimeStep;
00740                                         mPoseBlender.interpolate(interp - mLastInterp);
00741                                         mLastInterp = interp;
00742                                 }
00743                                 
00744                                 return;
00745                         }
00746                         
00747                         // is calculating a new keyframe pose, make sure the last one gets applied
00748                         mPoseBlender.interpolate(1.f);
00749                         mPoseBlender.clearBlenders();
00750 
00751                         mTimeStepCount = quantum_count;
00752                         mLastTime = mTime;
00753                         mTime = (F32)quantum_count * mTimeStep;
00754                         mLastInterp = 0.f;
00755                 }
00756                 else
00757                 {
00758                         mLastTime = mTime;
00759                         mTime = update_time;
00760                 }
00761         }
00762 
00763         // query pending motions for completion
00764         for (motion_set_t::iterator iter = mLoadingMotions.begin();
00765                  iter != mLoadingMotions.end(); )
00766         {
00767                 motion_set_t::iterator curiter = iter++;
00768                 LLMotion* motionp = *curiter;
00769                 if( !motionp)
00770                 {
00771                         continue; // maybe shouldn't happen but i've seen it -MG
00772                 }
00773                 LLMotion::LLMotionInitStatus status = motionp->onInitialize(mCharacter);
00774                 if (status == LLMotion::STATUS_SUCCESS)
00775                 {
00776                         mLoadingMotions.erase(curiter);
00777                         // add motion to our loaded motion list
00778                         addLoadedMotion(motionp);
00779                         // this motion should be playing
00780                         if (!motionp->isStopped())
00781                         {
00782                                 activateMotionInstance(motionp, mTime);
00783                         }
00784                 }
00785                 else if (status == LLMotion::STATUS_FAILURE)
00786                 {
00787                         llinfos << "Motion " << motionp->getID() << " init failed." << llendl;
00788                         sRegistry.markBad(motionp->getID());
00789                         mLoadingMotions.erase(curiter);
00790 
00791                         mAllMotions.erase(motionp->getID());
00792                         delete motionp;
00793                 }
00794         }
00795 
00796         resetJointSignatures();
00797 
00798         if (!mPaused)
00799         {
00800                 // update additive motions
00801                 updateAdditiveMotions();
00802                 resetJointSignatures();
00803 
00804                 // update all regular motions
00805                 updateRegularMotions();
00806 
00807                 if (use_quantum)
00808                 {
00809                         mPoseBlender.blendAndCache(TRUE);
00810                 }
00811                 else
00812                 {
00813                         mPoseBlender.blendAndApply();
00814                 }
00815         }
00816 
00817         mHasRunOnce = TRUE;
00818 //      llinfos << "Motion controller time " << motionTimer.getElapsedTimeF32() << llendl;
00819 }
00820 
00821 
00822 //-----------------------------------------------------------------------------
00823 // activateMotionInstance()
00824 //-----------------------------------------------------------------------------
00825 BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time)
00826 {
00827         if (mLoadingMotions.find(motion) != mLoadingMotions.end())
00828         {
00829                 // we want to start this motion, but we can't yet, so flag it as started
00830                 motion->setStopped(FALSE);
00831                 // report pending animations as activated
00832                 return TRUE;
00833         }
00834 
00835         motion->mResidualWeight = motion->getPose()->getWeight();
00836         motion->mActivationTimestamp = time;
00837 
00838         // set stop time based on given duration and ease out time
00839         if (motion->getDuration() != 0.f && !motion->getLoop())
00840         {
00841                 F32 ease_out_time;
00842                 F32 motion_duration;
00843 
00844                 // should we stop at the end of motion duration, or a bit earlier 
00845                 // to allow it to ease out while moving?
00846                 ease_out_time = motion->getEaseOutDuration();
00847 
00848                 // is the clock running when the motion is easing in?
00849                 // if not (POSTURE_EASE) then we need to wait that much longer before triggering the stop
00850                 motion_duration = llmax(motion->getDuration() - ease_out_time, 0.f);
00851                 motion->mSendStopTimestamp = time + motion_duration;
00852         } 
00853         else
00854         {
00855                 motion->mSendStopTimestamp = F32_MAX;
00856         }
00857 
00858         mActiveMotions.remove(motion); // in case it is already in the active list
00859         mActiveMotions.push_front(motion);
00860 
00861         motion->activate();
00862         motion->onUpdate(0.f, mJointSignature[1]);
00863 
00864         return TRUE;
00865 }
00866 
00867 //-----------------------------------------------------------------------------
00868 // deactivateMotionInstance()
00869 //-----------------------------------------------------------------------------
00870 BOOL LLMotionController::deactivateMotionInstance(LLMotion *motion)
00871 {
00872         motion->deactivate();
00873 
00874         motion_set_t::iterator found_it = mDeprecatedMotions.find(motion);
00875         if (found_it != mDeprecatedMotions.end())
00876         {
00877                 // deprecated motions need to be completely excised
00878                 removeMotionInstance(motion);   
00879                 mDeprecatedMotions.erase(found_it);
00880         }
00881         else
00882         {
00883                 // for motions that we are keeping, simply remove from active queue
00884                 mActiveMotions.remove(motion);
00885         }
00886 
00887         return TRUE;
00888 }
00889 
00890 void LLMotionController::deprecateMotionInstance(LLMotion* motion)
00891 {
00892         mDeprecatedMotions.insert(motion);
00893 
00894         //fade out deprecated motion
00895         stopMotionInstance(motion, FALSE);
00896         //no longer canonical
00897         mAllMotions.erase(motion->getID());
00898 }
00899 
00900 //-----------------------------------------------------------------------------
00901 // isMotionActive()
00902 //-----------------------------------------------------------------------------
00903 bool LLMotionController::isMotionActive(LLMotion *motion)
00904 {
00905         return (motion && motion->isActive());
00906 }
00907 
00908 //-----------------------------------------------------------------------------
00909 // isMotionLoading()
00910 //-----------------------------------------------------------------------------
00911 bool LLMotionController::isMotionLoading(LLMotion* motion)
00912 {
00913         return (mLoadingMotions.find(motion) != mLoadingMotions.end());
00914 }
00915 
00916 
00917 //-----------------------------------------------------------------------------
00918 // findMotion()
00919 //-----------------------------------------------------------------------------
00920 LLMotion *LLMotionController::findMotion(const LLUUID& id)
00921 {
00922         return get_if_there<LLUUID, LLMotion*>(mAllMotions, id, NULL);
00923 }
00924 
00925 //-----------------------------------------------------------------------------
00926 // deactivateAllMotions()
00927 //-----------------------------------------------------------------------------
00928 void LLMotionController::deactivateAllMotions()
00929 {
00930         //They must all die, precious.
00931         for (std::map<LLUUID, LLMotion*>::iterator iter = mAllMotions.begin();
00932                  iter != mAllMotions.end(); iter++)
00933         {
00934                 LLMotion* motionp = iter->second;
00935                 if (motionp) motionp->deactivate();
00936         }
00937 
00938         // delete all motion instances
00939         deleteAllMotions();
00940 }
00941 
00942 
00943 //-----------------------------------------------------------------------------
00944 // flushAllMotions()
00945 //-----------------------------------------------------------------------------
00946 void LLMotionController::flushAllMotions()
00947 {
00948         std::vector<std::pair<LLUUID,F32> > active_motions;
00949         active_motions.reserve(mActiveMotions.size());
00950         for (motion_list_t::iterator iter = mActiveMotions.begin();
00951                  iter != mActiveMotions.end(); )
00952         {
00953                 motion_list_t::iterator curiter = iter++;
00954                 LLMotion* motionp = *curiter;
00955                 F32 dtime = mTime - motionp->mActivationTimestamp;
00956                 active_motions.push_back(std::make_pair(motionp->getID(),dtime));
00957                 motionp->deactivate();
00958         }
00959 
00960         // delete all motion instances
00961         deleteAllMotions();
00962 
00963         // kill current hand pose that was previously called out by
00964         // keyframe motion
00965         mCharacter->removeAnimationData("Hand Pose");
00966 
00967         // restart motions
00968         for (std::vector<std::pair<LLUUID,F32> >::iterator iter = active_motions.begin();
00969                  iter != active_motions.end(); ++iter)
00970         {
00971                 startMotion(iter->first, iter->second);
00972         }
00973 }
00974 
00975 //-----------------------------------------------------------------------------
00976 // pause()
00977 //-----------------------------------------------------------------------------
00978 void LLMotionController::pause()
00979 {
00980         if (!mPaused)
00981         {
00982                 //llinfos << "Pausing animations..." << llendl;
00983                 mPauseTime = mTimer.getElapsedTimeF32();
00984                 mPaused = TRUE;
00985         }
00986         
00987 }
00988 
00989 //-----------------------------------------------------------------------------
00990 // unpause()
00991 //-----------------------------------------------------------------------------
00992 void LLMotionController::unpause()
00993 {
00994         if (mPaused)
00995         {
00996                 //llinfos << "Unpausing animations..." << llendl;
00997                 mTimer.reset();
00998                 mTimer.setAge(mPauseTime);
00999                 mPaused = FALSE;
01000         }
01001 }
01002 // End

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