Bläddra i källkod

Fixing animation event triggering
Fixing an issue with scene object animation

BearishSun 9 år sedan
förälder
incheckning
5389d377a1

+ 9 - 11
Source/BansheeCore/Source/BsAnimation.cpp

@@ -940,23 +940,21 @@ namespace BansheeEngine
 
 
 			float clipLength = clipInfo.clip->getLength();
 			float clipLength = clipInfo.clip->getLength();
 			AnimationUtility::wrapTime(start, 0.0f, clipLength, loop);
 			AnimationUtility::wrapTime(start, 0.0f, clipLength, loop);
-			AnimationUtility::wrapTime(end, 0.0f, clipLength, false);
+			AnimationUtility::wrapTime(end, 0.0f, clipLength, loop);
 
 
-			for (auto& event : events)
+			if (start < end)
 			{
 			{
-				if (event.time > start && event.time <= end)
-					onEventTriggered(clipInfo.clip, event.name);
+				for (auto& event : events)
+				{
+					if (event.time > start && event.time <= end)
+						onEventTriggered(clipInfo.clip, event.name);
+				}
 			}
 			}
-
-			// Check the looped portion
-			if(loop && end >= clipLength)
+			else if(end < start) // End is looped, but start is not
 			{
 			{
-				start = 0.0f;
-				end = end - clipLength;
-
 				for (auto& event : events)
 				for (auto& event : events)
 				{
 				{
-					if (event.time > start && event.time <= end)
+					if (event.time > start && event.time < clipLength && event.time > 0 && event.time <= end)
 						onEventTriggered(clipInfo.clip, event.name);
 						onEventTriggered(clipInfo.clip, event.name);
 				}
 				}
 			}
 			}

+ 8 - 6
Source/BansheeCore/Source/BsAnimationManager.cpp

@@ -139,6 +139,14 @@ namespace BansheeEngine
 				curBoneIdx += numBones;
 				curBoneIdx += numBones;
 			}
 			}
 
 
+			// Reset mapped SO transform
+			for (UINT32 i = 0; i < anim->sceneObjectPose.numBones; i++)
+			{
+				anim->sceneObjectPose.positions[i] = Vector3::ZERO;
+				anim->sceneObjectPose.rotations[i] = Quaternion::IDENTITY;
+				anim->sceneObjectPose.scales[i] = Vector3::ONE;
+			}
+
 			// Update mapped scene objects
 			// Update mapped scene objects
 			for(UINT32 i = 0; i < anim->numSceneObjects; i++)
 			for(UINT32 i = 0; i < anim->numSceneObjects; i++)
 			{
 			{
@@ -159,8 +167,6 @@ namespace BansheeEngine
 						const TAnimationCurve<Vector3>& curve = state.curves->position[curveIdx].curve;
 						const TAnimationCurve<Vector3>& curve = state.curves->position[curveIdx].curve;
 						anim->sceneObjectPose.positions[curveIdx] = curve.evaluate(state.time, state.positionCaches[curveIdx], state.loop);
 						anim->sceneObjectPose.positions[curveIdx] = curve.evaluate(state.time, state.positionCaches[curveIdx], state.loop);
 					}
 					}
-					else
-						anim->sceneObjectPose.positions[curveIdx] = Vector3::ZERO;
 				}
 				}
 
 
 				{
 				{
@@ -171,8 +177,6 @@ namespace BansheeEngine
 						anim->sceneObjectPose.rotations[curveIdx] = curve.evaluate(state.time, state.rotationCaches[curveIdx], state.loop);
 						anim->sceneObjectPose.rotations[curveIdx] = curve.evaluate(state.time, state.rotationCaches[curveIdx], state.loop);
 						anim->sceneObjectPose.rotations[curveIdx].normalize();
 						anim->sceneObjectPose.rotations[curveIdx].normalize();
 					}
 					}
-					else
-						anim->sceneObjectPose.rotations[curveIdx] = Quaternion::ZERO;
 				}
 				}
 
 
 				{
 				{
@@ -182,8 +186,6 @@ namespace BansheeEngine
 						const TAnimationCurve<Vector3>& curve = state.curves->scale[curveIdx].curve;
 						const TAnimationCurve<Vector3>& curve = state.curves->scale[curveIdx].curve;
 						anim->sceneObjectPose.scales[curveIdx] = curve.evaluate(state.time, state.scaleCaches[curveIdx], state.loop);
 						anim->sceneObjectPose.scales[curveIdx] = curve.evaluate(state.time, state.scaleCaches[curveIdx], state.loop);
 					}
 					}
-					else
-						anim->sceneObjectPose.scales[curveIdx] = Vector3::ONE;
 				}
 				}
 			}
 			}
 
 

+ 8 - 0
Source/BansheeCore/Source/BsAnimationUtility.cpp

@@ -64,6 +64,14 @@ namespace BansheeEngine
 	{
 	{
 		// TODO: We calculate tangents by sampling. There must be an analytical way to calculate tangents when converting
 		// TODO: We calculate tangents by sampling. There must be an analytical way to calculate tangents when converting
 		// a curve.
 		// a curve.
+		// Consider: 
+		//  - Sampling multiple points to calculate tangents to improve precision
+		//  - Store the original quaternion curve with the euler curve
+		//    - This way conversion from euler to quaternion can be done while individual keyframes are being modified
+		//      ensuring the conversion results are immediately visible, and that no accumulation error happens are curves
+		//		are converted between two formats back and forth.
+		//  - Don't store rotation tangents directly, instead store tangent parameters (TCB) which can be shared between
+		//    both curves, and used for tangent calculation.
 		const float FIT_TIME = 0.001f;
 		const float FIT_TIME = 0.001f;
 
 
 		auto eulerToQuaternion = [&](INT32 keyIdx, Vector3& angles, const Quaternion& lastQuat)
 		auto eulerToQuaternion = [&](INT32 keyIdx, Vector3& angles, const Quaternion& lastQuat)