Selaa lähdekoodia

Exposed morph shapes to C#

BearishSun 9 vuotta sitten
vanhempi
sitoutus
a1d890d07d

+ 14 - 0
Source/BansheeCore/Include/BsAnimation.h

@@ -238,6 +238,20 @@ namespace BansheeEngine
 		 */
 		 */
 		void setSkeleton(const SPtr<Skeleton>& skeleton);
 		void setSkeleton(const SPtr<Skeleton>& skeleton);
 
 
+		/** 
+		 * Sets morph shapes that can be used for per-vertex blending animation. After they're set call 
+		 * setMorphShapeWeight() to apply morph shapes. 
+		 */
+		void setMorphShapes(const SPtr<MorphShapes>& morphShapes);
+
+		/**
+		 * Changes a weight of a single morph shape, determining how much of it to apply on top of the base mesh.
+		 *
+		 * @param idx		Index of the morph shape to modify. This must match the shapes provided to setMorphShapes().
+		 * @param weight	Weight that determines how much of the shape to apply to the mesh, in range [0, 1]. 	
+		 */
+		void setMorphShapeWeight(UINT32 idx, float weight);
+
 		/** 
 		/** 
 		 * Sets a mask that allows certain bones from the skeleton to be disabled. Caller must ensure that the mask matches
 		 * Sets a mask that allows certain bones from the skeleton to be disabled. Caller must ensure that the mask matches
 		 * the skeleton assigned to the animation.
 		 * the skeleton assigned to the animation.

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

@@ -130,6 +130,9 @@ namespace BansheeEngine
 		/** Gets the skeleton required for animation of this mesh, if any is available. */
 		/** Gets the skeleton required for animation of this mesh, if any is available. */
 		SPtr<Skeleton> getSkeleton() const { return mSkeleton; }
 		SPtr<Skeleton> getSkeleton() const { return mSkeleton; }
 
 
+		/** Returns an object containing all shapes used for morph animation, if any are available. */
+		SPtr<MorphShapes> getMorphShapes() const { return mMorphShapes; }
+
 		/** Retrieves a core implementation of a mesh usable only from the core thread. */
 		/** Retrieves a core implementation of a mesh usable only from the core thread. */
 		SPtr<MeshCore> getCore() const;
 		SPtr<MeshCore> getCore() const;
 
 

+ 12 - 0
Source/BansheeCore/Source/BsAnimation.cpp

@@ -571,6 +571,18 @@ namespace BansheeEngine
 		mDirty |= AnimDirtyStateFlag::Skeleton;
 		mDirty |= AnimDirtyStateFlag::Skeleton;
 	}
 	}
 
 
+	void Animation::setMorphShapes(const SPtr<MorphShapes>& morphShapes)
+	{
+		BS_EXCEPT(NotImplementedException, "TODO");
+		// TODO
+	}
+
+	void Animation::setMorphShapeWeight(UINT32 idx, float weight)
+	{
+		BS_EXCEPT(NotImplementedException, "TODO");
+		// TODO
+	}
+
 	void Animation::setMask(const SkeletonMask& mask)
 	void Animation::setMask(const SkeletonMask& mask)
 	{
 	{
 		mSkeletonMask = mask;
 		mSkeletonMask = mask;

+ 3 - 0
Source/BansheeEngine/Include/BsCAnimation.h

@@ -77,6 +77,9 @@ namespace BansheeEngine
 		/** @copydoc Animation::setState */
 		/** @copydoc Animation::setState */
 		void setState(const HAnimationClip& clip, AnimationClipState state);
 		void setState(const HAnimationClip& clip, AnimationClipState state);
 
 
+		/** @copydoc Animation::setMorphShapeWeight */
+		void setMorphShapeWeight(UINT32 idx, float weight);
+
 		/** Sets bounds that will be used for animation and mesh culling. Only relevant if setUseBounds() is set to true. */
 		/** Sets bounds that will be used for animation and mesh culling. Only relevant if setUseBounds() is set to true. */
 		void setBounds(const AABox& bounds);
 		void setBounds(const AABox& bounds);
 
 

+ 6 - 0
Source/BansheeEngine/Source/BsCAnimation.cpp

@@ -118,6 +118,12 @@ namespace BansheeEngine
 			return mInternal->setState(clip, state);
 			return mInternal->setState(clip, state);
 	}
 	}
 
 
