Bläddra i källkod

Added a per-collider raycast query

BearishSun 9 år sedan
förälder
incheckning
01d4129fc7

+ 7 - 0
BansheeCore/Include/BsCCollider.h

@@ -62,6 +62,13 @@ namespace BansheeEngine
 		/** @copydoc Collider::getRigidbody */
 		/** @copydoc Collider::getRigidbody */
 		HRigidbody getRigidbody() const { return mParent; }
 		HRigidbody getRigidbody() const { return mParent; }
 
 
+		/** @copydoc Collider::rayCast(const Ray&, PhysicsQueryHit&, float) */
+		inline bool rayCast(const Ray& ray, PhysicsQueryHit& hit, float maxDist = FLT_MAX) const;
+
+		/** @copydoc Collider::rayCast(const Vector3&, const Vector3&, PhysicsQueryHit&, float) */
+		inline bool rayCast(const Vector3& origin, const Vector3& unitDir, PhysicsQueryHit& hit,
+			float maxDist = FLT_MAX) const;
+
 		/** @copydoc Collider::onCollisionBegin */
 		/** @copydoc Collider::onCollisionBegin */
 		Event<void(const CollisionData&)> onCollisionBegin;
 		Event<void(const CollisionData&)> onCollisionBegin;
 
 

+ 22 - 0
BansheeCore/Include/BsCollider.h

@@ -42,6 +42,28 @@ namespace BansheeEngine
 		inline void setLayer(UINT64 layer);
 		inline void setLayer(UINT64 layer);
 		inline UINT64 getLayer() const;
 		inline UINT64 getLayer() const;
 
 
+		/** 
+		 * Checks does the ray hit this collider. 
+		 *
+		 * @param[in]	ray		Ray to check.
+		 * @param[out]	hit		Information about the hit. Valid only if the method returns true.
+		 * @param[in]	maxDist	Maximum distance from the ray origin to search for hits.
+		 * @return				True if the ray has hit the collider.
+		 */
+		inline bool rayCast(const Ray& ray, PhysicsQueryHit& hit, float maxDist = FLT_MAX) const;
+
+		/** 
+		 * Checks does the ray hit this collider. 
+		 *
+		 * @param[in]	origin	Origin of the ray to check.
+		 * @param[in]	unitDir	Unit direction of the ray to check.
+		 * @param[out]	hit		Information about the hit. Valid only if the method returns true.
+		 * @param[in]	maxDist	Maximum distance from the ray origin to search for hits.
+		 * @return				True if the ray has hit the collider.
+		 */
+		inline bool rayCast(const Vector3& origin, const Vector3& unitDir, PhysicsQueryHit& hit,
+			float maxDist = FLT_MAX) const;
+
 		Event<void(const CollisionData&)> onCollisionBegin;
 		Event<void(const CollisionData&)> onCollisionBegin;
 		Event<void(const CollisionData&)> onCollisionStay;
 		Event<void(const CollisionData&)> onCollisionStay;
 		Event<void(const CollisionData&)> onCollisionEnd;
 		Event<void(const CollisionData&)> onCollisionEnd;

+ 48 - 46
BansheeCore/Include/BsPhysics.h

@@ -3,6 +3,7 @@
 #pragma once
 #pragma once
 
 
 #include "BsCorePrerequisites.h"
 #include "BsCorePrerequisites.h"
+#include "BsPhysicsCommon.h"
 #include "BsModule.h"
 #include "BsModule.h"
 #include "BsVector3.h"
 #include "BsVector3.h"
 #include "BsVector2.h"
 #include "BsVector2.h"
@@ -41,22 +42,6 @@ namespace BansheeEngine
 	typedef Flags<PhysicsFlag> PhysicsFlags;
 	typedef Flags<PhysicsFlag> PhysicsFlags;
 	BS_FLAGS_OPERATORS(PhysicsFlag)
 	BS_FLAGS_OPERATORS(PhysicsFlag)
 
 
