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.
actorid
Chris Robinson 12 years ago
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;
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);
NIFObjectLoader::load(sceneMgr, objectlist, name, group);
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…
Cancel
Save