Sfoglia il codice sorgente

PhysX implementation for physics queries

BearishSun 9 anni fa
parent
commit
3558a71c51
35 ha cambiato i file con 722 aggiunte e 213 eliminazioni
  1. 1 1
      BansheeCore/BansheeCore.vcxproj
  2. 6 6
      BansheeCore/BansheeCore.vcxproj.filters
  3. 30 3
      BansheeCore/Include/BsCharacterController.h
  4. 18 1
      BansheeCore/Include/BsCollider.h
  5. 0 24
      BansheeCore/Include/BsCollision.h
  6. 3 0
      BansheeCore/Include/BsComponent.h
  7. 2 0
      BansheeCore/Include/BsCorePrerequisites.h
  8. 19 0
      BansheeCore/Include/BsJoint.h
  9. 58 38
      BansheeCore/Include/BsPhysics.h
  10. 48 0
      BansheeCore/Include/BsPhysicsCommon.h
  11. 19 1
      BansheeCore/Include/BsRigidbody.h
  12. 4 1
      BansheeCore/Source/BsCBoxCollider.cpp
  13. 5 1
      BansheeCore/Source/BsCCapsuleCollider.cpp
  14. 14 2
      BansheeCore/Source/BsCCharacterController.cpp
  15. 17 3
      BansheeCore/Source/BsCCollider.cpp
  16. 4 1
      BansheeCore/Source/BsCD6Joint.cpp
  17. 4 1
      BansheeCore/Source/BsCDistanceJoint.cpp
  18. 4 1
      BansheeCore/Source/BsCFixedJoint.cpp
  19. 4 1
      BansheeCore/Source/BsCHingeJoint.cpp
  20. 2 0
      BansheeCore/Source/BsCJoint.cpp
  21. 1 0
      BansheeCore/Source/BsCMeshCollider.cpp
  22. 4 1
      BansheeCore/Source/BsCPlaneCollider.cpp
  23. 5 0
      BansheeCore/Source/BsCRigidbody.cpp
  24. 4 1
      BansheeCore/Source/BsCSliderJoint.cpp
  25. 4 1
      BansheeCore/Source/BsCSphereCollider.cpp
  26. 4 1
      BansheeCore/Source/BsCSphericalJoint.cpp
  27. 1 0
      BansheeCore/Source/BsCollider.cpp
  28. 59 0
      BansheeCore/Source/BsPhysics.cpp
  29. 0 1
      BansheeCore/Source/BsRigidbody.cpp
  30. 1 1
      BansheePhysX/Include/BsFPhysXCollider.h
  31. 41 40
      BansheePhysX/Include/BsPhysX.h
  32. 318 80
      BansheePhysX/Source/BsPhysX.cpp
  33. 3 2
      BansheePhysX/Source/BsPhysXCharacterController.cpp
  34. 9 0
      BansheeUtility/Include/BsCapsule.h
  35. 6 0
      BansheeUtility/Include/BsLineSegment3.h

+ 1 - 1
BansheeCore/BansheeCore.vcxproj

@@ -318,7 +318,7 @@
     <ClInclude Include="Include\BsCMeshCollider.h" />
     <ClInclude Include="Include\BsCMeshCollider.h" />
     <ClInclude Include="Include\BsCMeshColliderRTTI.h" />
     <ClInclude Include="Include\BsCMeshColliderRTTI.h" />
     <ClInclude Include="Include\BsCollider.h" />
     <ClInclude Include="Include\BsCollider.h" />
-    <ClInclude Include="Include\BsCollision.h" />
+    <ClInclude Include="Include\BsPhysicsCommon.h" />
     <ClInclude Include="Include\BsCoreObjectCore.h" />
     <ClInclude Include="Include\BsCoreObjectCore.h" />
     <ClInclude Include="Include\BsCPlaneCollider.h" />
     <ClInclude Include="Include\BsCPlaneCollider.h" />
     <ClInclude Include="Include\BsCPlaneColliderRTTI.h" />
     <ClInclude Include="Include\BsCPlaneColliderRTTI.h" />

+ 6 - 6
BansheeCore/BansheeCore.vcxproj.filters

@@ -605,15 +605,9 @@
     <ClInclude Include="Include\BsPhysicsMaterialRTTI.h">
     <ClInclude Include="Include\BsPhysicsMaterialRTTI.h">
       <Filter>Header Files\RTTI</Filter>
       <Filter>Header Files\RTTI</Filter>
     </ClInclude>
     </ClInclude>
-    <ClInclude Include="Include\BsCollider.h">
-      <Filter>Header Files\Physics</Filter>
-    </ClInclude>
     <ClInclude Include="Include\BsRigidbody.h">
     <ClInclude Include="Include\BsRigidbody.h">
       <Filter>Header Files\Physics</Filter>
       <Filter>Header Files\Physics</Filter>
     </ClInclude>
     </ClInclude>
-    <ClInclude Include="Include\BsCollision.h">
-      <Filter>Header Files\Physics</Filter>
-    </ClInclude>
     <ClInclude Include="Include\BsBoxCollider.h">
     <ClInclude Include="Include\BsBoxCollider.h">
       <Filter>Header Files\Physics</Filter>
       <Filter>Header Files\Physics</Filter>
     </ClInclude>
     </ClInclude>
@@ -755,6 +749,12 @@
     <ClInclude Include="Include\BsCCharacterControllerRTTI.h">
     <ClInclude Include="Include\BsCCharacterControllerRTTI.h">
       <Filter>Header Files\RTTI</Filter>
       <Filter>Header Files\RTTI</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\BsCollider.h">
+      <Filter>Header Files\Physics</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsPhysicsCommon.h">
+      <Filter>Header Files\Physics</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsCoreApplication.cpp">
     <ClCompile Include="Source\BsCoreApplication.cpp">

+ 30 - 3
BansheeCore/Include/BsCharacterController.h

@@ -3,6 +3,7 @@
 #pragma once
 #pragma once
 
 
 #include "BsCorePrerequisites.h"
 #include "BsCorePrerequisites.h"
+#include "BsPhysicsCommon.h"
 #include "BsVector3.h"
 #include "BsVector3.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
@@ -199,7 +200,23 @@ namespace BansheeEngine
 		/** Triggered when the controller hits another character controller. */
 		/** Triggered when the controller hits another character controller. */
 		Event<void(const ControllerControllerCollision&)> onControllerHit;
 		Event<void(const ControllerControllerCollision&)> onControllerHit;
 
 
+		/** @cond INTERNAL */
+
+		/** 
+		 * Sets the object that owns this physics object, if any. Used for high level systems so they can easily map their
+		 * high level physics objects from the low level ones returned by various queries and events.
+		 */
+		void _setOwner(PhysicsOwnerType type, void* owner) { mOwner.type = type; mOwner.ownerData = owner; }
+
+		/** 
+		 * Gets the object that owns this physics object, if any. Used for high level systems so they can easily map their
+		 * high level physics objects from the low level ones returned by various queries and events.
+		 */
+		void* _getOwner(PhysicsOwnerType type) const { return mOwner.type == type ? mOwner.ownerData : nullptr; }
+
+		/** @endcond */
 	private:
 	private:
+		PhysicsObjectOwner mOwner;
 		UINT64 mLayer = 1;
 		UINT64 mLayer = 1;
 	};
 	};
 
 
@@ -269,14 +286,24 @@ namespace BansheeEngine
 	/** Contains data about a collision of a character controller and a collider. */
 	/** Contains data about a collision of a character controller and a collider. */
 	struct ControllerColliderCollision : ControllerCollision
 	struct ControllerColliderCollision : ControllerCollision
 	{
 	{
-		Collider* collider; /**< Collider that was touched. */
+		/**
+		 * Component of the controller that was touched. Can be null if the controller has no component parent, in which 
+		 * case check ::colliderRaw. 
+		 */
+		HCollider collider;
+		Collider* colliderRaw; /**< Collider that was touched. */
 		UINT32 triangleIndex; /**< Touched triangle index for mesh colliders. */
 		UINT32 triangleIndex; /**< Touched triangle index for mesh colliders. */
 	};
 	};
 
 
-	/** Contains data about a collision between two character controllers */
+	/** Contains data about a collision between two character controllers. */
 	struct ControllerControllerCollision : ControllerCollision
 	struct ControllerControllerCollision : ControllerCollision
 	{
 	{
-		CharacterController* controller; /**< Controller that was touched. */
+		/**
+		 * Component of the controller that was touched. Can be null if the controller has no component parent, in which 
+		 * case check ::controllerRaw. 
+		 */
+		HCharacterController controller; 
+		CharacterController* controllerRaw; /**< Controller that was touched. */
 	};
 	};
 
 
 	/** @} */
 	/** @} */

+ 18 - 1
BansheeCore/Include/BsCollider.h

@@ -3,7 +3,7 @@
 #pragma once
 #pragma once
 
 
 #include "BsCorePrerequisites.h"
 #include "BsCorePrerequisites.h"
-#include "BsCollision.h"
+#include "BsPhysicsCommon.h"
 #include "BsVector3.h"
 #include "BsVector3.h"
 #include "BsQuaternion.h"
 #include "BsQuaternion.h"
 
 
@@ -46,9 +46,26 @@ namespace BansheeEngine
 		Event<void(const CollisionData&)> onCollisionStay;
 		Event<void(const CollisionData&)> onCollisionStay;
 		Event<void(const CollisionData&)> onCollisionEnd;
 		Event<void(const CollisionData&)> onCollisionEnd;
 
 
+		/** @cond INTERNAL */
+
 		FCollider* _getInternal() const { return mInternal; }
 		FCollider* _getInternal() const { return mInternal; }
+
+		/** 
+		 * Sets the object that owns this physics object, if any. Used for high level systems so they can easily map their
+		 * high level physics objects from the low level ones returned by various queries and events.
+		 */
+		void _setOwner(PhysicsOwnerType type, void* owner) { mOwner.type = type; mOwner.ownerData = owner; }
+
+		/** 
+		 * Gets the object that owns this physics object, if any. Used for high level systems so they can easily map their
+		 * high level physics objects from the low level ones returned by various queries and events.
+		 */
+		void* _getOwner(PhysicsOwnerType type) const { return mOwner.type == type ? mOwner.ownerData : nullptr; }
+
+		/** @endcond */
 	protected:
 	protected:
 		FCollider* mInternal = nullptr;
 		FCollider* mInternal = nullptr;
+		PhysicsObjectOwner mOwner;
 		SPtr<Rigidbody> mRigidbody;
 		SPtr<Rigidbody> mRigidbody;
 		Vector3 mScale = Vector3::ONE;
 		Vector3 mScale = Vector3::ONE;
 	};
 	};

+ 0 - 24
BansheeCore/Include/BsCollision.h

@@ -1,24 +0,0 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsVector3.h"
-
-namespace BansheeEngine
-{
-	struct ContactPoint
-	{
-		Vector3 position; /**< Contact point in world space. */
-		Vector3 normal; /**< Normal pointing from the second shape to the first shape. */
-		/** Impulse applied to the objects to keep them from penetrating. Divide by simulation step to get the force. */
-		float impulse;
-		float separation; /**< Determines how far are the objects. Negative value denotes penetration. */
-	};
-
-	struct CollisionData
-	{
-		Collider* collider;
-		Vector<ContactPoint> contactPoints; // Note: Not too happy this is heap allocated, use static allocator?
-	};
-}

+ 3 - 0
BansheeCore/Include/BsComponent.h

@@ -22,6 +22,9 @@ namespace BansheeEngine
 		/** @copydoc sceneObject */
 		/** @copydoc sceneObject */
 		HSceneObject SO() const { return sceneObject(); }
 		HSceneObject SO() const { return sceneObject(); }
 
 
+		/**	Returns a handle to this object. */
+		HComponent getHandle() const { return mThisHandle; }
+
 		/**
 		/**
 		 * Called once per frame on all components.
 		 * Called once per frame on all components.
 		 * 			
 		 * 			

+ 2 - 0
BansheeCore/Include/BsCorePrerequisites.h

@@ -271,6 +271,7 @@ namespace BansheeEngine
 	class CSphericalJoint;
 	class CSphericalJoint;
 	class CSliderJoint;
 	class CSliderJoint;
 	class CD6Joint;
 	class CD6Joint;
+	class CCharacterController;
 	// Asset import
 	// Asset import
 	class SpecificImporter;
 	class SpecificImporter;
 	class Importer;
 	class Importer;
@@ -518,6 +519,7 @@ namespace BansheeEngine
 	typedef GameObjectHandle<CSphericalJoint> HSphericalJoint;
 	typedef GameObjectHandle<CSphericalJoint> HSphericalJoint;
 	typedef GameObjectHandle<CFixedJoint> HFixedJoint;
 	typedef GameObjectHandle<CFixedJoint> HFixedJoint;
 	typedef GameObjectHandle<CD6Joint> HD6Joint;
 	typedef GameObjectHandle<CD6Joint> HD6Joint;
+	typedef GameObjectHandle<CCharacterController> HCharacterController;
 
 
 	/** @} */
 	/** @} */
 }
 }