+	void CAnimation::setMorphShapeWeight(UINT32 idx, float weight)
+	{
+		if (mInternal != nullptr)
+			return mInternal->setMorphShapeWeight(idx, weight);
+	}
+
 	void CAnimation::setBounds(const AABox& bounds)
 	void CAnimation::setBounds(const AABox& bounds)
 	{
 	{
 		mBounds = bounds;
 		mBounds = bounds;

+ 9 - 0
Source/BansheeEngine/Source/BsRenderable.cpp

@@ -261,7 +261,10 @@ namespace BansheeEngine
 		mAnimation = animation;
 		mAnimation = animation;
 
 
 		if (mAnimation != nullptr && mMesh.isLoaded(false))
 		if (mAnimation != nullptr && mMesh.isLoaded(false))
+		{
 			mAnimation->setSkeleton(mMesh->getSkeleton());
 			mAnimation->setSkeleton(mMesh->getSkeleton());
+			mAnimation->setMorphShapes(mMesh->getMorphShapes());
+		}
 
 
 		_markCoreDirty();
 		_markCoreDirty();
 	}
 	}
@@ -315,9 +318,15 @@ namespace BansheeEngine
 		if(mAnimation != nullptr)
 		if(mAnimation != nullptr)
 		{
 		{
 			if (mMesh.isLoaded(false))
 			if (mMesh.isLoaded(false))
+			{
 				mAnimation->setSkeleton(mMesh->getSkeleton());
 				mAnimation->setSkeleton(mMesh->getSkeleton());
+				mAnimation->setMorphShapes(mMesh->getMorphShapes());
+			}
 			else
 			else
+			{
 				mAnimation->setSkeleton(nullptr);
 				mAnimation->setSkeleton(nullptr);
+				mAnimation->setMorphShapes(nullptr);
+			}
 		}
 		}
 	}
 	}
 
 

+ 35 - 0
Source/MBansheeEngine/Animation/Animation.cs

@@ -376,6 +376,41 @@ namespace BansheeEngine
             }
             }
         }
         }
 
 
+        /// <summary>
+        /// Changes a weight of a single morph shape, determining how much of it to apply on top of the base mesh.
+        /// </summary>
+        /// <param name="name">Name of the morph shape to modify the weight for. This depends on the mesh the animation
+        ///                    is currently animating.</param>
+        /// <param name="weight">Weight that determines how much of the shape to apply to the mesh, in range[0, 1].</param>
+        public void SetMorphShapeWeight(string name, float weight)
+        {
+            switch (state)
+            {
+                case State.Active:
+                    if (animatedRenderable == null)
+                        return;
+
+                    Mesh mesh = animatedRenderable.Mesh;
+                    if (mesh == null)
+                        return;
+
+                    MorphShapes morphShapes = mesh.MorphShapes;
+                    if (morphShapes == null)
+                        return;
+
+                    string[] shapeNames = morphShapes.Shapes;
+                    for (int i = 0; i < shapeNames.Length; i++)
+                    {
+                        if (shapeNames[i] == name)
+                        {
+                            _native.SetMorphShapeWeight(i, weight);
+                            break;
+                        }
+                    }
+                    break;
+            }
+        }
+
         /// <summary>
         /// <summary>
         /// Allows the caller to play an animation clip during edit mode. This form of animation playback is limited as
         /// Allows the caller to play an animation clip during edit mode. This form of animation playback is limited as
         /// you have no control over clip properties, and features like blending, cross fade or animation events are not
         /// you have no control over clip properties, and features like blending, cross fade or animation events are not

+ 8 - 0
Source/MBansheeEngine/Animation/Interop/NativeAnimation.cs

@@ -130,6 +130,11 @@ namespace BansheeEngine
             Internal_SetState(mCachedPtr, clipPtr, ref state);
             Internal_SetState(mCachedPtr, clipPtr, ref state);
         }
         }
 
 
