1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-19 22:23:51 +00:00

Parameterize the number of bone groups

This commit is contained in:
Chris Robinson 2013-05-10 16:33:13 -07:00
parent 8a9b0eb5f7
commit 921f534980
2 changed files with 57 additions and 22 deletions

View file

@ -20,7 +20,7 @@ namespace MWRender
Ogre::Real Animation::AnimationValue::getValue() const Ogre::Real Animation::AnimationValue::getValue() const
{ {
AnimStateMap::const_iterator iter = mAnimation->mStates.find(mAnimation->mAnimationName); AnimStateMap::const_iterator iter = mAnimation->mStates.find(mAnimationName);
if(iter != mAnimation->mStates.end()) if(iter != mAnimation->mStates.end())
return iter->second.mTime; return iter->second.mTime;
return 0.0f; return 0.0f;
@ -55,7 +55,8 @@ Animation::Animation(const MWWorld::Ptr &ptr)
, mAnimVelocity(0.0f) , mAnimVelocity(0.0f)
, mAnimSpeedMult(1.0f) , mAnimSpeedMult(1.0f)
{ {
mAnimationValuePtr.bind(OGRE_NEW AnimationValue(this)); for(size_t i = 0;i < sNumGroups;i++)
mAnimationValuePtr[i].bind(OGRE_NEW AnimationValue(this));
} }
Animation::~Animation() Animation::~Animation()
@ -114,7 +115,7 @@ void Animation::setObjectRoot(Ogre::SceneNode *node, const std::string &model, b
for(size_t i = 0;i < mObjectRoot.mControllers.size();i++) for(size_t i = 0;i < mObjectRoot.mControllers.size();i++)
{ {
if(mObjectRoot.mControllers[i].getSource().isNull()) if(mObjectRoot.mControllers[i].getSource().isNull())
mObjectRoot.mControllers[i].setSource(mAnimationValuePtr); mObjectRoot.mControllers[i].setSource(mAnimationValuePtr[0]);
} }
} }
@ -143,6 +144,23 @@ void Animation::setRenderProperties(const NifOgre::ObjectList &objlist, Ogre::ui
} }
size_t Animation::detectAnimGroup(const Ogre::Node *node)
{
while(node)
{
#if 0
const Ogre::String &name = node->getName();
if(name == "Bip01 L Clavicle")
return 2;
if(name == "Bip01 Spine1")
return 1;
#endif
node = node->getParent();
}
return 0;
}
void Animation::addAnimSource(const std::string &model) void Animation::addAnimSource(const std::string &model)
{ {
OgreAssert(mInsert, "Object is missing a root!"); OgreAssert(mInsert, "Object is missing a root!");
@ -164,30 +182,32 @@ void Animation::addAnimSource(const std::string &model)
if(!Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(kfname)) if(!Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(kfname))
return; return;
std::vector<Ogre::Controller<Ogre::Real> > ctrls;
mAnimSources.push_back(AnimSource()); mAnimSources.push_back(AnimSource());
NifOgre::Loader::createKfControllers(mSkelBase, kfname, NifOgre::Loader::createKfControllers(mSkelBase, kfname, mAnimSources.back().mTextKeys, ctrls);
mAnimSources.back().mTextKeys, if(mAnimSources.back().mTextKeys.size() == 0 || ctrls.size() == 0)
mAnimSources.back().mControllers);
if(mAnimSources.back().mTextKeys.size() == 0 || mAnimSources.back().mControllers.size() == 0)
{ {
mAnimSources.pop_back(); mAnimSources.pop_back();
return; return;
} }
std::vector<Ogre::Controller<Ogre::Real> > &ctrls = mAnimSources.back().mControllers; std::vector<Ogre::Controller<Ogre::Real> > *grpctrls = mAnimSources.back().mControllers;
NifOgre::NodeTargetValue<Ogre::Real> *dstval; NifOgre::NodeTargetValue<Ogre::Real> *dstval;
for(size_t i = 0;i < ctrls.size();i++) for(size_t i = 0;i < ctrls.size();i++)
{ {
dstval = static_cast<NifOgre::NodeTargetValue<Ogre::Real>*>(ctrls[i].getDestination().getPointer()); dstval = static_cast<NifOgre::NodeTargetValue<Ogre::Real>*>(ctrls[i].getDestination().getPointer());
if(i == 0 && !mAccumRoot) size_t grp = detectAnimGroup(dstval->getNode());
if(!mAccumRoot && grp == 0)
{ {
mAccumRoot = mInsert; mAccumRoot = mInsert;
mNonAccumRoot = dstval->getNode(); mNonAccumRoot = dstval->getNode();
} }
ctrls[i].setSource(mAnimationValuePtr); ctrls[i].setSource(mAnimationValuePtr[grp]);
grpctrls[grp].push_back(ctrls[i]);
} }
} }
@ -195,7 +215,8 @@ void Animation::clearAnimSources()
{ {
mStates.clear(); mStates.clear();
mAnimationName.empty(); for(size_t i = 0;i < sNumGroups;i++)
mAnimationValuePtr[i]->setAnimName(std::string());
mNonAccumCtrl = NULL; mNonAccumCtrl = NULL;
mAnimVelocity = 0.0f; mAnimVelocity = 0.0f;
@ -485,10 +506,10 @@ bool Animation::play(const std::string &groupname, const std::string &start, con
NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl = NULL; NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl = NULL;
if(mNonAccumRoot) if(mNonAccumRoot)
{ {
for(size_t i = 0;i < iter->mControllers.size();i++) for(size_t i = 0;i < iter->mControllers[0].size();i++)
{ {
NifOgre::NodeTargetValue<Ogre::Real> *dstval; NifOgre::NodeTargetValue<Ogre::Real> *dstval;
dstval = dynamic_cast<NifOgre::NodeTargetValue<Ogre::Real>*>(iter->mControllers[i].getDestination().getPointer()); dstval = dynamic_cast<NifOgre::NodeTargetValue<Ogre::Real>*>(iter->mControllers[0][i].getDestination().getPointer());
if(dstval && dstval->getNode() == mNonAccumRoot) if(dstval && dstval->getNode() == mNonAccumRoot)
{ {
nonaccumctrl = dstval; nonaccumctrl = dstval;
@ -510,7 +531,7 @@ bool Animation::play(const std::string &groupname, const std::string &start, con
mStates[groupname] = state; mStates[groupname] = state;
// FIXME // FIXME
mAnimationName = groupname; mAnimationValuePtr[0]->setAnimName(groupname);
mNonAccumCtrl = nonaccumctrl; mNonAccumCtrl = nonaccumctrl;
mAnimVelocity = 0.0f; mAnimVelocity = 0.0f;
@ -590,11 +611,17 @@ Ogre::Vector3 Animation::runAnimation(float duration)
for(size_t i = 0;i < mObjectRoot.mControllers.size();i++) for(size_t i = 0;i < mObjectRoot.mControllers.size();i++)
mObjectRoot.mControllers[i].update(); mObjectRoot.mControllers[i].update();
if(!mAnimationName.empty() && (stateiter=mStates.find(mAnimationName)) != mStates.end())
// Apply group controllers
for(size_t grp = 0;grp < sNumGroups;grp++)
{ {
AnimSource *src = stateiter->second.mSource; const std::string &name = mAnimationValuePtr[grp]->getAnimName();
for(size_t i = 0;i < src->mControllers.size();i++) if(!name.empty() && (stateiter=mStates.find(name)) != mStates.end())
src->mControllers[i].update(); {
AnimSource *src = stateiter->second.mSource;
for(size_t i = 0;i < src->mControllers[grp].size();i++)
src->mControllers[grp][i].update();
}
} }
if(mSkelBase) if(mSkelBase)

View file

@ -15,23 +15,31 @@ namespace MWRender
class Animation class Animation
{ {
protected: protected:
static const size_t sNumGroups = 1;
class AnimationValue : public Ogre::ControllerValue<Ogre::Real> class AnimationValue : public Ogre::ControllerValue<Ogre::Real>
{ {
private: private:
Animation *mAnimation; Animation *mAnimation;
std::string mAnimationName;
public: public:
AnimationValue(Animation *anim) AnimationValue(Animation *anim)
: mAnimation(anim) : mAnimation(anim)
{ } { }
void setAnimName(const std::string &name)
{ mAnimationName = name; }
const std::string &getAnimName() const
{ return mAnimationName; }
virtual Ogre::Real getValue() const; virtual Ogre::Real getValue() const;
virtual void setValue(Ogre::Real value); virtual void setValue(Ogre::Real value);
}; };
struct AnimSource { struct AnimSource {
NifOgre::TextKeyMap mTextKeys; NifOgre::TextKeyMap mTextKeys;
std::vector<Ogre::Controller<Ogre::Real> > mControllers; std::vector<Ogre::Controller<Ogre::Real> > mControllers[sNumGroups];
}; };
typedef std::vector<AnimSource> AnimSourceList; typedef std::vector<AnimSource> AnimSourceList;
@ -69,9 +77,9 @@ protected:
AnimStateMap mStates; AnimStateMap mStates;
// Note: One per animation group (lower body, upper body, left arm, etc). Ogre::SharedPtr<AnimationValue> mAnimationValuePtr[sNumGroups];
std::string mAnimationName;
Ogre::SharedPtr<AnimationValue> mAnimationValuePtr; static size_t detectAnimGroup(const Ogre::Node *node);
static float calcAnimVelocity(const NifOgre::TextKeyMap &keys, static float calcAnimVelocity(const NifOgre::TextKeyMap &keys,
NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl, NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl,