Explorar el Código

Added character controller structs and enums to managed code

BearishSun hace 9 años
padre
commit
3ab055c49c

+ 1 - 0
MBansheeEngine/MBansheeEngine.csproj

@@ -111,6 +111,7 @@
     <Compile Include="PathEx.cs" />
     <Compile Include="Physics\BoxCollider.cs" />
     <Compile Include="Physics\CapsuleCollider.cs" />
+    <Compile Include="Physics\CharacterController.cs" />
     <Compile Include="Physics\Collider.cs" />
     <Compile Include="Physics\Joint.cs" />
     <Compile Include="Physics\MeshCollider.cs" />

+ 172 - 0
MBansheeEngine/Physics/CharacterController.cs

@@ -0,0 +1,172 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+using System.Runtime.InteropServices;
+
+namespace BansheeEngine
+{
+    /// <summary>
+    /// Special physics controller meant to be used for game characters. Uses the "slide-and-collide" physics instead of
+    /// of the standard physics model to handle various issues with manually moving kinematic objects.Uses a capsule to
+    /// represent the character's bounds. 
+    /// </summary>
+    public class CharacterController : Component
+    {
+        [SerializeField]
+        internal SerializableData serializableData = new SerializableData();
+
+        // TODO
+
+        /// <summary>
+        /// Holds all data the character controller component needs to persist through serialization.
+        /// </summary>
+        [SerializeObject]
+        internal class SerializableData
+        {
+            public Vector3 position;
+            public float contactOffset = 0.1f;
+            public float stepOffset = 0.5f;
+            public Radian slopeLimit = new Degree(45.0f);
+            public float minMoveDistance = 0.0f;
+            public float height = 0.0f;
+            public float radius = 1.0f;
+            public Vector3 up = Vector3.YAxis;
+            public CharacterClimbingMode climbingMode = CharacterClimbingMode.Normal;
+            public CharacterNonWalkableMode nonWalkableMode = CharacterNonWalkableMode.Prevent;
+        }
+    }
+
+    /// <summary>
+    /// Controls climbing behaviour for a capsule character controller. Normally the character controller will not
+    /// automatically climb when heights are greater than the assigned step offset.However due to the shape of the capsule
+    /// it might automatically climb over slightly larger heights than assigned step offsets.
+    /// </summary>
+    public enum CharacterClimbingMode
+    {
+        /// <summary>
+        /// Normal behaviour. Capsule character controller will be able to auto-step even above the step offset.
+        /// </summary>
+        Normal,
+        /// <summary>
+        /// The system will attempt to limit auto-step to the provided step offset and no higher.
+        /// </summary>
+		Constrained
+    }
+
+    /// <summary>
+    /// Controls behaviour when a character controller reaches a slope thats larger than its slope offset.
+    /// </summary>
+    public enum CharacterNonWalkableMode
+    {
+        /// <summary>
+        /// Character will be prevented from going further, but will be allowed to move laterally.
+        /// </summary>
+        Prevent,
+        /// <summary>
+        /// Character will be prevented from going further, but also slide down the slope.
+        /// </summary>
+		PreventAndSlide
+    }
+
+    /// <summary>
+    /// Reports in which directions is the character colliding with other objects.
+    /// </summary>
+    public enum CharacterCollisionFlag
+    {
+        /// <summary>
+        /// Character is colliding with its sides. 
+        /// </summary>
+        Sides = 0x1,
+        /// <summary>
+        /// Character is colliding with the ceiling.
+        /// </summary>
+		Up = 0x2,
+        /// <summary>
+        /// Character is colliding with the ground.
+        /// </summary>
+		Down = 0x4
+	}
+
+    /// <summary>
+    /// Used for passing CharacterController initialization data between native and managed code.
+    /// </summary>
+    [StructLayout(LayoutKind.Sequential)]
+    internal struct ScriptCharacterControllerData
+    {
+        public Vector3 position;
+        public float contactOffset;
+        public float stepOffset;
+        public Radian slopeLimit;
+        public float minMoveDistance;
+        public float height;
+        public float radius;
+        public Vector3 up;
+        public CharacterClimbingMode climbingMode;
+        public CharacterNonWalkableMode nonWalkableMode;
+    }
+
+    /// <summary>
+    /// Used for passing ControllerCollision data between native and managed code.
+    /// </summary>
+    internal struct ScriptControllerCollision // Note: Must match C++ struct ScriptControllerCollision
+    {
+        public Vector3 position;
+        public Vector3 normal;
+        public Vector3 motionDir;
+        public float motionAmount;
+        public Collider collider;
+        public int triangleIndex;
+        public CharacterController controller;
+        public bool isControllerCollision;
+    }
+
+    /// <summary>
+    /// Contains data about a collision of a character controller and another object.
+    /// </summary>
+    public class ControllerCollision
+    {
+        /// <summary>
+        /// Contact position.
+        /// </summary>
+        public Vector3 position;
+
+        /// <summary>
+        /// Contact normal.
+        /// </summary>
+        public Vector3 normal;
+
+        /// <summary>
+        /// Direction of motion after the hit.
+        /// </summary>
+        public Vector3 motionDir;
+
+        /// <summary>
+        /// Magnitude of motion after the hit.
+        /// </summary>
+        public float motionAmount;
+    };
+
+    /// <summary>
+    /// Contains data about a collision of a character controller and a collider.
+    /// </summary>
+    public class ControllerColliderCollision : ControllerCollision
+    {
+        /// <summary>
+        /// Collider that was touched. 
+        /// </summary>
+        public Collider collider;
+
+        /// <summary>
+        /// Touched triangle index for mesh colliders.
+        /// </summary>
+        public int triangleIndex;
+    };
+
+    /** Contains data about a collision between two character controllers. */
+    public class ControllerControllerCollision : ControllerCollision
+    {
+        /// <summary>
+        /// Controller that was touched.
+        /// </summary>
+        public CharacterController controller;
+    };
+}

