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

Keep track of the animation layers a given object list is animating on

This only tracks layers they explicitly animate on. They may animate on other
layers as well, if nothing else is animating on them.
This commit is contained in:
Chris Robinson 2013-04-23 02:48:11 -07:00
parent e378176937
commit e4c5aac966
4 changed files with 58 additions and 20 deletions

View file

@ -22,7 +22,7 @@ ActivatorAnimation::ActivatorAnimation(const MWWorld::Ptr &ptr)
const std::string name = "meshes\\"+ref->mBase->mModel;
addObjectList(mPtr.getRefData().getBaseNode(), name, false);
setRenderProperties(mObjectLists.back(), RV_Misc, RQG_Main, RQG_Alpha);
setRenderProperties(mObjects.back().mObjectList, RV_Misc, RQG_Main, RQG_Alpha);
}
}

View file

@ -78,9 +78,9 @@ Animation::~Animation()
if(mInsert)
{
Ogre::SceneManager *sceneMgr = mInsert->getCreator();
for(size_t i = 0;i < mObjectLists.size();i++)
destroyObjectList(sceneMgr, mObjectLists[i]);
mObjectLists.clear();
for(size_t i = 0;i < mObjects.size();i++)
destroyObjectList(sceneMgr, mObjects[i].mObjectList);
mObjects.clear();
}
}
@ -93,9 +93,13 @@ void Animation::addObjectList(Ogre::SceneNode *node, const std::string &model, b
assert(mInsert);
}
mObjectLists.push_back(!baseonly ? NifOgre::Loader::createObjects(mInsert, model) :
NifOgre::Loader::createObjectBase(mInsert, model));
NifOgre::ObjectList &objlist = mObjectLists.back();
mObjects.push_back(ObjectInfo());
ObjectInfo &obj = mObjects.back();
obj.mActiveLayers = 0;
obj.mObjectList = (!baseonly ? NifOgre::Loader::createObjects(mInsert, model) :
NifOgre::Loader::createObjectBase(mInsert, model));
NifOgre::ObjectList &objlist = obj.mObjectList;
if(objlist.mSkelBase)
{
if(!mSkelBase)
@ -202,12 +206,12 @@ NifOgre::TextKeyMap::const_iterator Animation::findGroupStart(const NifOgre::Tex
bool Animation::hasAnimation(const std::string &anim)
{
for(std::vector<NifOgre::ObjectList>::const_iterator iter(mObjectLists.begin());iter != mObjectLists.end();iter++)
for(std::vector<ObjectInfo>::const_iterator iter(mObjects.begin());iter != mObjects.end();iter++)
{
if(iter->mTextKeys.size() == 0)
if(iter->mObjectList.mTextKeys.size() == 0)
continue;
const NifOgre::TextKeyMap &keys = iter->mTextKeys.begin()->second;
const NifOgre::TextKeyMap &keys = iter->mObjectList.mTextKeys.begin()->second;
if(findGroupStart(keys, anim) != keys.end())
return true;
}
@ -430,21 +434,45 @@ void Animation::play(const std::string &groupname, const std::string &start, con
size_t layeridx = 0;
try {
for(std::vector<ObjectInfo>::iterator iter(mObjects.begin());iter != mObjects.end();iter++)
iter->mActiveLayers &= ~(1<<layeridx);
if(groupname.empty())
{
// Do not allow layer 0 to be disabled
assert(layeridx != 0);
mLayer[layeridx].mGroupName.clear();
mLayer[layeridx].mTextKeys = NULL;
mLayer[layeridx].mControllers = NULL;
mLayer[layeridx].mLooping = false;
mLayer[layeridx].mPlaying = false;
if(layeridx == 0)
{
mNonAccumCtrl = NULL;
mAnimVelocity = 0.0f;
}
return;
}
bool foundanim = false;
/* Look in reverse; last-inserted source has priority. */
for(std::vector<NifOgre::ObjectList>::reverse_iterator iter(mObjectLists.rbegin());iter != mObjectLists.rend();iter++)
for(std::vector<ObjectInfo>::reverse_iterator iter(mObjects.rbegin());iter != mObjects.rend();iter++)
{
if(iter->mTextKeys.size() == 0)
NifOgre::ObjectList &objlist = iter->mObjectList;
if(objlist.mTextKeys.size() == 0)
continue;
const NifOgre::TextKeyMap &keys = iter->mTextKeys.begin()->second;
const NifOgre::TextKeyMap &keys = objlist.mTextKeys.begin()->second;
NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl = NULL;
if(layeridx == 0)
{
for(size_t i = 0;i < iter->mControllers.size();i++)
for(size_t i = 0;i < objlist.mControllers.size();i++)
{
NifOgre::NodeTargetValue<Ogre::Real> *dstval;
dstval = dynamic_cast<NifOgre::NodeTargetValue<Ogre::Real>*>(iter->mControllers[i].getDestination().getPointer());
dstval = dynamic_cast<NifOgre::NodeTargetValue<Ogre::Real>*>(objlist.mControllers[i].getDestination().getPointer());
if(dstval && dstval->getNode() == mNonAccumRoot)
{
nonaccumctrl = dstval;
@ -459,7 +487,7 @@ void Animation::play(const std::string &groupname, const std::string &start, con
continue;
mLayer[layeridx].mGroupName = groupname;
mLayer[layeridx].mTextKeys = &keys;
mLayer[layeridx].mControllers = &iter->mControllers;
mLayer[layeridx].mControllers = &objlist.mControllers;
mLayer[layeridx].mLooping = loop;
mLayer[layeridx].mPlaying = true;
@ -469,6 +497,7 @@ void Animation::play(const std::string &groupname, const std::string &start, con
mAnimVelocity = 0.0f;
}
iter->mActiveLayers |= (1<<layeridx);
foundanim = true;
}
@ -541,9 +570,9 @@ Ogre::Vector3 Animation::runAnimation(float duration)
if(mSkelBase)
{
const Ogre::SkeletonInstance *baseinst = mSkelBase->getSkeleton();
for(std::vector<NifOgre::ObjectList>::iterator iter(mObjectLists.begin());iter != mObjectLists.end();iter++)
for(std::vector<ObjectInfo>::iterator iter(mObjects.begin());iter != mObjects.end();iter++)
{
Ogre::Entity *ent = iter->mSkelBase;
Ogre::Entity *ent = iter->mObjectList.mSkelBase;
if(!ent) continue;
Ogre::SkeletonInstance *inst = ent->getSkeleton();

View file

@ -38,9 +38,18 @@ protected:
MWWorld::Ptr mPtr;
MWMechanics::CharacterController *mController;
struct ObjectInfo {
NifOgre::ObjectList mObjectList;
/* Bit-field specifying which animation layers this object list is
* explicitly animating on (1 = layer 0, 2 = layer 1, 4 = layer 2.
* etc).
*/
int mActiveLayers;
};
Ogre::SceneNode *mInsert;
Ogre::Entity *mSkelBase;
std::vector<NifOgre::ObjectList> mObjectLists;
std::vector<ObjectInfo> mObjects;
Ogre::Node *mAccumRoot;
Ogre::Bone *mNonAccumRoot;
Ogre::Vector3 mAccumulate;

View file

@ -25,7 +25,7 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr &ptr)
addObjectList(mPtr.getRefData().getBaseNode(), "meshes\\base_anim.nif", true);
addObjectList(mPtr.getRefData().getBaseNode(), model, false);
setRenderProperties(mObjectLists.back(), RV_Actors, RQG_Main, RQG_Alpha);
setRenderProperties(mObjects.back().mObjectList, RV_Actors, RQG_Main, RQG_Alpha);
}
}