-	/** Hit information from a physics query. */
-	struct PhysicsQueryHit
-	{
-		Vector3 point; /**< Position of the hit in world space. */
-		Vector3 normal; /**< Normal to the surface that was 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. */
-		UINT32 triangleIdx; /**< Index of the triangle that was hit (only applicable when triangle meshes are 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>
 	{
 	{
 	public:
 	public:
@@ -106,7 +91,7 @@ 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);
+		virtual bool rayCast(const Ray& ray, PhysicsQueryHit& hit, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const;
 
 
 		/**
 		/**
 		 * 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.
@@ -120,7 +105,7 @@ namespace BansheeEngine
 		 * @return					True if something was hit, false otherwise.
 		 * @return					True if something was hit, false otherwise.
 		 */
 		 */
 		virtual bool rayCast(const Vector3& origin, const Vector3& unitDir, 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) const = 0;
 
 
 		/**
 		/**
 		 * Performs a sweep into the scene using a box and returns the closest found hit, if any.
 		 * Performs a sweep into the scene using a box and returns the closest found hit, if any.
@@ -135,7 +120,7 @@ namespace BansheeEngine
 		 * @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& unitDir, 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) const = 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.
@@ -149,7 +134,7 @@ namespace BansheeEngine
 		 * @return					True if something was hit, false otherwise.
 		 * @return					True if something was hit, false otherwise.
 		 */
 		 */
 		virtual bool sphereCast(const Sphere& sphere, const Vector3& unitDir, 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) const = 0;
 
 
 		/**
 		/**
 		 * Performs a sweep into the scene using a capsule and returns the closest found hit, if any.
 		 * Performs a sweep into the scene using a capsule and returns the closest found hit, if any.
@@ -164,7 +149,7 @@ namespace BansheeEngine
 		 * @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& unitDir,
 		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) const = 0;
 
 
 		/**
 		/**
 		 * Performs a sweep into the scene using a convex mesh and returns the closest found hit, if any.
 		 * Performs a sweep into the scene using a convex mesh and returns the closest found hit, if any.
@@ -180,7 +165,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& unitDir, 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) const = 0;
 
 
 		/**
 		/**
 		 * Casts a ray into the scene and returns all found hits.
 		 * Casts a ray into the scene and returns all found hits.
@@ -191,7 +176,7 @@ 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);
+		virtual Vector<PhysicsQueryHit> rayCastAll(const Ray& ray, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const;
 
 
 		/**
 		/**
 		 * Casts a ray into the scene and returns all found hits.
 		 * Casts a ray into the scene and returns all found hits.
@@ -204,7 +189,7 @@ namespace BansheeEngine
 		 * @return					List of all detected hits.
 		 * @return					List of all detected hits.
 		 */
 		 */
 		virtual Vector<PhysicsQueryHit> rayCastAll(const Vector3& origin, const Vector3& unitDir,
 		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) const = 0;
 
 
 		/**
 		/**
 		 * Performs a sweep into the scene using a box and returns all found hits.
 		 * Performs a sweep into the scene using a box and returns all found hits.
@@ -218,7 +203,7 @@ namespace BansheeEngine
 		 * @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& unitDir, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
+			const Vector3& unitDir, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const = 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.
@@ -231,7 +216,7 @@ namespace BansheeEngine
 		 * @return					List of all detected hits.
 		 * @return					List of all detected hits.
 		 */
 		 */
 		virtual Vector<PhysicsQueryHit> sphereCastAll(const Sphere& sphere, const Vector3& unitDir,
 		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) const = 0;
 
 
 		/**
 		/**
 		 * Performs a sweep into the scene using a capsule and returns all found hits.
 		 * Performs a sweep into the scene using a capsule and returns all found hits.
@@ -245,7 +230,7 @@ namespace BansheeEngine
 		 * @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& unitDir, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
+			const Vector3& unitDir, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const = 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.
@@ -260,7 +245,7 @@ namespace BansheeEngine
 		 * @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& unitDir, 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) const = 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
@@ -272,7 +257,7 @@ 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);
+		virtual bool rayCastAny(const Ray& ray, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const;
 
 
 		/**
 		/**
 		 * 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
@@ -286,7 +271,7 @@ namespace BansheeEngine
 		 * @return					True if something was hit, false otherwise.
 		 * @return					True if something was hit, false otherwise.
 		 */
 		 */
 		virtual bool rayCastAny(const Vector3& origin, const Vector3& unitDir,
 		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) const = 0;
 
 
 		/**
 		/**
 		 * Performs a sweep into the scene using a box and checks if it has hit anything. This can be significantly more
 		 * Performs a sweep into the scene using a box and checks if it has hit anything. This can be significantly more
@@ -301,7 +286,7 @@ namespace BansheeEngine
 		 * @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& unitDir,
 		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) const = 0;
 
 
 		/**
 		/**
 		 * Performs a sweep into the scene using a sphere and checks if it has hit anything. This can be significantly more
 		 * Performs a sweep into the scene using a sphere and checks if it has hit anything. This can be significantly more
@@ -315,7 +300,7 @@ namespace BansheeEngine
 		 * @return					True if something was hit, false otherwise.
 		 * @return					True if something was hit, false otherwise.
 		 */
 		 */
 		virtual bool sphereCastAny(const Sphere& sphere, const Vector3& unitDir,
 		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) const = 0;
 
 
 		/**
 		/**
 		 * Performs a sweep into the scene using a capsule and checks if it has hit anything. This can be significantly more
 		 * Performs a sweep into the scene using a capsule and checks if it has hit anything. This can be significantly more
@@ -330,7 +315,7 @@ namespace BansheeEngine
 		 * @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& unitDir,
 		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) const = 0;
 
 
 		/**
 		/**
 		 * Performs a sweep into the scene using a convex mesh and checks if it has hit anything. This can be significantly
 		 * Performs a sweep into the scene using a convex mesh and checks if it has hit anything. This can be significantly
@@ -346,7 +331,7 @@ namespace BansheeEngine
 		 * @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& unitDir, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) = 0;
+			const Vector3& unitDir, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const = 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.
@@ -357,7 +342,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);
+			UINT64 layer = BS_ALL_LAYERS) const;
 
 
 		/**
 		/**
 		 * 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.
@@ -366,7 +351,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);
+		virtual Vector<HCollider> sphereOverlap(const Sphere& sphere, UINT64 layer = BS_ALL_LAYERS) const;
 
 
 		/**
 		/**
 		 * 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.
@@ -377,7 +362,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);
+			UINT64 layer = BS_ALL_LAYERS) const;
 
 
 		/**
 		/**
 		 * 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.
@@ -389,7 +374,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);
+			const Quaternion& rotation, UINT64 layer = BS_ALL_LAYERS) const;
 
 
 		/**
 		/**
 		 * Checks if the provided box overlaps any other collider in the scene.
 		 * Checks if the provided box overlaps any other collider in the scene.
@@ -399,7 +384,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					True if there is overlap with another object, false otherwise.
 		 * @return					True if there is overlap with another object, false otherwise.
 		 */
 		 */
-		virtual bool boxOverlapAny(const AABox& box, const Quaternion& rotation, UINT64 layer = BS_ALL_LAYERS) = 0;
+		virtual bool boxOverlapAny(const AABox& box, const Quaternion& rotation, UINT64 layer = BS_ALL_LAYERS) const = 0;
 
 
 		/**
 		/**
 		 * Checks if the provided sphere overlaps any other collider in the scene.
 		 * Checks if the provided sphere overlaps any other collider in the scene.
@@ -408,7 +393,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					True if there is overlap with another object, false otherwise.
 		 * @return					True if there is overlap with another object, false otherwise.
 		 */
 		 */
-		virtual bool sphereOverlapAny(const Sphere& sphere, UINT64 layer = BS_ALL_LAYERS) = 0;
+		virtual bool sphereOverlapAny(const Sphere& sphere, UINT64 layer = BS_ALL_LAYERS) const = 0;
 
 
 		/**
 		/**
 		 * Checks if the provided capsule overlaps any other collider in the scene.
 		 * Checks if the provided capsule overlaps any other collider in the scene.
@@ -419,7 +404,7 @@ namespace BansheeEngine
 		 * @return					True if there is overlap with another object, false otherwise.
 		 * @return					True if there is overlap with another object, false otherwise.
 		 */
 		 */
 		virtual bool capsuleOverlapAny(const Capsule& capsule, const Quaternion& rotation, 
 		virtual bool capsuleOverlapAny(const Capsule& capsule, const Quaternion& rotation, 
-			UINT64 layer = BS_ALL_LAYERS) = 0;
+			UINT64 layer = BS_ALL_LAYERS) const = 0;
 
 
 		/**
 		/**
 		 * Checks if the provided convex mesh overlaps any other collider in the scene.
 		 * Checks if the provided convex mesh overlaps any other collider in the scene.
@@ -431,7 +416,7 @@ namespace BansheeEngine
 		 * @return					True if there is overlap with another object, false otherwise.
 		 * @return					True if there is overlap with another object, false otherwise.
 		 */
 		 */
 		virtual bool convexOverlapAny(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
 		virtual bool convexOverlapAny(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
-			UINT64 layer = BS_ALL_LAYERS) = 0;
+			UINT64 layer = BS_ALL_LAYERS) const = 0;
 
 
 		/******************************************************************************************************************/
 		/******************************************************************************************************************/
 		/************************************************* OPTIONS ********************************************************/
 		/************************************************* OPTIONS ********************************************************/
@@ -464,23 +449,40 @@ 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;
 
 
+		/** @cond INTERNAL */
+
 		/** @copydoc Physics::boxOverlap() */
 		/** @copydoc Physics::boxOverlap() */
 		virtual Vector<Collider*> _boxOverlap(const AABox& box, const Quaternion& rotation,
 		virtual Vector<Collider*> _boxOverlap(const AABox& box, const Quaternion& rotation,
-			UINT64 layer = BS_ALL_LAYERS) = 0;
+			UINT64 layer = BS_ALL_LAYERS) const = 0;
 
 
 		/** @copydoc Physics::sphereOverlap() */
 		/** @copydoc Physics::sphereOverlap() */
-		virtual Vector<Collider*> _sphereOverlap(const Sphere& sphere, UINT64 layer = BS_ALL_LAYERS) = 0;
+		virtual Vector<Collider*> _sphereOverlap(const Sphere& sphere, UINT64 layer = BS_ALL_LAYERS) const = 0;
 
 
 		/** @copydoc Physics::capsuleOverlap() */
 		/** @copydoc Physics::capsuleOverlap() */
 		virtual Vector<Collider*> _capsuleOverlap(const Capsule& capsule, const Quaternion& rotation,
 		virtual Vector<Collider*> _capsuleOverlap(const Capsule& capsule, const Quaternion& rotation,
-			UINT64 layer = BS_ALL_LAYERS) = 0;
+			UINT64 layer = BS_ALL_LAYERS) const = 0;
 
 
 		/** @copydoc Physics::convexOverlap() */
 		/** @copydoc Physics::convexOverlap() */
 		virtual Vector<Collider*> _convexOverlap(const HPhysicsMesh& mesh, const Vector3& position,
 		virtual Vector<Collider*> _convexOverlap(const HPhysicsMesh& mesh, const Vector3& position,
-			const Quaternion& rotation, UINT64 layer = BS_ALL_LAYERS) = 0;
+			const Quaternion& rotation, UINT64 layer = BS_ALL_LAYERS) const = 0;
+
+		/** 
+		 * Checks does the ray hit the provided collider. 
+		 *
+		 * @param[in]	origin		Origin of the ray to check.
+		 * @param[in]	unitDir		Unit direction of the ray to check.
+		 * @param[in]	collider	Collider to check for hit.
+		 * @param[out]	hit			Information about the hit. Valid only if the method returns true.
+		 * @param[in]	maxDist		Maximum distance from the ray origin to search for hits.
+		 * @return					True if the ray has hit the collider.
+		 */
+		virtual bool _rayCast(const Vector3& origin, const Vector3& unitDir, const Collider& collider, PhysicsQueryHit& hit, 
+			float maxDist = FLT_MAX) const = 0;
 
 
 		bool _isUpdateInProgress() const { return mUpdateInProgress; }
 		bool _isUpdateInProgress() const { return mUpdateInProgress; }
 
 
+		/** @endcond */
+
 		static const UINT64 CollisionMapSize = 64;
 		static const UINT64 CollisionMapSize = 64;
 	protected:
 	protected:
 		friend class Rigidbody;
 		friend class Rigidbody;

+ 17 - 0
BansheeCore/Include/BsPhysicsCommon.h

@@ -4,6 +4,7 @@
 
 
 #include "BsCorePrerequisites.h"
 #include "BsCorePrerequisites.h"
 #include "BsVector3.h"
 #include "BsVector3.h"
+#include "BsVector2.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
@@ -45,4 +46,20 @@ namespace BansheeEngine
 		PhysicsOwnerType type = PhysicsOwnerType::None; /**< Type of owner. */
 		PhysicsOwnerType type = PhysicsOwnerType::None; /**< Type of owner. */
 		void* ownerData = nullptr; /**< Data managed by the owner. */
 		void* ownerData = nullptr; /**< Data managed by the owner. */
 	};
 	};
