Răsfoiți Sursa

Joints limits and drivers are now passed as boxed between managed and native code

BearishSun 9 ani în urmă
părinte
comite
30f4ca0e25

+ 161 - 161
Source/BansheeMono/Include/BsMonoUtil.h

@@ -1,162 +1,162 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#pragma once
-
-#include "BsMonoPrerequisites.h"
-#include "BsException.h"
-#include "BsDebug.h"
-#include "BsMonoArray.h"
-#include <mono/jit/jit.h>
-#include <codecvt>
-
-namespace BansheeEngine
-{
-	/** @addtogroup Mono
-	 *  @{
-	 */
-
-	/**	Utility class containing methods for various common Mono/Script related operations. */
-	class BS_MONO_EXPORT MonoUtil
-	{
-	public:
-		/**	Converts a Mono (i.e. managed) string to a native wide string. */
-		static WString monoToWString(MonoString* str)
-		{
-			if(str == nullptr)
-				return StringUtil::WBLANK;
-
-			int len = mono_string_length(str);
-			mono_unichar2* monoChars = mono_string_chars(str);
-
-			WString ret(len, '0');
-			for(int i = 0; i < len; i++)
-				ret[i] = monoChars[i];
-
-			return ret;
-		}
-
-		/**	Converts a Mono (i.e. managed) string to a native narrow string. */
-		static String monoToString(MonoString* str)
-		{
-			if(str == nullptr)
-				return StringUtil::BLANK;
-
-			int len = mono_string_length(str);
-			mono_unichar2* monoChars = mono_string_chars(str);
-
-			String ret(len, '0');
-			for(int i = 0; i < len; i++)
-				ret[i] = (char)monoChars[i];
-
-			return ret;
-		}
-
-		/**	Converts a native wide string to a Mono (i.e. managed) string. */
-		static MonoString* wstringToMono(const WString& str)
-		{
-			if (sizeof(wchar_t) == 2) // Assuming UTF-16
-				return mono_string_from_utf16((mono_unichar2*)str.c_str());
-			else // Assuming UTF-32
-			{
-				const std::codecvt_mode convMode = (std::codecvt_mode)(std::little_endian);
-				typedef std::codecvt_utf16<UINT32, 1114111, convMode> utf16utf32;
-
-				std::wstring_convert<utf16utf32, UINT32> conversion("?");
-				UINT32* start = (UINT32*)str.data();
-				UINT32* end = (start + (str.size() - 1) / 4);
-
-				mono_unichar2* convertedStr = (mono_unichar2*)conversion.to_bytes(start, end).c_str();
-				return mono_string_from_utf16(convertedStr);
-			}
-		}
-
-		/**	Converts a native narrow string to a Mono (i.e. managed) string. */
-		static MonoString* stringToMono(const String& str)
-		{
-			return wstringToMono(toWString(str));
-		}
-
-		/**	Outputs name and namespace for the type of the specified object. */
-		static void getClassName(MonoObject* obj, String& ns, String& typeName)
-		{
-			if (obj == nullptr)
-				return;
-
-			::MonoClass* monoClass = mono_object_get_class(obj);
-			getClassName(monoClass, ns, typeName);
-		}
-
-		/**	Outputs name and namespace for the specified type. */
-		static void getClassName(::MonoClass* monoClass, String& ns, String& typeName)
-		{
-			::MonoClass* nestingClass = mono_class_get_nesting_type(monoClass);
-
-			if (nestingClass == nullptr)
-			{
-				ns = mono_class_get_namespace(monoClass);
-				typeName = mono_class_get_name(monoClass);
-
-				return;
-			}
-			else
-			{
-				typeName = String("+") + mono_class_get_name(monoClass);
-
-				do 
-				{
-					::MonoClass* nextNestingClass = mono_class_get_nesting_type(nestingClass);
-					if (nextNestingClass != nullptr)
-					{
-						typeName = String("+") + mono_class_get_name(nestingClass) + typeName;
-						nestingClass = nextNestingClass;
-					}
-					else
-					{
-						ns = mono_class_get_namespace(nestingClass);
-						typeName = mono_class_get_name(nestingClass) + typeName;
-
-						break;
-					}
-				} while (true);
-			}
-		}
-
-		/** @copydoc throwIfException */
-		static void throwIfException(MonoException* exception)
-		{
-			throwIfException(reinterpret_cast<MonoObject*>(exception));
-		}
-
-		/**	Throws a native exception if the provided object is a valid managed exception. */
-		static void throwIfException(MonoObject* exception)
-		{
-			if(exception != nullptr)
-			{
-				::MonoClass* exceptionClass = mono_object_get_class(exception);
-				::MonoProperty* exceptionMsgProp = mono_class_get_property_from_name(exceptionClass, "Message");
-				::MonoMethod* exceptionMsgGetter = mono_property_get_get_method(exceptionMsgProp);
-				MonoString* exceptionMsg = (MonoString*)mono_runtime_invoke(exceptionMsgGetter, exception, nullptr, nullptr);
-
-				::MonoProperty* exceptionStackProp = mono_class_get_property_from_name(exceptionClass, "StackTrace");
-				::MonoMethod* exceptionStackGetter = mono_property_get_get_method(exceptionStackProp);
-				MonoString* exceptionStackTrace = (MonoString*)mono_runtime_invoke(exceptionStackGetter, exception, nullptr, nullptr);
-
-				// Note: If you modify this format make sure to also modify Debug.ParseExceptionMessage in managed code.
-				String msg =  "Managed exception: " + toString(monoToWString(exceptionMsg)) + "\n" + toString(monoToWString(exceptionStackTrace));
-
-				LOGERR(msg);
-			}
-		}
-
-		template<class T, class... Args>
-		static void invokeThunk(T* thunk, Args... args)
-		{
-			MonoException* exception = nullptr;
-			thunk(std::forward<Args>(args)..., &exception);
-
-			throwIfException(exception);
-		}
-	};
-
-	/** @} */
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsMonoPrerequisites.h"
+#include "BsException.h"
+#include "BsDebug.h"
+#include "BsMonoArray.h"
+#include <mono/jit/jit.h>
+#include <codecvt>
+
+namespace BansheeEngine
+{
+	/** @addtogroup Mono
+	 *  @{
+	 */
+
+	/**	Utility class containing methods for various common Mono/Script related operations. */
+	class BS_MONO_EXPORT MonoUtil
+	{
+	public:
+		/**	Converts a Mono (i.e. managed) string to a native wide string. */
+		static WString monoToWString(MonoString* str)
+		{
+			if(str == nullptr)
+				return StringUtil::WBLANK;
+
+			int len = mono_string_length(str);
+			mono_unichar2* monoChars = mono_string_chars(str);
+
+			WString ret(len, '0');
+			for(int i = 0; i < len; i++)
+				ret[i] = monoChars[i];
+
+			return ret;
+		}
+
+		/**	Converts a Mono (i.e. managed) string to a native narrow string. */
+		static String monoToString(MonoString* str)
+		{
+			if(str == nullptr)
+				return StringUtil::BLANK;
+
+			int len = mono_string_length(str);
+			mono_unichar2* monoChars = mono_string_chars(str);
+
+			String ret(len, '0');
+			for(int i = 0; i < len; i++)
+				ret[i] = (char)monoChars[i];
+
+			return ret;
+		}
+
+		/**	Converts a native wide string to a Mono (i.e. managed) string. */
+		static MonoString* wstringToMono(const WString& str)
+		{
+			if (sizeof(wchar_t) == 2) // Assuming UTF-16
+				return mono_string_from_utf16((mono_unichar2*)str.c_str());
+			else // Assuming UTF-32
+			{
+				const std::codecvt_mode convMode = (std::codecvt_mode)(std::little_endian);
+				typedef std::codecvt_utf16<UINT32, 1114111, convMode> utf16utf32;
+
+				std::wstring_convert<utf16utf32, UINT32> conversion("?");
+				UINT32* start = (UINT32*)str.data();
+				UINT32* end = (start + (str.size() - 1) / 4);
+
+				mono_unichar2* convertedStr = (mono_unichar2*)conversion.to_bytes(start, end).c_str();
+				return mono_string_from_utf16(convertedStr);
+			}
+		}
+
+		/**	Converts a native narrow string to a Mono (i.e. managed) string. */
+		static MonoString* stringToMono(const String& str)
+		{
+			return wstringToMono(toWString(str));
+		}
+
+		/**	Outputs name and namespace for the type of the specified object. */
+		static void getClassName(MonoObject* obj, String& ns, String& typeName)
+		{
+			if (obj == nullptr)
+				return;
+
+			::MonoClass* monoClass = mono_object_get_class(obj);
+			getClassName(monoClass, ns, typeName);
+		}
+
+		/**	Outputs name and namespace for the specified type. */
+		static void getClassName(::MonoClass* monoClass, String& ns, String& typeName)
+		{
+			::MonoClass* nestingClass = mono_class_get_nesting_type(monoClass);
+
+			if (nestingClass == nullptr)
+			{
+				ns = mono_class_get_namespace(monoClass);
+				typeName = mono_class_get_name(monoClass);
+
+				return;
+			}
+			else
+			{
+				typeName = String("+") + mono_class_get_name(monoClass);
+
+				do 
+				{
+					::MonoClass* nextNestingClass = mono_class_get_nesting_type(nestingClass);
+					if (nextNestingClass != nullptr)
+					{
+						typeName = String("+") + mono_class_get_name(nestingClass) + typeName;
+						nestingClass = nextNestingClass;
+					}
+					else
+					{
+						ns = mono_class_get_namespace(nestingClass);
+						typeName = mono_class_get_name(nestingClass) + typeName;
+
+						break;
+					}
+				} while (true);
+			}
+		}
+
+		/** @copydoc throwIfException */
+		static void throwIfException(MonoException* exception)
+		{
+			throwIfException(reinterpret_cast<MonoObject*>(exception));
+		}
+
+		/**	Throws a native exception if the provided object is a valid managed exception. */
+		static void throwIfException(MonoObject* exception)
+		{
+			if(exception != nullptr)
+			{
+				::MonoClass* exceptionClass = mono_object_get_class(exception);
+				::MonoProperty* exceptionMsgProp = mono_class_get_property_from_name(exceptionClass, "Message");
+				::MonoMethod* exceptionMsgGetter = mono_property_get_get_method(exceptionMsgProp);
+				MonoString* exceptionMsg = (MonoString*)mono_runtime_invoke(exceptionMsgGetter, exception, nullptr, nullptr);
+
+				::MonoProperty* exceptionStackProp = mono_class_get_property_from_name(exceptionClass, "StackTrace");
+				::MonoMethod* exceptionStackGetter = mono_property_get_get_method(exceptionStackProp);
+				MonoString* exceptionStackTrace = (MonoString*)mono_runtime_invoke(exceptionStackGetter, exception, nullptr, nullptr);
+
+				// Note: If you modify this format make sure to also modify Debug.ParseExceptionMessage in managed code.
+				String msg =  "Managed exception: " + toString(monoToWString(exceptionMsg)) + "\n" + toString(monoToWString(exceptionStackTrace));
+
+				LOGERR(msg);
+			}
+		}
+
+		template<class T, class... Args>
+		static void invokeThunk(T* thunk, Args... args)
+		{
+			MonoException* exception = nullptr;
+			thunk(std::forward<Args>(args)..., &exception);
+
+			throwIfException(exception);
+		}
+	};
+
+	/** @} */
 }
 }

