Ver Fonte

Added C# Rigidbody wrapper

BearishSun há 9 anos atrás
pai
commit
1cc79b5688

+ 8 - 4
BansheeCore/Include/BsCRigidbody.h

@@ -17,7 +17,8 @@ namespace BansheeEngine
 	/**
 	 * @copydoc	Rigidbody
 	 *
-	 * Wraps Rigidbody as a Component.
+	 * Wraps Rigidbody as a Component. Colliders that are on the same scene object as the rigidbody, or on child scene 
+	 * objects are automatically considered as part of the rigidbody.
 	 */
 	class BS_CORE_EXPORT CRigidbody : public Component
 	{
@@ -178,14 +179,17 @@ namespace BansheeEngine
 
 		/** 
 		 * Searches child scene objects for Collider components and attaches them to the rigidbody. Make sure to call
-		 * clearChildColliders() if you need to clear old colliders first. 
+		 * clearColliders() if you need to clear old colliders first. 
 		 */
 		void updateColliders();
 
 		/** Unregisters all child colliders from the Rigidbody. */
 		void clearColliders();
 
-		/** Registers a new collider with the Rigidbody. */
+		/** 
+		 * Registers a new collider with the Rigidbody. This collider will then be used to calculate Rigidbody's geometry
+         * used for collisions, and optionally (depending on set flags) total mass, inertia tensors and center of mass.
+		 */
 		void addCollider(const HCollider& collider);
 
 		/** Unregisters the collider from the Rigidbody. */
@@ -241,7 +245,7 @@ namespace BansheeEngine
 		CollisionReportMode mCollisionReportMode = CollisionReportMode::None;
 		Vector3 mCMassPosition;
 		Quaternion mCMassRotation;
-		Vector3 mIntertiaTensor;
+		Vector3 mInertiaTensor;
 		float mMass = 0.0f;
 		float mMaxAngularVelocity = 1.0f;
 		float mLinearDrag = 0.0f;

+ 2 - 2
BansheeCore/Include/BsCRigidbodyRTTI.h

@@ -22,7 +22,7 @@ namespace BansheeEngine
 		BS_PLAIN_MEMBER(mFlags);
 		BS_PLAIN_MEMBER(mCMassPosition);
 		BS_PLAIN_MEMBER(mCMassRotation);
-		BS_PLAIN_MEMBER(mIntertiaTensor);
+		BS_PLAIN_MEMBER(mInertiaTensor);
 		BS_PLAIN_MEMBER(mMass);
 		BS_PLAIN_MEMBER(mMaxAngularVelocity);
 		BS_PLAIN_MEMBER(mLinearDrag);
@@ -41,7 +41,7 @@ namespace BansheeEngine
 			BS_ADD_PLAIN_FIELD(mFlags, 2);
 			BS_ADD_PLAIN_FIELD(mCMassPosition, 3);
 			BS_ADD_PLAIN_FIELD(mCMassRotation, 4);
-			BS_ADD_PLAIN_FIELD(mIntertiaTensor, 5);
+			BS_ADD_PLAIN_FIELD(mInertiaTensor, 5);
 			BS_ADD_PLAIN_FIELD(mMass, 6);
 			BS_ADD_PLAIN_FIELD(mMaxAngularVelocity, 7);
 			BS_ADD_PLAIN_FIELD(mLinearDrag, 8);

+ 1 - 0
BansheeCore/Include/BsCorePrerequisites.h

@@ -290,6 +290,7 @@ namespace BansheeEngine
 	class StringTable;
 	class PhysicsMaterial;
 	class PhysicsMesh;
+	class CollisionData;
 	// Scene
 	class SceneObject;
 	class Component;

+ 9 - 7
BansheeCore/Include/BsRigidbody.h

@@ -43,7 +43,7 @@ namespace BansheeEngine
 		{
 			/** No options. */
 			None = 0x00,
-			/** Automatically calculate center of mass transform and inertia tensors from child shapes (colliders) */
+			/** Automatically calculate center of mass transform and inertia tensors from child shapes (colliders). */
 			AutoTensors = 0x01,
 			/** Calculate mass distribution from child shapes (colliders). Only relevant when auto-tensors is on. */
 			AutoMass = 0x02,
@@ -151,10 +151,10 @@ namespace BansheeEngine
 		 */
 		virtual void wakeUp() = 0;
 
-		/** Sets a treshold of force and torque under which the object will be considered to be put to sleep. */
+		/** Sets a threshold of force and torque under which the object will be considered to be put to sleep. */
 		virtual void setSleepThreshold(float threshold) = 0;
 
-		/** Gets a treshold of force and torque under which the object will be considered to be put to sleep. */
+		/** Gets a threshold of force and torque under which the object will be considered to be put to sleep. */
 		virtual float getSleepThreshold() const = 0;
 
 		/** Sets whether or not the rigidbody will have the global gravity force applied to it. */
@@ -189,7 +189,8 @@ namespace BansheeEngine
 
 		/** 
 		 * Sets the inertia tensor in local mass space. Inertia tensor determines how difficult is to rotate the object.
-		 * Values of zero in the inertia tensor mean the object will be unable to rotate around a specific axis.
+		 * Values of zero in the inertia tensor mean the object will be unable to rotate around a specific axis. Only 
+		 * relevant if Flag::AutoTensors is turned off.
 		 */
 		virtual void setInertiaTensor(const Vector3& tensor) = 0;
 
@@ -203,10 +204,11 @@ namespace BansheeEngine
 		virtual float getMaxAngularVelocity() const = 0;
 
 		/**
-		 * Sets the rigidbody's center of mass transform. 
+		 * Sets the rigidbody's center of mass transform. Only relevant if Flag::AutoTensors is turned off.
 		 *
 		 * @param[in]	position	Position of the center of mass.
-		 * @param[in]	rotation	Rotation that determines orientation of the inertia tensor.
+		 * @param[in]	rotation	Rotation that determines orientation of the inertia tensor (rotation of the center of 
+		 *							mass frame).
 		 */
 		virtual void setCenterOfMass(const Vector3& position, const Quaternion& rotation) = 0;
 
@@ -239,7 +241,7 @@ namespace BansheeEngine
 		virtual void setInterpolationMode(InterpolationMode value) { mInterpolationMode = value; }
 
 		/** Gets interpolation mode that controls how is the rigidbody transfrom updated from the physics simulation. */
-		virtual InterpolationMode getInterpolationMode(InterpolationMode value) const { return mInterpolationMode; }
+		virtual InterpolationMode getInterpolationMode() const { return mInterpolationMode; }
 
 		/** Sets flags that control the behaviour of the rigidbody. */
 		virtual void setFlags(Flag flags) { mFlags = flags; }

+ 2 - 2
BansheeCore/Source/BsCRigidbody.cpp

@@ -134,7 +134,7 @@ namespace BansheeEngine
 
 	void CRigidbody::setInertiaTensor(const Vector3& tensor)
 	{
-		mIntertiaTensor = tensor;
+		mInertiaTensor = tensor;
 
 		if (mInternal != nullptr)
 			mInternal->setInertiaTensor(tensor);
@@ -446,7 +446,7 @@ namespace BansheeEngine
 		if(((UINT32)mFlags & (UINT32)Rigidbody::Flag::AutoTensors) == 0)
 		{
 			mInternal->setCenterOfMass(mCMassPosition, mCMassRotation);
-			mInternal->setInertiaTensor(mIntertiaTensor);
+			mInternal->setInertiaTensor(mInertiaTensor);
 			mInternal->setMass(mMass);
 		}
 		else

+ 38 - 38
Documentation/GitHub/license.md

@@ -1,39 +1,39 @@
-# License
-
-Banshee if offered using a dual-license model: LGPL v3 and Commercial.
-
-## GNU Lesser General Public License v3
-
-Banshee is offered completely free for personal or commercial use under the GNU Lesser General Public License v3 (LGPL v3). You will find the complete terms of the license in the License sub-directory that comes with the project. 
-
-## Commercial
-A commercial license is available for those that are not comfortable with LGPL terms. The commercial license is a paid per-user license that allows you to distribute your application under your own terms.
-
-It is available under the "pay what you want" model, meaning you can purchase it for as little as $0 or as much as $1000. This is completely up to you and we won't judge if you just want a free license.
-
-However if you like Banshee consider giving us some money as this ensures we can pay the costs for developing it further. All the money will be invested into (in the order of importance):
- - My (the author) living costs, hardware, software and services used for and by Banshee
- - Hiring more developers to help with adding more features faster (see [Roadmap](roadmap.md))
- - Hiring people to help with testing, building demos/examples, managing website, improving documentation and tutorials
- 
-## Third party licenses
-Licences for all third party libraries used by Banshee can be found in License\ThirdParty sub-directory.
-
-## License FAQ
-
-*Why have two separate licenses?*
-LGPL is offered because at its core Banshee is an open source project. Commercial license is offered because we wish to fund Banshee development so we can make it bigger and better than other open source engines and to be able to compete with the big proprietary engines.  
-
-*How do I get a commercial license?*
-Until a website is set up, you must contact me personally at [email protected]
-
-*What are the differences between the two licenses?*
-Engine features for both license models are identical. The only difference are the license terms.
-
-*What are the limitations of the LGPL license?*
-When modifying the source code of the engine, or linking the engine statically with your application you will be required to release your code/application under LGPL or a compatible license.
-
-This involves providing the source code for your application, as well as giving the rights to use, modify and redistribute your code/application to anyone who acquires it.
-
-*What are the limitations of the commercial license?*
+# License
+
+Banshee if offered using a dual-license model: LGPL v3 and Commercial.
+
+## GNU Lesser General Public License v3
+
+Banshee is offered completely free for personal or commercial use under the GNU Lesser General Public License v3 (LGPL v3). You will find the complete terms of the license in the License sub-directory that comes with the project. 
+
+## Commercial
+A commercial license is available for those that are not comfortable with LGPL terms. The commercial license is a paid per-user license that allows you to distribute your application under your own terms.
+
+It is available under the "pay what you want" model, meaning you can purchase it for as little as $0 or as much as $1000. This is completely up to you and we won't judge if you just want a free license.
+
+However if you like Banshee consider giving us some money as this ensures we can pay the costs for developing it further. All the money will be invested into (in the order of importance):
+ - My (the author) living costs, hardware, software and services used for and by Banshee
+ - Hiring more developers to help with adding more features faster (see [Roadmap](roadmap.md))
+ - Hiring people to help with testing, building demos/examples, managing website, improving documentation and tutorials
+ 
+## Third party licenses
+Licenses for all third party libraries used by Banshee can be found in License\ThirdParty sub-directory.
+
+## License FAQ
+
+*Why have two separate licenses?*
+LGPL is offered because at its core Banshee is an open source project. Commercial license is offered because we wish to fund Banshee development so we can make it bigger and better than other open source engines and to be able to compete with the big proprietary engines.  
+
+*How do I get a commercial license?*
+Until a website is set up, you must contact me personally at [email protected]
+
+*What are the differences between the two licenses?*
+Engine features for both license models are identical. The only difference are the license terms.
+
+*What are the limitations of the LGPL license?*
+When modifying the source code of the engine, or linking the engine statically with your application you will be required to release your code/application under LGPL or a compatible license.
+
+This involves providing the source code for your application, as well as giving the rights to use, modify and redistribute your code/application to anyone who acquires it.
+
+*What are the limitations of the commercial license?*
 You can publish binaries of your product (including all portions of Banshee, modified or original) under any terms you wish. The only limitation being that you are not allowed to publish Banshee's source code (modified or original) under a custom license (source code must be published under the LGPL).

+ 45 - 45
Documentation/GitHub/roadmap.md

@@ -1,45 +1,45 @@
-# Roadmap
-
-**Current version: v0.2**
-
----------------------------------------------------
-
-Banshee is currently in development, and the current focus is to finish the most important high level systems so that people can start using it to create games as soon as possible. These systems are:
- - Physics (colliders, triggers, rigidbodies, joints, character controller)
- - Animation (skeletal, blend shapes, generic script variables)
- - Audio (popular file format support, music, 3D audio)
- 
-The plan is to finish these roughly around mid-2016.
-
----------------------------------------------------
-
-Quickly to follow will be:
- - Ports for Linux & Mac
- - Vulkan (and possibly DX12) implementation
- - Physically based renderer
- - Website for the community
- 
-These are planned for an early 2017 release.
-
----------------------------------------------------
-
-There are many more features planned, but these are without a specific timeline or order:
- - Mobile render API (likely Vulkan, possibly Metal for iOS)
- - Android/iOS/WP ports
- - High level networking (replication, RPCs)
- - Global illumination (+ other fancy graphics)
- - Occlussion culling
- - Terrain
- - Effects/Particle editor
- - AI support
- - Cinematics editor
- - Higher level resource streaming support (including level and texture streaming)
- - Unified shading language
- - Visual shader editor
- - More specialized 2D editor features
- - Script debugging
- - Level of detail
- - XBONE/PS4/WIIU ports
- - Much more...
- 
-A /very/ rough estimate is about two months each for every one of these features.
+# Roadmap
+
+**Current version: v0.2**
+
+---------------------------------------------------
+
+Banshee is currently in development, and the current focus is to finish the most important high level systems so that people can start using it to create games as soon as possible. These systems are:
+ - Physics (colliders, triggers, rigidbodies, joints, character controller)
+ - Animation (skeletal, blend shapes, generic script variables)
+ - Audio (popular file format support, music, 3D audio)
+ 
+The plan is to finish these roughly around mid-2016.
+
+---------------------------------------------------
+
+Quickly to follow will be:
+ - Ports for Linux & Mac
+ - Vulkan (and possibly DX12) implementation
+ - Physically based renderer
+ - Website for the community
+ 
+These are planned for an early 2017 release.
+
+---------------------------------------------------
+
+There are many more features planned, but these are without a specific timeline or order:
+ - Mobile render API (likely Vulkan, possibly Metal for iOS)
+ - Android/iOS/WP ports
+ - High level networking (replication, RPCs)
+ - Global illumination (+ other fancy graphics)
+ - Occlussion culling
+ - Terrain
+ - Effects/Particle editor
+ - AI support
+ - Cinematics editor
+ - Higher level resource streaming support (including level and texture streaming)
+ - Unified shading language
+ - Visual shader editor
+ - More specialized 2D editor features
+ - Script debugging
+ - Level of detail
+ - XBONE/PS4/WIIU ports
+ - Much more...
+ 
+A *very* rough estimate is about two months each for every one of these features.

+ 10 - 0
MBansheeEngine/GameObject.cs

@@ -21,4 +21,14 @@ namespace BansheeEngine
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern UInt64 Internal_GetInstanceId(IntPtr thisPtr);
     }
+
+    /// <summary>
+    /// Flags used for notifying child scene object and components when a transform has been changed.
+    /// </summary>
+    public enum TransformChangedFlags
+    {
+        None = 0x00,
+        Transform = 0x01,
+        Parent = 0x02
+    }
 }

+ 1 - 0
MBansheeEngine/MBansheeEngine.csproj

@@ -112,6 +112,7 @@
     <Compile Include="Physics\BoxCollider.cs" />
     <Compile Include="Physics\CapsuleCollider.cs" />
     <Compile Include="Physics\Collider.cs" />
+    <Compile Include="Physics\Joint.cs" />
     <Compile Include="Physics\MeshCollider.cs" />
     <Compile Include="Physics\NativeBoxCollider.cs" />
     <Compile Include="Physics\NativeCapsuleCollider.cs" />

+ 3 - 3
MBansheeEngine/Physics/Collider.cs

@@ -185,7 +185,7 @@ namespace BansheeEngine
         /// <param name="hit">Information about the hit. Valid only if the method returns true.</param>
         /// <param name="maxDist">Maximum distance from the ray origin to search for hits.</param>
         /// <returns>True if the ray has hit the collider.</returns>
-        public bool Raycast(Vector3 origin, Vector3 unitDir, out PhysicsQueryHit hit, float maxDist)
+        public bool Raycast(Vector3 origin, Vector3 unitDir, out PhysicsQueryHit hit, float maxDist = float.MaxValue)
         {
             hit = new PhysicsQueryHit();
 
@@ -279,7 +279,7 @@ namespace BansheeEngine
         /// </summary>
         /// <param name="parent">Rigidbody that is the potential parent.</param>
         /// <returns>True if collider can be a part of the rigidbody.</returns>
-        protected virtual bool IsValidParent(Rigidbody parent)
+        protected internal virtual bool IsValidParent(Rigidbody parent)
         {
             return true;
         }
@@ -363,7 +363,7 @@ namespace BansheeEngine
         /// <summary>
         /// Applies the collision report mode to the internal collider depending on the current state.
         /// </summary>
-        protected void UpdateCollisionReportMode()
+        internal void UpdateCollisionReportMode()
         {
             CollisionReportMode mode = serializableData.collisionReportMode;
 

+ 9 - 0
MBansheeEngine/Physics/Joint.cs

@@ -0,0 +1,9 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+namespace BansheeEngine
+{
+    public class Joint : Component
+    {
+        // TODO
+    }
+}

+ 3 - 0
MBansheeEngine/Physics/NativeCollider.cs

@@ -13,6 +13,9 @@ namespace BansheeEngine
     {
         private Collider component;
 
+        /// <summary>
+        /// Component that owns the native collider object.
+        /// </summary>
         public Collider Component
         {
             get { return component; }

+ 392 - 2
MBansheeEngine/Physics/NativeRigidbody.cs

@@ -1,7 +1,397 @@
-namespace BansheeEngine
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+
+using System;
+using System.Runtime.CompilerServices;
+
+namespace BansheeEngine
 {
+    /// <summary>
+    /// Wrapper around the native Rigidbody class.
+    /// <see cref="Rigidbody"/>
+    /// </summary>
     internal class NativeRigidbody : ScriptObject
     {
-        // TODO
+        private Rigidbody component;
+
+        /// <summary>
+        /// Component that owns the native rigidbody object.
+        /// </summary>
+        public Rigidbody Component
+        {
+            get { return component; }
+            set { component = value; }
+        }
+
+        public Vector3 Position
+        {
+            get { Vector3 pos; Internal_GetPosition(mCachedPtr, out pos); return pos; }
+            set { Quaternion rot = Rotation; Internal_SetTransform(mCachedPtr, ref value, ref rot); }
+        }
+
+        public Quaternion Rotation
+        {
+            get { Quaternion rot; Internal_GetRotation(mCachedPtr, out rot); return rot; }
+            set { Vector3 pos = Position; Internal_SetTransform(mCachedPtr, ref pos, ref value); }
+        }
+
+        public float Mass
+        {
+            get { return Internal_GetMass(mCachedPtr); }
+            set { Internal_SetMass(mCachedPtr, value); }
+        }
+
+        public bool Kinematic
+        {
+            get { return Internal_GetIsKinematic(mCachedPtr); }
+            set { Internal_SetIsKinematic(mCachedPtr, value); }
+        }
+
+        public bool Sleeping
+        {
+            get { return Internal_IsSleeping(mCachedPtr); }
+            set
+            {
+                if (value)
+                    Internal_Sleep(mCachedPtr);
+                else
+                    Internal_WakeUp(mCachedPtr);
+            }
+        }
+
+        public float SleepThreshold
+        {
+            get { return Internal_GetSleepThreshold(mCachedPtr); }
+            set { Internal_SetSleepThreshold(mCachedPtr, value); }
+        }
+
+        public bool UseGravity
+        {
+            get { return Internal_GetUseGravity(mCachedPtr); }
+            set { Internal_SetUseGravity(mCachedPtr, value); }
+        }
+
+        public Vector3 Velocity
+        {
+            get { Vector3 velocity; Internal_GetVelocity(mCachedPtr, out velocity); return velocity; }
+            set { Internal_SetVelocity(mCachedPtr, ref value); }
+        }
+
+        public Vector3 AngularVelocity
+        {
+            get { Vector3 velocity; Internal_GetAngularVelocity(mCachedPtr, out velocity); return velocity; }
+            set { Internal_SetAngularVelocity(mCachedPtr, ref value); }
+        }
+
+        public float Drag
+        {
+            get { return Internal_GetDrag(mCachedPtr); }
+            set { Internal_SetDrag(mCachedPtr, value); }
+        }
+
+        public float AngularDrag
+        {
+            get { return Internal_GetAngularDrag(mCachedPtr); }
+            set { Internal_SetAngularDrag(mCachedPtr, value); }
+        }
+
+        public Vector3 InertiaTensor
+        {
+            get { Vector3 tensor; Internal_GetInertiaTensor(mCachedPtr, out tensor); return tensor; }
+            set { Internal_SetInertiaTensor(mCachedPtr, ref value); }
+        }
+
+        public Vector3 CenterOfMassPosition
+        {
+            get { Vector3 pos; Internal_GetCenterOfMassPosition(mCachedPtr, out pos); return pos; }
+            set { Quaternion rot = CenterOfMassRotation; Internal_SetCenterOfMass(mCachedPtr, ref value, ref rot); }
+        }
+
+        public Quaternion CenterOfMassRotation
+        {
+            get { Quaternion rot; Internal_GetCenterOfMassRotation(mCachedPtr, out rot); return rot; }
+            set { Vector3 pos = CenterOfMassPosition; Internal_SetCenterOfMass(mCachedPtr, ref pos, ref value); }
+        }
+
+        public float MaxAngularVelocity
+        {
+            get { return Internal_GetMaxAngularVelocity(mCachedPtr); }
+            set { Internal_SetMaxAngularVelocity(mCachedPtr, value); }
+        }
+
+        public int PositionSolverCount
+        {
+            get { return Internal_GetPositionSolverCount(mCachedPtr); }
+            set { Internal_SetPositionSolverCount(mCachedPtr, value); }
+        }
+
+        public int VelocitySolverCount
+        {
+            get { return Internal_GetVelocitySolverCount(mCachedPtr); }
+            set { Internal_SetVelocitySolverCount(mCachedPtr, value); }
+        }
+
+        public RigidbodyInterpolationMode InterpolationMode
+        {
+            get { return Internal_GetInterpolationMode(mCachedPtr); }
+            set { Internal_SetInterpolationMode(mCachedPtr, value); }
+        }
+
+        public RigidbodyFlag Flags
+        {
+            get { return Internal_GetFlags(mCachedPtr); }
+            set { Internal_SetFlags(mCachedPtr, value); }
+        }
+
+        public NativeRigidbody(SceneObject linkedSO)
+        {
+            IntPtr linkedSOPtr = IntPtr.Zero;
+            if (linkedSO != null)
+                linkedSOPtr = linkedSO.GetCachedPtr();
+
+            Internal_CreateInstance(this, linkedSOPtr);
+        }
+
+        public void Destroy()
+        {
+            Internal_Destroy(mCachedPtr);
+        }
+
+        public void Move(Vector3 position)
+        {
+            Internal_Move(mCachedPtr, ref position);
+        }
+
+        public void Rotate(Quaternion rotation)
+        {
+            Internal_Rotate(mCachedPtr, ref rotation);
+        }
+
+        public void AddForce(Vector3 force, ForceMode mode)
+        {
+            Internal_AddForce(mCachedPtr, ref force, mode);
+        }
+
+        public void AddTorque(Vector3 torque, ForceMode mode)
+        {
+            Internal_AddTorque(mCachedPtr, ref torque, mode);
+        }
+
+        public void AddForceAtPoint(Vector3 force, Vector3 position, PointForceMode mode)
+        {
+            Internal_AddForceAtPoint(mCachedPtr, ref force, ref position, mode);
+        }
+
+        public Vector3 GetVelocityAtPoint(Vector3 position)
+        {
+            Vector3 velocity;
+            Internal_GetVelocityAtPoint(mCachedPtr, ref position, out velocity);
+            return velocity;
+        }
+
+        public void AddCollider(Collider collider)
+        {
+            if (collider == null)
+                return;
+
+            IntPtr colliderPtr = collider.GetCachedPtr();
+            Internal_AddCollider(mCachedPtr, colliderPtr);
+        }
+
+        public void RemoveCollider(Collider collider)
+        {
+            if (collider == null)
+                return;
+
+            IntPtr colliderPtr = collider.GetCachedPtr();
+            Internal_RemoveCollider(mCachedPtr, colliderPtr);
+        }
+
+        public void RemoveColliders()
+        {
+            Internal_RemoveColliders(mCachedPtr);
+        }
+
+        public void UpdateMassDistribution()
+        {
+            Internal_UpdateMassDistribution(mCachedPtr);
+        }
+
+        private void Internal_DoOnCollisionBegin(ScriptCollisionData scriptCollisionData)
+        {
+            CollisionData collisionData;
+            collisionData.colliderA = scriptCollisionData.colliderA.Component;
+            collisionData.colliderB = scriptCollisionData.colliderB.Component;
+            collisionData.contactPoints = scriptCollisionData.contactPoints;
+
+            Component.DoOnCollisionBegin(collisionData);
+        }
+
+        private void Internal_DoOnCollisionStay(ScriptCollisionData scriptCollisionData)
+        {
+            CollisionData collisionData;
+            collisionData.colliderA = scriptCollisionData.colliderA.Component;
+            collisionData.colliderB = scriptCollisionData.colliderB.Component;
+            collisionData.contactPoints = scriptCollisionData.contactPoints;
+
+            Component.DoOnCollisionStay(collisionData);
+        }
+
+        private void Internal_DoOnCollisionEnd(ScriptCollisionData scriptCollisionData)
+        {
+            CollisionData collisionData;
+            collisionData.colliderA = scriptCollisionData.colliderA.Component;
+            collisionData.colliderB = scriptCollisionData.colliderB.Component;
+            collisionData.contactPoints = scriptCollisionData.contactPoints;
+
+            Component.DoOnCollisionEnd(collisionData);
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_CreateInstance(NativeRigidbody instance, IntPtr linkedSO);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_Destroy(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_Move(IntPtr thisPtr, ref Vector3 position);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_Rotate(IntPtr thisPtr, ref Quaternion rotation);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetPosition(IntPtr thisPtr, out Vector3 position);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetRotation(IntPtr thisPtr, out Quaternion rotation);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetTransform(IntPtr thisPtr, ref Vector3 pos, ref Quaternion rot);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetMass(IntPtr thisPtr, float mass);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern float Internal_GetMass(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetIsKinematic(IntPtr thisPtr, bool kinematic);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_GetIsKinematic(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_IsSleeping(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_Sleep(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_WakeUp(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetSleepThreshold(IntPtr thisPtr, float threshold);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern float Internal_GetSleepThreshold(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetUseGravity(IntPtr thisPtr, bool gravity);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_GetUseGravity(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetVelocity(IntPtr thisPtr, ref Vector3 velocity);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetVelocity(IntPtr thisPtr, out Vector3 velocity);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetAngularVelocity(IntPtr thisPtr, ref Vector3 velocity);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetAngularVelocity(IntPtr thisPtr, out Vector3 velocity);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetDrag(IntPtr thisPtr, float drag);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern float Internal_GetDrag(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetAngularDrag(IntPtr thisPtr, float drag);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern float Internal_GetAngularDrag(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetInertiaTensor(IntPtr thisPtr, ref Vector3 tensor);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetInertiaTensor(IntPtr thisPtr, out Vector3 tensor);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetMaxAngularVelocity(IntPtr thisPtr, float maxVelocity);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern float Internal_GetMaxAngularVelocity(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetCenterOfMass(IntPtr thisPtr, ref Vector3 position, ref Quaternion rotation);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetCenterOfMassPosition(IntPtr thisPtr, out Vector3 position);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetCenterOfMassRotation(IntPtr thisPtr, out Quaternion rotation);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetPositionSolverCount(IntPtr thisPtr, int count);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern int Internal_GetPositionSolverCount(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetVelocitySolverCount(IntPtr thisPtr, int count);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern int Internal_GetVelocitySolverCount(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetInterpolationMode(IntPtr thisPtr, RigidbodyInterpolationMode value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern RigidbodyInterpolationMode Internal_GetInterpolationMode(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetFlags(IntPtr thisPtr, RigidbodyFlag flags);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern RigidbodyFlag Internal_GetFlags(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_AddForce(IntPtr thisPtr, ref Vector3 force, ForceMode mode);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_AddTorque(IntPtr thisPtr, ref Vector3 torque, ForceMode mode);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_AddForceAtPoint(IntPtr thisPtr, ref Vector3 force, ref Vector3 position, PointForceMode mode);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetVelocityAtPoint(IntPtr thisPtr, ref Vector3 point, out Vector3 velocity);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_AddCollider(IntPtr thisPtr, IntPtr collider);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_RemoveCollider(IntPtr thisPtr, IntPtr collider);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_RemoveColliders(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_UpdateMassDistribution(IntPtr thisPtr);
     }
 }

+ 4 - 4
MBansheeEngine/Physics/PhysicsCommon.cs

@@ -65,7 +65,7 @@ namespace BansheeEngine
         /// Determines how far are the objects. Negative value denotes penetration.
         /// </summary>
         public float separation;
-    };
+    }
 
     /// <summary>
     /// Information about a collision between two physics objects.
@@ -86,7 +86,7 @@ namespace BansheeEngine
         /// Information about all the contact points for the hit. 
         /// </summary>
         public ContactPoint[] contactPoints;
-    };
+    }
 
     /// <summary>
     /// Interop class used for passing PhysicsQueryHit data from native to managed code. <see cref="PhysicsQueryHit"/>.
@@ -111,7 +111,7 @@ namespace BansheeEngine
         public NativeCollider colliderA;
         public NativeCollider colliderB;
         public ContactPoint[] contactPoints;
-    };
+    }
 
     /// <summary>
     /// Determines which collision events will be reported by physics objects.
@@ -131,5 +131,5 @@ namespace BansheeEngine
         /// remains in collision. 
         /// </summary>
 		ReportPersistent, 
-	};
+	}
 }

+ 782 - 2
MBansheeEngine/Physics/Rigidbody.cs

@@ -1,7 +1,787 @@
-namespace BansheeEngine
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+using System;
+using System.Collections.Generic;
+
+namespace BansheeEngine
 {
+    /// <summary>
+    /// Rigidbody is a dynamic physics object that can be moved using forces (or directly). It will interact with other
+    /// static and dynamic physics objects in the scene accordingly(i.e.it will push other non-kinematic rigidbodies,
+    /// and collide with static objects).
+    /// 
+    /// The shape and mass of a rigidbody is governed by its colliders. You must attach at least one collider for the
+    /// rigidbody to be valid. Colliders that are on the same scene object as the rigidbody, or on child scene objects
+    /// are automatically considered as part of the rigidbody.
+    /// </summary>
     public class Rigidbody : Component
     {
-        // TODO
+        internal NativeRigidbody native;
+        private List<Collider> children = new List<Collider>();
+        private Joint parentJoint;
+
+        [SerializeField]
+        internal SerializableData serializableData = new SerializableData();
+
+        /// <summary>
+        /// Triggered when some object starts interacting with one of the child colliders. Only triggered if proper
+        /// collision report mode is turned on.
+        /// </summary>
+        public event Action<CollisionData> OnCollisionBegin;
+
+        /// <summary>
+        /// Triggered for every frame that an object remains interacting with one of the child colliders. Only triggered if
+        /// proper collision report mode is turned on.
+        /// </summary>
+        public event Action<CollisionData> OnCollisionStay;
+
+        /// <summary>
+        /// Triggered when some object stops interacting with one of the child colliders. Only triggered if proper collision
+        /// report mode is turned on.
+        /// </summary>
+        public event Action<CollisionData> OnCollisionEnd;
+
+        /// <summary>
+        /// Determines the mass of the object and all of its collider shapes. Only relevant if RigidbodyFlag.AutoMass or 
+        /// RigidbodyFlag.AutoTensors is turned off. Value of zero means the object is immovable (but can be rotated).
+        /// </summary>
+        public float Mass
+        {
+            get { return serializableData.mass; }
+            set
+            {
+                serializableData.mass = value;
+
+                if (native != null)
+                    native.Mass = value;
+            }
+        }
+
+        /// <summary>
+        /// Determines if the body is kinematic. Kinematic body will not move in response to external forces (e.g. gravity,
+        ///  or another object pushing it), essentially behaving like collider. Unlike a collider though, you can still move
+        /// the object and have other dynamic objects respond correctly (i.e. it will push other objects).
+        /// </summary>
+        public bool Kinematic
+        {
+            get { return serializableData.isKinematic; }
+            set
+            {
+                if (serializableData.isKinematic == value)
+                    return;
+
+                serializableData.isKinematic = value;
+
+                if (native != null)
+                {
+                    native.Kinematic = value;
+
+                    ClearColliders();
+                    UpdateColliders();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Determines if the body is sleeping. Objects that aren't moved/rotated for a while are put to sleep to reduce 
+        /// load on the physics system. You may also manually force objects to sleep or wake up.
+        /// </summary>
+        public bool Sleeping
+        {
+            get
+            {
+                if (native != null)
+                    return native.Sleeping;
+
+                return true;
+            }
+            set
+            {
+                if (native != null)
+                    native.Sleeping = value;
+            }
+        }
+
+        /// <summary>
+        /// Threshold of force and torque under which the object will be considered to be put to sleep.
+        /// </summary>
+        public float SleepThreshold
+        {
+            get { return serializableData.sleepThreshold; }
+            set
+            {
+                serializableData.sleepThreshold = value;
+
+                if (native != null)
+                    native.SleepThreshold = value;
+            }
+        }
+
+        /// <summary>
+        /// Determines whether or not the rigidbody will have the global gravity force applied to it.
+        /// </summary>
+        public bool UseGravity
+        {
+            get { return serializableData.useGravity; }
+            set
+            {
+                serializableData.useGravity = value;
+
+                if (native != null)
+                    native.UseGravity = value;
+            }
+        }
+
+        /// <summary>
+        /// Determines current linear velocity of the body.
+        /// </summary>
+        public Vector3 Velocity
+        {
+            get
+            {
+                if (native != null)
+                    return native.Velocity;
+
+                return Vector3.Zero;
+            }
+            set
+            {
+                if (native != null)
+                    native.Velocity = value;
+            }
+        }
+
+        /// <summary>
+        /// Determines current angular velocity of the body.
+        /// </summary>
+        public Vector3 AngularVelocity
+        {
+            get
+            {
+                if (native != null)
+                    return native.AngularVelocity;
+
+                return Vector3.Zero;
+            }
+            set
+            {
+                if (native != null)
+                    native.AngularVelocity = value;
+            }
+        }
+
+        /// <summary>
+        /// Determines linear drag of the body. Higher drag values means the object resists linear movement more.
+        /// </summary>
+        public float Drag
+        {
+            get { return serializableData.linearDrag; }
+            set
+            {
+                serializableData.linearDrag = value;
+
+                if (native != null)
+                    native.Drag = value;
+            }
+        }
+
+        /// <summary>
+        /// Determines angular drag of the body. Higher drag values means the object resists angular movement more.
+        /// </summary>
+        public float AngularDrag
+        {
+            get { return serializableData.angularDrag; }
+            set
+            {
+                serializableData.angularDrag = value;
+
+                if (native != null)
+                    native.AngularDrag = value;
+            }
+        }
+
+        /// <summary>
+        /// Sets the inertia tensor in local mass space. Inertia tensor determines how difficult is to rotate the object. 
+        /// Values of zero in the inertia tensor mean the object will be unable to rotate around a specific axis. Changing
+        /// this value is only relevant if RigidbodyFlag.AutoTensors is turned off.
+        /// </summary>
+        public Vector3 InertiaTensor
+        {
+            get { return serializableData.inertiaTensor; }
+            set
+            {
+                serializableData.inertiaTensor = value;
+
+                if (native != null)
+                    native.InertiaTensor = value;
+            }
+        }
+
+        /// <summary>
+        /// Determines position of the center of the mass. Changing this value is only relevant if RigidbodyFlag.AutoTensors
+        /// is turned off.
+        /// </summary>
+        public Vector3 CenterOfMassPosition
+        {
+            get { return serializableData.centerMassPosition; }
+            set
+            {
+                serializableData.centerMassPosition = value;
+
+                if (native != null)
+                    native.CenterOfMassPosition = value;
+            }
+        }
+
+        /// <summary>
+        /// Determines rotation of the inertia tensor (rotation of the center of mass frame). Changing this value is only 
+        /// relevant if RigidbodyFlag.AutoTensors is turned off.
+        /// </summary>
+        public Quaternion CenterOfMassRotation
+        {
+            get { return serializableData.centerMassRotation; }
+            set
+            {
+                serializableData.centerMassRotation = value;
+
+                if (native != null)
+                    native.CenterOfMassRotation = value;
+            }
+        }
+
+        /// <summary>
+        /// Determines maximum angular velocity of the rigidbody. Velocity will be clamped to this value.
+        /// </summary>
+        public float MaxAngularVelocity
+        {
+            get { return serializableData.maxAngularVelocity; }
+            set
+            {
+                serializableData.maxAngularVelocity = value;
+
+                if (native != null)
+                    native.MaxAngularVelocity = value;
+            }
+        }
+
+        /// <summary>
+        /// Determines number of iterations to use when solving for position. Higher values can improve precision and 
+        /// numerical stability of the simulation.
+        /// </summary>
+        public int PositionSolverCount
+        {
+            get { return serializableData.positionSolverCount; }
+            set
+            {
+                serializableData.positionSolverCount = value;
+
+                if (native != null)
+                    serializableData.positionSolverCount = value;
+            }
+        }
+
+        /// <summary>
+        /// Determines number of iterations to use when solving for velocity. Higher values can improve precision and 
+        /// numerical stability of the simulation.
+        /// </summary>
+        public int VelocitySolverCount
+        {
+            get { return serializableData.velocitySolverCount; }
+            set
+            {
+                serializableData.velocitySolverCount = value;
+
+                if (native != null)
+                    serializableData.velocitySolverCount = value;
+            }
+        }
+
+        /// <summary>
+        /// Determines interpolation mode that controls how is the rigidbody transfrom updated from the physics simulation.
+        /// </summary>
+        public RigidbodyInterpolationMode InterpolationMode
+        {
+            get { return serializableData.interpolationMode; }
+            set
+            {
+                serializableData.interpolationMode = value;
+
+                if (native != null)
+                    serializableData.interpolationMode = value;
+            }
+        }
+
+        /// <summary>
+        /// Determines which (if any) collision events are reported.
+        /// </summary>
+        public CollisionReportMode CollisionReportMode
+        {
+            get { return serializableData.collisionReportMode; }
+            set
+            {
+                if (serializableData.collisionReportMode == value)
+                    return;
+
+                serializableData.collisionReportMode = value;
+
+                foreach (var entry in children)
+                    entry.UpdateCollisionReportMode();
+            }
+        }
+
+        /// <summary>
+        /// Various flags that control the behaviour of the rigidbody.
+        /// </summary>
+        public RigidbodyFlag Flags
+        {
+            get { return serializableData.flags; }
+            set
+            {
+                if (serializableData.flags == value)
+                    return;
+
+                serializableData.flags = value;
+
+                if (native != null)
+                {
+                    native.Flags = value;
+                    native.UpdateMassDistribution();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Moves the rigidbody to a specific position. This method will ensure physically correct movement, i.e. the body
+        /// will collide with other objects along the way.
+        /// </summary>
+        /// <param name="position">New position for the body.</param>
+        public void Move(Vector3 position)
+        {
+            if (native != null)
+                native.Move(position);
+        }
+
+        /// <summary>
+        /// Rotates the rigidbody. This method will ensure physically correct rotation, i.e. the body will collide with
+        /// other objects along the way.
+        /// </summary>
+        /// <param name="rotation">New orientation of the body.</param>
+        public void Rotate(Quaternion rotation)
+        {
+            if (native != null)
+                native.Rotate(rotation);
+        }
+
+        /// <summary>
+        /// Applies a force to the center of the mass of the rigidbody. This will produce linear momentum.
+        /// </summary>
+        /// <param name="force">Force to apply.</param>
+        /// <param name="mode">Determines what type of force was applied.</param>
+        public void AddForce(Vector3 force, ForceMode mode = ForceMode.Force)
+        {
+            if (native != null)
+                native.AddForce(force, mode);
+        }
+
+        /// <summary>
+        /// Applies a torque to the rigidbody. This will produce angular momentum.
+        /// </summary>
+        /// <param name="torque">Torque to apply.</param>
+        /// <param name="mode">Determines what type of torque was applied.</param>
+        public void AddTorque(Vector3 torque, ForceMode mode = ForceMode.Force)
+        {
+            if (native != null)
+                native.AddTorque(torque, mode);
+        }
+
+        /// <summary>
+        /// Applies a force to a specific point on the rigidbody. This will in most cases produce both linear and angular
+        /// momentum.
+        /// </summary>
+        /// <param name="force">Force to apply.</param>
+        /// <param name="position">World position to apply the force at.</param>
+        /// <param name="mode">Determines what type of force was applied.</param>
+        public void AddForceAtPoint(Vector3 force, Vector3 position, PointForceMode mode = PointForceMode.Force)
+        {
+            if (native != null)
+                native.AddForceAtPoint(force, position, mode);
+        }
+
+        /// <summary>
+        /// Returns the total (linear + angular) velocity at a specific point. 
+        /// </summary>
+        /// <param name="position">Point in world space.</param>
+        /// <returns>Total velocity of the point.</returns>
+        public Vector3 GetVelocityAtPoint(Vector3 position)
+        {
+            if (native != null)
+                return native.GetVelocityAtPoint(position);
+
+            return position;
+        }
+
+        /// <summary>
+        /// Triggered when one of the child colliders begins touching another object.
+        /// </summary>
+        /// <param name="data">Data about a collision.</param>
+        internal void DoOnCollisionBegin(CollisionData data)
+        {
+            if (OnCollisionBegin != null)
+                OnCollisionBegin(data);
+        }
+
+        /// <summary>
+        /// Triggered when one of the child colliders ends touching another object.
+        /// </summary>
+        /// <param name="data">Data about the collision.</param>
+        internal void DoOnCollisionStay(CollisionData data)
+        {
+            if (OnCollisionStay != null)
+                OnCollisionStay(data);
+        }
+
+        /// <summary>
+        /// Triggered when one of the child colliders ends touching another object.
+        /// </summary>
+        /// <param name="data">Data about the collision.</param>
+        internal void DoOnCollisionEnd(CollisionData data)
+        {
+            if (OnCollisionEnd != null)
+                OnCollisionEnd(data);
+        }
+
+        /// <summary>
+        /// Recalculates rigidbody's mass, inertia tensors and center of mass depending on the currently set child 
+        /// colliders. This should be called whenever relevant child collider properties change(like mass or shape).
+        /// 
+        /// If automatic tensor calculation is turned off then this will do nothing. If automatic mass calculation is turned
+        /// off then this will use the mass set directly on the body using <see cref="Mass"/>.
+        /// </summary>
+        internal void UpdateMassDistribution()
+        {
+            if (native != null)
+                native.UpdateMassDistribution();
+        }
+
+        /// <summary>
+        /// Unregisters all child colliders from the Rigidbody.
+        /// </summary>
+        internal void ClearColliders()
+        {
+            foreach (var collider in children)
+                collider.SetRigidbody(null, true);
+
+            children.Clear();
+
+            if (native != null)
+                native.RemoveColliders();
+        }
+
+        /// <summary>
+        /// Registers a new collider with the Rigidbody. This collider will then be used to calculate Rigidbody's geometry
+        /// used for collisions, and optionally (depending on set flags) total mass, inertia tensors and center of mass.
+        /// </summary>
+        /// <param name="collider">Collider to register.</param>
+        internal void AddCollider(Collider collider)
+	    {
+		    if (native == null)
+			    return;
+
+            children.Add(collider);
+            native.AddCollider(collider);
+	    }
+
+        /// <summary>
+        /// Unregisters the collider from the Rigidbody.
+        /// </summary>
+        /// <param name="collider">Collider to unregister.</param>
+        internal void RemoveCollider(Collider collider)
+        {
+            if (native == null)
+                return;
+
+            if (children.Exists(x => x == collider))
+            {
+                native.RemoveCollider(collider);
+                children.Remove(collider);
+            }
+        }
+
+        private void OnReset()
+        {
+            RestoreNative();
+        }
+
+        private void OnEnable()
+        {
+            if (native == null)
+                RestoreNative();
+        }
+
+        private void OnDisable()
+        {
+            DestroyNative();
+        }
+
+        private void OnDestroy()
+        {
+            DestroyNative();
+        }
+
+        private void OnTransformChanged(TransformChangedFlags flags)
+        {
+            if (!SceneObject.Active)
+                return;
+
+            if ((flags & TransformChangedFlags.Parent) != 0)
+            {
+                ClearColliders();
+                UpdateColliders();
+
+                if ((serializableData.flags & RigidbodyFlag.AutoTensors) != 0)
+                    native.UpdateMassDistribution();
+
+#if DEBUG
+			CheckForNestedRigibody();
+#endif
+            }
+
+            native.Position = SceneObject.Position;
+            native.Rotation = SceneObject.Rotation;
+
+            if (parentJoint != null)
+                parentJoint.NotifyRigidbodyMoved(this);
+        }
+
+        /// <summary>
+        /// Searches child scene objects for Collider components and attaches them to the rigidbody. Make sure to call
+        /// <see cref="ClearColliders"/> if you need to clear old colliders first.
+        /// </summary>
+        private void UpdateColliders()
+        {
+            Stack<SceneObject> todo = new Stack<SceneObject>();
+            todo.Push(SceneObject);
+
+            while (todo.Count > 0)
+            {
+                SceneObject currentSO = todo.Pop();
+
+                if (currentSO.GetComponent<Collider>() != null)
+                {
+                    Collider[] colliders = currentSO.GetComponents<Collider>();
+
+                    foreach (var entry in colliders)
+                    {
+                        if (!entry.IsValidParent(this))
+                            continue;
+
+                        entry.SetRigidbody(this, true);
+
+                        children.Add(entry);
+                        native.AddCollider(entry);
+                    }
+                }
+
+                int childCount = currentSO.GetNumChildren();
+                for (int i = 0; i < childCount; i++)
+                {
+                    SceneObject child = currentSO.GetChild(i);
+
+                    if (child.GetComponent<Rigidbody>() != null)
+                        continue;
+
+                    todo.Push(child);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Checks if the rigidbody is nested under another rigidbody, and throws out a warning if so.
+        /// </summary>
+        private void CheckForNestedRigibody()
+        {
+            SceneObject currentSO = SceneObject.Parent;
+
+            while (currentSO != null)
+            {
+                if (currentSO.GetComponent<Rigidbody>() != null)
+                {
+                    Debug.LogWarning("Nested Rigidbodies detected. This will result in inconsistent transformations. " +
+                        "To parent one Rigidbody to another move its colliders to the new parent, but remove the " +
+                        "Rigidbody component.");
+                    return;
+                }
+
+                currentSO = currentSO.Parent;
+            }
+        }
+
+        /// <summary>
+        /// Destroys the internal rigidbody representation.
+        /// </summary>
+        private void DestroyNative()
+        {
+            ClearColliders();
+
+            if (native != null)
+            {
+                native.Destroy();
+                native = null;
+            }
+        }
+
+        /// <summary>
+        /// Restores internal rigidbody representation and assigns it the properties stored by the component.
+        /// </summary>
+        private void RestoreNative()
+        {
+            native = new NativeRigidbody(SceneObject);
+
+            UpdateColliders();
+
+#if DEBUG
+		    CheckForNestedRigibody();
+#endif
+
+            native.Position = SceneObject.Position;
+            native.Rotation = SceneObject.Rotation;
+
+            // Note: Merge into one call to avoid many virtual function calls
+            native.PositionSolverCount = serializableData.positionSolverCount;
+            native.VelocitySolverCount = serializableData.velocitySolverCount;
+            native.MaxAngularVelocity = serializableData.maxAngularVelocity;
+            native.Drag = serializableData.linearDrag;;
+            native.AngularDrag = serializableData.angularDrag;
+            native.SleepThreshold = serializableData.sleepThreshold;
+            native.UseGravity = serializableData.useGravity;
+            native.Kinematic = serializableData.isKinematic;
+            native.InterpolationMode = serializableData.interpolationMode;
+            native.Flags = serializableData.flags;
+
+            if ((serializableData.flags & RigidbodyFlag.AutoTensors) == 0)
+            {
+                native.CenterOfMassPosition = serializableData.centerMassPosition;
+                native.CenterOfMassRotation = serializableData.centerMassRotation;
+                native.InertiaTensor = serializableData.inertiaTensor;
+                native.Mass = serializableData.mass;
+            }
+            else
+            {
+                if ((serializableData.flags & RigidbodyFlag.AutoMass) == 0)
+                    native.Mass = serializableData.mass;
+
+                native.UpdateMassDistribution();
+            }
+        }
+
+        /// <summary>
+        /// Holds all data the rigidbody component needs to persist through serialization.
+        /// </summary>
+        [SerializeObject]
+        internal class SerializableData
+        {
+            public int positionSolverCount = 4;
+            public int velocitySolverCount = 1;
+            public RigidbodyFlag flags = RigidbodyFlag.AutoTensors | RigidbodyFlag.AutoMass;
+            public RigidbodyInterpolationMode interpolationMode = RigidbodyInterpolationMode.None;
+            public CollisionReportMode collisionReportMode = CollisionReportMode.None;
+            public Vector3 centerMassPosition;
+            public Quaternion centerMassRotation;
+            public Vector3 inertiaTensor;
+            public float mass = 0.0f;
+            public float maxAngularVelocity = 1.0f;
+            public float linearDrag = 0.0f;
+            public float angularDrag = 0.0f;
+            public float sleepThreshold = 0.0f;
+            public bool useGravity = true;
+            public bool isKinematic = false;
+        }
+    }
+
+    /// <summary>
+    /// Type of force or torque that can be applied to a rigidbody.
+    /// </summary>
+    public enum ForceMode
+    {
+        /// <summary>
+        /// Value applied is a force.
+        /// </summary>
+        Force,
+        /// <summary>
+        /// Value applied is an impulse (i.e. a direct change in its linear or angular momentum).
+        /// </summary>
+		Impulse,
+        /// <summary>
+        /// Value applied is velocity.
+        /// </summary>
+		Velocity,
+        /// <summary>
+        /// Value applied is accelearation.
+        /// </summary>
+		Acceleration
+    }
+
+    /// <summary>
+    /// Type of force that can be applied to a rigidbody at an arbitrary point.
+    /// </summary>
+    public enum PointForceMode
+    {
+        /// <summary>
+        /// Value applied is a force.
+        /// </summary>
+        Force,
+        /// <summary>
+        /// Value applied is an impulse (i.e. a direct change in its linear or angular momentum).
+        /// </summary>
+		Impulse,
+    }
+
+    /// <summary>
+    /// Flags that control options of a Rigidbody object.
+    /// </summary>
+    public enum RigidbodyFlag
+    {
+        /// <summary>
+        /// No options. 
+        /// </summary>
+        None = 0x00,
+        /// <summary>
+        /// Automatically calculate center of mass transform and inertia tensors from child shapes (colliders)
+        /// </summary>
+        AutoTensors = 0x01,
+        /// <summary>
+        /// Calculate mass distribution from child shapes (colliders). Only relevant when auto-tensors is on.
+        /// </summary>
+        AutoMass = 0x02,
+        /// <summary>
+        /// Enables continous collision detection. This can prevent fast moving bodies from tunneling through each other.
+        /// This must also be enabled globally in Physics otherwise the flag will be ignored.
+        /// </summary>
+		CCD = 0x04
+    }
+
+    /// <summary>
+    /// Determines interpolation mode for a rigidbody transform during physics simulation.
+    /// </summary>
+    public enum RigidbodyInterpolationMode
+    {
+        /// <summary>
+        /// No interpolation is performed, physics transform is copied straight to the rigidbody when physics tick is done.
+        /// </summary>
+        None,
+        /// <summary>
+        /// Physics transfrom from the most recent tick is saved and slowly interpolated to during the following render 
+        /// frames. This can improve smoothness of the visible movement at framerates higher than the physics simulation 
+        /// but will introduce a delay of one physics tick to all such objects. This can create slight inconsistencies as
+        /// non-interpolated objects will have no such delay, as well as cause input lag due to the delayed reaction.
+        /// </summary>
+        Interpolate,
+        /// <summary>
+        /// Physics transform movement will be extrapolated from the last physics simulation tick. This will improve
+        /// smoothness of visible movement at framerates higher than the physics simulation. Unlike Interpolate it will
+        /// not introduce an input delay, but will introduce an error as the exact position/rotation of the objects is
+        /// extrapolated from the last frame's movement and velocities. 
+        /// </summary>
+        Extrapolate
     }
 }

+ 2 - 2
MBansheeEngine/SceneObject.cs

@@ -281,9 +281,9 @@ namespace BansheeEngine
         /// <typeparam name="T">Type of the component to search for. Includes any components derived from the type.
         /// </typeparam>
         /// <returns>All components matching the specified type.</returns>
-        public Component[] GetComponents<T>() where T : Component
+        public T[] GetComponents<T>() where T : Component
         {
-            return Component.Internal_GetComponentsPerType(this, typeof(T));
+            return (T[])Component.Internal_GetComponentsPerType(this, typeof(T));
         }
 
         /// <summary>

+ 1 - 1
SBansheeEngine/Include/BsScriptCollider.h

@@ -58,7 +58,7 @@ namespace BansheeEngine
 		/** Triggered when some object starts interacting with the collider. */
 		static void onCollisionBegin(MonoObject* instance, const CollisionData& collisionData);
 
-		/** Triggered when some object remains interacting with the collider through a frame. */
+		/** Triggered when some object remains interacting with the collider throughout a frame. */
 		static void onCollisionStay(MonoObject* instance, const CollisionData& collisionData);
 
 		/** Triggered when some object ends interacting with the collider. */

+ 87 - 2
SBansheeEngine/Include/BsScriptRigidbody.h

@@ -4,6 +4,7 @@
 
 #include "BsScriptEnginePrerequisites.h"
 #include "BsScriptObject.h"
+#include "BsRigidbody.h"
 
 namespace BansheeEngine
 {
@@ -20,12 +21,96 @@ namespace BansheeEngine
 
 		ScriptRigidbody(MonoObject* instance, const SPtr<Rigidbody>& body);
 
+		/** Triggered when some object starts interacting with the rigidbody. */
+		static void onCollisionBegin(MonoObject* instance, const CollisionData& collisionData);
+
+		/** Triggered when some object remains interacting with the rigidbody throughout a frame. */
+		static void onCollisionStay(MonoObject* instance, const CollisionData& collisionData);
+
+		/** Triggered when some object ends interacting with the rigidbody. */
+		static void onCollisionEnd(MonoObject* instance, const CollisionData& collisionData);
+
 		SPtr<Rigidbody> mRigidbody;
 
 		/************************************************************************/
 		/* 								CLR HOOKS						   		*/
 		/************************************************************************/
-		
-		// TODO - Dummy class
+		static void internal_CreateInstance(MonoObject* instance, ScriptSceneObject* linkedSO);
+		static void internal_Destroy(ScriptRigidbody* thisPtr);
+
+		static void internal_Move(ScriptRigidbody* thisPtr, Vector3* position);
+		static void internal_Rotate(ScriptRigidbody* thisPtr, Quaternion* rotation);
+
+		static void internal_GetPosition(ScriptRigidbody* thisPtr, Vector3* position);
+		static void internal_GetRotation(ScriptRigidbody* thisPtr, Quaternion* rotation);
+		static void internal_SetTransform(ScriptRigidbody* thisPtr, Vector3* pos, Quaternion* rot);
+
+		static void internal_SetMass(ScriptRigidbody* thisPtr, float mass);
+		static float internal_GetMass(ScriptRigidbody* thisPtr);
+
+		static void internal_SetIsKinematic(ScriptRigidbody* thisPtr, bool kinematic);
+		static bool internal_GetIsKinematic(ScriptRigidbody* thisPtr);
+
+		static bool internal_IsSleeping(ScriptRigidbody* thisPtr);
+		static void internal_Sleep(ScriptRigidbody* thisPtr);
+		static void internal_WakeUp(ScriptRigidbody* thisPtr);
+
+		static void internal_SetSleepThreshold(ScriptRigidbody* thisPtr, float threshold);
+		static float internal_GetSleepThreshold(ScriptRigidbody* thisPtr);
+
+		static void internal_SetUseGravity(ScriptRigidbody* thisPtr, bool gravity);
+		static bool internal_GetUseGravity(ScriptRigidbody* thisPtr);
+
+		static void internal_SetVelocity(ScriptRigidbody* thisPtr, Vector3* velocity);
+		static void internal_GetVelocity(ScriptRigidbody* thisPtr, Vector3* velocity);
+
+		static void internal_SetAngularVelocity(ScriptRigidbody* thisPtr, Vector3* velocity);
+		static void internal_GetAngularVelocity(ScriptRigidbody* thisPtr, Vector3* velocity);
+
+		static void internal_SetDrag(ScriptRigidbody* thisPtr, float drag);
+		static float internal_GetDrag(ScriptRigidbody* thisPtr);
+
+		static void internal_SetAngularDrag(ScriptRigidbody* thisPtr, float drag);
+		static float internal_GetAngularDrag(ScriptRigidbody* thisPtr);
+
+		static void internal_SetInertiaTensor(ScriptRigidbody* thisPtr, Vector3* tensor);
+		static void internal_GetInertiaTensor(ScriptRigidbody* thisPtr, Vector3* tensor);
+
+		static void internal_SetMaxAngularVelocity(ScriptRigidbody* thisPtr, float maxVelocity);
+		static float internal_GetMaxAngularVelocity(ScriptRigidbody* thisPtr);
+
+		static void internal_SetCenterOfMass(ScriptRigidbody* thisPtr, Vector3* position, Quaternion* rotation);
+		static void internal_GetCenterOfMassPosition(ScriptRigidbody* thisPtr, Vector3* position);
+		static void internal_GetCenterOfMassRotation(ScriptRigidbody* thisPtr, Quaternion* rotation);
+
+		static void internal_SetPositionSolverCount(ScriptRigidbody* thisPtr, UINT32 count);
+		static UINT32 internal_GetPositionSolverCount(ScriptRigidbody* thisPtr);
+
+		static void internal_SetVelocitySolverCount(ScriptRigidbody* thisPtr, UINT32 count);
+		static UINT32 internal_GetVelocitySolverCount(ScriptRigidbody* thisPtr);
+
+		static void internal_SetInterpolationMode(ScriptRigidbody* thisPtr, Rigidbody::InterpolationMode value);
+		static Rigidbody::InterpolationMode internal_GetInterpolationMode(ScriptRigidbody* thisPtr);
+
+		static void internal_SetFlags(ScriptRigidbody* thisPtr, Rigidbody::Flag flags);
+		static Rigidbody::Flag internal_GetFlags(ScriptRigidbody* thisPtr);
+
+		static void internal_AddForce(ScriptRigidbody* thisPtr, Vector3* force, ForceMode mode);
+		static void internal_AddTorque(ScriptRigidbody* thisPtr, Vector3* torque, ForceMode mode);
+		static void internal_AddForceAtPoint(ScriptRigidbody* thisPtr, Vector3* force, Vector3* position, PointForceMode mode);
+
+		static void internal_GetVelocityAtPoint(ScriptRigidbody* thisPtr, Vector3* point, Vector3* velocity);
+
+		static void internal_AddCollider(ScriptRigidbody* thisPtr, ScriptColliderBase* collider);
+		static void internal_RemoveCollider(ScriptRigidbody* thisPtr, ScriptColliderBase* collider);
+		static void internal_RemoveColliders(ScriptRigidbody* thisPtr);
+
+		static void internal_UpdateMassDistribution(ScriptRigidbody* thisPtr);
+
+		typedef void(__stdcall *OnCollisionThunkDef) (MonoObject*, MonoObject*, MonoException**);
+
+		static OnCollisionThunkDef onCollisionBeginThunk;
+		static OnCollisionThunkDef onCollisionStayThunk;
+		static OnCollisionThunkDef onCollisionEndThunk;
 	};
 }

+ 370 - 2
SBansheeEngine/Source/BsScriptRigidbody.cpp

@@ -1,15 +1,383 @@
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 #include "BsScriptRigidbody.h"
+#include "BsMonoUtil.h"
+#include "BsMonoClass.h"
+#include "BsMonoMethod.h"
+#include "BsScriptCollisionData.h"
+#include "BsScriptSceneObject.h"
+#include "BsScriptCollider.h"
+#include "BsCollider.h"
+#include "BsQuaternion.h"
+
+using namespace std::placeholders;
 
 namespace BansheeEngine
 {
+	ScriptRigidbody::OnCollisionThunkDef ScriptRigidbody::onCollisionBeginThunk = nullptr;
+	ScriptRigidbody::OnCollisionThunkDef ScriptRigidbody::onCollisionStayThunk = nullptr;
+	ScriptRigidbody::OnCollisionThunkDef ScriptRigidbody::onCollisionEndThunk = nullptr;
+
 	ScriptRigidbody::ScriptRigidbody(MonoObject* instance, const SPtr<Rigidbody>& body)
 		:ScriptObject(instance), mRigidbody(body)
-	{ }
+	{
+		body->onCollisionBegin.connect(std::bind(&ScriptRigidbody::onCollisionBegin, instance, _1));
+		body->onCollisionStay.connect(std::bind(&ScriptRigidbody::onCollisionStay, instance, _1));
+		body->onCollisionEnd.connect(std::bind(&ScriptRigidbody::onCollisionEnd, instance, _1));
+	}
 
 	void ScriptRigidbody::initRuntimeData()
 	{
-		// TODO
+		metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptRigidbody::internal_CreateInstance);
+		metaData.scriptClass->addInternalCall("Internal_Destroy", &ScriptRigidbody::internal_Destroy);
+
+		metaData.scriptClass->addInternalCall("Internal_Move", &ScriptRigidbody::internal_Move);
+		metaData.scriptClass->addInternalCall("Internal_Rotate", &ScriptRigidbody::internal_Rotate);
+
+		metaData.scriptClass->addInternalCall("Internal_GetPosition", &ScriptRigidbody::internal_GetPosition);
+		metaData.scriptClass->addInternalCall("Internal_GetRotation", &ScriptRigidbody::internal_GetRotation);
+		metaData.scriptClass->addInternalCall("Internal_SetTransform", &ScriptRigidbody::internal_SetTransform);
+
+		metaData.scriptClass->addInternalCall("Internal_SetMass", &ScriptRigidbody::internal_SetMass);
+		metaData.scriptClass->addInternalCall("Internal_GetMass", &ScriptRigidbody::internal_GetMass);
+
+		metaData.scriptClass->addInternalCall("Internal_SetIsKinematic", &ScriptRigidbody::internal_SetIsKinematic);
+		metaData.scriptClass->addInternalCall("Internal_GetIsKinematic", &ScriptRigidbody::internal_GetIsKinematic);
+
+		metaData.scriptClass->addInternalCall("Internal_IsSleeping", &ScriptRigidbody::internal_IsSleeping);
+		metaData.scriptClass->addInternalCall("Internal_Sleep", &ScriptRigidbody::internal_Sleep);
+		metaData.scriptClass->addInternalCall("Internal_WakeUp", &ScriptRigidbody::internal_WakeUp);
+
+		metaData.scriptClass->addInternalCall("Internal_SetSleepThreshold", &ScriptRigidbody::internal_SetSleepThreshold);
+		metaData.scriptClass->addInternalCall("Internal_GetSleepThreshold", &ScriptRigidbody::internal_GetSleepThreshold);
+
+		metaData.scriptClass->addInternalCall("Internal_SetUseGravity", &ScriptRigidbody::internal_SetUseGravity);
+		metaData.scriptClass->addInternalCall("Internal_GetUseGravity", &ScriptRigidbody::internal_GetUseGravity);
+
+		metaData.scriptClass->addInternalCall("Internal_SetVelocity", &ScriptRigidbody::internal_SetVelocity);
+		metaData.scriptClass->addInternalCall("Internal_GetVelocity", &ScriptRigidbody::internal_GetVelocity);
+
+		metaData.scriptClass->addInternalCall("Internal_SetAngularVelocity", &ScriptRigidbody::internal_SetAngularVelocity);
+		metaData.scriptClass->addInternalCall("Internal_GetAngularVelocity", &ScriptRigidbody::internal_GetAngularVelocity);
+
+		metaData.scriptClass->addInternalCall("Internal_SetDrag", &ScriptRigidbody::internal_SetDrag);
+		metaData.scriptClass->addInternalCall("Internal_GetDrag", &ScriptRigidbody::internal_GetDrag);
+
+		metaData.scriptClass->addInternalCall("Internal_SetAngularDrag", &ScriptRigidbody::internal_SetAngularDrag);
+		metaData.scriptClass->addInternalCall("Internal_GetAngularDrag", &ScriptRigidbody::internal_GetAngularDrag);
+
+		metaData.scriptClass->addInternalCall("Internal_SetInertiaTensor", &ScriptRigidbody::internal_SetInertiaTensor);
+		metaData.scriptClass->addInternalCall("Internal_GetInertiaTensor", &ScriptRigidbody::internal_GetInertiaTensor);
+
+		metaData.scriptClass->addInternalCall("Internal_SetMaxAngularVelocity", &ScriptRigidbody::internal_SetMaxAngularVelocity);
+		metaData.scriptClass->addInternalCall("Internal_GetMaxAngularVelocity", &ScriptRigidbody::internal_GetMaxAngularVelocity);
+
+		metaData.scriptClass->addInternalCall("Internal_SetCenterOfMass", &ScriptRigidbody::internal_SetCenterOfMass);
+		metaData.scriptClass->addInternalCall("Internal_GetCenterOfMassPosition", &ScriptRigidbody::internal_GetCenterOfMassPosition);
+		metaData.scriptClass->addInternalCall("Internal_GetCenterOfMassRotation", &ScriptRigidbody::internal_GetCenterOfMassRotation);
+
+		metaData.scriptClass->addInternalCall("Internal_SetPositionSolverCount", &ScriptRigidbody::internal_SetPositionSolverCount);
+		metaData.scriptClass->addInternalCall("Internal_GetPositionSolverCount", &ScriptRigidbody::internal_GetPositionSolverCount);
+
+		metaData.scriptClass->addInternalCall("Internal_SetVelocitySolverCount", &ScriptRigidbody::internal_SetVelocitySolverCount);
+		metaData.scriptClass->addInternalCall("Internal_GetVelocitySolverCount", &ScriptRigidbody::internal_GetVelocitySolverCount);
+
+		metaData.scriptClass->addInternalCall("Internal_SetInterpolationMode", &ScriptRigidbody::internal_SetInterpolationMode);
+		metaData.scriptClass->addInternalCall("Internal_GetInterpolationMode", &ScriptRigidbody::internal_GetInterpolationMode);
+
+		metaData.scriptClass->addInternalCall("Internal_SetFlags", &ScriptRigidbody::internal_SetFlags);
+		metaData.scriptClass->addInternalCall("Internal_GetFlags", &ScriptRigidbody::internal_GetFlags);
+
+		metaData.scriptClass->addInternalCall("Internal_AddForce", &ScriptRigidbody::internal_AddForce);
+		metaData.scriptClass->addInternalCall("Internal_AddTorque", &ScriptRigidbody::internal_AddTorque);
+		metaData.scriptClass->addInternalCall("Internal_AddForceAtPoint", &ScriptRigidbody::internal_AddForceAtPoint);
+
+		metaData.scriptClass->addInternalCall("Internal_GetVelocityAtPoint", &ScriptRigidbody::internal_GetVelocityAtPoint);
+
+		metaData.scriptClass->addInternalCall("Internal_AddCollider", &ScriptRigidbody::internal_AddCollider);
+		metaData.scriptClass->addInternalCall("Internal_RemoveCollider", &ScriptRigidbody::internal_RemoveCollider);
+		metaData.scriptClass->addInternalCall("Internal_RemoveColliders", &ScriptRigidbody::internal_RemoveColliders);
+
+		metaData.scriptClass->addInternalCall("Internal_UpdateMassDistribution", &ScriptRigidbody::internal_UpdateMassDistribution);
+
+		onCollisionBeginThunk = (OnCollisionThunkDef)metaData.scriptClass->getMethod("Internal_DoOnCollisionBegin", 1)->getThunk();
+		onCollisionStayThunk = (OnCollisionThunkDef)metaData.scriptClass->getMethod("Internal_DoOnCollisionStay", 1)->getThunk();
+		onCollisionEndThunk = (OnCollisionThunkDef)metaData.scriptClass->getMethod("Internal_DoOnCollisionEnd", 1)->getThunk();
+	}
+
+	void ScriptRigidbody::onCollisionBegin(MonoObject* instance, const CollisionData& collisionData)
+	{
+		MonoObject* managedCollisionData = ScriptCollisionDataHelper::box(ScriptCollisionDataHelper::create(collisionData));
+		MonoUtil::invokeThunk(onCollisionBeginThunk, instance, managedCollisionData);
+	}
+
+	void ScriptRigidbody::onCollisionStay(MonoObject* instance, const CollisionData& collisionData)
+	{
+		MonoObject* managedCollisionData = ScriptCollisionDataHelper::box(ScriptCollisionDataHelper::create(collisionData));
+		MonoUtil::invokeThunk(onCollisionStayThunk, instance, managedCollisionData);
+	}
+
+	void ScriptRigidbody::onCollisionEnd(MonoObject* instance, const CollisionData& collisionData)
+	{
+		MonoObject* managedCollisionData = ScriptCollisionDataHelper::box(ScriptCollisionDataHelper::create(collisionData));
+		MonoUtil::invokeThunk(onCollisionEndThunk, instance, managedCollisionData);
+	}
+
+	void ScriptRigidbody::internal_CreateInstance(MonoObject* instance, ScriptSceneObject* linkedSO)
+	{
+		HSceneObject so;
+		if (linkedSO != nullptr)
+			so = linkedSO->getNativeSceneObject();
+
+		SPtr<Rigidbody> rigidbody = Rigidbody::create(so);
+		rigidbody->_setOwner(PhysicsOwnerType::Script, instance);
+
+		ScriptRigidbody* scriptRigidbody = new (bs_alloc<ScriptRigidbody>()) ScriptRigidbody(instance, rigidbody);
+	}
+
+	void ScriptRigidbody::internal_Destroy(ScriptRigidbody* thisPtr)
+	{
+		thisPtr->mRigidbody = nullptr;
+	}
+
+	void ScriptRigidbody::internal_Move(ScriptRigidbody* thisPtr, Vector3* position)
+	{
+		thisPtr->mRigidbody->move(*position);
+	}
+
+	void ScriptRigidbody::internal_Rotate(ScriptRigidbody* thisPtr, Quaternion* rotation)
+	{
+		thisPtr->mRigidbody->rotate(*rotation);
+	}
+
+	void ScriptRigidbody::internal_GetPosition(ScriptRigidbody* thisPtr, Vector3* position)
+	{
+		*position = thisPtr->mRigidbody->getPosition();
+	}
+
+	void ScriptRigidbody::internal_GetRotation(ScriptRigidbody* thisPtr, Quaternion* rotation)
+	{
+		*rotation = thisPtr->mRigidbody->getRotation();
+	}
+
+	void ScriptRigidbody::internal_SetTransform(ScriptRigidbody* thisPtr, Vector3* pos, Quaternion* rot)
+	{
+		thisPtr->mRigidbody->setTransform(*pos, *rot);
+	}
+
+	void ScriptRigidbody::internal_SetMass(ScriptRigidbody* thisPtr, float mass)
+	{
+		thisPtr->mRigidbody->setMass(mass);
+	}
+
+	float ScriptRigidbody::internal_GetMass(ScriptRigidbody* thisPtr)
+	{
+		return thisPtr->mRigidbody->getMass();
+	}
+
+	void ScriptRigidbody::internal_SetIsKinematic(ScriptRigidbody* thisPtr, bool kinematic)
+	{
+		thisPtr->mRigidbody->setIsKinematic(kinematic);
+	}
+
+	bool ScriptRigidbody::internal_GetIsKinematic(ScriptRigidbody* thisPtr)
+	{
+		return thisPtr->mRigidbody->getIsKinematic();
+	}
+
+	bool ScriptRigidbody::internal_IsSleeping(ScriptRigidbody* thisPtr)
+	{
+		return thisPtr->mRigidbody->isSleeping();
+	}
+
+	void ScriptRigidbody::internal_Sleep(ScriptRigidbody* thisPtr)
+	{
+		thisPtr->mRigidbody->sleep();
+	}
+
+	void ScriptRigidbody::internal_WakeUp(ScriptRigidbody* thisPtr)
+	{
+		thisPtr->mRigidbody->wakeUp();
+	}
+
+	void ScriptRigidbody::internal_SetSleepThreshold(ScriptRigidbody* thisPtr, float threshold)
+	{
+		thisPtr->mRigidbody->setSleepThreshold(threshold);
+	}
+
+	float ScriptRigidbody::internal_GetSleepThreshold(ScriptRigidbody* thisPtr)
+	{
+		return thisPtr->mRigidbody->getSleepThreshold();
+	}
+
+	void ScriptRigidbody::internal_SetUseGravity(ScriptRigidbody* thisPtr, bool gravity)
+	{
+		thisPtr->mRigidbody->setUseGravity(gravity);
+	}
+
+	bool ScriptRigidbody::internal_GetUseGravity(ScriptRigidbody* thisPtr)
+	{
+		return thisPtr->mRigidbody->getUseGravity();
+	}
+
+	void ScriptRigidbody::internal_SetVelocity(ScriptRigidbody* thisPtr, Vector3* velocity)
+	{
+		thisPtr->mRigidbody->setVelocity(*velocity);
+	}
+
+	void ScriptRigidbody::internal_GetVelocity(ScriptRigidbody* thisPtr, Vector3* velocity)
+	{
+		*velocity = thisPtr->mRigidbody->getVelocity();
+	}
+
+	void ScriptRigidbody::internal_SetAngularVelocity(ScriptRigidbody* thisPtr, Vector3* velocity)
+	{
+		thisPtr->mRigidbody->setAngularVelocity(*velocity);
+	}
+
+	void ScriptRigidbody::internal_GetAngularVelocity(ScriptRigidbody* thisPtr, Vector3* velocity)
+	{
+		*velocity = thisPtr->mRigidbody->getAngularVelocity();
+	}
+
+	void ScriptRigidbody::internal_SetDrag(ScriptRigidbody* thisPtr, float drag)
+	{
+		thisPtr->mRigidbody->setDrag(drag);
+	}
+
+	float ScriptRigidbody::internal_GetDrag(ScriptRigidbody* thisPtr)
+	{
+		return thisPtr->mRigidbody->getDrag();
+	}
+
+	void ScriptRigidbody::internal_SetAngularDrag(ScriptRigidbody* thisPtr, float drag)
+	{
+		thisPtr->mRigidbody->setAngularDrag(drag);
+	}
+
+	float ScriptRigidbody::internal_GetAngularDrag(ScriptRigidbody* thisPtr)
+	{
+		return thisPtr->mRigidbody->getAngularDrag();
+	}
+
+	void ScriptRigidbody::internal_SetInertiaTensor(ScriptRigidbody* thisPtr, Vector3* tensor)
+	{
+		thisPtr->mRigidbody->setInertiaTensor(*tensor);
+	}
+
+	void ScriptRigidbody::internal_GetInertiaTensor(ScriptRigidbody* thisPtr, Vector3* tensor)
+	{
+		*tensor = thisPtr->mRigidbody->getInertiaTensor();
+	}
+
+	void ScriptRigidbody::internal_SetMaxAngularVelocity(ScriptRigidbody* thisPtr, float maxVelocity)
+	{
+		thisPtr->mRigidbody->setMaxAngularVelocity(maxVelocity);
+	}
+
+	float ScriptRigidbody::internal_GetMaxAngularVelocity(ScriptRigidbody* thisPtr)
+	{
+		return thisPtr->mRigidbody->getMaxAngularVelocity();
+	}
+
+	void ScriptRigidbody::internal_SetCenterOfMass(ScriptRigidbody* thisPtr, Vector3* position, Quaternion* rotation)
+	{
+		thisPtr->mRigidbody->setCenterOfMass(*position, *rotation);
+	}
+
+	void ScriptRigidbody::internal_GetCenterOfMassPosition(ScriptRigidbody* thisPtr, Vector3* position)
+	{
+		*position = thisPtr->mRigidbody->getCenterOfMassPosition();
+	}
+
+	void ScriptRigidbody::internal_GetCenterOfMassRotation(ScriptRigidbody* thisPtr, Quaternion* rotation)
+	{
+		*rotation = thisPtr->mRigidbody->getCenterOfMassRotation();
+	}
+
+	void ScriptRigidbody::internal_SetPositionSolverCount(ScriptRigidbody* thisPtr, UINT32 count)
+	{
+		thisPtr->mRigidbody->setPositionSolverCount(count);
+	}
+
+	UINT32 ScriptRigidbody::internal_GetPositionSolverCount(ScriptRigidbody* thisPtr)
+	{
+		return thisPtr->mRigidbody->getPositionSolverCount();
+	}
+
+	void ScriptRigidbody::internal_SetVelocitySolverCount(ScriptRigidbody* thisPtr, UINT32 count)
+	{
+		thisPtr->mRigidbody->setVelocitySolverCount(count);
+	}
+
+	UINT32 ScriptRigidbody::internal_GetVelocitySolverCount(ScriptRigidbody* thisPtr)
+	{
+		return thisPtr->mRigidbody->getVelocitySolverCount();
+	}
+
+	void ScriptRigidbody::internal_SetInterpolationMode(ScriptRigidbody* thisPtr, Rigidbody::InterpolationMode value)
+	{
+		thisPtr->mRigidbody->setInterpolationMode(value);
+	}
+
+	Rigidbody::InterpolationMode ScriptRigidbody::internal_GetInterpolationMode(ScriptRigidbody* thisPtr)
+	{
+		return thisPtr->mRigidbody->getInterpolationMode();
+	}
+
+	void ScriptRigidbody::internal_SetFlags(ScriptRigidbody* thisPtr, Rigidbody::Flag flags)
+	{
+		thisPtr->mRigidbody->setFlags(flags);
+	}
+
+	Rigidbody::Flag ScriptRigidbody::internal_GetFlags(ScriptRigidbody* thisPtr)
+	{
+		return thisPtr->mRigidbody->getFlags();
+	}
+
+	void ScriptRigidbody::internal_AddForce(ScriptRigidbody* thisPtr, Vector3* force, ForceMode mode)
+	{
+		thisPtr->mRigidbody->addForce(*force, mode);
+	}
+
+	void ScriptRigidbody::internal_AddTorque(ScriptRigidbody* thisPtr, Vector3* torque, ForceMode mode)
+	{
+		thisPtr->mRigidbody->addTorque(*torque, mode);
+	}
+
+	void ScriptRigidbody::internal_AddForceAtPoint(ScriptRigidbody* thisPtr, Vector3* force, Vector3* position, PointForceMode mode)
+	{
+		thisPtr->mRigidbody->addForceAtPoint(*force, *position, mode);
+	}
+
+	void ScriptRigidbody::internal_GetVelocityAtPoint(ScriptRigidbody* thisPtr, Vector3* point, Vector3* velocity)
+	{
+		*velocity = thisPtr->mRigidbody->getVelocityAtPoint(*point);
+	}
+
+	void ScriptRigidbody::internal_AddCollider(ScriptRigidbody* thisPtr, ScriptColliderBase* collider)
+	{
+		if (collider == nullptr)
+			return;
+
+		thisPtr->mRigidbody->addCollider(collider->getCollider()->_getInternal());
+	}
+
+	void ScriptRigidbody::internal_RemoveCollider(ScriptRigidbody* thisPtr, ScriptColliderBase* collider)
+	{
+		if (collider == nullptr)
+			return;
+
+		thisPtr->mRigidbody->removeCollider(collider->getCollider()->_getInternal());
+	}
+
+	void ScriptRigidbody::internal_RemoveColliders(ScriptRigidbody* thisPtr)
+	{
+		thisPtr->mRigidbody->removeColliders();
+	}
+
+	void ScriptRigidbody::internal_UpdateMassDistribution(ScriptRigidbody* thisPtr)
+	{
+		thisPtr->mRigidbody->updateMassDistribution();
 	}
 }