+
+	/** Hit information from a physics query. */
+	struct PhysicsQueryHit
+	{
+		Vector3 point; /**< Position of the hit in world space. */
+		Vector3 normal; /**< Normal to the surface that was 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. */
+		UINT32 triangleIdx; /**< Index of the triangle that was hit (only applicable when triangle meshes are 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;
+	};
 }
 }

+ 17 - 0
BansheeCore/Source/BsCCollider.cpp

@@ -146,6 +146,23 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
+	bool CCollider::rayCast(const Ray& ray, PhysicsQueryHit& hit, float maxDist) const
+	{
+		if (mInternal == nullptr)
+			return false;
+
+		return mInternal->rayCast(ray, hit, maxDist);
+	}
+
+	bool CCollider::rayCast(const Vector3& origin, const Vector3& unitDir, PhysicsQueryHit& hit,
+		float maxDist) const
+	{
+		if (mInternal == nullptr)
+			return false;
+
+		return mInternal->rayCast(origin, unitDir, hit, maxDist);
+	}
+
 	void CCollider::restoreInternal()
 	void CCollider::restoreInternal()
 	{
 	{
 		if (mInternal == nullptr)
 		if (mInternal == nullptr)

+ 12 - 0
BansheeCore/Source/BsCollider.cpp

@@ -3,6 +3,8 @@
 #include "BsCollider.h"
 #include "BsCollider.h"
 #include "BsCollider.h"
 #include "BsCollider.h"
 #include "BsFCollider.h"
 #include "BsFCollider.h"
+#include "BsRay.h"
+#include "BsPhysics.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
@@ -97,4 +99,14 @@ namespace BansheeEngine
 	{
 	{
 		return mInternal->getLayer();
 		return mInternal->getLayer();
 	}
 	}
+
+	bool Collider::rayCast(const Ray& ray, PhysicsQueryHit& hit, float maxDist) const
+	{
+		return gPhysics()._rayCast(ray.getOrigin(), ray.getDirection(), *this, hit, maxDist);
+	}
+
+	bool Collider::rayCast(const Vector3& origin, const Vector3& unitDir, PhysicsQueryHit& hit, float maxDist) const
+	{
+		return gPhysics()._rayCast(origin, unitDir, *this, hit, maxDist);
+	}
 }
 }

+ 7 - 7
BansheeCore/Source/BsPhysics.cpp

@@ -28,17 +28,17 @@ namespace BansheeEngine
 		return mCollisionMap[groupA][groupB];
 		return mCollisionMap[groupA][groupB];
 	}
 	}
 
 
-	bool Physics::rayCast(const Ray& ray, PhysicsQueryHit& hit, UINT64 layer, float max)
+	bool Physics::rayCast(const Ray& ray, PhysicsQueryHit& hit, UINT64 layer, float max) const
 	{
 	{
 		return rayCast(ray.getOrigin(), ray.getDirection(), hit, layer, max);
 		return rayCast(ray.getOrigin(), ray.getDirection(), hit, layer, max);
 	}
 	}
 
 
-	Vector<PhysicsQueryHit> Physics::rayCastAll(const Ray& ray, UINT64 layer, float max)
+	Vector<PhysicsQueryHit> Physics::rayCastAll(const Ray& ray, UINT64 layer, float max) const
 	{
 	{
 		return rayCastAll(ray.getOrigin(), ray.getDirection(), layer, max);
 		return rayCastAll(ray.getOrigin(), ray.getDirection(), layer, max);
 	}
 	}
 
 
-	bool Physics::rayCastAny(const Ray& ray, UINT64 layer, float max)
+	bool Physics::rayCastAny(const Ray& ray, UINT64 layer, float max) const
 	{
 	{
 		return rayCastAny(ray.getOrigin(), ray.getDirection(), layer, max);
 		return rayCastAny(ray.getOrigin(), ray.getDirection(), layer, max);
 	}
 	}
@@ -64,23 +64,23 @@ namespace BansheeEngine
 		return output;
 		return output;
 	}
 	}
 
 
-	Vector<HCollider> Physics::boxOverlap(const AABox& box, const Quaternion& rotation, UINT64 layer)
+	Vector<HCollider> Physics::boxOverlap(const AABox& box, const Quaternion& rotation, UINT64 layer) const
 	{
 	{
 		return rawToComponent(_boxOverlap(box, rotation, layer));
 		return rawToComponent(_boxOverlap(box, rotation, layer));
 	}
 	}
 
 
-	Vector<HCollider> Physics::sphereOverlap(const Sphere& sphere, UINT64 layer)
+	Vector<HCollider> Physics::sphereOverlap(const Sphere& sphere, UINT64 layer) const
 	{
 	{
 		return rawToComponent(_sphereOverlap(sphere, layer));
 		return rawToComponent(_sphereOverlap(sphere, layer));
 	}
 	}
 
 
-	Vector<HCollider> Physics::capsuleOverlap(const Capsule& capsule, const Quaternion& rotation, UINT64 layer)
+	Vector<HCollider> Physics::capsuleOverlap(const Capsule& capsule, const Quaternion& rotation, UINT64 layer) const
 	{
 	{
 		return rawToComponent(_capsuleOverlap(capsule, rotation, layer));
 		return rawToComponent(_capsuleOverlap(capsule, rotation, layer));
 	}
 	}
 
 
 	Vector<HCollider> Physics::convexOverlap(const HPhysicsMesh& mesh, const Vector3& position,
 	Vector<HCollider> Physics::convexOverlap(const HPhysicsMesh& mesh, const Vector3& position,
-		const Quaternion& rotation, UINT64 layer)
+		const Quaternion& rotation, UINT64 layer) const
 	{
 	{
 		return rawToComponent(_convexOverlap(mesh, position, rotation, layer));
 		return rawToComponent(_convexOverlap(mesh, position, rotation, layer));
 	}
 	}

+ 28 - 23
BansheePhysX/Include/BsPhysX.h

@@ -71,77 +71,78 @@ namespace BansheeEngine
 
 
 		/** @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& unitDir, 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) const override;
 
 
 		/** @copydoc Physics::boxCast */
 		/** @copydoc Physics::boxCast */
 		bool boxCast(const AABox& box, const Quaternion& rotation, const Vector3& unitDir, 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) const override;
 
 
 		/** @copydoc Physics::sphereCast */
 		/** @copydoc Physics::sphereCast */
 		bool sphereCast(const Sphere& sphere, const Vector3& unitDir, 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) const override;
 
 
 		/** @copydoc Physics::capsuleCast */
 		/** @copydoc Physics::capsuleCast */
 		bool capsuleCast(const Capsule& capsule, const Quaternion& rotation, const Vector3& unitDir,
 		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) const 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& unitDir, PhysicsQueryHit& hit, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
+			const Vector3& unitDir, PhysicsQueryHit& hit, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const 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& unitDir,
 		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) const 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& unitDir, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