+ 0 - 1
MBansheeEngine/Physics/Joint.cs

@@ -1,6 +1,5 @@
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-
 using System.Runtime.InteropServices;
 
 namespace BansheeEngine

+ 45 - 0
SBansheeEngine/Include/BsScriptControllerCollision.h

@@ -0,0 +1,45 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "BsScriptObject.h"
+#include "BsCharacterController.h"
+
+namespace BansheeEngine
+{
+	/** Interop struct between C++ & CLR for ControllerCollision. */
+	struct ScriptControllerCollision // Note: Must match C++ struct ScriptControllerCollision
+	{
+		Vector3 position;
+		Vector3 normal;
+		Vector3 motionDir;
+		float motionAmount;
+		MonoObject* collider;
+		int triangleIndex;
+		MonoObject* controller;
+		bool isControllerCollision;
+	};
+
+	/** Helper class for dealing with ControllerCollision structure. */
+	class BS_SCR_BE_EXPORT ScriptControllerCollisionHelper : public ScriptObject<ScriptControllerCollisionHelper>
+	{
+		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "ScriptControllerCollision")
+
+	public:
+		/** Converts native collision data to its managed counterpart. */
+		static ScriptControllerCollision create(const ControllerColliderCollision& data);
+
+		/** Converts native collision data to its managed counterpart. */
+		static ScriptControllerCollision create(const ControllerControllerCollision& data);
+
+		/** Unboxes a boxed managed ScriptControllerCollision struct and returns the native version of the structure. */
+		static ScriptControllerCollision unbox(MonoObject* obj);
+
+		/** Boxes a native ScriptControllerCollision struct and returns a managed object containing it. */
+		static MonoObject* box(const ScriptControllerCollision& value);
+
+	private:
+		ScriptControllerCollisionHelper(MonoObject* instance);
+	};
+}

+ 2 - 0
SBansheeEngine/SBansheeEngine.vcxproj

