Implement a KeyframeController

actorid
Chris Robinson 12 years ago
parent f69a8259e1
commit 261ea1fe5e

@ -37,6 +37,7 @@ Animation::Animation(const MWWorld::Ptr &ptr)
, mNonAccumRoot(NULL)
, mAccumulate(Ogre::Vector3::ZERO)
, mLastPosition(0.0f)
, mCurrentControllers(NULL)
, mCurrentKeys(NULL)
, mCurrentAnim(NULL)
, mCurrentTime(0.0f)
@ -68,6 +69,7 @@ void Animation::setAnimationSources(const std::vector<std::string> &names)
return;
Ogre::SceneManager *sceneMgr = mInsert->getCreator();
mCurrentControllers = &mObjectList.mControllers;
mCurrentAnim = NULL;
mCurrentKeys = NULL;
mAnimVelocity = 0.0f;
@ -78,6 +80,7 @@ void Animation::setAnimationSources(const std::vector<std::string> &names)
destroyObjectList(sceneMgr, mAnimationSources[i]);
mAnimationSources.clear();
Ogre::SharedPtr<Ogre::ControllerValue<Ogre::Real> > ctrlval(OGRE_NEW AnimationValue(this));
Ogre::SkeletonInstance *skelinst = mObjectList.mSkelBase->getSkeleton();
std::vector<std::string>::const_iterator nameiter;
for(nameiter = names.begin();nameiter != names.end();nameiter++)
@ -90,7 +93,7 @@ void Animation::setAnimationSources(const std::vector<std::string> &names)
mAnimationSources.pop_back();
continue;
}
const NifOgre::ObjectList &objects = mAnimationSources.back();
NifOgre::ObjectList &objects = mAnimationSources.back();
for(size_t i = 0;i < objects.mControllers.size();i++)
{
@ -104,7 +107,13 @@ void Animation::setAnimationSources(const std::vector<std::string> &names)
dstval->setNode(bone);
}
Ogre::Entity *ent = mAnimationSources.back().mSkelBase;
for(size_t i = 0;i < objects.mControllers.size();i++)
{
if(objects.mControllers[i].getSource().isNull())
objects.mControllers[i].setSource(ctrlval);
}
Ogre::Entity *ent = objects.mSkelBase;
Ogre::SkeletonPtr skel = Ogre::SkeletonManager::getSingleton().getByName(ent->getSkeleton()->getName());
Ogre::Skeleton::BoneIterator boneiter = skel->getBoneIterator();
while(boneiter.hasMoreElements())
@ -167,6 +176,7 @@ void Animation::createObjectList(Ogre::SceneNode *node, const std::string &model
if(mObjectList.mControllers[i].getSource().isNull())
mObjectList.mControllers[i].setSource(ctrlval);
}
mCurrentControllers = &mObjectList.mControllers;
}
@ -441,12 +451,13 @@ void Animation::play(const std::string &groupname, const std::string &start, con
try {
bool found = false;
/* Look in reverse; last-inserted source has priority. */
for(std::vector<NifOgre::ObjectList>::const_reverse_iterator iter(mAnimationSources.rbegin());iter != mAnimationSources.rend();iter++)
for(std::vector<NifOgre::ObjectList>::reverse_iterator iter(mAnimationSources.rbegin());iter != mAnimationSources.rend();iter++)
{
if(iter->mSkelBase->hasAnimationState(groupname))
{
mCurrentAnim = iter->mSkelBase->getSkeleton()->getAnimation(groupname);
mCurrentKeys = &mTextKeys[groupname];
mCurrentControllers = &iter->mControllers;
mAnimVelocity = 0.0f;
if(mNonAccumRoot)
@ -495,8 +506,8 @@ Ogre::Vector3 Animation::runAnimation(float timepassed)
if(!handleEvent(time, evt))
break;
}
for(size_t i = 0;i < mObjectList.mControllers.size();i++)
mObjectList.mControllers[i].update();
for(size_t i = 0;i < mCurrentControllers->size();i++)
(*mCurrentControllers)[i].update();
return movement;
}

@ -49,6 +49,7 @@ protected:
std::vector<NifOgre::ObjectList> mAnimationSources;
std::vector<Ogre::Controller<Ogre::Real> > *mCurrentControllers;
NifOgre::TextKeyMap *mCurrentKeys;
NifOgre::TextKeyMap::const_iterator mNextKey;
Ogre::Animation *mCurrentAnim;

@ -169,6 +169,101 @@ public:
typedef DefaultFunction Function;
};
class KeyframeController
{
public:
class Value : public NodeTargetValue<Ogre::Real>
{
private:
Nif::QuaternionKeyList mRotations;
Nif::Vector3KeyList mTranslations;
Nif::FloatKeyList mScales;
public:
Value(Ogre::Node *target, const Nif::NiKeyframeData *data)
: NodeTargetValue<Ogre::Real>(target)
, mRotations(data->mRotations)
, mTranslations(data->mTranslations)
, mScales(data->mScales)
{ }
virtual Ogre::Real getValue() const
{
// Should not be called
return 0.0f;
}
virtual void setValue(Ogre::Real time)
{
if(mRotations.mKeys.size() > 0)
{
if(time <= mRotations.mKeys.front().mTime)
mNode->setOrientation(mRotations.mKeys.front().mValue);
else if(time >= mRotations.mKeys.back().mTime)
mNode->setOrientation(mRotations.mKeys.back().mValue);
else
{
Nif::QuaternionKeyList::VecType::const_iterator iter(mRotations.mKeys.begin()+1);
for(;iter != mRotations.mKeys.end();iter++)
{
if(iter->mTime < time)
continue;
Nif::QuaternionKeyList::VecType::const_iterator last(iter-1);
float a = (time-last->mTime) / (iter->mTime-last->mTime);
mNode->setOrientation(Ogre::Quaternion::nlerp(a, last->mValue, iter->mValue));
break;
}
}
}
if(mTranslations.mKeys.size() > 0)
{
if(time <= mTranslations.mKeys.front().mTime)
mNode->setPosition(mTranslations.mKeys.front().mValue);
else if(time >= mTranslations.mKeys.back().mTime)
mNode->setPosition(mTranslations.mKeys.back().mValue);
else
{
Nif::Vector3KeyList::VecType::const_iterator iter(mTranslations.mKeys.begin()+1);
for(;iter != mTranslations.mKeys.end();iter++)
{
if(iter->mTime < time)
continue;
Nif::Vector3KeyList::VecType::const_iterator last(iter-1);
float a = (time-last->mTime) / (iter->mTime-last->mTime);
mNode->setPosition(last->mValue + ((iter->mValue - last->mValue)*a));
break;
}
}
}
if(mScales.mKeys.size() > 0)
{
if(time <= mScales.mKeys.front().mTime)
mNode->setScale(Ogre::Vector3(mScales.mKeys.front().mValue));
else if(time >= mScales.mKeys.back().mTime)
mNode->setScale(Ogre::Vector3(mScales.mKeys.back().mValue));
else
{
Nif::FloatKeyList::VecType::const_iterator iter(mScales.mKeys.begin()+1);
for(;iter != mScales.mKeys.end();iter++)
{
if(iter->mTime < time)
continue;
Nif::FloatKeyList::VecType::const_iterator last(iter-1);
float a = (time-last->mTime) / (iter->mTime-last->mTime);
mNode->setScale(Ogre::Vector3(last->mValue + ((iter->mValue - last->mValue)*a)));
break;
}
}
}
}
};
typedef DefaultFunction Function;
};
class UVController
{
public:
@ -1546,6 +1641,18 @@ class NIFObjectLoader : Ogre::ManualResourceLoader
objectlist.mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
}
else if(ctrl->recType == Nif::RC_NiKeyframeController)
{
const Nif::NiKeyframeController *key = static_cast<const Nif::NiKeyframeController*>(ctrl.getPtr());
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(mName, ctrl->target->recIndex);
Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid);
Ogre::ControllerValueRealPtr srcval; /* Filled in later */
Ogre::ControllerValueRealPtr dstval(OGRE_NEW KeyframeController::Value(trgtbone, key->data.getPtr()));
Ogre::ControllerFunctionRealPtr func(OGRE_NEW KeyframeController::Function(key, false));
objectlist.mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
}
ctrl = ctrl->next;
}

Loading…
Cancel
Save