Ver código fonte

Exposed physics queries and global physics options to C#

BearishSun 9 anos atrás
pai
commit
38080d3731

+ 1 - 1
BansheeCore/Include/BsPhysics.h

@@ -536,7 +536,7 @@ namespace BansheeEngine
 		virtual bool _rayCast(const Vector3& origin, const Vector3& unitDir, const Collider& collider, PhysicsQueryHit& hit, 
 		virtual bool _rayCast(const Vector3& origin, const Vector3& unitDir, const Collider& collider, PhysicsQueryHit& hit, 
 			float maxDist = FLT_MAX) const = 0;
 			float maxDist = FLT_MAX) const = 0;
 
 
-		/** Checks is the physics update currently in progress. */
+		/** Checks is the physics simulation update currently in progress. */
 		bool _isUpdateInProgress() const { return mUpdateInProgress; }
 		bool _isUpdateInProgress() const { return mUpdateInProgress; }
 
 
 		/** @endcond */
 		/** @endcond */

+ 16 - 2
BansheeEngine/Include/BsGUICommandEvent.h

@@ -14,8 +14,22 @@ namespace BansheeEngine
 	/**	Type of valid command events. */
 	/**	Type of valid command events. */
 	enum class GUICommandEventType
 	enum class GUICommandEventType
 	{
 	{
-		Redraw, FocusLost, FocusGained, MoveLeft, MoveRight, MoveUp, MoveDown, 
-		SelectLeft, SelectRight, SelectUp, SelectDown, Escape, Delete, Backspace, Return, Confirm
+		Redraw, /**< GUI system is forcing the GUI element to redraw itself. */
+		FocusLost, /**< GUI element lost input focus. */
+		FocusGained, /**< GUI element gained input focus. */
+		MoveLeft, /**< Input caret was moved left (e.g. for navigating an input box). */
+		MoveRight, /**< Input caret was moved right (e.g. for navigating an input box). */
+		MoveUp, /**< Input caret was moved up (e.g. for navigating an input box). */ 
+		MoveDown, /**< Input caret was moved down (e.g. for navigating an input box). */ 
+		SelectLeft, /**< Input Selection was moved left (e.g. for selecting text in an input box). */ 
+		SelectRight, /**< Input Selection was moved right (e.g. for selecting text in an input box). */ 
+		SelectUp, /**< Input Selection was moved up (e.g. for selecting text in an input box). */ 
+		SelectDown, /**< Input Selection was moved down (e.g. for selecting text in an input box). */ 
+		Escape, /**< Escape key was pressed. */
+		Delete, /**< Delete key was pressed. */
+		Backspace, /**< Backspace key was pressed. */
+		Return, /**< Shift + Enter was pressed. */
+		Confirm /**< Enter key was pressed. */
 	};
 	};
 
 
 	/**
 	/**

+ 1 - 0
BansheeEngine/Source/BsGUITexture.cpp

@@ -211,6 +211,7 @@ namespace BansheeEngine
 
 
 	Vector2I GUITexture::_getOptimalSize() const
 	Vector2I GUITexture::_getOptimalSize() const
 	{
 	{
+		// TODO - Accounting for style dimensions might be redundant here, I'm pretty sure we do that on higher level anyway
 		Vector2I optimalSize;
 		Vector2I optimalSize;
 
 
 		if(_getDimensions().fixedWidth())
 		if(_getDimensions().fixedWidth())

+ 3 - 3
BansheeUtility/Include/BsCapsule.h

@@ -12,7 +12,7 @@ namespace BansheeEngine
 	 *  @{
 	 *  @{
 	 */
 	 */
 
 
