From 2362e920f309b272994cd1763f7e668fc7033de8 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 7 Apr 2013 12:41:27 -0700 Subject: [PATCH] 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. --- apps/openmw/mwrender/animation.cpp | 52 ++++++++++++++++++---------- apps/openmw/mwrender/animation.hpp | 3 +- components/nifogre/ogrenifloader.cpp | 29 +++------------- components/nifogre/ogrenifloader.hpp | 4 ++- 4 files changed, 42 insertions(+), 46 deletions(-) diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 8ecebc707..686fbbb84 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -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 &names) { if(!mObjectList.mSkelBase) return; + Ogre::SceneManager *sceneMgr = mInsert->getCreator(); mCurrentAnim = NULL; mCurrentKeys = NULL; @@ -64,19 +74,24 @@ void Animation::setAnimationSources(const std::vector &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::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 <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 &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::const_iterator iter(mSkeletonSources.begin());iter != mSkeletonSources.end();iter++) + for(std::vector::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::const_reverse_iterator iter(mSkeletonSources.rbegin());iter != mSkeletonSources.rend();iter++) + for(std::vector::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; diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 55aaca427..22ab9fc7e 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -47,7 +47,7 @@ protected: Ogre::Vector3 mAccumulate; Ogre::Vector3 mLastPosition; - std::vector mSkeletonSources; + std::vector 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); diff --git a/components/nifogre/ogrenifloader.cpp b/components/nifogre/ogrenifloader.cpp index 90139c9f0..d3da77e41 100644 --- a/components/nifogre/ogrenifloader.cpp +++ b/components/nifogre/ogrenifloader.cpp @@ -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(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 diff --git a/components/nifogre/ogrenifloader.hpp b/components/nifogre/ogrenifloader.hpp index 88cbaf691..3a7a22f8b 100644 --- a/components/nifogre/ogrenifloader.hpp +++ b/components/nifogre/ogrenifloader.hpp @@ -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"); }; }