+        public void SetMorphShapeWeight(int idx, float weight)
+        {
+            Internal_SetMorphShapeWeight(mCachedPtr, idx, weight);
+        }
+
         public bool GetGenericCurveValue(int curveIdx, out float value)
         public bool GetGenericCurveValue(int curveIdx, out float value)
         {
         {
             return Internal_GetGenericCurveValue(mCachedPtr, curveIdx, out value);
             return Internal_GetGenericCurveValue(mCachedPtr, curveIdx, out value);
@@ -212,6 +217,9 @@ namespace BansheeEngine
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetState(IntPtr thisPtr, IntPtr clipPtr, ref AnimationClipState state);
         private static extern void Internal_SetState(IntPtr thisPtr, IntPtr clipPtr, ref AnimationClipState state);
 
 
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetMorphShapeWeight(IntPtr thisPtr, int idx, float weight);
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern int Internal_GetNumClips(IntPtr thisPtr);
         private static extern int Internal_GetNumClips(IntPtr thisPtr);
 
 

+ 37 - 0
Source/MBansheeEngine/Animation/MorphShapes.cs

@@ -0,0 +1,37 @@
+//********************************** 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 a set of morph shapes, used for morph target animation. Each morph shape contains a single possible shape
+    /// that can be added on top of the base shape in order to create the animation.
+    /// </summary>
+    public class MorphShapes : ScriptObject
+    {
+        /// <summary>
+        /// Constructor for internal runtime use only.
+        /// </summary>
+        private MorphShapes()
+        { }
+
+        /// <summary>
+        /// Returns a list of names of all available morph shapes.
+        /// </summary>
+        public string[] Shapes
+        {
+            get { return Internal_GetShapes(mCachedPtr); }
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern string[] Internal_GetShapes(IntPtr instance);
+    }
+
+    /** @} */
+}

+ 1 - 0
Source/MBansheeEngine/MBansheeEngine.csproj

@@ -49,6 +49,7 @@
     <Compile Include="Animation\AnimationCurves.cs" />
     <Compile Include="Animation\AnimationCurves.cs" />
     <Compile Include="Animation\Bone.cs" />
     <Compile Include="Animation\Bone.cs" />
     <Compile Include="Animation\Interop\NativeAnimation.cs" />
     <Compile Include="Animation\Interop\NativeAnimation.cs" />
+    <Compile Include="Animation\MorphShapes.cs" />
     <Compile Include="Animation\Skeleton.cs" />
     <Compile Include="Animation\Skeleton.cs" />
     <Compile Include="Audio\Audio.cs" />
     <Compile Include="Audio\Audio.cs" />
     <Compile Include="Audio\AudioClip.cs" />
     <Compile Include="Audio\AudioClip.cs" />

+ 11 - 0
Source/MBansheeEngine/Rendering/Mesh.cs

@@ -160,6 +160,14 @@ namespace BansheeEngine
             get { return Internal_GetSkeleton(mCachedPtr); }
             get { return Internal_GetSkeleton(mCachedPtr); }
         }
         }
 
 
+        /// <summary>
+        /// Returns an object containing all shapes used for morph animation, if any are available.
+        /// </summary>
+        public MorphShapes MorphShapes
+        {
+            get { return Internal_GetMorphShapes(mCachedPtr); }
+        }
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_CreateInstance(Mesh instance, int numVertices,
         private static extern void Internal_CreateInstance(Mesh instance, int numVertices,
             int numIndices, SubMesh[] subMeshes, MeshUsage usage, VertexType vertex, IndexType index);
             int numIndices, SubMesh[] subMeshes, MeshUsage usage, VertexType vertex, IndexType index);
@@ -177,6 +185,9 @@ namespace BansheeEngine
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern Skeleton Internal_GetSkeleton(IntPtr thisPtr);
         private static extern Skeleton Internal_GetSkeleton(IntPtr thisPtr);
 
 
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern MorphShapes Internal_GetMorphShapes(IntPtr thisPtr);
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_GetBounds(IntPtr thisPtr, out AABox box, out Sphere sphere);
         private static extern void Internal_GetBounds(IntPtr thisPtr, out AABox box, out Sphere sphere);
 
 

+ 2 - 1
Source/MBansheeEngine/Rendering/Renderable.cs