+			const Vector3& unitDir, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const override;
 
 
 		/** @copydoc Physics::sphereCastAll */
 		/** @copydoc Physics::sphereCastAll */
 		Vector<PhysicsQueryHit> sphereCastAll(const Sphere& sphere, const Vector3& unitDir,
 		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) const 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& unitDir, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
+			const Vector3& unitDir, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const 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& unitDir, 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) const 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& unitDir,
 		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) const override;
 
 
 		/** @copydoc Physics::boxCastAny */
 		/** @copydoc Physics::boxCastAny */
 		bool boxCastAny(const AABox& box, const Quaternion& rotation, const Vector3& unitDir,
 		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) const override;
 
 
 		/** @copydoc Physics::sphereCastAny */
 		/** @copydoc Physics::sphereCastAny */
 		bool sphereCastAny(const Sphere& sphere, const Vector3& unitDir,
 		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) const override;
 
 
 		/** @copydoc Physics::capsuleCastAny */
 		/** @copydoc Physics::capsuleCastAny */
 		bool capsuleCastAny(const Capsule& capsule, const Quaternion& rotation, const Vector3& unitDir,
 		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) const 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& unitDir, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) override;
+			const Vector3& unitDir, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const 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) const override;
 
 
 		/** @copydoc Physics::sphereOverlapAny */
 		/** @copydoc Physics::sphereOverlapAny */
