1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-01 16:45:35 +00:00

Set all animation sources at once

This commit is contained in:
Chris Robinson 2013-02-23 03:34:03 -08:00
parent f841576bba
commit b8f5813609
5 changed files with 70 additions and 63 deletions

View file

@ -51,6 +51,7 @@ ActivatorAnimation::ActivatorAnimation(const MWWorld::Ptr &ptr)
ent->setVisibilityFlags(RV_Misc);
ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
}
setAnimationSource(mesh);
}
}

View file

@ -46,45 +46,64 @@ Animation::~Animation()
}
Ogre::Bone *Animation::insertSkeletonSource(const std::string &name)
void Animation::setAnimationSources(const std::vector<std::string> &names)
{
Ogre::SkeletonManager &skelMgr = Ogre::SkeletonManager::getSingleton();
Ogre::SkeletonPtr skel = skelMgr.getByName(name);
if(skel.isNull())
mCurrentAnim = NULL;
mCurrentKeys = NULL;
mAnimVelocity = 0.0f;
mAccumRoot = NULL;
mNonAccumRoot = NULL;
mSkeletonSources.clear();
std::vector<std::string>::const_iterator nameiter = names.begin();
while(nameiter != names.end())
{
NifOgre::Loader::createSkeleton(name);
skel = skelMgr.getByName(name);
Ogre::SkeletonPtr skel = skelMgr.getByName(*nameiter);
if(skel.isNull())
{
std::cerr<< "Failed to get skeleton source "<<name <<std::endl;
return NULL;
NifOgre::Loader::createSkeleton(*nameiter);
skel = skelMgr.getByName(*nameiter);
if(skel.isNull())
{
std::cerr<< "Failed to get skeleton source "<<*nameiter <<std::endl;
nameiter++;
continue;
}
}
}
skel->touch();
mSkeletonSources.push_back(skel);
skel->touch();
Ogre::Skeleton::BoneIterator boneiter = skel->getBoneIterator();
while(boneiter.hasMoreElements())
{
Ogre::Bone *bone = boneiter.getNext();
Ogre::UserObjectBindings &bindings = bone->getUserObjectBindings();
const Ogre::Any &data = bindings.getUserAny(NifOgre::sTextKeyExtraDataID);
if(data.isEmpty() || !Ogre::any_cast<bool>(data))
continue;
for(int i = 0;i < skel->getNumAnimations();i++)
Ogre::Skeleton::BoneIterator boneiter = skel->getBoneIterator();
while(boneiter.hasMoreElements())
{
Ogre::Animation *anim = skel->getAnimation(i);
const Ogre::Any &groupdata = bindings.getUserAny(std::string(NifOgre::sTextKeyExtraDataID)+
"@"+anim->getName());
if(!groupdata.isEmpty())
mTextKeys[anim->getName()] = Ogre::any_cast<NifOgre::TextKeyMap>(groupdata);
Ogre::Bone *bone = boneiter.getNext();
Ogre::UserObjectBindings &bindings = bone->getUserObjectBindings();
const Ogre::Any &data = bindings.getUserAny(NifOgre::sTextKeyExtraDataID);
if(data.isEmpty() || !Ogre::any_cast<bool>(data))
continue;
if(!mNonAccumRoot && mEntityList.mSkelBase)
{
mAccumRoot = mInsert;
mNonAccumRoot = mEntityList.mSkelBase->getSkeleton()->getBone(bone->getName());
}
mSkeletonSources.push_back(skel);
for(int i = 0;i < skel->getNumAnimations();i++)
{
Ogre::Animation *anim = skel->getAnimation(i);
const Ogre::Any &groupdata = bindings.getUserAny(std::string(NifOgre::sTextKeyExtraDataID)+
"@"+anim->getName());
if(!groupdata.isEmpty())
mTextKeys[anim->getName()] = Ogre::any_cast<NifOgre::TextKeyMap>(groupdata);
}
break;
}
return bone;
nameiter++;
}
return NULL;
}
void Animation::createEntityList(Ogre::SceneNode *node, const std::string &model)
@ -111,31 +130,6 @@ void Animation::createEntityList(Ogre::SceneNode *node, const std::string &model
Ogre::Skeleton::BoneIterator boneiter = skelinst->getBoneIterator();
while(boneiter.hasMoreElements())
boneiter.getNext()->setManuallyControlled(true);
Ogre::Bone *bone = insertSkeletonSource(skelinst->getName());
if(!bone)
{
for(std::vector<Ogre::SkeletonPtr>::const_iterator iter(mSkeletonSources.begin());
!bone && iter != mSkeletonSources.end();iter++)
{
Ogre::Skeleton::BoneIterator boneiter = (*iter)->getBoneIterator();
while(boneiter.hasMoreElements())
{
bone = boneiter.getNext();
Ogre::UserObjectBindings &bindings = bone->getUserObjectBindings();
const Ogre::Any &data = bindings.getUserAny(NifOgre::sTextKeyExtraDataID);
if(!data.isEmpty() && Ogre::any_cast<bool>(data))
break;
bone = NULL;
}
}
}
if(bone)
{
mAccumRoot = mInsert;
mNonAccumRoot = skelinst->getBone(bone->getName());
}
}
}

View file

@ -57,9 +57,15 @@ protected:
* anything. If the marker is not found, it resets to the beginning. */
void reset(const std::string &marker);
/* Inserts an additional skeleton into the animation source chain. Returns
* the bone representing the non-accum root from the base skeleton. */
Ogre::Bone *insertSkeletonSource(const std::string &name);
/* Specifies a list of skeleton names to use as animation sources. */
void setAnimationSources(const std::vector<std::string> &names);
/* Specifies a single skeleton name to use as an animation source. */
void setAnimationSource(const std::string &name)
{
std::vector<std::string> names(1, name);
setAnimationSources(names);
}
void createEntityList(Ogre::SceneNode *node, const std::string &model);

View file

@ -23,10 +23,9 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr &ptr)
assert (ref->mBase != NULL);
if(!ref->mBase->mModel.empty())
{
if((ref->mBase->mFlags&ESM::Creature::Biped))
insertSkeletonSource("meshes\\base_anim.nif");
std::string model = "meshes\\"+ref->mBase->mModel;
createEntityList(mPtr.getRefData().getBaseNode(), "meshes\\"+ref->mBase->mModel);
createEntityList(mPtr.getRefData().getBaseNode(), model);
for(size_t i = 0;i < mEntityList.mEntities.size();i++)
{
Ogre::Entity *ent = mEntityList.mEntities[i];
@ -52,6 +51,12 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr &ptr)
}
ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
}
std::vector<std::string> names;
if((ref->mBase->mFlags&ESM::Creature::Biped))
names.push_back("meshes\\base_anim.nif");
names.push_back(model);
setAnimationSources(names);
}
}

View file

@ -125,13 +125,14 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor
base->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
}
std::vector<std::string> skelnames(1, smodel);
if(!mNpc->isMale() && !isBeast)
insertSkeletonSource("meshes\\base_anim_female.nif");
skelnames.push_back("meshes\\base_anim_female.nif");
else if(mBodyPrefix.find("argonian") != std::string::npos)
insertSkeletonSource("meshes\\argonian_swimkna.nif");
skelnames.push_back("meshes\\argonian_swimkna.nif");
if(mNpc->mModel.length() > 0)
insertSkeletonSource("meshes\\"+Misc::StringUtils::lowerCase(mNpc->mModel));
skelnames.push_back("meshes\\"+Misc::StringUtils::lowerCase(mNpc->mModel));
setAnimationSources(skelnames);
updateParts(true);
}