Explorar o código

Added C# AnimationCurve

BearishSun %!s(int64=9) %!d(string=hai) anos
pai
achega
4dd9edcc77

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

@@ -42,7 +42,8 @@ namespace BansheeEngine
     /// <summary>
     /// <summary>
     /// Contains information about a currently playing animation clip.
     /// Contains information about a currently playing animation clip.
     /// </summary>
     /// </summary>
-    public struct AnimationClipState
+    [StructLayout(LayoutKind.Sequential), SerializeObject]
+    public struct AnimationClipState // Note: Must match C++ struct AnimationClipState
     {
     {
         /// <summary>
         /// <summary>
         /// Layer the clip is playing on. Multiple clips can be played simulatenously on different layers.
         /// Layer the clip is playing on. Multiple clips can be played simulatenously on different layers.

+ 81 - 0
Source/MBansheeEngine/Animation/AnimationCurve.cs

@@ -0,0 +1,81 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace BansheeEngine
+{
+    /// <summary>
+    /// Animation keyframe, represented as an endpoint of a cubic hermite spline.
+    /// </summary>
+    [StructLayout(LayoutKind.Sequential), SerializeObject]
+    public struct KeyFrame // Note: Must match C++ struct TKeyFrame<float>
+    {
+        /// <summary>
+        /// Value of the key.
+        /// </summary>
+        public float value;
+        /// <summary>
+        /// Input tangent (going from the previous key to this one) of the key.
+        /// </summary>
+        public float inTangent;
+        /// <summary>
+        /// Output tangent (going from this key to next one) of the key.
+        /// </summary>
+        public float outTangent;
+        /// <summary>
+        /// Position of the key along the animation spline.
+        /// </summary>
+        public float time;
+    }
+
+    /// <summary>
+    /// Animation spline represented by a set of keyframes, each representing an endpoint of a cubic hermite curve. The
+    /// spline can be evaluated at any time, and uses caching to speed up multiple sequential evaluations.
+    /// </summary>
+    public class AnimationCurve : ScriptObject
+    {
+        /// <summary>
+        /// Creates a new animation curve.
+        /// </summary>
+        /// <param name="keyFrames">Keyframes to initialize the curve with.</param>
+        public AnimationCurve(KeyFrame[] keyFrames)
+        {
+            Internal_Create(this, keyFrames);
+        }
+
+        /// <summary>
+        /// Keyframes that represent the curve.
+        /// </summary>
+        public KeyFrame[] KeyFrames
+        {
+            get { return Internal_GetKeyFrames(mCachedPtr); }
+            set { Internal_SetKeyFrames(mCachedPtr, value); }
+        }
+
+        /// <summary>
+        /// Evaluate the animation curve at the specified time.
+        /// </summary>
+        /// <param name="time">Time to evaluate the curve at. </param>
+        /// <param name="loop">If true the curve will loop when it goes past the end or beggining. Otherwise the curve 
+        ///                    value will be clamped.</param>
+        /// <returns>Interpolated value from the curve at provided time.</returns>
+        public float Evaluate(float time, bool loop = true)
+        {
+            return Internal_Evaluate(mCachedPtr, time, loop);
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_Create(AnimationCurve instance, KeyFrame[] keyframes);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern KeyFrame[] Internal_GetKeyFrames(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetKeyFrames(IntPtr thisPtr, KeyFrame[] keyframes);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern float Internal_Evaluate(IntPtr thisPtr, float time, bool loop);
+    }
+}

+ 1 - 0
Source/MBansheeEngine/MBansheeEngine.csproj

@@ -45,6 +45,7 @@
   <ItemGroup>
   <ItemGroup>
     <Compile Include="Animation\Animation.cs" />
     <Compile Include="Animation\Animation.cs" />
     <Compile Include="Animation\AnimationClip.cs" />
     <Compile Include="Animation\AnimationClip.cs" />
+    <Compile Include="Animation\AnimationCurve.cs" />
     <Compile Include="Animation\Interop\NativeAnimation.cs" />
     <Compile Include="Animation\Interop\NativeAnimation.cs" />
     <Compile Include="Audio\Audio.cs" />
     <Compile Include="Audio\Audio.cs" />
     <Compile Include="Audio\AudioClip.cs" />
     <Compile Include="Audio\AudioClip.cs" />

+ 2 - 0
Source/SBansheeEngine/CMakeSources.cmake

@@ -140,6 +140,7 @@ set(BS_SBANSHEEENGINE_INC_WRAPPERS
 	"Include/BsScriptAudioListener.h"
 	"Include/BsScriptAudioListener.h"
 	"Include/BsScriptAnimationClip.h"
 	"Include/BsScriptAnimationClip.h"
 	"Include/BsScriptAnimation.h"
 	"Include/BsScriptAnimation.h"
+	"Include/BsScriptAnimationCurve.h"
 )
 )
 
 
 set(BS_SBANSHEEENGINE_INC_WRAPPERS_GUI
 set(BS_SBANSHEEENGINE_INC_WRAPPERS_GUI
@@ -270,6 +271,7 @@ set(BS_SBANSHEEENGINE_SRC_WRAPPERS
 	"Source/BsScriptAudioListener.cpp"
 	"Source/BsScriptAudioListener.cpp"
 	"Source/BsScriptAnimationClip.cpp"
 	"Source/BsScriptAnimationClip.cpp"
 	"Source/BsScriptAnimation.cpp"
 	"Source/BsScriptAnimation.cpp"
+	"Source/BsScriptAnimationCurve.cpp"
 )
 )
 
 
 set(BS_SBANSHEEENGINE_INC_SERIALIZATION
 set(BS_SBANSHEEENGINE_INC_SERIALIZATION

+ 45 - 0
Source/SBansheeEngine/Include/BsScriptAnimationCurve.h

@@ -0,0 +1,45 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "BsScriptObject.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup ScriptInteropEngine
+	 *  @{
+	 */
+	
+	/** Interop class between C++ & CLR for KeyFrame. */
+	class BS_SCR_BE_EXPORT ScriptKeyFrame : public ScriptObject<ScriptKeyFrame>
+	{
+	public:
+		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "KeyFrame")
+
+	private:
+		ScriptKeyFrame(MonoObject* instance);
+	};
+
+	/** Interop class between C++ & CLR for AnimationCurve. */
+	class BS_SCR_BE_EXPORT ScriptAnimationCurve : public ScriptObject<ScriptAnimationCurve>
+	{
+	public:
+		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "AnimationCurve")
+
+	private:
+		ScriptAnimationCurve(MonoObject* instance, const SPtr<TAnimationCurve<float>>& curve);
+
+		SPtr<TAnimationCurve<float>> mCurve;
+
+		/************************************************************************/
+		/* 								CLR HOOKS						   		*/
+		/************************************************************************/
+		static void internal_Create(MonoObject* instance, MonoArray* keyframes);
+		static MonoArray* internal_GetKeyFrames(ScriptAnimationCurve* thisPtr);
+		static void internal_SetKeyFrames(ScriptAnimationCurve* thisPtr, MonoArray* keyframes);
+		static float internal_Evaluate(ScriptAnimationCurve* thisPtr, float time, bool loop);
+	};
+
+	/** @} */
+}

+ 76 - 0
Source/SBansheeEngine/Source/BsScriptAnimationCurve.cpp

@@ -0,0 +1,76 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsScriptAnimationCurve.h"
+#include "BsMonoUtil.h"
+#include "BsMonoClass.h"
+#include "BsMonoMethod.h"
+#include "BsAnimationCurve.h"
+
+using namespace std::placeholders;
+
+namespace BansheeEngine
+{
+	ScriptKeyFrame::ScriptKeyFrame(MonoObject* instance)
+		:ScriptObject(instance)
+	{ }
+
+	void ScriptKeyFrame::initRuntimeData()
+	{
+		// Do nothing
+	}
+
+	ScriptAnimationCurve::ScriptAnimationCurve(MonoObject* instance, const SPtr<TAnimationCurve<float>>& curve)
+		:ScriptObject(instance), mCurve(curve)
+	{ }
+
+	void ScriptAnimationCurve::initRuntimeData()
+	{
+		metaData.scriptClass->addInternalCall("Internal_Create", &ScriptAnimationCurve::internal_Create);
+		metaData.scriptClass->addInternalCall("Internal_GetKeyFrames", &ScriptAnimationCurve::internal_GetKeyFrames);
+		metaData.scriptClass->addInternalCall("Internal_SetKeyFrames", &ScriptAnimationCurve::internal_SetKeyFrames);
+		metaData.scriptClass->addInternalCall("Internal_Evaluate", &ScriptAnimationCurve::internal_Evaluate);
+	}
+
+	void ScriptAnimationCurve::internal_Create(MonoObject* instance, MonoArray* keyFrames)
+	{
+		ScriptArray inArray(keyFrames);
+		
+		UINT32 numKeyframes = inArray.size();
+		Vector<TKeyframe<float>> nativeKeyframes(numKeyframes);
+
+		memcpy(nativeKeyframes.data(), (UINT8*)inArray.getRawPtr<TKeyframe<float>>(), 
+			numKeyframes * sizeof(TKeyframe<float>));
+
+		SPtr<TAnimationCurve<float>> curve = bs_shared_ptr_new<TAnimationCurve<float>>(nativeKeyframes);
+		new (bs_alloc<ScriptAnimationCurve>()) ScriptAnimationCurve(instance, curve);
+	}
+
+	MonoArray* ScriptAnimationCurve::internal_GetKeyFrames(ScriptAnimationCurve* thisPtr)
+	{
+		UINT32 numKeyframes = thisPtr->mCurve->getNumKeyFrames();
+
+		ScriptArray output = ScriptArray::create<ScriptKeyFrame>(numKeyframes);
+		for (UINT32 i = 0; i < numKeyframes; i++)
+			output.set(i, thisPtr->mCurve->getKeyFrame(i));
+
+		return output.getInternal();
+	}
+
+	void ScriptAnimationCurve::internal_SetKeyFrames(ScriptAnimationCurve* thisPtr, MonoArray* keyFrames)
+	{
+		ScriptArray inArray(keyFrames);
+
+		UINT32 numKeyframes = inArray.size();
+		Vector<TKeyframe<float>> nativeKeyframes(numKeyframes);
+
+		memcpy(nativeKeyframes.data(), (UINT8*)inArray.getRawPtr<TKeyframe<float>>(),
+			numKeyframes * sizeof(TKeyframe<float>));
+
+		thisPtr->mCurve = bs_shared_ptr_new<TAnimationCurve<float>>(nativeKeyframes);
+	}
+
+	float ScriptAnimationCurve::internal_Evaluate(ScriptAnimationCurve* thisPtr, float time, bool loop)
+	{
+		return thisPtr->mCurve->evaluate(time, loop);
+	}
+}