-	/** Represents a capsule represented by a line segment and a radius. */
+	/** Represents a capsule with a line segment and a radius. */
 	class BS_UTILITY_EXPORT Capsule
 	class BS_UTILITY_EXPORT Capsule
 	{
 	{
 	public:
 	public:
@@ -27,8 +27,8 @@ namespace BansheeEngine
 		std::pair<bool, float> intersects(const Ray& ray) const;
 		std::pair<bool, float> intersects(const Ray& ray) const;
 
 
 		/**
 		/**
-		 * Returns the line segment along which the capsule lies. 
-		 * All capsule points are at equal distance from this segment.
+		 * Returns the line segment along which the capsule lies. All capsule points are at equal distance from this 
+		 * segment.
 		 */
 		 */
 		const LineSegment3& getSegment() const { return mSegment; }
 		const LineSegment3& getSegment() const { return mSegment; }
 
 

+ 3 - 1
MBansheeEngine/MBansheeEngine.csproj

@@ -51,6 +51,8 @@
     <Compile Include="GUI\GUIListView.cs" />
     <Compile Include="GUI\GUIListView.cs" />
     <Compile Include="GUI\GUIWidget.cs" />
     <Compile Include="GUI\GUIWidget.cs" />
     <Compile Include="Layers.cs" />
     <Compile Include="Layers.cs" />
+    <Compile Include="Math\Capsule.cs" />
+    <Compile Include="Math\LineSegment.cs" />
     <Compile Include="NativeCamera.cs" />
     <Compile Include="NativeCamera.cs" />
     <Compile Include="ContextMenu.cs" />
     <Compile Include="ContextMenu.cs" />
     <Compile Include="Cursor.cs" />
     <Compile Include="Cursor.cs" />
@@ -178,7 +180,7 @@
     <Compile Include="Shader.cs" />
     <Compile Include="Shader.cs" />
     <Compile Include="ShaderInclude.cs" />
     <Compile Include="ShaderInclude.cs" />
     <Compile Include="ShortcutKey.cs" />
     <Compile Include="ShortcutKey.cs" />
-    <Compile Include="Sphere.cs" />
+    <Compile Include="Math\Sphere.cs" />
     <Compile Include="SpriteTexture.cs" />
     <Compile Include="SpriteTexture.cs" />
     <Compile Include="StringTable.cs" />
     <Compile Include="StringTable.cs" />
     <Compile Include="StringTables.cs" />
     <Compile Include="StringTables.cs" />

+ 48 - 0
MBansheeEngine/Math/Capsule.cs

@@ -0,0 +1,48 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+using System.Runtime.InteropServices;
+
+namespace BansheeEngine
+{
+    /// <summary>
+    /// Represents a capsule with a line segment and a radius.
+    /// </summary>
+    [StructLayout(LayoutKind.Sequential), SerializeObject]
+    public struct Capsule // Note: Must match C++ struct Capsule
+    {
+        [SerializeField]
+        private LineSegment segment;
+
+        [SerializeField]
+        private float radius;
+
+        /// <summary>
+        /// Radius that defines the distance of the capsule from its line segment.
+        /// </summary>
+        public float Radius
+        {
+            get { return radius; }
+            set { radius = value; }
+        }
+
+        /// <summary>
+        /// Line segment along which the capsule lies. All capsule points are at equal distance from this segment.
+        /// </summary>
+        public LineSegment Segment
+        {
+            get { return segment; }
+            set { segment = value; }
+        }
+
+        /// <summary>
+        /// Creates a new capsule object.
+        /// </summary>
+        /// <param name="center">Line segment along which the capsule lies.</param>
+        /// <param name="radius">Radius that defines the distance of the capsule from its line segment.</param>
+        public Capsule(LineSegment segment, float radius)
+        {
+            this.segment = segment;
+            this.radius = radius;
+        }
+    };
+}

+ 1 - 1
MBansheeEngine/Sphere.cs → MBansheeEngine/Math/Sphere.cs

@@ -8,7 +8,7 @@ namespace BansheeEngine
     /// A sphere represented by a center point and a radius.
     /// A sphere represented by a center point and a radius.
     /// </summary>
     /// </summary>
     [StructLayout(LayoutKind.Sequential), SerializeObject]
     [StructLayout(LayoutKind.Sequential), SerializeObject]
-    public struct Sphere // Note: Must match C++ enum Sphere
+    public struct Sphere // Note: Must match C++ struct Sphere
     {
     {
         [SerializeField]
         [SerializeField]
         private float _radius;
         private float _radius;

+ 2 - 0
MBansheeEngine/Physics/Joint.cs

@@ -487,6 +487,7 @@ namespace BansheeEngine
     /// Specifies parameters for a drive that will attempt to move the D6 joint bodies to the specified drive position and
     /// Specifies parameters for a drive that will attempt to move the D6 joint bodies to the specified drive position and
     /// velocity.
     /// velocity.
     /// </summary>
     /// </summary>
+    [SerializeObject]
     public class D6JointDrive
     public class D6JointDrive
     {
     {
         /// <summary>
         /// <summary>
@@ -549,6 +550,7 @@ namespace BansheeEngine
     /// <summary>
     /// <summary>
     /// Properties of a drive that drives the hinge joint's angular velocity towards a paricular value.
     /// Properties of a drive that drives the hinge joint's angular velocity towards a paricular value.
     /// </summary>
     /// </summary>
+    [SerializeObject]
     public class HingeJointDrive
     public class HingeJointDrive
     {
     {
         /// <summary>
         /// <summary>

+ 665 - 3
MBansheeEngine/Physics/Physics.cs

@@ -1,14 +1,676 @@
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+using System;
+using System.Runtime.CompilerServices;
+
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
+    /// <summary>
+    /// Provides global access to the physics system, including scene queries and global options.
+    /// </summary>
     public static class Physics
     public static class Physics
     {
     {
-        public static bool IsUpdateInProgress
+        /// <summary>
+        /// Global gravity value for all objects in the scene.
+        /// </summary>
+        public static Vector3 Gravity
+        {
+            get { Vector3 gravity; Internal_GetGravity(out gravity); return gravity; }
+            set { Internal_SetGravity(ref value); }
+        }
+
+        /// <summary>
+        /// Casts a ray into the scene and returns the closest found hit, if any.
+        /// </summary>
+        /// <param name="ray">Ray to cast into the scene.</param>
+        /// <param name="hit">Information recorded about a hit. Only valid if method returns true.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <param name="max">Maximum distance at which to perform the query. Hits past this distance will not be detected.
+        ///                   </param>
+        /// <returns>True if something was hit, false otherwise.</returns>
+        public static bool RayCast(Ray ray, out PhysicsQueryHit hit, ulong layer = ulong.MaxValue, float max = float.MaxValue)
+        {
+            ScriptPhysicsQueryHit scriptHit = new ScriptPhysicsQueryHit();
+            if (RayCast(ray.origin, ray.direction, out hit, layer, max))
+            {
+                ConvertPhysicsQueryHit(ref scriptHit, out hit);
+                return true;
+            }
+
+            return false;
+        }
+
+        /// <summary>
+        /// Casts a ray into the scene and returns the closest found hit, if any.
+        /// </summary>
+        /// <param name="origin">Origin of the ray to cast into the scene.</param>
+        /// <param name="unitDir">Unit direction of the ray to cast into the scene.</param>
+        /// <param name="hit">Information recorded about a hit. Only valid if method returns true.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <param name="max">Maximum distance at which to perform the query. Hits past this distance will not be detected.
+        ///                   </param>
+        /// <returns>True if something was hit, false otherwise.</returns>
+        public static bool RayCast(Vector3 origin, Vector3 unitDir, out PhysicsQueryHit hit,
+           ulong layer = ulong.MaxValue, float max = float.MaxValue)
+        {
+            ScriptPhysicsQueryHit scriptHit = new ScriptPhysicsQueryHit();
+            if(Internal_RayCast(ref origin, ref unitDir, out scriptHit, layer, max))
+            {
+                ConvertPhysicsQueryHit(ref scriptHit, out hit);
+                return true;
+            }
+
+            hit = new PhysicsQueryHit();
+            return false;
+        }
+
+        /// <summary>
+        /// Performs a sweep into the scene using a box and returns the closest found hit, if any.
+        /// </summary>
+        /// <param name="box">Box to sweep through the scene.</param>
+        /// <param name="rotation">Orientation of the box.</param>
+        /// <param name="unitDir">Unit direction towards which to perform the sweep.</param>
+        /// <param name="hit">Information recorded about a hit. Only valid if method returns true.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <param name="max">Maximum distance at which to perform the query. Hits past this distance will not be detected.
+        ///                   </param>
+        /// <returns>True if something was hit, false otherwise.</returns>
+        public static bool BoxCast(AABox box, Quaternion rotation, Vector3 unitDir, out PhysicsQueryHit hit,
+            ulong layer = ulong.MaxValue, float max = float.MaxValue)
+        {
+            ScriptPhysicsQueryHit scriptHit = new ScriptPhysicsQueryHit();
+            if(Internal_BoxCast(ref box, ref rotation, ref unitDir, out scriptHit, layer, max))
+            {
+                ConvertPhysicsQueryHit(ref scriptHit, out hit);
+                return true;
+            }
+
+            hit = new PhysicsQueryHit();
+            return false;
+        }
+
+        /// <summary>
+        /// Performs a sweep into the scene using a sphere and returns the closest found hit, if any.
+        /// </summary>
+        /// <param name="sphere">Sphere to sweep through the scene.</param>
+        /// <param name="unitDir">Unit direction towards which to perform the sweep.</param>
+        /// <param name="hit">Information recorded about a hit. Only valid if method returns true.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <param name="max">Maximum distance at which to perform the query. Hits past this distance will not be detected.
+        ///                   </param>
+        /// <returns>True if something was hit, false otherwise.</returns>
+        public static bool SphereCast(Sphere sphere, Vector3 unitDir, out PhysicsQueryHit hit,
+            ulong layer = ulong.MaxValue, float max = float.MaxValue)
+        {
+            ScriptPhysicsQueryHit scriptHit = new ScriptPhysicsQueryHit();
+            if(Internal_SphereCast(ref sphere, ref unitDir, out scriptHit, layer, max))
+            {
+                ConvertPhysicsQueryHit(ref scriptHit, out hit);
+                return true;
+            }
+
+            hit = new PhysicsQueryHit();
+            return false;
+        }
+
+        /// <summary>
+        /// Performs a sweep into the scene using a capsule and returns the closest found hit, if any.
+        /// </summary>
+        /// <param name="capsule">Capsule to sweep through the scene.</param>
+        /// <param name="rotation">Orientation of the capsule.</param>
+        /// <param name="unitDir">Unit direction towards which to perform the sweep.</param>
+        /// <param name="hit">Information recorded about a hit. Only valid if method returns true.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <param name="max">Maximum distance at which to perform the query. Hits past this distance will not be detected.
+        ///                   </param>
+        /// <returns>True if something was hit, false otherwise.</returns>
+        public static bool CapsuleCast(Capsule capsule, Quaternion rotation, Vector3 unitDir,
+            out PhysicsQueryHit hit, ulong layer = ulong.MaxValue, float max = float.MaxValue)
+        {
+            ScriptPhysicsQueryHit scriptHit = new ScriptPhysicsQueryHit();
+            if(Internal_CapsuleCast(ref capsule, ref rotation, ref unitDir, out scriptHit, layer, max))
+            {
+                ConvertPhysicsQueryHit(ref scriptHit, out hit);
+                return true;
+            }
+
+            hit = new PhysicsQueryHit();
+            return false;
+        }
+
+        /// <summary>
+        /// Performs a sweep into the scene using a convex mesh and returns the closest found hit, if any.
+        /// </summary>
+        /// <param name="mesh">Mesh to sweep through the scene. Must be convex.</param>
+        /// <param name="position">Starting position of the mesh.</param>
+        /// <param name="rotation">Orientation of the mesh.</param>
+        /// <param name="unitDir">Unit direction towards which to perform the sweep.</param>
+        /// <param name="hit">Information recorded about a hit. Only valid if method returns true.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <param name="max">Maximum distance at which to perform the query. Hits past this distance will not be detected.
+        ///                   </param>
+        /// <returns>True if something was hit, false otherwise.</returns>
+        public static bool ConvexCast(PhysicsMesh mesh, Vector3 position, Quaternion rotation,
+            Vector3 unitDir, out PhysicsQueryHit hit, ulong layer = ulong.MaxValue, float max = float.MaxValue)
+        {
+            IntPtr meshPtr = IntPtr.Zero;
+            if (mesh != null)
+                meshPtr = mesh.GetCachedPtr();
+
+            ScriptPhysicsQueryHit scriptHit = new ScriptPhysicsQueryHit();
+            if(Internal_ConvexCast(meshPtr, ref position, ref rotation, ref unitDir, out scriptHit, layer, max))
+            {
+                ConvertPhysicsQueryHit(ref scriptHit, out hit);
+                return true;
+            }
+
+            hit = new PhysicsQueryHit();
+            return false;
+        }
+
+        /// <summary>
+        /// Casts a ray into the scene and returns all found hits.
+        /// </summary>
+        /// <param name="ray">Ray to cast into the scene.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <param name="max">Maximum distance at which to perform the query. Hits past this distance will not be detected.
+        ///                   </param>
+        /// <returns>List of all detected hits.</returns>
+        public static PhysicsQueryHit[] RayCastAll(Ray ray, ulong layer = ulong.MaxValue, float max = float.MaxValue)
+        {
+            return RayCastAll(ray.origin, ray.direction, layer, max);
+        }
+
+        /// <summary>
+        /// Casts a ray into the scene and returns all found hits.
+        /// </summary>
+        /// <param name="origin">Origin of the ray to cast into the scene.</param>
+        /// <param name="unitDir">Unit direction of the ray to cast into the scene.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <param name="max">Maximum distance at which to perform the query. Hits past this distance will not be detected.
+        ///                   </param>
+        /// <returns>List of all detected hits.</returns>
+        public static PhysicsQueryHit[] RayCastAll(Vector3 origin, Vector3 unitDir,
+			ulong layer = ulong.MaxValue, float max = float.MaxValue)
+        {
+            return ConvertPhysicsQueryHits(Internal_RayCastAll(ref origin, ref unitDir, layer, max));
+        }
+
+        /// <summary>
+        /// Performs a sweep into the scene using a box and returns all found hits.
+        /// </summary>
+        /// <param name="box">Box to sweep through the scene.</param>
+        /// <param name="rotation">Orientation of the box.</param>
+        /// <param name="unitDir">Unit direction towards which to perform the sweep.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <param name="max">Maximum distance at which to perform the query. Hits past this distance will not be detected.
+        ///                   </param>
+        /// <returns>List of all detected hits.</returns>
+        public static PhysicsQueryHit[] BoxCastAll(AABox box, Quaternion rotation,
+            Vector3 unitDir, ulong layer = ulong.MaxValue, float max = float.MaxValue)
+        {
+            return ConvertPhysicsQueryHits(Internal_BoxCastAll(ref box, ref rotation, ref unitDir, layer, max));
+        }
+
+        /// <summary>
+        /// Performs a sweep into the scene using a sphere and returns all found hits.
+        /// </summary>
+        /// <param name="sphere">Sphere to sweep through the scene.</param>
+        /// <param name="unitDir">Unit direction towards which to perform the sweep.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <param name="max">Maximum distance at which to perform the query. Hits past this distance will not be detected.
+        ///                   </param>
+        /// <returns>List of all detected hits.</returns>
+        public static PhysicsQueryHit[] SphereCastAll(Sphere sphere, Vector3 unitDir,
+            ulong layer = ulong.MaxValue, float max = float.MaxValue)
+        {
+            return ConvertPhysicsQueryHits(Internal_SphereCastAll(ref sphere, ref unitDir, layer, max));
+        }
+
+        /// <summary>
+        /// Performs a sweep into the scene using a capsule and returns all found hits.
+        /// </summary>
+        /// <param name="capsule">Capsule to sweep through the scene.</param>
+        /// <param name="rotation">Orientation of the capsule.</param>
+        /// <param name="unitDir">Unit direction towards which to perform the sweep.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <param name="max">Maximum distance at which to perform the query. Hits past this distance will not be detected.
+        ///                   </param>
+        /// <returns>List of all detected hits.</returns>
+        public static PhysicsQueryHit[] CapsuleCastAll(Capsule capsule, Quaternion rotation,
+            Vector3 unitDir, ulong layer = ulong.MaxValue, float max = float.MaxValue)
+        {
+            return ConvertPhysicsQueryHits(Internal_CapsuleCastAll(ref capsule, ref rotation, ref unitDir, layer, max));
+        }
+
+        /// <summary>
+        /// Performs a sweep into the scene using a convex mesh and returns all found hits.
+        /// </summary>
+        /// <param name="mesh">Mesh to sweep through the scene. Must be convex.</param>
+        /// <param name="position">Starting position of the mesh.</param>
+        /// <param name="rotation">Orientation of the mesh.</param>
+        /// <param name="unitDir">Unit direction towards which to perform the sweep.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <param name="max">Maximum distance at which to perform the query. Hits past this distance will not be detected.
+        ///                   </param>
+        /// <returns>List of all detected hits.</returns>
+        public static PhysicsQueryHit[] ConvexCastAll(PhysicsMesh mesh, Vector3 position,
+            Quaternion rotation, Vector3 unitDir, ulong layer = ulong.MaxValue, float max = float.MaxValue)
+        {
+            IntPtr meshPtr = IntPtr.Zero;
+            if (mesh != null)
+                meshPtr = mesh.GetCachedPtr();
+
+            return ConvertPhysicsQueryHits(Internal_ConvexCastAll(meshPtr, ref position, ref rotation, ref unitDir, layer, max));
+        }
+
+        /// <summary>
+        /// Casts a ray into the scene and checks if it has hit anything. This can be significantly more efficient than 
+        /// other types of cast* calls.
+        /// </summary>
+        /// <param name="ray">Ray to cast into the scene.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <param name="max">Maximum distance at which to perform the query. Hits past this distance will not be detected.
+        ///                   </param>
+        /// <returns>True if something was hit, false otherwise.</returns>
+        public static bool RayCastAny(Ray ray, ulong layer = ulong.MaxValue, float max = float.MaxValue)
+        {
+            return RayCastAny(ray.origin, ray.direction, layer, max);
+        }
+
+        /// <summary>
+        /// Casts a ray into the scene and checks if it has hit anything. This can be significantly more efficient than 
+        /// other types of cast* calls.
+        /// </summary>
+        /// <param name="origin">Origin of the ray to cast into the scene.</param>
+        /// <param name="unitDir">Unit direction of the ray to cast into the scene.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <param name="max">Maximum distance at which to perform the query. Hits past this distance will not be detected.
+        ///                   </param>
+        /// <returns>True if something was hit, false otherwise.</returns>
+        public static bool RayCastAny(Vector3 origin, Vector3 unitDir, ulong layer = ulong.MaxValue, 
+            float max = float.MaxValue)
+        {
+            return Internal_RayCastAny(ref origin, ref unitDir, layer, max);
+        }
+
+        /// <summary>
+        /// Performs a sweep into the scene using a box and checks if it has hit anything. This can be significantly more 
+        /// efficient than other types of cast* calls.
+        /// </summary>
+        /// <param name="box">Box to sweep through the scene.</param>
+        /// <param name="rotation">Orientation of the box.</param>
+        /// <param name="unitDir">Unit direction towards which to perform the sweep.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <param name="max">Maximum distance at which to perform the query. Hits past this distance will not be detected.
+        ///                   </param>
+        /// <returns>True if something was hit, false otherwise.</returns>
+        public static bool BoxCastAny(AABox box, Quaternion rotation, Vector3 unitDir, ulong layer = ulong.MaxValue, 
+            float max = float.MaxValue)
+        {
+            return Internal_BoxCastAny(ref box, ref rotation, ref unitDir, layer, max);
+        }
+
+        /// <summary>
+        /// Performs a sweep into the scene using a sphere and checks if it has hit anything. This can be significantly more
+        /// efficient than other types of cast* calls.
+        /// </summary>
+        /// <param name="sphere">Sphere to sweep through the scene.</param>
+        /// <param name="unitDir">Unit direction towards which to perform the sweep.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <param name="max">Maximum distance at which to perform the query. Hits past this distance will not be detected.
+        ///                   </param>
+        /// <returns>True if something was hit, false otherwise.</returns>
+        public static bool SphereCastAny(Sphere sphere, Vector3 unitDir, ulong layer = ulong.MaxValue, 
+            float max = float.MaxValue)
+        {
+            return Internal_SphereCastAny(ref sphere, ref unitDir, layer, max);
+        }
+
+        /// <summary>
+        /// Performs a sweep into the scene using a capsule and checks if it has hit anything. This can be significantly 
+        /// more efficient than other types of cast* calls.
+        /// </summary>
+        /// <param name="capsule">Capsule to sweep through the scene.</param>
+        /// <param name="rotation">Orientation of the capsule.</param>
+        /// <param name="unitDir">Unit direction towards which to perform the sweep.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <param name="max">Maximum distance at which to perform the query. Hits past this distance will not be detected.
+        ///                   </param>
+        /// <returns>True if something was hit, false otherwise.</returns>
+        public static bool CapsuleCastAny(Capsule capsule, Quaternion rotation, Vector3 unitDir,
+            ulong layer = ulong.MaxValue, float max = float.MaxValue)
+        {
+            return Internal_CapsuleCastAny(ref capsule, ref rotation, ref unitDir, layer, max);
+        }
+
+        /// <summary>
+        /// Performs a sweep into the scene using a convex mesh and checks if it has hit anything. This can be significantly
+        /// more efficient than other types of cast* calls.
+        /// </summary>
+        /// <param name="mesh">Mesh to sweep through the scene. Must be convex.</param>
+        /// <param name="position">Starting position of the mesh.</param>
+        /// <param name="rotation">Orientation of the mesh.</param>
+        /// <param name="unitDir">Unit direction towards which to perform the sweep.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <param name="max">Maximum distance at which to perform the query. Hits past this distance will not be detected.
+        ///                   </param>
+        /// <returns>True if something was hit, false otherwise.</returns>
+        public static bool ConvexCastAny(PhysicsMesh mesh, Vector3 position, Quaternion rotation,
+            Vector3 unitDir, ulong layer = ulong.MaxValue, float max = float.MaxValue)
+        {
+            IntPtr meshPtr = IntPtr.Zero;
+            if (mesh != null)
+                meshPtr = mesh.GetCachedPtr();
+
+            return Internal_ConvexCastAny(meshPtr, ref position, ref rotation, ref unitDir, layer, max);
+        }
+
+        /// <summary>
+        /// Returns a list of all colliders in the scene that overlap the provided box.
+        /// </summary>
+        /// <param name="box">Box to check for overlap.</param>
+        /// <param name="rotation">Orientation of the box.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <returns>List of all colliders that overlap the box.</returns>
+        public static Collider[] BoxOverlap(AABox box, Quaternion rotation, ulong layer = ulong.MaxValue)
+        {
+            return ConvertColliders(Internal_BoxOverlap(ref box, ref rotation, layer));
+        }
+
+        /// <summary>
+        /// Returns a list of all colliders in the scene that overlap the provided sphere.
+        /// </summary>
+        /// <param name="sphere">Sphere to check for overlap.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <returns>List of all colliders that overlap the sphere.</returns>
+        public static Collider[] SphereOverlap(Sphere sphere, ulong layer = ulong.MaxValue)
+        {
+            return ConvertColliders(Internal_SphereOverlap(ref sphere, layer));
+        }
+
+        /// <summary>
+        /// Returns a list of all colliders in the scene that overlap the provided capsule.
+        /// </summary>
+        /// <param name="capsule">Capsule to check for overlap.</param>
+        /// <param name="rotation">Orientation of the capsule.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <returns>List of all colliders that overlap the sphere.</returns>
+        public static Collider[] CapsuleOverlap(Capsule capsule, Quaternion rotation, ulong layer = ulong.MaxValue)
+        {
+            return ConvertColliders(Internal_CapsuleOverlap(ref capsule, ref rotation, layer));
+        }
+
+        /// <summary>
+        /// Returns a list of all colliders in the scene that overlap the provided convex mesh.
+        /// </summary>
+        /// <param name="mesh">Mesh to check for overlap. Must be convex.</param>
+        /// <param name="position">Position of the mesh.</param>
+        /// <param name="rotation">Orientation of the mesh.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <returns>List of all colliders that overlap the mesh.</returns>
+        public static Collider[] ConvexOverlap(PhysicsMesh mesh, Vector3 position, Quaternion rotation, 
+            ulong layer = ulong.MaxValue)
+        {
+            IntPtr meshPtr = IntPtr.Zero;
+            if (mesh != null)
+                meshPtr = mesh.GetCachedPtr();
+
+            return ConvertColliders(Internal_ConvexOverlap(meshPtr, ref position, ref rotation, layer));
+        }
+
+        /// <summary>
+        /// Checks if the provided box overlaps any other collider in the scene.
+        /// </summary>
+        /// <param name="box">Box to check for overlap.</param>
+        /// <param name="rotation">Orientation of the box.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <returns>True if there is overlap with another object, false otherwise.</returns>
+        public static bool BoxOverlapAny(AABox box, Quaternion rotation, ulong layer = ulong.MaxValue)
+        {
+            return Internal_BoxOverlapAny(ref box, ref rotation, layer);
+        }
+
+        /// <summary>
+        /// Checks if the provided sphere overlaps any other collider in the scene.
+        /// </summary>
+        /// <param name="sphere">Sphere to check for overlap.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <returns>True if there is overlap with another object, false otherwise.</returns>
+        public static bool SphereOverlapAny(Sphere sphere, ulong layer = ulong.MaxValue)
+        {
+            return Internal_SphereOverlapAny(ref sphere, layer);
+        }
+
+        /// <summary>
+        /// Checks if the provided capsule overlaps any other collider in the scene.
+        /// </summary>
+        /// <param name="capsule">Capsule to check for overlap.</param>
+        /// <param name="rotation">Orientation of the capsule.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <returns>True if there is overlap with another object, false otherwise.</returns>
+        public static bool CapsuleOverlapAny(Capsule capsule, Quaternion rotation, ulong layer = ulong.MaxValue)
+        {
+            return Internal_CapsuleOverlapAny(ref capsule, ref rotation, layer);
+        }
+
+        /// <summary>
+        /// Checks if the provided convex mesh overlaps any other collider in the scene.
+        /// </summary>
+        /// <param name="mesh">Mesh to check for overlap. Must be convex.</param>
+        /// <param name="position">Position of the mesh.</param>
+        /// <param name="rotation">Orientation of the mesh.</param>
+        /// <param name="layer">Layers to consider for the query. This allows you to ignore certain groups of objects.
+        ///                     </param>
+        /// <returns>True if there is overlap with another object, false otherwise.</returns>
+        public static bool ConvexOverlapAny(PhysicsMesh mesh, Vector3 position, Quaternion rotation,
+            ulong layer = ulong.MaxValue)
+        {
+            IntPtr meshPtr = IntPtr.Zero;
+            if (mesh != null)
+                meshPtr = mesh.GetCachedPtr();
+
+            return Internal_ConvexOverlapAny(meshPtr, ref position, ref rotation, layer);
+        }
+
+        /// <summary>
+        /// Adds a new physics region. Certain physics options require you to set up regions in which physics objects are
+        /// allowed to be in, and objects outside of these regions will not be handled by physics.You do not need to set
+        /// up these regions by default.
+        /// </summary>
+        /// <param name="region">Region of space that physics objects are allowed to be in.</param>
+        /// <returns>A unique handle to the region.</returns>
+        public static int AddPhysicsRegion(AABox region)
+        {
+            return Internal_AddPhysicsRegion(ref region);
+        }
+
+        /// <summary>
+        /// Removes a physics region.
+        /// </summary>
+        /// <param name="handle">Handle of the region returned by <see cref="AddPhysicsRegion"/></param>
+        public static void RemovePhysicsRegion(int handle)
         {
         {
-            get { return false; /* TODO */ }
+            Internal_RemovePhysicsRegion(handle);
         }
         }
 
 
-        // TODO
+        /// <summary>
+        /// Removes all physics regions. 
+        /// </summary>
+        public static void ClearPhysicsRegions()
+        {
+            Internal_ClearPhysicsRegions();
+        }
+
+        /// <summary>
+        /// Enables or disables collision between two layers. Each physics object can be assigned a specific layer, and here
+        /// you can determine which layers can interact with each other.
+        /// </summary>
+        /// <param name="layerA">First collision layer.</param>
+        /// <param name="layerB">Second collision layer.</param>
+        /// <param name="enabled">True if the layers are allowed to interact, false otherwise.</param>
+        public static void ToggleCollision(ulong layerA, ulong layerB, bool enabled)
+        {
+            Internal_ToggleCollision(layerA, layerB, enabled);
+        }
+
+        /// <summary>
+        /// Checks if two collision layers are allowed to interact.
+        /// </summary>
+        /// <param name="layerA">First collision layer.</param>
+        /// <param name="layerB">Second collision layer.</param>
+        /// <returns>True if the two provided layers are allowed to interact.</returns>
+        public static bool IsCollisionEnabled(ulong layerA, ulong layerB)
+        {
+            return Internal_IsCollisionEnabled(layerA, layerB);
+        }
+
+        /// <summary>
+        /// Checks is the physics simulation update currently in progress.
+        /// </summary>
+        internal static bool IsUpdateInProgress
+        {
+            get { return Internal_IsUpdateInProgress(); }
+        }
+
+        /// <summary>
+        /// Converts a physics query hit info retrieved from native code into managed physics query hit.
+        /// </summary>
+        /// <param name="scriptHit">Native physics query hit info.</param>
+        /// <param name="hit">Managed physics query hit info</param>
+        private static void ConvertPhysicsQueryHit(ref ScriptPhysicsQueryHit scriptHit, out PhysicsQueryHit hit)
+        {
+            hit.collider = scriptHit.collider.Component;
+            hit.distance = scriptHit.distance;
+            hit.normal = scriptHit.normal;
+            hit.point = scriptHit.point;
+            hit.triangleIdx = scriptHit.triangleIdx;
+            hit.uv = scriptHit.uv;
+        }
+
+        /// <summary>
+        /// Converts all provided physics query hit infos retrieved from native code into managed physics query hits.
+        /// </summary>
+        /// <param name="scriptHits">Native physics query hits.</param>
+        /// <returns>Converted managed physics query hits.</returns>
+        private static PhysicsQueryHit[] ConvertPhysicsQueryHits(ScriptPhysicsQueryHit[] scriptHits)
+        {
+            PhysicsQueryHit[] output = new PhysicsQueryHit[scriptHits.Length];
+
+            for (int i = 0; i < scriptHits.Length; i++)
+                ConvertPhysicsQueryHit(ref scriptHits[i], out output[i]);
+
+            return output;
+        }
+
+        /// <summary>
+        /// Converts an array of native colliders to collider components.
+        /// </summary>
+        /// <param name="colliders">Native colliders.</param>
+        /// <returns>Managed collider components.</returns>
+        private static Collider[] ConvertColliders(NativeCollider[] colliders)
+        {
+            Collider[] output = new Collider[colliders.Length];
+            for (int i = 0; i < colliders.Length; i++)
+                output[i] = colliders[i].Component;
+
+            return output;
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetGravity(out Vector3 gravity);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetGravity(ref Vector3 gravity);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern int Internal_AddPhysicsRegion(ref AABox region);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_RemovePhysicsRegion(int handle);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_ClearPhysicsRegions();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_ToggleCollision(ulong layerA, ulong layerB, bool enabled);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_IsCollisionEnabled(ulong layerA, ulong layerB);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_IsUpdateInProgress();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_RayCast(ref Vector3 origin, ref Vector3 unitDir, out ScriptPhysicsQueryHit hit, ulong layer, float max);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_BoxCast(ref AABox box, ref Quaternion rotation, ref Vector3 unitDir, out ScriptPhysicsQueryHit hit, ulong layer, float max);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_SphereCast(ref Sphere sphere, ref Vector3 unitDir, out ScriptPhysicsQueryHit hit, ulong layer, float max);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_CapsuleCast(ref Capsule capsule, ref Quaternion rotation, ref Vector3 unitDir, out ScriptPhysicsQueryHit hit, ulong layer, float max);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_ConvexCast(IntPtr mesh, ref Vector3 position, ref Quaternion rotation, ref Vector3 unitDir, out ScriptPhysicsQueryHit hit, ulong layer, float max);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern ScriptPhysicsQueryHit[] Internal_RayCastAll(ref Vector3 origin, ref Vector3 unitDir, ulong layer, float max);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern ScriptPhysicsQueryHit[] Internal_BoxCastAll(ref AABox box, ref Quaternion rotation, ref Vector3 unitDir, ulong layer, float max);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern ScriptPhysicsQueryHit[] Internal_SphereCastAll(ref Sphere sphere, ref Vector3 unitDir, ulong layer, float max);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern ScriptPhysicsQueryHit[] Internal_CapsuleCastAll(ref Capsule capsule, ref Quaternion rotation, ref Vector3 unitDir, ulong layer, float max);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern ScriptPhysicsQueryHit[] Internal_ConvexCastAll(IntPtr mesh, ref Vector3 position, ref Quaternion rotation, ref Vector3 unitDir, ulong layer, float max);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_RayCastAny(ref Vector3 origin, ref Vector3 unitDir, ulong layer, float max);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_BoxCastAny(ref AABox box, ref Quaternion rotation, ref Vector3 unitDir, ulong layer, float max);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_SphereCastAny(ref Sphere sphere, ref Vector3 unitDir, ulong layer,  float max);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_CapsuleCastAny(ref Capsule capsule, ref Quaternion rotation, ref Vector3 unitDir, ulong layer, float max);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_ConvexCastAny(IntPtr mesh, ref Vector3 position, ref Quaternion rotation, ref Vector3 unitDir, ulong layer, float max);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern NativeCollider[] Internal_BoxOverlap(ref AABox box, ref Quaternion rotation, ulong layer);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern NativeCollider[] Internal_SphereOverlap(ref Sphere sphere, ulong layer);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern NativeCollider[] Internal_CapsuleOverlap(ref Capsule capsule, ref Quaternion rotation, ulong layer);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern NativeCollider[] Internal_ConvexOverlap(IntPtr mesh, ref Vector3 position, ref Quaternion rotation, ulong layer);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_BoxOverlapAny(ref AABox box, ref Quaternion rotation, ulong layer);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_SphereOverlapAny(ref Sphere sphere, ulong layer);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_CapsuleOverlapAny(ref Capsule capsule, ref Quaternion rotation, ulong layer);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_ConvexOverlapAny(IntPtr mesh, ref Vector3 position, ref Quaternion rotation, ulong layer);
     }
     }
 }
 }

+ 63 - 0
SBansheeEngine/Include/BsScriptPhysics.h

@@ -0,0 +1,63 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "BsScriptObject.h"
+#include "BsScriptPhysicsQueryHit.h"
+
+namespace BansheeEngine
+{
+	/**	Interop class between C++ & CLR for Physics. */
+	class BS_SCR_BE_EXPORT ScriptPhysics : public ScriptObject<ScriptPhysics>
+	{
+	public:
+		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "Physics")
+
+	private:
+		ScriptPhysics(MonoObject* instance);
+
+		/************************************************************************/
+		/* 								CLR HOOKS						   		*/
+		/************************************************************************/
+		static void internal_GetGravity(Vector3* gravity);
+		static void internal_SetGravity(Vector3* gravity);
+
+		static int internal_AddPhysicsRegion(AABox* region);
+		static void internal_RemovePhysicsRegion(int handle);
+		static void internal_ClearPhysicsRegions();
+
+		static void internal_ToggleCollision(UINT64 layerA, UINT64 layerB, bool enabled);
+		static bool internal_IsCollisionEnabled(UINT64 layerA, UINT64 layerB);
+
+		static bool internal_IsUpdateInProgress();
+
+		static bool internal_RayCast(Vector3* origin, Vector3* unitDir, ScriptPhysicsQueryHit* hit, UINT64 layer, float max);
+		static bool internal_BoxCast(AABox* box, Quaternion* rotation, Vector3* unitDir, ScriptPhysicsQueryHit* hit, UINT64 layer, float max);
+		static bool internal_SphereCast(Sphere* sphere, Vector3* unitDir, ScriptPhysicsQueryHit* hit, UINT64 layer, float max);
+		static bool internal_CapsuleCast(Capsule* capsule, Quaternion* rotation, Vector3* unitDir, ScriptPhysicsQueryHit* hit, UINT64 layer, float max);
+		static bool internal_ConvexCast(ScriptPhysicsMesh* mesh, Vector3* position, Quaternion* rotation, Vector3* unitDir, ScriptPhysicsQueryHit* hit, UINT64 layer, float max);
+
+		static MonoArray* internal_RayCastAll(Vector3* origin, Vector3* unitDir, UINT64 layer, float max);
+		static MonoArray* internal_BoxCastAll(AABox* box, Quaternion* rotation, Vector3* unitDir, UINT64 layer, float max);
+		static MonoArray* internal_SphereCastAll(Sphere* sphere, Vector3* unitDir, UINT64 layer, float max);
+		static MonoArray* internal_CapsuleCastAll(Capsule* capsule, Quaternion* rotation, Vector3* unitDir, UINT64 layer, float max);
+		static MonoArray* internal_ConvexCastAll(ScriptPhysicsMesh* mesh, Vector3* position, Quaternion* rotation, Vector3* unitDir, UINT64 layer, float max);
+
+		static bool internal_RayCastAny(Vector3* origin, Vector3* unitDir, UINT64 layer, float max);
+		static bool internal_BoxCastAny(AABox* box, Quaternion* rotation, Vector3* unitDir, UINT64 layer, float max);
+		static bool internal_SphereCastAny(Sphere* sphere, Vector3* unitDir, UINT64 layer, float max);
+		static bool internal_CapsuleCastAny(Capsule* capsule, Quaternion* rotation, Vector3* unitDir, UINT64 layer, float max);
+		static bool internal_ConvexCastAny(ScriptPhysicsMesh* mesh, Vector3* position, Quaternion* rotation, Vector3* unitDir, UINT64 layer, float max);
+
+		static MonoArray* internal_BoxOverlap(AABox* box, Quaternion* rotation, UINT64 layer);
+		static MonoArray* internal_SphereOverlap(Sphere* sphere, UINT64 layer);
+		static MonoArray* internal_CapsuleOverlap(Capsule* capsule, Quaternion* rotation, UINT64 layer);
+		static MonoArray* internal_ConvexOverlap(ScriptPhysicsMesh* mesh, Vector3* position, Quaternion* rotation, UINT64 layer);
+
+		static bool internal_BoxOverlapAny(AABox* box, Quaternion* rotation, UINT64 layer);
+		static bool internal_SphereOverlapAny(Sphere* sphere, UINT64 layer);
+		static bool internal_CapsuleOverlapAny(Capsule* capsule, Quaternion* rotation, UINT64 layer);
+		static bool internal_ConvexOverlapAny(ScriptPhysicsMesh* mesh, Vector3* position, Quaternion* rotation, UINT64 layer);
+	};
+}

+ 2 - 0
SBansheeEngine/SBansheeEngine.vcxproj

@@ -330,6 +330,7 @@
     <ClInclude Include="Include\BsScriptObject.h" />
     <ClInclude Include="Include\BsScriptObject.h" />
     <ClInclude Include="Include\BsScriptObjectImpl.h" />
     <ClInclude Include="Include\BsScriptObjectImpl.h" />
     <ClInclude Include="Include\BsScriptObjectManager.h" />
     <ClInclude Include="Include\BsScriptObjectManager.h" />
+    <ClInclude Include="Include\BsScriptPhysics.h" />
     <ClInclude Include="Include\BsScriptPhysicsMaterial.h" />
     <ClInclude Include="Include\BsScriptPhysicsMaterial.h" />
     <ClInclude Include="Include\BsScriptPhysicsMesh.h" />
     <ClInclude Include="Include\BsScriptPhysicsMesh.h" />
     <ClInclude Include="Include\BsScriptPhysicsQueryHit.h" />
     <ClInclude Include="Include\BsScriptPhysicsQueryHit.h" />
@@ -454,6 +455,7 @@
     <ClCompile Include="Source\BsScriptObject.cpp" />
     <ClCompile Include="Source\BsScriptObject.cpp" />
     <ClCompile Include="Source\BsScriptObjectImpl.cpp" />
     <ClCompile Include="Source\BsScriptObjectImpl.cpp" />
     <ClCompile Include="Source\BsScriptObjectManager.cpp" />
     <ClCompile Include="Source\BsScriptObjectManager.cpp" />
+    <ClCompile Include="Source\BsScriptPhysics.cpp" />
     <ClCompile Include="Source\BsScriptPhysicsMaterial.cpp" />
     <ClCompile Include="Source\BsScriptPhysicsMaterial.cpp" />
     <ClCompile Include="Source\BsScriptPhysicsMesh.cpp" />
     <ClCompile Include="Source\BsScriptPhysicsMesh.cpp" />
     <ClCompile Include="Source\BsScriptPhysicsQueryHit.cpp" />
     <ClCompile Include="Source\BsScriptPhysicsQueryHit.cpp" />

+ 6 - 0
SBansheeEngine/SBansheeEngine.vcxproj.filters

@@ -431,6 +431,9 @@
     <ClInclude Include="Source\BsScriptD6Joint.h">
     <ClInclude Include="Source\BsScriptD6Joint.h">
       <Filter>Header Files\Physics</Filter>
       <Filter>Header Files\Physics</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\BsScriptPhysics.h">
+      <Filter>Header Files\Physics</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsScriptTexture2D.cpp">
     <ClCompile Include="Source\BsScriptTexture2D.cpp">
@@ -799,5 +802,8 @@
     <ClCompile Include="Source\BsScriptD6Joint.cpp">
     <ClCompile Include="Source\BsScriptD6Joint.cpp">
       <Filter>Source Files\Physics</Filter>
       <Filter>Source Files\Physics</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="Source\BsScriptPhysics.cpp">
+      <Filter>Source Files\Physics</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 276 - 0
SBansheeEngine/Source/BsScriptPhysics.cpp

@@ -0,0 +1,276 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsScriptPhysics.h"
+#include "BsMonoManager.h"
+#include "BsMonoClass.h"
+#include "BsMonoUtil.h"
+#include "BsPhysics.h"
+#include "BsScriptPhysicsMesh.h"
+#include "BsScriptCollider.h"
+#include "BsCollider.h"
+
+namespace BansheeEngine
+{
+	ScriptPhysics::ScriptPhysics(MonoObject* instance)
+		:ScriptObject(instance)
+	{ }
+
+	void ScriptPhysics::initRuntimeData()
+	{
+		metaData.scriptClass->addInternalCall("Internal_GetGravity", &ScriptPhysics::internal_GetGravity);
+		metaData.scriptClass->addInternalCall("Internal_SetGravity", &ScriptPhysics::internal_SetGravity);
+
+		metaData.scriptClass->addInternalCall("Internal_AddPhysicsRegion", &ScriptPhysics::internal_AddPhysicsRegion);
+		metaData.scriptClass->addInternalCall("Internal_RemovePhysicsRegion", &ScriptPhysics::internal_RemovePhysicsRegion);
+		metaData.scriptClass->addInternalCall("Internal_ClearPhysicsRegions", &ScriptPhysics::internal_ClearPhysicsRegions);
+
+		metaData.scriptClass->addInternalCall("Internal_ToggleCollision", &ScriptPhysics::internal_ToggleCollision);
+		metaData.scriptClass->addInternalCall("Internal_IsCollisionEnabled", &ScriptPhysics::internal_IsCollisionEnabled);
+
+		metaData.scriptClass->addInternalCall("Internal_IsUpdateInProgress", &ScriptPhysics::internal_IsUpdateInProgress);
+
+		metaData.scriptClass->addInternalCall("Internal_RayCast", &ScriptPhysics::internal_RayCast);
+		metaData.scriptClass->addInternalCall("Internal_BoxCast", &ScriptPhysics::internal_BoxCast);
+		metaData.scriptClass->addInternalCall("Internal_SphereCast", &ScriptPhysics::internal_SphereCast);
+		metaData.scriptClass->addInternalCall("Internal_CapsuleCast", &ScriptPhysics::internal_CapsuleCast);
+		metaData.scriptClass->addInternalCall("Internal_ConvexCast", &ScriptPhysics::internal_ConvexCast);
+
+		metaData.scriptClass->addInternalCall("Internal_RayCastAll", &ScriptPhysics::internal_RayCastAll);
+		metaData.scriptClass->addInternalCall("Internal_BoxCastAll", &ScriptPhysics::internal_BoxCastAll);
+		metaData.scriptClass->addInternalCall("Internal_SphereCastAll", &ScriptPhysics::internal_SphereCastAll);
+		metaData.scriptClass->addInternalCall("Internal_CapsuleCastAll", &ScriptPhysics::internal_CapsuleCastAll);
+		metaData.scriptClass->addInternalCall("Internal_ConvexCastAll", &ScriptPhysics::internal_ConvexCastAll);
+
+		metaData.scriptClass->addInternalCall("Internal_RayCastAny", &ScriptPhysics::internal_RayCastAny);
+		metaData.scriptClass->addInternalCall("Internal_BoxCastAny", &ScriptPhysics::internal_BoxCastAny);
+		metaData.scriptClass->addInternalCall("Internal_SphereCastAny", &ScriptPhysics::internal_SphereCastAny);
+		metaData.scriptClass->addInternalCall("Internal_CapsuleCastAny", &ScriptPhysics::internal_CapsuleCastAny);
+		metaData.scriptClass->addInternalCall("Internal_ConvexCastAny", &ScriptPhysics::internal_ConvexCastAny);
+
+		metaData.scriptClass->addInternalCall("Internal_BoxOverlap", &ScriptPhysics::internal_BoxOverlap);
+		metaData.scriptClass->addInternalCall("Internal_SphereOverlap", &ScriptPhysics::internal_SphereOverlap);
+		metaData.scriptClass->addInternalCall("Internal_CapsuleOverlap", &ScriptPhysics::internal_CapsuleOverlap);
+		metaData.scriptClass->addInternalCall("Internal_ConvexOverlap", &ScriptPhysics::internal_ConvexOverlap);
+
+		metaData.scriptClass->addInternalCall("Internal_BoxOverlapAny", &ScriptPhysics::internal_BoxOverlapAny);
+		metaData.scriptClass->addInternalCall("Internal_SphereOverlapAny", &ScriptPhysics::internal_SphereOverlapAny);
+		metaData.scriptClass->addInternalCall("Internal_CapsuleOverlapAny", &ScriptPhysics::internal_CapsuleOverlapAny);
+		metaData.scriptClass->addInternalCall("Internal_ConvexOverlapAny", &ScriptPhysics::internal_ConvexOverlapAny);
+	}
+
+	void ScriptPhysics::internal_GetGravity(Vector3* gravity)
+	{
+		*gravity = gPhysics().getGravity();
+	}
+
+	void ScriptPhysics::internal_SetGravity(Vector3* gravity)
+	{
+		gPhysics().setGravity(*gravity);
+	}
+
+	int ScriptPhysics::internal_AddPhysicsRegion(AABox* region)
+	{
+		return gPhysics().addBroadPhaseRegion(*region);
+	}
+
+	void ScriptPhysics::internal_RemovePhysicsRegion(int handle)
+	{
+		gPhysics().removeBroadPhaseRegion(handle);
+	}
+
+	void ScriptPhysics::internal_ClearPhysicsRegions()
+	{
+		gPhysics().clearBroadPhaseRegions();
+	}
+
+	void ScriptPhysics::internal_ToggleCollision(UINT64 layerA, UINT64 layerB, bool enabled)
+	{
+		gPhysics().toggleCollision(layerA, layerB, enabled);
+	}
+
+	bool ScriptPhysics::internal_IsCollisionEnabled(UINT64 layerA, UINT64 layerB)
+	{
+		return gPhysics().isCollisionEnabled(layerA, layerB);
+	}
+
+	bool ScriptPhysics::internal_IsUpdateInProgress()
+	{
+		return gPhysics()._isUpdateInProgress();
+	}
+
+	bool ScriptPhysics::internal_RayCast(Vector3* origin, Vector3* unitDir, ScriptPhysicsQueryHit* hit, UINT64 layer, float max)
+	{
+		PhysicsQueryHit nativeHit;
+		bool wasHit = gPhysics().rayCast(*origin, *unitDir, nativeHit, layer, max);
+		*hit = ScriptPhysicsQueryHitHelper::create(nativeHit);
+
+		return wasHit;
+	}
+
+	bool ScriptPhysics::internal_BoxCast(AABox* box, Quaternion* rotation, Vector3* unitDir, ScriptPhysicsQueryHit* hit, UINT64 layer, float max)
+	{
+		PhysicsQueryHit nativeHit;
+		bool wasHit = gPhysics().boxCast(*box, *rotation, *unitDir, nativeHit, layer, max);
+		*hit = ScriptPhysicsQueryHitHelper::create(nativeHit);
+
+		return wasHit;
+	}
+
+	bool ScriptPhysics::internal_SphereCast(Sphere* sphere, Vector3* unitDir, ScriptPhysicsQueryHit* hit, UINT64 layer, float max)
+	{
+		PhysicsQueryHit nativeHit;
+		bool wasHit = gPhysics().sphereCast(*sphere, *unitDir, nativeHit, layer, max);
+		*hit = ScriptPhysicsQueryHitHelper::create(nativeHit);
+
+		return wasHit;
+	}
+
+	bool ScriptPhysics::internal_CapsuleCast(Capsule* capsule, Quaternion* rotation, Vector3* unitDir, ScriptPhysicsQueryHit* hit, UINT64 layer, float max)
+	{
+		PhysicsQueryHit nativeHit;
+		bool wasHit = gPhysics().capsuleCast(*capsule, *rotation, *unitDir, nativeHit, layer, max);
+		*hit = ScriptPhysicsQueryHitHelper::create(nativeHit);
+
+		return wasHit;
+	}
+
+	bool ScriptPhysics::internal_ConvexCast(ScriptPhysicsMesh* mesh, Vector3* position, Quaternion* rotation, Vector3* unitDir, ScriptPhysicsQueryHit* hit, UINT64 layer, float max)
+	{
+		HPhysicsMesh meshHandle;
+		if (mesh != nullptr)
+			meshHandle = mesh->getHandle();
+
+		PhysicsQueryHit nativeHit;
+		bool wasHit = gPhysics().convexCast(meshHandle, *position, *rotation, *unitDir, nativeHit, layer, max);
+		*hit = ScriptPhysicsQueryHitHelper::create(nativeHit);
+
+		return wasHit;
+	}
+
+	MonoArray* nativeToManagedHitArray(const Vector<PhysicsQueryHit>& hits)
+	{
+		UINT32 numHits = (UINT32)hits.size();
+		ScriptArray output = ScriptArray::create<ScriptPhysicsQueryHitHelper>(numHits);
+
+		for (UINT32 i = 0; i < numHits; i++)
+			output.set(i, ScriptPhysicsQueryHitHelper::box(ScriptPhysicsQueryHitHelper::create(hits[i])));
+
+		return output.getInternal();
+	}
+
+	MonoArray* ScriptPhysics::internal_RayCastAll(Vector3* origin, Vector3* unitDir, UINT64 layer, float max)
+	{
+		return nativeToManagedHitArray(gPhysics().rayCastAll(*origin, *unitDir, layer, max));
+	}
+
+	MonoArray* ScriptPhysics::internal_BoxCastAll(AABox* box, Quaternion* rotation, Vector3* unitDir, UINT64 layer, float max)
+	{
+		return nativeToManagedHitArray(gPhysics().boxCastAll(*box, *rotation, *unitDir, layer, max));
+	}
+
+	MonoArray* ScriptPhysics::internal_SphereCastAll(Sphere* sphere, Vector3* unitDir, UINT64 layer, float max)
+	{
+		return nativeToManagedHitArray(gPhysics().sphereCastAll(*sphere, *unitDir, layer, max));
+	}
+
+	MonoArray* ScriptPhysics::internal_CapsuleCastAll(Capsule* capsule, Quaternion* rotation, Vector3* unitDir, UINT64 layer, float max)
+	{
+		return nativeToManagedHitArray(gPhysics().capsuleCastAll(*capsule, *rotation, *unitDir, layer, max));
+	}
+
+	MonoArray* ScriptPhysics::internal_ConvexCastAll(ScriptPhysicsMesh* mesh, Vector3* position, Quaternion* rotation, Vector3* unitDir, UINT64 layer, float max)
+	{
+		HPhysicsMesh meshHandle;
+		if (mesh != nullptr)
+			meshHandle = mesh->getHandle();
+
+		return nativeToManagedHitArray(gPhysics().convexCastAll(meshHandle, *position, *rotation, *unitDir, layer, max));
+	}
+
+	bool ScriptPhysics::internal_RayCastAny(Vector3* origin, Vector3* unitDir, UINT64 layer, float max)
+	{
+		return gPhysics().rayCastAny(*origin, *unitDir, layer, max);
+	}
+
+	bool ScriptPhysics::internal_BoxCastAny(AABox* box, Quaternion* rotation, Vector3* unitDir, UINT64 layer, float max)
+	{
+		return gPhysics().boxCastAny(*box, *rotation, *unitDir, layer, max);
+	}
+
+	bool ScriptPhysics::internal_SphereCastAny(Sphere* sphere, Vector3* unitDir, UINT64 layer, float max)
+	{
+		return gPhysics().sphereCastAny(*sphere, *unitDir, layer, max);
+	}
+
+	bool ScriptPhysics::internal_CapsuleCastAny(Capsule* capsule, Quaternion* rotation, Vector3* unitDir, UINT64 layer, float max)
+	{
+		return gPhysics().capsuleCastAny(*capsule, *rotation, *unitDir, layer, max);
+	}
+
+	bool ScriptPhysics::internal_ConvexCastAny(ScriptPhysicsMesh* mesh, Vector3* position, Quaternion* rotation, Vector3* unitDir, UINT64 layer, float max)
+	{
+		HPhysicsMesh meshHandle;
+		if (mesh != nullptr)
+			meshHandle = mesh->getHandle();
+
+		return gPhysics().convexCastAny(meshHandle, *position, *rotation, *unitDir, layer, max);
+	}
+
+	MonoArray* nativeToManagedColliderArray(const Vector<Collider*>& colliders)
+	{
+		UINT32 numColliders = (UINT32)colliders.size();
+		ScriptArray output = ScriptArray::create<ScriptCollider>(numColliders);
+		for (UINT32 i = 0; i < numColliders; i++)
+			output.set(i, colliders[i]->_getOwner(PhysicsOwnerType::Script));
+
+		return output.getInternal();
+	}
+
+	MonoArray* ScriptPhysics::internal_BoxOverlap(AABox* box, Quaternion* rotation, UINT64 layer)
+	{
+		return nativeToManagedColliderArray(gPhysics()._boxOverlap(*box, *rotation, layer));
+	}
+
+	MonoArray* ScriptPhysics::internal_SphereOverlap(Sphere* sphere, UINT64 layer)
+	{
+		return nativeToManagedColliderArray(gPhysics()._sphereOverlap(*sphere, layer));
+	}
+
+	MonoArray* ScriptPhysics::internal_CapsuleOverlap(Capsule* capsule, Quaternion* rotation, UINT64 layer)
+	{
+		return nativeToManagedColliderArray(gPhysics()._capsuleOverlap(*capsule, *rotation, layer));
+	}
+
+	MonoArray* ScriptPhysics::internal_ConvexOverlap(ScriptPhysicsMesh* mesh, Vector3* position, Quaternion* rotation, UINT64 layer)
+	{
+		HPhysicsMesh meshHandle;
+		if (mesh != nullptr)
+			meshHandle = mesh->getHandle();
+
+		return nativeToManagedColliderArray(gPhysics()._convexOverlap(meshHandle, *position, *rotation, layer));
+	}
+
+	bool ScriptPhysics::internal_BoxOverlapAny(AABox* box, Quaternion* rotation, UINT64 layer)
+	{
+		return gPhysics().boxOverlapAny(*box, *rotation, layer);
+	}
+
+	bool ScriptPhysics::internal_SphereOverlapAny(Sphere* sphere, UINT64 layer)
+	{
+		return gPhysics().sphereOverlapAny(*sphere, layer);
+	}
+
+	bool ScriptPhysics::internal_CapsuleOverlapAny(Capsule* capsule, Quaternion* rotation, UINT64 layer)
+	{
+		return gPhysics().capsuleOverlapAny(*capsule, *rotation, layer);
+	}
+
+	bool ScriptPhysics::internal_ConvexOverlapAny(ScriptPhysicsMesh* mesh, Vector3* position, Quaternion* rotation, UINT64 layer)
+	{
+		HPhysicsMesh meshHandle;
+		if (mesh != nullptr)
+			meshHandle = mesh->getHandle();
+
+		return gPhysics().convexOverlapAny(meshHandle, *position, *rotation, layer);
+	}
+}