mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 19:56:38 +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()) | ||||
|         params.mObjects = NifOgre::Loader::createObjects(mInsert, model); | ||||
|     else | ||||
|     { | ||||
|         if (!mSkelBase) | ||||
|             return; | ||||
|         params.mObjects = NifOgre::Loader::createObjects(mSkelBase, bonename, "", mInsert, model); | ||||
|     } | ||||
| 
 | ||||
|     setRenderProperties(params.mObjects, RV_Effects, | ||||
|                         RQG_Main, RQG_Alpha, 0.f, false, NULL); | ||||
|  |  | |||
|  | @ -88,6 +88,9 @@ void CreatureWeaponAnimation::updateParts() | |||
| 
 | ||||
| void CreatureWeaponAnimation::updatePart(NifOgre::ObjectScenePtr& scene, int slot) | ||||
| { | ||||
|     if (!mSkelBase) | ||||
|         return; | ||||
| 
 | ||||
|     MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); | ||||
|     MWWorld::ContainerStoreIterator it = inv.getSlot(slot); | ||||
| 
 | ||||
|  | @ -181,7 +184,9 @@ void CreatureWeaponAnimation::releaseArrow() | |||
| Ogre::Vector3 CreatureWeaponAnimation::runAnimation(float 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()) | ||||
|     { | ||||
|  |  | |||
|  | @ -335,7 +335,10 @@ void NpcAnimation::updateNpcBase() | |||
| } | ||||
| 
 | ||||
| void NpcAnimation::updateParts() | ||||
| {     | ||||
| { | ||||
|     if (!mSkelBase) | ||||
|         return; | ||||
| 
 | ||||
|     mAlpha = 1.f; | ||||
|     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 ret = Animation::runAnimation(timepassed); | ||||
| 
 | ||||
|     mHeadAnimationTime->update(timepassed); | ||||
| 
 | ||||
|     Ogre::SkeletonInstance *baseinst = mSkelBase->getSkeleton(); | ||||
|     if(mViewMode == VM_FirstPerson) | ||||
|     if (mSkelBase) | ||||
|     { | ||||
|         float pitch = mPtr.getRefData().getPosition().rot[0]; | ||||
|         Ogre::Node *node = baseinst->getBone("Bip01 Neck"); | ||||
|         node->pitch(Ogre::Radian(-pitch), Ogre::Node::TS_WORLD); | ||||
|         Ogre::SkeletonInstance *baseinst = mSkelBase->getSkeleton(); | ||||
|         if(mViewMode == VM_FirstPerson) | ||||
|         { | ||||
|             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;
 | ||||
|         // updateSkeletonInstance, below, touches the hands.
 | ||||
|         node->translate(mFirstPersonOffset, Ogre::Node::TS_WORLD); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         // In third person mode we may still need pitch for ranged weapon targeting
 | ||||
|         pitchSkeleton(mPtr.getRefData().getPosition().rot[0], baseinst); | ||||
|             // This has to be done before this function ends;
 | ||||
|             // updateSkeletonInstance, below, touches the hands.
 | ||||
|             node->translate(mFirstPersonOffset, Ogre::Node::TS_WORLD); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             // In third person mode we may still need pitch for ranged weapon targeting
 | ||||
|             pitchSkeleton(mPtr.getRefData().getPosition().rot[0], baseinst); | ||||
| 
 | ||||
|         Ogre::Node* node = baseinst->getBone("Bip01 Head"); | ||||
|         if (node) | ||||
|             node->rotate(Ogre::Quaternion(mHeadYaw, Ogre::Vector3::UNIT_Z) * Ogre::Quaternion(mHeadPitch, Ogre::Vector3::UNIT_X), Ogre::Node::TS_WORLD); | ||||
|             Ogre::Node* node = baseinst->getBone("Bip01 Head"); | ||||
|             if (node) | ||||
|                 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.
 | ||||
| 
 | ||||
|  | @ -659,7 +665,9 @@ Ogre::Vector3 NpcAnimation::runAnimation(float timepassed) | |||
|         if (!isSkinned(mObjectParts[i])) | ||||
|             continue; | ||||
| 
 | ||||
|         updateSkeletonInstance(baseinst, mObjectParts[i]->mSkelBase->getSkeleton()); | ||||
|         if (mSkelBase) | ||||
|             updateSkeletonInstance(mSkelBase->getSkeleton(), mObjectParts[i]->mSkelBase->getSkeleton()); | ||||
| 
 | ||||
|         mObjectParts[i]->mSkelBase->getAllAnimationStates()->_notifyDirty(); | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue