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

AnimationClip and all related classes ported to use the script binding
generator
Various general fixes to script binding genration

BearishSun 8 лет назад
Родитель
Сommit
ec77a59680
34 измененных файлов с 544 добавлено и 1578 удалено
  1. 57 21
      Source/BansheeCore/Include/BsAnimationClip.h
  2. 65 3
      Source/BansheeCore/Include/BsAnimationCurve.h
  3. 13 3
      Source/BansheeCore/Include/BsAnimationUtility.h
  4. 0 1
      Source/BansheeCore/Source/BsAnimationClip.cpp
  5. 3 3
      Source/BansheeCore/Source/BsAnimationCurve.cpp
  6. 108 18
      Source/BansheeCore/Source/BsAnimationUtility.cpp
  7. 5 2
      Source/BansheeCore/Source/BsMaterialRTTI.cpp
  8. 5 5
      Source/BansheeFBXImporter/Source/BsFBXImporter.cpp
  9. 1 0
      Source/CMake/GenerateScriptBindings.cmake
  10. 2 1
      Source/MBansheeEditor/Utility/EdAnimationCurve.cs
  11. 45 23
      Source/MBansheeEditor/Windows/Animation/EditorAnimInfo.cs
  12. 2 2
      Source/MBansheeEditor/Windows/Animation/GUIAnimEvents.cs
  13. 7 7
      Source/MBansheeEditor/Windows/Animation/GUICurveEditor.cs
  14. 4 8
      Source/MBansheeEditor/Windows/AnimationWindow.cs
  15. 33 28
      Source/MBansheeEngine/Animation/Animation.cs
  16. 0 149
      Source/MBansheeEngine/Animation/AnimationClip.cs
  17. 0 340
      Source/MBansheeEngine/Animation/AnimationCurve.cs
  18. 0 38
      Source/MBansheeEngine/Animation/AnimationCurves.cs
  19. 1 4
      Source/MBansheeEngine/MBansheeEngine.csproj
  20. 4 8
      Source/SBansheeEditor/Source/BsScriptImportOptions.cpp
  21. 4 6
      Source/SBansheeEngine/CMakeSources.cmake
  22. 64 0
      Source/SBansheeEngine/Include/BsAnimationEx.h
  23. 0 66
      Source/SBansheeEngine/Include/BsScriptAnimationClip.h
  24. 0 52
      Source/SBansheeEngine/Include/BsScriptAnimationCurve.h
  25. 0 129
      Source/SBansheeEngine/Include/BsScriptAnimationCurves.h
  26. 32 0
      Source/SBansheeEngine/Include/BsScriptQuaternion.h
  27. 58 0
      Source/SBansheeEngine/Source/BsAnimationEx.cpp
  28. 2 1
      Source/SBansheeEngine/Source/BsScriptAnimation.cpp
  29. 0 145
      Source/SBansheeEngine/Source/BsScriptAnimationClip.cpp
  30. 0 93
      Source/SBansheeEngine/Source/BsScriptAnimationCurve.cpp
  31. 0 420
      Source/SBansheeEngine/Source/BsScriptAnimationCurves.cpp
  32. 1 1
      Source/SBansheeEngine/Source/BsScriptAssemblyManager.cpp
  33. 1 1
      Source/SBansheeEngine/Source/BsScriptMaterial.cpp
  34. 27 0
      Source/SBansheeEngine/Source/BsScriptQuaternion.cpp

+ 57 - 21
Source/BansheeCore/Include/BsAnimationClip.h

@@ -17,8 +17,11 @@ namespace bs
 	struct AnimationCurveMapping;
 
 	/** A set of animation curves representing translation/rotation/scale and generic animation. */
-	struct AnimationCurves
+	struct BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Animation) AnimationCurves
 	{
+		BS_SCRIPT_EXPORT()
+		AnimationCurves() {}
+
 		/** 
 		 * Registers a new curve used for animating position. 
 		 *
@@ -26,6 +29,7 @@ namespace bs
 		 *							in a skeleton, if any.
 		 * @param[in]	curve		Curve to add to the clip.
 		 */
+		BS_SCRIPT_EXPORT(n:AddPositionCurve)
 		void addPositionCurve(const String& name, const TAnimationCurve<Vector3>& curve);
 
 		/** 
@@ -35,6 +39,7 @@ namespace bs
 		 *							in a skeleton, if any.
 		 * @param[in]	curve		Curve to add to the clip.
 		 */
+		BS_SCRIPT_EXPORT(n:AddRotationCurve)
 		void addRotationCurve(const String& name, const TAnimationCurve<Quaternion>& curve);
 
 		/** 
@@ -44,6 +49,7 @@ namespace bs
 		 *							in a skeleton, if any.
 		 * @param[in]	curve		Curve to add to the clip.
 		 */
+		BS_SCRIPT_EXPORT(n:AddScaleCurve)
 		void addScaleCurve(const String& name, const TAnimationCurve<Vector3>& curve);
 
 		/** 
@@ -53,50 +59,74 @@ namespace bs
 		 *							from animation.
 		 * @param[in]	curve		Curve to add to the clip.
 		 */
+		BS_SCRIPT_EXPORT(n:AddGenericCurve)
 		void addGenericCurve(const String& name, const TAnimationCurve<float>& curve);
 
 		/** Removes an existing curve from the clip. */
+		BS_SCRIPT_EXPORT(n:RemovePositionCurve)
 		void removePositionCurve(const String& name);
 
 		/** Removes an existing curve from the clip. */
+		BS_SCRIPT_EXPORT(n:RemoveRotationCurve)
 		void removeRotationCurve(const String& name);
 
 		/** Removes an existing curve from the clip. */
+		BS_SCRIPT_EXPORT(n:RemoveScaleCurve)
 		void removeScaleCurve(const String& name);
 
 		/** Removes an existing curve from the clip. */
+		BS_SCRIPT_EXPORT(n:RemoveGenericCurve)
 		void removeGenericCurve(const String& name);
 
+		/** Curves for animating scene object's position. */
 		Vector<TNamedAnimationCurve<Vector3>> position;
+
+		/** Curves for animating scene object's rotation. */
 		Vector<TNamedAnimationCurve<Quaternion>> rotation;
+
+		/** Curves for animating scene object's scale. */
 		Vector<TNamedAnimationCurve<Vector3>> scale;
+
+		/** Curves for animating generic component properties. */
 		Vector<TNamedAnimationCurve<float>> generic;
 	};
 
 	/** Contains a set of animation curves used for moving and rotating the root bone. */
-	struct RootMotion
+	struct BS_SCRIPT_EXPORT(m:Animation) RootMotion
 	{
 		RootMotion() { }
 		RootMotion(const TAnimationCurve<Vector3>& position, const TAnimationCurve<Quaternion>& rotation)
 			:position(position), rotation(rotation)
 		{ }
 
+		/** Animation curve representing the movement of the root bone. */
 		TAnimationCurve<Vector3> position;
+
+		/** Animation curve representing the rotation of the root bone. */
 		TAnimationCurve<Quaternion> rotation;
 	};
 
 	/** Event that is triggered when animation reaches a certain point. */
-	struct AnimationEvent
+	struct BS_SCRIPT_EXPORT(m:Animation,pl:true) AnimationEvent
 	{
 		AnimationEvent()
 			:time(0.0f)
 		{ }
 
+		/** 
+		 * Constructs a new animation event.
+		 *
+		 * @param[in]	name	Name used to identify the event when triggered.
+		 * @param[in]	time	Time at which to trigger the event, in seconds.
+		 */
 		AnimationEvent(const String& name, float time)
 			:name(name), time(time)
 		{ }
 
+		/** Name used to identify the event when triggered. */
 		String name;
+
+		/** Time at which to trigger the event, in seconds. */
 		float time;
 	};
 
@@ -116,24 +146,28 @@ namespace bs
 	 * Contains animation curves for translation/rotation/scale of scene objects/skeleton bones, as well as curves for
 	 * generic property animation. 
 	 */
-	class BS_CORE_EXPORT AnimationClip : public Resource
+	class BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Animation) AnimationClip : public Resource
 	{
 	public:
 		virtual ~AnimationClip() { }
 
-		/** 
-		 * Returns all curves stored in the animation. Returned value will not be updated if the animation clip curves are
-		 * added or removed. Caller must monitor for changes and retrieve a new set of curves when that happens.
-		 */
+		/** @copydoc setCurves() */
+		BS_SCRIPT_EXPORT(n:Curves,pr:getter)
 		SPtr<AnimationCurves> getCurves() const { return mCurves; }
 
-		/** Assigns a new set of curves to be used by the animation. The clip will store a copy of this object.*/
+		/** 
+		 * A set of all curves stored in the animation. Returned value will not be updated if the animation clip curves are
+		 * added or removed, as it is a copy of clip's internal values.
+		 */
+		BS_SCRIPT_EXPORT(n:Curves,pr:setter)
 		void setCurves(const AnimationCurves& curves);
 
-		/** Returns all events that will be triggered by the animation. */
+		/** @copydoc setEvents() */
+		BS_SCRIPT_EXPORT(n:Events,pr:getter)
 		const Vector<AnimationEvent>& getEvents() const { return mEvents; }
 
-		/** Sets events that will be triggered as the animation is playing. */
+		/** A set of all events to be triggered as the animation is playing. */
+		BS_SCRIPT_EXPORT(n:Events,pr:setter)
 		void setEvents(const Vector<AnimationEvent>& events) { mEvents = events; }
 
 		/** 
@@ -141,9 +175,11 @@ namespace bs
 		 * animation curves manually, instead of through the normal animation process. This property is only available
 		 * if animation clip was imported with root motion import enabled. 
 		 */
+		BS_SCRIPT_EXPORT(n:RootMotion,pr:getter)
 		SPtr<RootMotion> getRootMotion() const { return mRootMotion; }
 
 		/** Checks if animation clip has root motion curves separate from the normal animation curves. */
+		BS_SCRIPT_EXPORT(n:HasRootMotion,pr:getter)
 		bool hasRootMotion() const;
 
 		/**
@@ -181,25 +217,23 @@ namespace bs
 		 * Checks are the curves contained within the clip additive. Additive clips are intended to be added on top of
 		 * other clips.
 		 */
+		BS_SCRIPT_EXPORT(n:IsAddtive,pr:getter)
 		bool isAdditive() const { return mIsAdditive; }
 
 		/** Returns the length of the animation clip, in seconds. */
+		BS_SCRIPT_EXPORT(n:Length,pr:getter)
 		float getLength() const { return mLength; }
 
-		/** 
-		 * Returns the number of samples per second the animation clip curves were sampled at.
-		 *
-		 * @note	This value is not used by the animation clip or curves directly since unevenly spaced keyframes are
-		 *			supported. But it can be of value when determining the original sample rate of an imported animation
-		 *			or similar.
-		 */
+		/** @copydoc setSampleRate() */
+		BS_SCRIPT_EXPORT(n:SampleRate,pr:getter)
 		UINT32 getSampleRate() const { return mSampleRate; }
 
 		/** 
-		 * Sets the number of samples per second the animation clip curves were sampled at.
-		 *
-		 * @see	getSampleRate()
+		 * Number of samples per second the animation clip curves were sampled at. This value is not used by the animation
+		 * clip or curves directly since unevenly spaced keyframes are supported. But it can be of value when determining
+		 * the original sample rate of an imported animation or similar.
 		 */
+		BS_SCRIPT_EXPORT(n:SampleRate,pr:setter)
 		void setSampleRate(UINT32 sampleRate) { mSampleRate = sampleRate; }
 
 		/** 
@@ -212,6 +246,7 @@ namespace bs
 		 * Creates an animation clip with no curves. After creation make sure to register some animation curves before
 		 * using it. 
 		 */
+		BS_SCRIPT_EXPORT(ec:AnimationClip)
 		static HAnimationClip create(bool isAdditive = false);
 
 		/** 
@@ -225,6 +260,7 @@ namespace bs
 		 * @param[in]	rootMotion	Optional set of curves that can be used for animating the root bone. Not used by the
 		 *							animation system directly but is instead provided to the user for manual evaluation.
 		 */
+		BS_SCRIPT_EXPORT(ec:AnimationClip)
 		static HAnimationClip create(const SPtr<AnimationCurves>& curves, bool isAdditive = false, UINT32 sampleRate = 1, 
 			const SPtr<RootMotion>& rootMotion = nullptr);
 

+ 65 - 3
Source/BansheeCore/Include/BsAnimationCurve.h

@@ -4,6 +4,8 @@
 
 #include "BsCorePrerequisites.h"
 #include "BsCurveCache.h"
+#include "BsVector3.h"
+#include "BsQuaternion.h"
 
 namespace bs
 {
@@ -21,6 +23,10 @@ namespace bs
 		float time; /**< Position of the key along the animation spline. */
 	};
 
+	template struct BS_SCRIPT_EXPORT(m:Animation,n:KeyFrame,pl:true) TKeyframe<float>;
+	template struct BS_SCRIPT_EXPORT(m:Animation,n:KeyFrameVec3,pl:true) TKeyframe<Vector3>;
+	template struct BS_SCRIPT_EXPORT(m:Animation,n:KeyFrameQuat,pl:true) TKeyframe<Quaternion>;
+
 	/**
 	 * 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.
@@ -32,6 +38,13 @@ namespace bs
 		typedef TKeyframe<T> KeyFrame;
 
 		TAnimationCurve();
+
+		/**
+		 * Creates a new animation curve.
+		 * 
+		 * @param[in]	keyframes	Keyframes to initialize the curve with
+		 */
+		BS_SCRIPT_EXPORT()
 		TAnimationCurve(const Vector<KeyFrame>& keyframes);
 
 		/**
@@ -58,6 +71,7 @@ namespace bs
 		 *						value will be clamped.
 		 * @return				Interpolated value from the curve at provided time.
 		 */
+		BS_SCRIPT_EXPORT(n:Evaluate)
 		T evaluate(float time, bool loop = true) const;
 
 		/**
@@ -96,6 +110,10 @@ namespace bs
 		/** Returns a keyframe at the specified index. */
 		const TKeyframe<T>& getKeyFrame(UINT32 idx) const { return mKeyframes[idx]; }
 
+		/** Returns a list of all keyframes in the curve. */
+		BS_SCRIPT_EXPORT(n:KeyFrames,pr:getter)
+		const Vector<TKeyframe<T>>& getKeyFrames() const { return mKeyframes; }
+
 	private:
 		friend struct RTTIPlainType<TAnimationCurve<T>>;
 
@@ -154,10 +172,20 @@ namespace bs
 		float mLength;
 	};
 
-	/** Flags that described an TAnimationCurve<T>. */
-	enum class AnimationCurveFlag
+#ifdef BS_SBGEN
+	template class BS_SCRIPT_EXPORT(m:Animation,n:AnimationCurve) TAnimationCurve<float>;
+	template class BS_SCRIPT_EXPORT(m:Animation,n:Vector3Curve) TAnimationCurve<Vector3>;
+	template class BS_SCRIPT_EXPORT(m:Animation,n:QuaternionCurve) TAnimationCurve<Quaternion>;
+#endif
+
+	/** Flags that describe an animation curve. */
+	enum BS_SCRIPT_EXPORT(n:AnimationCurveFlags) class AnimationCurveFlag
 	{
-		/** Signifies that the curve was imported from an external file, and not created manually in-engine. */
+		/**
+		 * If enabled, the curve was imported from an external file and not created within the engine. This will affect
+		 * how are animation results applied to scene objects (with imported animations it is assumed the curve is
+		 * animating bones and with in-engine curves it is assumed the curve is animating scene objects).
+		 */
 		ImportedCurve = 1 << 0,
 		/** Signifies the curve is used to animate between different frames within a morph channel. In range [0, 1]. */
 		MorphFrame = 1 << 1,
@@ -172,10 +200,44 @@ namespace bs
 	template <class T>
 	struct TNamedAnimationCurve
 	{
+		TNamedAnimationCurve() { }
+
+		/**
+		 * Constructs a new named animation curve.
+		 * 
+		 * @param[in]	name	Name of the curve.
+		 * @param[in]	curve	Curve containing the animation data.
+		 */
+		TNamedAnimationCurve(const String& name, const TAnimationCurve<T> curve)
+			:name(name), curve(curve)
+		{ }
+
+		/**
+		 * Constructs a new named animation curve.
+		 * 
+		 * @param[in]	name	Name of the curve.
+		 * @param[in]	flags	Flags that describe the animation curve.
+		 * @param[in]	curve	Curve containing the animation data.
+		 */
+		TNamedAnimationCurve(const String& name, AnimationCurveFlags flags, const TAnimationCurve<T> curve)
+			:name(name), curve(curve)
+		{ }
+
+		/** Name of the curve. */
 		String name;
+
+		/** Flags that describe the animation curve. */
 		AnimationCurveFlags flags;
+
+		/** Actual curve containing animation data. */
 		TAnimationCurve<T> curve;
 	};
 
+#ifdef BS_SBGEN
+	template class BS_SCRIPT_EXPORT(m:Animation,n:NamedFloatCurve,pl:true) TNamedAnimationCurve<float>;
+	template class BS_SCRIPT_EXPORT(m:Animation,n:NamedVector3Curve,pl:true) TNamedAnimationCurve<Vector3>;
+	template class BS_SCRIPT_EXPORT(m:Animation,n:NamedQuaternionCurve,pl:true) TNamedAnimationCurve<Quaternion>;
+#endif
+
 	/** @} */
 }

+ 13 - 3
Source/BansheeCore/Include/BsAnimationUtility.h

@@ -12,7 +12,7 @@ namespace bs
 	 */
 
 	/** Helper class for dealing with animations, animation clips and curves. */
-	class BS_CORE_EXPORT AnimationUtility
+	class BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Animation) AnimationUtility
 	{
 	public:
 		/**
@@ -26,10 +26,20 @@ namespace bs
 		static void wrapTime(float& time, float start, float end, bool loop);
 
 		/** Converts a curve in euler angles (in degrees) into a curve using quaternions. */
-		static TAnimationCurve<Quaternion> eulerToQuaternionCurve(const TAnimationCurve<Vector3>& eulerCurve);
+		BS_SCRIPT_EXPORT(n:EulerToQuaternionCurve)
+		static SPtr<TAnimationCurve<Quaternion>> eulerToQuaternionCurve(const SPtr<TAnimationCurve<Vector3>>& eulerCurve);
 
 		/** Converts a curve in quaternions into a curve using euler angles (in degrees). */
-		static TAnimationCurve<Vector3> quaternionToEulerCurve(const TAnimationCurve<Quaternion>& quatCurve);
+		BS_SCRIPT_EXPORT(n:QuaternionToEulerCurve)
+		static SPtr<TAnimationCurve<Vector3>> quaternionToEulerCurve(const SPtr<TAnimationCurve<Quaternion>>& quatCurve);
+
+		/** Splits a Vector3 curve into three individual curves, one for each component. */
+		BS_SCRIPT_EXPORT(n:SplitCurve)
+		static Vector<SPtr<TAnimationCurve<float>>> splitCurve(const SPtr<TAnimationCurve<Vector3>>& compoundCurve);
+
+		/** Combines three single component curves into a Vector3 curve. */
+		BS_SCRIPT_EXPORT(n:CombineCurve)
+		static SPtr<TAnimationCurve<Vector3>> combineCurve(const Vector<SPtr<TAnimationCurve<float>>>& curveComponents);
 
 		/** Scales all curve values and tangents by the specified scale factor. */
 		template<class T> 

+ 0 - 1
Source/BansheeCore/Source/BsAnimationClip.cpp

@@ -7,7 +7,6 @@
 
 namespace bs
 {
-
 	void AnimationCurves::addPositionCurve(const String& name, const TAnimationCurve<Vector3>& curve)
 	{
 		auto iterFind = std::find_if(position.begin(), position.end(), [&](auto x) { return x.name == name; });

+ 3 - 3
Source/BansheeCore/Source/BsAnimationCurve.cpp

@@ -525,7 +525,7 @@ namespace bs
 			mKeyframes[i].value = getDiff(mKeyframes[i].value, refKey.value);
 	}
 
-	template class TAnimationCurve<Vector3>;
-	template class TAnimationCurve<Quaternion>;
-	template class TAnimationCurve<float>;
+	template BS_CORE_EXPORT class TAnimationCurve<Vector3>;
+	template BS_CORE_EXPORT class TAnimationCurve<Quaternion>;
+	template BS_CORE_EXPORT class TAnimationCurve<float>;
 }

+ 108 - 18
Source/BansheeCore/Source/BsAnimationUtility.cpp

@@ -66,7 +66,7 @@ namespace bs
 		}
 	}
 
-	TAnimationCurve<Quaternion> AnimationUtility::eulerToQuaternionCurve(const TAnimationCurve<Vector3>& eulerCurve)
+	SPtr<TAnimationCurve<Quaternion>> AnimationUtility::eulerToQuaternionCurve(const SPtr<TAnimationCurve<Vector3>>& eulerCurve)
 	{
 		// TODO: We calculate tangents by sampling which can introduce error in the tangents. The error can be exacerbated
 		// by the fact we constantly switch between the two representations, possibly losing precision every time. Instead 
@@ -103,15 +103,15 @@ namespace bs
 			return quat;
 		};
 
-		INT32 numKeys = (INT32)eulerCurve.getNumKeyFrames();
+		INT32 numKeys = (INT32)eulerCurve->getNumKeyFrames();
 		Vector<TKeyframe<Quaternion>> quatKeyframes(numKeys);
 
 		// Calculate key values
 		Quaternion lastQuat(BsZero);
 		for (INT32 i = 0; i < numKeys; i++)
 		{
-			float time = eulerCurve.getKeyFrame(i).time;
-			Vector3 angles = eulerCurve.getKeyFrame(i).value;
+			float time = eulerCurve->getKeyFrame(i).time;
+			Vector3 angles = eulerCurve->getKeyFrame(i).value;
 			Quaternion quat = eulerToQuaternion(i, angles, lastQuat);
 
 			quatKeyframes[i].time = time;
@@ -129,15 +129,15 @@ namespace bs
 			TKeyframe<Quaternion>& currentKey = quatKeyframes[i];
 			TKeyframe<Quaternion>& nextKey = quatKeyframes[i + 1];
 
-			const TKeyframe<Vector3>& currentEulerKey = eulerCurve.getKeyFrame(i);
-			const TKeyframe<Vector3>& nextEulerKey = eulerCurve.getKeyFrame(i + 1);
+			const TKeyframe<Vector3>& currentEulerKey = eulerCurve->getKeyFrame(i);
+			const TKeyframe<Vector3>& nextEulerKey = eulerCurve->getKeyFrame(i + 1);
 
 			float dt = nextKey.time - currentKey.time;
 			float startFitTime = currentKey.time + dt * FIT_TIME;
 			float endFitTime = currentKey.time + dt * (1.0f - FIT_TIME);
 
-			Vector3 anglesStart = eulerCurve.evaluate(startFitTime, false);
-			Vector3 anglesEnd = eulerCurve.evaluate(endFitTime, false);
+			Vector3 anglesStart = eulerCurve->evaluate(startFitTime, false);
+			Vector3 anglesEnd = eulerCurve->evaluate(endFitTime, false);
 			Quaternion startFitValue = eulerToQuaternion(i, anglesStart, currentKey.value);
 			Quaternion endFitValue = eulerToQuaternion(i, anglesEnd, startFitValue);
 
@@ -148,10 +148,10 @@ namespace bs
 			setStepTangent(currentEulerKey, nextEulerKey, currentKey, nextKey);
 		}
 
-		return TAnimationCurve<Quaternion>(quatKeyframes);
+		return bs_shared_ptr_new<TAnimationCurve<Quaternion>>(quatKeyframes);
 	}
 
-	TAnimationCurve<Vector3> AnimationUtility::quaternionToEulerCurve(const TAnimationCurve<Quaternion>& quatCurve)
+	SPtr<TAnimationCurve<Vector3>> AnimationUtility::quaternionToEulerCurve(const SPtr<TAnimationCurve<Quaternion>>& quatCurve)
 	{
 		// TODO: We calculate tangents by sampling. There must be an analytical way to calculate tangents when converting
 		// a curve.
@@ -171,14 +171,14 @@ namespace bs
 			return euler;
 		};
 
-		INT32 numKeys = (INT32)quatCurve.getNumKeyFrames();
+		INT32 numKeys = (INT32)quatCurve->getNumKeyFrames();
 		Vector<TKeyframe<Vector3>> eulerKeyframes(numKeys);
 
 		// Calculate key values
 		for (INT32 i = 0; i < numKeys; i++)
 		{
-			float time = quatCurve.getKeyFrame(i).time;
-			Quaternion quat = quatCurve.getKeyFrame(i).value;
+			float time = quatCurve->getKeyFrame(i).time;
+			Quaternion quat = quatCurve->getKeyFrame(i).value;
 			Vector3 euler = quaternionToEuler(quat);
 
 			eulerKeyframes[i].time = time;
@@ -194,15 +194,15 @@ namespace bs
 			TKeyframe<Vector3>& currentKey = eulerKeyframes[i];
 			TKeyframe<Vector3>& nextKey = eulerKeyframes[i + 1];
 
-			const TKeyframe<Quaternion>& currentQuatKey = quatCurve.getKeyFrame(i);
-			const TKeyframe<Quaternion>& nextQuatKey = quatCurve.getKeyFrame(i + 1);
+			const TKeyframe<Quaternion>& currentQuatKey = quatCurve->getKeyFrame(i);
+			const TKeyframe<Quaternion>& nextQuatKey = quatCurve->getKeyFrame(i + 1);
 
 			float dt = nextKey.time - currentKey.time;
 			float startFitTime = currentKey.time + dt * FIT_TIME;
 			float endFitTime = currentKey.time + dt * (1.0f - FIT_TIME);
 
-			Quaternion startQuat = Quaternion::normalize(quatCurve.evaluate(startFitTime, false));
-			Quaternion endQuat = Quaternion::normalize(quatCurve.evaluate(endFitTime, false));
+			Quaternion startQuat = Quaternion::normalize(quatCurve->evaluate(startFitTime, false));
+			Quaternion endQuat = Quaternion::normalize(quatCurve->evaluate(endFitTime, false));
 			Vector3 startFitValue = quaternionToEuler(startQuat);
 			Vector3 endFitValue = quaternionToEuler(endQuat);
 
@@ -220,7 +220,97 @@ namespace bs
 			setStepTangent(currentQuatKey, nextQuatKey, currentKey, nextKey);
 		}
 
