Reworked raycasting on engine side. Re-added raycasting to scripting

This commit is contained in:
Diren D Bharwani 2023-01-02 22:31:48 +08:00
parent ddfbc71400
commit 58a44997b2
15 changed files with 627 additions and 293 deletions

View File

@ -66,7 +66,7 @@
NumberOfChildren: 0 NumberOfChildren: 0
Components: Components:
Transform Component: Transform Component:
Translate: {x: -1.45715916, y: 7, z: 0.319963396} Translate: {x: -1.45715916, y: 7, z: 0.64831841}
Rotate: {x: -0, y: 0, z: -0} Rotate: {x: -0, y: 0, z: -0}
Scale: {x: 1, y: 1, z: 1} Scale: {x: 1, y: 1, z: 1}
IsActive: true IsActive: true

View File

@ -84,9 +84,27 @@ namespace SHADE
// Sphere VS Convex // Sphere VS Convex
static FaceQuery findClosestFace (const SHSphereCollisionShape& sphere, const SHConvexPolyhedronCollisionShape& polyhedron) noexcept; static FaceQuery findClosestFace
static int32_t findClosestPoint (const SHSphereCollisionShape& sphere, const SHConvexPolyhedronCollisionShape& polyhedron, int32_t faceIndex) noexcept; (
static int32_t findVoronoiRegion (const SHSphereCollisionShape& sphere, const SHVec3& faceVertex, const SHVec3& faceNormal, const SHVec3& tangent1, const SHVec3& tangent2) noexcept; const SHSphereCollisionShape& sphere
, const SHConvexPolyhedronCollisionShape& polyhedron
) noexcept;
static int32_t findClosestPoint
(
const SHSphereCollisionShape& sphere
, const SHConvexPolyhedronCollisionShape& polyhedron
, int32_t faceIndex
) noexcept;
static int32_t findVoronoiRegion
(
const SHSphereCollisionShape& sphere
, const SHVec3& faceVertex
, const SHVec3& faceNormal
, const SHVec3& tangent1
, const SHVec3& tangent2
) noexcept;
// Capsule VS Convex // Capsule VS Convex

View File