+ 27 - 14
Source/MBansheeEngine/Physics/Joint.cs

@@ -581,10 +581,10 @@ namespace BansheeEngine
         /// <summary>
         /// <summary>
         /// Used for accessing drive data from native code.
         /// Used for accessing drive data from native code.
         /// </summary>
         /// </summary>
-        /// <param name="output">Native readable drive structure.</param>
-        private void Internal_GetNative(out D6JointDriveData output)
+        /// <returns>Native readable drive structure.</returns>
+        private D6JointDriveData Internal_GetNative()
         {
         {
-            output = data;
+            return data;
         }
         }
     }
     }
 
 
@@ -683,10 +683,10 @@ namespace BansheeEngine
         /// <summary>
         /// <summary>
         /// Used for accessing drive data from native code.
         /// Used for accessing drive data from native code.
         /// </summary>
         /// </summary>
-        /// <param name="output">Native readable drive structure.</param>
-        private void Internal_GetNative(out HingeJointDriveData output)
+        /// <returns>Native readable drive structure.</returns>
+        private HingeJointDriveData Internal_GetNative()
         {
         {
-            output = data;
+            return data;
         }
         }
     };
     };
 
 
@@ -873,14 +873,18 @@ namespace BansheeEngine
         /// <summary>
         /// <summary>
         /// Used for accessing limit data from native code.
         /// Used for accessing limit data from native code.
         /// </summary>
         /// </summary>
