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:
parent
f841576bba
commit
b8f5813609
5 changed files with 70 additions and 63 deletions
|
@ -51,6 +51,7 @@ ActivatorAnimation::ActivatorAnimation(const MWWorld::Ptr &ptr)
|
|||
ent->setVisibilityFlags(RV_Misc);
|
||||
ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
|
||||
}
|
||||
setAnimationSource(mesh);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue