mirror of
https://github.com/OpenMW/openmw.git
synced 2025-06-02 13:11:33 +00:00
Crash fix for creatures with no skeleton base (Fixes #2419)
This commit is contained in:
parent
0ad514b29b
commit
191c0104f6
3 changed files with 37 additions and 20 deletions
|
@ -1271,7 +1271,11 @@ void Animation::addEffect(const std::string &model, int effectId, bool loop, con
|
||||||
if (bonename.empty())
|
if (bonename.empty())
|
||||||
params.mObjects = NifOgre::Loader::createObjects(mInsert, model);
|
params.mObjects = NifOgre::Loader::createObjects(mInsert, model);
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (!mSkelBase)
|
||||||
|
return;
|
||||||
params.mObjects = NifOgre::Loader::createObjects(mSkelBase, bonename, "", mInsert, model);
|
params.mObjects = NifOgre::Loader::createObjects(mSkelBase, bonename, "", mInsert, model);
|
||||||
|
}
|
||||||
|
|
||||||
setRenderProperties(params.mObjects, RV_Effects,
|
setRenderProperties(params.mObjects, RV_Effects,
|
||||||
RQG_Main, RQG_Alpha, 0.f, false, NULL);
|
RQG_Main, RQG_Alpha, 0.f, false, NULL);
|
||||||
|
|
|
@ -88,6 +88,9 @@ void CreatureWeaponAnimation::updateParts()
|
||||||
|
|
||||||
void CreatureWeaponAnimation::updatePart(NifOgre::ObjectScenePtr& scene, int slot)
|
void CreatureWeaponAnimation::updatePart(NifOgre::ObjectScenePtr& scene, int slot)
|
||||||
{
|
{
|
||||||
|
if (!mSkelBase)
|
||||||
|
return;
|
||||||
|
|
||||||
MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr);
|
MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr);
|
||||||
MWWorld::ContainerStoreIterator it = inv.getSlot(slot);
|
MWWorld::ContainerStoreIterator it = inv.getSlot(slot);
|
||||||
|
|
||||||
|
@ -181,7 +184,9 @@ void CreatureWeaponAnimation::releaseArrow()
|
||||||
Ogre::Vector3 CreatureWeaponAnimation::runAnimation(float duration)
|
Ogre::Vector3 CreatureWeaponAnimation::runAnimation(float duration)
|
||||||
{
|
{
|
||||||
Ogre::Vector3 ret = Animation::runAnimation(duration);
|
Ogre::Vector3 ret = Animation::runAnimation(duration);
|
||||||
pitchSkeleton(mPtr.getRefData().getPosition().rot[0], mSkelBase->getSkeleton());
|
|
||||||
|
if (mSkelBase)
|
||||||
|
pitchSkeleton(mPtr.getRefData().getPosition().rot[0], mSkelBase->getSkeleton());
|
||||||
|
|
||||||
if (!mWeapon.isNull())
|
if (!mWeapon.isNull())
|
||||||
{
|
{
|
||||||
|
|
|
@ -335,7 +335,10 @@ void NpcAnimation::updateNpcBase()
|
||||||
}
|
}
|
||||||
|
|
||||||
void NpcAnimation::updateParts()
|
void NpcAnimation::updateParts()
|
||||||
{
|
{
|
||||||
|
if (!mSkelBase)
|
||||||
|
return;
|
||||||
|
|
||||||
mAlpha = 1.f;
|
mAlpha = 1.f;
|
||||||
const MWWorld::Class &cls = mPtr.getClass();
|
const MWWorld::Class &cls = mPtr.getClass();
|
||||||
|
|
||||||
|
@ -621,30 +624,33 @@ NifOgre::ObjectScenePtr NpcAnimation::insertBoundedPart(const std::string &model
|
||||||
}
|
}
|
||||||
|
|
||||||
Ogre::Vector3 NpcAnimation::runAnimation(float timepassed)
|
Ogre::Vector3 NpcAnimation::runAnimation(float timepassed)
|
||||||
{
|
{
|
||||||
Ogre::Vector3 ret = Animation::runAnimation(timepassed);
|
Ogre::Vector3 ret = Animation::runAnimation(timepassed);
|
||||||
|
|
||||||
mHeadAnimationTime->update(timepassed);
|
mHeadAnimationTime->update(timepassed);
|
||||||
|
|
||||||
Ogre::SkeletonInstance *baseinst = mSkelBase->getSkeleton();
|
if (mSkelBase)
|
||||||
if(mViewMode == VM_FirstPerson)
|
|
||||||
{
|
{
|
||||||
float pitch = mPtr.getRefData().getPosition().rot[0];
|
Ogre::SkeletonInstance *baseinst = mSkelBase->getSkeleton();
|
||||||
Ogre::Node *node = baseinst->getBone("Bip01 Neck");
|
if(mViewMode == VM_FirstPerson)
|
||||||
node->pitch(Ogre::Radian(-pitch), Ogre::Node::TS_WORLD);
|
{
|
||||||
|
float pitch = mPtr.getRefData().getPosition().rot[0];
|
||||||
|
Ogre::Node *node = baseinst->getBone("Bip01 Neck");
|
||||||
|
node->pitch(Ogre::Radian(-pitch), Ogre::Node::TS_WORLD);
|
||||||
|
|
||||||
// This has to be done before this function ends;
|
// This has to be done before this function ends;
|
||||||
// updateSkeletonInstance, below, touches the hands.
|
// updateSkeletonInstance, below, touches the hands.
|
||||||
node->translate(mFirstPersonOffset, Ogre::Node::TS_WORLD);
|
node->translate(mFirstPersonOffset, Ogre::Node::TS_WORLD);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// In third person mode we may still need pitch for ranged weapon targeting
|
// In third person mode we may still need pitch for ranged weapon targeting
|
||||||
pitchSkeleton(mPtr.getRefData().getPosition().rot[0], baseinst);
|
pitchSkeleton(mPtr.getRefData().getPosition().rot[0], baseinst);
|
||||||
|
|
||||||
Ogre::Node* node = baseinst->getBone("Bip01 Head");
|
Ogre::Node* node = baseinst->getBone("Bip01 Head");
|
||||||
if (node)
|
if (node)
|
||||||
node->rotate(Ogre::Quaternion(mHeadYaw, Ogre::Vector3::UNIT_Z) * Ogre::Quaternion(mHeadPitch, Ogre::Vector3::UNIT_X), Ogre::Node::TS_WORLD);
|
node->rotate(Ogre::Quaternion(mHeadYaw, Ogre::Vector3::UNIT_Z) * Ogre::Quaternion(mHeadPitch, Ogre::Vector3::UNIT_X), Ogre::Node::TS_WORLD);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mFirstPersonOffset = 0.f; // reset the X, Y, Z offset for the next frame.
|
mFirstPersonOffset = 0.f; // reset the X, Y, Z offset for the next frame.
|
||||||
|
|
||||||
|
@ -659,7 +665,9 @@ Ogre::Vector3 NpcAnimation::runAnimation(float timepassed)
|
||||||
if (!isSkinned(mObjectParts[i]))
|
if (!isSkinned(mObjectParts[i]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
updateSkeletonInstance(baseinst, mObjectParts[i]->mSkelBase->getSkeleton());
|
if (mSkelBase)
|
||||||
|
updateSkeletonInstance(mSkelBase->getSkeleton(), mObjectParts[i]->mSkelBase->getSkeleton());
|
||||||
|
|
||||||
mObjectParts[i]->mSkelBase->getAllAnimationStates()->_notifyDirty();
|
mObjectParts[i]->mSkelBase->getAllAnimationStates()->_notifyDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue