Implemented a custom physics engine #316
|
@ -66,7 +66,7 @@
|
|||
NumberOfChildren: 0
|
||||
Components:
|
||||
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}
|
||||
Scale: {x: 1, y: 1, z: 1}
|
||||
IsActive: true
|
||||
|
|
|
@ -84,9 +84,27 @@ namespace SHADE
|
|||
|
||||
// Sphere VS Convex
|
||||
|
||||
static FaceQuery findClosestFace (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;
|
||||
static FaceQuery findClosestFace
|
||||
(
|
||||
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
|
||||
|
||||
|
|
|
@ -185,7 +185,11 @@ namespace SHADE
|
|||
/* 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;
|
||||
|
||||
|
@ -227,7 +231,12 @@ namespace SHADE
|
|||
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
|
||||
int32_t closestPointIndex = -1;
|
||||
|
@ -253,7 +262,14 @@ namespace SHADE
|
|||
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;
|
||||
|
||||
|
|
|
@ -160,44 +160,53 @@ namespace SHADE
|
|||
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())
|
||||
return raycastHits;
|
||||
return results;
|
||||
|
||||
// Test potential hits individually
|
||||
// Cull entities that are on different layers
|
||||
for (auto& shapeID : POTENTIAL_HITS)
|
||||
// Iterate through all potential hits
|
||||
const int NUM_HITS = static_cast<int>(POTENTIAL_HITS.size());
|
||||
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
|
||||
const EntityID EID = shapeID.GetEntityID();
|
||||
const uint32_t IDX = shapeID.GetShapeIndex();
|
||||
const uint32_t IDX = HIT_ID.GetShapeIndex();
|
||||
const auto* SHAPE = colliders.find(EID)->second->GetCollisionShape(IDX);
|
||||
|
||||
const auto* COLLIDER = colliders.find(EID)->second;
|
||||
const auto* SHAPE = COLLIDER->GetCollisionShape(IDX);
|
||||
|
||||
// Cull by layer
|
||||
const bool LAYER_MATCH = SHAPE->GetCollisionTag().GetMask() & layer;
|
||||
// Filter the layers
|
||||
const bool LAYER_MATCH = SHAPE->GetCollisionTag().GetMask() & info.layers;
|
||||
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
|
||||
// We cast to the underlying shape. THis is done because a convex hull will not have an inherited raycast method.
|
||||
// Kinda awkward oversight...oops
|
||||
|
||||
SHRaycastResult result;
|
||||
SHRaycastResult baseResult;
|
||||
switch (SHAPE->GetType())
|
||||
{
|
||||
case SHCollisionShape::Type::SPHERE:
|
||||
{
|
||||
result = dynamic_cast<const SHSphereCollisionShape*>(SHAPE)->Raycast(ray);
|
||||
baseResult = dynamic_cast<const SHSphereCollisionShape*>(SHAPE)->Raycast(info.ray);
|
||||
break;
|
||||
}
|
||||
case SHCollisionShape::Type::BOX:
|
||||
{
|
||||
result = dynamic_cast<const SHBoxCollisionShape*>(SHAPE)->Raycast(ray);
|
||||
baseResult = dynamic_cast<const SHBoxCollisionShape*>(SHAPE)->Raycast(info.ray);
|
||||
break;
|
||||
}
|
||||
case SHCollisionShape::Type::CAPSULE:
|
||||
|
@ -205,118 +214,25 @@ namespace SHADE
|
|||
// TODO
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
default: continue; // Redundant case
|
||||
}
|
||||
|
||||
// If distance is greater than specified, skip this result
|
||||
if (!result || result.distance > distance)
|
||||
if (!baseResult || baseResult.distance > info.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;
|
||||
// Copy to a physics raycast result
|
||||
SHPhysicsRaycastResult result;
|
||||
memcpy_s(&result, sizeof(SHRaycastResult), &baseResult, sizeof(SHRaycastResult));
|
||||
|
||||
raycastHits.emplace_back(physicsResult);
|
||||
result.entityHit = EID;
|
||||
result.shapeIndex = IDX;
|
||||
|
||||
results.emplace_back(result);
|
||||
}
|
||||
|
||||
// Sort by distance
|
||||
std::ranges::sort(raycastHits.begin(), raycastHits.end(), [](const SHPhysicsRaycastResult& lhs, const SHPhysicsRaycastResult& rhs)
|
||||
{
|
||||
return lhs.distance < rhs.distance;
|
||||
});
|
||||
|
||||
return raycastHits;
|
||||
return results;
|
||||
}
|
||||
|
||||
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 */
|
||||
|
|
|
@ -13,12 +13,15 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
|
||||
// Project Headers
|
||||
#include "Broadphase/SHDynamicAABBTree.h"
|
||||
#include "Physics/Dynamics/SHContactManager.h"
|
||||
#include "SHCollider.h"
|
||||
#include "SHPhysicsRaycastResult.h"
|
||||
#include "CollisionTags/SHCollisionTags.h"
|
||||
#include "CollisionTags/SHCollisionTags.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -38,7 +41,52 @@ namespace SHADE
|
|||
/* 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 */
|
||||
|
@ -98,68 +146,13 @@ namespace SHADE
|
|||
/**
|
||||
* @brief
|
||||
* Casts a ray into the collision space.
|
||||
* @param ray
|
||||
* The ray to cast. 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.
|
||||
* @param info
|
||||
* Contains the information for the raycast.
|
||||
* @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.
|
||||
* A container of the objects hit by the ray. If nothing was hit, the container
|
||||
* will be empty.
|
||||
*/
|
||||
[[nodiscard]] const RaycastHits& Raycast
|
||||
(
|
||||
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;
|
||||
[[nodiscard]] const RaycastResults& Raycast(const RaycastInfo& info) noexcept;
|
||||
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -184,12 +177,8 @@ namespace SHADE
|
|||
Colliders colliders;
|
||||
NarrowphaseBatch narrowphaseBatch;
|
||||
|
||||
RaycastHits raycastHits; // Reusable container for raycast results
|
||||
|
||||
SHAABBTree broadphase;
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Member Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -202,7 +191,6 @@ namespace SHADE
|
|||
|
||||
void collideTriggers (const SHCollisionKey& key, NarrowphasePair& narrowphasePair) const noexcept;
|
||||
void collideManifolds (const SHCollisionKey& key, NarrowphasePair& narrowphasePair) const noexcept;
|
||||
|
||||
};
|
||||
|
||||
} // namespace SHADE
|
|
@ -19,6 +19,7 @@
|
|||
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "Editor/SHEditor.h"
|
||||
#include "Physics/Collision/SHCollisionSpace.h"
|
||||
#include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h"
|
||||
#include "Physics/Interface/SHColliderComponent.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 */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -76,8 +76,25 @@ namespace SHADE
|
|||
*/
|
||||
void Init() 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();
|
||||
|
||||
/**
|
||||
* @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 */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -129,6 +146,12 @@ namespace SHADE
|
|||
|
||||
using EventFunctionPair = std::pair<SHEventHandle(SHPhysicsSystem::*)(SHEventPtr), SHEventIdentifier>;
|
||||
|
||||
struct RaycastHit
|
||||
{
|
||||
SHVec3 start;
|
||||
SHVec3 end;
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -149,6 +172,11 @@ namespace SHADE
|
|||
SHCollisionSpace* collisionSpace;
|
||||
SHPhysicsObjectManager physicsObjectManager;
|
||||
|
||||
// For the debug drawer to draw rays
|
||||
#ifdef SHEDITOR
|
||||
std::vector<RaycastHit> raycastHits;
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Function Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -67,4 +67,16 @@ namespace SHADE
|
|||
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
|
||||
#include "ECS_Base/Entity/SHEntity.h"
|
||||
#include "Physics/Collision/SHCollisionSpace.h"
|
||||
#include "Physics/Collision/Contacts/SHCollisionEvents.h"
|
||||
|
||||
|
||||
|
@ -26,6 +27,7 @@ namespace SHADE
|
|||
class SHVec3;
|
||||
struct SHRay;
|
||||
struct SHPhysicsRaycastResult;
|
||||
struct SHCollisionSpace::RaycastInfo;
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -51,5 +53,8 @@ namespace SHADE
|
|||
[[nodiscard]] static const std::vector<SHTriggerEvent>& GetTriggerInfo () noexcept;
|
||||
[[nodiscard]] static double GetFixedDT () 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()
|
||||
{
|
||||
//return Convert::ToCLI(getNativeCollisionShape<SHAABB>().GetCenter());
|
||||
return Vector3::Zero;
|
||||
}
|
||||
void BoxCollider::Center::set(Vector3 value)
|
||||
{
|
||||
//getNativeCollisionShape<SHAABB>().SetCenter(Convert::ToNative(value));
|
||||
return Convert::ToCLI(getNativeCollisionShape<SHBoxCollisionShape>().GetCenter());
|
||||
}
|
||||
Vector3 BoxCollider::HalfExtents::get()
|
||||
{
|
||||
//return Convert::ToCLI(getNativeCollisionShape<SHAABB>().GetExtents());
|
||||
return Vector3::Zero;
|
||||
return Convert::ToCLI(getNativeCollisionShape<SHBoxCollisionShape>().GetWorldExtents());
|
||||
}
|
||||
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 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));
|
||||
return Convert::ToCLI(getNativeCollisionShape<SHBoxCollisionShape>().GetOrientation());
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -184,10 +164,6 @@ namespace SHADE
|
|||
{
|
||||
return Convert::ToCLI(getNativeCollisionShape<SHSphereCollisionShape>().GetCenter());
|
||||
}
|
||||
void SphereCollider::Center::set(Vector3 value)
|
||||
{
|
||||
getNativeCollisionShape<SHSphereCollisionShape>().SetCenter(Convert::ToNative(value));
|
||||
}
|
||||
float SphereCollider::Radius::get()
|
||||
{
|
||||
return getNativeCollisionShape<SHSphereCollisionShape>().GetWorldRadius();
|
||||
|
|
|
@ -142,15 +142,14 @@ namespace SHADE
|
|||
/* Properties */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Center of the Bounding Box formed by this bound.
|
||||
/// Center of the box collider.
|
||||
/// </summary>
|
||||
property Vector3 Center
|
||||
{
|
||||
Vector3 get();
|
||||
void set(Vector3 value);
|
||||
}
|
||||
/// <summary>
|
||||
/// Half of the scale of the Bounding Box formed by this bound.
|
||||
/// Half of the scale of the box collider.
|
||||
/// </summary>
|
||||
property Vector3 HalfExtents
|
||||
{
|
||||
|
@ -158,22 +157,11 @@ namespace SHADE
|
|||
void set(Vector3 value);
|
||||
}
|
||||
/// <summary>
|
||||
/// Position of the bottom left back corner of the Bounding Box formed by this
|
||||
/// bound.
|
||||
/// The orientation of the box.
|
||||
/// </summary>
|
||||
property Vector3 Min
|
||||
property Quaternion Orientation
|
||||
{
|
||||
Vector3 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);
|
||||
Quaternion get();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
@ -201,12 +189,11 @@ namespace SHADE
|
|||
/* Properties */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Center of the Bounding Sphere formed by this bound.
|
||||
/// Center of the sphere.
|
||||
/// </summary>
|
||||
property Vector3 Center
|
||||
{
|
||||
Vector3 get();
|
||||
void set(Vector3 value);
|
||||
}
|
||||
/// <summary>
|
||||
/// Radius of the Bounding Sphere formed by this bound.
|
||||
|
|
|
@ -15,10 +15,15 @@
|
|||
// External Dependencies
|
||||
#include "Physics/System/SHPhysicsSystemInterface.h"
|
||||
// Project Header
|
||||
#include "Components/Collider.hxx"
|
||||
#include "Components/Transform.hxx"
|
||||
#include "Engine/GameObject.hxx"
|
||||
#include "Physics/Collision/SHCollisionSpace.h"
|
||||
#include "Utility/Convert.hxx"
|
||||
#include "Utility/Debug.hxx"
|
||||
|
||||
using namespace System::Collections::Generic;
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -41,49 +46,301 @@ namespace SHADE
|
|||
/* 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));
|
||||
}
|
||||
|
||||
RaycastHit Physics::Raycast(Ray ray, float distance)
|
||||
{
|
||||
return RaycastHit{};
|
||||
return results;
|
||||
}
|
||||
|
||||
RaycastHit Physics::Linecast(Vector3 start, Vector3 end)
|
||||
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));
|
||||
}
|
||||
|
||||
RaycastHit Physics::ColliderRaycast(GameObject object, Ray ray)
|
||||
{
|
||||
return RaycastHit{};
|
||||
return results;
|
||||
}
|
||||
|
||||
RaycastHit Physics::ColliderRaycast(GameObject object, Ray ray, float distance)
|
||||
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));
|
||||
}
|
||||
|
||||
RaycastHit Physics::ColliderRaycast(GameObject object, int shapeIndex, Ray ray)
|
||||
{
|
||||
return RaycastHit{};
|
||||
return results;
|
||||
}
|
||||
|
||||
RaycastHit Physics::ColliderRaycast(GameObject object, int shapeIndex, Ray ray, float distance)
|
||||
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));
|
||||
}
|
||||
|
||||
RaycastHit Physics::ColliderLineCast(GameObject object, Vector3 start, Vector3 end)
|
||||
{
|
||||
return RaycastHit{};
|
||||
return results;
|
||||
}
|
||||
|
||||
RaycastHit Physics::ColliderLineCast(GameObject object, int shapeIndex, Vector3 start, Vector3 end)
|
||||
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;
|
||||
}
|
||||
|
||||
List<RaycastHit>^ Physics::ColliderRaycast(GameObject object, int shapeIndex, Ray ray, bool continuous)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
List<RaycastHit>^ Physics::ColliderRaycast(GameObject object, int shapeIndex, Ray ray, float distance, bool continuous)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
List<RaycastHit>^ Physics::ColliderLineCast(GameObject object, Vector3 start, Vector3 end, bool continuous)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
List<RaycastHit>^ Physics::ColliderLineCast(GameObject object, int shapeIndex, Vector3 start, Vector3 end, bool continuous)
|
||||
{
|
||||
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
|
||||
|
||||
|
||||
// Project Includes
|
||||
#include "Math/Ray.hxx"
|
||||
#include "RaycastHit.hxx"
|
||||
|
@ -39,83 +40,146 @@ namespace SHADE
|
|||
/* Raycast Function Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
// TODO(Diren): Add layers for raycasting
|
||||
|
||||
/// <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>
|
||||
/// <param name="ray">The ray to cast.</param>
|
||||
/// <returns>The result of the raycast.</returns>
|
||||
static RaycastHit Raycast (Ray ray);
|
||||
/// <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>^ Raycast (Ray ray, bool continuous);
|
||||
|
||||
/// <summary>
|
||||
/// Casts a ray for a given distance into the world.
|
||||
/// </summary>
|
||||
/// <param name="ray">The ray to cast.</param>
|
||||
/// <param name="distance">The distance to cast the ray.</param>
|
||||
/// <returns>The result of the raycast.</returns>
|
||||
static RaycastHit Raycast (Ray ray, float distance);
|
||||
/// <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>^ Raycast (Ray ray, float distance, bool continuous);
|
||||
|
||||
/// <summary>
|
||||
/// Casts a bounded ray into the world.
|
||||
/// </summary>
|
||||
/// <param name="start">The start of the bounded ray.</param>
|
||||
/// <param name="end">The end of the bounded ray.</param>
|
||||
/// <returns>The result of the raycast.</returns>
|
||||
static RaycastHit Linecast (Vector3 start, Vector3 end);
|
||||
/// <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>^ Linecast (Vector3 start, Vector3 end, bool continuous);
|
||||
|
||||
/// <summary>
|
||||
/// Casts an infinite ray w.r.t a GameObject.
|
||||
/// </summary>
|
||||
/// <param name="object">The GameObject to cast the ray to.</param>
|
||||
/// <param name="ray">The ray to cast.</param>
|
||||
/// <returns>The result of the raycast.</returns>
|
||||
static RaycastHit ColliderRaycast (GameObject object, Ray ray);
|
||||
/// <param name="ray">
|
||||
/// The ray to cast. <br/>
|
||||
/// 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>
|
||||
/// Casts a ray for a given distance w.r.t a GameObject.
|
||||
/// </summary>
|
||||
/// <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>
|
||||
/// <returns>The result of the raycast.</returns>
|
||||
static RaycastHit ColliderRaycast (GameObject object, Ray ray, float distance);
|
||||
/// <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, float distance, bool continuous);
|
||||
|
||||
/// <summary>
|
||||
/// Casts an infinite ray w.r.t a specific collider on a GameObject.
|
||||
/// </summary>
|
||||
/// <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="ray">The ray to cast.</param>
|
||||
/// <returns>The result of the raycast.</returns>
|
||||
static RaycastHit ColliderRaycast (GameObject object, int shapeIndex, Ray ray);
|
||||
/// <param name="ray">
|
||||
/// The ray to cast. <br/>
|
||||
/// 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>
|
||||
/// Casts a ray for a given distance w.r.t a specific collider on a GameObject.
|
||||
/// </summary>
|
||||
/// <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="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>
|
||||
/// <returns>The result of the raycast.</returns>
|
||||
static RaycastHit ColliderRaycast (GameObject object, int shapeIndex, Ray ray, float distance);
|
||||
/// <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, float distance, bool continuous);
|
||||
|
||||
/// <summary>
|
||||
/// Casts a bounded ray w.r.t a GameObject.
|
||||
/// </summary>
|
||||
/// <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>
|
||||
/// <returns>The result of the raycast.</returns>
|
||||
static RaycastHit ColliderLineCast (GameObject object, Vector3 start, Vector3 end);
|
||||
/// <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>^ ColliderLineCast (GameObject object, Vector3 start, Vector3 end, bool continuous);
|
||||
|
||||
/// <summary>
|
||||
/// Casts a bounded ray w.r.t a specific collider on a GameObject.
|
||||
/// </summary>
|
||||
/// <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="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>
|
||||
/// <returns>The result of the raycast.</returns>
|
||||
static RaycastHit ColliderLineCast (GameObject object, int shapeIndex, Vector3 start, Vector3 end);
|
||||
/// <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>^ ColliderLineCast (GameObject object, int shapeIndex, Vector3 start, Vector3 end, bool continuous);
|
||||
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -103,6 +103,39 @@ namespace SHADE
|
|||
/* 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 */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -141,6 +141,20 @@ namespace SHADE
|
|||
/* 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 */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
|
Loading…
Reference in New Issue