-		return TAnimationCurve<Vector3>(eulerKeyframes);
+		return bs_shared_ptr_new<TAnimationCurve<Vector3>>(eulerKeyframes);
+	}
+
+	Vector<SPtr<TAnimationCurve<float>>> AnimationUtility::splitCurve(const SPtr<TAnimationCurve<Vector3>>& compoundCurve)
+	{
+		UINT32 numKeyFrames = compoundCurve->getNumKeyFrames();
+		Vector<TKeyframe<float>> keyFrames[3];
+
+		for (UINT32 i = 0; i < numKeyFrames; i++)
+		{
+			const TKeyframe<Vector3>& key = compoundCurve->getKeyFrame(i);
+
+			TKeyframe<float> newKey;
+			newKey.time = key.time;
+
+			for (UINT32 j = 0; j < 3; j++)
+			{
+				bool addNew = true;
+				if (i > 0)
+				{
+					const TKeyframe<float>& prevKey = keyFrames[j].back();
+
+					bool isEqual = Math::approxEquals(prevKey.value, key.value[j]) &&
+						Math::approxEquals(prevKey.outTangent, key.inTangent[j]);
+
+					addNew = !isEqual;
+				}
+
+				if (addNew)
+				{
+					newKey.value = key.value[j];
+					newKey.inTangent = key.inTangent[j];
+					newKey.outTangent = key.outTangent[j];
+
+					keyFrames[j].push_back(newKey);
+				}
+			}
+		}
+
+		Vector<SPtr<TAnimationCurve<float>>> output(3);
+		for (UINT32 i = 0; i < 3; i++)
+			output[i] = bs_shared_ptr_new<TAnimationCurve<float>>(keyFrames[i]);
+
+		return output;
+	}
+
+	SPtr<TAnimationCurve<Vector3>> AnimationUtility::combineCurve(const Vector<SPtr<TAnimationCurve<float>>>& curveComponents)
+	{
+		// Find unique keyframe times
+		Map<float, TKeyframe<Vector3>> keyFrames;
+		for(UINT32 i = 0; i < 3; i++)
+		{
+			if (i >= (UINT32)curveComponents.size())
+				break;
+
+			UINT32 numKeyFrames = curveComponents[i]->getNumKeyFrames();
+			for (UINT32 j = 0; j < numKeyFrames; j++)
+			{
+				const TKeyframe<float>& keyFrame = curveComponents[i]->getKeyFrame(j);
+
+				auto iterFind = keyFrames.find(keyFrame.time);
+				if (iterFind == keyFrames.end())
+				{
+					TKeyframe<Vector3> newKeyFrame;
+					newKeyFrame.time = keyFrame.time;
+
+					keyFrames.insert(std::make_pair(keyFrame.time, newKeyFrame));
+				}
+			}
+		}
+
+		// Populate keyframe values
+		Vector<TKeyframe<Vector3>> keyframeList(keyFrames.size());
+		UINT32 idx = 0;
+		for(auto& entry : keyFrames)
+		{
+			TKeyframe<Vector3>& keyFrame = entry.second;
+			
+			for(UINT32 j = 0; j < 3; j++)
+			{
+				TKeyframe<float> currentKey = curveComponents[j]->evaluateKey(keyFrame.time, false);
+				keyFrame.value[j] = currentKey.value;
+				keyFrame.inTangent[j] = currentKey.inTangent;
+				keyFrame.outTangent[j] = currentKey.outTangent;
+			}
+
+			keyframeList[idx] = keyFrame;
+			idx++;
+		}
+
+		return bs_shared_ptr_new<TAnimationCurve<Vector3>>(keyframeList);
 	}
 
 	template<class T>

+ 5 - 2
Source/BansheeCore/Source/BsMaterialRTTI.cpp

@@ -16,8 +16,11 @@ namespace bs
 
 		material->initializeTechniques();
 
-		SPtr<MaterialParams> matParams = any_cast<SPtr<MaterialParams>>(material->mRTTIData);
-		material->setParams(matParams);
+		if (material->getNumTechniques() > 0)
+		{
+			SPtr<MaterialParams> matParams = any_cast<SPtr<MaterialParams>>(material->mRTTIData);
+			material->setParams(matParams);
+		}
 
 		material->mRTTIData = nullptr; // Delete temporary data
 	}

+ 5 - 5
Source/BansheeFBXImporter/Source/BsFBXImporter.cpp

@@ -1774,13 +1774,13 @@ namespace bs
 				boneAnim.scale = TAnimationCurve<Vector3>(keyframes);
 			}
 
-			TAnimationCurve<Vector3> eulerAnimation;
+			SPtr<TAnimationCurve<Vector3>> eulerAnimation = bs_shared_ptr_new<TAnimationCurve<Vector3>>();
 			if (hasCurveValues(rotation))
 			{
 				float defaultValues[3];
 				memcpy(defaultValues, &defaultRotation, sizeof(defaultValues));
 
-				eulerAnimation = importCurve<Vector3, 3>(rotation, defaultValues, importOptions, clip.start, clip.end);
+				*eulerAnimation = importCurve<Vector3, 3>(rotation, defaultValues, importOptions, clip.start, clip.end);
 			}
 			else
 			{
@@ -1789,18 +1789,18 @@ namespace bs
 				keyframes[0].inTangent = Vector3::ZERO;
 				keyframes[0].outTangent = Vector3::ZERO;
 
-				eulerAnimation = TAnimationCurve<Vector3>(keyframes);
+				*eulerAnimation = TAnimationCurve<Vector3>(keyframes);
 			}
 
 			if(importOptions.reduceKeyframes)
 			{
 				boneAnim.translation = reduceKeyframes(boneAnim.translation);
 				boneAnim.scale = reduceKeyframes(boneAnim.scale);
-				eulerAnimation = reduceKeyframes(eulerAnimation);
+				*eulerAnimation = reduceKeyframes(*eulerAnimation);
 			}
 
 			boneAnim.translation = AnimationUtility::scaleCurve(boneAnim.translation, importScene.scaleFactor);
-			boneAnim.rotation = AnimationUtility::eulerToQuaternionCurve(eulerAnimation);
+			boneAnim.rotation = *AnimationUtility::eulerToQuaternionCurve(eulerAnimation);
 		}
 
 		if (importOptions.importBlendShapes)

+ 1 - 0
Source/CMake/GenerateScriptBindings.cmake

@@ -73,6 +73,7 @@ if(BansheeSBGen_FOUND)
 			-output-cs-editor ${BS_GENERATED_CS_EDITOR_OUTPUT_DIR}
 			-- ${BS_INCLUDE_DIRS}
 			-DBS_STATIC_LIB
+			-DBS_SBGEN
 			-w)
 
 		message(STATUS "Generating script bindings, please wait...")

+ 2 - 1
Source/MBansheeEditor/Utility/EdAnimationCurve.cs

@@ -342,7 +342,8 @@ namespace BansheeEditor
             });
 
             UpdateTangents();
-            native.KeyFrames = keyFrames;
+
+            native = new AnimationCurve(keyFrames);
         }
 
         /// <summary>

+ 45 - 23
Source/MBansheeEditor/Windows/Animation/EditorAnimInfo.cs

@@ -130,7 +130,7 @@ namespace BansheeEditor
                         {
                             foreach (var tangentEntry in tangents)
                             {
-                                if (tangentEntry.name == curveEntry.Name)
+                                if (tangentEntry.name == curveEntry.name)
                                 {
                                     tangentsX = tangentEntry.tangentsX;
                                     tangentsY = tangentEntry.tangentsY;
@@ -140,39 +140,53 @@ namespace BansheeEditor
                             }
                         }
 
+                        // Convert compound curve to three per-component curves
+                        AnimationCurve[] componentCurves = AnimationUtility.SplitCurve(curveEntry.curve);
+
                         FieldAnimCurves fieldCurves = new FieldAnimCurves();
                         fieldCurves.type = SerializableProperty.FieldType.Vector3;
                         fieldCurves.curveInfos = new CurveDrawInfo[3];
                         fieldCurves.isPropertyCurve = !clipInfo.isImported;
 
                         fieldCurves.curveInfos[0] = new CurveDrawInfo();
-                        fieldCurves.curveInfos[0].curve = new EdAnimationCurve(curveEntry.X, tangentsX);
+                        fieldCurves.curveInfos[0].curve = new EdAnimationCurve(componentCurves[0], tangentsX);
                         fieldCurves.curveInfos[0].color = GUICurveDrawing.GetUniqueColor(globalCurveIdx++);
 
                         fieldCurves.curveInfos[1] = new CurveDrawInfo();
-                        fieldCurves.curveInfos[1].curve = new EdAnimationCurve(curveEntry.Y, tangentsY);
+                        fieldCurves.curveInfos[1].curve = new EdAnimationCurve(componentCurves[1], tangentsY);
                         fieldCurves.curveInfos[1].color = GUICurveDrawing.GetUniqueColor(globalCurveIdx++);
 
                         fieldCurves.curveInfos[2] = new CurveDrawInfo();
-                        fieldCurves.curveInfos[2].curve = new EdAnimationCurve(curveEntry.Z, tangentsZ);
+                        fieldCurves.curveInfos[2].curve = new EdAnimationCurve(componentCurves[2], tangentsZ);
                         fieldCurves.curveInfos[2].color = GUICurveDrawing.GetUniqueColor(globalCurveIdx++);
 
-                        string curvePath = curveEntry.Name.TrimEnd('/') + subPath;
+                        string curvePath = curveEntry.name.TrimEnd('/') + subPath;
                         clipInfo.curves[curvePath] = fieldCurves;
                     }
                 };
 
