Implemented a custom physics engine #316
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
|
@ -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 */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -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 */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -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:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -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 */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -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 */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
|
Loading…
Reference in New Issue