mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-26 18:35:20 +00:00
Don't share skeleton instances between bounded parts on an NPC
However, a skeleton instance will still be shared between entities in an entity list.
This commit is contained in:
parent
5c3a7f7d52
commit
b6354c6282
@ -146,6 +146,21 @@ void Animation::applyAnimation(const Ogre::Animation *anim, float time, Ogre::Sk
|
|||||||
mEntityList.mSkelBase->getAllAnimationStates()->_notifyDirty();
|
mEntityList.mSkelBase->getAllAnimationStates()->_notifyDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Animation::updateSkeletonInstance(const Ogre::SkeletonInstance *skelsrc, Ogre::SkeletonInstance *skel)
|
||||||
|
{
|
||||||
|
Ogre::Skeleton::BoneIterator boneiter = skel->getBoneIterator();
|
||||||
|
while(boneiter.hasMoreElements())
|
||||||
|
{
|
||||||
|
Ogre::Bone *bone = boneiter.getNext();
|
||||||
|
if(!skelsrc->hasBone(bone->getName()))
|
||||||
|
continue;
|
||||||
|
Ogre::Bone *srcbone = skelsrc->getBone(bone->getName());
|
||||||
|
bone->setOrientation(srcbone->getOrientation());
|
||||||
|
bone->setPosition(srcbone->getPosition());
|
||||||
|
bone->setScale(srcbone->getScale());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Ogre::Vector3 Animation::updatePosition(float time)
|
Ogre::Vector3 Animation::updatePosition(float time)
|
||||||
{
|
{
|
||||||
|
@ -37,8 +37,13 @@ protected:
|
|||||||
|
|
||||||
float mAnimSpeedMult;
|
float mAnimSpeedMult;
|
||||||
|
|
||||||
|
/* Applies the given animation to the given skeleton instance, using the specified time. */
|
||||||
void applyAnimation(const Ogre::Animation *anim, float time, Ogre::SkeletonInstance *skel);
|
void applyAnimation(const Ogre::Animation *anim, float time, Ogre::SkeletonInstance *skel);
|
||||||
|
|
||||||
|
/* Updates a skeleton instance so that all bones matching the source skeleton (based on
|
||||||
|
* bone names) are positioned identically. */
|
||||||
|
void updateSkeletonInstance(const Ogre::SkeletonInstance *skelsrc, Ogre::SkeletonInstance *skel);
|
||||||
|
|
||||||
/* Updates the animation to the specified time, and returns the movement
|
/* Updates the animation to the specified time, and returns the movement
|
||||||
* vector since the last update or reset. */
|
* vector since the last update or reset. */
|
||||||
Ogre::Vector3 updatePosition(float time);
|
Ogre::Vector3 updatePosition(float time);
|
||||||
|
@ -305,6 +305,21 @@ NifOgre::EntityList NpcAnimation::insertBoundedPart(const std::string &mesh, int
|
|||||||
parts[i]->setVisibilityFlags(mVisibilityFlags);
|
parts[i]->setVisibilityFlags(mVisibilityFlags);
|
||||||
parts[i]->getUserObjectBindings().setUserAny(Ogre::Any(group));
|
parts[i]->getUserObjectBindings().setUserAny(Ogre::Any(group));
|
||||||
}
|
}
|
||||||
|
if(entities.mSkelBase)
|
||||||
|
{
|
||||||
|
Ogre::AnimationStateSet *aset = entities.mSkelBase->getAllAnimationStates();
|
||||||
|
Ogre::AnimationStateIterator asiter = aset->getAnimationStateIterator();
|
||||||
|
while(asiter.hasMoreElements())
|
||||||
|
{
|
||||||
|
Ogre::AnimationState *state = asiter.getNext();
|
||||||
|
state->setEnabled(false);
|
||||||
|
state->setLoop(false);
|
||||||
|
}
|
||||||
|
Ogre::SkeletonInstance *skelinst = entities.mSkelBase->getSkeleton();
|
||||||
|
Ogre::Skeleton::BoneIterator boneiter = skelinst->getBoneIterator();
|
||||||
|
while(boneiter.hasMoreElements())
|
||||||
|
boneiter.getNext()->setManuallyControlled(true);
|
||||||
|
}
|
||||||
return entities;
|
return entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,7 +332,16 @@ Ogre::Vector3 NpcAnimation::runAnimation(float timepassed)
|
|||||||
}
|
}
|
||||||
mTimeToChange += timepassed;
|
mTimeToChange += timepassed;
|
||||||
|
|
||||||
return Animation::runAnimation(timepassed);
|
Ogre::Vector3 ret = Animation::runAnimation(timepassed);
|
||||||
|
const Ogre::SkeletonInstance *skelsrc = mEntityList.mSkelBase->getSkeleton();
|
||||||
|
for(size_t i = 0;i < sPartListSize;i++)
|
||||||
|
{
|
||||||
|
Ogre::Entity *ent = (this->*sPartList[i].ents).mSkelBase;
|
||||||
|
if(!ent) continue;
|
||||||
|
updateSkeletonInstance(skelsrc, ent->getSkeleton());
|
||||||
|
ent->getAllAnimationStates()->_notifyDirty();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NpcAnimation::removeEntities(NifOgre::EntityList &entities)
|
void NpcAnimation::removeEntities(NifOgre::EntityList &entities)
|
||||||
|
@ -1228,19 +1228,18 @@ EntityList Loader::createEntities(Ogre::Entity *parent, const std::string &bonen
|
|||||||
|
|
||||||
if(entitylist.mSkelBase)
|
if(entitylist.mSkelBase)
|
||||||
{
|
{
|
||||||
entitylist.mSkelBase->shareSkeletonInstanceWith(parent);
|
|
||||||
parentNode->attachObject(entitylist.mSkelBase);
|
parentNode->attachObject(entitylist.mSkelBase);
|
||||||
for(size_t i = 0;i < entitylist.mEntities.size();i++)
|
for(size_t i = 0;i < entitylist.mEntities.size();i++)
|
||||||
{
|
{
|
||||||
Ogre::Entity *entity = entitylist.mEntities[i];
|
Ogre::Entity *entity = entitylist.mEntities[i];
|
||||||
if(entity != entitylist.mSkelBase && entity->hasSkeleton())
|
if(entity != entitylist.mSkelBase && entity->hasSkeleton())
|
||||||
{
|
{
|
||||||
entity->shareSkeletonInstanceWith(parent);
|
entity->shareSkeletonInstanceWith(entitylist.mSkelBase);
|
||||||
parentNode->attachObject(entity);
|
parentNode->attachObject(entity);
|
||||||
}
|
}
|
||||||
else if(entity != entitylist.mSkelBase)
|
else if(entity != entitylist.mSkelBase)
|
||||||
{
|
{
|
||||||
Ogre::TagPoint *tag = parent->attachObjectToBone(bonename, entity);
|
Ogre::TagPoint *tag = entitylist.mSkelBase->attachObjectToBone(bonename, entity);
|
||||||
tag->setScale(scale);
|
tag->setScale(scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user