@ -185,7 +185,11 @@ namespace SHADE
/* Private Member Functions Definitions */ /* Private Member Functions Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHCollision::FaceQuery SHCollision::findClosestFace(const SHSphereCollisionShape& sphere, const SHConvexPolyhedronCollisionShape& polyhedron) noexcept SHCollision::FaceQuery SHCollision::findClosestFace
(
const SHSphereCollisionShape& sphere
, const SHConvexPolyhedronCollisionShape& polyhedron
) noexcept
{ {
FaceQuery faceQuery; FaceQuery faceQuery;
@ -227,7 +231,12 @@ namespace SHADE
return faceQuery; return faceQuery;
} }
int32_t SHCollision::findClosestPoint(const SHSphereCollisionShape& sphere, const SHConvexPolyhedronCollisionShape& polyhedron, int32_t faceIndex) noexcept int32_t SHCollision::findClosestPoint
(
const SHSphereCollisionShape& sphere
, const SHConvexPolyhedronCollisionShape& polyhedron
, int32_t faceIndex
) noexcept
{ {
// Find closest point on face // Find closest point on face
int32_t closestPointIndex = -1; int32_t closestPointIndex = -1;
@ -253,7 +262,14 @@ namespace SHADE
return closestPointIndex; return closestPointIndex;
} }
int32_t SHCollision::findVoronoiRegion(const SHSphereCollisionShape& sphere, const SHVec3& faceVertex, const SHVec3& faceNormal, const SHVec3& tangent1, const SHVec3& tangent2) noexcept int32_t SHCollision::findVoronoiRegion
(
const SHSphereCollisionShape& sphere
, const SHVec3& faceVertex
, const SHVec3& faceNormal
, const SHVec3& tangent1
, const SHVec3& tangent2
) noexcept
{ {
static constexpr int NUM_TANGENTS = 2; static constexpr int NUM_TANGENTS = 2;

View File

@ -160,44 +160,53 @@ namespace SHADE
contactManager->Update(); contactManager->Update();
} }
const SHCollisionSpace::RaycastHits& SHCollisionSpace::Raycast(const SHRay& ray, float distance, uint16_t layer) noexcept const SHCollisionSpace::RaycastResults& SHCollisionSpace::Raycast(const RaycastInfo& info) noexcept
{ {
raycastHits.clear(); static RaycastResults results;
results.clear();
const bool FILTER_COLLIDER = info.colliderEntityID.has_value();
// Cast ray into the broadphase scene
const auto& POTENTIAL_HITS = broadphase.Query(info.ray, info.distance);
const auto& POTENTIAL_HITS = broadphase.Query(ray, distance);
if (POTENTIAL_HITS.empty()) if (POTENTIAL_HITS.empty())
return raycastHits; return results;
// Test potential hits individually // Iterate through all potential hits
// Cull entities that are on different layers const int NUM_HITS = static_cast<int>(POTENTIAL_HITS.size());
for (auto& shapeID : POTENTIAL_HITS) for (const int i : std::ranges::views::iota(0, NUM_HITS))
{ {
const auto HIT_ID = POTENTIAL_HITS[i];
const EntityID EID = HIT_ID.GetEntityID();
if (FILTER_COLLIDER && EID == info.colliderEntityID.value())
continue;
// Get shape // Get shape
const EntityID EID = shapeID.GetEntityID(); const uint32_t IDX = HIT_ID.GetShapeIndex();
const uint32_t IDX = shapeID.GetShapeIndex(); const auto* SHAPE = colliders.find(EID)->second->GetCollisionShape(IDX);
const auto* COLLIDER = colliders.find(EID)->second; // Filter the layers
const auto* SHAPE = COLLIDER->GetCollisionShape(IDX); const bool LAYER_MATCH = SHAPE->GetCollisionTag().GetMask() & info.layers;
// Cull by layer
const bool LAYER_MATCH = SHAPE->GetCollisionTag().GetMask() & layer;
if (!LAYER_MATCH) if (!LAYER_MATCH)
continue; continue;
// Well this is awkward...I honestly don't have the mental capacity to solve this oversight right now. // We cast to the underlying shape. THis is done because a convex hull will not have an inherited raycast method.
// Cast the underlying shape to raycast. Convex hulls do not have an inherited raycast function // Kinda awkward oversight...oops
SHRaycastResult result; SHRaycastResult baseResult;
switch (SHAPE->GetType()) switch (SHAPE->GetType())
{ {
case SHCollisionShape::Type::SPHERE: case SHCollisionShape::Type::SPHERE:
{ {
result = dynamic_cast<const SHSphereCollisionShape*>(SHAPE)->Raycast(ray); baseResult = dynamic_cast<const SHSphereCollisionShape*>(SHAPE)->Raycast(info.ray);
break; break;
} }
case SHCollisionShape::Type::BOX: case SHCollisionShape::Type::BOX:
{ {
result = dynamic_cast<const SHBoxCollisionShape*>(SHAPE)->Raycast(ray); baseResult = dynamic_cast<const SHBoxCollisionShape*>(SHAPE)->Raycast(info.ray);
break; break;
} }
case SHCollisionShape::Type::CAPSULE: case SHCollisionShape::Type::CAPSULE:
@ -205,118 +214,25 @@ namespace SHADE
// TODO // TODO
break; break;
} }
default: break; default: continue; // Redundant case
} }
// If distance is greater than specified, skip this result if (!baseResult || baseResult.distance > info.distance)
if (!result || result.distance > distance)
continue; continue;
SHPhysicsRaycastResult physicsResult; // Copy to a physics raycast result
physicsResult.hit = result.hit; SHPhysicsRaycastResult result;
physicsResult.distance = result.distance; memcpy_s(&result, sizeof(SHRaycastResult), &baseResult, sizeof(SHRaycastResult));
physicsResult.angle = result.angle;
physicsResult.position = result.position;
physicsResult.normal = result.normal;
physicsResult.entityHit = EID;
physicsResult.shapeIndex = IDX;
raycastHits.emplace_back(physicsResult); result.entityHit = EID;
result.shapeIndex = IDX;
results.emplace_back(result);
} }
// Sort by distance return results;
std::ranges::sort(raycastHits.begin(), raycastHits.end(), [](const SHPhysicsRaycastResult& lhs, const SHPhysicsRaycastResult& rhs)
{
return lhs.distance < rhs.distance;
});
return raycastHits;
} }
const SHCollisionSpace::RaycastHits& SHCollisionSpace::Linecast(const SHVec3& start, const SHVec3& end, uint16_t layer) noexcept
{
// Create bounded ray and reuse the raycast function
const SHRay BOUNDED_RAY{ start, SHVec3::Normalise(end - start) };
const float DISTANCE = SHVec3::Distance(end, start);
return Raycast(BOUNDED_RAY, DISTANCE, layer);
}
const SHCollisionSpace::RaycastHits& SHCollisionSpace::ColliderRaycast(EntityID colliderEID, const SHRay& ray, float distance, uint16_t layer) noexcept
{
raycastHits.clear();
const auto& POTENTIAL_HITS = broadphase.Query(ray, distance);
if (POTENTIAL_HITS.empty())
return raycastHits;
// Test potential hits individually
// Cull entities that are on different layers
for (auto& shapeID : POTENTIAL_HITS)
{
// Get shape
const EntityID EID = shapeID.GetEntityID();
const auto* COLLIDER = colliders.find(EID)->second;
// Cull any shapes on the same entity
if (EID == colliderEID)
continue;
const uint32_t IDX = shapeID.GetShapeIndex();
const auto* SHAPE = COLLIDER->GetCollisionShape(IDX);
// Cull by layer
const bool LAYER_MATCH = SHAPE->GetCollisionTag().GetMask() & layer;
if (!LAYER_MATCH)
continue;
// Well this is awkward...I honestly don't have the mental capacity to solve this oversight right now.
// Cast the underlying shape to raycast. Convex hulls do not have an inherited raycast function
SHRaycastResult result;
switch (SHAPE->GetType())
{
case SHCollisionShape::Type::SPHERE:
{
result = dynamic_cast<const SHSphereCollisionShape*>(SHAPE)->Raycast(ray);
break;
}
case SHCollisionShape::Type::BOX:
{
result = dynamic_cast<const SHBoxCollisionShape*>(SHAPE)->Raycast(ray);
break;
}
case SHCollisionShape::Type::CAPSULE:
{
// TODO
break;
}
default: break;
}
// If distance is greater than specified, skip this result
if (!result || result.distance > distance)
continue;
SHPhysicsRaycastResult physicsResult;
physicsResult.hit = result.hit;
physicsResult.distance = result.distance;
physicsResult.angle = result.angle;
physicsResult.position = result.position;
physicsResult.normal = result.normal;
physicsResult.entityHit = EID;
physicsResult.shapeIndex = IDX;
raycastHits.emplace_back(physicsResult);
}
// Sort by distance
std::ranges::sort(raycastHits.begin(), raycastHits.end(), [](const SHPhysicsRaycastResult& lhs, const SHPhysicsRaycastResult& rhs)
{
return lhs.distance < rhs.distance;
});
return raycastHits;
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Private Member Functions Definitions */ /* Private Member Functions Definitions */

View File

