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:
parent
8a9b0eb5f7
commit
921f534980
2 changed files with 57 additions and 22 deletions
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue