Преглед изворни кода

Offset all animation clips to start at time 0 on import

BearishSun пре 9 година
родитељ
комит
e660d4fe4f

+ 4 - 0
Source/BansheeCore/Include/BsAnimationUtility.h

@@ -34,6 +34,10 @@ namespace BansheeEngine
 		/** Scales all curve values and tangents by the specified scale factor. */
 		template<class T> 
 		static TAnimationCurve<T> scaleCurve(const TAnimationCurve<T>& curve, float factor);
+
+		/** Adds a time offset to all keyframes in the provided curve. */
+		template<class T>
+		static TAnimationCurve<T> offsetCurve(const TAnimationCurve<T>& curve, float offset);
 	};
 
 	/** @} */

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

@@ -235,7 +235,29 @@ namespace BansheeEngine
 		return TAnimationCurve<T>(newKeyframes);
 	}
 
+	template<class T>
+	TAnimationCurve<T> AnimationUtility::offsetCurve(const TAnimationCurve<T>& curve, float offset)
+	{
+		INT32 numKeys = (INT32)curve.getNumKeyFrames();
+
+		Vector<TKeyframe<T>> newKeyframes(numKeys);
+		for (INT32 i = 0; i < numKeys; i++)
+		{
+			const TKeyframe<T>& key = curve.getKeyFrame(i);
+			newKeyframes[i].time = key.time + offset;
+			newKeyframes[i].value = key.value;
+			newKeyframes[i].inTangent = key.inTangent;
+			newKeyframes[i].outTangent = key.outTangent;
+		}
+
+		return TAnimationCurve<T>(newKeyframes);
+	}
+
 	template BS_CORE_EXPORT TAnimationCurve<Vector3> AnimationUtility::scaleCurve(const TAnimationCurve<Vector3>& curve, float factor);
 	template BS_CORE_EXPORT TAnimationCurve<Quaternion> AnimationUtility::scaleCurve(const TAnimationCurve<Quaternion>& curve, float factor);
 	template BS_CORE_EXPORT TAnimationCurve<float> AnimationUtility::scaleCurve(const TAnimationCurve<float>& curve, float factor);
+
+	template BS_CORE_EXPORT TAnimationCurve<Vector3> AnimationUtility::offsetCurve(const TAnimationCurve<Vector3>& curve, float offset);
+	template BS_CORE_EXPORT TAnimationCurve<Quaternion> AnimationUtility::offsetCurve(const TAnimationCurve<Quaternion>& curve, float offset);
+	template BS_CORE_EXPORT TAnimationCurve<float> AnimationUtility::offsetCurve(const TAnimationCurve<float>& curve, float offset);
 }

+ 34 - 3
Source/BansheeFBXImporter/Source/BsFBXImporter.cpp

@@ -452,11 +452,42 @@ namespace BansheeEngine
 		{
 			SPtr<AnimationCurves> curves = bs_shared_ptr_new<AnimationCurves>();
 			
+			// Offset animations so they start at time 0
+			float animStart = std::numeric_limits<float>::infinity();
+
 			for (auto& bone : clip.boneAnimations)
 			{
-				curves->position.push_back({ bone.node->name, AnimationCurveFlag::ImportedCurve, bone.translation });
-				curves->rotation.push_back({ bone.node->name, AnimationCurveFlag::ImportedCurve, bone.rotation });
-				curves->scale.push_back({ bone.node->name, AnimationCurveFlag::ImportedCurve, bone.scale });
+				if(bone.translation.getNumKeyFrames() > 0)
+					animStart = std::min(bone.translation.getKeyFrame(0).time, animStart);
+
+				if (bone.rotation.getNumKeyFrames() > 0)
+					animStart = std::min(bone.rotation.getKeyFrame(0).time, animStart);
+
+				if (bone.scale.getNumKeyFrames() > 0)
+					animStart = std::min(bone.scale.getKeyFrame(0).time, animStart);
+			}
+
+			if (animStart != 0.0f && animStart != std::numeric_limits<float>::infinity())
+			{
+				for (auto& bone : clip.boneAnimations)
+				{
+					TAnimationCurve<Vector3> translation = AnimationUtility::offsetCurve(bone.translation, -animStart);
+					TAnimationCurve<Quaternion> rotation = AnimationUtility::offsetCurve(bone.rotation, -animStart);
+					TAnimationCurve<Vector3> scale = AnimationUtility::offsetCurve(bone.scale, -animStart);
+
+					curves->position.push_back({ bone.node->name, AnimationCurveFlag::ImportedCurve, translation });
+					curves->rotation.push_back({ bone.node->name, AnimationCurveFlag::ImportedCurve, rotation });
+					curves->scale.push_back({ bone.node->name, AnimationCurveFlag::ImportedCurve, scale });
+				}
+			}
+			else
+			{
+				for (auto& bone : clip.boneAnimations)
+				{
+					curves->position.push_back({ bone.node->name, AnimationCurveFlag::ImportedCurve, bone.translation });
+					curves->rotation.push_back({ bone.node->name, AnimationCurveFlag::ImportedCurve, bone.rotation });
+					curves->scale.push_back({ bone.node->name, AnimationCurveFlag::ImportedCurve, bone.scale });
+				}
 			}
 
 			// See if any splits are required. We only split the first clip as it is assumed if FBX has multiple clips the