@@ -283,6 +283,7 @@
     <ClInclude Include="Include\BsScriptColor.h" />
     <ClInclude Include="Include\BsScriptComponent.h" />
     <ClInclude Include="Include\BsScriptContextMenu.h" />
+    <ClInclude Include="Include\BsScriptControllerCollision.h" />
     <ClInclude Include="Include\BsScriptCursor.h" />
     <ClInclude Include="Include\BsScriptDebug.h" />
     <ClInclude Include="Include\BsScriptEnginePrerequisites.h" />
@@ -395,6 +396,7 @@
     <ClCompile Include="Source\BsScriptColor.cpp" />
     <ClCompile Include="Source\BsScriptComponent.cpp" />
     <ClCompile Include="Source\BsScriptContextMenu.cpp" />
+    <ClCompile Include="Source\BsScriptControllerCollision.cpp" />
     <ClCompile Include="Source\BsScriptCursor.cpp" />
     <ClCompile Include="Source\BsScriptDebug.cpp" />
     <ClCompile Include="Source\BsScriptEnginePlugin.cpp" />

+ 6 - 0
SBansheeEngine/SBansheeEngine.vcxproj.filters

@@ -404,6 +404,9 @@
     <ClInclude Include="Include\BsScriptJointCommon.h">
       <Filter>Header Files\Physics</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsScriptControllerCollision.h">
+      <Filter>Header Files\Physics</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsScriptTexture2D.cpp">
@@ -745,5 +748,8 @@
     <ClCompile Include="Source\BsScriptJointCommon.cpp">
       <Filter>Source Files\Physics</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsScriptControllerCollision.cpp">
+      <Filter>Source Files\Physics</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 62 - 0
SBansheeEngine/Source/BsScriptControllerCollision.cpp

@@ -0,0 +1,62 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsScriptControllerCollision.h"
+#include "BsMonoManager.h"
+#include "BsMonoClass.h"
+#include "BsCollider.h"
+
+namespace BansheeEngine
+{
+	ScriptControllerCollisionHelper::ScriptControllerCollisionHelper(MonoObject* instance)
+		:ScriptObject(instance)
+	{ }
+
+	void ScriptControllerCollisionHelper::initRuntimeData()
+	{ }
+
+	ScriptControllerCollision ScriptControllerCollisionHelper::create(const ControllerColliderCollision& data)
+	{
+		ScriptControllerCollision output;
+
+		if (data.colliderRaw != nullptr)
+			output.collider = (MonoObject*)data.colliderRaw->_getOwner(PhysicsOwnerType::Script);
+
+		output.isControllerCollision = false;
+		output.motionAmount = data.motionAmount;
+		output.motionDir = data.motionDir;
+		output.normal = data.normal;
+		output.position = data.position;
+		output.triangleIndex = data.triangleIndex;
+
+		return output;
+	}
+
+	ScriptControllerCollision ScriptControllerCollisionHelper::create(const ControllerControllerCollision& data)
+	{
+		ScriptControllerCollision output;
+
+		if (data.controllerRaw != nullptr)
+			output.controller = (MonoObject*)data.controllerRaw->_getOwner(PhysicsOwnerType::Script);
+
+		output.isControllerCollision = true;
+		output.motionAmount = data.motionAmount;
+		output.motionDir = data.motionDir;
+		output.normal = data.normal;
+		output.position = data.position;
+		output.triangleIndex = 0;
+
+		return output;
+	}
+
+	MonoObject* ScriptControllerCollisionHelper::box(const ScriptControllerCollision& value)
+	{
+		// We're casting away const but it's fine since structs are passed by value anyway
+		return mono_value_box(MonoManager::instance().getDomain(),
+			metaData.scriptClass->_getInternalClass(), (void*)&value);
+	}
+
+	ScriptControllerCollision ScriptControllerCollisionHelper::unbox(MonoObject* obj)
+	{
+		return *(ScriptControllerCollision*)mono_object_unbox(obj);
+	}
+}