-        /// <param name="output">Native readable limit structure.</param>
-        private void Internal_GetNative(ref ScriptLimitLinearRange output)
+        /// <returns>Native readable limit structure.</returns>
+        private ScriptLimitLinearRange Internal_GetNative()
         {
         {
+            ScriptLimitLinearRange output;
+
             output.contactDist = ContactDist;
             output.contactDist = ContactDist;
             output.restitution = Restitution;
             output.restitution = Restitution;
             output.spring = Spring;
             output.spring = Spring;
             output.lower = Lower;
             output.lower = Lower;
             output.upper = Upper;
             output.upper = Upper;
+
+            return output;
         }
         }
     }
     }
 
 
@@ -977,13 +981,16 @@ namespace BansheeEngine
         /// <summary>
         /// <summary>
         /// Used for accessing limit data from native code.
         /// Used for accessing limit data from native code.
         /// </summary>
         /// </summary>
-        /// <param name="output">Native readable limit structure.</param>
-        private void Internal_GetNative(ref ScriptLimitLinear output)
+        /// <returns>Native readable limit structure.</returns>
+        private ScriptLimitLinear Internal_GetNative()
         {
         {
+            ScriptLimitLinear output;
             output.contactDist = ContactDist;
             output.contactDist = ContactDist;
             output.restitution = Restitution;
             output.restitution = Restitution;
             output.spring = Spring;
             output.spring = Spring;
             output.extent = Extent;
             output.extent = Extent;
+
+            return output;
         }
         }
     }
     }
 
 