+ 19 - 0
BansheeCore/Include/BsJoint.h

@@ -3,6 +3,7 @@
 #pragma once
 #pragma once
 
 
 #include "BsCorePrerequisites.h"
 #include "BsCorePrerequisites.h"
+#include "BsPhysicsCommon.h"
 #include "BsFJoint.h"
 #include "BsFJoint.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
@@ -55,7 +56,25 @@ namespace BansheeEngine
 
 
 		/** Triggered when the joint's break force or torque is exceeded. */
 		/** Triggered when the joint's break force or torque is exceeded. */
 		Event<void()> onJointBreak;
 		Event<void()> onJointBreak;
+
+		/** @cond INTERNAL */
+
+		/** 
+		 * Sets the object that owns this physics object, if any. Used for high level systems so they can easily map their
+		 * high level physics objects from the low level ones returned by various queries and events.
+		 */
+		void _setOwner(PhysicsOwnerType type, void* owner) { mOwner.type = type; mOwner.ownerData = owner; }
+
+		/** 
+		 * Gets the object that owns this physics object, if any. Used for high level systems so they can easily map their
+		 * high level physics objects from the low level ones returned by various queries and events.
+		 */
+		void* _getOwner(PhysicsOwnerType type) const { return mOwner.type == type ? mOwner.ownerData : nullptr; }
+
+		/** @endcond */
+
 	protected:
 	protected:
+		PhysicsObjectOwner mOwner;
 		FJoint* mInternal = nullptr;
 		FJoint* mInternal = nullptr;
 	};
 	};
 
 

+ 58 - 38
BansheeCore/Include/BsPhysics.h

@@ -49,7 +49,12 @@ namespace BansheeEngine
 		Vector2 uv; /**< UV coordinates of the triangle that was hit (only applicable when triangle meshes are hit). */
 		Vector2 uv; /**< UV coordinates of the triangle that was hit (only applicable when triangle meshes are hit). */
 		float distance; /**< Distance from the query origin to the hit position. */
 		float distance; /**< Distance from the query origin to the hit position. */
 		UINT32 triangleIdx; /**< Index of the triangle that was hit (only applicable when triangle meshes are hit). */
 		UINT32 triangleIdx; /**< Index of the triangle that was hit (only applicable when triangle meshes are hit). */
-		HCollider collider; /**< Collider that was hit. */
+		Collider* colliderRaw; /**< Collider that was hit. */
+		/** 
+		 * Component of the collider that was hit. This may be null if the hit collider has no owner component, in which
+		 * case refer to ::colliderRaw.
+		 */
+		HCollider collider;
 	};
 	};
 
 
 	class BS_CORE_EXPORT Physics : public Module<Physics>
 	class BS_CORE_EXPORT Physics : public Module<Physics>
@@ -101,20 +106,20 @@ namespace BansheeEngine
 		 *						detected.
 		 *						detected.
 		 * @return				True if something was hit, false otherwise.
 		 * @return				True if something was hit, false otherwise.
 		 */
 		 */
