mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-25 06:35:30 +00:00
Use an unconnected object list for animation sources
We'll want the controllers, as the plan is to use their keyframe controllers to animate the actual skeleton used for the meshes.
This commit is contained in:
parent
80a1abd48a
commit
2362e920f3
@ -16,6 +16,19 @@
|
||||
namespace MWRender
|
||||
{
|
||||
|
||||
void Animation::destroyObjectList(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objects)
|
||||
{
|
||||
for(size_t i = 0;i < objects.mParticles.size();i++)
|
||||
sceneMgr->destroyParticleSystem(objects.mParticles[i]);
|
||||
for(size_t i = 0;i < objects.mEntities.size();i++)
|
||||
sceneMgr->destroyEntity(objects.mEntities[i]);
|
||||
objects.mControllers.clear();
|
||||
objects.mCameras.clear();
|
||||
objects.mParticles.clear();
|
||||
objects.mEntities.clear();
|
||||
objects.mSkelBase = NULL;
|
||||
}
|
||||
|
||||
Animation::Animation(const MWWorld::Ptr &ptr)
|
||||
: mPtr(ptr)
|
||||
, mController(NULL)
|
||||
@ -40,16 +53,12 @@ Animation::~Animation()
|
||||
if(mInsert)
|
||||
{
|
||||
Ogre::SceneManager *sceneMgr = mInsert->getCreator();
|
||||
for(size_t i = 0;i < mObjectList.mParticles.size();i++)
|
||||
sceneMgr->destroyParticleSystem(mObjectList.mParticles[i]);
|
||||
for(size_t i = 0;i < mObjectList.mEntities.size();i++)
|
||||
sceneMgr->destroyEntity(mObjectList.mEntities[i]);
|
||||
destroyObjectList(sceneMgr, mObjectList);
|
||||
|
||||
for(size_t i = 0;i < mAnimationSources.size();i++)
|
||||
destroyObjectList(sceneMgr, mAnimationSources[i]);
|
||||
mAnimationSources.clear();
|
||||
}
|
||||
mObjectList.mControllers.clear();
|
||||
mObjectList.mCameras.clear();
|
||||
mObjectList.mParticles.clear();
|
||||
mObjectList.mEntities.clear();
|
||||
mObjectList.mSkelBase = NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -57,6 +66,7 @@ void Animation::setAnimationSources(const std::vector<std::string> &names)
|
||||
{
|
||||
if(!mObjectList.mSkelBase)
|
||||
return;
|
||||
Ogre::SceneManager *sceneMgr = mInsert->getCreator();
|
||||
|
||||
mCurrentAnim = NULL;
|
||||
mCurrentKeys = NULL;
|
||||
@ -64,19 +74,24 @@ void Animation::setAnimationSources(const std::vector<std::string> &names)
|
||||
mAccumRoot = NULL;
|
||||
mNonAccumRoot = NULL;
|
||||
mTextKeys.clear();
|
||||
mSkeletonSources.clear();
|
||||
for(size_t i = 0;i < mAnimationSources.size();i++)
|
||||
destroyObjectList(sceneMgr, mAnimationSources[i]);
|
||||
mAnimationSources.clear();
|
||||
|
||||
std::vector<std::string>::const_iterator nameiter;
|
||||
for(nameiter = names.begin();nameiter != names.end();nameiter++)
|
||||
{
|
||||
Ogre::SkeletonPtr skel = NifOgre::Loader::getSkeleton(*nameiter);
|
||||
if(skel.isNull())
|
||||
mAnimationSources.push_back(NifOgre::Loader::createObjectBase(sceneMgr, *nameiter));
|
||||
if(!mAnimationSources.back().mSkelBase)
|
||||
{
|
||||
std::cerr<< "Failed to get skeleton source "<<*nameiter <<std::endl;
|
||||
destroyObjectList(sceneMgr, mAnimationSources.back());
|
||||
mAnimationSources.pop_back();
|
||||
continue;
|
||||
}
|
||||
skel->touch();
|
||||
|
||||
Ogre::Entity *ent = mAnimationSources.back().mSkelBase;
|
||||
Ogre::SkeletonPtr skel = Ogre::SkeletonManager::getSingleton().getByName(ent->getSkeleton()->getName());
|
||||
Ogre::Skeleton::BoneIterator boneiter = skel->getBoneIterator();
|
||||
while(boneiter.hasMoreElements())
|
||||
{
|
||||
@ -92,7 +107,6 @@ void Animation::setAnimationSources(const std::vector<std::string> &names)
|
||||
mNonAccumRoot = mObjectList.mSkelBase->getSkeleton()->getBone(bone->getName());
|
||||
}
|
||||
|
||||
mSkeletonSources.push_back(skel);
|
||||
for(int i = 0;i < skel->getNumAnimations();i++)
|
||||
{
|
||||
Ogre::Animation *anim = skel->getAnimation(i);
|
||||
@ -144,9 +158,9 @@ void Animation::createObjectList(Ogre::SceneNode *node, const std::string &model
|
||||
|
||||
bool Animation::hasAnimation(const std::string &anim)
|
||||
{
|
||||
for(std::vector<Ogre::SkeletonPtr>::const_iterator iter(mSkeletonSources.begin());iter != mSkeletonSources.end();iter++)
|
||||
for(std::vector<NifOgre::ObjectList>::const_iterator iter(mAnimationSources.begin());iter != mAnimationSources.end();iter++)
|
||||
{
|
||||
if((*iter)->hasAnimation(anim))
|
||||
if(iter->mSkelBase->hasAnimationState(anim))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -413,11 +427,11 @@ 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<Ogre::SkeletonPtr>::const_reverse_iterator iter(mSkeletonSources.rbegin());iter != mSkeletonSources.rend();iter++)
|
||||
for(std::vector<NifOgre::ObjectList>::const_reverse_iterator iter(mAnimationSources.rbegin());iter != mAnimationSources.rend();iter++)
|
||||
{
|
||||
if((*iter)->hasAnimation(groupname))
|
||||
if(iter->mSkelBase->hasAnimationState(groupname))
|
||||
{
|
||||
mCurrentAnim = (*iter)->getAnimation(groupname);
|
||||
mCurrentAnim = iter->mSkelBase->getSkeleton()->getAnimation(groupname);
|
||||
mCurrentKeys = &mTextKeys[groupname];
|
||||
mAnimVelocity = 0.0f;
|
||||
|
||||
|
@ -47,7 +47,7 @@ protected:
|
||||
Ogre::Vector3 mAccumulate;
|
||||
Ogre::Vector3 mLastPosition;
|
||||
|
||||
std::vector<Ogre::SkeletonPtr> mSkeletonSources;
|
||||
std::vector<NifOgre::ObjectList> mAnimationSources;
|
||||
|
||||
NifOgre::TextKeyMap *mCurrentKeys;
|
||||
NifOgre::TextKeyMap::const_iterator mNextKey;
|
||||
@ -92,6 +92,7 @@ protected:
|
||||
}
|
||||
|
||||
void createObjectList(Ogre::SceneNode *node, const std::string &model);
|
||||
static void destroyObjectList(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objects);
|
||||
|
||||
public:
|
||||
Animation(const MWWorld::Ptr &ptr);
|
||||
|
@ -1768,35 +1768,14 @@ ObjectList Loader::createObjects(Ogre::Entity *parent, const std::string &bonena
|
||||
}
|
||||
|
||||
|
||||
Ogre::SkeletonPtr Loader::getSkeleton(std::string name, const std::string &group)
|
||||
ObjectList Loader::createObjectBase(Ogre::SceneManager *sceneMgr, std::string name, const std::string &group)
|
||||
{
|
||||
Ogre::SkeletonPtr skel;
|
||||
ObjectList objectlist;
|
||||
|
||||
Misc::StringUtils::toLower(name);
|
||||
skel = Ogre::SkeletonManager::getSingleton().getByName(name);
|
||||
if(!skel.isNull())
|
||||
return skel;
|
||||
NIFObjectLoader::load(sceneMgr, objectlist, name, group);
|
||||
|
||||
Nif::NIFFile::ptr nif = Nif::NIFFile::create(name);
|
||||
if(nif->numRoots() < 1)
|
||||
{
|
||||
nif->warn("Found no root nodes in "+name+".");
|
||||
return skel;
|
||||
}
|
||||
|
||||
// The first record is assumed to be the root node
|
||||
const Nif::Record *r = nif->getRoot(0);
|
||||
assert(r != NULL);
|
||||
|
||||
const Nif::Node *node = dynamic_cast<const Nif::Node*>(r);
|
||||
if(node == NULL)
|
||||
{
|
||||
nif->warn("First record in "+name+" was not a node, but a "+
|
||||
r->recName+".");
|
||||
return skel;
|
||||
}
|
||||
|
||||
return NIFSkeletonLoader::createSkeleton(name, group, node);
|
||||
return objectlist;
|
||||
}
|
||||
|
||||
} // namespace NifOgre
|
||||
|
@ -69,7 +69,9 @@ public:
|
||||
std::string name,
|
||||
const std::string &group="General");
|
||||
|
||||
static Ogre::SkeletonPtr getSkeleton(std::string name, const std::string &group="General");
|
||||
static ObjectList createObjectBase(Ogre::SceneManager *sceneMgr,
|
||||
std::string name,
|
||||
const std::string &group="General");
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user