-            loadVector3Curve(clipCurves.PositionCurves, editorCurveData.positionCurves, "/Position");
-            loadVector3Curve(clipCurves.RotationCurves, editorCurveData.rotationCurves, "/Rotation");
-            loadVector3Curve(clipCurves.ScaleCurves, editorCurveData.scaleCurves, "/Scale");
+            // Convert rotation from quaternion to euler
+            NamedQuaternionCurve[] rotationCurves = clipCurves.Rotation;
+            NamedVector3Curve[] eulerRotationCurves = new NamedVector3Curve[rotationCurves.Length];
+            for(int i = 0; i < rotationCurves.Length; i++)
+            {
+                eulerRotationCurves[i] = new NamedVector3Curve();
+                eulerRotationCurves[i].name = rotationCurves[i].name;
+                eulerRotationCurves[i].flags = rotationCurves[i].flags;
+                eulerRotationCurves[i].curve = AnimationUtility.QuaternionToEulerCurve(rotationCurves[i].curve);
+            }
+
+            loadVector3Curve(clipCurves.Position, editorCurveData.positionCurves, "/Position");
+            loadVector3Curve(eulerRotationCurves, editorCurveData.rotationCurves, "/Rotation");
+            loadVector3Curve(clipCurves.Scale, editorCurveData.scaleCurves, "/Scale");
 
             // Find which individual float curves belong to the same field
             Dictionary<string, Tuple<int, int, bool>[]> floatCurveMapping = new Dictionary<string, Tuple<int, int, bool>[]>();
             {
                 int curveIdx = 0;
-                foreach (var curveEntry in clipCurves.FloatCurves)
+                foreach (var curveEntry in clipCurves.Generic)
                 {
-                    string path = curveEntry.Name;
+                    string path = curveEntry.name;
                     string pathNoSuffix = null;
 
                     string pathSuffix;
@@ -188,7 +202,7 @@ namespace BansheeEditor
                     int currentTangentIdx = 0;
                     foreach (var tangentEntry in editorCurveData.floatCurves)
                     {
-                        if (tangentEntry.name == curveEntry.Name)
+                        if (tangentEntry.name == curveEntry.name)
                         {
                             tangentIdx = currentTangentIdx;
                             break;
@@ -265,15 +279,15 @@ namespace BansheeEditor
                         tangents = editorCurveData.floatCurves[tangentIdx].tangents;
 
                     fieldCurves.curveInfos[i] = new CurveDrawInfo();
-                    fieldCurves.curveInfos[i].curve = new EdAnimationCurve(clipCurves.FloatCurves[curveIdx].Curve, tangents);
+                    fieldCurves.curveInfos[i].curve = new EdAnimationCurve(clipCurves.Generic[curveIdx].curve, tangents);
                     fieldCurves.curveInfos[i].color = GUICurveDrawing.GetUniqueColor(globalCurveIdx++);
 
-                    if (clipCurves.FloatCurves[curveIdx].Flags.HasFlag(AnimationCurveFlags.MorphFrame))
+                    if (clipCurves.Generic[curveIdx].flags.HasFlag(AnimationCurveFlags.MorphFrame))
                     {
                         curvePath = "MorphShapes/Frames/" + KVP.Key;
                         isMorphCurve = true;
                     }
-                    else if (clipCurves.FloatCurves[curveIdx].Flags.HasFlag(AnimationCurveFlags.MorphWeight))
+                    else if (clipCurves.Generic[curveIdx].flags.HasFlag(AnimationCurveFlags.MorphWeight))
                     {
                         curvePath = "MorphShapes/Weight/" + KVP.Key;
                         isMorphCurve = true;
@@ -338,7 +352,7 @@ namespace BansheeEditor
             }
 
             List<NamedVector3Curve> positionCurves = new List<NamedVector3Curve>();
-            List<NamedVector3Curve> rotationCurves = new List<NamedVector3Curve>();
+            List<NamedQuaternionCurve> rotationCurves = new List<NamedQuaternionCurve>();
             List<NamedVector3Curve> scaleCurves = new List<NamedVector3Curve>();
             List<NamedFloatCurve> floatCurves = new List<NamedFloatCurve>();
 
@@ -366,10 +380,14 @@ namespace BansheeEditor
 
                     string curvePath = sb.ToString();
 
-                    NamedVector3Curve curve = new NamedVector3Curve(curvePath,
+                    NamedVector3Curve curve = new NamedVector3Curve();
+                    curve.name = curvePath;
+                    curve.curve = AnimationUtility.CombineCurve(new[]
+                    {
                         new AnimationCurve(kvp.Value.curveInfos[0].curve.KeyFrames),
                         new AnimationCurve(kvp.Value.curveInfos[1].curve.KeyFrames),
-                        new AnimationCurve(kvp.Value.curveInfos[2].curve.KeyFrames));
+                        new AnimationCurve(kvp.Value.curveInfos[1].curve.KeyFrames)
+                    });
 
                     EditorVector3CurveTangents curveTangents = new EditorVector3CurveTangents();
                     curveTangents.name = curvePath;
@@ -384,7 +402,11 @@ namespace BansheeEditor
                     }
                     else if (lastEntry == "Rotation")
                     {
-                        rotationCurves.Add(curve);
+                        NamedQuaternionCurve quatCurve = new NamedQuaternionCurve();
+                        quatCurve.name = curve.name;
+                        quatCurve.curve = AnimationUtility.EulerToQuaternionCurve(curve.curve);
+
+                        rotationCurves.Add(quatCurve);
                         rotationTangents.Add(curveTangents);
                     }
                     else if (lastEntry == "Scale")
@@ -401,7 +423,7 @@ namespace BansheeEditor
 
                         NamedFloatCurve curve = new NamedFloatCurve(fullPath,
                             new AnimationCurve(kvp.Value.curveInfos[idx].curve.KeyFrames));
-                        curve.Flags = flags;
+                        curve.flags = flags;
 
                         EditorFloatCurveTangents curveTangents = new EditorFloatCurveTangents();
                         curveTangents.name = fullPath;
@@ -464,10 +486,10 @@ namespace BansheeEditor
             }
 
             AnimationCurves newClipCurves = new AnimationCurves();
-            newClipCurves.PositionCurves = positionCurves.ToArray();
-            newClipCurves.RotationCurves = rotationCurves.ToArray();
-            newClipCurves.ScaleCurves = scaleCurves.ToArray();
-            newClipCurves.FloatCurves = floatCurves.ToArray();
+            newClipCurves.Position = positionCurves.ToArray();
+            newClipCurves.Rotation = rotationCurves.ToArray();
+            newClipCurves.Scale = scaleCurves.ToArray();
+            newClipCurves.Generic = floatCurves.ToArray();
 
             clip.Curves = newClipCurves;
             clip.Events = events;

+ 2 - 2
Source/MBansheeEditor/Windows/Animation/GUIAnimEvents.cs

@@ -53,7 +53,7 @@ namespace BansheeEditor
             {
                 AnimationEvent evnt = events[i];
 
-                int xPos = (int)(((evnt.Time - rangeOffset) / GetRange()) * drawableWidth) + PADDING;
+                int xPos = (int)(((evnt.time - rangeOffset) / GetRange()) * drawableWidth) + PADDING;
                 if (relativeCoords.x >= (xPos - EVENT_HALF_WIDTH) && relativeCoords.x <= (xPos + EVENT_HALF_WIDTH))
                 {
                     eventIdx = i;
@@ -122,7 +122,7 @@ namespace BansheeEditor
             float eventHalfWidth = lengthPerPixel * EVENT_HALF_WIDTH;
             for (int i = 0; i < events.Length; i++)
             {
-                float t = events[i].Time;
+                float t = events[i].time;
 
                 float min = t - eventHalfWidth;
                 float max = t + eventHalfWidth;

+ 7 - 7
Source/MBansheeEditor/Windows/Animation/GUICurveEditor.cs

@@ -1114,7 +1114,7 @@ namespace BansheeEditor
             AnimationEvent animEvent = events[eventIdx].animEvent;
 
             Vector2I position = new Vector2I();
-            position.x = guiEvents.GetOffset(animEvent.Time);
+            position.x = guiEvents.GetOffset(animEvent.time);
             position.y = EVENTS_HEIGHT/2;
 
             Rect2I eventBounds = GUIUtility.CalculateBounds(eventsPanel, window.GUI);
@@ -1227,9 +1227,9 @@ namespace BansheeEditor
         {
             int selectedIndex = -1;
             string methodName = "";
-            if (!string.IsNullOrEmpty(animEvent.Name))
+            if (!string.IsNullOrEmpty(animEvent.name))
             {
-                string[] nameEntries = animEvent.Name.Split('/');
+                string[] nameEntries = animEvent.name.Split('/');
                 if (nameEntries.Length > 1)
                 {
                     string typeName = nameEntries[0];
@@ -1247,8 +1247,8 @@ namespace BansheeEditor
             }
 
             GUIFloatField timeField = new GUIFloatField(new LocEdString("Time"), 40, "");
-            timeField.Value = animEvent.Time;
-            timeField.OnChanged += x => { animEvent.Time = x; changesMade = true; updateCallback(); };
+            timeField.Value = animEvent.time;
+            timeField.OnChanged += x => { animEvent.time = x; changesMade = true; updateCallback(); };
 
             GUIListBoxField componentField = new GUIListBoxField(componentNames, new LocEdString("Component"), 40);
             if (selectedIndex != -1)
@@ -1260,7 +1260,7 @@ namespace BansheeEditor
                 if (x != -1)
                     compName = componentNames[x] + "/";
 
-                animEvent.Name = compName + x;
+                animEvent.name = compName + x;
 
                 changesMade = true;
                 updateCallback();
@@ -1274,7 +1274,7 @@ namespace BansheeEditor
                 if(componentField.Index != -1)
                     compName = componentNames[componentField.Index] + "/";
 
-                animEvent.Name = compName + x;
+                animEvent.name = compName + x;
 
                 changesMade = true;
                 updateCallback();

+ 4 - 8
Source/MBansheeEditor/Windows/AnimationWindow.cs

@@ -861,7 +861,7 @@ namespace BansheeEditor
 
             clipState.events = new AnimationEvent[clipInfo.events.Length];
             for (int i = 0; i < clipState.events.Length; i++)
-                clipState.events[i] = new AnimationEvent(clipInfo.events[i].Name, clipInfo.events[i].Time);
+                clipState.events[i] = new AnimationEvent(clipInfo.events[i].name, clipInfo.events[i].time);
 
             foreach (var curveField in clipInfo.curves)
             {
@@ -901,7 +901,7 @@ namespace BansheeEditor
             AnimationEvent[] events = animationClipState.events;
             clipInfo.events = new AnimationEvent[events.Length];
             for(int i = 0; i < events.Length; i++)
-                clipInfo.events[i] = new AnimationEvent(events[i].Name, events[i].Time);
+                clipInfo.events[i] = new AnimationEvent(events[i].name, events[i].time);
 
             foreach (var KVP in animationClipState.curves)
             {
@@ -911,9 +911,7 @@ namespace BansheeEditor
 
                 for (int i = 0; i < fieldCurves.curveInfos.Length; i++)
                 {
-                    AnimationCurve curve = fieldCurves.curveInfos[i].curve.Normal;
-                    curve.KeyFrames = KVP.Value[i].keyFrames;
-
+                    AnimationCurve curve = new AnimationCurve(KVP.Value[i].keyFrames);
                     fieldCurves.curveInfos[i].curve = new EdAnimationCurve(curve, KVP.Value[i].tangentModes);
                 }
 
@@ -939,9 +937,7 @@ namespace BansheeEditor
                 FieldAnimCurves fieldCurves = currentKVP.Value;
                 for (int i = 0; i < fieldCurves.curveInfos.Length; i++)
                 {
-                    AnimationCurve curve = currentKVP.Value.curveInfos[i].curve.Normal;
-                    curve.KeyFrames = new KeyFrame[0];
-
+                    AnimationCurve curve = new AnimationCurve(new KeyFrame[0]);
                     fieldCurves.curveInfos[i].curve = new EdAnimationCurve(curve, new TangentMode[0]);
                 }
             }

+ 33 - 28
Source/MBansheeEngine/Animation/Animation.cs

@@ -874,42 +874,47 @@ namespace BansheeEngine
             {
                 SceneObject root = SceneObject;
 
-                Action<NamedVector3Curve[]> findMappings = x =>
+                Action<string,AnimationCurveFlags> findMappings = (name, flags) =>
                 {
-                    foreach (var curve in x)
-                    {
-                        if (curve.Flags.HasFlag(AnimationCurveFlags.ImportedCurve))
-                            continue;
+                    if (flags.HasFlag(AnimationCurveFlags.ImportedCurve))
+                        return;
 
-                        SceneObject currentSO = FindSceneObject(root, curve.Name);
+                    SceneObject currentSO = FindSceneObject(root, name);
 
-                        bool found = false;
-                        for (int i = 0; i < newMappingInfos.Count; i++)
+                    bool found = false;
+                    for (int i = 0; i < newMappingInfos.Count; i++)
+                    {
+                        if (newMappingInfos[i].sceneObject == currentSO)
                         {
-                            if (newMappingInfos[i].sceneObject == currentSO)
-                            {
-                                found = true;
-                                break;
-                            }
+                            found = true;
+                            break;
                         }
+                    }
 
-                        if (!found)
-                        {
-                            SceneObjectMappingInfo newMappingInfo = new SceneObjectMappingInfo();
-                            newMappingInfo.isMappedToBone = false;
-                            newMappingInfo.sceneObject = currentSO;
+                    if (!found)
+                    {
+                        SceneObjectMappingInfo newMappingInfo = new SceneObjectMappingInfo();
+                        newMappingInfo.isMappedToBone = false;
+                        newMappingInfo.sceneObject = currentSO;
 
-                            newMappingInfos.Add(newMappingInfo);
+                        newMappingInfos.Add(newMappingInfo);
 
-                            _native.MapCurveToSceneObject(curve.Name, currentSO);
-                        }
+                        _native.MapCurveToSceneObject(name, currentSO);
                     }
                 };
 
                 AnimationCurves curves = primaryClip.Curves;
-                findMappings(curves.PositionCurves);
-                findMappings(curves.RotationCurves);
-                findMappings(curves.ScaleCurves);
+                NamedVector3Curve[] posCurves = curves.Position;
+                foreach (var curve in posCurves)
+                    findMappings(curve.name, curve.flags);
+
+                NamedQuaternionCurve[] rotCurves = curves.Rotation;
+                foreach (var curve in rotCurves)
+                    findMappings(curve.name, curve.flags);
+
+                NamedVector3Curve[] scaleCurves = curves.Scale;
+                foreach (var curve in scaleCurves)
+                    findMappings(curve.name, curve.flags);
             }
 
             mappingInfo = newMappingInfos;
@@ -1119,16 +1124,16 @@ namespace BansheeEngine
             AnimationCurves curves = clip.Curves;
 
             List<FloatCurvePropertyInfo> newFloatProperties = new List<FloatCurvePropertyInfo>();
-            for (int i = 0; i < curves.FloatCurves.Length; i++)
+            for (int i = 0; i < curves.Generic.Length; i++)
             {
-                bool isMorphCurve = curves.FloatCurves[i].Flags.HasFlag(AnimationCurveFlags.MorphWeight) ||
-                                    curves.FloatCurves[i].Flags.HasFlag(AnimationCurveFlags.MorphFrame);
+                bool isMorphCurve = curves.Generic[i].flags.HasFlag(AnimationCurveFlags.MorphWeight) ||
+                                    curves.Generic[i].flags.HasFlag(AnimationCurveFlags.MorphFrame);
 
                 if (isMorphCurve)
                     continue;
 
                 string suffix;
-                SerializableProperty property = FindProperty(SceneObject, curves.FloatCurves[i].Name, out suffix);
+                SerializableProperty property = FindProperty(SceneObject, curves.Generic[i].name, out suffix);
                 if (property == null)
                     continue;
 

+ 0 - 149
Source/MBansheeEngine/Animation/AnimationClip.cs

@@ -1,149 +0,0 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-using System;
-using System.Runtime.CompilerServices;
-
-namespace BansheeEngine
-{
-    /** @addtogroup Animation
-     *  @{
-     */
-
-    /// <summary>
-    /// Contains animation curves for translation/rotation/scale of scene object/skeleton bones, as well as curves for
-    /// generic property animation.
-    /// </summary>
-    public class AnimationClip : Resource
-    {
-        // Constructor for runtime use only (dummy parameter to differentiate from the normal constructor)
-        private AnimationClip(bool dummy)
-        { }
-
-        /// <summary>
-        /// Creates a new animation clip with no curves or events.
-        /// </summary>
-        public AnimationClip()
-        {
-            Internal_CreateInstance(this);
-        }
-
-        /// <summary>
-        /// Returns the length of the animation clip, in seconds.
-        /// </summary>
-        public float Length
-        {
-            get { return Internal_GetLength(mCachedPtr); }
-        }
-
-        /// <summary>
-        /// Returns the number of samples per second the animation clip curves were sampled at. This value is not used by
-        /// the animation clip or curves directly since unevenly spaced keyframes are supported. But it can be of value when
-        /// determining the original sample rate of an imported animation or similar.
-        /// </summary>
-        public int SampleRate
-        {
-            get { return Internal_GetSampleRate(mCachedPtr); }
-            set { Internal_SetSampleRate(mCachedPtr, value); }
-        }
-
-        /// <summary>
-        /// A set of all curves stored in the animation clip.
-        /// </summary>
-        public AnimationCurves Curves
-        {
-            get { return Internal_GetAnimationCurves(mCachedPtr); }
-            set { Internal_SetAnimationCurves(mCachedPtr, value); }
-        }
-
-        /// <summary>
-        /// A set of all events stored in the animation clip.
-        /// </summary>
-        public AnimationEvent[] Events
-        {
-            get { return Internal_GetAnimationEvents(mCachedPtr); }
-            set { Internal_SetAnimationEvents(mCachedPtr, value); }
-        }
-
-        /// <summary>
-        /// Returns a set of curves containing motion of the root bone. This allows the user to evaluate the root bone
-        /// animation curves manually, instead of through the normal animation process. This property is only available
-        /// if animation clip was imported with root motion import enabled.
-        /// </summary>
-        public RootMotion RootMotion
-        {
-            get { return Internal_GetRootMotion(mCachedPtr); }
-        }
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_CreateInstance(AnimationClip instance);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern AnimationCurves Internal_GetAnimationCurves(IntPtr thisPtr);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_SetAnimationCurves(IntPtr thisPtr, AnimationCurves curves);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern AnimationEvent[] Internal_GetAnimationEvents(IntPtr thisPtr);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_SetAnimationEvents(IntPtr thisPtr, AnimationEvent[] events);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern RootMotion Internal_GetRootMotion(IntPtr thisPtr);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern float Internal_GetLength(IntPtr thisPtr);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern int Internal_GetSampleRate(IntPtr thisPtr);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_SetSampleRate(IntPtr thisPtr, int sampleRate);
-    }
-
-    /// <summary>
-    /// Event that is triggered when animation reaches a certain point.
-    /// </summary>
-    public class AnimationEvent
-    {
-        /// <summary>
-        /// Constructs a new animation event.
-        /// </summary>
-        /// <param name="name">Name used to identify the event when it is triggered.</param>
-        /// <param name="time">Time at which to trigger the event, in seconds.</param>
-        public AnimationEvent(string name, float time)
-        {
-            Name = name;
-            Time = time;
-        }
-
-        /// <summary>
-        /// Name used to identify the event when it is triggered.
-        /// </summary>
-        public string Name;
-
-        /// <summary>
-        /// Time at which to trigger the event, in seconds.
-        /// </summary>
-        public float Time;
-    }
-
-    /// <summary>
-    /// Contains a set of animation curves used for moving and rotating the root bone.
-    /// </summary>
-    public class RootMotion
-    {
-        /// <summary>
-        /// Animation curve representing the movement of the root bone.
-        /// </summary>
-        public Vector3Curve Position;
-
-        /// <summary>
-        /// Animation curve representing the rotation of the root bone.
-        /// </summary>
-        public QuaternionCurve Rotation;
-    }
-
-    /** @} */
-}

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

@@ -1,340 +0,0 @@
-//********************************** 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>
-    /// Flags that describe an <see cref="AnimationCurve"/>
-    /// </summary>
-    public enum AnimationCurveFlags // Note: Must match C++ enum AnimationCurveFlags
-    {
-        /// <summary>
-        /// If enabled, the curve was imported from an external file and not created within the engine. This will affect
-        /// how are animation results applied to scene objects (with imported animations it is assumed the curve is
-        /// animating bones and with in-engine curves it is assumed the curve is animating scene objects).
-        /// </summary>
-        ImportedCurve = 1 << 0,
-        /// <summary>
-        /// Signifies the curve is used to animate between different frames within a morph channel. In range [0, 1].
-        /// </summary>
-        MorphFrame = 1 << 1,
-        /// <summary>
-        /// Signifies the curve is used to adjust the weight of a morph channel. In range [0, 1].
-        /// </summary>
-        MorphWeight = 1 << 2
-    }
-
-    /// <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>
-        /// Constructor for internal runtime use only.
-        /// </summary>
-        private AnimationCurve()
-        { }
-
-        /// <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);
-    }
-    
-    /// <summary>
-    /// A set of animation curves for a 3D vector paired with a name.
-    /// </summary>
-    public class NamedVector3Curve
-    {
-        /// <summary>
-        /// Constructor for internal runtime use only.
-        /// </summary>
-        /// <param name="name">Name of the curve.</param>
-        /// <param name="flags">Flags that describe the animation curve, of type <see cref="AnimationCurveFlags"/>.</param>
-        /// <param name="x">Curve representing the x axis of the vector.</param>
-        /// <param name="y">Curve representing the y axis of the vector.</param>
-        /// <param name="z">Curve representing the z axis of the vector.</param>
-        private NamedVector3Curve(string name, int flags, AnimationCurve x, AnimationCurve y, AnimationCurve z)
-        {
-            Name = name;
-            Flags = (AnimationCurveFlags) flags;
-            X = x;
-            Y = y;
-            Z = z;
-        }
-
-        /// <summary>
-        /// Constructs a new named animation curve.
-        /// </summary>
-        /// <param name="name">Name of the curve.</param>
-        /// <param name="x">Curve representing the x axis of the vector.</param>
-        /// <param name="y">Curve representing the y axis of the vector.</param>
-        /// <param name="z">Curve representing the z axis of the vector.</param>
-        public NamedVector3Curve(string name, AnimationCurve x, AnimationCurve y, AnimationCurve z)
-        {
-            Name = name;
-            X = x;
-            Y = y;
-            Z = z;
-        }
-
-        /// <summary>
-        /// Name of the curve.
-        /// </summary>
-        public string Name;
-
-        /// <summary>
-        /// Flags that describe the animation curve.
-        /// </summary>
-        public AnimationCurveFlags Flags;
-
-        /// <summary>
-        /// Animation curve for the x axis.
-        /// </summary>
-        public AnimationCurve X;
-
-        /// <summary>
-        /// Animation curve for the y axis.
-        /// </summary>
-        public AnimationCurve Y;
-
-        /// <summary>
-        /// Animation curve for the z axis.
-        /// </summary>
-        public AnimationCurve Z;
-    }
-
-    /// <summary>
-    /// An animation curve for a single floating point value paired with a name.
-    /// </summary>
-    public class NamedFloatCurve
-    {
-        /// <summary>
-        /// Constructor for internal runtime use only.
-        /// </summary>
-        /// <param name="name">Name of the curve.</param>
-        /// <param name="flags">Flags that describe the animation curve, of type <see cref="AnimationCurveFlags"/>.</param>
-        /// <param name="curve">Curve representing the floating point values.</param>
-        private NamedFloatCurve(string name, int flags, AnimationCurve curve)
-        {
-            Name = name;
-            Flags = (AnimationCurveFlags)flags;
-            Curve = curve;
-        }
-
-        /// <summary>
-        /// Constructs a new named animation curve.
-        /// </summary>
-        /// <param name="name">Name of the curve.</param>
-        /// <param name="curve">Curve representing the floating point values.</param>
-        public NamedFloatCurve(string name, AnimationCurve curve)
-        {
-            Name = name;
-            Curve = curve;
-        }
-
-        /// <summary>
-        /// Name of the curve.
-        /// </summary>
-        public string Name;
-
-        /// <summary>
-        /// Flags that describe the animation curve.
-        /// </summary>
-        public AnimationCurveFlags Flags;
-
-        /// <summary>
-        /// Animation curve.
-        /// </summary>
-        public AnimationCurve Curve;
-    }
-
-    /// <summary>
-    /// A set of animation curves for a 3D vector.
-    /// </summary>
-    public class Vector3Curve
-    {
-        /// <summary>
-        /// Constructs a new 3D vector animation curve.
-        /// </summary>
-        /// <param name="x">Curve representing the x axis of the vector.</param>
-        /// <param name="y">Curve representing the y axis of the vector.</param>
-        /// <param name="z">Curve representing the z axis of the vector.</param>
-        public Vector3Curve(AnimationCurve x, AnimationCurve y, AnimationCurve z)
-        {
-            X = x;
-            Y = y;
-            Z = z;
-        }
-
-        /// <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 Vector3 Evaluate(float time, bool loop = true)
-        {
-            Vector3 output = new Vector3();
-
-            if (X != null)
-                output.x = X.Evaluate(time, loop);
-
-            if (Y != null)
-                output.y = Y.Evaluate(time, loop);
-
-            if (Z != null)
-                output.z = Z.Evaluate(time, loop);
-
-            return output;
-        }
-
-        /// <summary>
-        /// Animation curve for the x axis.
-        /// </summary>
-        public AnimationCurve X;
-
-        /// <summary>
-        /// Animation curve for the y axis.
-        /// </summary>
-        public AnimationCurve Y;
-
-        /// <summary>
-        /// Animation curve for the z axis.
-        /// </summary>
-        public AnimationCurve Z;
-    }
-
-    /// <summary>
-    /// A set of animation curves for a quaternion.
-    /// </summary>
-    public class QuaternionCurve
-    {
-        /// <summary>
-        /// Constructs a new quaternion animation curve.
-        /// </summary>
-        /// <param name="x">Curve representing the x component of the quaternion.</param>
-        /// <param name="y">Curve representing the y component of the quaternion.</param>
-        /// <param name="z">Curve representing the z component of the quaternion.</param>
-        /// <param name="w">Curve representing the w component of the quaternion.</param>
-        public QuaternionCurve(AnimationCurve x, AnimationCurve y, AnimationCurve z, AnimationCurve w)
-        {
-            X = x;
-            Y = y;
-            Z = z;
-            W = w;
-        }
-
-        /// <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 Quaternion Evaluate(float time, bool loop = true)
-        {
-            Quaternion output = new Quaternion();
-
-            if (X != null)
-                output.x = X.Evaluate(time, loop);
-
-            if (Y != null)
-                output.y = Y.Evaluate(time, loop);
-
-            if (Z != null)
-                output.z = Z.Evaluate(time, loop);
-
-            if (W != null)
-                output.w = W.Evaluate(time, loop);
-
-            return output;
-        }
-
-        /// <summary>
-        /// Animation curve for the x component.
-        /// </summary>
-        public AnimationCurve X;
-
-        /// <summary>
-        /// Animation curve for the y component.
-        /// </summary>
-        public AnimationCurve Y;
-
-        /// <summary>
-        /// Animation curve for the z component.
-        /// </summary>
-        public AnimationCurve Z;
-
-        /// <summary>
-        /// Animation curve for the w component.
-        /// </summary>
-        public AnimationCurve W;
-    }
-}

+ 0 - 38
Source/MBansheeEngine/Animation/AnimationCurves.cs

@@ -1,38 +0,0 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-using System;
-
-namespace BansheeEngine
-{
-    /** @addtogroup Animation
-     *  @{
-     */
-
-    /// <summary>
-    /// Contains a set of animation curves used within an <see cref="AnimationClip"/>.
-    /// </summary>
-    public class AnimationCurves
-    {
-        /// <summary>
-        /// Curves for animating a scene object's position.
-        /// </summary>
-        public NamedVector3Curve[] PositionCurves;
-
-        /// <summary>
-        /// Curves for animating a scene object's rotation (in euler angles).
-        /// </summary>
-        public NamedVector3Curve[] RotationCurves;
-
-        /// <summary>
-        /// Curves for animating a scene object's scale.
-        /// </summary>
-        public NamedVector3Curve[] ScaleCurves;
-
-        /// <summary>
-        /// Curves for animating generic component properties.
-        /// </summary>
-        public NamedFloatCurve[] FloatCurves;
-    }
-
-    /** @} */
-}

+ 1 - 4
Source/MBansheeEngine/MBansheeEngine.csproj

@@ -34,7 +34,7 @@
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
   <ItemGroup>
-	<CSFile Include="*.cs"/>
+    <CSFile Include="*.cs" />
     <Reference Include="System" />
     <Reference Include="System.Core" />
     <Reference Include="System.Xml.Linq" />
@@ -45,9 +45,6 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Animation\Animation.cs" />
-    <Compile Include="Animation\AnimationClip.cs" />
-    <Compile Include="Animation\AnimationCurve.cs" />
-    <Compile Include="Animation\AnimationCurves.cs" />
     <Compile Include="Animation\Bone.cs" />
     <Compile Include="Animation\Interop\NativeAnimation.cs" />
     <Compile Include="Audio\Audio.cs" />

+ 4 - 8
Source/SBansheeEditor/Source/BsScriptImportOptions.cpp

@@ -14,7 +14,8 @@
 #include "BsRenderer.h"
 #include "BsScriptFont.h"
 #include "BsRTTIType.h"
-#include "BsScriptAnimationClip.h"
+
+#include "BsScriptAnimationEvent.generated.h"
 
 using namespace std::placeholders;
 
@@ -755,9 +756,7 @@ namespace bs
 			ScriptArray scriptEvents(monoEvents);
 			for (UINT32 i = 0; i < scriptEvents.size(); i++)
 			{
-				MonoObject* monoEvent = scriptEvents.get<MonoObject*>(i);
-				AnimationEvent event = ScriptAnimationEvent::toNative(monoEvent);
-
+				AnimationEvent event = ScriptAnimationEvent::fromInterop(scriptEvents.get<__AnimationEventInterop>(i));
 				output.events.push_back(event);
 			}
 		}
@@ -773,10 +772,7 @@ namespace bs
 		ScriptArray scriptEvents = ScriptArray::create<ScriptAnimationEvent>(numEvents);
 
 		for (UINT32 i = 0; i < numEvents; i++)
-		{
-			MonoObject* monoEvent = ScriptAnimationEvent::toManaged(events.events[i]);
-			scriptEvents.set(i, monoEvent);
-		}
+			scriptEvents.set(i, ScriptAnimationEvent::toInterop(events.events[i]));
 
 		MonoObject* instance = metaData.scriptClass->createInstance();
 		nameField->set(instance, monoString);

+ 4 - 6
Source/SBansheeEngine/CMakeSources.cmake

@@ -130,11 +130,9 @@ set(BS_SBANSHEEENGINE_INC_WRAPPERS
 	"Include/BsScriptAudio.h"
 	"Include/BsScriptAudioSource.h"
 	"Include/BsScriptAudioListener.h"
-	"Include/BsScriptAnimationClip.h"
 	"Include/BsScriptAnimation.h"
-	"Include/BsScriptAnimationCurve.h"
-	"Include/BsScriptAnimationCurves.h"
 	"Include/BsScriptManagedComponent.h"
+	"Include/BsScriptQuaternion.h"
 )
 
 set(BS_SBANSHEEENGINE_INC_WRAPPERS_GUI
@@ -255,11 +253,9 @@ set(BS_SBANSHEEENGINE_SRC_WRAPPERS
 	"Source/BsScriptAudio.cpp"
 	"Source/BsScriptAudioSource.cpp"
 	"Source/BsScriptAudioListener.cpp"
-	"Source/BsScriptAnimationClip.cpp"
 	"Source/BsScriptAnimation.cpp"
-	"Source/BsScriptAnimationCurve.cpp"
-	"Source/BsScriptAnimationCurves.cpp"
 	"Source/BsScriptManagedComponent.cpp"
+	"Source/BsScriptQuaternion.cpp"
 )
 
 set(BS_SBANSHEEENGINE_INC_SERIALIZATION
@@ -306,6 +302,7 @@ set(BS_SBANSHEEENGINE_INC_EXTENSIONS
 	"Include/BsMeshEx.h"
 	"Include/BsSkeletonEx.h"
 	"Include/BsPhysicsMeshEx.h"
+	"Include/BsAnimationEx.h"
 )
 
 set(BS_SBANSHEEENGINE_SRC_EXTENSIONS
@@ -316,6 +313,7 @@ set(BS_SBANSHEEENGINE_SRC_EXTENSIONS
 	"Source/BsMeshEx.cpp"
 	"Source/BsSkeletonEx.cpp"
 	"Source/BsPhysicsMeshEx.cpp"
+	"Source/BsAnimationEx.cpp"
 )
 
 source_group("Header Files" FILES ${BS_SBANSHEEENGINE_INC_NOFILTER})

+ 64 - 0
Source/SBansheeEngine/Include/BsAnimationEx.h

@@ -0,0 +1,64 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "BsScriptResource.h"
+#include "BsAnimationClip.h"
+
+namespace bs
+{
+	/** @addtogroup ScriptInteropEngine
+	 *  @{
+	 */
+	/** @cond SCRIPT_EXTENSIONS */
+
+	/** Extension class for AnimationCurves, for adding additional functionality for the script version of the class. */
+	class BS_SCRIPT_EXPORT(e:AnimationCurves) AnimationCurvesEx
+	{
+	public:
+		BS_SCRIPT_EXPORT(e:AnimationCurves,n:Position,pr:getter)
+		static Vector<TNamedAnimationCurve<Vector3>> getPositionCurves(const SPtr<AnimationCurves>& thisPtr);
+
+		/** Curves for animating scene object's position. */
+		BS_SCRIPT_EXPORT(e:AnimationCurves,n:Position,pr:setter)
+		static void setPositionCurves(const SPtr<AnimationCurves>& thisPtr, const Vector<TNamedAnimationCurve<Vector3>>& value);
+
+		BS_SCRIPT_EXPORT(e:AnimationCurves,n:Rotation,pr:getter)
+		static Vector<TNamedAnimationCurve<Quaternion>> getRotationCurves(const SPtr<AnimationCurves>& thisPtr);
+
+		/** Curves for animating scene object's rotation. */
+		BS_SCRIPT_EXPORT(e:AnimationCurves,n:Rotation,pr:setter)
+		static void setRotationCurves(const SPtr<AnimationCurves>& thisPtr, const Vector<TNamedAnimationCurve<Quaternion>>& value);
+
+		BS_SCRIPT_EXPORT(e:AnimationCurves,n:Scale,pr:getter)
+		static Vector<TNamedAnimationCurve<Vector3>> getScaleCurves(const SPtr<AnimationCurves>& thisPtr);
+
+		/** Curves for animating scene object's scale. */
+		BS_SCRIPT_EXPORT(e:AnimationCurves,n:Scale,pr:setter)
+		static void setScaleCurves(const SPtr<AnimationCurves>& thisPtr, const Vector<TNamedAnimationCurve<Vector3>>& value);
+
+		BS_SCRIPT_EXPORT(e:AnimationCurves,n:Generic,pr:getter)
+		static Vector<TNamedAnimationCurve<float>> getGenericCurves(const SPtr<AnimationCurves>& thisPtr);
+
+		/** Curves for animating generic component properties. */
+		BS_SCRIPT_EXPORT(e:AnimationCurves,n:Generic,pr:setter)
+		static void setGenericCurves(const SPtr<AnimationCurves>& thisPtr, const Vector<TNamedAnimationCurve<float>>& value);
+	};
+
+	/** Extension class for RootMotion, for adding additional functionality for the script version of the class. */
+	class BS_SCRIPT_EXPORT(e:RootMotion) RootMotionEx
+	{
+	public:
+		/** Animation curve representing the movement of the root bone. */
+		BS_SCRIPT_EXPORT(e:RootMotion,n:Position,pr:getter)
+		static TAnimationCurve<Vector3> getPositionCurves(const SPtr<RootMotion>& thisPtr);
+
+		/** Animation curve representing the rotation of the root bone. */
+		BS_SCRIPT_EXPORT(e:RootMotion,n:Rotation,pr:getter)
+		static TAnimationCurve<Quaternion> getRotationCurves(const SPtr<RootMotion>& thisPtr);
+	};
+
+	/** @endcond */
+	/** @} */
+}

+ 0 - 66
Source/SBansheeEngine/Include/BsScriptAnimationClip.h

@@ -1,66 +0,0 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#pragma once
-
-#include "BsScriptEnginePrerequisites.h"
-#include "BsScriptResource.h"
-#include "BsAnimationClip.h"
-
-namespace bs
-{
-	/** @addtogroup ScriptInteropEngine
-	 *  @{
-	 */
-
-	/**	Interop class between C++ & CLR for AnimationClip. */
-	class BS_SCR_BE_EXPORT ScriptAnimationClip : public TScriptResource<ScriptAnimationClip, AnimationClip>
-	{
-	public:
-		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "AnimationClip")
-
-		/**	Creates an empty, uninitialized managed instance of the resource interop object. */
-		static MonoObject* createInstance();
-
-	private:
-		friend class ScriptResourceManager;
-		friend class BuiltinResourceTypes;
-
-		ScriptAnimationClip(MonoObject* instance, const HAnimationClip& animationClip);
-
-		/************************************************************************/
-		/* 								CLR HOOKS						   		*/
-		/************************************************************************/
-		static void internal_CreateInstance(MonoObject* instance);
-		static MonoObject* internal_GetAnimationCurves(ScriptAnimationClip* thisPtr);
-		static void internal_SetAnimationCurves(ScriptAnimationClip* thisPtr, MonoObject* curves);
-		static MonoArray* internal_GetAnimationEvents(ScriptAnimationClip* thisPtr);
-		static void internal_SetAnimationEvents(ScriptAnimationClip* thisPtr, MonoArray* events);
-		static MonoObject* internal_GetRootMotion(ScriptAnimationClip* thisPtr);
-		static float internal_GetLength(ScriptAnimationClip* thisPtr);
-		static UINT32 internal_GetSampleRate(ScriptAnimationClip* thisPtr);
-		static void internal_SetSampleRate(ScriptAnimationClip* thisPtr, UINT32 sampleRate);
-	};
-
-	/**	Interop class between C++ & CLR for AnimationEvent. */
-	class BS_SCR_BE_EXPORT ScriptAnimationEvent : public ScriptObject<ScriptAnimationEvent>
-	{
-	public:
-		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "AnimationEvent")
-
-		/** Converts managed animation event its native counterpart. */
-		static AnimationEvent toNative(MonoObject* object);
-
-		/** Converts native animation event to its managed counterpart. */
-		static MonoObject* toManaged(const AnimationEvent& event);
-	private:
-		ScriptAnimationEvent(MonoObject* instance);
-
-		/************************************************************************/
-		/* 								CLR HOOKS						   		*/
-		/************************************************************************/
-		static MonoField* sNameField;
-		static MonoField* sTimeField;
-	};
-
-	/** @} */
-}

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

@@ -1,52 +0,0 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#pragma once
-
-#include "BsScriptEnginePrerequisites.h"
-#include "BsScriptObject.h"
-#include "BsAnimationCurve.h"
-
-namespace bs
-{
-	/** @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")
-
-		/** Returns the internal native curve stored in this wrapper. */
-		SPtr<TAnimationCurve<float>> getInternal() const { return mCurve; }
-
-		/** Creates a new managed object wrapping the provided curve. */
-		static MonoObject* create(const TAnimationCurve<float>& curve);
-
-	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);
-	};
-
-	/** @} */
-}

+ 0 - 129
Source/SBansheeEngine/Include/BsScriptAnimationCurves.h

@@ -1,129 +0,0 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#pragma once
-
-#include "BsScriptEnginePrerequisites.h"
-#include "BsScriptObject.h"
-#include "BsAnimationCurve.h"
-
-namespace bs
-{
-	/** @addtogroup ScriptInteropEngine
-	 *  @{
-	 */
-
-	/**	Interop class between C++ & CLR for AnimationCurves. */
-	class BS_SCR_BE_EXPORT ScriptAnimationCurves : public ScriptObject<ScriptAnimationCurves>
-	{
-	public:
-		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "AnimationCurves")
-
-		/** Converts managed animation curves its native counterpart. */
-		static SPtr<AnimationCurves> toNative(MonoObject* object);
-
-		/** Converts native animation curves to its managed counterpart. */
-		static MonoObject* toManaged(const SPtr<AnimationCurves>& curves);
-	private:
-		ScriptAnimationCurves(MonoObject* instance);
-
-		/************************************************************************/
-		/* 								CLR HOOKS						   		*/
-		/************************************************************************/
-		static MonoField* sPositionCurvesField;
-		static MonoField* sRotationCurvesField;
-		static MonoField* sScaleCurvesField;
-		static MonoField* sFloatCurvesField;
-	};
-
-	/**	Interop class between C++ & CLR for NamedVector3Curve. */
-	class BS_SCR_BE_EXPORT ScriptNamedVector3Curve : public ScriptObject<ScriptNamedVector3Curve>
-	{
-	public:
-		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "NamedVector3Curve")
-
-		/** Converts managed 3D vector animation curve its native counterpart. */
-		static TNamedAnimationCurve<Vector3> toNative(MonoObject* object);
-
-		/** Converts native 3D vector animation curve to its managed counterpart. */
-		static MonoObject* toManaged(const TNamedAnimationCurve<Vector3>& curve);
-	private:
-		ScriptNamedVector3Curve(MonoObject* instance);
-
-		/************************************************************************/
-		/* 								CLR HOOKS						   		*/
-		/************************************************************************/
-		static MonoField* sNameField;
-		static MonoField* sFlagsField;
-		static MonoField* sXCurveField;
-		static MonoField* sYCurveField;
-		static MonoField* sZCurveField;
-	};
-
-	/**	Interop class between C++ & CLR for NamedFloatCurve. */
-	class BS_SCR_BE_EXPORT ScriptNamedFloatCurve : public ScriptObject<ScriptNamedFloatCurve>
-	{
-	public:
-		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "NamedFloatCurve")
-
-		/** Converts managed float animation curve its native counterpart. */
-		static TNamedAnimationCurve<float> toNative(MonoObject* object);
-
-		/** Converts native float animation curve to its managed counterpart. */
-		static MonoObject* toManaged(const TNamedAnimationCurve<float>& curve);
-	private:
-		ScriptNamedFloatCurve(MonoObject* instance);
-
-		/************************************************************************/
-		/* 								CLR HOOKS						   		*/
-		/************************************************************************/
-		static MonoField* sNameField;
-		static MonoField* sFlagsField;
-		static MonoField* sCurveField;
-	};
-
-	/**	Interop class between C++ & CLR for Vector3Curve. */
-	class BS_SCR_BE_EXPORT ScriptVector3Curve : public ScriptObject<ScriptVector3Curve>
-	{
-	public:
-		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "Vector3Curve")
-
-		/** Converts native 3D vector animation curve to its managed counterpart. */
-		static MonoObject* toManaged(const TAnimationCurve<Vector3>& curve);
-	private:
-		ScriptVector3Curve(MonoObject* instance);
-	};
-
-	/**	Interop class between C++ & CLR for QuaternionCurve. */
-	class BS_SCR_BE_EXPORT ScriptQuaternionCurve : public ScriptObject<ScriptQuaternionCurve>
-	{
-	public:
-		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "QuaternionCurve")
-
-		/** Converts native quaternion animation curve to its managed counterpart. */
-		static MonoObject* toManaged(const TAnimationCurve<Quaternion>& curve);
-	private:
-		ScriptQuaternionCurve(MonoObject* instance);
-	};
-
-	struct RootMotion;
-
-	/**	Interop class between C++ & CLR for RootMotion. */
-	class BS_SCR_BE_EXPORT ScriptRootMotion : public ScriptObject<ScriptRootMotion>
-	{
-	public:
-		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "RootMotion")
-
-		/** Converts native root motion object to its managed counterpart. */
-		static MonoObject* toManaged(const SPtr<RootMotion>& rootMotion);
-	private:
-		ScriptRootMotion(MonoObject* instance);
-
-		/************************************************************************/
-		/* 								CLR HOOKS						   		*/
-		/************************************************************************/
-		static MonoField* sPositionField;
-		static MonoField* sRotationField;
-	};
-
-	/** @} */
-}