@ -13,12 +13,15 @@
#pragma once #pragma once
#include <optional>
// Project Headers // Project Headers
#include "Broadphase/SHDynamicAABBTree.h" #include "Broadphase/SHDynamicAABBTree.h"
#include "Physics/Dynamics/SHContactManager.h" #include "Physics/Dynamics/SHContactManager.h"
#include "SHCollider.h" #include "SHCollider.h"
#include "SHPhysicsRaycastResult.h" #include "SHPhysicsRaycastResult.h"
#include "CollisionTags/SHCollisionTags.h" #include "CollisionTags/SHCollisionTags.h"
#include "CollisionTags/SHCollisionTags.h"
namespace SHADE namespace SHADE
{ {
@ -38,7 +41,52 @@ namespace SHADE
/* Type Definitions */ /* Type Definitions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
using RaycastHits = std::vector<SHPhysicsRaycastResult>; /**
* @brief
* Contains information to cast a ray into the collision space.
* The collider entityID and shape index is optional.
*/
struct RaycastInfo
{
private:
/*-------------------------------------------------------------------------------*/
/* Friends */
/*-------------------------------------------------------------------------------*/
friend class SHCollisionSpace;
public:
/*-------------------------------------------------------------------------------*/
/* Data Members */
/*-------------------------------------------------------------------------------*/
bool continuous = false;
uint16_t layers = static_cast<uint16_t>(SHCollisionTag::Layer::ALL);
float distance = std::numeric_limits<float>::infinity();
SHRay ray;
/*-------------------------------------------------------------------------------*/
/* Setter Functions */
/*-------------------------------------------------------------------------------*/
/**
* @brief
* Sets the collider ID for the raycast. Setting this specifies that the ray
* should ignore this collider.
* @param eid
* The entity ID of the collider.
*/
void SetColliderID(EntityID eid) noexcept { colliderEntityID = eid; }
private:
/*-------------------------------------------------------------------------------*/
/* Data Members */
/*-------------------------------------------------------------------------------*/
std::optional<EntityID> colliderEntityID;
};
using RaycastResults = std::vector<SHPhysicsRaycastResult>;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */ /* Constructors & Destructor */
@ -98,68 +146,13 @@ namespace SHADE
/** /**
* @brief * @brief
* Casts a ray into the collision space. * Casts a ray into the collision space.
* @param ray * @param info
* The ray to cast. The direction of the ray must be normalised. * Contains the information for the raycast.
* @param distance
* The distance to cast the ray. Defaults to infinity.
* @param layer
* The layer(s) the ray is casting on. Defaults to all layers.
* @return * @return
* A container of all the objects the raycast hit, ordered by distance. <br/> * A container of the objects hit by the ray. If nothing was hit, the container
* The first object in the container is the first object hit etc. * will be empty.
*/ */
[[nodiscard]] const RaycastHits& Raycast [[nodiscard]] const RaycastResults& Raycast(const RaycastInfo& info) noexcept;
(
const SHRay& ray
, float distance = std::numeric_limits<float>::infinity()
, uint16_t layer = static_cast<uint16_t>(SHCollisionTag::Layer::ALL)
) noexcept;
/**
* @brief
* Casts a bounded ray into the collision space.
* @param start
* The origin of the ray.
* @param end
* The end of the ray.
* @param layer
* The layer(s) the ray is casting on. Defaults to all layers.
* @return
* A container of all the objects the raycast hit, ordered by distance. <br/>
* The first object in the container is the first object hit etc.
*/
[[nodiscard]] const RaycastHits& Linecast
(
const SHVec3& start
, const SHVec3& end
, uint16_t layer = static_cast<uint16_t>(SHCollisionTag::Layer::ALL)
) noexcept;
/**
* @brief
* Casts a ray into the collision space from a collider's position. <br/>
* The collider and all it's shapes will be ignored.
* @param colliderEID
* The entityID of the collider to cast from.
* @param ray
* The ray to cast. <br/>
* The position of the ray is the position offset from the collider's position. <br/>
* The direction of the ray must be normalised.
* @param distance
* The distance to cast the ray. Defaults to infinity.
* @param layer
* The layer(s) the ray is casting on. Defaults to all layers.
* @return
* A container of all the objects the raycast hit, ordered by distance. <br/>
* The first object in the container is the first object hit etc.
*/
[[nodiscard]] const RaycastHits& ColliderRaycast
(
EntityID colliderEID
, const SHRay& ray
, float distance = std::numeric_limits<float>::infinity()
, uint16_t layer = static_cast<uint16_t>(SHCollisionTag::Layer::ALL)
) noexcept;
private: private:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -184,25 +177,20 @@ namespace SHADE
Colliders colliders; Colliders colliders;
NarrowphaseBatch narrowphaseBatch; NarrowphaseBatch narrowphaseBatch;
RaycastHits raycastHits; // Reusable container for raycast results
SHAABBTree broadphase; SHAABBTree broadphase;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Member Functions */ /* Member Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
// Broadphase helpers // Broadphase helpers
void broadphaseQuery (SHRigidBody::Type rigidBodyType, SHCollider* collider) noexcept; void broadphaseQuery (SHRigidBody::Type rigidBodyType, SHCollider* collider) noexcept;
// Narrowphase helpers // Narrowphase helpers
void collideTriggers (const SHCollisionKey& key, NarrowphasePair& narrowphasePair) const noexcept; void collideTriggers (const SHCollisionKey& key, NarrowphasePair& narrowphasePair) const noexcept;
void collideManifolds (const SHCollisionKey& key, NarrowphasePair& narrowphasePair) const noexcept; void collideManifolds (const SHCollisionKey& key, NarrowphasePair& narrowphasePair) const noexcept;
}; };
} // namespace SHADE } // namespace SHADE

View File

@ -19,6 +19,7 @@
#include "ECS_Base/Managers/SHEntityManager.h" #include "ECS_Base/Managers/SHEntityManager.h"
#include "ECS_Base/Managers/SHSystemManager.h" #include "ECS_Base/Managers/SHSystemManager.h"
#include "Editor/SHEditor.h" #include "Editor/SHEditor.h"
#include "Physics/Collision/SHCollisionSpace.h"
#include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h" #include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h"
#include "Physics/Interface/SHColliderComponent.h" #include "Physics/Interface/SHColliderComponent.h"
#include "Scripting/SHScriptEngine.h" #include "Scripting/SHScriptEngine.h"
@ -189,6 +190,25 @@ namespace SHADE
} }
} }
const std::vector<SHPhysicsRaycastResult>& SHPhysicsSystem::Raycast(const SHCollisionSpace::RaycastInfo& info) noexcept
{
auto& results = collisionSpace->Raycast(info);
// Load start and end points into the container for debug drawing
#ifdef SHEDITOR
SHVec3 endPos = info.ray.position + info.ray.direction * SHRay::MAX_RAYCAST_DIST;
if (!results.empty())
endPos = results.back().position;
raycastHits.emplace_back(info.ray.position, endPos);
#endif
return results;
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Private Function Member Definitions */ /* Private Function Member Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/

View File

@ -76,8 +76,25 @@ namespace SHADE
*/ */
void Init() override; void Init() override;
void Exit() override; void Exit() override;
/**
* @brief
* Forces the world to take a single step. Interpolation of bodies cannot be done when
* forcing an update.
*/
void ForceUpdate(); void ForceUpdate();
/**
* @brief
* Casts a ray into the collision space.
* @param info
* Contains the information for the raycast.
* @return
* A container of the objects hit by the ray. If nothing was hit, the container
* will be empty.
*/
[[nodiscard]] const std::vector<SHPhysicsRaycastResult>& Raycast(const SHCollisionSpace::RaycastInfo& info) noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* System Routines */ /* System Routines */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -129,6 +146,12 @@ namespace SHADE
using EventFunctionPair = std::pair<SHEventHandle(SHPhysicsSystem::*)(SHEventPtr), SHEventIdentifier>; using EventFunctionPair = std::pair<SHEventHandle(SHPhysicsSystem::*)(SHEventPtr), SHEventIdentifier>;
struct RaycastHit
{
SHVec3 start;
SHVec3 end;
};
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -149,6 +172,11 @@ namespace SHADE
SHCollisionSpace* collisionSpace; SHCollisionSpace* collisionSpace;
SHPhysicsObjectManager physicsObjectManager; SHPhysicsObjectManager physicsObjectManager;
// For the debug drawer to draw rays
#ifdef SHEDITOR
std::vector<RaycastHit> raycastHits;
#endif
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Function Members */ /* Function Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -67,4 +67,16 @@ namespace SHADE
return 0.0; return 0.0;
} }
const std::vector<SHPhysicsRaycastResult>& SHPhysicsSystemInterface::Raycast(const SHCollisionSpace::RaycastInfo& info) noexcept
{
static std::vector<SHPhysicsRaycastResult> emptyVec;
auto* physicsSystem = SHSystemManager::GetSystem<SHPhysicsSystem>();
if (physicsSystem)
return physicsSystem->Raycast(info);
SHLOGV_WARNING("Failed to get fixed update rate. 0.0 returned instead.");
return emptyVec;
}
} }

View File

@ -14,6 +14,7 @@ of DigiPen Institute of Technology is prohibited.
// Project Headers // Project Headers
#include "ECS_Base/Entity/SHEntity.h" #include "ECS_Base/Entity/SHEntity.h"
#include "Physics/Collision/SHCollisionSpace.h"
#include "Physics/Collision/Contacts/SHCollisionEvents.h" #include "Physics/Collision/Contacts/SHCollisionEvents.h"
@ -26,6 +27,7 @@ namespace SHADE
class SHVec3; class SHVec3;
struct SHRay; struct SHRay;
struct SHPhysicsRaycastResult; struct SHPhysicsRaycastResult;
struct SHCollisionSpace::RaycastInfo;
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -47,9 +49,12 @@ namespace SHADE
/* Static Usage Functions */ /* Static Usage Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
[[nodiscard]] static const std::vector<SHCollisionEvent>& GetCollisionInfo () noexcept; [[nodiscard]] static const std::vector<SHCollisionEvent>& GetCollisionInfo () noexcept;
[[nodiscard]] static const std::vector<SHTriggerEvent>& GetTriggerInfo () noexcept; [[nodiscard]] static const std::vector<SHTriggerEvent>& GetTriggerInfo () noexcept;
[[nodiscard]] static double GetFixedDT () noexcept; [[nodiscard]] static double GetFixedDT () noexcept;
[[nodiscard]] static int GetFixedUpdateRate () noexcept; [[nodiscard]] static int GetFixedUpdateRate () noexcept;
[[nodiscard]] static const std::vector<SHPhysicsRaycastResult>& Raycast (const SHCollisionSpace::RaycastInfo& info) noexcept;
}; };
} }

View File

@ -128,39 +128,19 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
Vector3 BoxCollider::Center::get() Vector3 BoxCollider::Center::get()
{ {
//return Convert::ToCLI(getNativeCollisionShape<SHAABB>().GetCenter()); return Convert::ToCLI(getNativeCollisionShape<SHBoxCollisionShape>().GetCenter());
return Vector3::Zero;
}
void BoxCollider::Center::set(Vector3 value)
{
//getNativeCollisionShape<SHAABB>().SetCenter(Convert::ToNative(value));
} }
Vector3 BoxCollider::HalfExtents::get() Vector3 BoxCollider::HalfExtents::get()
{ {
//return Convert::ToCLI(getNativeCollisionShape<SHAABB>().GetExtents()); return Convert::ToCLI(getNativeCollisionShape<SHBoxCollisionShape>().GetWorldExtents());
return Vector3::Zero;
} }
void BoxCollider::HalfExtents::set(Vector3 value) void BoxCollider::HalfExtents::set(Vector3 value)
{ {
//getNativeCollisionShape<SHAABB>().SetExtents(Convert::ToNative(value)); getNativeCollisionShape<SHBoxCollisionShape>().SetWorldExtents(Convert::ToNative(value));
} }
Vector3 BoxCollider::Min::get() Quaternion BoxCollider::Orientation::get()
{ {
//return Convert::ToCLI(getNativeCollisionShape<SHAABB>().GetMin()); return Convert::ToCLI(getNativeCollisionShape<SHBoxCollisionShape>().GetOrientation());
return Vector3::Zero;
}
void BoxCollider::Min::set(Vector3 value)
{
//getNativeCollisionShape<SHAABB>().SetMin(Convert::ToNative(value));
}
Vector3 BoxCollider::Max::get()
{
//return Convert::ToCLI(getNativeCollisionShape<SHAABB>().GetMax());
return Vector3::Zero;
}
void BoxCollider::Max::set(Vector3 value)
{
//getNativeCollisionShape<SHAABB>().SetMax(Convert::ToNative(value));
} }
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -184,10 +164,6 @@ namespace SHADE
{ {
return Convert::ToCLI(getNativeCollisionShape<SHSphereCollisionShape>().GetCenter()); return Convert::ToCLI(getNativeCollisionShape<SHSphereCollisionShape>().GetCenter());
} }
void SphereCollider::Center::set(Vector3 value)
{
getNativeCollisionShape<SHSphereCollisionShape>().SetCenter(Convert::ToNative(value));
}
float SphereCollider::Radius::get() float SphereCollider::Radius::get()
{ {
return getNativeCollisionShape<SHSphereCollisionShape>().GetWorldRadius(); return getNativeCollisionShape<SHSphereCollisionShape>().GetWorldRadius();

View File

@ -142,15 +142,14 @@ namespace SHADE
/* Properties */ /* Properties */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Center of the Bounding Box formed by this bound. /// Center of the box collider.
/// </summary> /// </summary>
property Vector3 Center property Vector3 Center
{ {
Vector3 get(); Vector3 get();
void set(Vector3 value);
} }
/// <summary> /// <summary>
/// Half of the scale of the Bounding Box formed by this bound. /// Half of the scale of the box collider.
/// </summary> /// </summary>
property Vector3 HalfExtents property Vector3 HalfExtents
{ {
@ -158,22 +157,11 @@ namespace SHADE
void set(Vector3 value); void set(Vector3 value);
} }
/// <summary> /// <summary>
/// Position of the bottom left back corner of the Bounding Box formed by this /// The orientation of the box.
/// bound.
/// </summary> /// </summary>
property Vector3 Min property Quaternion Orientation
{ {
Vector3 get(); Quaternion get();
void set(Vector3 value);
}
/// <summary>
/// Position of the top right front corner of the Bounding Box formed by this
/// bound.
/// </summary>
property Vector3 Max
{
Vector3 get();
void set(Vector3 value);
} }
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -201,12 +189,11 @@ namespace SHADE
/* Properties */ /* Properties */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Center of the Bounding Sphere formed by this bound. /// Center of the sphere.
/// </summary> /// </summary>
property Vector3 Center property Vector3 Center
{ {
Vector3 get(); Vector3 get();
void set(Vector3 value);
} }
/// <summary> /// <summary>
/// Radius of the Bounding Sphere formed by this bound. /// Radius of the Bounding Sphere formed by this bound.

View File

@ -15,10 +15,15 @@
// External Dependencies // External Dependencies
#include "Physics/System/SHPhysicsSystemInterface.h" #include "Physics/System/SHPhysicsSystemInterface.h"
// Project Header // Project Header
#include "Components/Collider.hxx"
#include "Components/Transform.hxx"
#include "Engine/GameObject.hxx" #include "Engine/GameObject.hxx"
#include "Physics/Collision/SHCollisionSpace.h"
#include "Utility/Convert.hxx" #include "Utility/Convert.hxx"
#include "Utility/Debug.hxx" #include "Utility/Debug.hxx"
using namespace System::Collections::Generic;
namespace SHADE namespace SHADE
{ {
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -41,49 +46,301 @@ namespace SHADE
/* Raycast Function Member Definitions */ /* Raycast Function Member Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
RaycastHit Physics::Raycast(Ray ray) List<RaycastHit>^ Physics::Raycast(Ray ray, bool continuous)
{ {
return RaycastHit{}; List<RaycastHit>^ results = gcnew List<RaycastHit>();
// Cast natively
SHCollisionSpace::RaycastInfo raycastInfo;
raycastInfo.ray = Convert::ToNative(ray);
raycastInfo.continuous = continuous;
const auto& NATIVE_RESULTS = SHPhysicsSystemInterface::Raycast(raycastInfo);
if (!NATIVE_RESULTS.empty())
{
for (const auto& nativeResult : NATIVE_RESULTS)
results->Add(Convert::ToCLI(nativeResult));
}
return results;
} }
RaycastHit Physics::Raycast(Ray ray, float distance) List<RaycastHit>^ Physics::Raycast(Ray ray, float distance, bool continuous)
{ {
return RaycastHit{}; List<RaycastHit>^ results = gcnew List<RaycastHit>();
// Cast natively
SHCollisionSpace::RaycastInfo raycastInfo;
raycastInfo.ray = Convert::ToNative(ray);
raycastInfo.distance = distance;
raycastInfo.continuous = continuous;
const auto& NATIVE_RESULTS = SHPhysicsSystemInterface::Raycast(raycastInfo);
if (!NATIVE_RESULTS.empty())
{
for (const auto& nativeResult : NATIVE_RESULTS)
results->Add(Convert::ToCLI(nativeResult));
}
return results;
} }
RaycastHit Physics::Linecast(Vector3 start, Vector3 end) List<RaycastHit>^ Physics::Linecast(Vector3 start, Vector3 end, bool continuous)
{ {
return RaycastHit{}; List<RaycastHit>^ results = gcnew List<RaycastHit>();
// Cast natively
Vector3 direction = end - start;
direction.Normalise();
const Ray CLI_RAY( start, direction );
SHCollisionSpace::RaycastInfo raycastInfo;
raycastInfo.ray = Convert::ToNative(CLI_RAY);
raycastInfo.distance = (end - start).GetMagnitude();
raycastInfo.continuous = continuous;
const auto& NATIVE_RESULTS = SHPhysicsSystemInterface::Raycast(raycastInfo);
if (!NATIVE_RESULTS.empty())
{
for (const auto& nativeResult : NATIVE_RESULTS)
results->Add(Convert::ToCLI(nativeResult));
}
return results;
} }
RaycastHit Physics::ColliderRaycast(GameObject object, Ray ray) List<RaycastHit>^ Physics::ColliderRaycast(GameObject object, Ray ray, bool continuous)
{ {
return RaycastHit{}; List<RaycastHit>^ results = gcnew List<RaycastHit>();
// Get the collider's position (same as the transform)
Transform^ managedTransform = object.GetComponent<Transform^>();
if (!managedTransform)
throw gcnew System::InvalidOperationException("Attempted to retrieve invalid Transform.");
const Vector3 COLLIDER_POS = managedTransform->GlobalPosition;
ray.Position += COLLIDER_POS;
SHCollisionSpace::RaycastInfo raycastInfo;
raycastInfo.ray = Convert::ToNative(ray);
raycastInfo.continuous = continuous;
raycastInfo.SetColliderID(object.EntityId);
const auto& NATIVE_RESULTS = SHPhysicsSystemInterface::Raycast(raycastInfo);
if (!NATIVE_RESULTS.empty())
{
for (const auto& nativeResult : NATIVE_RESULTS)
results->Add(Convert::ToCLI(nativeResult));
}
return results;
} }
RaycastHit Physics::ColliderRaycast(GameObject object, Ray ray, float distance) List<RaycastHit>^ Physics::ColliderRaycast(GameObject object, Ray ray, float distance, bool continuous)
{ {
return RaycastHit{}; List<RaycastHit>^ results = gcnew List<RaycastHit>();
// Get the collider's position (same as the transform)
Transform^ managedTransform = object.GetComponent<Transform^>();
if (!managedTransform)
throw gcnew System::InvalidOperationException("Attempted to retrieve invalid Transform.");
const Vector3 COLLIDER_POS = managedTransform->GlobalPosition;
ray.Position += COLLIDER_POS;
SHCollisionSpace::RaycastInfo raycastInfo;
raycastInfo.ray = Convert::ToNative(ray);
raycastInfo.distance = distance;
raycastInfo.continuous = continuous;
raycastInfo.SetColliderID(object.EntityId);
const auto& NATIVE_RESULTS = SHPhysicsSystemInterface::Raycast(raycastInfo);
if (!NATIVE_RESULTS.empty())
{
for (const auto& nativeResult : NATIVE_RESULTS)
results->Add(Convert::ToCLI(nativeResult));
}
return results;
} }
RaycastHit Physics::ColliderRaycast(GameObject object, int shapeIndex, Ray ray) List<RaycastHit>^ Physics::ColliderRaycast(GameObject object, int shapeIndex, Ray ray, bool continuous)
{ {
return RaycastHit{}; List<RaycastHit>^ results = gcnew List<RaycastHit>();
// Get the collider's position
Vector3 shapePos = Vector3::Zero;
Collider^ managedCollider = object.GetComponent<Collider^>();
if (!managedCollider)
throw gcnew System::InvalidOperationException("Attempted to retrieve invalid Collider.");
CollisionShape^ managedShape = managedCollider->GetCollisionShape(shapeIndex);
if (!managedShape)
throw gcnew System::InvalidOperationException("Attempted to retrieve invalid CollisionShape.");
const auto& NATIVE_SHAPE = managedShape->getNativeCollisionShape();
switch (NATIVE_SHAPE.GetType())
{
case SHCollisionShape::Type::SPHERE:
{
shapePos = Convert::ToCLI(dynamic_cast<const SHSphereCollisionShape&>(NATIVE_SHAPE).GetCenter());
break;
}
case SHCollisionShape::Type::BOX:
{
shapePos = Convert::ToCLI(dynamic_cast<const SHBoxCollisionShape&>(NATIVE_SHAPE).GetCenter());
break;
}
default: break;
}
ray.Position += shapePos;
SHCollisionSpace::RaycastInfo raycastInfo;
raycastInfo.ray = Convert::ToNative(ray);
raycastInfo.continuous = continuous;
raycastInfo.SetColliderID(object.EntityId);
const auto& NATIVE_RESULTS = SHPhysicsSystemInterface::Raycast(raycastInfo);
if (!NATIVE_RESULTS.empty())
{
for (const auto& nativeResult : NATIVE_RESULTS)
results->Add(Convert::ToCLI(nativeResult));
}
return results;
} }
RaycastHit Physics::ColliderRaycast(GameObject object, int shapeIndex, Ray ray, float distance) List<RaycastHit>^ Physics::ColliderRaycast(GameObject object, int shapeIndex, Ray ray, float distance, bool continuous)
{ {
return RaycastHit{}; List<RaycastHit>^ results = gcnew List<RaycastHit>();
// Get the collider's position
Vector3 shapePos = Vector3::Zero;
Collider^ managedCollider = object.GetComponent<Collider^>();
if (!managedCollider)
throw gcnew System::InvalidOperationException("Attempted to retrieve invalid Collider.");
CollisionShape^ managedShape = managedCollider->GetCollisionShape(shapeIndex);
if (!managedShape)
throw gcnew System::InvalidOperationException("Attempted to retrieve invalid CollisionShape.");
const auto& NATIVE_SHAPE = managedShape->getNativeCollisionShape();
switch (NATIVE_SHAPE.GetType())
{
case SHCollisionShape::Type::SPHERE:
{
shapePos = Convert::ToCLI(dynamic_cast<const SHSphereCollisionShape&>(NATIVE_SHAPE).GetCenter());
break;
}
case SHCollisionShape::Type::BOX:
{
shapePos = Convert::ToCLI(dynamic_cast<const SHBoxCollisionShape&>(NATIVE_SHAPE).GetCenter());
break;
}
default: break;
}
ray.Position += shapePos;
SHCollisionSpace::RaycastInfo raycastInfo;
raycastInfo.ray = Convert::ToNative(ray);
raycastInfo.continuous = continuous;
raycastInfo.distance = distance;
raycastInfo.SetColliderID(object.EntityId);
const auto& NATIVE_RESULTS = SHPhysicsSystemInterface::Raycast(raycastInfo);
if (!NATIVE_RESULTS.empty())
{
for (const auto& nativeResult : NATIVE_RESULTS)
results->Add(Convert::ToCLI(nativeResult));
}
return results;
} }
RaycastHit Physics::ColliderLineCast(GameObject object, Vector3 start, Vector3 end) List<RaycastHit>^ Physics::ColliderLineCast(GameObject object, Vector3 start, Vector3 end, bool continuous)
{ {
return RaycastHit{}; List<RaycastHit>^ results = gcnew List<RaycastHit>();
// Get the collider's position (same as the transform)
Transform^ managedTransform = object.GetComponent<Transform^>();
if (!managedTransform)
throw gcnew System::InvalidOperationException("Attempted to retrieve invalid Transform.");
const Vector3 COLLIDER_POS = managedTransform->GlobalPosition;
start += COLLIDER_POS;
Vector3 direction = end - start;
direction.Normalise();
const Ray CLI_RAY( start, direction );
SHCollisionSpace::RaycastInfo raycastInfo;
raycastInfo.ray = Convert::ToNative(CLI_RAY);
raycastInfo.distance = (end - start).GetMagnitude();
raycastInfo.continuous = continuous;
raycastInfo.SetColliderID(object.EntityId);
const auto& NATIVE_RESULTS = SHPhysicsSystemInterface::Raycast(raycastInfo);
if (!NATIVE_RESULTS.empty())
{
for (const auto& nativeResult : NATIVE_RESULTS)
results->Add(Convert::ToCLI(nativeResult));
}
return results;
} }
RaycastHit Physics::ColliderLineCast(GameObject object, int shapeIndex, Vector3 start, Vector3 end) List<RaycastHit>^ Physics::ColliderLineCast(GameObject object, int shapeIndex, Vector3 start, Vector3 end, bool continuous)
{ {
return RaycastHit{}; List<RaycastHit>^ results = gcnew List<RaycastHit>();
// Get the collider's position
Vector3 shapePos = Vector3::Zero;
Collider^ managedCollider = object.GetComponent<Collider^>();
if (!managedCollider)
throw gcnew System::InvalidOperationException("Attempted to retrieve invalid Collider.");
CollisionShape^ managedShape = managedCollider->GetCollisionShape(shapeIndex);
if (!managedShape)
throw gcnew System::InvalidOperationException("Attempted to retrieve invalid CollisionShape.");
const auto& NATIVE_SHAPE = managedShape->getNativeCollisionShape();
switch (NATIVE_SHAPE.GetType())
{
case SHCollisionShape::Type::SPHERE:
{
shapePos = Convert::ToCLI(dynamic_cast<const SHSphereCollisionShape&>(NATIVE_SHAPE).GetCenter());
break;
}
case SHCollisionShape::Type::BOX:
{
shapePos = Convert::ToCLI(dynamic_cast<const SHBoxCollisionShape&>(NATIVE_SHAPE).GetCenter());
break;
}
default: break;
}
start += shapePos;
Vector3 direction = end - start;
direction.Normalise();
const Ray CLI_RAY( start, direction );
SHCollisionSpace::RaycastInfo raycastInfo;
raycastInfo.ray = Convert::ToNative(CLI_RAY);
raycastInfo.continuous = continuous;
raycastInfo.distance = (end - start).GetMagnitude();
raycastInfo.SetColliderID(object.EntityId);
const auto& NATIVE_RESULTS = SHPhysicsSystemInterface::Raycast(raycastInfo);
if (!NATIVE_RESULTS.empty())
{
for (const auto& nativeResult : NATIVE_RESULTS)
results->Add(Convert::ToCLI(nativeResult));
}
return results;
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/

View File

@ -10,6 +10,7 @@
#pragma once #pragma once
// Project Includes // Project Includes
#include "Math/Ray.hxx" #include "Math/Ray.hxx"
#include "RaycastHit.hxx" #include "RaycastHit.hxx"
@ -39,83 +40,146 @@ namespace SHADE
/* Raycast Function Members */ /* Raycast Function Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
// TODO(Diren): Add layers for raycasting
/// <summary> /// <summary>
/// Casts an infinite ray into the world. /// Casts an infinite ray into the world. <br/>
/// This raycast will stop at the first object hit.
/// </summary> /// </summary>
/// <param name="ray">The ray to cast.</param> /// <param name="ray">The ray to cast.</param>
/// <returns>The result of the raycast.</returns> /// <param name="continuous">
static RaycastHit Raycast (Ray ray); /// Whether or not the raycast should stop at the first object hit.
/// </param>
/// <returns>
/// The results of the raycast. If nothing was hit, an empty list is returned.
/// </returns>
static System::Collections::Generic::List<RaycastHit>^ Raycast (Ray ray, bool continuous);
/// <summary> /// <summary>
/// Casts a ray for a given distance into the world. /// Casts a ray for a given distance into the world.
/// </summary> /// </summary>
/// <param name="ray">The ray to cast.</param> /// <param name="ray">The ray to cast.</param>
/// <param name="distance">The distance to cast the ray.</param> /// <param name="distance">The distance to cast the ray.</param>
/// <returns>The result of the raycast.</returns> /// <param name="continuous">
static RaycastHit Raycast (Ray ray, float distance); /// Whether or not the raycast should stop at the first object hit.
/// </param>
/// <returns>
/// The results of the raycast. If nothing was hit, an empty list is returned.
/// </returns>
static System::Collections::Generic::List<RaycastHit>^ Raycast (Ray ray, float distance, bool continuous);
/// <summary> /// <summary>
/// Casts a bounded ray into the world. /// Casts a bounded ray into the world.
/// </summary> /// </summary>
/// <param name="start">The start of the bounded ray.</param> /// <param name="start">The start of the bounded ray.</param>
/// <param name="end">The end of the bounded ray.</param> /// <param name="end">The end of the bounded ray.</param>
/// <returns>The result of the raycast.</returns> /// <param name="continuous">
static RaycastHit Linecast (Vector3 start, Vector3 end); /// Whether or not the raycast should stop at the first object hit.
/// </param>
/// <returns>
/// The results of the raycast. If nothing was hit, an empty list is returned.
/// </returns>
static System::Collections::Generic::List<RaycastHit>^ Linecast (Vector3 start, Vector3 end, bool continuous);
/// <summary> /// <summary>
/// Casts an infinite ray w.r.t a GameObject. /// Casts an infinite ray w.r.t a GameObject.
/// </summary> /// </summary>
/// <param name="object">The GameObject to cast the ray to.</param> /// <param name="object">The GameObject to cast the ray to.</param>
/// <param name="ray">The ray to cast.</param> /// <param name="ray">
/// <returns>The result of the raycast.</returns> /// The ray to cast. <br/>
static RaycastHit ColliderRaycast (GameObject object, Ray ray); /// The position of the ray is offset from the collider's position.
/// </param>
/// <param name="continuous">
/// Whether or not the raycast should stop at the first object hit.
/// </param>
/// <returns>
/// The results of the raycast. If nothing was hit, an empty list is returned.
/// </returns>
static System::Collections::Generic::List<RaycastHit>^ ColliderRaycast (GameObject object, Ray ray, bool continuous);
/// <summary> /// <summary>
/// Casts a ray for a given distance w.r.t a GameObject. /// Casts a ray for a given distance w.r.t a GameObject.
/// </summary> /// </summary>
/// <param name="object">The GameObject to cast the ray to.</param> /// <param name="object">The GameObject to cast the ray to.</param>
/// <param name="ray">The ray to cast.</param> /// <param name="ray">
/// The ray to cast. <br/>
/// The position of the ray is offset from the collider's position.
/// </param>
/// <param name="distance">The distance to cast the ray.</param> /// <param name="distance">The distance to cast the ray.</param>
/// <returns>The result of the raycast.</returns> /// <param name="continuous">
static RaycastHit ColliderRaycast (GameObject object, Ray ray, float distance); /// Whether or not the raycast should stop at the first object hit.
/// </param>
/// <returns>
/// The results of the raycast. If nothing was hit, an empty list is returned.
/// </returns>
static System::Collections::Generic::List<RaycastHit>^ ColliderRaycast (GameObject object, Ray ray, float distance, bool continuous);
/// <summary> /// <summary>
/// Casts an infinite ray w.r.t a specific collider on a GameObject. /// Casts an infinite ray w.r.t a specific collider on a GameObject.
/// </summary> /// </summary>
/// <param name="object">The GameObject to cast the ray to.</param> /// <param name="object">The GameObject to cast the ray to.</param>
/// <param name="shapeIndex">The collision shape index on the collider to cast to.</param> /// <param name="shapeIndex">The collision shape index on the collider to cast to.</param>
/// <param name="ray">The ray to cast.</param> /// <param name="ray">
/// <returns>The result of the raycast.</returns> /// The ray to cast. <br/>
static RaycastHit ColliderRaycast (GameObject object, int shapeIndex, Ray ray); /// The position of the ray is offset from the collider's position.
/// </param>
/// <param name="continuous">
/// Whether or not the raycast should stop at the first object hit.
/// </param>
/// <returns>
/// The results of the raycast. If nothing was hit, an empty list is returned.
/// </returns>
static System::Collections::Generic::List<RaycastHit>^ ColliderRaycast (GameObject object, int shapeIndex, Ray ray, bool continuous);
/// <summary> /// <summary>
/// Casts a ray for a given distance w.r.t a specific collider on a GameObject. /// Casts a ray for a given distance w.r.t a specific collider on a GameObject.
/// </summary> /// </summary>
/// <param name="object">The GameObject to cast the ray to.</param> /// <param name="object">The GameObject to cast the ray to.</param>
/// <param name="shapeIndex">The collision shape index on the collider to cast to.</param> /// <param name="shapeIndex">The collision shape index on the collider to cast to.</param>
/// <param name="ray">The ray to cast.</param> /// <param name="ray">
/// The ray to cast. <br/>
/// The position of the ray is offset from the collider's position.
/// </param>
/// <param name="distance">The distance to cast the ray.</param> /// <param name="distance">The distance to cast the ray.</param>
/// <returns>The result of the raycast.</returns> /// <param name="continuous">
static RaycastHit ColliderRaycast (GameObject object, int shapeIndex, Ray ray, float distance); /// Whether or not the raycast should stop at the first object hit.
/// </param>
/// <returns>
/// The results of the raycast. If nothing was hit, an empty list is returned.
/// </returns>
static System::Collections::Generic::List<RaycastHit>^ ColliderRaycast (GameObject object, int shapeIndex, Ray ray, float distance, bool continuous);
/// <summary> /// <summary>
/// Casts a bounded ray w.r.t a GameObject. /// Casts a bounded ray w.r.t a GameObject.
/// </summary> /// </summary>
/// <param name="object">The GameObject to cast the ray to.</param> /// <param name="object">The GameObject to cast the ray to.</param>
/// <param name="start">The start of the bounded ray.</param> /// <param name="start">
/// The start of the bounded ray. <br/>
/// The start of the ray is offset from the collider's position. </param>
/// <param name="end"></param> /// <param name="end"></param>
/// <returns>The result of the raycast.</returns> /// <param name="continuous">
static RaycastHit ColliderLineCast (GameObject object, Vector3 start, Vector3 end); /// Whether or not the raycast should stop at the first object hit.
/// </param>
/// <returns>
/// The results of the raycast. If nothing was hit, an empty list is returned.
/// </returns>
static System::Collections::Generic::List<RaycastHit>^ ColliderLineCast (GameObject object, Vector3 start, Vector3 end, bool continuous);
/// <summary> /// <summary>
/// Casts a bounded ray w.r.t a specific collider on a GameObject. /// Casts a bounded ray w.r.t a specific collider on a GameObject.
/// </summary> /// </summary>
/// <param name="object">The GameObject to cast the ray to.</param> /// <param name="object">The GameObject to cast the ray to.</param>
/// <param name="shapeIndex">The collision shape index on the collider to cast to.</param> /// <param name="shapeIndex">The collision shape index on the collider to cast to.</param>
/// <param name="start">The start of the bounded ray.</param> /// <param name="start">
/// The start of the bounded ray. <br/>
/// The start of the ray is offset from the collider's position. </param>
/// <param name="end">The end of the bounded ray.</param> /// <param name="end">The end of the bounded ray.</param>
/// <returns>The result of the raycast.</returns> /// <param name="continuous">
static RaycastHit ColliderLineCast (GameObject object, int shapeIndex, Vector3 start, Vector3 end); /// Whether or not the raycast should stop at the first object hit.
/// </param>
/// <returns>
/// The results of the raycast. If nothing was hit, an empty list is returned./// </returns>
static System::Collections::Generic::List<RaycastHit>^ ColliderLineCast (GameObject object, int shapeIndex, Vector3 start, Vector3 end, bool continuous);
private: private:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -103,6 +103,39 @@ namespace SHADE
/* Physics Conversions */ /* Physics Conversions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHPhysicsRaycastResult Convert::ToNative(RaycastHit cli)
{
// This function shouldn't be used anyway, so we leave the entityHit empty.
SHPhysicsRaycastResult native;
native.hit = cli.Hit;
native.position = ToNative(cli.Position);
native.normal = ToNative(cli.Normal);
native.distance = cli.Distance;
native.shapeIndex = cli.CollisionShapeIndex;
return native;
}
RaycastHit Convert::ToCLI(const SHPhysicsRaycastResult& native)
{
RaycastHit cli;
cli.Hit = native.hit;
cli.Position = ToCLI(native.position);
cli.Normal = ToCLI(native.normal);
cli.Distance = native.distance;
cli.CollisionShapeIndex = native.shapeIndex;
cli.Other = SHEntityManager::IsValidEID(native.entityHit)
? GameObject(native.entityHit)
: System::Nullable<GameObject>();
return cli;
}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Handle Conversions */ /* Handle Conversions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -141,6 +141,20 @@ namespace SHADE
/* Physics Conversions */ /* Physics Conversions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/// <summary>
/// Converts from a managed RaycastHit to a native SHPhysicsRaycastResult
/// </summary>
/// <param name="cli">The managed RaycastHit to convert from.</param>
/// <returns>Native copy of a managed RaycastHit.</returns>
static SHPhysicsRaycastResult ToNative(RaycastHit cli);
/// <summary>
/// Converts from a native SHPhysicsRaycastResult to a managed RaycastHit
/// </summary>
/// <param name="cli">The native SHPhysicsRaycastResult to convert from.</param>
/// <returns>Managed copy of a native SHPhysicsRaycastResult.</returns>
static RaycastHit ToCLI(const SHPhysicsRaycastResult& native);
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Handle Conversions */ /* Handle Conversions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/