-		virtual bool rayCast(const Ray& ray, PhysicsQueryHit& hit, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
+		virtual bool rayCast(const Ray& ray, PhysicsQueryHit& hit, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX);
 
 
 		/**
 		/**
 		 * Casts a ray into the scene and returns the closest found hit, if any.
 		 * Casts a ray into the scene and returns the closest found hit, if any.
 		 * 
 		 * 
 		 * @param[in]	origin		Origin of the ray to cast into the scene.
 		 * @param[in]	origin		Origin of the ray to cast into the scene.
-		 * @param[in]	direction	Direction of the ray to cast into the scene.
+		 * @param[in]	unitDir		Unit direction of the ray to cast into the scene.
 		 * @param[out]	hit			Information recorded about a hit. Only valid if method returns true.
 		 * @param[out]	hit			Information recorded about a hit. Only valid if method returns true.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 *							detected.
 		 *							detected.
 		 * @return					True if something was hit, false otherwise.
 		 * @return					True if something was hit, false otherwise.
 		 */
 		 */
-		virtual bool rayCast(const Vector3& origin, const Vector3& direction, PhysicsQueryHit& hit, 
+		virtual bool rayCast(const Vector3& origin, const Vector3& unitDir, PhysicsQueryHit& hit,
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 
 
 		/**
 		/**
@@ -122,28 +127,28 @@ namespace BansheeEngine
 		 * 
 		 * 
 		 * @param[in]	box			Box to sweep through the scene.
 		 * @param[in]	box			Box to sweep through the scene.
 		 * @param[in]	rotation	Orientation of the box.
 		 * @param[in]	rotation	Orientation of the box.
-		 * @param[in]	direction	Direction towards which to perform the sweep.
+		 * @param[in]	unitDir		Unit direction towards which to perform the sweep.
 		 * @param[out]	hit			Information recorded about a hit. Only valid if method returns true.
 		 * @param[out]	hit			Information recorded about a hit. Only valid if method returns true.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 *							detected.
 		 *							detected.
 		 * @return					True if something was hit, false otherwise.
 		 * @return					True if something was hit, false otherwise.
 		 */
 		 */
-		virtual bool boxCast(const AABox& box, const Quaternion& rotation, const Vector3& direction, PhysicsQueryHit& hit,
+		virtual bool boxCast(const AABox& box, const Quaternion& rotation, const Vector3& unitDir, PhysicsQueryHit& hit,
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 
 
 		/**
 		/**
 		 * Performs a sweep into the scene using a sphere and returns the closest found hit, if any.
 		 * Performs a sweep into the scene using a sphere and returns the closest found hit, if any.
 		 * 
 		 * 
 		 * @param[in]	sphere		Sphere to sweep through the scene.
 		 * @param[in]	sphere		Sphere to sweep through the scene.
-		 * @param[in]	direction	Direction towards which to perform the sweep.
+		 * @param[in]	unitDir		Unit direction towards which to perform the sweep.
 		 * @param[out]	hit			Information recorded about a hit. Only valid if method returns true.
 		 * @param[out]	hit			Information recorded about a hit. Only valid if method returns true.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 *							detected.
 		 *							detected.
 		 * @return					True if something was hit, false otherwise.
 		 * @return					True if something was hit, false otherwise.
 		 */
 		 */
-		virtual bool sphereCast(const Sphere& sphere, const Vector3& direction, PhysicsQueryHit& hit,
+		virtual bool sphereCast(const Sphere& sphere, const Vector3& unitDir, PhysicsQueryHit& hit,
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 
 
 		/**
 		/**
@@ -151,14 +156,14 @@ namespace BansheeEngine
 		 * 
 		 * 
 		 * @param[in]	capsule		Capsule to sweep through the scene.
 		 * @param[in]	capsule		Capsule to sweep through the scene.
 		 * @param[in]	rotation	Orientation of the capsule.
 		 * @param[in]	rotation	Orientation of the capsule.
-		 * @param[in]	direction	Direction towards which to perform the sweep.
+		 * @param[in]	unitDir		Unit direction towards which to perform the sweep.
 		 * @param[out]	hit			Information recorded about a hit. Only valid if method returns true.
 		 * @param[out]	hit			Information recorded about a hit. Only valid if method returns true.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 *							detected.
 		 *							detected.
 		 * @return					True if something was hit, false otherwise.
 		 * @return					True if something was hit, false otherwise.
 		 */
 		 */
-		virtual bool capsuleCast(const Capsule& capsule, const Quaternion& rotation, const Vector3& direction, 
+		virtual bool capsuleCast(const Capsule& capsule, const Quaternion& rotation, const Vector3& unitDir,
 			PhysicsQueryHit& hit, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 			PhysicsQueryHit& hit, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 
 
 		/**
 		/**
@@ -167,7 +172,7 @@ namespace BansheeEngine
 		 * @param[in]	mesh		Mesh to sweep through the scene. Must be convex.
 		 * @param[in]	mesh		Mesh to sweep through the scene. Must be convex.
 		 * @param[in]	position	Starting position of the mesh.
 		 * @param[in]	position	Starting position of the mesh.
 		 * @param[in]	rotation	Orientation of the mesh.
 		 * @param[in]	rotation	Orientation of the mesh.
-		 * @param[in]	direction	Direction towards which to perform the sweep.
+		 * @param[in]	unitDir		Unit direction towards which to perform the sweep.
 		 * @param[out]	hit			Information recorded about a hit. Only valid if method returns true.
 		 * @param[out]	hit			Information recorded about a hit. Only valid if method returns true.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
@@ -175,7 +180,7 @@ namespace BansheeEngine
 		 * @return					True if something was hit, false otherwise.
 		 * @return					True if something was hit, false otherwise.
 		 */
 		 */
 		virtual bool convexCast(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
 		virtual bool convexCast(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
-			const Vector3& direction, PhysicsQueryHit& hit, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
+			const Vector3& unitDir, PhysicsQueryHit& hit, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 
 
 		/**
 		/**
 		 * Casts a ray into the scene and returns all found hits.
 		 * Casts a ray into the scene and returns all found hits.
@@ -186,19 +191,19 @@ namespace BansheeEngine
 		 *						detected.
 		 *						detected.
 		 * @return				List of all detected hits.
 		 * @return				List of all detected hits.
 		 */
 		 */
-		virtual Vector<PhysicsQueryHit> rayCastAll(const Ray& ray, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
+		virtual Vector<PhysicsQueryHit> rayCastAll(const Ray& ray, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX);
 
 
 		/**
 		/**
 		 * Casts a ray into the scene and returns all found hits.
 		 * Casts a ray into the scene and returns all found hits.
 		 * 
 		 * 
 		 * @param[in]	origin		Origin of the ray to cast into the scene.
 		 * @param[in]	origin		Origin of the ray to cast into the scene.
-		 * @param[in]	direction	Direction of the ray to cast into the scene.
+		 * @param[in]	unitDir		Unit direction of the ray to cast into the scene.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 *							detected.
 		 *							detected.
 		 * @return					List of all detected hits.
 		 * @return					List of all detected hits.
 		 */
 		 */
-		virtual Vector<PhysicsQueryHit> rayCastAll(const Vector3& origin, const Vector3& direction, 
+		virtual Vector<PhysicsQueryHit> rayCastAll(const Vector3& origin, const Vector3& unitDir,
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 
 
 		/**
 		/**
@@ -206,26 +211,26 @@ namespace BansheeEngine
 		 * 
 		 * 
 		 * @param[in]	box			Box to sweep through the scene.
 		 * @param[in]	box			Box to sweep through the scene.
 		 * @param[in]	rotation	Orientation of the box.
 		 * @param[in]	rotation	Orientation of the box.
-		 * @param[in]	direction	Direction towards which to perform the sweep.
+		 * @param[in]	unitDir		Unit direction towards which to perform the sweep.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 *							detected.
 		 *							detected.
 		 * @return					List of all detected hits.
 		 * @return					List of all detected hits.
 		 */
 		 */
 		virtual Vector<PhysicsQueryHit> boxCastAll(const AABox& box, const Quaternion& rotation, 
 		virtual Vector<PhysicsQueryHit> boxCastAll(const AABox& box, const Quaternion& rotation, 
-			const Vector3& direction, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
+			const Vector3& unitDir, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 
 
 		/**
 		/**
 		 * Performs a sweep into the scene using a sphere and returns all found hits.
 		 * Performs a sweep into the scene using a sphere and returns all found hits.
 		 * 
 		 * 
 		 * @param[in]	sphere		Sphere to sweep through the scene.
 		 * @param[in]	sphere		Sphere to sweep through the scene.
-		 * @param[in]	direction	Direction towards which to perform the sweep.
+		 * @param[in]	unitDir		Unit direction towards which to perform the sweep.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 *							detected.
 		 *							detected.
 		 * @return					List of all detected hits.
 		 * @return					List of all detected hits.
 		 */
 		 */
-		virtual Vector<PhysicsQueryHit> sphereCastAll(const Sphere& sphere, const Vector3& direction, 
+		virtual Vector<PhysicsQueryHit> sphereCastAll(const Sphere& sphere, const Vector3& unitDir,
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 
 
 		/**
 		/**
@@ -233,14 +238,14 @@ namespace BansheeEngine
 		 * 
 		 * 
 		 * @param[in]	capsule		Capsule to sweep through the scene.
 		 * @param[in]	capsule		Capsule to sweep through the scene.
 		 * @param[in]	rotation	Orientation of the capsule.
 		 * @param[in]	rotation	Orientation of the capsule.
-		 * @param[in]	direction	Direction towards which to perform the sweep.
+		 * @param[in]	unitDir		Unit direction towards which to perform the sweep.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 *							detected.
 		 *							detected.
 		 * @return					List of all detected hits.
 		 * @return					List of all detected hits.
 		 */
 		 */
 		virtual Vector<PhysicsQueryHit> capsuleCastAll(const Capsule& capsule, const Quaternion& rotation, 
 		virtual Vector<PhysicsQueryHit> capsuleCastAll(const Capsule& capsule, const Quaternion& rotation, 
-			const Vector3& direction, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
+			const Vector3& unitDir, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 
 
 		/**
 		/**
 		 * Performs a sweep into the scene using a convex mesh and returns all found hits.
 		 * Performs a sweep into the scene using a convex mesh and returns all found hits.
@@ -248,14 +253,14 @@ namespace BansheeEngine
 		 * @param[in]	mesh		Mesh to sweep through the scene. Must be convex.
 		 * @param[in]	mesh		Mesh to sweep through the scene. Must be convex.
 		 * @param[in]	position	Starting position of the mesh.
 		 * @param[in]	position	Starting position of the mesh.
 		 * @param[in]	rotation	Orientation of the mesh.
 		 * @param[in]	rotation	Orientation of the mesh.
-		 * @param[in]	direction	Direction towards which to perform the sweep.
+		 * @param[in]	unitDir		Unit direction towards which to perform the sweep.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 *							detected.
 		 *							detected.
 		 * @return					List of all detected hits.
 		 * @return					List of all detected hits.
 		 */
 		 */
 		virtual Vector<PhysicsQueryHit> convexCastAll(const HPhysicsMesh& mesh, const Vector3& position, 
 		virtual Vector<PhysicsQueryHit> convexCastAll(const HPhysicsMesh& mesh, const Vector3& position, 
-			const Quaternion& rotation, const Vector3& direction, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
+			const Quaternion& rotation, const Vector3& unitDir, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 
 
 		/**
 		/**
 		 * Casts a ray into the scene and checks if it has hit anything. This can be significantly more efficient than other
 		 * Casts a ray into the scene and checks if it has hit anything. This can be significantly more efficient than other
@@ -267,20 +272,20 @@ namespace BansheeEngine
 		 *						detected.
 		 *						detected.
 		 * @return				True if something was hit, false otherwise.
 		 * @return				True if something was hit, false otherwise.
 		 */
 		 */
-		virtual bool rayCastAny(const Ray& ray, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
+		virtual bool rayCastAny(const Ray& ray, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX);
 
 
 		/**
 		/**
 		 * Casts a ray into the scene and checks if it has hit anything. This can be significantly more efficient than other
 		 * 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.
 		 * types of cast* calls.
 		 * 
 		 * 
 		 * @param[in]	origin		Origin of the ray to cast into the scene.
 		 * @param[in]	origin		Origin of the ray to cast into the scene.
-		 * @param[in]	direction	Direction of the ray to cast into the scene.
+		 * @param[in]	unitDir		Unit direction of the ray to cast into the scene.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 *							detected.
 		 *							detected.
 		 * @return					True if something was hit, false otherwise.
 		 * @return					True if something was hit, false otherwise.
 		 */
 		 */
-		virtual bool rayCastAny(const Vector3& origin, const Vector3& direction,
+		virtual bool rayCastAny(const Vector3& origin, const Vector3& unitDir,
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 
 
 		/**
 		/**
@@ -289,13 +294,13 @@ namespace BansheeEngine
 		 * 
 		 * 
 		 * @param[in]	box			Box to sweep through the scene.
 		 * @param[in]	box			Box to sweep through the scene.
 		 * @param[in]	rotation	Orientation of the box.
 		 * @param[in]	rotation	Orientation of the box.
-		 * @param[in]	direction	Direction towards which to perform the sweep.
+		 * @param[in]	unitDir		Unit direction towards which to perform the sweep.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 *							detected.
 		 *							detected.
 		 * @return					True if something was hit, false otherwise.
 		 * @return					True if something was hit, false otherwise.
 		 */
 		 */
-		virtual bool boxCastAny(const AABox& box, const Quaternion& rotation, const Vector3& direction,
+		virtual bool boxCastAny(const AABox& box, const Quaternion& rotation, const Vector3& unitDir,
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 
 
 		/**
 		/**
@@ -303,13 +308,13 @@ namespace BansheeEngine
 		 * efficient than other types of cast* calls.
 		 * efficient than other types of cast* calls.
 		 * 
 		 * 
 		 * @param[in]	sphere		Sphere to sweep through the scene.
 		 * @param[in]	sphere		Sphere to sweep through the scene.
-		 * @param[in]	direction	Direction towards which to perform the sweep.
+		 * @param[in]	unitDir		Unit direction towards which to perform the sweep.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 *							detected.
 		 *							detected.
 		 * @return					True if something was hit, false otherwise.
 		 * @return					True if something was hit, false otherwise.
 		 */
 		 */
-		virtual bool sphereCastAny(const Sphere& sphere, const Vector3& direction, 
+		virtual bool sphereCastAny(const Sphere& sphere, const Vector3& unitDir,
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 
 
 		/**
 		/**
@@ -318,13 +323,13 @@ namespace BansheeEngine
 		 * 
 		 * 
 		 * @param[in]	capsule		Capsule to sweep through the scene.
 		 * @param[in]	capsule		Capsule to sweep through the scene.
 		 * @param[in]	rotation	Orientation of the capsule.
 		 * @param[in]	rotation	Orientation of the capsule.
-		 * @param[in]	direction	Direction towards which to perform the sweep.
+		 * @param[in]	unitDir		Unit direction towards which to perform the sweep.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 *							detected.
 		 *							detected.
 		 * @return					True if something was hit, false otherwise.
 		 * @return					True if something was hit, false otherwise.
 		 */
 		 */
-		virtual bool capsuleCastAny(const Capsule& capsule, const Quaternion& rotation, const Vector3& direction,
+		virtual bool capsuleCastAny(const Capsule& capsule, const Quaternion& rotation, const Vector3& unitDir,
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 
 
 		/**
 		/**
@@ -334,14 +339,14 @@ namespace BansheeEngine
 		 * @param[in]	mesh		Mesh to sweep through the scene. Must be convex.
 		 * @param[in]	mesh		Mesh to sweep through the scene. Must be convex.
 		 * @param[in]	position	Starting position of the mesh.
 		 * @param[in]	position	Starting position of the mesh.
 		 * @param[in]	rotation	Orientation of the mesh.
 		 * @param[in]	rotation	Orientation of the mesh.
-		 * @param[in]	direction	Direction towards which to perform the sweep.
+		 * @param[in]	unitDir		Unit direction towards which to perform the sweep.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 * @param[in]	max			Maximum distance at which to perform the query. Hits past this distance will not be
 		 *							detected.
 		 *							detected.
 		 * @return					True if something was hit, false otherwise.
 		 * @return					True if something was hit, false otherwise.
 		 */
 		 */
 		virtual bool convexCastAny(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
 		virtual bool convexCastAny(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
-			const Vector3& direction, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
+			const Vector3& unitDir, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
 
 
 		/**
 		/**
 		 * Returns a list of all colliders in the scene that overlap the provided box.
 		 * Returns a list of all colliders in the scene that overlap the provided box.
@@ -352,7 +357,7 @@ namespace BansheeEngine
 		 * @return					List of all colliders that overlap the box.
 		 * @return					List of all colliders that overlap the box.
 		 */
 		 */
 		virtual Vector<HCollider> boxOverlap(const AABox& box, const Quaternion& rotation, 
 		virtual Vector<HCollider> boxOverlap(const AABox& box, const Quaternion& rotation, 
-			UINT64 layer = BS_ALL_LAYERS) = 0;
+			UINT64 layer = BS_ALL_LAYERS);
 
 
 		/**
 		/**
 		 * Returns a list of all colliders in the scene that overlap the provided sphere.
 		 * Returns a list of all colliders in the scene that overlap the provided sphere.
@@ -361,7 +366,7 @@ namespace BansheeEngine
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @param[in]	layer		Layers to consider for the query. This allows you to ignore certain groups of objects.
 		 * @return					List of all colliders that overlap the sphere.
 		 * @return					List of all colliders that overlap the sphere.
 		 */
 		 */
-		virtual Vector<HCollider> sphereOverlap(const Sphere& sphere, UINT64 layer = BS_ALL_LAYERS) = 0;
+		virtual Vector<HCollider> sphereOverlap(const Sphere& sphere, UINT64 layer = BS_ALL_LAYERS);
 
 
 		/**
 		/**
 		 * Returns a list of all colliders in the scene that overlap the provided capsule.
 		 * Returns a list of all colliders in the scene that overlap the provided capsule.
@@ -372,7 +377,7 @@ namespace BansheeEngine
 		 * @return					List of all colliders that overlap the capsule.
 		 * @return					List of all colliders that overlap the capsule.
 		 */
 		 */
 		virtual Vector<HCollider> capsuleOverlap(const Capsule& capsule, const Quaternion& rotation,
 		virtual Vector<HCollider> capsuleOverlap(const Capsule& capsule, const Quaternion& rotation,
-			UINT64 layer = BS_ALL_LAYERS) = 0;
+			UINT64 layer = BS_ALL_LAYERS);
 
 
 		/**
 		/**
 		 * Returns a list of all colliders in the scene that overlap the provided convex mesh.
 		 * Returns a list of all colliders in the scene that overlap the provided convex mesh.
@@ -384,7 +389,7 @@ namespace BansheeEngine
 		 * @return					List of all colliders that overlap the mesh.
 		 * @return					List of all colliders that overlap the mesh.
 		 */
 		 */
 		virtual Vector<HCollider> convexOverlap(const HPhysicsMesh& mesh, const Vector3& position, 
 		virtual Vector<HCollider> convexOverlap(const HPhysicsMesh& mesh, const Vector3& position, 
-			const Quaternion& rotation, UINT64 layer = BS_ALL_LAYERS) = 0;
+			const Quaternion& rotation, UINT64 layer = BS_ALL_LAYERS);
 
 
 		/**
 		/**
 		 * Checks if the provided box overlaps any other collider in the scene.
 		 * Checks if the provided box overlaps any other collider in the scene.
@@ -459,6 +464,21 @@ namespace BansheeEngine
 		void toggleCollision(UINT64 groupA, UINT64 groupB, bool enabled);
 		void toggleCollision(UINT64 groupA, UINT64 groupB, bool enabled);
 		bool isCollisionEnabled(UINT64 groupA, UINT64 groupB) const;
 		bool isCollisionEnabled(UINT64 groupA, UINT64 groupB) const;
 
 
+		/** @copydoc Physics::boxOverlap() */
+		virtual Vector<Collider*> _boxOverlap(const AABox& box, const Quaternion& rotation,
+			UINT64 layer = BS_ALL_LAYERS) = 0;
+
+		/** @copydoc Physics::sphereOverlap() */
+		virtual Vector<Collider*> _sphereOverlap(const Sphere& sphere, UINT64 layer = BS_ALL_LAYERS) = 0;
+
+		/** @copydoc Physics::capsuleOverlap() */
+		virtual Vector<Collider*> _capsuleOverlap(const Capsule& capsule, const Quaternion& rotation,
+			UINT64 layer = BS_ALL_LAYERS) = 0;
+
+		/** @copydoc Physics::convexOverlap() */
+		virtual Vector<Collider*> _convexOverlap(const HPhysicsMesh& mesh, const Vector3& position,
+			const Quaternion& rotation, UINT64 layer = BS_ALL_LAYERS) = 0;
+
 		bool _isUpdateInProgress() const { return mUpdateInProgress; }
 		bool _isUpdateInProgress() const { return mUpdateInProgress; }
 
 
 		static const UINT64 CollisionMapSize = 64;
 		static const UINT64 CollisionMapSize = 64;

+ 48 - 0
BansheeCore/Include/BsPhysicsCommon.h

@@ -0,0 +1,48 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsVector3.h"
+
+namespace BansheeEngine
+{
+	/** Information about a single contact point during physics collision. */
+	struct ContactPoint
+	{
+		Vector3 position; /**< Contact point in world space. */
+		Vector3 normal; /**< Normal pointing from the second shape to the first shape. */
+		/** Impulse applied to the objects to keep them from penetrating. Divide by simulation step to get the force. */
+		float impulse;
+		float separation; /**< Determines how far are the objects. Negative value denotes penetration. */
+	};
+
+	/** Information about a collision between two physics objects. */
+	struct CollisionData
+	{
+		Collider* colliderRaw; /**< Collider that was hit. */
+
+		/** 
+		 * Component of the collider that was hit. Can be null if collider is not owned by a component, in which case
+		 * use ::colliderRaw directly. 
+		 */
+		HCollider collider; 
+		// Note: Not too happy this is heap allocated, use static allocator?
+		Vector<ContactPoint> contactPoints; /**< Information about all the contact points for the hit */ 
+	};
+
+	/** Determines what parent, if any, owns a physics object. */
+	enum class PhysicsOwnerType
+	{
+		None, /** No parent, object is used directly. */
+		Component, /** Object is used by a C++ Component. */
+		Script /** Object is used by the scripting system. */
+	};
+
+	/** Contains information about a parent for a physics object. */
+	struct PhysicsObjectOwner
+	{
+		PhysicsOwnerType type = PhysicsOwnerType::None; /**< Type of owner. */
+		void* ownerData = nullptr; /**< Data managed by the owner. */
+	};
+}

+ 19 - 1
BansheeCore/Include/BsRigidbody.h

@@ -3,7 +3,7 @@
 #pragma once
 #pragma once
 
 
 #include "BsCorePrerequisites.h"
 #include "BsCorePrerequisites.h"
-#include "BsCollision.h"
+#include "BsPhysicsCommon.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
@@ -108,13 +108,31 @@ namespace BansheeEngine
 		Event<void(const CollisionData&)> onCollisionStay;
 		Event<void(const CollisionData&)> onCollisionStay;
 		Event<void(const CollisionData&)> onCollisionEnd;
 		Event<void(const CollisionData&)> onCollisionEnd;
 
 
+		/** @cond INTERNAL */
+
 		void _setPriority(UINT32 priority);
 		void _setPriority(UINT32 priority);
 		void _setPhysicsId(UINT32 id) { mPhysicsId = id; }
 		void _setPhysicsId(UINT32 id) { mPhysicsId = id; }
 		void _setTransform(const Vector3& position, const Quaternion& rotation);
 		void _setTransform(const Vector3& position, const Quaternion& rotation);
+
+		/** 
+		 * Sets the object that owns this physics object, if any. Used for high level systems so they can easily map their
+		 * high level physics objects from the low level ones returned by various queries and events.
+		 */
+		void _setOwner(PhysicsOwnerType type, void* owner) { mOwner.type = type; mOwner.ownerData = owner; }
+
+		/** 
+		 * Gets the object that owns this physics object, if any. Used for high level systems so they can easily map their
+		 * high level physics objects from the low level ones returned by various queries and events.
+		 */
+		void* _getOwner(PhysicsOwnerType type) const { return mOwner.type == type ? mOwner.ownerData : nullptr; }
+
+		/** @endcond */
+
 	protected:
 	protected:
 		friend class FCollider;
 		friend class FCollider;
 
 
 		Flag mFlags = Flag::None;
 		Flag mFlags = Flag::None;
+		PhysicsObjectOwner mOwner;
 		UINT32 mPriority = 0;
 		UINT32 mPriority = 0;
 		UINT32 mPhysicsId = 0;
 		UINT32 mPhysicsId = 0;
 		HSceneObject mLinkedSO;
 		HSceneObject mLinkedSO;

+ 4 - 1
BansheeCore/Source/BsCBoxCollider.cpp

@@ -42,7 +42,10 @@ namespace BansheeEngine
 
 
 	SPtr<Collider> CBoxCollider::createInternal()
 	SPtr<Collider> CBoxCollider::createInternal()
 	{
 	{
-		return BoxCollider::create(mExtents, SO()->getWorldPosition(), SO()->getWorldRotation());
+		SPtr<Collider> collider = BoxCollider::create(mExtents, SO()->getWorldPosition(), SO()->getWorldRotation());
+		collider->_setOwner(PhysicsOwnerType::Component, this);
+
+		return collider;
 	}
 	}
 
 
 	RTTITypeBase* CBoxCollider::getRTTIStatic()
 	RTTITypeBase* CBoxCollider::getRTTIStatic()

+ 5 - 1
BansheeCore/Source/BsCCapsuleCollider.cpp

@@ -72,7 +72,11 @@ namespace BansheeEngine
 
 
 	SPtr<Collider> CCapsuleCollider::createInternal()
 	SPtr<Collider> CCapsuleCollider::createInternal()
 	{
 	{
-		return CapsuleCollider::create(mRadius, mHalfHeight, SO()->getWorldPosition(), SO()->getWorldRotation());
+		SPtr<Collider> collider = CapsuleCollider::create(mRadius, mHalfHeight, SO()->getWorldPosition(), 
+			SO()->getWorldRotation());
+
+		collider->_setOwner(PhysicsOwnerType::Component, this);
+		return collider;
 	}
 	}
 
 
 	RTTITypeBase* CCapsuleCollider::getRTTIStatic()
 	RTTITypeBase* CCapsuleCollider::getRTTIStatic()

+ 14 - 2
BansheeCore/Source/BsCCharacterController.cpp

@@ -2,6 +2,7 @@
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 #include "BsCCharacterController.h"
 #include "BsCCharacterController.h"
 #include "BsSceneObject.h"
 #include "BsSceneObject.h"
+#include "BsCollider.h"
 #include "BsCCharacterControllerRTTI.h"
 #include "BsCCharacterControllerRTTI.h"
 
 
 using namespace std::placeholders;
 using namespace std::placeholders;
@@ -134,12 +135,14 @@ namespace BansheeEngine
 	void CCharacterController::onDestroyed()
 	void CCharacterController::onDestroyed()
 	{
 	{
 		// This should release the last reference and destroy the internal controller
 		// This should release the last reference and destroy the internal controller
+		mInternal->_setOwner(PhysicsOwnerType::None, nullptr);
 		mInternal = nullptr;
 		mInternal = nullptr;
 	}
 	}
 
 
 	void CCharacterController::onDisabled()
 	void CCharacterController::onDisabled()
 	{
 	{
 		// This should release the last reference and destroy the internal controller
 		// This should release the last reference and destroy the internal controller
+		mInternal->_setOwner(PhysicsOwnerType::None, nullptr);
 		mInternal = nullptr;
 		mInternal = nullptr;
 	}
 	}
 
 
@@ -147,6 +150,7 @@ namespace BansheeEngine
 	{
 	{
 		mDesc.position = SO()->getWorldPosition();
 		mDesc.position = SO()->getWorldPosition();
 		mInternal = CharacterController::create(mDesc);
 		mInternal = CharacterController::create(mDesc);
+		mInternal->_setOwner(PhysicsOwnerType::Component, this);
 
 
 		mInternal->onColliderHit.connect(std::bind(&CCharacterController::triggerOnColliderHit, this, _1));
 		mInternal->onColliderHit.connect(std::bind(&CCharacterController::triggerOnColliderHit, this, _1));
 		mInternal->onControllerHit.connect(std::bind(&CCharacterController::triggerOnControllerHit, this, _1));
 		mInternal->onControllerHit.connect(std::bind(&CCharacterController::triggerOnControllerHit, this, _1));
@@ -182,12 +186,20 @@ namespace BansheeEngine
 
 
 	void CCharacterController::triggerOnColliderHit(const ControllerColliderCollision& value)
 	void CCharacterController::triggerOnColliderHit(const ControllerColliderCollision& value)
 	{
 	{
-		onColliderHit(value);
+		// Const-cast and modify is okay because we're the only object receiving this event
+		ControllerColliderCollision& hit = const_cast<ControllerColliderCollision&>(value);
+		hit.collider = mThisHandle;
+
+		onColliderHit(hit);
 	}
 	}
 
 
 	void CCharacterController::triggerOnControllerHit(const ControllerControllerCollision& value)
 	void CCharacterController::triggerOnControllerHit(const ControllerControllerCollision& value)
 	{
 	{
-		onControllerHit(value);
+		// Const-cast and modify is okay because we're the only object receiving this event
+		ControllerControllerCollision& hit = const_cast<ControllerControllerCollision&>(value);
+		hit.controller = mThisHandle;
+
+		onControllerHit(hit);
 	}
 	}
 
 
 	RTTITypeBase* CCharacterController::getRTTIStatic()
 	RTTITypeBase* CCharacterController::getRTTIStatic()

+ 17 - 3
BansheeCore/Source/BsCCollider.cpp

@@ -95,6 +95,7 @@ namespace BansheeEngine
 		mParent = nullptr;
 		mParent = nullptr;
 
 
 		// This should release the last reference and destroy the internal collider
 		// This should release the last reference and destroy the internal collider
+		mInternal->_setOwner(PhysicsOwnerType::None, nullptr);
 		mInternal = nullptr;
 		mInternal = nullptr;
 	}
 	}
 
 
@@ -106,6 +107,7 @@ namespace BansheeEngine
 		mParent = nullptr;
 		mParent = nullptr;
 
 
 		// This should release the last reference and destroy the internal collider
 		// This should release the last reference and destroy the internal collider
+		mInternal->_setOwner(PhysicsOwnerType::None, nullptr);
 		mInternal = nullptr;
 		mInternal = nullptr;
 	}
 	}
 
 
@@ -250,17 +252,29 @@ namespace BansheeEngine
 
 
 	void CCollider::triggerOnCollisionBegin(const CollisionData& data)
 	void CCollider::triggerOnCollisionBegin(const CollisionData& data)
 	{
 	{
-		onCollisionBegin(data);
+		// Const-cast and modify is okay because we're the only object receiving this event
+		CollisionData& hit = const_cast<CollisionData&>(data);
+		hit.collider = mThisHandle;
+
+		onCollisionBegin(hit);
 	}
 	}
 
 
 	void CCollider::triggerOnCollisionStay(const CollisionData& data)
 	void CCollider::triggerOnCollisionStay(const CollisionData& data)
 	{
 	{
-		onCollisionStay(data);
+		// Const-cast and modify is okay because we're the only object receiving this event
+		CollisionData& hit = const_cast<CollisionData&>(data);
+		hit.collider = mThisHandle;
+
+		onCollisionStay(hit);
 	}
 	}
 
 
 	void CCollider::triggerOnCollisionEnd(const CollisionData& data)
 	void CCollider::triggerOnCollisionEnd(const CollisionData& data)
 	{
 	{
-		onCollisionEnd(data);
+		// Const-cast and modify is okay because we're the only object receiving this event
+		CollisionData& hit = const_cast<CollisionData&>(data);
+		hit.collider = mThisHandle;
+
+		onCollisionEnd(hit);
 	}
 	}
 
 
 	RTTITypeBase* CCollider::getRTTIStatic()
 	RTTITypeBase* CCollider::getRTTIStatic()

+ 4 - 1
BansheeCore/Source/BsCD6Joint.cpp

@@ -162,7 +162,10 @@ namespace BansheeEngine
 
 
 	SPtr<Joint> CD6Joint::createInternal()
 	SPtr<Joint> CD6Joint::createInternal()
 	{
 	{
-		return D6Joint::create();
+		SPtr<Joint> joint = D6Joint::create();
+
+		joint->_setOwner(PhysicsOwnerType::Component, this);
+		return joint;
 	}
 	}
 
 
 	RTTITypeBase* CD6Joint::getRTTIStatic()
 	RTTITypeBase* CD6Joint::getRTTIStatic()

+ 4 - 1
BansheeCore/Source/BsCDistanceJoint.cpp

@@ -106,7 +106,10 @@ namespace BansheeEngine
 
 
 	SPtr<Joint> CDistanceJoint::createInternal()
 	SPtr<Joint> CDistanceJoint::createInternal()
 	{
 	{
-		return DistanceJoint::create();
+		SPtr<Joint> joint = DistanceJoint::create();
+
+		joint->_setOwner(PhysicsOwnerType::Component, this);
+		return joint;
 	}
 	}
 
 
 	RTTITypeBase* CDistanceJoint::getRTTIStatic()
 	RTTITypeBase* CDistanceJoint::getRTTIStatic()

+ 4 - 1
BansheeCore/Source/BsCFixedJoint.cpp

@@ -15,7 +15,10 @@ namespace BansheeEngine
 
 
 	SPtr<Joint> CFixedJoint::createInternal()
 	SPtr<Joint> CFixedJoint::createInternal()
 	{
 	{
-		return FixedJoint::create();
+		SPtr<Joint> joint = FixedJoint::create();
+
+		joint->_setOwner(PhysicsOwnerType::Component, this);
+		return joint;
 	}
 	}
 
 
 	RTTITypeBase* CFixedJoint::getRTTIStatic()
 	RTTITypeBase* CFixedJoint::getRTTIStatic()

+ 4 - 1
BansheeCore/Source/BsCHingeJoint.cpp

@@ -82,7 +82,10 @@ namespace BansheeEngine
 
 
 	SPtr<Joint> CHingeJoint::createInternal()
 	SPtr<Joint> CHingeJoint::createInternal()
 	{
 	{
-		return HingeJoint::create();
+		SPtr<Joint> joint = HingeJoint::create();
+
+		joint->_setOwner(PhysicsOwnerType::Component, this);
+		return joint;
 	}
 	}
 
 
 	RTTITypeBase* CHingeJoint::getRTTIStatic()
 	RTTITypeBase* CHingeJoint::getRTTIStatic()

+ 2 - 0
BansheeCore/Source/BsCJoint.cpp

@@ -131,12 +131,14 @@ namespace BansheeEngine
 			mBodies[1]->_setJoint(HJoint());
 			mBodies[1]->_setJoint(HJoint());
 
 
 		// This should release the last reference and destroy the internal joint
 		// This should release the last reference and destroy the internal joint
+		mInternal->_setOwner(PhysicsOwnerType::None, nullptr);
 		mInternal = nullptr;
 		mInternal = nullptr;
 	}
 	}
 
 
 	void CJoint::onDisabled()
 	void CJoint::onDisabled()
 	{
 	{
 		// This should release the last reference and destroy the internal joint
 		// This should release the last reference and destroy the internal joint
+		mInternal->_setOwner(PhysicsOwnerType::None, nullptr);
 		mInternal = nullptr;
 		mInternal = nullptr;
 	}
 	}
 
 

+ 1 - 0
BansheeCore/Source/BsCMeshCollider.cpp

@@ -47,6 +47,7 @@ namespace BansheeEngine
 	{
 	{
 		SPtr<MeshCollider> collider = MeshCollider::create(SO()->getWorldPosition(), SO()->getWorldRotation());
 		SPtr<MeshCollider> collider = MeshCollider::create(SO()->getWorldPosition(), SO()->getWorldRotation());
 		collider->setMesh(mMesh);
 		collider->setMesh(mMesh);
+		collider->_setOwner(PhysicsOwnerType::Component, this);
 
 
 		return collider;
 		return collider;
 	}
 	}

+ 4 - 1
BansheeCore/Source/BsCPlaneCollider.cpp

@@ -42,7 +42,10 @@ namespace BansheeEngine
 
 
 	SPtr<Collider> CPlaneCollider::createInternal()
 	SPtr<Collider> CPlaneCollider::createInternal()
 	{
 	{
-		return PlaneCollider::create(SO()->getWorldPosition(), SO()->getWorldRotation());
+		SPtr<Collider> collider = PlaneCollider::create(SO()->getWorldPosition(), SO()->getWorldRotation());
+
+		collider->_setOwner(PhysicsOwnerType::Component, this);
+		return collider;
 	}
 	}
 
 
 	bool CPlaneCollider::isValidParent(const HRigidbody& parent) const
 	bool CPlaneCollider::isValidParent(const HRigidbody& parent) const

+ 5 - 0
BansheeCore/Source/BsCRigidbody.cpp

@@ -353,18 +353,23 @@ namespace BansheeEngine
 	void CRigidbody::onDestroyed()
 	void CRigidbody::onDestroyed()
 	{
 	{
 		clearColliders();
 		clearColliders();
+
+		mInternal->_setOwner(PhysicsOwnerType::None, nullptr);
 		mInternal = nullptr;
 		mInternal = nullptr;
 	}
 	}
 
 
 	void CRigidbody::onDisabled()
 	void CRigidbody::onDisabled()
 	{
 	{
 		clearColliders();
 		clearColliders();
+
+		mInternal->_setOwner(PhysicsOwnerType::None, nullptr);
 		mInternal = nullptr;
 		mInternal = nullptr;
 	}
 	}
 
 
 	void CRigidbody::onEnabled()
 	void CRigidbody::onEnabled()
 	{
 	{
 		mInternal = Rigidbody::create(SO());
 		mInternal = Rigidbody::create(SO());
+		mInternal->_setOwner(PhysicsOwnerType::Component, this);
 
 
 		updateColliders();
 		updateColliders();
 
 

+ 4 - 1
BansheeCore/Source/BsCSliderJoint.cpp

@@ -66,7 +66,10 @@ namespace BansheeEngine
 
 
 	SPtr<Joint> CSliderJoint::createInternal()
 	SPtr<Joint> CSliderJoint::createInternal()
 	{
 	{
-		return SliderJoint::create();
+		SPtr<Joint> joint = SliderJoint::create();
+
+		joint->_setOwner(PhysicsOwnerType::Component, this);
+		return joint;
 	}
 	}
 
 
 	RTTITypeBase* CSliderJoint::getRTTIStatic()
 	RTTITypeBase* CSliderJoint::getRTTIStatic()

+ 4 - 1
BansheeCore/Source/BsCSphereCollider.cpp

@@ -42,7 +42,10 @@ namespace BansheeEngine
 
 
 	SPtr<Collider> CSphereCollider::createInternal()
 	SPtr<Collider> CSphereCollider::createInternal()
 	{
 	{
-		return SphereCollider::create(mRadius, SO()->getWorldPosition(), SO()->getWorldRotation());
+		SPtr<Collider> collider = SphereCollider::create(mRadius, SO()->getWorldPosition(), SO()->getWorldRotation());
+
+		collider->_setOwner(PhysicsOwnerType::Component, this);
+		return collider;
 	}
 	}
 
 
 	RTTITypeBase* CSphereCollider::getRTTIStatic()
 	RTTITypeBase* CSphereCollider::getRTTIStatic()

+ 4 - 1
BansheeCore/Source/BsCSphericalJoint.cpp

@@ -50,7 +50,10 @@ namespace BansheeEngine
 
 
 	SPtr<Joint> CSphericalJoint::createInternal()
 	SPtr<Joint> CSphericalJoint::createInternal()
 	{
 	{
-		return SphericalJoint::create();
+		SPtr<Joint> joint = SphericalJoint::create();
+
+		joint->_setOwner(PhysicsOwnerType::Component, this);
+		return joint;
 	}
 	}
 
 
 	RTTITypeBase* CSphericalJoint::getRTTIStatic()
 	RTTITypeBase* CSphericalJoint::getRTTIStatic()

+ 1 - 0
BansheeCore/Source/BsCollider.cpp

@@ -1,6 +1,7 @@
 //********************************** 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. **********************//
 #include "BsCollider.h"
 #include "BsCollider.h"
+#include "BsCollider.h"
 #include "BsFCollider.h"
 #include "BsFCollider.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine

+ 59 - 0
BansheeCore/Source/BsPhysics.cpp

@@ -2,6 +2,8 @@
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 #include "BsPhysics.h"
 #include "BsPhysics.h"
 #include "BsRigidbody.h"
 #include "BsRigidbody.h"
+#include "BsRay.h"
+#include "BsCCollider.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
@@ -26,6 +28,63 @@ namespace BansheeEngine
 		return mCollisionMap[groupA][groupB];
 		return mCollisionMap[groupA][groupB];
 	}
 	}
 
 
+	bool Physics::rayCast(const Ray& ray, PhysicsQueryHit& hit, UINT64 layer, float max)
+	{
+		return rayCast(ray.getOrigin(), ray.getDirection(), hit, layer, max);
+	}
+
+	Vector<PhysicsQueryHit> Physics::rayCastAll(const Ray& ray, UINT64 layer, float max)
+	{
+		return rayCastAll(ray.getOrigin(), ray.getDirection(), layer, max);
+	}
+
+	bool Physics::rayCastAny(const Ray& ray, UINT64 layer, float max)
+	{
+		return rayCastAny(ray.getOrigin(), ray.getDirection(), layer, max);
+	}
+
+	Vector<HCollider> rawToComponent(const Vector<Collider*>& raw)
+	{
+		if (raw.empty())
+			return Vector<HCollider>(0);
+
+		Vector<HCollider> output;
+		for (auto& entry : raw)
+		{
+			if (entry == nullptr)
+				continue;
+
+			CCollider* component = (CCollider*)entry->_getOwner(PhysicsOwnerType::Component);
+			if (component == nullptr)
+				continue;
+
+			output.push_back(component->getHandle());
+		}
+
+		return output;
+	}
+
+	Vector<HCollider> Physics::boxOverlap(const AABox& box, const Quaternion& rotation, UINT64 layer)
+	{
+		return rawToComponent(_boxOverlap(box, rotation, layer));
+	}
+
+	Vector<HCollider> Physics::sphereOverlap(const Sphere& sphere, UINT64 layer)
+	{
+		return rawToComponent(_sphereOverlap(sphere, layer));
+	}
+
+	Vector<HCollider> Physics::capsuleOverlap(const Capsule& capsule, const Quaternion& rotation, UINT64 layer)
+	{
+		return rawToComponent(_capsuleOverlap(capsule, rotation, layer));
+	}
+
+	Vector<HCollider> Physics::convexOverlap(const HPhysicsMesh& mesh, const Vector3& position,
+		const Quaternion& rotation, UINT64 layer)
+	{
+		return rawToComponent(_convexOverlap(mesh, position, rotation, layer));
+	}
+
 	void Physics::registerRigidbody(Rigidbody* body, UINT32 priority)
 	void Physics::registerRigidbody(Rigidbody* body, UINT32 priority)
 	{
 	{
 		assert(priority <= MAX_PRIORITY && "Priority value too high");
 		assert(priority <= MAX_PRIORITY && "Priority value too high");

+ 0 - 1
BansheeCore/Source/BsRigidbody.cpp

@@ -17,7 +17,6 @@ namespace BansheeEngine
 
 
 	Rigidbody::~Rigidbody()
 	Rigidbody::~Rigidbody()
 	{
 	{
-		// It is assumed that child colliders will keep the parent Rigidbody alive, so we don't need to clear their parents
 		gPhysics().unregisterRigidbody(mPhysicsId, mPriority);
 		gPhysics().unregisterRigidbody(mPhysicsId, mPriority);
 	}
 	}
 
 

+ 1 - 1
BansheePhysX/Include/BsFPhysXCollider.h

@@ -3,7 +3,7 @@
 #pragma once
 #pragma once
 
 
 #include "BsPhysXPrerequisites.h"
 #include "BsPhysXPrerequisites.h"
-#include "BsCollision.h"
+#include "BsPhysicsCommon.h"
 #include "BsFCollider.h"
 #include "BsFCollider.h"
 #include "PxRigidStatic.h"
 #include "PxRigidStatic.h"
 
 

+ 41 - 40
BansheePhysX/Include/BsPhysX.h

@@ -4,7 +4,7 @@
 
 
 #include "BsPhysXPrerequisites.h"
 #include "BsPhysXPrerequisites.h"
 #include "BsPhysics.h"
 #include "BsPhysics.h"
-#include "BSCollision.h"
+#include "BsPhysicsCommon.h"
 #include "PxPhysics.h"
 #include "PxPhysics.h"
 #include "foundation/Px.h"
 #include "foundation/Px.h"
 #include "characterkinematic\PxControllerManager.h"
 #include "characterkinematic\PxControllerManager.h"
@@ -69,89 +69,65 @@ namespace BansheeEngine
 		/** @copydoc Physics::createCharacterController*/
 		/** @copydoc Physics::createCharacterController*/
 		SPtr<CharacterController> createCharacterController(const CHAR_CONTROLLER_DESC& desc) override;
 		SPtr<CharacterController> createCharacterController(const CHAR_CONTROLLER_DESC& desc) override;
 
 
-		/** @copydoc Physics::rayCast(const Ray&, PhysicsQueryHit&, UINT64, float) */
-		bool rayCast(const Ray& ray, PhysicsQueryHit& hit, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
-
 		/** @copydoc Physics::rayCast(const Vector3&, const Vector3&, UINT64, float) */
 		/** @copydoc Physics::rayCast(const Vector3&, const Vector3&, UINT64, float) */
-		bool rayCast(const Vector3& origin, const Vector3& direction, PhysicsQueryHit& hit,
+		bool rayCast(const Vector3& origin, const Vector3& unitDir, PhysicsQueryHit& hit,
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 
 
 		/** @copydoc Physics::boxCast */
 		/** @copydoc Physics::boxCast */
-		bool boxCast(const AABox& box, const Quaternion& rotation, const Vector3& direction, PhysicsQueryHit& hit,
+		bool boxCast(const AABox& box, const Quaternion& rotation, const Vector3& unitDir, PhysicsQueryHit& hit,
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 
 
 		/** @copydoc Physics::sphereCast */
 		/** @copydoc Physics::sphereCast */
-		bool sphereCast(const Sphere& sphere, const Vector3& direction, PhysicsQueryHit& hit,
+		bool sphereCast(const Sphere& sphere, const Vector3& unitDir, PhysicsQueryHit& hit,
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 
 
 		/** @copydoc Physics::capsuleCast */
 		/** @copydoc Physics::capsuleCast */
-		bool capsuleCast(const Capsule& capsule, const Quaternion& rotation, const Vector3& direction,
+		bool capsuleCast(const Capsule& capsule, const Quaternion& rotation, const Vector3& unitDir,
 			PhysicsQueryHit& hit, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 			PhysicsQueryHit& hit, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 
 
 		/** @copydoc Physics::convexCast */
 		/** @copydoc Physics::convexCast */
 		bool convexCast(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
 		bool convexCast(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
-			const Vector3& direction, PhysicsQueryHit& hit, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
-
-		/** @copydoc Physics::rayCastAll(const Ray&, UINT64, float) */
-		Vector<PhysicsQueryHit> rayCastAll(const Ray& ray, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
+			const Vector3& unitDir, PhysicsQueryHit& hit, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 
 
 		/** @copydoc Physics::rayCastAll(const Vector3&, const Vector3&, UINT64, float) */
 		/** @copydoc Physics::rayCastAll(const Vector3&, const Vector3&, UINT64, float) */
-		Vector<PhysicsQueryHit> rayCastAll(const Vector3& origin, const Vector3& direction,
+		Vector<PhysicsQueryHit> rayCastAll(const Vector3& origin, const Vector3& unitDir,
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 
 
 		/** @copydoc Physics::boxCastAll */
 		/** @copydoc Physics::boxCastAll */
 		Vector<PhysicsQueryHit> boxCastAll(const AABox& box, const Quaternion& rotation,
 		Vector<PhysicsQueryHit> boxCastAll(const AABox& box, const Quaternion& rotation,
-			const Vector3& direction, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
+			const Vector3& unitDir, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 
 
 		/** @copydoc Physics::sphereCastAll */
 		/** @copydoc Physics::sphereCastAll */
-		Vector<PhysicsQueryHit> sphereCastAll(const Sphere& sphere, const Vector3& direction,
+		Vector<PhysicsQueryHit> sphereCastAll(const Sphere& sphere, const Vector3& unitDir,
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 
 
 		/** @copydoc Physics::capsuleCastAll */
 		/** @copydoc Physics::capsuleCastAll */
 		Vector<PhysicsQueryHit> capsuleCastAll(const Capsule& capsule, const Quaternion& rotation,
 		Vector<PhysicsQueryHit> capsuleCastAll(const Capsule& capsule, const Quaternion& rotation,
-			const Vector3& direction, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
+			const Vector3& unitDir, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 
 
 		/** @copydoc Physics::convexCastAll */
 		/** @copydoc Physics::convexCastAll */
 		Vector<PhysicsQueryHit> convexCastAll(const HPhysicsMesh& mesh, const Vector3& position,
 		Vector<PhysicsQueryHit> convexCastAll(const HPhysicsMesh& mesh, const Vector3& position,
-			const Quaternion& rotation, const Vector3& direction, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
-
-		/** @copydoc Physics::rayCastAny(const Ray&, UINT64, float) */
-		bool rayCastAny(const Ray& ray, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
+			const Quaternion& rotation, const Vector3& unitDir, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 
 
 		/** @copydoc Physics::rayCastAny(const Vector3&, const Vector3&, UINT64, float) */
 		/** @copydoc Physics::rayCastAny(const Vector3&, const Vector3&, UINT64, float) */
-		bool rayCastAny(const Vector3& origin, const Vector3& direction,
+		bool rayCastAny(const Vector3& origin, const Vector3& unitDir,
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 
 
 		/** @copydoc Physics::boxCastAny */
 		/** @copydoc Physics::boxCastAny */
-		bool boxCastAny(const AABox& box, const Quaternion& rotation, const Vector3& direction,
+		bool boxCastAny(const AABox& box, const Quaternion& rotation, const Vector3& unitDir,
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 
 
 		/** @copydoc Physics::sphereCastAny */
 		/** @copydoc Physics::sphereCastAny */
-		bool sphereCastAny(const Sphere& sphere, const Vector3& direction,
+		bool sphereCastAny(const Sphere& sphere, const Vector3& unitDir,
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 
 
 		/** @copydoc Physics::capsuleCastAny */
 		/** @copydoc Physics::capsuleCastAny */
-		bool capsuleCastAny(const Capsule& capsule, const Quaternion& rotation, const Vector3& direction,
+		bool capsuleCastAny(const Capsule& capsule, const Quaternion& rotation, const Vector3& unitDir,
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 			UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 
 
 		/** @copydoc Physics::convexCastAny */
 		/** @copydoc Physics::convexCastAny */
 		bool convexCastAny(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
 		bool convexCastAny(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
-			const Vector3& direction, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
-
-		/** @copydoc Physics::boxOverlap */
-		Vector<HCollider> boxOverlap(const AABox& box, const Quaternion& rotation,
-			UINT64 layer = BS_ALL_LAYERS) override;
-
-		/** @copydoc Physics::sphereOverlap */
-		Vector<HCollider> sphereOverlap(const Sphere& sphere, UINT64 layer = BS_ALL_LAYERS) override;
-
-		/** @copydoc Physics::capsuleOverlap */
-		Vector<HCollider> capsuleOverlap(const Capsule& capsule, const Quaternion& rotation,
-			UINT64 layer = BS_ALL_LAYERS) override;
-
-		/** @copydoc Physics::convexOverlap */
-		Vector<HCollider> convexOverlap(const HPhysicsMesh& mesh, const Vector3& position,
-			const Quaternion& rotation, UINT64 layer = BS_ALL_LAYERS) override;
+			const Vector3& unitDir, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
 
 
 		/** @copydoc Physics::boxOverlapAny */
 		/** @copydoc Physics::boxOverlapAny */
 		bool boxOverlapAny(const AABox& box, const Quaternion& rotation, UINT64 layer = BS_ALL_LAYERS) override;
 		bool boxOverlapAny(const AABox& box, const Quaternion& rotation, UINT64 layer = BS_ALL_LAYERS) override;
@@ -179,6 +155,21 @@ namespace BansheeEngine
 		void removeBroadPhaseRegion(UINT32 regionId) override;
 		void removeBroadPhaseRegion(UINT32 regionId) override;
 		void clearBroadPhaseRegions() override;
 		void clearBroadPhaseRegions() override;
 
 
+		/** @copydoc Physics::_boxOverlap */
+		Vector<Collider*> _boxOverlap(const AABox& box, const Quaternion& rotation,
+			UINT64 layer = BS_ALL_LAYERS) override;
+
+		/** @copydoc Physics::_sphereOverlap */
+		Vector<Collider*> _sphereOverlap(const Sphere& sphere, UINT64 layer = BS_ALL_LAYERS) override;
+
+		/** @copydoc Physics::_capsuleOverlap */
+		Vector<Collider*> _capsuleOverlap(const Capsule& capsule, const Quaternion& rotation,
+			UINT64 layer = BS_ALL_LAYERS) override;
+
+		/** @copydoc Physics::_convexOverlap */
+		Vector<Collider*> _convexOverlap(const HPhysicsMesh& mesh, const Vector3& position,
+			const Quaternion& rotation, UINT64 layer = BS_ALL_LAYERS) override;
+
 		void _reportContactEvent(const ContactEvent& event);
 		void _reportContactEvent(const ContactEvent& event);
 		void _reportTriggerEvent(const TriggerEvent& event);
 		void _reportTriggerEvent(const TriggerEvent& event);
 		void _reportJointBreakEvent(const JointBreakEvent& event);
 		void _reportJointBreakEvent(const JointBreakEvent& event);
@@ -194,6 +185,16 @@ namespace BansheeEngine
 
 
 		void triggerEvents();
 		void triggerEvents();
 
 
+		// Scene query helpers
+		inline bool sweep(const physx::PxGeometry& geometry, const physx::PxTransform& tfrm, const Vector3& unitDir,
+			PhysicsQueryHit& hit, UINT64 layer, float maxDist) const;
+		inline Vector<PhysicsQueryHit> sweepAll(const physx::PxGeometry& geometry, const physx::PxTransform& tfrm, 
+			const Vector3& unitDir, UINT64 layer, float maxDist) const;
+		inline bool sweepAny(const physx::PxGeometry& geometry, const physx::PxTransform& tfrm, const Vector3& unitDir,
+			UINT64 layer, float maxDist) const;
+		inline Vector<Collider*> overlap(const physx::PxGeometry& geometry, const physx::PxTransform& tfrm, UINT64 layer) const;
+		inline bool overlapAny(const physx::PxGeometry& geometry, const physx::PxTransform& tfrm, UINT64 layer) const;
+
 		float mSimulationStep = 1.0f/60.0f;
 		float mSimulationStep = 1.0f/60.0f;
 		float mLastSimulationTime = 0.0f;
 		float mLastSimulationTime = 0.0f;
 		float mTesselationLength = 3.0f;
 		float mTesselationLength = 3.0f;

+ 318 - 80
BansheePhysX/Source/BsPhysX.cpp

@@ -16,9 +16,12 @@
 #include "BsPhysXD6Joint.h"
 #include "BsPhysXD6Joint.h"
 #include "BsPhysXCharacterController.h"
 #include "BsPhysXCharacterController.h"
 #include "BsTaskScheduler.h"
 #include "BsTaskScheduler.h"
+#include "BsCCollider.h"
 #include "BsTime.h"
 #include "BsTime.h"
 #include "Bsvector3.h"
 #include "Bsvector3.h"
 #include "BsAABox.h"
 #include "BsAABox.h"
+#include "BsCapsule.h"
+#include "foundation\PxTransform.h"
 
 
 using namespace physx;
 using namespace physx;
 
 
@@ -300,6 +303,96 @@ namespace BansheeEngine
 		return PxFilterFlags();
 		return PxFilterFlags();
 	}
 	}
 
 
+	void parseHit(const PxRaycastHit& input, PhysicsQueryHit& output)
+	{
+		output.point = fromPxVector(input.position);
+		output.normal = fromPxVector(input.normal);
+		output.distance = input.distance;
+		output.triangleIdx = input.faceIndex;
+		output.uv = Vector2(input.u, input.v);
+		output.colliderRaw = (Collider*)input.shape->userData;
+
+		if (output.colliderRaw != nullptr)
+		{
+			CCollider* component = (CCollider*)output.colliderRaw->_getOwner(PhysicsOwnerType::Component);
+			if (component != nullptr)
+				output.collider = component->getHandle();
+		}
+	}
+
+	void parseHit(const PxSweepHit& input, PhysicsQueryHit& output)
+	{
+		output.point = fromPxVector(input.position);
+		output.normal = fromPxVector(input.normal);
+		output.distance = input.distance;
+		output.triangleIdx = input.faceIndex;
+		output.colliderRaw = (Collider*)input.shape->userData;
+
+		if (output.colliderRaw != nullptr)
+		{
+			CCollider* component = (CCollider*)output.colliderRaw->_getOwner(PhysicsOwnerType::Component);
+			if (component != nullptr)
+				output.collider = component->getHandle();
+		}
+	}
+
+	struct PhysXRaycastQueryCallback : PxRaycastCallback
+	{
+		Vector<PhysicsQueryHit> data;
+
+		PhysXRaycastQueryCallback()
+			:PxRaycastCallback(nullptr, 0)
+		{ }
+
+		PxAgain processTouches(const PxRaycastHit* buffer, PxU32 nbHits) override
+		{
+			for (PxU32 i = 0; i < nbHits; i++)
+			{
+				data.push_back(PhysicsQueryHit());
+				parseHit(buffer[i], data.back());
+			}
+
+			return true;
+		}
+	};
+
+	struct PhysXSweepQueryCallback : PxSweepCallback
+	{
+		Vector<PhysicsQueryHit> data;
+
+		PhysXSweepQueryCallback()
+			:PxSweepCallback(nullptr, 0)
+		{ }
+
+		PxAgain processTouches(const PxSweepHit* buffer, PxU32 nbHits) override
+		{
+			for (PxU32 i = 0; i < nbHits; i++)
+			{
+				data.push_back(PhysicsQueryHit());
+				parseHit(buffer[i], data.back());
+			}
+
+			return true;
+		}
+	};
+
+	struct PhysXOverlapQueryCallback : PxOverlapCallback
+	{
+		Vector<Collider*> data;
+
+		PhysXOverlapQueryCallback()
+			:PxOverlapCallback(nullptr, 0)
+		{ }
+
+		PxAgain processTouches(const PxOverlapHit* buffer, PxU32 nbHits) override
+		{
+			for (PxU32 i = 0; i < nbHits; i++)
+				data.push_back((Collider*)buffer[i].shape->userData);
+
+			return true;
+		}
+	};
+
 	static PhysXAllocator gPhysXAllocator;
 	static PhysXAllocator gPhysXAllocator;
 	static PhysXErrorCallback gPhysXErrorHandler;
 	static PhysXErrorCallback gPhysXErrorHandler;
 	static PhysXCPUDispatcher gPhysXCPUDispatcher;
 	static PhysXCPUDispatcher gPhysXCPUDispatcher;
@@ -429,7 +522,7 @@ namespace BansheeEngine
 
 
 		for(auto& entry : mTriggerEvents)
 		for(auto& entry : mTriggerEvents)
 		{
 		{
-			data.collider = entry.other;
+			data.colliderRaw = entry.other;
 
 
 			switch (entry.type)
 			switch (entry.type)
 			{
 			{
@@ -448,7 +541,7 @@ namespace BansheeEngine
 		auto notifyContact = [&](Collider* obj, Collider* other, ContactEventType type, 
 		auto notifyContact = [&](Collider* obj, Collider* other, ContactEventType type, 
 			const Vector<ContactPoint>& points, bool flipNormals = false)
 			const Vector<ContactPoint>& points, bool flipNormals = false)
 		{
 		{
-			data.collider = other;
+			data.colliderRaw = other;
 			data.contactPoints = points;
 			data.contactPoints = points;
 
 
 			if(flipNormals)
 			if(flipNormals)
@@ -583,179 +676,324 @@ namespace BansheeEngine
 		return bs_shared_ptr_new<PhysXCharacterController>(mCharManager, desc);
 		return bs_shared_ptr_new<PhysXCharacterController>(mCharManager, desc);
 	}
 	}
 
 
-	bool PhysX::rayCast(const Ray& ray, PhysicsQueryHit& hit, UINT64 layer, float max)
+	Vector<PhysicsQueryHit> PhysX::sweepAll(const PxGeometry& geometry, const PxTransform& tfrm, const Vector3& unitDir,
+		UINT64 layer, float maxDist) const
+	{
+		PhysXSweepQueryCallback output;
+
+		PxQueryFilterData filterData;
+		memcpy(&filterData.data.word0, &layer, sizeof(layer));
+
+		mScene->sweep(geometry, tfrm, toPxVector(unitDir), maxDist, output,
+			PxHitFlag::eDEFAULT | PxHitFlag::eUV, filterData);
+
+		return output.data;
+	}
+
+	bool PhysX::sweepAny(const PxGeometry& geometry, const PxTransform& tfrm, const Vector3& unitDir, UINT64 layer, 
+		float maxDist) const
 	{
 	{
-		// TODO
-		return false;
+		PxSweepBuffer output;
+
+		PxQueryFilterData filterData;
+		filterData.flags |= PxQueryFlag::eANY_HIT;
+		memcpy(&filterData.data.word0, &layer, sizeof(layer));
+
+		return mScene->sweep(geometry, tfrm, toPxVector(unitDir), maxDist, output, 
+			PxHitFlag::eDEFAULT | PxHitFlag::eUV | PxHitFlag::eMESH_ANY, filterData);
 	}
 	}
 
 
-	bool PhysX::rayCast(const Vector3& origin, const Vector3& direction, PhysicsQueryHit& hit, UINT64 layer, float max)
+	bool PhysX::rayCast(const Vector3& origin, const Vector3& unitDir, PhysicsQueryHit& hit, UINT64 layer, float max)
 	{
 	{
-		// TODO
-		return false;
+		PxRaycastBuffer output;
+
+		PxQueryFilterData filterData;
+		memcpy(&filterData.data.word0, &layer, sizeof(layer));
+
+		bool wasHit = mScene->raycast(toPxVector(origin),
+			toPxVector(unitDir), max, output, PxHitFlag::eDEFAULT | PxHitFlag::eUV, filterData);
+
+		if (wasHit)
+			parseHit(output.block, hit);
+
+		return wasHit;
 	}
 	}
 
 
-	bool PhysX::boxCast(const AABox& box, const Quaternion& rotation, const Vector3& direction, PhysicsQueryHit& hit,
+	bool PhysX::boxCast(const AABox& box, const Quaternion& rotation, const Vector3& unitDir, PhysicsQueryHit& hit,
 		UINT64 layer, float max)
 		UINT64 layer, float max)
 	{
 	{
-		// TODO
-		return false;
+		PxBoxGeometry geometry(toPxVector(box.getHalfSize()));
+		PxTransform transform = toPxTransform(box.getCenter(), rotation);
+
+		return sweep(geometry, transform, unitDir, hit, layer, max);
 	}
 	}
 
 
-	bool PhysX::sphereCast(const Sphere& sphere, const Vector3& direction, PhysicsQueryHit& hit,
+	bool PhysX::sphereCast(const Sphere& sphere, const Vector3& unitDir, PhysicsQueryHit& hit,
 		UINT64 layer, float max)
 		UINT64 layer, float max)
 	{
 	{
-		// TODO
-		return false;
+		PxSphereGeometry geometry(sphere.getRadius());
+		PxTransform transform = toPxTransform(sphere.getCenter(), Quaternion::IDENTITY);
+
+		return sweep(geometry, transform, unitDir, hit, layer, max);
 	}
 	}
 
 
-	bool PhysX::capsuleCast(const Capsule& capsule, const Quaternion& rotation, const Vector3& direction,
+	bool PhysX::capsuleCast(const Capsule& capsule, const Quaternion& rotation, const Vector3& unitDir,
 		PhysicsQueryHit& hit, UINT64 layer, float max)
 		PhysicsQueryHit& hit, UINT64 layer, float max)
 	{
 	{
-		// TODO
-		return false;
+		PxCapsuleGeometry geometry(capsule.getRadius(), capsule.getHeight() * 0.5f);
+		PxTransform transform = toPxTransform(capsule.getCenter(), Quaternion::IDENTITY);
+
+		return sweep(geometry, transform, unitDir, hit, layer, max);
 	}
 	}
 
 
 	bool PhysX::convexCast(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
 	bool PhysX::convexCast(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
-		const Vector3& direction, PhysicsQueryHit& hit, UINT64 layer, float max)
+		const Vector3& unitDir, PhysicsQueryHit& hit, UINT64 layer, float max)
 	{
 	{
-		// TODO
-		return false;
-	}
+		if (mesh == nullptr)
+			return false;
 
 
-	Vector<PhysicsQueryHit> PhysX::rayCastAll(const Ray& ray, UINT64 layer, float max)
-	{
-		// TODO
-		return Vector<PhysicsQueryHit>();
+		PhysXMesh* physxMesh = static_cast<PhysXMesh*>(mesh.get());
+		if (physxMesh->getType() != PhysicsMeshType::Convex)
+			return false;
+
+		PxConvexMeshGeometry geometry(physxMesh->_getConvex());
+		PxTransform transform = toPxTransform(position, rotation);
+
+		return sweep(geometry, transform, unitDir, hit, layer, max);
 	}
 	}
 
 
-	Vector<PhysicsQueryHit> PhysX::rayCastAll(const Vector3& origin, const Vector3& direction,
+	Vector<PhysicsQueryHit> PhysX::rayCastAll(const Vector3& origin, const Vector3& unitDir,
 		UINT64 layer, float max)
 		UINT64 layer, float max)
 	{
 	{
-		// TODO
-		return Vector<PhysicsQueryHit>();
+		PhysXRaycastQueryCallback output;
+
+		PxQueryFilterData filterData;
+		memcpy(&filterData.data.word0, &layer, sizeof(layer));
+
+		mScene->raycast(toPxVector(origin), toPxVector(unitDir), max, output,
+			PxHitFlag::eDEFAULT | PxHitFlag::eUV | PxHitFlag::eMESH_MULTIPLE, filterData);
+
+		return output.data;
 	}
 	}
 
 
 	Vector<PhysicsQueryHit> PhysX::boxCastAll(const AABox& box, const Quaternion& rotation,
 	Vector<PhysicsQueryHit> PhysX::boxCastAll(const AABox& box, const Quaternion& rotation,
-		const Vector3& direction, UINT64 layer, float max)
+		const Vector3& unitDir, UINT64 layer, float max)
 	{
 	{
-		// TODO
-		return Vector<PhysicsQueryHit>();
+		PxBoxGeometry geometry(toPxVector(box.getHalfSize()));
+		PxTransform transform = toPxTransform(box.getCenter(), rotation);
+
+		return sweepAll(geometry, transform, unitDir, layer, max);
 	}
 	}
 
 
-	Vector<PhysicsQueryHit> PhysX::sphereCastAll(const Sphere& sphere, const Vector3& direction,
+	Vector<PhysicsQueryHit> PhysX::sphereCastAll(const Sphere& sphere, const Vector3& unitDir,
 		UINT64 layer, float max)
 		UINT64 layer, float max)
 	{
 	{
-		// TODO
-		return Vector<PhysicsQueryHit>();
+		PxSphereGeometry geometry(sphere.getRadius());
+		PxTransform transform = toPxTransform(sphere.getCenter(), Quaternion::IDENTITY);
+
+		return sweepAll(geometry, transform, unitDir, layer, max);
 	}
 	}
 
 
 	Vector<PhysicsQueryHit> PhysX::capsuleCastAll(const Capsule& capsule, const Quaternion& rotation,
 	Vector<PhysicsQueryHit> PhysX::capsuleCastAll(const Capsule& capsule, const Quaternion& rotation,
-		const Vector3& direction, UINT64 layer, float max)
+		const Vector3& unitDir, UINT64 layer, float max)
 	{
 	{
-		// TODO
-		return Vector<PhysicsQueryHit>();
+		PxCapsuleGeometry geometry(capsule.getRadius(), capsule.getHeight() * 0.5f);
+		PxTransform transform = toPxTransform(capsule.getCenter(), Quaternion::IDENTITY);
+
+		return sweepAll(geometry, transform, unitDir, layer, max);
 	}
 	}
 
 
 	Vector<PhysicsQueryHit> PhysX::convexCastAll(const HPhysicsMesh& mesh, const Vector3& position,
 	Vector<PhysicsQueryHit> PhysX::convexCastAll(const HPhysicsMesh& mesh, const Vector3& position,
-		const Quaternion& rotation, const Vector3& direction, UINT64 layer, float max)
+		const Quaternion& rotation, const Vector3& unitDir, UINT64 layer, float max)
 	{
 	{
-		// TODO
-		return Vector<PhysicsQueryHit>();
-	}
+		if (mesh == nullptr)
+			return Vector<PhysicsQueryHit>(0);
 
 
-	bool PhysX::rayCastAny(const Ray& ray, UINT64 layer, float max)
-	{
-		// TODO
-		return false;
+		PhysXMesh* physxMesh = static_cast<PhysXMesh*>(mesh.get());
+		if (physxMesh->getType() != PhysicsMeshType::Convex)
+			return Vector<PhysicsQueryHit>(0);
+
+		PxConvexMeshGeometry geometry(physxMesh->_getConvex());
+		PxTransform transform = toPxTransform(position, rotation);
+
+		return sweepAll(geometry, transform, unitDir, layer, max);
 	}
 	}
 
 
-	bool PhysX::rayCastAny(const Vector3& origin, const Vector3& direction,
+	bool PhysX::rayCastAny(const Vector3& origin, const Vector3& unitDir,
 		UINT64 layer, float max)
 		UINT64 layer, float max)
 	{
 	{
-		// TODO
-		return false;
+		PxRaycastBuffer output;
+
+		PxQueryFilterData filterData;
+		filterData.flags |= PxQueryFlag::eANY_HIT;
+		memcpy(&filterData.data.word0, &layer, sizeof(layer));
+
+		return mScene->raycast(toPxVector(origin),
+			toPxVector(unitDir), max, output, PxHitFlag::eDEFAULT | PxHitFlag::eUV | PxHitFlag::eMESH_ANY, filterData);
 	}
 	}
 
 
-	bool PhysX::boxCastAny(const AABox& box, const Quaternion& rotation, const Vector3& direction,
+	bool PhysX::boxCastAny(const AABox& box, const Quaternion& rotation, const Vector3& unitDir,
 		UINT64 layer, float max)
 		UINT64 layer, float max)
 	{
 	{
-		// TODO
-		return false;
+		PxBoxGeometry geometry(toPxVector(box.getHalfSize()));
+		PxTransform transform = toPxTransform(box.getCenter(), rotation);
+
+		return sweepAny(geometry, transform, unitDir, layer, max);
 	}
 	}
 
 
-	bool PhysX::sphereCastAny(const Sphere& sphere, const Vector3& direction,
+	bool PhysX::sphereCastAny(const Sphere& sphere, const Vector3& unitDir,
 		UINT64 layer, float max)
 		UINT64 layer, float max)
 	{
 	{
-		// TODO
-		return false;
+		PxSphereGeometry geometry(sphere.getRadius());
+		PxTransform transform = toPxTransform(sphere.getCenter(), Quaternion::IDENTITY);
+
+		return sweepAny(geometry, transform, unitDir, layer, max);
 	}
 	}
 
 
-	bool PhysX::capsuleCastAny(const Capsule& capsule, const Quaternion& rotation, const Vector3& direction,
+	bool PhysX::capsuleCastAny(const Capsule& capsule, const Quaternion& rotation, const Vector3& unitDir,
 		UINT64 layer, float max)
 		UINT64 layer, float max)
 	{
 	{
-		// TODO
-		return false;
+		PxCapsuleGeometry geometry(capsule.getRadius(), capsule.getHeight() * 0.5f);
+		PxTransform transform = toPxTransform(capsule.getCenter(), Quaternion::IDENTITY);
+
+		return sweepAny(geometry, transform, unitDir, layer, max);
 	}
 	}
 
 
 	bool PhysX::convexCastAny(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
 	bool PhysX::convexCastAny(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
-		const Vector3& direction, UINT64 layer, float max)
+		const Vector3& unitDir, UINT64 layer, float max)
 	{
 	{
-		// TODO
-		return false;
+		if (mesh == nullptr)
+			return false;
+
+		PhysXMesh* physxMesh = static_cast<PhysXMesh*>(mesh.get());
+		if (physxMesh->getType() != PhysicsMeshType::Convex)
+			return false;
+
+		PxConvexMeshGeometry geometry(physxMesh->_getConvex());
+		PxTransform transform = toPxTransform(position, rotation);
+
+		return sweepAny(geometry, transform, unitDir, layer, max);
 	}
 	}
 
 
-	Vector<HCollider> PhysX::boxOverlap(const AABox& box, const Quaternion& rotation,
+	Vector<Collider*> PhysX::_boxOverlap(const AABox& box, const Quaternion& rotation,
 		UINT64 layer)
 		UINT64 layer)
 	{
 	{
-		// TODO
-		return Vector<HCollider>();
+		PxBoxGeometry geometry(toPxVector(box.getHalfSize()));
+		PxTransform transform = toPxTransform(box.getCenter(), rotation);
+
+		return overlap(geometry, transform, layer);
 	}
 	}
 
 
-	Vector<HCollider> PhysX::sphereOverlap(const Sphere& sphere, UINT64 layer)
+	Vector<Collider*> PhysX::_sphereOverlap(const Sphere& sphere, UINT64 layer)
 	{
 	{
-		// TODO
-		return Vector<HCollider>();
+		PxSphereGeometry geometry(sphere.getRadius());
+		PxTransform transform = toPxTransform(sphere.getCenter(), Quaternion::IDENTITY);
+
+		return overlap(geometry, transform, layer);
 	}
 	}
 
 
-	Vector<HCollider> PhysX::capsuleOverlap(const Capsule& capsule, const Quaternion& rotation,
+	Vector<Collider*> PhysX::_capsuleOverlap(const Capsule& capsule, const Quaternion& rotation,
 		UINT64 layer)
 		UINT64 layer)
 	{
 	{
-		// TODO
-		return Vector<HCollider>();
+		PxCapsuleGeometry geometry(capsule.getRadius(), capsule.getHeight() * 0.5f);
+		PxTransform transform = toPxTransform(capsule.getCenter(), Quaternion::IDENTITY);
+
+		return overlap(geometry, transform, layer);
 	}
 	}
 
 
-	Vector<HCollider> PhysX::convexOverlap(const HPhysicsMesh& mesh, const Vector3& position,
+	Vector<Collider*> PhysX::_convexOverlap(const HPhysicsMesh& mesh, const Vector3& position,
 		const Quaternion& rotation, UINT64 layer)
 		const Quaternion& rotation, UINT64 layer)
 	{
 	{
-		// TODO
-		return Vector<HCollider>();
+		if (mesh == nullptr)
+			return Vector<Collider*>(0);
+
+		PhysXMesh* physxMesh = static_cast<PhysXMesh*>(mesh.get());
+		if (physxMesh->getType() != PhysicsMeshType::Convex)
+			return Vector<Collider*>(0);
+
+		PxConvexMeshGeometry geometry(physxMesh->_getConvex());
+		PxTransform transform = toPxTransform(position, rotation);
+
+		return overlap(geometry, transform, layer);
 	}
 	}
 
 
 	bool PhysX::boxOverlapAny(const AABox& box, const Quaternion& rotation, UINT64 layer)
 	bool PhysX::boxOverlapAny(const AABox& box, const Quaternion& rotation, UINT64 layer)
 	{
 	{
-		// TODO
-		return false;
+		PxBoxGeometry geometry(toPxVector(box.getHalfSize()));
+		PxTransform transform = toPxTransform(box.getCenter(), rotation);
+
+		return overlapAny(geometry, transform, layer);
 	}
 	}
 
 
 	bool PhysX::sphereOverlapAny(const Sphere& sphere, UINT64 layer)
 	bool PhysX::sphereOverlapAny(const Sphere& sphere, UINT64 layer)
 	{
 	{
-		// TODO
-		return false;
+		PxSphereGeometry geometry(sphere.getRadius());
+		PxTransform transform = toPxTransform(sphere.getCenter(), Quaternion::IDENTITY);
+
+		return overlapAny(geometry, transform, layer);
 	}
 	}
 
 
 	bool PhysX::capsuleOverlapAny(const Capsule& capsule, const Quaternion& rotation,
 	bool PhysX::capsuleOverlapAny(const Capsule& capsule, const Quaternion& rotation,
 		UINT64 layer)
 		UINT64 layer)
 	{
 	{
-		// TODO
-		return false;
+		PxCapsuleGeometry geometry(capsule.getRadius(), capsule.getHeight() * 0.5f);
+		PxTransform transform = toPxTransform(capsule.getCenter(), Quaternion::IDENTITY);
+
+		return overlapAny(geometry, transform, layer);
 	}
 	}
 
 
 	bool PhysX::convexOverlapAny(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
 	bool PhysX::convexOverlapAny(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
 		UINT64 layer)
 		UINT64 layer)
 	{
 	{
-		// TODO
-		return false;
+		if (mesh == nullptr)
+			return false;
+
+		PhysXMesh* physxMesh = static_cast<PhysXMesh*>(mesh.get());
+		if (physxMesh->getType() != PhysicsMeshType::Convex)
+			return false;
+
+		PxConvexMeshGeometry geometry(physxMesh->_getConvex());
+		PxTransform transform = toPxTransform(position, rotation);
+
+		return overlapAny(geometry, transform, layer);
+	}
+
+	bool PhysX::sweep(const PxGeometry& geometry, const PxTransform& tfrm, const Vector3& unitDir,
+		PhysicsQueryHit& hit, UINT64 layer, float maxDist) const
+	{
+		PxSweepBuffer output;
+
+		PxQueryFilterData filterData;
+		memcpy(&filterData.data.word0, &layer, sizeof(layer));
+
+		bool wasHit = mScene->sweep(geometry, tfrm, toPxVector(unitDir), maxDist, output,
+			PxHitFlag::eDEFAULT | PxHitFlag::eUV, filterData);
+
+		if (wasHit)
+			parseHit(output.block, hit);
+
+		return wasHit;
+	}
+
+	bool PhysX::overlapAny(const PxGeometry& geometry, const PxTransform& tfrm, UINT64 layer) const
+	{
+		PxOverlapBuffer output;
+
+		PxQueryFilterData filterData;
+		memcpy(&filterData.data.word0, &layer, sizeof(layer));
+
+		return mScene->overlap(geometry, tfrm, output, filterData);
+	}
+
+	Vector<Collider*> PhysX::overlap(const PxGeometry& geometry, const PxTransform& tfrm, UINT64 layer) const
+	{
+		PhysXOverlapQueryCallback output;
+
+		PxQueryFilterData filterData;
+		memcpy(&filterData.data.word0, &layer, sizeof(layer));
+
+		mScene->overlap(geometry, tfrm, output, filterData);
+		return output.data;
 	}
 	}
 
 
 	void PhysX::setFlag(PhysicsFlags flag, bool enabled)
 	void PhysX::setFlag(PhysicsFlags flag, bool enabled)

+ 3 - 2
BansheePhysX/Source/BsPhysXCharacterController.cpp

@@ -3,6 +3,7 @@
 #include "BsPhysXCharacterController.h"
 #include "BsPhysXCharacterController.h"
 #include "BsTime.h"
 #include "BsTime.h"
 #include "BsPhysX.h"
 #include "BsPhysX.h"
+#include "BsCCollider.h"
 #include "characterkinematic\PxControllerManager.h"
 #include "characterkinematic\PxControllerManager.h"
 
 
 using namespace physx;
 using namespace physx;
@@ -225,7 +226,7 @@ namespace BansheeEngine
 		collision.motionDir = fromPxVector(hit.dir);
 		collision.motionDir = fromPxVector(hit.dir);
 		collision.motionAmount = hit.length;
 		collision.motionAmount = hit.length;
 		collision.triangleIndex = hit.triangleIndex;
 		collision.triangleIndex = hit.triangleIndex;
-		collision.collider = (Collider*)hit.shape->userData;
+		collision.colliderRaw = (Collider*)hit.shape->userData;
 
 
 		onColliderHit(collision);
 		onColliderHit(collision);
 	}
 	}
@@ -240,7 +241,7 @@ namespace BansheeEngine
 		collision.normal = fromPxVector(hit.worldNormal);
 		collision.normal = fromPxVector(hit.worldNormal);
 		collision.motionDir = fromPxVector(hit.dir);
 		collision.motionDir = fromPxVector(hit.dir);
 		collision.motionAmount = hit.length;
 		collision.motionAmount = hit.length;
-		collision.controller = (CharacterController*)hit.controller->getUserData();
+		collision.controllerRaw = (CharacterController*)hit.controller->getUserData();
 
 
 		CharacterController::onControllerHit(collision);
 		CharacterController::onControllerHit(collision);
 	}
 	}

+ 9 - 0
BansheeUtility/Include/BsCapsule.h

@@ -35,6 +35,15 @@ namespace BansheeEngine
 		/** Returns the radius of the capsule. It defines the distance of the capsule from its line segment. */
 		/** Returns the radius of the capsule. It defines the distance of the capsule from its line segment. */
 		float getRadius() const { return mRadius; }
 		float getRadius() const { return mRadius; }
 
 
+		/** 
+		 * Returns the height of the capsule. The height is the distance between centers of the hemispheres that form the
+		 * capsule's ends.
+		 */
+		float getHeight() const { return mSegment.getLength(); }
+
+		/** Returns the center point of the capsule. */
+		Vector3 getCenter() const { return mSegment.getCenter(); }
+
 	private:
 	private:
 		LineSegment3 mSegment;
 		LineSegment3 mSegment;
 		float mRadius;
 		float mRadius;

+ 6 - 0
BansheeUtility/Include/BsLineSegment3.h

@@ -33,6 +33,12 @@ namespace BansheeEngine
 
 
 		/** Returns the ending point of the line segment. */
 		/** Returns the ending point of the line segment. */
 		const Vector3& getEnd() const { return mEnd; }
 		const Vector3& getEnd() const { return mEnd; }
+
+		/** Returns the length of the line segment. */
+		float getLength() const { return mStart.distance(mEnd); }
+
+		/** Returns the center point along the line segment. */
+		Vector3 getCenter() const { return mStart + (mEnd - mStart) * 0.5f; }
 	private:
 	private:
 		Vector3 mStart, mEnd;
 		Vector3 mStart, mEnd;
 	};
 	};