@@ -1089,14 +1096,17 @@ namespace BansheeEngine
         /// <summary>
         /// <summary>
         /// Used for accessing limit data from native code.
         /// Used for accessing limit data from native code.
         /// </summary>
         /// </summary>
-        /// <param name="output">Native readable limit structure.</param>
-        private void Internal_GetNative(ref ScriptLimitAngularRange output)
+        /// <returns>Native readable limit structure.</returns>
+        private ScriptLimitAngularRange Internal_GetNative()
         {
         {
+            ScriptLimitAngularRange output;
             output.contactDist = ContactDist;
             output.contactDist = ContactDist;
             output.restitution = Restitution;
             output.restitution = Restitution;
             output.spring = Spring;
             output.spring = Spring;
             output.lower = Lower;
             output.lower = Lower;
             output.upper = Upper;
             output.upper = Upper;
+
+            return output;
         }
         }
     }
     }
 
 
@@ -1205,14 +1215,17 @@ namespace BansheeEngine
         /// <summary>
         /// <summary>
         /// Used for accessing limit data from native code.
         /// Used for accessing limit data from native code.
         /// </summary>
         /// </summary>
-        /// <param name="output">Native readable limit structure.</param>
-        private void Internal_GetNative(ref ScriptLimitConeRange output)
+        /// <returns>Native readable limit structure.</returns>
+        private ScriptLimitConeRange Internal_GetNative()
         {
         {
+            ScriptLimitConeRange output;
             output.contactDist = ContactDist;
             output.contactDist = ContactDist;
             output.restitution = Restitution;
             output.restitution = Restitution;
             output.spring = Spring;
             output.spring = Spring;
             output.yLimitAngle = YLimitAngle;
             output.yLimitAngle = YLimitAngle;
             output.zLimitAngle = ZLimitAngle;
             output.zLimitAngle = ZLimitAngle;
+
+            return output;
         }
         }
 	}
 	}
 
 

