//----------------------------------------------------------------------------- // LLKeyframeMotionParam::onInitialize(LLCharacter *character) //----------------------------------------------------------------------------- LLMotion::LLMotionInitStatus LLKeyframeMotionParam::onInitialize(LLCharacter *character) { mCharacter = character; if (!loadMotions()) { return STATUS_FAILURE; } for (motion_map_t::iterator iter = mParameterizedMotions.begin(); iter != mParameterizedMotions.end(); ++iter) { motion_list_t& motionList = iter->second; for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) { const ParameterizedMotion& paramMotion = *iter2; LLMotion* motion = paramMotion.mMotion; motion->onInitialize(character); // <FS> Fix copy paste error //if (motion->getDuration() > mEaseInDuration) if (motion->getEaseInDuration() > mEaseInDuration) // </FS> { mEaseInDuration = motion->getEaseInDuration(); } if (motion->getEaseOutDuration() > mEaseOutDuration) { mEaseOutDuration = motion->getEaseOutDuration(); } if (motion->getDuration() > mDuration) { mDuration = motion->getDuration(); } if (motion->getPriority() > mPriority) { mPriority = motion->getPriority(); } LLPose *pose = motion->getPose(); mPoseBlender.addMotion(motion); for (LLJointState *jsp = pose->getFirstJointState(); jsp; jsp = pose->getNextJointState()) { LLPose *blendedPose = mPoseBlender.getBlendedPose(); blendedPose->addJointState(jsp); } } } return STATUS_SUCCESS; }
//----------------------------------------------------------------------------- // updateLoadingMotions() //----------------------------------------------------------------------------- void LLMotionController::updateLoadingMotions() { // query pending motions for completion for (motion_set_t::iterator iter = mLoadingMotions.begin(); iter != mLoadingMotions.end(); ) { motion_set_t::iterator curiter = iter++; LLMotion* motionp = *curiter; if( !motionp) { continue; // maybe shouldn't happen but i've seen it -MG } LLMotion::LLMotionInitStatus status = motionp->onInitialize(mCharacter); if (status == LLMotion::STATUS_SUCCESS) { mLoadingMotions.erase(curiter); // add motion to our loaded motion list mLoadedMotions.insert(motionp); // this motion should be playing if (!motionp->isStopped()) { //<singu> F32 start_time = mAnimTime; if (!mDisableSyncing) { motionp->aisync_loaded(); start_time = motionp->syncActivationTime(start_time); } ++mDisableSyncing; //</singu> activateMotionInstance(motionp, start_time); //<singu> --mDisableSyncing; //</singu> } } else if (status == LLMotion::STATUS_FAILURE) { llinfos << "Motion " << motionp->getID() << " init failed." << llendl; sRegistry.markBad(motionp->getID()); mLoadingMotions.erase(curiter); // Singu note: a motion in mLoadingMotions will not be in mActiveMotions // and therefore not be in mDeprecatedMotions. So, we don't have to // check for it's existence there. llassert(mDeprecatedMotions.find(motionp) == mDeprecatedMotions.end()); mAllMotions.erase(motionp->getID()); //<singu> // Make sure we're not registered anymore. motionp->unregister_client(); //</singu> delete motionp; } } }
//----------------------------------------------------------------------------- // createMotion() //----------------------------------------------------------------------------- LLMotion* LLMotionController::createMotion( const LLUUID &id ) { LLMemType mt(LLMemType::MTYPE_ANIMATION); // do we have an instance of this motion for this character? LLMotion *motion = findMotion(id); // if not, we need to create one if (!motion) { // look up constructor and create it motion = sRegistry.createMotion(id); if (!motion) { return NULL; } // look up name for default motions const char* motion_name = gAnimLibrary.animStateToString(id); if (motion_name) { motion->setName(motion_name); } // initialize the new instance LLMotion::LLMotionInitStatus stat = motion->onInitialize(mCharacter); switch(stat) { case LLMotion::STATUS_FAILURE: llinfos << "Motion " << id << " init failed." << llendl; sRegistry.markBad(id); delete motion; return NULL; case LLMotion::STATUS_HOLD: mLoadingMotions.insert(motion); break; case LLMotion::STATUS_SUCCESS: // add motion to our list mLoadedMotions.insert(motion); break; default: llerrs << "Invalid initialization status" << llendl; break; } mAllMotions[id] = motion; } return motion; }
//----------------------------------------------------------------------------- // updateLoadingMotions() //----------------------------------------------------------------------------- void LLMotionController::updateLoadingMotions() { // query pending motions for completion for (motion_set_t::iterator iter = mLoadingMotions.begin(); iter != mLoadingMotions.end(); ) { motion_set_t::iterator curiter = iter++; LLMotion* motionp = *curiter; if( !motionp) { continue; // maybe shouldn't happen but i've seen it -MG } LLMotion::LLMotionInitStatus status = motionp->onInitialize(mCharacter); if (status == LLMotion::STATUS_SUCCESS) { mLoadingMotions.erase(curiter); // add motion to our loaded motion list mLoadedMotions.insert(motionp); // this motion should be playing if (!motionp->isStopped()) { activateMotionInstance(motionp, mAnimTime); } } else if (status == LLMotion::STATUS_FAILURE) { llinfos << "Motion " << motionp->getID() << " init failed." << llendl; sRegistry.markBad(motionp->getID()); mLoadingMotions.erase(curiter); motion_set_t::iterator found_it = mDeprecatedMotions.find(motionp); if (found_it != mDeprecatedMotions.end()) { mDeprecatedMotions.erase(found_it); } mAllMotions.erase(motionp->getID()); delete motionp; } } }
//----------------------------------------------------------------------------- // updateMotion() //----------------------------------------------------------------------------- void LLMotionController::updateMotion() { BOOL use_quantum = (mTimeStep != 0.f); // Update timing info for this time step. if (!mPaused) { F32 update_time = mTimeOffset + (mTimer.getElapsedTimeF32() * mTimeFactor); if (use_quantum) { F32 time_interval = fmodf(update_time, mTimeStep); // always animate *ahead* of actual time S32 quantum_count = llmax(0, llfloor((update_time - time_interval) / mTimeStep)) + 1; if (quantum_count == mTimeStepCount) { // we're still in same time quantum as before, so just interpolate and exit if (!mPaused) { F32 interp = time_interval / mTimeStep; mPoseBlender.interpolate(interp - mLastInterp); mLastInterp = interp; } return; } // is calculating a new keyframe pose, make sure the last one gets applied mPoseBlender.interpolate(1.f); mPoseBlender.clearBlenders(); mTimeStepCount = quantum_count; mLastTime = mTime; mTime = (F32)quantum_count * mTimeStep; mLastInterp = 0.f; } else { mLastTime = mTime; mTime = update_time; } } // query pending motions for completion for (motion_set_t::iterator iter = mLoadingMotions.begin(); iter != mLoadingMotions.end(); ) { motion_set_t::iterator curiter = iter++; LLMotion* motionp = *curiter; if( !motionp) { continue; // maybe shouldn't happen but i've seen it -MG } LLMotion::LLMotionInitStatus status = motionp->onInitialize(mCharacter); if (status == LLMotion::STATUS_SUCCESS) { mLoadingMotions.erase(curiter); // add motion to our loaded motion list addLoadedMotion(motionp); // this motion should be playing if (!motionp->isStopped()) { activateMotion(motionp, mTime); } } else if (status == LLMotion::STATUS_FAILURE) { llinfos << "Motion " << motionp->getID() << " init failed." << llendl; sRegistry.markBad(motionp->getID()); mLoadingMotions.erase(curiter); mAllMotions.erase(motionp->getID()); delete motionp; } } resetJointSignatures(); if (!mPaused) { // update additive motions updateAdditiveMotions(); resetJointSignatures(); // update all regular motions updateRegularMotions(); if (use_quantum) { mPoseBlender.blendAndCache(TRUE); } else { mPoseBlender.blendAndApply(); } } mHasRunOnce = TRUE; // llinfos << "Motion controller time " << motionTimer.getElapsedTimeF32() << llendl; }