//-----------------------------------------------------------------------------
// 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;
		}
	}
}
示例#5
0
//-----------------------------------------------------------------------------
// 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;
}