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:
parent
e378176937
commit
e4c5aac966
4 changed files with 58 additions and 20 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue