Просмотр исходного кода

Querying components from OnDestroy callback now properly returns only non-destroyed components (fixes a crash on exit for Animation component)
Animation proxies are now properly visible on the animation thread
Final skeleton poses are now properly visible on the core thread
Checking if a Renderable has an animation now returns a valid answer
C# Animation OnEnable/OnDisable callbacks now trigger properly
Pause/unpause animation when exiting/entering play-mode in editor

BearishSun 9 лет назад
Родитель
Сommit
6869dbcfbc

+ 3 - 0
Source/BansheeCore/Include/BsAnimationManager.h

@@ -109,5 +109,8 @@ namespace BansheeEngine
 		std::atomic<INT32> mDataReadyCount;
 		std::atomic<INT32> mDataReadyCount;
 	};
 	};
 
 
+	/** Provides easier access to AnimationManager. */
+	BS_CORE_EXPORT AnimationManager& gAnimation();
+
 	/** @} */
 	/** @} */
 }
 }

+ 7 - 1
Source/BansheeCore/Source/BsAnimationManager.cpp

@@ -66,7 +66,7 @@ namespace BansheeEngine
 		for (auto& anim : mAnimations)
 		for (auto& anim : mAnimations)
 		{
 		{
 			anim.second->updateAnimProxy(timeDelta);
 			anim.second->updateAnimProxy(timeDelta);
-			mProxies[anim.second->mId] = anim.second->mAnimProxy;
+			mProxies.push_back(anim.second->mAnimProxy);
 		}
 		}
 
 
 		// Make sure thread finishes writing all changes to the anim proxies as they will be read by the animation thread
 		// Make sure thread finishes writing all changes to the anim proxies as they will be read by the animation thread
@@ -116,6 +116,7 @@ namespace BansheeEngine
 				Matrix4* boneDst = renderData.transforms.data() + curBoneIdx;
 				Matrix4* boneDst = renderData.transforms.data() + curBoneIdx;
 				anim->skeleton->getPose(boneDst, anim->localPose, anim->layers, anim->numLayers);
 				anim->skeleton->getPose(boneDst, anim->localPose, anim->layers, anim->numLayers);
 
 
+				renderData.poseInfos[anim->id] = info;
 				curBoneIdx += numBones;
 				curBoneIdx += numBones;
 			}
 			}
 			else
 			else
@@ -211,4 +212,9 @@ namespace BansheeEngine
 	{
 	{
 		mAnimations.erase(animId);
 		mAnimations.erase(animId);
 	}
 	}
+
+	AnimationManager& gAnimation()
+	{
+		return AnimationManager::instance();
+	}
 }
 }

+ 6 - 5
Source/BansheeCore/Source/BsSceneObject.cpp

@@ -85,9 +85,11 @@ namespace BansheeEngine
 
 
 			mChildren.clear();
 			mChildren.clear();
 
 
-			for (auto iter = mComponents.begin(); iter != mComponents.end(); ++iter)
+			// It's important to remove the elements from the array as soon as they're destroyed, as OnDestroy callbacks
+			// for components might query the SO's components, and we want to only return live ones 
+			while (!mComponents.empty())
 			{
 			{
-				HComponent component = *iter;
+				HComponent component = mComponents.back();
 				component->_setIsDestroyed();
 				component->_setIsDestroyed();
 
 
 				if (isInstantiated())
 				if (isInstantiated())
@@ -98,11 +100,10 @@ namespace BansheeEngine
 					component->onDestroyed();
 					component->onDestroyed();
 				}
 				}
 
 
-				component->destroyInternal(*iter, true);
+				component->destroyInternal(component, true);
+				mComponents.erase(mComponents.end() - 1);
 			}
 			}
 
 
-			mComponents.clear();
-
 			GameObjectManager::instance().unregisterObject(handle);
 			GameObjectManager::instance().unregisterObject(handle);
 		}
 		}
 		else
 		else

+ 1 - 1
Source/BansheeEngine/Include/BsRenderable.h

@@ -168,7 +168,7 @@ namespace BansheeEngine
 		UINT32 getRendererId() const { return mRendererId; }
 		UINT32 getRendererId() const { return mRendererId; }
 
 
 		/** Checks is the mesh geometry rendered by this renderable animated using skeleton or blend shape animation. */
 		/** Checks is the mesh geometry rendered by this renderable animated using skeleton or blend shape animation. */
-		bool isAnimated() const { return mAnimationId != (UINT32)-1; }
+		bool isAnimated() const { return mAnimationId != (UINT64)-1; }
 
 
 		/** Returns the identifier of the animation, if this object is animated using skeleton or blend shape animation. */
 		/** Returns the identifier of the animation, if this object is animated using skeleton or blend shape animation. */
 		UINT64 getAnimationId() const { return mAnimationId; }
 		UINT64 getAnimationId() const { return mAnimationId; }

+ 2 - 2
Source/MBansheeEngine/Animation/Animation.cs

@@ -296,12 +296,12 @@ namespace BansheeEngine
                 _native.SetState(clip, state);
                 _native.SetState(clip, state);
         }
         }
 
 
-        private void OnEnabled()
+        private void OnEnable()
         {
         {
             RestoreNative();
             RestoreNative();
         }
         }
 
 
-        private void OnDisabled()
+        private void OnDisable()
         {
         {
             DestroyNative();
             DestroyNative();
         }
         }

+ 1 - 1
Source/RenderBeast/Source/BsObjectRendering.cpp

@@ -87,7 +87,7 @@ namespace BansheeEngine
 		mPerObjectParams.gWorldDeterminantSign.set(data.worldDeterminantSign);
 		mPerObjectParams.gWorldDeterminantSign.set(data.worldDeterminantSign);
 		mPerObjectParams.gMatWorldViewProj.set(wvpMatrix);
 		mPerObjectParams.gMatWorldViewProj.set(wvpMatrix);
 
 