+ 32 - 0
Source/SBansheeEngine/Include/BsScriptQuaternion.h

@@ -0,0 +1,32 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "BsScriptObject.h"
+#include "BsQuaternion.h"
+
+namespace bs
+{
+	/** @addtogroup ScriptInteropEngine
+	 *  @{
+	 */
+
+	/**	Interop class between C++ & CLR for Quaternion. */
+	class BS_SCR_BE_EXPORT ScriptQuaternion : public ScriptObject <ScriptQuaternion>
+	{
+	public:
+		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "Quaternion")
+
+		/** Unboxes a boxed managed Quaternion struct and returns the native version of the structure. */
+		static Quaternion unbox(MonoObject* obj);
+
+		/**	Boxes a native Quaternion struct and returns a managed object containing it. */
+		static MonoObject* box(const Quaternion& value);
+
+	private:
+		ScriptQuaternion(MonoObject* instance);
+	};
+
+	/** @} */
+}

+ 58 - 0
Source/SBansheeEngine/Source/BsAnimationEx.cpp

@@ -0,0 +1,58 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsAnimationEx.h"
+
+using namespace std::placeholders;
+
+namespace bs
+{
+	Vector<TNamedAnimationCurve<Vector3>> AnimationCurvesEx::getPositionCurves(const SPtr<AnimationCurves>& thisPtr)
+	{
+		return thisPtr->position;
+	}
+
+	void AnimationCurvesEx::setPositionCurves(const SPtr<AnimationCurves>& thisPtr, const Vector<TNamedAnimationCurve<Vector3>>& value)
+	{
+		thisPtr->position = value;
+	}
+
+	Vector<TNamedAnimationCurve<Quaternion>> AnimationCurvesEx::getRotationCurves(const SPtr<AnimationCurves>& thisPtr)
+	{
+		return thisPtr->rotation;
+	}
+
+	void AnimationCurvesEx::setRotationCurves(const SPtr<AnimationCurves>& thisPtr, const Vector<TNamedAnimationCurve<Quaternion>>& value)
+	{
+		thisPtr->rotation = value;
+	}
+
+	Vector<TNamedAnimationCurve<Vector3>> AnimationCurvesEx::getScaleCurves(const SPtr<AnimationCurves>& thisPtr)
+	{
+		return thisPtr->scale;
+	}
+
+	void AnimationCurvesEx::setScaleCurves(const SPtr<AnimationCurves>& thisPtr, const Vector<TNamedAnimationCurve<Vector3>>& value)
+	{
+		thisPtr->scale = value;
+	}
+
+	Vector<TNamedAnimationCurve<float>> AnimationCurvesEx::getGenericCurves(const SPtr<AnimationCurves>& thisPtr)
+	{
+		return thisPtr->generic;
+	}
+
+	void AnimationCurvesEx::setGenericCurves(const SPtr<AnimationCurves>& thisPtr, const Vector<TNamedAnimationCurve<float>>& value)
+	{
+		thisPtr->generic = value;
+	}
+
+	TAnimationCurve<Vector3> RootMotionEx::getPositionCurves(const SPtr<RootMotion>& thisPtr)
+	{
+		return thisPtr->position;
+	}
+
+	TAnimationCurve<Quaternion> RootMotionEx::getRotationCurves(const SPtr<RootMotion>& thisPtr)
+	{
+		return thisPtr->rotation;
+	}
+}