@@ -164,7 +164,8 @@ namespace BansheeEngine
         /// <param name="animation">Component that was added</param>
         /// <param name="animation">Component that was added</param>
         internal void RegisterAnimation(Animation animation)
         internal void RegisterAnimation(Animation animation)
         {
         {
-            bool isMeshAnimated = serializableData.mesh != null && serializableData.mesh.Skeleton != null; // TODO - Also check for blend shapes here
+            bool isMeshAnimated = serializableData.mesh != null && 
+                (serializableData.mesh.Skeleton != null || serializableData.mesh.MorphShapes != null);
 
 
             if (!isMeshAnimated)
             if (!isMeshAnimated)
                 return;
                 return;

+ 2 - 0
Source/SBansheeEngine/CMakeSources.cmake

@@ -146,6 +146,7 @@ set(BS_SBANSHEEENGINE_INC_WRAPPERS
 	"Include/BsScriptAnimationCurve.h"
 	"Include/BsScriptAnimationCurve.h"
 	"Include/BsScriptAnimationCurves.h"
 	"Include/BsScriptAnimationCurves.h"
 	"Include/BsScriptSkeleton.h"
 	"Include/BsScriptSkeleton.h"
+	"Include/BsScriptMorphShapes.h"
 )
 )
 
 
 set(BS_SBANSHEEENGINE_INC_WRAPPERS_GUI
 set(BS_SBANSHEEENGINE_INC_WRAPPERS_GUI
@@ -282,6 +283,7 @@ set(BS_SBANSHEEENGINE_SRC_WRAPPERS
 	"Source/BsScriptAnimationCurve.cpp"
 	"Source/BsScriptAnimationCurve.cpp"
 	"Source/BsScriptAnimationCurves.cpp"
 	"Source/BsScriptAnimationCurves.cpp"
 	"Source/BsScriptSkeleton.cpp"
 	"Source/BsScriptSkeleton.cpp"
+	"Source/BsScriptMorphShapes.cpp"
 )
 )
 
 
 set(BS_SBANSHEEENGINE_INC_SERIALIZATION
 set(BS_SBANSHEEENGINE_INC_SERIALIZATION

+ 2 - 0
Source/SBansheeEngine/Include/BsScriptAnimation.h

@@ -55,6 +55,8 @@ namespace BansheeEngine
 		static bool internal_GetState(ScriptAnimation* thisPtr, ScriptAnimationClip* clip, AnimationClipState* state);
 		static bool internal_GetState(ScriptAnimation* thisPtr, ScriptAnimationClip* clip, AnimationClipState* state);
 		static void internal_SetState(ScriptAnimation* thisPtr, ScriptAnimationClip* clip, AnimationClipState* state);
 		static void internal_SetState(ScriptAnimation* thisPtr, ScriptAnimationClip* clip, AnimationClipState* state);
 
 
+		static void internal_SetMorphShapeWeight(ScriptAnimation* thisPtr, UINT32 idx, float weight);
+
 		static UINT32 internal_GetNumClips(ScriptAnimation* thisPtr);
 		static UINT32 internal_GetNumClips(ScriptAnimation* thisPtr);
 		static MonoObject* internal_GetClip(ScriptAnimation* thisPtr, UINT32 idx);
 		static MonoObject* internal_GetClip(ScriptAnimation* thisPtr, UINT32 idx);
 
 

+ 1 - 0
Source/SBansheeEngine/Include/BsScriptMesh.h

@@ -85,6 +85,7 @@ namespace BansheeEngine
 		static MonoArray* internal_GetSubMeshes(ScriptMesh* thisPtr);
 		static MonoArray* internal_GetSubMeshes(ScriptMesh* thisPtr);
 		static UINT32 internal_GetSubMeshCount(ScriptMesh* thisPtr);
 		static UINT32 internal_GetSubMeshCount(ScriptMesh* thisPtr);
 		static MonoObject* internal_GetSkeleton(ScriptMesh* thisPtr);
 		static MonoObject* internal_GetSkeleton(ScriptMesh* thisPtr);
+		static MonoObject* internal_GetMorphShapes(ScriptMesh* thisPtr);
 		static void internal_GetBounds(ScriptMesh* thisPtr, AABox* box, Sphere* sphere);
 		static void internal_GetBounds(ScriptMesh* thisPtr, AABox* box, Sphere* sphere);
 		static MonoObject* internal_GetMeshData(ScriptMesh* thisPtr);
 		static MonoObject* internal_GetMeshData(ScriptMesh* thisPtr);
 		static void internal_SetMeshData(ScriptMesh* thisPtr, ScriptMeshData* value);
 		static void internal_SetMeshData(ScriptMesh* thisPtr, ScriptMeshData* value);

+ 41 - 0
Source/SBansheeEngine/Include/BsScriptMorphShapes.h

@@ -0,0 +1,41 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "BsScriptObject.h"
+#include "BsAnimation.h"
+
+namespace BansheeEngine
+{
+	class ScriptAnimationClip;
+
+	/** @addtogroup ScriptInteropEngine
+	 *  @{
+	 */
+
+	/**	Interop class between C++ & CLR for MorphShapes. */
+	class BS_SCR_BE_EXPORT ScriptMorphShapes : public ScriptObject <ScriptMorphShapes>
+	{
+	public:
+		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "MorphShapes")
+
+		/**	Returns the native wrapped object. */
+		SPtr<MorphShapes> getInternal() const { return mMorphShapes; }
+
+		/** Creates a managed object from the native morph shapes object. */
+		static MonoObject* create(const SPtr<MorphShapes>& morphShapes);
+
+	private:
+		ScriptMorphShapes(MonoObject* managedInstance, const SPtr<MorphShapes>& morphShapes);
+
+		SPtr<MorphShapes> mMorphShapes;
+
+		/************************************************************************/
+		/* 								CLR HOOKS						   		*/
+		/************************************************************************/
+		static MonoArray* internal_GetShapes(ScriptMorphShapes* thisPtr);
+	};
+
+	/** @} */
+}

+ 7 - 0
Source/SBansheeEngine/Source/BsScriptAnimation.cpp

@@ -49,6 +49,8 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_GetState", &ScriptAnimation::internal_GetState);
 		metaData.scriptClass->addInternalCall("Internal_GetState", &ScriptAnimation::internal_GetState);
 		metaData.scriptClass->addInternalCall("Internal_SetState", &ScriptAnimation::internal_SetState);
 		metaData.scriptClass->addInternalCall("Internal_SetState", &ScriptAnimation::internal_SetState);
 
 
+		metaData.scriptClass->addInternalCall("Internal_SetMorphShapeWeight", &ScriptAnimation::internal_SetMorphShapeWeight);
+
 		metaData.scriptClass->addInternalCall("Internal_GetNumClips", &ScriptAnimation::internal_GetNumClips);
 		metaData.scriptClass->addInternalCall("Internal_GetNumClips", &ScriptAnimation::internal_GetNumClips);
 		metaData.scriptClass->addInternalCall("Internal_GetClip", &ScriptAnimation::internal_GetClip);
 		metaData.scriptClass->addInternalCall("Internal_GetClip", &ScriptAnimation::internal_GetClip);
 
 
@@ -192,6 +194,11 @@ namespace BansheeEngine
 		thisPtr->getInternal()->setState(nativeClip, *state);
 		thisPtr->getInternal()->setState(nativeClip, *state);
 	}
 	}
 
 
+	void ScriptAnimation::internal_SetMorphShapeWeight(ScriptAnimation* thisPtr, UINT32 idx, float weight)
+	{
+		thisPtr->getInternal()->setMorphShapeWeight(idx, weight);
+	}
+
 	bool ScriptAnimation::internal_GetGenericCurveValue(ScriptAnimation* thisPtr, UINT32 curveIdx, float* value)
 	bool ScriptAnimation::internal_GetGenericCurveValue(ScriptAnimation* thisPtr, UINT32 curveIdx, float* value)
 	{
 	{
 		return thisPtr->getInternal()->getGenericCurveValue(curveIdx, *value);
 		return thisPtr->getInternal()->getGenericCurveValue(curveIdx, *value);

+ 13 - 0
Source/SBansheeEngine/Source/BsScriptMesh.cpp

@@ -9,6 +9,7 @@
 #include "BsMonoManager.h"
 #include "BsMonoManager.h"
 #include "BsCoreThread.h"
 #include "BsCoreThread.h"
 #include "BsScriptSkeleton.h"
 #include "BsScriptSkeleton.h"
+#include "BsScriptMorphShapes.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
@@ -43,6 +44,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_GetSubMeshes", &ScriptMesh::internal_GetSubMeshes);
 		metaData.scriptClass->addInternalCall("Internal_GetSubMeshes", &ScriptMesh::internal_GetSubMeshes);
 		metaData.scriptClass->addInternalCall("Internal_GetSubMeshCount", &ScriptMesh::internal_GetSubMeshCount);
 		metaData.scriptClass->addInternalCall("Internal_GetSubMeshCount", &ScriptMesh::internal_GetSubMeshCount);
 		metaData.scriptClass->addInternalCall("Internal_GetSkeleton", &ScriptMesh::internal_GetSkeleton);
 		metaData.scriptClass->addInternalCall("Internal_GetSkeleton", &ScriptMesh::internal_GetSkeleton);
+		metaData.scriptClass->addInternalCall("Internal_GetMorphShapes", &ScriptMesh::internal_GetMorphShapes);
 		metaData.scriptClass->addInternalCall("Internal_GetBounds", &ScriptMesh::internal_GetBounds);
 		metaData.scriptClass->addInternalCall("Internal_GetBounds", &ScriptMesh::internal_GetBounds);
 		metaData.scriptClass->addInternalCall("Internal_GetMeshData", &ScriptMesh::internal_GetMeshData);
 		metaData.scriptClass->addInternalCall("Internal_GetMeshData", &ScriptMesh::internal_GetMeshData);
 		metaData.scriptClass->addInternalCall("Internal_SetMeshData", &ScriptMesh::internal_SetMeshData);
 		metaData.scriptClass->addInternalCall("Internal_SetMeshData", &ScriptMesh::internal_SetMeshData);
@@ -126,6 +128,17 @@ namespace BansheeEngine
 		return ScriptSkeleton::create(skeleton);
 		return ScriptSkeleton::create(skeleton);
 	}
 	}
 
 
+	MonoObject* ScriptMesh::internal_GetMorphShapes(ScriptMesh* thisPtr)
+	{
+		HMesh mesh = thisPtr->getHandle();
+
+		SPtr<MorphShapes> morphShapes = mesh->getMorphShapes();
+		if (morphShapes == nullptr)
+			return nullptr;
+
+		return ScriptMorphShapes::create(morphShapes);
+	}
+
 	void ScriptMesh::internal_GetBounds(ScriptMesh* thisPtr, AABox* box, Sphere* sphere)
 	void ScriptMesh::internal_GetBounds(ScriptMesh* thisPtr, AABox* box, Sphere* sphere)
 	{
 	{
 		HMesh mesh = thisPtr->getHandle();
 		HMesh mesh = thisPtr->getHandle();

+ 48 - 0
Source/SBansheeEngine/Source/BsScriptMorphShapes.cpp

@@ -0,0 +1,48 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsScriptMorphShapes.h"
+#include "BsScriptMeta.h"
+#include "BsMonoField.h"
+#include "BsMonoMethod.h"
+#include "BsMonoClass.h"
+#include "BsMonoManager.h"
+#include "BsMonoUtil.h"
+#include "BsMorphShapes.h"
+
+using namespace std::placeholders;
+
+namespace BansheeEngine
+{
+	ScriptMorphShapes::ScriptMorphShapes(MonoObject* managedInstance, const SPtr<MorphShapes>& morphShapes)
+		:ScriptObject(managedInstance), mMorphShapes(morphShapes)
+	{ }
+
+	void ScriptMorphShapes::initRuntimeData()
+	{
+		metaData.scriptClass->addInternalCall("Internal_GetShapes", &ScriptMorphShapes::internal_GetShapes);
+	}
+
+	MonoObject* ScriptMorphShapes::create(const SPtr<MorphShapes>& morphShapes)
+	{
+		MonoObject* instance = metaData.scriptClass->createInstance();
+
+		new (bs_alloc<ScriptMorphShapes>()) ScriptMorphShapes(instance, morphShapes);
+		return instance;
+	}
+
+	MonoArray* ScriptMorphShapes::internal_GetShapes(ScriptMorphShapes* thisPtr)
+	{
+		SPtr<MorphShapes> morphShapes = thisPtr->getInternal();
+
+		UINT32 numShapes = morphShapes->getNumShapes();
+		ScriptArray scriptArray(MonoUtil::getStringClass(), numShapes);
+
+		for (UINT32 i = 0; i < numShapes; i++)
+		{
+			MonoString* monoString = MonoUtil::stringToMono(morphShapes->getShape(i)->getName());
+			scriptArray.set(i, monoString);
+		}
+
+		return scriptArray.getInternal();
+	}
+}