+ 6 - 6
Source/SBansheeEngine/Include/BsScriptJointCommon.h

@@ -29,7 +29,7 @@ namespace BansheeEngine
 		/************************************************************************/
 		/************************************************************************/
 		/* 								CLR HOOKS						   		*/
 		/* 								CLR HOOKS						   		*/
 		/************************************************************************/
 		/************************************************************************/
-		typedef void(__stdcall *GetNativeDataThunkDef) (MonoObject*, D6Joint::Drive*, MonoException**);
+		typedef MonoObject*(__stdcall *GetNativeDataThunkDef) (MonoObject*, MonoException**);
 
 
 		static GetNativeDataThunkDef getNativeDataThunk;
 		static GetNativeDataThunkDef getNativeDataThunk;
 	};
 	};
@@ -49,7 +49,7 @@ namespace BansheeEngine
 		/************************************************************************/
 		/************************************************************************/
 		/* 								CLR HOOKS						   		*/
 		/* 								CLR HOOKS						   		*/
 		/************************************************************************/
 		/************************************************************************/
-		typedef void(__stdcall *GetNativeDataThunkDef) (MonoObject*, HingeJoint::Drive*, MonoException**);
+		typedef MonoObject*(__stdcall *GetNativeDataThunkDef) (MonoObject*, MonoException**);
 
 
 		static GetNativeDataThunkDef getNativeDataThunk;
 		static GetNativeDataThunkDef getNativeDataThunk;
 	};
 	};
@@ -69,7 +69,7 @@ namespace BansheeEngine
 		/************************************************************************/
 		/************************************************************************/
 		/* 								CLR HOOKS						   		*/
 		/* 								CLR HOOKS						   		*/
 		/************************************************************************/
 		/************************************************************************/
-		typedef void(__stdcall *GetNativeDataThunkDef) (MonoObject*, LimitLinearRange*, MonoException**);
+		typedef MonoObject*(__stdcall *GetNativeDataThunkDef) (MonoObject*, MonoException**);
 
 
 		static GetNativeDataThunkDef getNativeDataThunk;
 		static GetNativeDataThunkDef getNativeDataThunk;
 	};
 	};
@@ -89,7 +89,7 @@ namespace BansheeEngine
 		/************************************************************************/
 		/************************************************************************/
 		/* 								CLR HOOKS						   		*/
 		/* 								CLR HOOKS						   		*/
 		/************************************************************************/
 		/************************************************************************/
-		typedef void(__stdcall *GetNativeDataThunkDef) (MonoObject*, LimitLinear*, MonoException**);
+		typedef MonoObject*(__stdcall *GetNativeDataThunkDef) (MonoObject*, MonoException**);
 
 
 		static GetNativeDataThunkDef getNativeDataThunk;
 		static GetNativeDataThunkDef getNativeDataThunk;
 	};
 	};
@@ -109,7 +109,7 @@ namespace BansheeEngine
 		/************************************************************************/
 		/************************************************************************/
 		/* 								CLR HOOKS						   		*/
 		/* 								CLR HOOKS						   		*/
 		/************************************************************************/
 		/************************************************************************/