+ 2 - 1
Source/SBansheeEngine/Source/BsScriptAnimation.cpp

@@ -9,7 +9,8 @@
 #include "BsMonoUtil.h"
 #include "BsScriptSceneObject.h"
 #include "BsScriptResourceManager.h"
-#include "BsScriptAnimationClip.h"
+
+#include "BsScriptAnimationClip.generated.h"
 
 using namespace std::placeholders;
 

+ 0 - 145
Source/SBansheeEngine/Source/BsScriptAnimationClip.cpp

@@ -1,145 +0,0 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#include "BsScriptAnimationClip.h"
-#include "BsScriptAnimationCurves.h"
-#include "BsScriptMeta.h"
-#include "BsMonoClass.h"
-#include "BsScriptResourceManager.h"
-
-namespace bs
-{
-	ScriptAnimationClip::ScriptAnimationClip(MonoObject* instance, const HAnimationClip& animationClip)
-		:TScriptResource(instance, animationClip)
-	{
-
-	}
-
-	void ScriptAnimationClip::initRuntimeData()
-	{
-		metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptAnimationClip::internal_CreateInstance);
-		metaData.scriptClass->addInternalCall("Internal_GetAnimationCurves", &ScriptAnimationClip::internal_GetAnimationCurves);
-		metaData.scriptClass->addInternalCall("Internal_SetAnimationCurves", &ScriptAnimationClip::internal_SetAnimationCurves);
-		metaData.scriptClass->addInternalCall("Internal_GetAnimationEvents", &ScriptAnimationClip::internal_GetAnimationEvents);
-		metaData.scriptClass->addInternalCall("Internal_SetAnimationEvents", &ScriptAnimationClip::internal_SetAnimationEvents);
-		metaData.scriptClass->addInternalCall("Internal_GetRootMotion", &ScriptAnimationClip::internal_GetRootMotion);
-		metaData.scriptClass->addInternalCall("Internal_GetLength", &ScriptAnimationClip::internal_GetLength);
-		metaData.scriptClass->addInternalCall("Internal_GetSampleRate", &ScriptAnimationClip::internal_GetSampleRate);
-		metaData.scriptClass->addInternalCall("Internal_SetSampleRate", &ScriptAnimationClip::internal_SetSampleRate);
-	}
-
-	MonoObject* ScriptAnimationClip::createInstance()
-	{
-		bool dummy = false;
-
-		void* params[1];
-		params[0] = &dummy;
-
-		return metaData.scriptClass->createInstance("bool", params);
-	}
-
-	void ScriptAnimationClip::internal_CreateInstance(MonoObject* instance)
-	{
-		HAnimationClip clip = AnimationClip::create();
-
-		ScriptResourceBase* scriptInstance = ScriptResourceManager::instance().createBuiltinScriptResource(clip, instance);
-	}
-
-	MonoObject* ScriptAnimationClip::internal_GetAnimationCurves(ScriptAnimationClip* thisPtr)
-	{
-		SPtr<AnimationCurves> curves = thisPtr->getHandle()->getCurves();
-		return ScriptAnimationCurves::toManaged(curves);
-	}
-
-	void ScriptAnimationClip::internal_SetAnimationCurves(ScriptAnimationClip* thisPtr, MonoObject* curves)
-	{
-		SPtr<AnimationCurves> nativeCurves = ScriptAnimationCurves::toNative(curves);
-		thisPtr->getHandle()->setCurves(*nativeCurves);
-	}
-
-	MonoArray* ScriptAnimationClip::internal_GetAnimationEvents(ScriptAnimationClip* thisPtr)
-	{
-		const Vector<AnimationEvent>& events = thisPtr->getHandle()->getEvents();
-
-		UINT32 numEvents = (UINT32)events.size();
-		ScriptArray eventsArray = ScriptArray::create<ScriptAnimationEvent>(numEvents);
-		for (UINT32 i = 0; i < numEvents; i++)
-			eventsArray.set(i, ScriptAnimationEvent::toManaged(events[i]));
-
-		return eventsArray.getInternal();
-	}
-
-	void ScriptAnimationClip::internal_SetAnimationEvents(ScriptAnimationClip* thisPtr, MonoArray* events)
-	{
-		Vector<AnimationEvent> nativeEvents;
-
-		if (events != nullptr)
-		{
-			ScriptArray eventsArray(events);
-
-			for (UINT32 i = 0; i < eventsArray.size(); i++)
-			{
-				AnimationEvent event = ScriptAnimationEvent::toNative(eventsArray.get<MonoObject*>(i));
-				nativeEvents.push_back(event);
-			}
-		}
-
-		thisPtr->getHandle()->setEvents(nativeEvents);
-	}
-
-	MonoObject* ScriptAnimationClip::internal_GetRootMotion(ScriptAnimationClip* thisPtr)
-	{
-		SPtr<RootMotion> rootMotion = thisPtr->getHandle()->getRootMotion();
-		return ScriptRootMotion::toManaged(rootMotion);
-	}
-
-	float ScriptAnimationClip::internal_GetLength(ScriptAnimationClip* thisPtr)
-	{
-		return thisPtr->getHandle()->getLength();
-	}
-
-	UINT32 ScriptAnimationClip::internal_GetSampleRate(ScriptAnimationClip* thisPtr)
-	{
-		return thisPtr->getHandle()->getSampleRate();
-	}
-
-	void ScriptAnimationClip::internal_SetSampleRate(ScriptAnimationClip* thisPtr, UINT32 sampleRate)
-	{
-		thisPtr->getHandle()->setSampleRate(sampleRate);
-	}
-
-	MonoField* ScriptAnimationEvent::sNameField = nullptr;
-	MonoField* ScriptAnimationEvent::sTimeField = nullptr;
-
-	ScriptAnimationEvent::ScriptAnimationEvent(MonoObject* instance)
-		:ScriptObject(instance)
-	{ }
-
-	void ScriptAnimationEvent::initRuntimeData()
-	{
-		sNameField = metaData.scriptClass->getField("Name");
-		sTimeField = metaData.scriptClass->getField("Time");
-	}
-
-	AnimationEvent ScriptAnimationEvent::toNative(MonoObject* instance)
-	{
-		AnimationEvent output;
-
-		MonoString* monoName = nullptr;
-		sNameField->get(instance, &monoName);
-
-		output.name = MonoUtil::monoToString(monoName);
-
-		sTimeField->get(instance, &output.time);
-
-		return output;
-	}
-
-	MonoObject* ScriptAnimationEvent::toManaged(const AnimationEvent& event)
-	{
-		MonoString* monoString = MonoUtil::stringToMono(event.name);
-		float time = event.time;
-
-		void* params[2] = { monoString, &time };
-		return metaData.scriptClass->createInstance("string,single", params);
-	}
-}

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