-		bool sphereOverlapAny(const Sphere& sphere, UINT64 layer = BS_ALL_LAYERS) override;
+		bool sphereOverlapAny(const Sphere& sphere, UINT64 layer = BS_ALL_LAYERS) const override;
 
 
 		/** @copydoc Physics::capsuleOverlapAny */
 		/** @copydoc Physics::capsuleOverlapAny */
 		bool capsuleOverlapAny(const Capsule& capsule, const Quaternion& rotation,
 		bool capsuleOverlapAny(const Capsule& capsule, const Quaternion& rotation,
-			UINT64 layer = BS_ALL_LAYERS) override;
+			UINT64 layer = BS_ALL_LAYERS) const override;
 
 
 		/** @copydoc Physics::convexOverlapAny */
 		/** @copydoc Physics::convexOverlapAny */
 		bool convexOverlapAny(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
 		bool convexOverlapAny(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
-			UINT64 layer = BS_ALL_LAYERS) override;
+			UINT64 layer = BS_ALL_LAYERS) const override;
 
 
 		void setFlag(PhysicsFlags flags, bool enabled) override;
 		void setFlag(PhysicsFlags flags, bool enabled) override;
 
 
@@ -157,18 +158,22 @@ namespace BansheeEngine
 
 
 		/** @copydoc Physics::_boxOverlap */
 		/** @copydoc Physics::_boxOverlap */
 		Vector<Collider*> _boxOverlap(const AABox& box, const Quaternion& rotation,
 		Vector<Collider*> _boxOverlap(const AABox& box, const Quaternion& rotation,
-			UINT64 layer = BS_ALL_LAYERS) override;
+			UINT64 layer = BS_ALL_LAYERS) const override;
 
 
 		/** @copydoc Physics::_sphereOverlap */
 		/** @copydoc Physics::_sphereOverlap */