-		typedef void(__stdcall *GetNativeDataThunkDef) (MonoObject*, LimitAngularRange*, MonoException**);
+		typedef MonoObject*(__stdcall *GetNativeDataThunkDef) (MonoObject*, MonoException**);
 
 
 		static GetNativeDataThunkDef getNativeDataThunk;
 		static GetNativeDataThunkDef getNativeDataThunk;
 	};
 	};
@@ -129,7 +129,7 @@ namespace BansheeEngine
 		/************************************************************************/
 		/************************************************************************/
 		/* 								CLR HOOKS						   		*/
 		/* 								CLR HOOKS						   		*/
 		/************************************************************************/
 		/************************************************************************/
-		typedef void(__stdcall *GetNativeDataThunkDef) (MonoObject*, LimitConeRange*, MonoException**);
+		typedef MonoObject*(__stdcall *GetNativeDataThunkDef) (MonoObject*, MonoException**);
 
 
 		static GetNativeDataThunkDef getNativeDataThunk;
 		static GetNativeDataThunkDef getNativeDataThunk;
 	};
 	};

+ 128 - 116
Source/SBansheeEngine/Source/BsScriptJointCommon.cpp

@@ -1,117 +1,129 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#include "BsScriptJointCommon.h"
-#include "BsMonoClass.h"
-#include "BsMonoMethod.h"
-#include "BsMonoUtil.h"
-
-namespace BansheeEngine
-{
-	ScriptD6JointDrive::GetNativeDataThunkDef ScriptD6JointDrive::getNativeDataThunk = nullptr;
-
-	ScriptD6JointDrive::ScriptD6JointDrive(MonoObject* instance)
-		:ScriptObject(instance)
-	{ }
-
-	void ScriptD6JointDrive::initRuntimeData()
-	{
-		getNativeDataThunk = (GetNativeDataThunkDef)metaData.scriptClass->getMethod("Internal_GetNative", 1)->getThunk();
-	}
-
-	D6Joint::Drive ScriptD6JointDrive::convert(MonoObject* instance)
-	{
-		D6Joint::Drive output;
-		MonoUtil::invokeThunk(getNativeDataThunk, instance, &output);
-		return output;
-	}
-
-	ScriptHingeJointDrive::GetNativeDataThunkDef ScriptHingeJointDrive::getNativeDataThunk = nullptr;
-
-	ScriptHingeJointDrive::ScriptHingeJointDrive(MonoObject* instance)
-		:ScriptObject(instance)
-	{ }
-
-	void ScriptHingeJointDrive::initRuntimeData()
-	{
-		getNativeDataThunk = (GetNativeDataThunkDef)metaData.scriptClass->getMethod("Internal_GetNative", 1)->getThunk();
-	}
-
-	HingeJoint::Drive ScriptHingeJointDrive::convert(MonoObject* instance)
-	{
-		HingeJoint::Drive output;
-		MonoUtil::invokeThunk(getNativeDataThunk, instance, &output);
-		return output;
-	}
-
-	ScriptLimitLinearRange::GetNativeDataThunkDef ScriptLimitLinearRange::getNativeDataThunk = nullptr;
-
-	ScriptLimitLinearRange::ScriptLimitLinearRange(MonoObject* instance)
-		:ScriptObject(instance)
-	{ }
-
-	void ScriptLimitLinearRange::initRuntimeData()
-	{
-		getNativeDataThunk = (GetNativeDataThunkDef)metaData.scriptClass->getMethod("Internal_GetNative", 1)->getThunk();
-	}
-
-	LimitLinearRange ScriptLimitLinearRange::convert(MonoObject* instance)
-	{
-		LimitLinearRange output;
-		MonoUtil::invokeThunk(getNativeDataThunk, instance, &output);
-		return output;
-	}
-
-	ScriptLimitLinear::GetNativeDataThunkDef ScriptLimitLinear::getNativeDataThunk = nullptr;
-
-	ScriptLimitLinear::ScriptLimitLinear(MonoObject* instance)
-		:ScriptObject(instance)
-	{ }
-
-	void ScriptLimitLinear::initRuntimeData()
-	{
-		getNativeDataThunk = (GetNativeDataThunkDef)metaData.scriptClass->getMethod("Internal_GetNative", 1)->getThunk();
-	}
-
-	LimitLinear ScriptLimitLinear::convert(MonoObject* instance)
-	{
-		LimitLinear output;
-		MonoUtil::invokeThunk(getNativeDataThunk, instance, &output);
-		return output;
-	}
-
-	ScriptLimitAngularRange::GetNativeDataThunkDef ScriptLimitAngularRange::getNativeDataThunk = nullptr;
-
-	ScriptLimitAngularRange::ScriptLimitAngularRange(MonoObject* instance)
-		:ScriptObject(instance)
-	{ }
-
-	void ScriptLimitAngularRange::initRuntimeData()
-	{
-		getNativeDataThunk = (GetNativeDataThunkDef)metaData.scriptClass->getMethod("Internal_GetNative", 1)->getThunk();
-	}
-
-	LimitAngularRange ScriptLimitAngularRange::convert(MonoObject* instance)
-	{
-		LimitAngularRange output;
-		MonoUtil::invokeThunk(getNativeDataThunk, instance, &output);
-		return output;
-	}
-
-	ScriptLimitConeRange::GetNativeDataThunkDef ScriptLimitConeRange::getNativeDataThunk = nullptr;
-
-	ScriptLimitConeRange::ScriptLimitConeRange(MonoObject* instance)
-		:ScriptObject(instance)
-	{ }
-
-	void ScriptLimitConeRange::initRuntimeData()
-	{
-		getNativeDataThunk = (GetNativeDataThunkDef)metaData.scriptClass->getMethod("Internal_GetNative", 1)->getThunk();
-	}
-
-	LimitConeRange ScriptLimitConeRange::convert(MonoObject* instance)
-	{
-		LimitConeRange output;
-		MonoUtil::invokeThunk(getNativeDataThunk, instance, &output);
-		return output;
-	}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsScriptJointCommon.h"
+#include "BsMonoClass.h"
+#include "BsMonoMethod.h"
+#include "BsMonoUtil.h"
+
+namespace BansheeEngine
+{
+	ScriptD6JointDrive::GetNativeDataThunkDef ScriptD6JointDrive::getNativeDataThunk = nullptr;
+
+	ScriptD6JointDrive::ScriptD6JointDrive(MonoObject* instance)
+		:ScriptObject(instance)
+	{ }
+
+	void ScriptD6JointDrive::initRuntimeData()
+	{
+		getNativeDataThunk = (GetNativeDataThunkDef)metaData.scriptClass->getMethod("Internal_GetNative", 1)->getThunk();
+	}
+
+	D6Joint::Drive ScriptD6JointDrive::convert(MonoObject* instance)
+	{
+		MonoException* exception = nullptr;
+		MonoObject* boxedOutput = getNativeDataThunk(instance, &exception);
+
+		MonoUtil::throwIfException(exception);
+		return *(D6Joint::Drive*)mono_object_unbox(boxedOutput);
+	}
+
+	ScriptHingeJointDrive::GetNativeDataThunkDef ScriptHingeJointDrive::getNativeDataThunk = nullptr;
+
+	ScriptHingeJointDrive::ScriptHingeJointDrive(MonoObject* instance)
+		:ScriptObject(instance)
+	{ }
+
+	void ScriptHingeJointDrive::initRuntimeData()
+	{
+		getNativeDataThunk = (GetNativeDataThunkDef)metaData.scriptClass->getMethod("Internal_GetNative", 1)->getThunk();
+	}
+
+	HingeJoint::Drive ScriptHingeJointDrive::convert(MonoObject* instance)
+	{
+		MonoException* exception = nullptr;
+		MonoObject* boxedOutput = getNativeDataThunk(instance, &exception);
+
+		MonoUtil::throwIfException(exception);
+		return *(HingeJoint::Drive*)mono_object_unbox(boxedOutput);
+	}
+
+	ScriptLimitLinearRange::GetNativeDataThunkDef ScriptLimitLinearRange::getNativeDataThunk = nullptr;
+
+	ScriptLimitLinearRange::ScriptLimitLinearRange(MonoObject* instance)
+		:ScriptObject(instance)
+	{ }
+
+	void ScriptLimitLinearRange::initRuntimeData()
+	{
+		getNativeDataThunk = (GetNativeDataThunkDef)metaData.scriptClass->getMethod("Internal_GetNative", 1)->getThunk();
+	}
+
+	LimitLinearRange ScriptLimitLinearRange::convert(MonoObject* instance)
+	{
+		MonoException* exception = nullptr;
+		MonoObject* boxedOutput = getNativeDataThunk(instance, &exception);
+
+		MonoUtil::throwIfException(exception);
+		return *(LimitLinearRange*)mono_object_unbox(boxedOutput);
+	}
+
+	ScriptLimitLinear::GetNativeDataThunkDef ScriptLimitLinear::getNativeDataThunk = nullptr;
+
+	ScriptLimitLinear::ScriptLimitLinear(MonoObject* instance)
+		:ScriptObject(instance)
+	{ }
+
+	void ScriptLimitLinear::initRuntimeData()
+	{
+		getNativeDataThunk = (GetNativeDataThunkDef)metaData.scriptClass->getMethod("Internal_GetNative", 1)->getThunk();
+	}
+
+	LimitLinear ScriptLimitLinear::convert(MonoObject* instance)
+	{
+		MonoException* exception = nullptr;
+		MonoObject* boxedOutput = getNativeDataThunk(instance, &exception);
+
+		MonoUtil::throwIfException(exception);
+		return *(LimitLinear*)mono_object_unbox(boxedOutput);
+	}
+
+	ScriptLimitAngularRange::GetNativeDataThunkDef ScriptLimitAngularRange::getNativeDataThunk = nullptr;
+
+	ScriptLimitAngularRange::ScriptLimitAngularRange(MonoObject* instance)
+		:ScriptObject(instance)
+	{ }
+
+	void ScriptLimitAngularRange::initRuntimeData()
+	{
+		getNativeDataThunk = (GetNativeDataThunkDef)metaData.scriptClass->getMethod("Internal_GetNative", 1)->getThunk();
+	}
+
+	LimitAngularRange ScriptLimitAngularRange::convert(MonoObject* instance)
+	{
+		MonoException* exception = nullptr;
+		MonoObject* boxedOutput = getNativeDataThunk(instance, &exception);
+
+		MonoUtil::throwIfException(exception);
+		return *(LimitAngularRange*)mono_object_unbox(boxedOutput);
+	}
+
+	ScriptLimitConeRange::GetNativeDataThunkDef ScriptLimitConeRange::getNativeDataThunk = nullptr;
+
+	ScriptLimitConeRange::ScriptLimitConeRange(MonoObject* instance)
+		:ScriptObject(instance)
+	{ }
+
+	void ScriptLimitConeRange::initRuntimeData()
+	{
+		getNativeDataThunk = (GetNativeDataThunkDef)metaData.scriptClass->getMethod("Internal_GetNative", 1)->getThunk();
+	}
+
+	LimitConeRange ScriptLimitConeRange::convert(MonoObject* instance)
+	{
+		MonoException* exception = nullptr;
+		MonoObject* boxedOutput = getNativeDataThunk(instance, &exception);
+
+		MonoUtil::throwIfException(exception);
+		return *(LimitConeRange*)mono_object_unbox(boxedOutput);
+	}
 }
 }