@@ -1,93 +0,0 @@
-//********************************** 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 bs
-{
-	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);
-	}
-
-	MonoObject* ScriptAnimationCurve::create(const TAnimationCurve<float>& curve)
-	{
-		SPtr<TAnimationCurve<float>> curvePtr = bs_shared_ptr_new<TAnimationCurve<float>>();
-		*curvePtr = curve;
-
-		MonoObject* instance = metaData.scriptClass->createInstance();
-		new (bs_alloc<ScriptAnimationCurve>()) ScriptAnimationCurve(instance, curvePtr);
-
-		return instance;
-	}
-
-	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>));
-
-		std::sort(nativeKeyframes.begin(), nativeKeyframes.end(), 
-			[](const TKeyframe<float>& x, const TKeyframe<float>& y)
-		{
-			return x.time < y.time;
-		});
-
-		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);
-	}
-}

+ 0 - 420
Source/SBansheeEngine/Source/BsScriptAnimationCurves.cpp

@@ -1,420 +0,0 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#include "BsScriptAnimationCurves.h"
-#include "BsScriptAnimationCurve.h"
-#include "BsMonoUtil.h"
-#include "BsMonoClass.h"
-#include "BsMonoField.h"
-#include "BsAnimationCurve.h"
-#include "BsAnimationClip.h"
-#include "BsAnimationUtility.h"
-#include "BsMath.h"
-#include "BsVector3.h"
-
-using namespace std::placeholders;
-
-namespace bs
-{
-	MonoField* ScriptAnimationCurves::sPositionCurvesField = nullptr;
-	MonoField* ScriptAnimationCurves::sRotationCurvesField = nullptr;
-	MonoField* ScriptAnimationCurves::sScaleCurvesField = nullptr;
-	MonoField* ScriptAnimationCurves::sFloatCurvesField = nullptr;
-
-	ScriptAnimationCurves::ScriptAnimationCurves(MonoObject* instance)
-		:ScriptObject(instance)
-	{ }
-
-	void ScriptAnimationCurves::initRuntimeData()
-	{
-		sPositionCurvesField = metaData.scriptClass->getField("PositionCurves");
-		sRotationCurvesField = metaData.scriptClass->getField("RotationCurves");
-		sScaleCurvesField = metaData.scriptClass->getField("ScaleCurves");
-		sFloatCurvesField = metaData.scriptClass->getField("FloatCurves");
-	}
-
-	SPtr<AnimationCurves> ScriptAnimationCurves::toNative(MonoObject* instance)
-	{
-		SPtr<AnimationCurves> output = bs_shared_ptr_new<AnimationCurves>();
-
-		MonoArray* monoPosCurves;
-		sPositionCurvesField->get(instance, &monoPosCurves);
-
-		if (monoPosCurves != nullptr)
-		{
-			ScriptArray scriptCurves(monoPosCurves);
-			for(UINT32 i = 0; i < scriptCurves.size(); i++)
-			{
-				MonoObject* monoCurve = scriptCurves.get<MonoObject*>(i);
-				output->position.push_back(ScriptNamedVector3Curve::toNative(monoCurve));
-			}
-		}
-
-		MonoArray* monoRotCurves;
-		sRotationCurvesField->get(instance, &monoRotCurves);
-
-		if (monoRotCurves != nullptr)
-		{
-			ScriptArray scriptCurves(monoRotCurves);
-			for (UINT32 i = 0; i < scriptCurves.size(); i++)
-			{
-				MonoObject* monoCurve = scriptCurves.get<MonoObject*>(i);
-				TNamedAnimationCurve<Vector3> eulerRotation = ScriptNamedVector3Curve::toNative(monoCurve);
-
-				TNamedAnimationCurve<Quaternion> quatRotation;
-				quatRotation.name = eulerRotation.name;
-				quatRotation.curve = AnimationUtility::eulerToQuaternionCurve(eulerRotation.curve);
-
-				// DEBUG ONLY
-				TAnimationCurve<Vector3> eulerRotation2 = AnimationUtility::quaternionToEulerCurve(quatRotation.curve);
-
-				output->rotation.push_back(quatRotation);
-			}
-		}
-
-		MonoArray* monoScaleCurves;
-		sScaleCurvesField->get(instance, &monoScaleCurves);
-
-		if (monoScaleCurves != nullptr)
-		{
-			ScriptArray scriptCurves(monoScaleCurves);
-			for (UINT32 i = 0; i < scriptCurves.size(); i++)
-			{
-				MonoObject* monoCurve = scriptCurves.get<MonoObject*>(i);
-				output->scale.push_back(ScriptNamedVector3Curve::toNative(monoCurve));
-			}
-		}
-
-		MonoArray* monoFloatCurves;
-		sFloatCurvesField->get(instance, &monoFloatCurves);
-
-		if (monoFloatCurves != nullptr)
-		{
-			ScriptArray scriptCurves(monoFloatCurves);
-			for (UINT32 i = 0; i < scriptCurves.size(); i++)
-			{
-				MonoObject* monoCurve = scriptCurves.get<MonoObject*>(i);
-				output->generic.push_back(ScriptNamedFloatCurve::toNative(monoCurve));
-			}
-		}
-
-		return output;
-	}
-
-	MonoObject* ScriptAnimationCurves::toManaged(const SPtr<AnimationCurves>& curves)
-	{
-		UINT32 numPosCurves = (UINT32)curves->position.size();
-		ScriptArray scriptPositionCurves = ScriptArray::create<ScriptNamedVector3Curve>(numPosCurves);
-
-		for(UINT32 i = 0; i < numPosCurves; i++)
-		{
-			MonoObject* monoCurve = ScriptNamedVector3Curve::toManaged(curves->position[i]);
-			scriptPositionCurves.set(i, monoCurve);
-		}
-
-		UINT32 numRotCurves = (UINT32)curves->rotation.size();
-		ScriptArray scriptRotationCurves = ScriptArray::create<ScriptNamedVector3Curve>(numRotCurves);
-
-		for (UINT32 i = 0; i < numRotCurves; i++)
-		{
-			TNamedAnimationCurve<Vector3> eulerRotationCurve;
-			eulerRotationCurve.name = curves->rotation[i].name;
-			eulerRotationCurve.curve = AnimationUtility::quaternionToEulerCurve(curves->rotation[i].curve);
-
-			MonoObject* monoCurve = ScriptNamedVector3Curve::toManaged(eulerRotationCurve);
-			scriptRotationCurves.set(i, monoCurve);
-		}
-
-		UINT32 numScaleCurves = (UINT32)curves->scale.size();
-		ScriptArray scriptScaleCurves = ScriptArray::create<ScriptNamedVector3Curve>(numScaleCurves);
-
-		for (UINT32 i = 0; i < numScaleCurves; i++)
-		{
-			MonoObject* monoCurve = ScriptNamedVector3Curve::toManaged(curves->scale[i]);
-			scriptScaleCurves.set(i, monoCurve);
-		}
-
-		UINT32 numFloatCurves = (UINT32)curves->generic.size();
-		ScriptArray scriptFloatCurves = ScriptArray::create<ScriptNamedFloatCurve>(numFloatCurves);
-
-		for (UINT32 i = 0; i < numFloatCurves; i++)
-		{
-			MonoObject* monoCurve = ScriptNamedFloatCurve::toManaged(curves->generic[i]);
-			scriptFloatCurves.set(i, monoCurve);
-		}
-
-		MonoObject* instance = metaData.scriptClass->createInstance();
-		sPositionCurvesField->set(instance, scriptPositionCurves.getInternal());
-		sRotationCurvesField->set(instance, scriptRotationCurves.getInternal());
-		sScaleCurvesField->set(instance, scriptScaleCurves.getInternal());
-		sFloatCurvesField->set(instance, scriptFloatCurves.getInternal());
-
-		return instance;
-	}
-
-	/** Converts compound animation curves into multiple float (single value) curves. */
-	template<class T, int C>
-	void convertCurves(const TAnimationCurve<T>& curve, TAnimationCurve<float>(&output)[C])
-	{
-		UINT32 numKeyFrames = curve.getNumKeyFrames();
-		Vector<TKeyframe<float>> keyFrames[C];
-
-		for (UINT32 i = 0; i < numKeyFrames; i++)
-		{
-			const TKeyframe<T>& key = curve.getKeyFrame(i);
-
-			TKeyframe<float> newKey;
-			newKey.time = key.time;
-
-			for (UINT32 j = 0; j < C; j++)
-			{
-				bool addNew = true;
-				if (i > 0)
-				{
-					const TKeyframe<float>& prevKey = keyFrames[j].back();
-
-					bool isEqual = Math::approxEquals(prevKey.value, key.value[j]) &&
-						Math::approxEquals(prevKey.outTangent, key.inTangent[j]);
-
-					addNew = !isEqual;
-				}
-
-				if (addNew)
-				{
-					newKey.value = key.value[j];
-					newKey.inTangent = key.inTangent[j];
-					newKey.outTangent = key.outTangent[j];
-
-					keyFrames[j].push_back(newKey);
-				}
-			}
-		}
-
-		for (UINT32 i = 0; i < C; i++)
-			output[i] = TAnimationCurve<float>(keyFrames[i]);
-	}
-
-	MonoField* ScriptNamedVector3Curve::sNameField = nullptr;
-	MonoField* ScriptNamedVector3Curve::sFlagsField = nullptr;
-	MonoField* ScriptNamedVector3Curve::sXCurveField = nullptr;
-	MonoField* ScriptNamedVector3Curve::sYCurveField = nullptr;
-	MonoField* ScriptNamedVector3Curve::sZCurveField = nullptr;
-
-	ScriptNamedVector3Curve::ScriptNamedVector3Curve(MonoObject* instance)
-		:ScriptObject(instance)
-	{ }
-
-	void ScriptNamedVector3Curve::initRuntimeData()
-	{
-		sNameField = metaData.scriptClass->getField("Name");
-		sFlagsField = metaData.scriptClass->getField("Flags");
-		sXCurveField = metaData.scriptClass->getField("X");
-		sYCurveField = metaData.scriptClass->getField("Y");
-		sZCurveField = metaData.scriptClass->getField("Z");
-	}
-
-	TNamedAnimationCurve<Vector3> ScriptNamedVector3Curve::toNative(MonoObject* instance)
-	{
-		TNamedAnimationCurve<Vector3> output;
-
-		MonoString* monoName = nullptr;
-		sNameField->get(instance, &monoName);
-
-		output.name = MonoUtil::monoToString(monoName);
-
-		UINT32 flags;
-		sFlagsField->get(instance, &flags);
-		output.flags = (AnimationCurveFlags)flags;
-
-		// Convert from three separate floating point curves, to a Vector3 curve
-		MonoObject* monoCurves[3];
-		sXCurveField->get(instance, &monoCurves[0]);
-		sYCurveField->get(instance, &monoCurves[1]);
-		sZCurveField->get(instance, &monoCurves[2]);
-
-		SPtr<TAnimationCurve<float>> curves[3];
-
-		// Find unique keyframe times
-		Map<float, TKeyframe<Vector3>> keyFrames;
-		for(UINT32 i = 0; i < 3; i++)
-		{
-			if (monoCurves[i] == nullptr)
-			{
-				curves[i] = bs_shared_ptr_new<TAnimationCurve<float>>();
-				continue;
-			}
-
-			ScriptAnimationCurve* scriptCurve = ScriptAnimationCurve::toNative(monoCurves[i]);
-			curves[i] = scriptCurve->getInternal();
-
-			UINT32 numKeyFrames = curves[i]->getNumKeyFrames();
-			for (UINT32 j = 0; j < numKeyFrames; j++)
-			{
-				const TKeyframe<float>& keyFrame = curves[i]->getKeyFrame(j);
-
-				auto iterFind = keyFrames.find(keyFrame.time);
-				if (iterFind == keyFrames.end())
-				{
-					TKeyframe<Vector3> newKeyFrame;
-					newKeyFrame.time = keyFrame.time;
-
-					keyFrames.insert(std::make_pair(keyFrame.time, newKeyFrame));
-				}
-			}
-		}
-
-		// Populate keyframe values
-		Vector<TKeyframe<Vector3>> keyframeList(keyFrames.size());
-		UINT32 idx = 0;
-		for(auto& entry : keyFrames)
-		{
-			TKeyframe<Vector3>& keyFrame = entry.second;
-			
-			for(UINT32 j = 0; j < 3; j++)
-			{
-				TKeyframe<float> currentKey = curves[j]->evaluateKey(keyFrame.time, false);
-				keyFrame.value[j] = currentKey.value;
-				keyFrame.inTangent[j] = currentKey.inTangent;
-				keyFrame.outTangent[j] = currentKey.outTangent;
-			}
-
-			keyframeList[idx] = keyFrame;
-			idx++;
-		}
-
-		output.curve = TAnimationCurve<Vector3>(keyframeList);
-		return output;
-	}
-
-	MonoObject* ScriptNamedVector3Curve::toManaged(const TNamedAnimationCurve<Vector3>& curve)
-	{
-		MonoString* monoString = MonoUtil::stringToMono(curve.name);
-
-		TAnimationCurve<float> curves[3];
-		convertCurves(curve.curve, curves);
-
-		MonoObject* monoXCurve = ScriptAnimationCurve::create(curves[0]);
-		MonoObject* monoYCurve = ScriptAnimationCurve::create(curves[1]);
-		MonoObject* monoZCurve = ScriptAnimationCurve::create(curves[2]);
-
-		UINT32 flags = curve.flags;
-
-		void* params[5] = { monoString, &flags, monoXCurve, monoYCurve, monoZCurve };
-		return metaData.scriptClass->createInstance("string,int,AnimationCurve,AnimationCurve,AnimationCurve", params);
-	}
-
-	MonoField* ScriptNamedFloatCurve::sNameField = nullptr;
-	MonoField* ScriptNamedFloatCurve::sFlagsField = nullptr;
-	MonoField* ScriptNamedFloatCurve::sCurveField = nullptr;
-
-	ScriptNamedFloatCurve::ScriptNamedFloatCurve(MonoObject* instance)
-		:ScriptObject(instance)
-	{ }
-
-	void ScriptNamedFloatCurve::initRuntimeData()
-	{
-		sNameField = metaData.scriptClass->getField("Name");
-		sFlagsField = metaData.scriptClass->getField("Flags");
-		sCurveField = metaData.scriptClass->getField("Curve");
-	}
-
-	TNamedAnimationCurve<float> ScriptNamedFloatCurve::toNative(MonoObject* instance)
-	{
-		TNamedAnimationCurve<float> output;
-
-		MonoString* monoName = nullptr;
-		sNameField->get(instance, &monoName);
-
-		output.name = MonoUtil::monoToString(monoName);
-
-		UINT32 flags;
-		sFlagsField->get(instance, &flags);
-		output.flags = (AnimationCurveFlags)flags;
-
-		MonoObject* monoCurve = nullptr;
-		sCurveField->get(instance, &monoCurve);
-
-		if(monoCurve != nullptr)
-		{
-			ScriptAnimationCurve* scriptCurve = ScriptAnimationCurve::toNative(monoCurve);
-			output.curve = *scriptCurve->getInternal();
-		}
-
-		return output;
-	}
-
-	MonoObject* ScriptNamedFloatCurve::toManaged(const TNamedAnimationCurve<float>& curve)
-	{
-		MonoString* monoString = MonoUtil::stringToMono(curve.name);
-		MonoObject* monoCurve = ScriptAnimationCurve::create(curve.curve);
-
-		UINT32 flags = curve.flags;
-		void* params[3] = { monoString, &flags, monoCurve };
-		return metaData.scriptClass->createInstance("string,int,AnimationCurve", params);
-	}
-
-	ScriptVector3Curve::ScriptVector3Curve(MonoObject* instance)
-		:ScriptObject(instance)
-	{ }
-
-	void ScriptVector3Curve::initRuntimeData()
-	{ }
-
-	MonoObject* ScriptVector3Curve::toManaged(const TAnimationCurve<Vector3>& curve)
-	{
-		TAnimationCurve<float> curves[3];
-		convertCurves(curve, curves);
-
-		MonoObject* monoXCurve = ScriptAnimationCurve::create(curves[0]);
-		MonoObject* monoYCurve = ScriptAnimationCurve::create(curves[1]);
-		MonoObject* monoZCurve = ScriptAnimationCurve::create(curves[2]);
-
-		void* params[3] = { monoXCurve, monoYCurve, monoZCurve };
-		return metaData.scriptClass->createInstance("AnimationCurve,AnimationCurve,AnimationCurve", params);
-	}
-
-	ScriptQuaternionCurve::ScriptQuaternionCurve(MonoObject* instance)
-		:ScriptObject(instance)
-	{ }
-
-	void ScriptQuaternionCurve::initRuntimeData()
-	{ }
-
-	MonoObject* ScriptQuaternionCurve::toManaged(const TAnimationCurve<Quaternion>& curve)
-	{
-		TAnimationCurve<float> curves[4];
-		convertCurves(curve, curves);
-
-		MonoObject* monoXCurve = ScriptAnimationCurve::create(curves[0]);
-		MonoObject* monoYCurve = ScriptAnimationCurve::create(curves[1]);
-		MonoObject* monoZCurve = ScriptAnimationCurve::create(curves[2]);
-		MonoObject* monoWCurve = ScriptAnimationCurve::create(curves[3]);
-
-		void* params[4] = { monoXCurve, monoYCurve, monoZCurve, monoWCurve };
-		return metaData.scriptClass->createInstance("AnimationCurve,AnimationCurve,AnimationCurve,AnimationCurve", params);
-	}
-
-	MonoField* ScriptRootMotion::sPositionField = nullptr;
-	MonoField* ScriptRootMotion::sRotationField = nullptr;
-
-	ScriptRootMotion::ScriptRootMotion(MonoObject* instance)
-		:ScriptObject(instance)
-	{ }
-
-	void ScriptRootMotion::initRuntimeData()
-	{
-		sPositionField = metaData.scriptClass->getField("Position");
-		sRotationField = metaData.scriptClass->getField("Rotation");
-	}
-
-	MonoObject* ScriptRootMotion::toManaged(const SPtr<RootMotion>& rootMotion)
-	{
-		MonoObject* monoPositionCurve = ScriptVector3Curve::toManaged(rootMotion->position);
-		MonoObject* monoRotationCurve = ScriptQuaternionCurve::toManaged(rootMotion->rotation);
-
-		MonoObject* instance = metaData.scriptClass->createInstance();
-		sPositionField->set(instance, monoPositionCurve);
-		sRotationField->set(instance, monoRotationCurve);
-
-		return instance;
-	}
-}