-		if(element.animationId != (UINT32)-1)
+		if(element.animationId != (UINT64)-1)
 			element.boneMatricesParam.set(boneMatrices);
 			element.boneMatricesParam.set(boneMatrices);
 	}
 	}
 
 

+ 1 - 1
Source/RenderBeast/Source/BsRenderBeast.cpp

@@ -726,7 +726,7 @@ namespace BansheeEngine
 		Matrix4 worldViewProjMatrix = viewProj * mRenderableShaderData[rendererId].worldTransform;
 		Matrix4 worldViewProjMatrix = viewProj * mRenderableShaderData[rendererId].worldTransform;
 
 
 		SPtr<GpuBufferCore> boneMatrices;
 		SPtr<GpuBufferCore> boneMatrices;
-		if(element.animationId != (UINT32)-1)
+		if(element.animationId != (UINT64)-1)
 		{
 		{
 			// Note: If multiple elements are using the same animation (not possible atm), this buffer should be created
 			// Note: If multiple elements are using the same animation (not possible atm), this buffer should be created
 			// earlier and then shared by all elements
 			// earlier and then shared by all elements

+ 3 - 3
Source/SBansheeEngine/Include/BsScriptAnimation.h

@@ -53,7 +53,7 @@ namespace BansheeEngine
 	};
 	};
 
 
 	/** Helper class for dealing with BlendSequentialClipInfo structure. */
 	/** Helper class for dealing with BlendSequentialClipInfo structure. */
-	class ScriptBlendClipInfo : public ScriptObject<ScriptBlendClipInfo>
+	class BS_SCR_BE_EXPORT ScriptBlendClipInfo : public ScriptObject<ScriptBlendClipInfo>
 	{
 	{
 	public:
 	public:
 		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "BlendClipInfo")
 		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "BlendClipInfo")
@@ -72,7 +72,7 @@ namespace BansheeEngine
 	};
 	};
 
 
 	/** Helper class for dealing with Blend1DInfo structure. */
 	/** Helper class for dealing with Blend1DInfo structure. */
-	class ScriptBlend1DInfo : public ScriptObject<ScriptBlend1DInfo>
+	class BS_SCR_BE_EXPORT ScriptBlend1DInfo : public ScriptObject<ScriptBlend1DInfo>
 	{
 	{
 	public:
 	public:
 		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "Blend1DInfo")
 		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "Blend1DInfo")
@@ -90,7 +90,7 @@ namespace BansheeEngine
 	};
 	};
 
 
 	/** Helper class for dealing with Blend2DInfo structure. */
 	/** Helper class for dealing with Blend2DInfo structure. */
-	class ScriptBlend2DInfo : public ScriptObject<ScriptBlend2DInfo>
+	class BS_SCR_BE_EXPORT ScriptBlend2DInfo : public ScriptObject<ScriptBlend2DInfo>
 	{
 	{
 	public:
 	public:
 		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "Blend2DInfo")
 		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "Blend2DInfo")

+ 4 - 0
Source/SBansheeEngine/Source/BsPlayInEditorManager.cpp

@@ -8,6 +8,7 @@
 #include "BsApplication.h"
 #include "BsApplication.h"
 #include "BsPhysics.h"
 #include "BsPhysics.h"
 #include "BsAudio.h"
 #include "BsAudio.h"
+#include "BsAnimationManager.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
@@ -47,6 +48,7 @@ namespace BansheeEngine
 
 
 			gPhysics().setPaused(true);
 			gPhysics().setPaused(true);
 			gAudio().setPaused(true);
 			gAudio().setPaused(true);
+			gAnimation().setPaused(true);
 
 
 			mSavedScene->_instantiate();
 			mSavedScene->_instantiate();
 			gSceneManager()._setRootNode(mSavedScene);
 			gSceneManager()._setRootNode(mSavedScene);
@@ -63,6 +65,7 @@ namespace BansheeEngine
 
 
 			gPhysics().setPaused(false);
 			gPhysics().setPaused(false);
 			gAudio().setPaused(false);
 			gAudio().setPaused(false);
+			gAnimation().setPaused(false);
 		}
 		}
 			break;
 			break;
 		case PlayInEditorState::Paused:
 		case PlayInEditorState::Paused:
@@ -70,6 +73,7 @@ namespace BansheeEngine
 			mFrameStepActive = false;
 			mFrameStepActive = false;
 			gPhysics().setPaused(true);
 			gPhysics().setPaused(true);
 			gAudio().setPaused(true);
 			gAudio().setPaused(true);
+			gAnimation().setPaused(true);
 
 
 			if (oldState == PlayInEditorState::Stopped)
 			if (oldState == PlayInEditorState::Stopped)
 			{
 			{

+ 5 - 1
Source/SBansheeEngine/Source/BsScriptRenderable.cpp

@@ -69,7 +69,11 @@ namespace BansheeEngine
 
 
 	void ScriptRenderable::internal_SetAnimation(ScriptRenderable* thisPtr, ScriptAnimation* animation)
 	void ScriptRenderable::internal_SetAnimation(ScriptRenderable* thisPtr, ScriptAnimation* animation)
 	{
 	{
-		thisPtr->getInternal()->setAnimation(animation->getInternal());
+		SPtr<Animation> anim;
+		if (animation != nullptr)
+			anim = animation->getInternal();
+
+		thisPtr->getInternal()->setAnimation(anim);
 	}
 	}
 
 
 	void ScriptRenderable::internal_UpdateTransform(ScriptRenderable* thisPtr, ScriptSceneObject* parent)
 	void ScriptRenderable::internal_UpdateTransform(ScriptRenderable* thisPtr, ScriptSceneObject* parent)