-		Vector<Collider*> _sphereOverlap(const Sphere& sphere, UINT64 layer = BS_ALL_LAYERS) override;
+		Vector<Collider*> _sphereOverlap(const Sphere& sphere, UINT64 layer = BS_ALL_LAYERS) const override;
 
 
 		/** @copydoc Physics::_capsuleOverlap */
 		/** @copydoc Physics::_capsuleOverlap */
 		Vector<Collider*> _capsuleOverlap(const Capsule& capsule, const Quaternion& rotation,
 		Vector<Collider*> _capsuleOverlap(const Capsule& capsule, const Quaternion& rotation,
-			UINT64 layer = BS_ALL_LAYERS) override;
+			UINT64 layer = BS_ALL_LAYERS) const override;
 
 
 		/** @copydoc Physics::_convexOverlap */
 		/** @copydoc Physics::_convexOverlap */
 		Vector<Collider*> _convexOverlap(const HPhysicsMesh& mesh, const Vector3& position,
 		Vector<Collider*> _convexOverlap(const HPhysicsMesh& mesh, const Vector3& position,
-			const Quaternion& rotation, UINT64 layer = BS_ALL_LAYERS) override;
+			const Quaternion& rotation, UINT64 layer = BS_ALL_LAYERS) const override;
+
+		/** @copydoc Physics::_rayCast */
+		bool _rayCast(const Vector3& origin, const Vector3& unitDir, const Collider& collider, PhysicsQueryHit& hit, 
+			float maxDist = FLT_MAX) const override;
 
 
 		void _reportContactEvent(const ContactEvent& event);
 		void _reportContactEvent(const ContactEvent& event);
 		void _reportTriggerEvent(const TriggerEvent& event);
 		void _reportTriggerEvent(const TriggerEvent& event);

+ 47 - 23
BansheePhysX/Source/BsPhysX.cpp

@@ -17,6 +17,7 @@
 #include "BsPhysXCharacterController.h"
 #include "BsPhysXCharacterController.h"
 #include "BsTaskScheduler.h"
 #include "BsTaskScheduler.h"
 #include "BsCCollider.h"
 #include "BsCCollider.h"
+#include "BsFPhysXCollider.h"
 #include "BsTime.h"
 #include "BsTime.h"
 #include "Bsvector3.h"
 #include "Bsvector3.h"
 #include "BsAABox.h"
 #include "BsAABox.h"
@@ -721,7 +722,7 @@ namespace BansheeEngine
 			PxHitFlag::eDEFAULT | PxHitFlag::eUV | PxHitFlag::eMESH_ANY, filterData);
 			PxHitFlag::eDEFAULT | PxHitFlag::eUV | PxHitFlag::eMESH_ANY, filterData);
 	}
 	}
 
 