+ 1 - 1
Source/SBansheeEngine/Source/BsScriptAssemblyManager.cpp

@@ -44,12 +44,12 @@
 #include "BsScriptStringTable.h"
 #include "BsScriptGUISkin.h"
 #include "BsScriptAudioClip.h"
-#include "BsScriptAnimationClip.h"
 #include "BsBuiltinResourceLookup.h"
 
 #include "BsScriptMesh.generated.h"
 #include "BsScriptPhysicsMesh.generated.h"
 #include "BsScriptPhysicsMaterial.generated.h"
+#include "BsScriptAnimationClip.generated.h"
 
 namespace bs
 {

+ 1 - 1
Source/SBansheeEngine/Source/BsScriptMaterial.cpp

@@ -72,7 +72,7 @@ namespace bs
 	{
 		HShader shader = nativeInstance->getHandle()->getShader();
 
-		if (shader == nullptr)
+		if (!shader.isLoaded())
 			return nullptr;
 
 		ScriptResourceBase* scriptShader = ScriptResourceManager::instance().getScriptResource(shader, true);

+ 27 - 0
Source/SBansheeEngine/Source/BsScriptQuaternion.cpp

@@ -0,0 +1,27 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsScriptQuaternion.h"
+#include "BsMonoManager.h"
+#include "BsMonoClass.h"
+#include "BsMonoUtil.h"
+
+namespace bs
+{
+	ScriptQuaternion::ScriptQuaternion(MonoObject* instance)
+		:ScriptObject(instance)
+	{ }
+
+	void ScriptQuaternion::initRuntimeData()
+	{ }
+
+	MonoObject* ScriptQuaternion::box(const Quaternion& value)
+	{
+		// We're casting away const but it's fine since structs are passed by value anyway
+		return MonoUtil::box(metaData.scriptClass->_getInternalClass(), (void*)&value);
+	}
+
+	Quaternion ScriptQuaternion::unbox(MonoObject* obj)
+	{
+		return *(Quaternion*)MonoUtil::unbox(obj);
+	}
+}