-	bool PhysX::rayCast(const Vector3& origin, const Vector3& unitDir, PhysicsQueryHit& hit, UINT64 layer, float max)
+	bool PhysX::rayCast(const Vector3& origin, const Vector3& unitDir, PhysicsQueryHit& hit, UINT64 layer, float max) const
 	{
 	{
 		PxRaycastBuffer output;
 		PxRaycastBuffer output;
 
 
@@ -738,7 +739,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	bool PhysX::boxCast(const AABox& box, const Quaternion& rotation, const Vector3& unitDir, PhysicsQueryHit& hit,
 	bool PhysX::boxCast(const AABox& box, const Quaternion& rotation, const Vector3& unitDir, PhysicsQueryHit& hit,
-		UINT64 layer, float max)
+		UINT64 layer, float max) const
 	{
 	{
 		PxBoxGeometry geometry(toPxVector(box.getHalfSize()));
 		PxBoxGeometry geometry(toPxVector(box.getHalfSize()));
 		PxTransform transform = toPxTransform(box.getCenter(), rotation);
 		PxTransform transform = toPxTransform(box.getCenter(), rotation);
@@ -747,7 +748,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	bool PhysX::sphereCast(const Sphere& sphere, const Vector3& unitDir, PhysicsQueryHit& hit,
 	bool PhysX::sphereCast(const Sphere& sphere, const Vector3& unitDir, PhysicsQueryHit& hit,
-		UINT64 layer, float max)
+		UINT64 layer, float max) const
 	{
 	{
 		PxSphereGeometry geometry(sphere.getRadius());
 		PxSphereGeometry geometry(sphere.getRadius());
 		PxTransform transform = toPxTransform(sphere.getCenter(), Quaternion::IDENTITY);
 		PxTransform transform = toPxTransform(sphere.getCenter(), Quaternion::IDENTITY);
@@ -756,7 +757,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	bool PhysX::capsuleCast(const Capsule& capsule, const Quaternion& rotation, const Vector3& unitDir,
 	bool PhysX::capsuleCast(const Capsule& capsule, const Quaternion& rotation, const Vector3& unitDir,
-		PhysicsQueryHit& hit, UINT64 layer, float max)
+		PhysicsQueryHit& hit, UINT64 layer, float max) const
 	{
 	{
 		PxCapsuleGeometry geometry(capsule.getRadius(), capsule.getHeight() * 0.5f);
 		PxCapsuleGeometry geometry(capsule.getRadius(), capsule.getHeight() * 0.5f);
 		PxTransform transform = toPxTransform(capsule.getCenter(), Quaternion::IDENTITY);
 		PxTransform transform = toPxTransform(capsule.getCenter(), Quaternion::IDENTITY);
@@ -765,7 +766,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	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& unitDir, PhysicsQueryHit& hit, UINT64 layer, float max)
+		const Vector3& unitDir, PhysicsQueryHit& hit, UINT64 layer, float max) const
 	{
 	{
 		if (mesh == nullptr)
 		if (mesh == nullptr)
 			return false;
 			return false;
@@ -781,7 +782,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	Vector<PhysicsQueryHit> PhysX::rayCastAll(const Vector3& origin, const Vector3& unitDir,
 	Vector<PhysicsQueryHit> PhysX::rayCastAll(const Vector3& origin, const Vector3& unitDir,
-		UINT64 layer, float max)
+		UINT64 layer, float max) const
 	{
 	{
 		PhysXRaycastQueryCallback output;
 		PhysXRaycastQueryCallback output;
 
 
@@ -795,7 +796,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	Vector<PhysicsQueryHit> PhysX::boxCastAll(const AABox& box, const Quaternion& rotation,
 	Vector<PhysicsQueryHit> PhysX::boxCastAll(const AABox& box, const Quaternion& rotation,
-		const Vector3& unitDir, UINT64 layer, float max)
+		const Vector3& unitDir, UINT64 layer, float max) const
 	{
 	{
 		PxBoxGeometry geometry(toPxVector(box.getHalfSize()));
 		PxBoxGeometry geometry(toPxVector(box.getHalfSize()));
 		PxTransform transform = toPxTransform(box.getCenter(), rotation);
 		PxTransform transform = toPxTransform(box.getCenter(), rotation);
@@ -804,7 +805,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	Vector<PhysicsQueryHit> PhysX::sphereCastAll(const Sphere& sphere, const Vector3& unitDir,
 	Vector<PhysicsQueryHit> PhysX::sphereCastAll(const Sphere& sphere, const Vector3& unitDir,
-		UINT64 layer, float max)
+		UINT64 layer, float max) const
 	{
 	{
 		PxSphereGeometry geometry(sphere.getRadius());
 		PxSphereGeometry geometry(sphere.getRadius());
 		PxTransform transform = toPxTransform(sphere.getCenter(), Quaternion::IDENTITY);
 		PxTransform transform = toPxTransform(sphere.getCenter(), Quaternion::IDENTITY);
@@ -813,7 +814,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	Vector<PhysicsQueryHit> PhysX::capsuleCastAll(const Capsule& capsule, const Quaternion& rotation,
 	Vector<PhysicsQueryHit> PhysX::capsuleCastAll(const Capsule& capsule, const Quaternion& rotation,
-		const Vector3& unitDir, UINT64 layer, float max)
+		const Vector3& unitDir, UINT64 layer, float max) const
 	{
 	{
 		PxCapsuleGeometry geometry(capsule.getRadius(), capsule.getHeight() * 0.5f);
 		PxCapsuleGeometry geometry(capsule.getRadius(), capsule.getHeight() * 0.5f);
 		PxTransform transform = toPxTransform(capsule.getCenter(), Quaternion::IDENTITY);
 		PxTransform transform = toPxTransform(capsule.getCenter(), Quaternion::IDENTITY);
@@ -822,7 +823,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	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& unitDir, UINT64 layer, float max)
+		const Quaternion& rotation, const Vector3& unitDir, UINT64 layer, float max) const
 	{
 	{
 		if (mesh == nullptr)
 		if (mesh == nullptr)
 			return Vector<PhysicsQueryHit>(0);
 			return Vector<PhysicsQueryHit>(0);
@@ -838,7 +839,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	bool PhysX::rayCastAny(const Vector3& origin, const Vector3& unitDir,
 	bool PhysX::rayCastAny(const Vector3& origin, const Vector3& unitDir,
-		UINT64 layer, float max)
+		UINT64 layer, float max) const
 	{
 	{
 		PxRaycastBuffer output;
 		PxRaycastBuffer output;
 
 
@@ -851,7 +852,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	bool PhysX::boxCastAny(const AABox& box, const Quaternion& rotation, const Vector3& unitDir,
 	bool PhysX::boxCastAny(const AABox& box, const Quaternion& rotation, const Vector3& unitDir,
-		UINT64 layer, float max)
+		UINT64 layer, float max) const
 	{
 	{
 		PxBoxGeometry geometry(toPxVector(box.getHalfSize()));
 		PxBoxGeometry geometry(toPxVector(box.getHalfSize()));
 		PxTransform transform = toPxTransform(box.getCenter(), rotation);
 		PxTransform transform = toPxTransform(box.getCenter(), rotation);
@@ -860,7 +861,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	bool PhysX::sphereCastAny(const Sphere& sphere, const Vector3& unitDir,
 	bool PhysX::sphereCastAny(const Sphere& sphere, const Vector3& unitDir,
-		UINT64 layer, float max)
+		UINT64 layer, float max) const
 	{
 	{
 		PxSphereGeometry geometry(sphere.getRadius());
 		PxSphereGeometry geometry(sphere.getRadius());
 		PxTransform transform = toPxTransform(sphere.getCenter(), Quaternion::IDENTITY);
 		PxTransform transform = toPxTransform(sphere.getCenter(), Quaternion::IDENTITY);
@@ -869,7 +870,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	bool PhysX::capsuleCastAny(const Capsule& capsule, const Quaternion& rotation, const Vector3& unitDir,
 	bool PhysX::capsuleCastAny(const Capsule& capsule, const Quaternion& rotation, const Vector3& unitDir,
-		UINT64 layer, float max)
+		UINT64 layer, float max) const
 	{
 	{
 		PxCapsuleGeometry geometry(capsule.getRadius(), capsule.getHeight() * 0.5f);
 		PxCapsuleGeometry geometry(capsule.getRadius(), capsule.getHeight() * 0.5f);
 		PxTransform transform = toPxTransform(capsule.getCenter(), Quaternion::IDENTITY);
 		PxTransform transform = toPxTransform(capsule.getCenter(), Quaternion::IDENTITY);
@@ -878,7 +879,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	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& unitDir, UINT64 layer, float max)
+		const Vector3& unitDir, UINT64 layer, float max) const
 	{
 	{
 		if (mesh == nullptr)
 		if (mesh == nullptr)
 			return false;
 			return false;
@@ -894,7 +895,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	Vector<Collider*> PhysX::_boxOverlap(const AABox& box, const Quaternion& rotation,
 	Vector<Collider*> PhysX::_boxOverlap(const AABox& box, const Quaternion& rotation,
-		UINT64 layer)
+		UINT64 layer) const
 	{
 	{
 		PxBoxGeometry geometry(toPxVector(box.getHalfSize()));
 		PxBoxGeometry geometry(toPxVector(box.getHalfSize()));
 		PxTransform transform = toPxTransform(box.getCenter(), rotation);
 		PxTransform transform = toPxTransform(box.getCenter(), rotation);
@@ -902,7 +903,7 @@ namespace BansheeEngine
 		return overlap(geometry, transform, layer);
 		return overlap(geometry, transform, layer);
 	}
 	}
 
 
-	Vector<Collider*> PhysX::_sphereOverlap(const Sphere& sphere, UINT64 layer)
+	Vector<Collider*> PhysX::_sphereOverlap(const Sphere& sphere, UINT64 layer) const
 	{
 	{
 		PxSphereGeometry geometry(sphere.getRadius());
 		PxSphereGeometry geometry(sphere.getRadius());
 		PxTransform transform = toPxTransform(sphere.getCenter(), Quaternion::IDENTITY);
 		PxTransform transform = toPxTransform(sphere.getCenter(), Quaternion::IDENTITY);
@@ -911,7 +912,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	Vector<Collider*> PhysX::_capsuleOverlap(const Capsule& capsule, const Quaternion& rotation,
 	Vector<Collider*> PhysX::_capsuleOverlap(const Capsule& capsule, const Quaternion& rotation,
-		UINT64 layer)
+		UINT64 layer) const
 	{
 	{
 		PxCapsuleGeometry geometry(capsule.getRadius(), capsule.getHeight() * 0.5f);
 		PxCapsuleGeometry geometry(capsule.getRadius(), capsule.getHeight() * 0.5f);
 		PxTransform transform = toPxTransform(capsule.getCenter(), Quaternion::IDENTITY);
 		PxTransform transform = toPxTransform(capsule.getCenter(), Quaternion::IDENTITY);
@@ -920,7 +921,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	Vector<Collider*> 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) const
 	{
 	{
 		if (mesh == nullptr)
 		if (mesh == nullptr)
 			return Vector<Collider*>(0);
 			return Vector<Collider*>(0);
@@ -935,7 +936,7 @@ namespace BansheeEngine
 		return overlap(geometry, transform, layer);
 		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) const
 	{
 	{
 		PxBoxGeometry geometry(toPxVector(box.getHalfSize()));
 		PxBoxGeometry geometry(toPxVector(box.getHalfSize()));
 		PxTransform transform = toPxTransform(box.getCenter(), rotation);
 		PxTransform transform = toPxTransform(box.getCenter(), rotation);
@@ -943,7 +944,7 @@ namespace BansheeEngine
 		return overlapAny(geometry, transform, layer);
 		return overlapAny(geometry, transform, layer);
 	}
 	}
 
 
-	bool PhysX::sphereOverlapAny(const Sphere& sphere, UINT64 layer)
+	bool PhysX::sphereOverlapAny(const Sphere& sphere, UINT64 layer) const
 	{
 	{
 		PxSphereGeometry geometry(sphere.getRadius());
 		PxSphereGeometry geometry(sphere.getRadius());
 		PxTransform transform = toPxTransform(sphere.getCenter(), Quaternion::IDENTITY);
 		PxTransform transform = toPxTransform(sphere.getCenter(), Quaternion::IDENTITY);
@@ -952,7 +953,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	bool PhysX::capsuleOverlapAny(const Capsule& capsule, const Quaternion& rotation,
 	bool PhysX::capsuleOverlapAny(const Capsule& capsule, const Quaternion& rotation,
-		UINT64 layer)
+		UINT64 layer) const
 	{
 	{
 		PxCapsuleGeometry geometry(capsule.getRadius(), capsule.getHeight() * 0.5f);
 		PxCapsuleGeometry geometry(capsule.getRadius(), capsule.getHeight() * 0.5f);
 		PxTransform transform = toPxTransform(capsule.getCenter(), Quaternion::IDENTITY);
 		PxTransform transform = toPxTransform(capsule.getCenter(), Quaternion::IDENTITY);
@@ -961,7 +962,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	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) const
 	{
 	{
 		if (mesh == nullptr)
 		if (mesh == nullptr)
 			return false;
 			return false;
@@ -976,6 +977,29 @@ namespace BansheeEngine
 		return overlapAny(geometry, transform, layer);
 		return overlapAny(geometry, transform, layer);
 	}
 	}
 
 
+	bool PhysX::_rayCast(const Vector3& origin, const Vector3& unitDir, const Collider& collider, PhysicsQueryHit& hit,
+		float maxDist) const
+	{
+		FPhysXCollider* physxCollider = static_cast<FPhysXCollider*>(collider._getInternal());
+		PxShape* shape = physxCollider->_getShape();
+
+		PxTransform transform = toPxTransform(collider.getPosition(), collider.getRotation());
+
+		PxRaycastHit hitInfo;
+		PxU32 maxHits = 1;
+		bool anyHit = false;
+		PxHitFlags hitFlags = PxHitFlag::eDEFAULT | PxHitFlag::eUV;
+		PxU32 hitCount = PxGeometryQuery::raycast(toPxVector(origin), toPxVector(unitDir),
+			shape->getGeometry().any(), transform,
+			maxDist, hitFlags, maxHits, &hitInfo, anyHit);
+
+		if(hitCount > 0)
+			parseHit(hitInfo, hit);
+
+		return hitCount > 0;
+
+	}
+
 	bool PhysX::sweep(const PxGeometry& geometry, const PxTransform& tfrm, const Vector3& unitDir,
 	bool PhysX::sweep(const PxGeometry& geometry, const PxTransform& tfrm, const Vector3& unitDir,
 		PhysicsQueryHit& hit, UINT64 layer, float maxDist) const
 		PhysicsQueryHit& hit, UINT64 layer, float maxDist) const
 	{
 	{