Cleaned up colliders

This commit is contained in:
Diren D Bharwani 2023-01-04 19:45:41 +08:00
parent dd2fc934a2
commit dffdec9d9c
49 changed files with 697 additions and 619 deletions

View File

@ -21,6 +21,7 @@
#include "Serialization/SHSerializationHelper.hpp" #include "Serialization/SHSerializationHelper.hpp"
#include "Tools/Utilities/SHClipboardUtilities.h" #include "Tools/Utilities/SHClipboardUtilities.h"
#include "SHInspectorCommands.h" #include "SHInspectorCommands.h"
#include "Physics/Collision/SHCompositeCollider.h"
#include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h" #include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h"
namespace SHADE namespace SHADE
{ {
@ -420,17 +421,20 @@ namespace SHADE
} }
ImGui::EndChild(); ImGui::EndChild();
// TODO: Handle differences between composite & hull collider
if (ImGui::BeginMenu("Add Collider")) if (ImGui::BeginMenu("Add Collider"))
{ {
int newColl = -1; int newColl = -1;
if (ImGui::Selectable("Box Collider")) if (ImGui::Selectable("Box Collider"))
{ {
component->GetCollider()->AddBoxCollisionShape(SHVec3::One); auto* compositeCollider = dynamic_cast<SHCompositeCollider* const>(component->GetCollider());
compositeCollider->AddBoxCollisionShape(SHVec3::One);
} }
if (ImGui::Selectable("Sphere Collider")) if (ImGui::Selectable("Sphere Collider"))
{ {
component->GetCollider()->AddSphereCollisionShape(1.0f); auto* compositeCollider = dynamic_cast<SHCompositeCollider* const>(component->GetCollider());
compositeCollider->AddSphereCollisionShape(1.0f);
} }
//No idea why this doesn't work //No idea why this doesn't work

View File

@ -13,7 +13,7 @@
#include <DirectXCollision.h> #include <DirectXCollision.h>
// Project Headers // Project Headers
#include "SHShape.h" #include "Math/SHRay.h"
namespace SHADE namespace SHADE
{ {
@ -25,8 +25,7 @@ namespace SHADE
* @brief * @brief
* Encapsulates a 3D Axis-Aligned Bounding Box. * Encapsulates a 3D Axis-Aligned Bounding Box.
*/ */
class SH_API SHAABB : public SHShape, class SH_API SHAABB : private DirectX::BoundingBox
private DirectX::BoundingBox
{ {
public: public:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -39,7 +38,7 @@ namespace SHADE
/* Constructors & Destructor */ /* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
~SHAABB () override = default; ~SHAABB () noexcept = default;
SHAABB () noexcept; SHAABB () noexcept;
SHAABB (const SHVec3& center, const SHVec3& halfExtents) noexcept; SHAABB (const SHVec3& center, const SHVec3& halfExtents) noexcept;
@ -85,7 +84,7 @@ namespace SHADE
* @return * @return
* True if the point is inside the aabb. * True if the point is inside the aabb.
*/ */
[[nodiscard]] bool TestPoint (const SHVec3& point) const noexcept override; [[nodiscard]] bool TestPoint (const SHVec3& point) const noexcept;
/** /**
* @brief * @brief
@ -96,7 +95,7 @@ namespace SHADE
* The result of the raycast. <br/> * The result of the raycast. <br/>
* See the corresponding header for the contents of the raycast result object. * See the corresponding header for the contents of the raycast result object.
*/ */
[[nodiscard]] SHRaycastResult Raycast (const SHRay& ray) const noexcept override; [[nodiscard]] SHRaycastResult Raycast (const SHRay& ray) const noexcept;
/** /**
* @brief * @brief

View File

@ -11,7 +11,7 @@
#pragma once #pragma once
// Project Headers // Project Headers
#include "SHShape.h" #include "Math/SHRay.h"
#include "Math/Vector/SHVec4.h" #include "Math/Vector/SHVec4.h"
namespace SHADE namespace SHADE
@ -24,14 +24,14 @@ namespace SHADE
* @brief * @brief
* Encapsulates a 3D plane in point-normal form. * Encapsulates a 3D plane in point-normal form.
*/ */
class SH_API SHPlane : public SHShape class SH_API SHPlane
{ {
public: public:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */ /* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
~SHPlane () override = default; ~SHPlane () noexcept = default;
SHPlane (const SHPlane& rhs) noexcept = default; SHPlane (const SHPlane& rhs) noexcept = default;
SHPlane (SHPlane&& rhs) noexcept = default; SHPlane (SHPlane&& rhs) noexcept = default;
@ -77,7 +77,7 @@ namespace SHADE
* @return * @return
* True if the point is on the plane. * True if the point is on the plane.
*/ */
[[nodiscard]] bool TestPoint (const SHVec3& point) const noexcept override; [[nodiscard]] bool TestPoint (const SHVec3& point) const noexcept;
/** /**
* @brief * @brief
@ -88,7 +88,7 @@ namespace SHADE
* The result of the raycast. <br/> * The result of the raycast. <br/>
* See the corresponding header for the contents of the raycast result object. * See the corresponding header for the contents of the raycast result object.
*/ */
[[nodiscard]] SHRaycastResult Raycast (const SHRay& ray) const noexcept override; [[nodiscard]] SHRaycastResult Raycast (const SHRay& ray) const noexcept;
/** /**
* @brief * @brief

View File

@ -1,42 +0,0 @@
/****************************************************************************************
* \file SHShape.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for a shape.
*
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
* disclosure of this file or its contents without the prior written consent
* of DigiPen Institute of Technology is prohibited.
****************************************************************************************/
#pragma once
// Project Headers
#include "Math/SHRay.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
/**
* @brief
* Encapsulates a base class for any shape.
*/
class SH_API SHShape
{
public:
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
virtual ~SHShape () = default;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] virtual bool TestPoint (const SHVec3& point) const noexcept = 0;
[[nodiscard]] virtual SHRaycastResult Raycast (const SHRay& ray) const noexcept = 0;
};
} // namespace SHADE

View File

@ -13,7 +13,7 @@
#include <unordered_map> #include <unordered_map>
// Project Headers // Project Headers
#include "Physics/Collision/CollisionShapes/SHCollisionShape.h" #include "Physics/Collision/Shapes/SHCollisionShape.h"
namespace SHADE namespace SHADE
{ {

View File

@ -14,7 +14,7 @@
#include "SHCollisionKey.h" #include "SHCollisionKey.h"
// Project Headers // Project Headers
#include "Physics/Collision/SHCompositeCollider.h" #include "Physics/Collision/SHCollider.h"
#include "Physics/Interface/SHColliderComponent.h" #include "Physics/Interface/SHColliderComponent.h"

View File

@ -12,7 +12,7 @@
// Primary Header // Primary Header
#include "Physics/Dynamics/SHRigidBody.h" #include "Physics/Dynamics/SHRigidBody.h"
#include "Physics/Collision/CollisionShapes/SHCollisionShape.h" #include "Physics/Collision/Shapes/SHCollisionShape.h"
namespace SHADE namespace SHADE
{ {

View File

@ -12,7 +12,7 @@
// Primary Header // Primary Header
#include "Physics/Dynamics/SHRigidBody.h" #include "Physics/Dynamics/SHRigidBody.h"
#include "Physics/Collision/CollisionShapes/SHCollisionShape.h" #include "Physics/Collision/Shapes/SHCollisionShape.h"
#include "SHContact.h" #include "SHContact.h"
#include "SHCollisionEvents.h" #include "SHCollisionEvents.h"

View File

@ -16,7 +16,7 @@
// Project Headers // Project Headers
#include "Math/SHMathHelpers.h" #include "Math/SHMathHelpers.h"
#include "Physics/Collision/CollisionShapes/SHBox.h" #include "Physics/Collision/Shapes/SHConvexPolyhedron.h"
// TODO // TODO

View File

@ -11,7 +11,6 @@
#pragma once #pragma once
// Project Headers // Project Headers
#include "Physics/Collision/CollisionShapes/SHCollisionShape.h"
#include "Physics/Collision/Contacts/SHManifold.h" #include "Physics/Collision/Contacts/SHManifold.h"
#include "Physics/Collision/Contacts/SHCollisionKey.h" #include "Physics/Collision/Contacts/SHCollisionKey.h"

View File

@ -15,6 +15,8 @@
// Project Headers // Project Headers
#include "Math/SHMathHelpers.h" #include "Math/SHMathHelpers.h"
#include "Physics/Collision/Shapes/SHConvexPolyhedron.h"
namespace SHADE namespace SHADE
{ {

View File

@ -15,7 +15,7 @@
// Project Headers // Project Headers
#include "Math/SHMathHelpers.h" #include "Math/SHMathHelpers.h"
#include "Physics/Collision/CollisionShapes/SHSphere.h" #include "Physics/Collision/Shapes/SHSphere.h"
// TODO // TODO

View File

@ -17,8 +17,8 @@
// Project Headers // Project Headers
#include "Math/Geometry/SHPlane.h" #include "Math/Geometry/SHPlane.h"
#include "Math/SHMathHelpers.h" #include "Math/SHMathHelpers.h"
#include "Physics/Collision/CollisionShapes/SHCollisionShape.h" #include "Physics/Collision/Shapes/SHSphere.h"
#include "Physics/Collision/CollisionShapes/SHBox.h" #include "Physics/Collision/Shapes/SHConvexPolyhedron.h"
namespace SHADE namespace SHADE
{ {

View File

@ -15,7 +15,7 @@
// Project Headers // Project Headers
#include "Math/SHMathHelpers.h" #include "Math/SHMathHelpers.h"
#include "Physics/Collision/CollisionShapes/SHSphere.h" #include "Physics/Collision/Shapes/SHSphere.h"
namespace SHADE namespace SHADE
{ {

View File

@ -0,0 +1,393 @@
/****************************************************************************************
* \file SHCollider.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for a Base Collider Class.
*
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
* disclosure of this file or its contents without the prior written consent
* of DigiPen Institute of Technology is prohibited.
****************************************************************************************/
#include <SHpch.h>
// Primary Header
#include "SHCollider.h"
// Project Headers
#include "Broadphase/SHDynamicAABBTree.h"
#include "Events/SHEvent.h"
#include "Math/SHMathHelpers.h"
#include "Physics/SHPhysicsEvents.h"
#include "Physics/Dynamics/SHRigidBody.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHCollider::SHCollider(EntityID eid, const SHTransform& worldTransform) noexcept
: entityID { eid }
, flags { 0 }
, rigidBody { nullptr }
, shapeLibrary { nullptr }
, broadphase { nullptr }
, transform { worldTransform }
{
flags |= ACTIVE_FLAG;
flags |= MOVED_FLAG;
}
SHCollider::SHCollider(const SHCollider& rhs) noexcept
: entityID { rhs.entityID }
, flags { rhs.flags }
, rigidBody { rhs.rigidBody }
, shapeLibrary { rhs.shapeLibrary }
, broadphase { rhs.broadphase }
, transform { rhs.transform }
{}
SHCollider::SHCollider(SHCollider&& rhs) noexcept
: entityID { rhs.entityID }
, flags { rhs.flags }
, rigidBody { rhs.rigidBody }
, shapeLibrary { rhs.shapeLibrary }
, broadphase { rhs.broadphase }
, transform { rhs.transform }
{}
SHCollider::~SHCollider() noexcept
{
if (!shapeLibrary)
{
SHLOGV_ERROR("Shape factory is unlinked with Composite Collider {}. Unable to add destroy collider!", entityID)
return;
}
for (auto* shape : shapes)
shapeLibrary->DestroyShape(shape);
}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/
SHCollider& SHCollider::operator=(const SHCollider& rhs) noexcept
{
if (this == &rhs)
return *this;
if (!shapeLibrary)
{
SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add copy shapes!", entityID)
return *this;
}
entityID = rhs.entityID;
flags = rhs.flags;
rigidBody = rhs.rigidBody;
shapeLibrary = rhs.shapeLibrary;
broadphase = rhs.broadphase;
transform = rhs.transform;
copyShapes(rhs);
return *this;
}
SHCollider& SHCollider::operator=(SHCollider&& rhs) noexcept
{
if (!shapeLibrary)
{
SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add copy shapes!", entityID)
return *this;
}
entityID = rhs.entityID;
flags = rhs.flags;
rigidBody = rhs.rigidBody;
shapeLibrary = rhs.shapeLibrary;
broadphase = rhs.broadphase;
transform = rhs.transform;
copyShapes(rhs);
return *this;
}
/*-----------------------------------------------------------------------------------*/
/* Getter Function Definitions */
/*-----------------------------------------------------------------------------------*/
EntityID SHCollider::GetEntityID() const noexcept
{
return entityID;
}
SHCollider::Type SHCollider::GetType() const noexcept
{
if (flags & COMPOSITE_FLAG)
return Type::COMPOSITE;
if (flags & HULL_FLAG)
return Type::HULL;
return Type::INVALID;
}
bool SHCollider::IsActive() const noexcept
{
return flags & ACTIVE_FLAG;
}
bool SHCollider::GetDebugDrawState() const noexcept
{
return flags & DRAW_FLAG;
}
const SHTransform& SHCollider::GetTransform() const noexcept
{
return transform;
}
const SHVec3& SHCollider::GetPosition() const noexcept
{
return transform.position;
}
const SHQuaternion& SHCollider::GetOrientation() const noexcept
{
return transform.orientation;
}
const SHVec3& SHCollider::GetScale() const noexcept
{
return transform.scale;
}
const SHCollider::CollisionShapes& SHCollider::GetCollisionShapes() const noexcept
{
return shapes;
}
SHCollisionShape* SHCollider::GetCollisionShape(int index) const
{
const int NUM_SHAPES = static_cast<int>(shapes.size());
if (index < 0 || index >= NUM_SHAPES)
throw std::invalid_argument("Out-of-range index!");
return shapes[index];
}
/*-----------------------------------------------------------------------------------*/
/* Setter Function Definitions */
/*-----------------------------------------------------------------------------------*/
void SHCollider::SetType(Type type) noexcept
{
if (type == Type::COMPOSITE)
flags |= COMPOSITE_FLAG;
if (type == Type::HULL)
flags |= HULL_FLAG;
}
void SHCollider::SetIsActive(bool state) noexcept
{
const bool PREV_STATE = flags & ACTIVE_FLAG;
state ? flags |= ACTIVE_FLAG : flags &= ~(ACTIVE_FLAG);
if (!broadphase)
return;
for (auto* shape : shapes)
{
if (PREV_STATE) // Previously inactive
broadphase->Insert(shape->id, shape->ComputeAABB());
else // Previously active
broadphase->Remove(shape->id);
}
}
void SHCollider::SetDebugDrawState(bool state) noexcept
{
state ? flags |= DRAW_FLAG : flags &= ~(DRAW_FLAG);
#ifdef SHEDITOR
// Broadcast event for the Debug Draw system to catch
const SHColliderOnDebugDrawEvent EVENT_DATA
{
.entityID = entityID
, .debugDrawState = state
};
SHEventManager::BroadcastEvent<SHColliderOnDebugDrawEvent>(EVENT_DATA, SH_PHYSICS_COLLIDER_DRAW_EVENT);
#endif
}
void SHCollider::SetRigidBody(SHRigidBody* rb) noexcept
{
rigidBody = rb;
}
void SHCollider::SetTransform(const SHTransform& newTransform) noexcept
{
flags |= MOVED_FLAG;
transform = newTransform;
}
void SHCollider::SetPosition(const SHVec3& newPosition) noexcept
{
flags |= MOVED_FLAG;
transform.position = newPosition;
}
void SHCollider::SetOrientation(const SHQuaternion& newOrientation) noexcept
{
flags |= MOVED_FLAG;
transform.orientation = newOrientation;
}
void SHCollider::SetScale(const SHVec3& newScale) noexcept
{
flags |= MOVED_FLAG;
transform.scale = newScale;
}
void SHCollider::SetLibrary(SHCollisionShapeLibrary* factory) noexcept
{
shapeLibrary = factory;
}
/*-----------------------------------------------------------------------------------*/
/* Public Member Function Definitions */
/*-----------------------------------------------------------------------------------*/
const SHMatrix& SHCollider::ComputeTRS() noexcept
{
return transform.ComputeTRS();
}
void SHCollider::RemoveCollisionShape(int index)
{
if (!shapeLibrary)
{
SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add remove shape!", entityID)
return;
}
const int NUM_SHAPES = static_cast<int>(shapes.size());
if (index < 0 || index >= NUM_SHAPES)
throw std::invalid_argument("Out-of-range index!");
auto shape = shapes.begin();
for (int i = 0; i < NUM_SHAPES; ++i, ++shape)
{
if (i == index)
break;
}
const SHPhysicsColliderRemovedEvent EVENT_DATA
{
.entityID = entityID
, .colliderType = (*shape)->GetType()
, .colliderIndex = index
};
// Remove from broadphase
if (broadphase)
broadphase->Remove((*shape)->id);
shapeLibrary->DestroyShape(*shape);
*shape = nullptr;
// Remove the shape from the container to prevent accessing a nullptr
shape = shapes.erase(shape);
// Broadcast Event for removing a shape
SHEventManager::BroadcastEvent<SHPhysicsColliderRemovedEvent>(EVENT_DATA, SH_PHYSICS_COLLIDER_REMOVED_EVENT);
if (rigidBody)
rigidBody->ComputeMassData();
SHLOG_INFO_D("Removing Collision Shape {} from Entity {}", index, entityID)
}
void SHCollider::Update() noexcept
{
for (auto* shape : shapes)
shape->Update();
}
/*-----------------------------------------------------------------------------------*/
/* Private Member Function Definitions */
/*-----------------------------------------------------------------------------------*/
void SHCollider::copyShapes(const SHCollider& rhsCollider)
{
for (const auto* shape : rhsCollider.shapes)
{
switch (shape->GetType())
{
case SHCollisionShape::Type::BOX:
{
const SHBox* RHS_BOX = dynamic_cast<const SHBox*>(shape);
const SHBoxCreateInfo BOX_CREATE_INFO
{
.Center = RHS_BOX->Center
, .Extents = RHS_BOX->Extents
, .RelativeExtents = RHS_BOX->relativeExtents
, .Orientation = RHS_BOX->Orientation
, .Scale = RHS_BOX->scale
};
const uint32_t NEW_INDEX = static_cast<uint32_t>(shapes.size());
const SHCollisionShapeID NEW_SHAPE_ID{ entityID, NEW_INDEX };
SHBox* box = shapeLibrary->CreateBox(NEW_SHAPE_ID, BOX_CREATE_INFO);
*box = *RHS_BOX;
shapes.emplace_back(box);
break;
}
case SHCollisionShape::Type::SPHERE:
{
const SHSphere* RHS_SPHERE = dynamic_cast<const SHSphere*>(shape);
const SHSphereCreateInfo SPHERE_CREATE_INFO
{
.Center = RHS_SPHERE->Center
, .Radius = RHS_SPHERE->Radius
, .RelativeRadius = RHS_SPHERE->relativeRadius
, .Scale = RHS_SPHERE->scale
};
const uint32_t NEW_INDEX = static_cast<uint32_t>(shapes.size());
const SHCollisionShapeID NEW_SHAPE_ID{ entityID, NEW_INDEX };
SHSphere* sphere = shapeLibrary->CreateSphere(NEW_SHAPE_ID, SPHERE_CREATE_INFO);
*sphere = *RHS_SPHERE;
shapes.emplace_back(sphere);
break;
}
case SHCollisionShape::Type::CAPSULE:
{
break;
}
default: break;
}
}
}
} // namespace SHADE

View File

@ -0,0 +1,178 @@
/****************************************************************************************
* \file SHCollider.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for a Base Collider Class.
*
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
* disclosure of this file or its contents without the prior written consent
* of DigiPen Institute of Technology is prohibited.
****************************************************************************************/
#pragma once
// Project Headers
#include "ECS_Base/Entity/SHEntity.h"
#include "Math/Transform/SHTransform.h"
#include "Physics/Collision/Shapes/SHCollisionShapeLibrary.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
class SHRigidBody;
class SHAABBTree;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
/**
* @brief
* Base class for a collider.
* There are only two collider types supported by SHADE Engine: Composite & Hull
*/
class SH_API SHCollider
{
private:
/*---------------------------------------------------------------------------------*/
/* Friends */
/*---------------------------------------------------------------------------------*/
friend class SHCollisionSpace;
friend struct SHManifold;
public:
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
/*---------------------------------------------------------------------------------*/
enum class Type
{
COMPOSITE
, HULL
, TOTAL
, INVALID = -1
};
using CollisionShapes = std::vector<SHCollisionShape*>;
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
/**
* @brief
* Constructor for a collider.
* @param eid
* The entity this collider belongs to.
* @param worldTransform
* The world transform for the collider. Defaults to the identity transform.
* This is particularly important for composite colliders for offsets & relative sizes.
* @return
*/
SHCollider (EntityID eid, const SHTransform& worldTransform = SHTransform::Identity) noexcept;
SHCollider (const SHCollider& rhs) noexcept;
SHCollider (SHCollider&& rhs) noexcept;
virtual ~SHCollider () noexcept;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
/*---------------------------------------------------------------------------------*/
SHCollider& operator=(const SHCollider& rhs) noexcept;
SHCollider& operator=(SHCollider&& rhs) noexcept;
/*---------------------------------------------------------------------------------*/
/* Getter Functions */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] EntityID GetEntityID () const noexcept;
[[nodiscard]] Type GetType () const noexcept;
[[nodiscard]] bool IsActive () const noexcept;
[[nodiscard]] bool GetDebugDrawState () const noexcept;
[[nodiscard]] const SHTransform& GetTransform () const noexcept;
[[nodiscard]] const SHVec3& GetPosition () const noexcept;
[[nodiscard]] const SHQuaternion& GetOrientation () const noexcept;
[[nodiscard]] const SHVec3& GetScale () const noexcept;
[[nodiscard]] const CollisionShapes& GetCollisionShapes () const noexcept;
[[nodiscard]] SHCollisionShape* GetCollisionShape (int index) const;
/*---------------------------------------------------------------------------------*/
/* Setter Functions */
/*---------------------------------------------------------------------------------*/
void SetType (Type type) noexcept;
void SetIsActive (bool state) noexcept;
void SetDebugDrawState (bool state) noexcept;
void SetRigidBody (SHRigidBody* rb) noexcept;
void SetTransform (const SHTransform& newTransform) noexcept;
void SetPosition (const SHVec3& newPosition) noexcept;
void SetOrientation (const SHQuaternion& newOrientation) noexcept;
void SetScale (const SHVec3& newScale) noexcept;
void SetLibrary (SHCollisionShapeLibrary* factory) noexcept;
/*---------------------------------------------------------------------------------*/
/* Member Functions */
/*---------------------------------------------------------------------------------*/
/**
* @brief
* Computes the TRS for the collider's transform
* @return
* The computed TRS.
*/
const SHMatrix& ComputeTRS() noexcept;
/**
* @brief
* Removes a shape from the container. Removal reduces the size of the container.
* If removing all, perform removal from back to front.
* @param index
* The index of the shape to remove.
* @throws
* Invalid argument for out-of-range indices.
*/
void RemoveCollisionShape (int index);
/**
* @brief
* Recomputes the transforms for all shapes in this composite collider.
*/
void Update () noexcept;
protected:
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
static constexpr uint8_t COMPOSITE_FLAG = 1U << static_cast<uint8_t>(Type::COMPOSITE);
static constexpr uint8_t HULL_FLAG = 1U << static_cast<uint8_t>(Type::HULL);
static constexpr uint8_t ACTIVE_FLAG = 1U << 2;
static constexpr uint8_t DRAW_FLAG = 1U << 3;
static constexpr uint8_t MOVED_FLAG = 1U << 4;
EntityID entityID;
uint8_t flags; // 0 0 0 hasMoved debugDraw active hull composite
SHRigidBody* rigidBody;
SHCollisionShapeLibrary* shapeLibrary;
SHAABBTree* broadphase;
SHTransform transform;
CollisionShapes shapes;
/*---------------------------------------------------------------------------------*/
/* Member Functions */
/*---------------------------------------------------------------------------------*/
void copyShapes (const SHCollider& rhsCollider);
};
} // namespace SHADE

View File

@ -40,7 +40,7 @@ namespace SHADE
/* Public Member Functions Definitions */ /* Public Member Functions Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHCollisionSpace::AddCollider(SHCompositeCollider* collider) noexcept void SHCollisionSpace::AddCollider(SHCollider* collider) noexcept
{ {
const bool INSERTED = colliders.emplace(collider->entityID, collider).second; const bool INSERTED = colliders.emplace(collider->entityID, collider).second;
if (!INSERTED) if (!INSERTED)
@ -56,7 +56,7 @@ namespace SHADE
broadphase.Insert(shape->id, shape->ComputeAABB()); broadphase.Insert(shape->id, shape->ComputeAABB());
} }
void SHCollisionSpace::RemoveCollider(SHCompositeCollider* collider) noexcept void SHCollisionSpace::RemoveCollider(SHCollider* collider) noexcept
{ {
colliders.erase(collider->entityID); colliders.erase(collider->entityID);
@ -85,14 +85,14 @@ namespace SHADE
// Update any colliders that have moved // Update any colliders that have moved
for (auto& collider : colliders | std::views::values) for (auto& collider : colliders | std::views::values)
{ {
const bool IS_ACTIVE = collider->active; const bool IS_ACTIVE = collider->IsActive();
const bool HAS_MOVED = collider->hasMoved; const bool HAS_MOVED = collider->flags & SHCollider::MOVED_FLAG;
if (!IS_ACTIVE || !HAS_MOVED) if (!IS_ACTIVE || !HAS_MOVED)
continue; continue;
// Clear hasMoved flag here // Clear hasMoved flag here
collider->hasMoved = false; collider->flags &= ~SHCollider::MOVED_FLAG;
// Update moved shapes in broadphase // Update moved shapes in broadphase
for (auto* shape : collider->shapes) for (auto* shape : collider->shapes)
@ -114,7 +114,7 @@ namespace SHADE
// Colliders without bodies are considered to be static bodies // Colliders without bodies are considered to be static bodies
// This is specific to this engine because of Unity's stupid convention. // This is specific to this engine because of Unity's stupid convention.
const bool IS_IMPLICIT_STATIC = !collider->rigidBody; const bool IS_IMPLICIT_STATIC = !collider->rigidBody;
const bool IS_ACTIVE = collider->active; const bool IS_ACTIVE = collider->IsActive();
// Skip inactive colliders // Skip inactive colliders
if (!IS_ACTIVE || IS_IMPLICIT_STATIC) if (!IS_ACTIVE || IS_IMPLICIT_STATIC)
@ -246,7 +246,7 @@ namespace SHADE
/* Private Member Functions Definitions */ /* Private Member Functions Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHCollisionSpace::broadphaseQuery(SHRigidBody::Type rigidBodyType, SHCompositeCollider* collider) noexcept void SHCollisionSpace::broadphaseQuery(SHRigidBody::Type rigidBodyType, SHCollider* collider) noexcept
{ {
for (auto* shape : collider->shapes) for (auto* shape : collider->shapes)
{ {

View File

@ -18,7 +18,7 @@
// Project Headers // Project Headers
#include "Broadphase/SHDynamicAABBTree.h" #include "Broadphase/SHDynamicAABBTree.h"
#include "Physics/Dynamics/SHContactManager.h" #include "Physics/Dynamics/SHContactManager.h"
#include "SHCompositeCollider.h" #include "SHCollider.h"
#include "SHPhysicsRaycastResult.h" #include "SHPhysicsRaycastResult.h"
#include "CollisionTags/SHCollisionTags.h" #include "CollisionTags/SHCollisionTags.h"
#include "CollisionTags/SHCollisionTags.h" #include "CollisionTags/SHCollisionTags.h"
@ -118,7 +118,7 @@ namespace SHADE
* @param collider * @param collider
* A collider to add. Duplicates will be ignored. * A collider to add. Duplicates will be ignored.
*/ */
void AddCollider (SHCompositeCollider* collider) noexcept; void AddCollider (SHCollider* collider) noexcept;
/** /**
* @brief * @brief
@ -127,7 +127,7 @@ namespace SHADE
* @param collider * @param collider
* A collider to remove. If a reference to it doesn't exist, it will be ignored. * A collider to remove. If a reference to it doesn't exist, it will be ignored.
*/ */
void RemoveCollider (SHCompositeCollider* collider) noexcept; void RemoveCollider (SHCollider* collider) noexcept;
/** /**
* @brief * @brief
@ -165,7 +165,7 @@ namespace SHADE
SHCollisionShape* B = nullptr; SHCollisionShape* B = nullptr;
}; };
using Colliders = std::unordered_map<EntityID, SHCompositeCollider*>; using Colliders = std::unordered_map<EntityID, SHCollider*>;
using NarrowphaseBatch = std::unordered_map<SHCollisionKey, NarrowphasePair, SHCollisionKeyHash>; using NarrowphaseBatch = std::unordered_map<SHCollisionKey, NarrowphasePair, SHCollisionKeyHash>;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -185,7 +185,7 @@ namespace SHADE
// Broadphase helpers // Broadphase helpers
void broadphaseQuery (SHRigidBody::Type rigidBodyType, SHCompositeCollider* collider) noexcept; void broadphaseQuery (SHRigidBody::Type rigidBodyType, SHCollider* collider) noexcept;
// Narrowphase helpers // Narrowphase helpers

View File

@ -1,7 +1,7 @@
/**************************************************************************************** /****************************************************************************************
* \file SHCollider.cpp * \file SHCompositeCollider.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520 * \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for a Base Collider Class. * \brief Implementation for a Composite Collider Class.
* *
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
* disclosure of this file or its contents without the prior written consent * disclosure of this file or its contents without the prior written consent
@ -15,12 +15,10 @@
// Project Headers // Project Headers
#include "Broadphase/SHDynamicAABBTree.h" #include "Broadphase/SHDynamicAABBTree.h"
#include "Events/SHEvent.h"
#include "Math/SHMathHelpers.h" #include "Math/SHMathHelpers.h"
#include "Physics/SHPhysicsEvents.h" #include "Physics/SHPhysicsEvents.h"
#include "Physics/Dynamics/SHRigidBody.h" #include "Physics/Dynamics/SHRigidBody.h"
namespace SHADE namespace SHADE
{ {
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -28,65 +26,18 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHCompositeCollider::SHCompositeCollider(EntityID eid, const SHTransform& worldTransform) noexcept SHCompositeCollider::SHCompositeCollider(EntityID eid, const SHTransform& worldTransform) noexcept
: entityID { eid } : SHCollider( eid, worldTransform )
, active { true } {
, debugDraw { false } flags |= COMPOSITE_FLAG;
, hasMoved { true } }
, rigidBody { nullptr }
, shapeLibrary { nullptr }
, broadphase { nullptr }
, transform { worldTransform }
{}
SHCompositeCollider::SHCompositeCollider(const SHCompositeCollider& rhs) noexcept SHCompositeCollider::SHCompositeCollider(const SHCompositeCollider& rhs) noexcept
: entityID { rhs.entityID } : SHCollider( rhs )
, active { rhs.active } {}
, debugDraw { rhs.debugDraw }
, hasMoved { rhs.hasMoved }
, rigidBody { rhs.rigidBody }
, shapeLibrary { rhs.shapeLibrary }
, broadphase { rhs.broadphase }
, transform { rhs.transform }
{
if (!shapeLibrary)
{
SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add copy shapes!", entityID)
return;
}
copyShapes(rhs);
}
SHCompositeCollider::SHCompositeCollider(SHCompositeCollider&& rhs) noexcept SHCompositeCollider::SHCompositeCollider(SHCompositeCollider&& rhs) noexcept
: entityID { rhs.entityID } : SHCollider( rhs )
, active { rhs.active } {}
, debugDraw { rhs.debugDraw }
, hasMoved { rhs.hasMoved }
, rigidBody { rhs.rigidBody }
, shapeLibrary { rhs.shapeLibrary }
, broadphase { rhs.broadphase }
, transform { rhs.transform }
{
if (!shapeLibrary)
{
SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add copy shapes!", entityID)
return;
}
copyShapes(rhs);
}
SHCompositeCollider::~SHCompositeCollider() noexcept
{
if (!shapeLibrary)
{
SHLOGV_ERROR("Shape factory is unlinked with Composite Collider {}. Unable to add destroy collider!", entityID)
return;
}
for (auto* shape : shapes)
shapeLibrary->DestroyShape(shape);
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */ /* Operator Overload Definitions */
@ -97,186 +48,22 @@ namespace SHADE
if (this == &rhs) if (this == &rhs)
return *this; return *this;
if (!shapeLibrary) SHCollider::operator=(rhs);
{
SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add copy shapes!", entityID)
return *this;
}
entityID = rhs.entityID;
active = rhs.active;
debugDraw = rhs.debugDraw;
hasMoved = rhs.hasMoved;
rigidBody = rhs.rigidBody;
shapeLibrary = rhs.shapeLibrary;
broadphase = rhs.broadphase;
transform = rhs.transform;
copyShapes(rhs);
return *this; return *this;
} }
SHCompositeCollider& SHCompositeCollider::operator=(SHCompositeCollider&& rhs) noexcept SHCompositeCollider& SHCompositeCollider::operator=(SHCompositeCollider&& rhs) noexcept
{ {
if (!shapeLibrary) SHCollider::operator=(rhs);
{
SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add copy shapes!", entityID)
return *this;
}
entityID = rhs.entityID;
active = rhs.active;
debugDraw = rhs.debugDraw;
hasMoved = rhs.hasMoved;
rigidBody = rhs.rigidBody;
shapeLibrary = rhs.shapeLibrary;
broadphase = rhs.broadphase;
transform = rhs.transform;
copyShapes(rhs);
return *this; return *this;
} }
/*-----------------------------------------------------------------------------------*/
/* Getter Function Definitions */
/*-----------------------------------------------------------------------------------*/
EntityID SHCompositeCollider::GetEntityID() const noexcept
{
return entityID;
}
bool SHCompositeCollider::IsActive() const noexcept
{
return active;
}
bool SHCompositeCollider::GetDebugDrawState() const noexcept
{
return debugDraw;
}
const SHTransform& SHCompositeCollider::GetTransform() const noexcept
{
return transform;
}
const SHVec3& SHCompositeCollider::GetPosition() const noexcept
{
return transform.position;
}
const SHQuaternion& SHCompositeCollider::GetOrientation() const noexcept
{
return transform.orientation;
}
const SHVec3& SHCompositeCollider::GetScale() const noexcept
{
return transform.scale;
}
const SHCompositeCollider::CollisionShapes& SHCompositeCollider::GetCollisionShapes() const noexcept
{
return shapes;
}
SHCollisionShape* SHCompositeCollider::GetCollisionShape(int index) const
{
const int NUM_SHAPES = static_cast<int>(shapes.size());
if (index < 0 || index >= NUM_SHAPES)
throw std::invalid_argument("Out-of-range index!");
return shapes[index];
}
/*-----------------------------------------------------------------------------------*/
/* Setter Function Definitions */
/*-----------------------------------------------------------------------------------*/
void SHCompositeCollider::SetIsActive(bool state) noexcept
{
if (active == state)
return;
active = state;
if (!broadphase)
return;
for (auto* shape : shapes)
{
if (active) // Previously inactive
broadphase->Insert(shape->id, shape->ComputeAABB());
else // Previously active
broadphase->Remove(shape->id);
}
}
void SHCompositeCollider::SetDebugDrawState(bool state) noexcept
{
debugDraw = state;
#ifdef SHEDITOR
// Broadcast event for the Debug Draw system to catch
const SHColliderOnDebugDrawEvent EVENT_DATA
{
.entityID = entityID
, .debugDrawState = debugDraw
};
SHEventManager::BroadcastEvent<SHColliderOnDebugDrawEvent>(EVENT_DATA, SH_PHYSICS_COLLIDER_DRAW_EVENT);
#endif
}
void SHCompositeCollider::SetRigidBody(SHRigidBody* rb) noexcept
{
rigidBody = rb;
}
void SHCompositeCollider::SetTransform(const SHTransform& newTransform) noexcept
{
hasMoved = true;
transform = newTransform;
}
void SHCompositeCollider::SetPosition(const SHVec3& newPosition) noexcept
{
hasMoved = true;
transform.position = newPosition;
}
void SHCompositeCollider::SetOrientation(const SHQuaternion& newOrientation) noexcept
{
hasMoved = true;
transform.orientation = newOrientation;
}
void SHCompositeCollider::SetScale(const SHVec3& newScale) noexcept
{
hasMoved = true;
transform.scale = newScale;
}
void SHCompositeCollider::SetFactory(SHCollisionShapeLibrary* factory) noexcept
{
shapeLibrary = factory;
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Public Member Function Definitions */ /* Public Member Function Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
const SHMatrix& SHCompositeCollider::ComputeTransformTRS() noexcept
{
return transform.ComputeTRS();
}
int SHCompositeCollider::AddSphereCollisionShape(float relativeRadius, const SHVec3& posOffset, const SHVec3& rotOffset) int SHCompositeCollider::AddSphereCollisionShape(float relativeRadius, const SHVec3& posOffset, const SHVec3& rotOffset)
{ {
if (!shapeLibrary) if (!shapeLibrary)
@ -386,106 +173,4 @@ namespace SHADE
} }
void SHCompositeCollider::RemoveCollisionShape(int index)
{
if (!shapeLibrary)
{
SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add remove shape!", entityID)
return;
}
const int NUM_SHAPES = static_cast<int>(shapes.size());
if (index < 0 || index >= NUM_SHAPES)
throw std::invalid_argument("Out-of-range index!");
auto shape = shapes.begin();
for (int i = 0; i < NUM_SHAPES; ++i, ++shape)
{
if (i == index)
break;
}
const SHPhysicsColliderRemovedEvent EVENT_DATA
{
.entityID = entityID
, .colliderType = (*shape)->GetType()
, .colliderIndex = index
};
// Remove from broadphase
if (broadphase)
broadphase->Remove((*shape)->id);
shapeLibrary->DestroyShape(*shape);
*shape = nullptr;
// Remove the shape from the container to prevent accessing a nullptr
shape = shapes.erase(shape);
// Broadcast Event for removing a shape
SHEventManager::BroadcastEvent<SHPhysicsColliderRemovedEvent>(EVENT_DATA, SH_PHYSICS_COLLIDER_REMOVED_EVENT);
if (rigidBody)
rigidBody->ComputeMassData();
SHLOG_INFO_D("Removing Collision Shape {} from Entity {}", index, entityID)
}
void SHCompositeCollider::RecomputeShapes() noexcept
{
for (auto* shape : shapes)
shape->Update();
}
/*-----------------------------------------------------------------------------------*/
/* Private Member Function Definitions */
/*-----------------------------------------------------------------------------------*/
void SHCompositeCollider::copyShapes(const SHCompositeCollider& rhsCollider)
{
for (const auto* shape : rhsCollider.shapes)
copyShape(shape);
}
void SHCompositeCollider::copyShape(const SHCollisionShape* rhsShape)
{
switch (rhsShape->GetType())
{
case SHCollisionShape::Type::BOX:
{
break;
}
case SHCollisionShape::Type::SPHERE:
{
const SHSphere* RHS_SPHERE = dynamic_cast<const SHSphere*>(rhsShape);
const SHSphereCreateInfo SPHERE_CREATE_INFO
{
.Center = RHS_SPHERE->Center
, .Radius = RHS_SPHERE->Radius
, .RelativeRadius = RHS_SPHERE->relativeRadius
, .Scale = RHS_SPHERE->scale
};
const uint32_t NEW_INDEX = static_cast<uint32_t>(shapes.size());
const SHCollisionShapeID NEW_SHAPE_ID{ entityID, NEW_INDEX };
SHSphere* sphere = shapeLibrary->CreateSphere(NEW_SHAPE_ID, SPHERE_CREATE_INFO);
*sphere = *RHS_SPHERE;
shapes.emplace_back(sphere);
break;
}
case SHCollisionShape::Type::CAPSULE:
{
break;
}
default: break;
}
}
} // namespace SHADE } // namespace SHADE

View File

@ -1,7 +1,7 @@
/**************************************************************************************** /****************************************************************************************
* \file SHCollider.h * \file SHCompositeCollider.h
* \author Diren D Bharwani, diren.dbharwani, 390002520 * \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for a Base Collider Class. * \brief Interface for a Composite Collider Class.
* *
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
* disclosure of this file or its contents without the prior written consent * disclosure of this file or its contents without the prior written consent
@ -11,63 +11,26 @@
#pragma once #pragma once
// Project Headers // Project Headers
#include "ECS_Base/Entity/SHEntity.h" #include "SHCollider.h"
#include "Math/Transform/SHTransform.h"
#include "Physics/Collision/CollisionShapes/SHCollisionShapeLibrary.h"
namespace SHADE namespace SHADE
{ {
/*-----------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
class SHRigidBody;
class SHAABBTree;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
/** /**
* @brief * @brief
* Base class for a collider. * Encapsulates the behaviour of a collider with composited shapes. <br/>
* There are only two collider types supported by SHADE Engine: Composite & Hull * Contains no data members but methods to add multiple shapes.
*/ */
class SH_API SHCompositeCollider class SH_API SHCompositeCollider : public SHCollider
{ {
private:
/*---------------------------------------------------------------------------------*/
/* Friends */
/*---------------------------------------------------------------------------------*/
friend class SHCollisionSpace;
friend struct SHManifold;
public: public:
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
/*---------------------------------------------------------------------------------*/
using CollisionShapes = std::vector<SHCollisionShape*>;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */ /* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/**
* @brief
* Constructor for a collider.
* @param eid
* The entity this collider belongs to.
* @param worldTransform
* The world transform for the collider. Defaults to the identity transform.
* This is particularly important for composite colliders for offsets & relative sizes.
* @return
*/
SHCompositeCollider(EntityID eid, const SHTransform& worldTransform = SHTransform::Identity) noexcept; SHCompositeCollider(EntityID eid, const SHTransform& worldTransform = SHTransform::Identity) noexcept;
SHCompositeCollider(const SHCompositeCollider& rhs) noexcept; SHCompositeCollider(const SHCompositeCollider& rhs) noexcept;
SHCompositeCollider(SHCompositeCollider&& rhs) noexcept; SHCompositeCollider(SHCompositeCollider&& rhs) noexcept;
~SHCompositeCollider () noexcept; ~SHCompositeCollider () noexcept override = default;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Operator Overloads */ /* Operator Overloads */
@ -76,50 +39,10 @@ namespace SHADE
SHCompositeCollider& operator=(const SHCompositeCollider& rhs) noexcept; SHCompositeCollider& operator=(const SHCompositeCollider& rhs) noexcept;
SHCompositeCollider& operator=(SHCompositeCollider&& rhs) noexcept; SHCompositeCollider& operator=(SHCompositeCollider&& rhs) noexcept;
/*---------------------------------------------------------------------------------*/
/* Getter Functions */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] EntityID GetEntityID () const noexcept;
[[nodiscard]] bool IsActive () const noexcept;
[[nodiscard]] bool GetDebugDrawState () const noexcept;
[[nodiscard]] const SHTransform& GetTransform () const noexcept;
[[nodiscard]] const SHVec3& GetPosition () const noexcept;
[[nodiscard]] const SHQuaternion& GetOrientation () const noexcept;
[[nodiscard]] const SHVec3& GetScale () const noexcept;
[[nodiscard]] const CollisionShapes& GetCollisionShapes () const noexcept;
[[nodiscard]] SHCollisionShape* GetCollisionShape (int index) const;
/*---------------------------------------------------------------------------------*/
/* Setter Functions */
/*---------------------------------------------------------------------------------*/
void SetIsActive (bool state) noexcept;
void SetDebugDrawState (bool state) noexcept;
void SetRigidBody (SHRigidBody* rb) noexcept;
void SetTransform (const SHTransform& newTransform) noexcept;
void SetPosition (const SHVec3& newPosition) noexcept;
void SetOrientation (const SHQuaternion& newOrientation) noexcept;
void SetScale (const SHVec3& newScale) noexcept;
void SetFactory (SHCollisionShapeLibrary* factory) noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Member Functions */ /* Member Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/**
* @brief
* Computes the TRS for the collider's transform
* @return
* The computed TRS.
*/
const SHMatrix& ComputeTransformTRS() noexcept;
/** /**
* @brief * @brief
* Adds a sphere collision shape. * Adds a sphere collision shape.
@ -151,49 +74,7 @@ namespace SHADE
int AddBoxCollisionShape (const SHVec3& relativeExtents, const SHVec3& posOffset = SHVec3::Zero, const SHVec3& rotOffset = SHVec3::Zero); int AddBoxCollisionShape (const SHVec3& relativeExtents, const SHVec3& posOffset = SHVec3::Zero, const SHVec3& rotOffset = SHVec3::Zero);
// TODO: Add Capsule // TODO: Add Capsule
/**
* @brief
* Removes a shape from the container. Removal reduces the size of the container.
* If removing all, perform removal from back to front.
* @param index
* The index of the shape to remove.
* @throws
* Invalid argument for out-of-range indices.
*/
void RemoveCollisionShape (int index);
/**
* @brief
* Recomputes the transforms for all shapes in this composite collider.
*/
void RecomputeShapes () noexcept;
protected:
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
EntityID entityID;
bool active;
bool debugDraw;
bool hasMoved;
SHRigidBody* rigidBody;
SHCollisionShapeLibrary* shapeLibrary;
SHAABBTree* broadphase;
SHTransform transform;
CollisionShapes shapes;
/*---------------------------------------------------------------------------------*/
/* Member Functions */
/*---------------------------------------------------------------------------------*/
void copyShapes (const SHCompositeCollider& rhsCollider);
void copyShape (const SHCollisionShape* rhsShape);
}; };
} // namespace SHADE } // namespace SHADE

View File

@ -16,7 +16,7 @@
// Project Headers // Project Headers
#include "Math/SHMathHelpers.h" #include "Math/SHMathHelpers.h"
#include "Math/SHMatrix.h" #include "Math/SHMatrix.h"
#include "Physics/Collision/SHCompositeCollider.h" #include "Physics/Collision/SHCollider.h"
namespace SHADE namespace SHADE
{ {

View File

@ -47,6 +47,7 @@ namespace SHADE
/* Friends */ /* Friends */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
friend class SHCollider;
friend class SHCompositeCollider; friend class SHCompositeCollider;
friend class SHCollision; friend class SHCollision;
friend class SHCollisionShapeLibrary; friend class SHCollisionShapeLibrary;

View File

@ -14,7 +14,7 @@
#include "SHCollisionShape.h" #include "SHCollisionShape.h"
// Project Headers // Project Headers
#include "Physics/Collision/SHCompositeCollider.h" #include "Physics/Collision/SHCollider.h"
#include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h" #include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h"
#include "Reflection/SHReflectionMetadata.h" #include "Reflection/SHReflectionMetadata.h"
#include "Tools/Utilities/SHUtilities.h" #include "Tools/Utilities/SHUtilities.h"

View File

@ -41,6 +41,7 @@ namespace SHADE
/* Friends */ /* Friends */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
friend class SHCollider;
friend class SHCompositeCollider; friend class SHCompositeCollider;
friend class SHColliderComponent; friend class SHColliderComponent;
friend class SHCollisionShapeLibrary; friend class SHCollisionShapeLibrary;
@ -191,7 +192,7 @@ namespace SHADE
SHCollisionShapeID id; SHCollisionShapeID id;
SHCompositeCollider* collider; // The collider it belongs to. SHCollider* collider; // The collider it belongs to.
SHCollisionTag* collisionTag; SHCollisionTag* collisionTag;
SHPhysicsMaterial material; // TODO: Change to pointer once instancing is supported SHPhysicsMaterial material; // TODO: Change to pointer once instancing is supported

View File

@ -25,30 +25,14 @@ namespace SHADE
{} {}
SHConvexPolyhedron::SHConvexPolyhedron(const SHConvexPolyhedron& rhs) noexcept SHConvexPolyhedron::SHConvexPolyhedron(const SHConvexPolyhedron& rhs) noexcept
: SHCollisionShape (rhs.id, rhs.GetType()) : SHCollisionShape ( rhs )
, halfEdgeStructure { nullptr } , halfEdgeStructure { rhs.halfEdgeStructure }
{ {}
material = rhs.material;
collider = rhs.collider;
transform = rhs.transform;
rotationOffset = rhs.rotationOffset;
flags = rhs.flags;
// Since all collision tags are taken from the matrix, we do not need to do a deep copy here.
collisionTag = rhs.collisionTag;
}
SHConvexPolyhedron::SHConvexPolyhedron(SHConvexPolyhedron&& rhs) noexcept SHConvexPolyhedron::SHConvexPolyhedron(SHConvexPolyhedron&& rhs) noexcept
: SHCollisionShape (rhs.id, rhs.GetType()) : SHCollisionShape ( rhs )
, halfEdgeStructure { nullptr } , halfEdgeStructure { rhs.halfEdgeStructure }
{ {}
material = rhs.material;
collider = rhs.collider;
transform = rhs.transform;
rotationOffset = rhs.rotationOffset;
flags = rhs.flags;
// Since all collision tags are taken from the matrix, we do not need to do a deep copy here.
collisionTag = rhs.collisionTag;
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */ /* Operator Overload Definitions */
@ -59,13 +43,7 @@ namespace SHADE
if (this == &rhs) if (this == &rhs)
return *this; return *this;
material = rhs.material; SHCollisionShape::operator=(rhs);
collider = rhs.collider;
transform = rhs.transform;
rotationOffset = rhs.rotationOffset;
flags = rhs.flags;
// Since all collision tags are taken from the matrix, we do not need to do a deep copy here.
collisionTag = rhs.collisionTag;
// Local Properties // Local Properties
halfEdgeStructure = rhs.halfEdgeStructure; halfEdgeStructure = rhs.halfEdgeStructure;
@ -75,13 +53,7 @@ namespace SHADE
SHConvexPolyhedron& SHConvexPolyhedron::operator=(SHConvexPolyhedron&& rhs) noexcept SHConvexPolyhedron& SHConvexPolyhedron::operator=(SHConvexPolyhedron&& rhs) noexcept
{ {
material = rhs.material; SHCollisionShape::operator=(rhs);
collider = rhs.collider;
transform = rhs.transform;
rotationOffset = rhs.rotationOffset;
flags = rhs.flags;
// Since all collision tags are taken from the matrix, we do not need to do a deep copy here.
collisionTag = rhs.collisionTag;
// Local Properties // Local Properties
halfEdgeStructure = rhs.halfEdgeStructure; halfEdgeStructure = rhs.halfEdgeStructure;

View File

@ -31,7 +31,7 @@ namespace SHADE
/* Friends */ /* Friends */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
friend class SHCompositeCollider; friend class SHCollider;
friend class SHCollision; friend class SHCollision;
friend class SHCollisionShapeLibrary; friend class SHCollisionShapeLibrary;

View File

@ -16,7 +16,7 @@
// Project Headers // Project Headers
#include "Math/SHMathHelpers.h" #include "Math/SHMathHelpers.h"
#include "Math/SHMatrix.h" #include "Math/SHMatrix.h"
#include "Physics/Collision/SHCompositeCollider.h" #include "Physics/Collision/SHCollider.h"
namespace SHADE namespace SHADE
{ {

View File

@ -46,6 +46,7 @@ namespace SHADE
/* Friends */ /* Friends */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
friend class SHCollider;
friend class SHCompositeCollider; friend class SHCompositeCollider;
friend class SHCollision; friend class SHCollision;
friend class SHCollisionShapeLibrary; friend class SHCollisionShapeLibrary;

View File

@ -178,7 +178,7 @@ namespace SHADE
rigidBody.collider->SetPosition(rigidBody.motionState.position); rigidBody.collider->SetPosition(rigidBody.motionState.position);
rigidBody.collider->SetOrientation(rigidBody.motionState.orientation); rigidBody.collider->SetOrientation(rigidBody.motionState.orientation);
rigidBody.collider->RecomputeShapes(); rigidBody.collider->Update();
} }
} }

View File

@ -17,7 +17,7 @@
#include <complex.h> #include <complex.h>
#include <numeric> #include <numeric>
#include "Physics/Collision/SHCompositeCollider.h" #include "Physics/Collision/SHCollider.h"
#include "Tools/Logger/SHLogger.h" #include "Tools/Logger/SHLogger.h"
namespace SHADE namespace SHADE
@ -296,7 +296,7 @@ namespace SHADE
/* Setter Functions Definitions */ /* Setter Functions Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHRigidBody::SetCollider(SHCompositeCollider* c) noexcept void SHRigidBody::SetCollider(SHCollider* c) noexcept
{ {
collider = c; collider = c;
} }

View File

@ -22,7 +22,7 @@ namespace SHADE
/* Forward Declarations */ /* Forward Declarations */
/*-------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------*/
class SHCompositeCollider; class SHCollider;
/*-------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------*/
/* Type Definitions */ /* Type Definitions */
@ -113,7 +113,7 @@ namespace SHADE
/* Setter Functions */ /* Setter Functions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SetCollider (SHCompositeCollider* c) noexcept; void SetCollider (SHCollider* c) noexcept;
/** /**
* @brief * @brief
@ -229,7 +229,7 @@ namespace SHADE
// The entityID here is only meant for linking with the actual component in the engine. // The entityID here is only meant for linking with the actual component in the engine.
EntityID entityID; EntityID entityID;
SHCompositeCollider* collider; SHCollider* collider;
Type bodyType; Type bodyType;

View File

@ -13,6 +13,9 @@
// Primary Header // Primary Header
#include "SHPhysicsObject.h" #include "SHPhysicsObject.h"
#include "Physics/Collision/SHCollider.h"
#include "Physics/Collision/SHCompositeCollider.h"
namespace SHADE namespace SHADE
{ {
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -111,7 +114,7 @@ namespace SHADE
collider->SetRigidBody(nullptr); collider->SetRigidBody(nullptr);
} }
SHCompositeCollider* SHPhysicsObject::CreateCollider(const SHTransform& transform) SHCollider* SHPhysicsObject::CreateCompositeCollider(const SHTransform& transform)
{ {
if (collider) if (collider)
{ {
@ -148,13 +151,13 @@ namespace SHADE
/* Private Member Function Definitions */ /* Private Member Function Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHPhysicsObject::deepCopyComponents(const SHRigidBody* rhsRigidBody, const SHCompositeCollider* rhsCollider) void SHPhysicsObject::deepCopyComponents(const SHRigidBody* rhsRigidBody, const SHCollider* rhsCollider)
{ {
if (rhsRigidBody) if (rhsRigidBody)
rigidBody = new SHRigidBody{ *rhsRigidBody }; rigidBody = new SHRigidBody{ *rhsRigidBody };
if (rhsCollider) if (rhsCollider)
collider = new SHCompositeCollider { *rhsCollider }; collider = new SHCollider { *rhsCollider };
} }
} // namespace SHADE } // namespace SHADE

View File

@ -11,7 +11,7 @@
#pragma once #pragma once
// Project Headers // Project Headers
#include "Physics/Collision/SHCompositeCollider.h" #include "Physics/Collision/SHCollider.h"
#include "Physics/Dynamics/SHRigidBody.h" #include "Physics/Dynamics/SHRigidBody.h"
namespace SHADE namespace SHADE
@ -33,7 +33,7 @@ namespace SHADE
EntityID entityID = MAX_EID; EntityID entityID = MAX_EID;
SHRigidBody* rigidBody = nullptr; SHRigidBody* rigidBody = nullptr;
SHCompositeCollider* collider = nullptr; SHCollider* collider = nullptr;
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor */ /* Constructors & Destructor */
@ -91,7 +91,7 @@ namespace SHADE
* Pointer to the collider that was created. The memory of this collider is managed * Pointer to the collider that was created. The memory of this collider is managed
* by the physics object itself. * by the physics object itself.
*/ */
SHCompositeCollider* CreateCollider (const SHTransform& transform = SHTransform::Identity); SHCollider* CreateCompositeCollider (const SHTransform& transform = SHTransform::Identity);
/** /**
* @brief * @brief
@ -104,6 +104,6 @@ namespace SHADE
/* Member Functions */ /* Member Functions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void deepCopyComponents(const SHRigidBody* rhsRigidBody, const SHCompositeCollider* rhsCollider); void deepCopyComponents(const SHRigidBody* rhsRigidBody, const SHCollider* rhsCollider);
}; };
} // namespace SHADE } // namespace SHADE

View File

@ -98,7 +98,7 @@ namespace SHADE
destroyPhysicsObject(entityID); destroyPhysicsObject(entityID);
} }
void SHPhysicsObjectManager::AddCollider(EntityID entityID) noexcept void SHPhysicsObjectManager::AddCollider(EntityID entityID, SHCollider::Type type) noexcept
{ {
SHPhysicsObject* physicsObject = ensurePhysicsObject(entityID); SHPhysicsObject* physicsObject = ensurePhysicsObject(entityID);
@ -116,11 +116,15 @@ namespace SHADE
} }
// Create a new composite collider in the physics object // Create a new composite collider in the physics object
physicsObject->CreateCollider(worldTransform); if (type == SHCollider::Type::COMPOSITE)
physicsObject->collider->SetFactory(&shapeLibrary); physicsObject->CreateCompositeCollider(worldTransform);
// TODO: Hull collider
physicsObject->collider->SetLibrary(&shapeLibrary);
// Link with the component // Link with the component
colliderComponent->SetCollider(physicsObject->collider); colliderComponent->SetCollider(dynamic_cast<SHCompositeCollider*>(physicsObject->collider));
} }
void SHPhysicsObjectManager::RemoveCollider(EntityID entityID) noexcept void SHPhysicsObjectManager::RemoveCollider(EntityID entityID) noexcept

View File

@ -14,7 +14,7 @@
// Project Headers // Project Headers
#include "SHPhysicsObject.h" #include "SHPhysicsObject.h"
#include "Physics/Collision/CollisionShapes/SHCollisionShapeLibrary.h" #include "Physics/Collision/Shapes/SHCollisionShapeLibrary.h"
namespace SHADE namespace SHADE
{ {
@ -77,7 +77,7 @@ namespace SHADE
* @param entityID * @param entityID
* The entity to link the new collider to. * The entity to link the new collider to.
*/ */
void AddCollider (EntityID entityID) noexcept; void AddCollider (EntityID entityID, SHCollider::Type type) noexcept;
/** /**
* @brief * @brief

View File

@ -13,11 +13,6 @@
// Primary Header // Primary Header
#include "SHColliderComponent.h" #include "SHColliderComponent.h"
// Project Headers
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Math/SHMathHelpers.h"
#include "Physics/System/SHPhysicsSystem.h"
namespace SHADE namespace SHADE
{ {
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -37,7 +32,7 @@ namespace SHADE
return collider; return collider;
} }
const SHCompositeCollider::CollisionShapes* const SHColliderComponent::GetCollisionShapes() const noexcept const SHCollider::CollisionShapes* const SHColliderComponent::GetCollisionShapes() const noexcept
{ {
if (!collider) if (!collider)
return nullptr; return nullptr;

View File

@ -55,7 +55,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
[[nodiscard]] SHCompositeCollider* const GetCollider () const noexcept; [[nodiscard]] SHCompositeCollider* const GetCollider () const noexcept;
[[nodiscard]] const SHCompositeCollider::CollisionShapes* const GetCollisionShapes() const noexcept; [[nodiscard]] const SHCollider::CollisionShapes* const GetCollisionShapes() const noexcept;
[[nodiscard]] SHCollisionShape* const GetCollisionShape (int index) const; [[nodiscard]] SHCollisionShape* const GetCollisionShape (int index) const;
// Required for serialisation // Required for serialisation

View File

@ -11,7 +11,7 @@
#pragma once #pragma once
// Project Headers // Project Headers
#include "Collision/CollisionShapes/SHCollisionShape.h" #include "Collision/Shapes/SHCollisionShape.h"
namespace SHADE namespace SHADE
{ {

View File

@ -83,7 +83,7 @@ namespace SHADE
physicsObject.collider->SetOrientation(WORLD_ROT); physicsObject.collider->SetOrientation(WORLD_ROT);
physicsObject.collider->SetScale(WORLD_SCL); physicsObject.collider->SetScale(WORLD_SCL);
physicsObject.collider->RecomputeShapes(); physicsObject.collider->Update();
} }
} }
} }

View File

@ -122,7 +122,7 @@ namespace SHADE
return onColliderDrawEvent.get()->handle; return onColliderDrawEvent.get()->handle;
} }
void SHPhysicsDebugDrawSystem::drawCollider(SHDebugDrawSystem* debugDrawSystem, const SHCompositeCollider& collider) noexcept void SHPhysicsDebugDrawSystem::drawCollider(SHDebugDrawSystem* debugDrawSystem, const SHCollider& collider) noexcept
{ {
for (const auto* SHAPE : collider.GetCollisionShapes()) for (const auto* SHAPE : collider.GetCollisionShapes())
{ {

View File

@ -18,9 +18,9 @@
#include "ECS_Base/System/SHSystemRoutine.h" #include "ECS_Base/System/SHSystemRoutine.h"
#include "Events/SHEvent.h" #include "Events/SHEvent.h"
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h" #include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
#include "Physics/Collision/SHCompositeCollider.h" #include "Physics/Collision/SHCollider.h"
#include "Physics/Collision/SHPhysicsRaycastResult.h" #include "Physics/Collision/SHPhysicsRaycastResult.h"
#include "Physics/Collision/CollisionShapes/SHSphere.h" #include "Physics/Collision/Shapes/SHSphere.h"
namespace SHADE namespace SHADE
@ -138,7 +138,7 @@ namespace SHADE
SHEventHandle onColliderDraw(SHEventPtr onColliderDrawEvent); SHEventHandle onColliderDraw(SHEventPtr onColliderDrawEvent);
static void drawCollider (SHDebugDrawSystem* debugDrawSystem, const SHCompositeCollider& collider) noexcept; static void drawCollider (SHDebugDrawSystem* debugDrawSystem, const SHCollider& collider) noexcept;
static void drawRaycast (SHDebugDrawSystem* debugDrawSystem, const DebugDrawInfo::Raycast& raycastInfo) noexcept; static void drawRaycast (SHDebugDrawSystem* debugDrawSystem, const DebugDrawInfo::Raycast& raycastInfo) noexcept;
}; };

View File

@ -308,6 +308,8 @@ namespace SHADE
const bool IS_RIGID_BODY = ADDED_ID == RIGID_BODY_COMPONENT_ID; const bool IS_RIGID_BODY = ADDED_ID == RIGID_BODY_COMPONENT_ID;
const bool IS_COLLIDER = ADDED_ID == COLLIDER_COMPONENT_ID; const bool IS_COLLIDER = ADDED_ID == COLLIDER_COMPONENT_ID;
// TODO: Hull Collider
// Check if its a physics component // Check if its a physics component
const bool IS_PHYSICS_COMPONENT = IS_RIGID_BODY || IS_COLLIDER; const bool IS_PHYSICS_COMPONENT = IS_RIGID_BODY || IS_COLLIDER;
if (!IS_PHYSICS_COMPONENT) if (!IS_PHYSICS_COMPONENT)
@ -329,7 +331,7 @@ namespace SHADE
if (IS_COLLIDER) if (IS_COLLIDER)
{ {
physicsObjectManager.AddCollider(EID); physicsObjectManager.AddCollider(EID, SHCollider::Type::COMPOSITE);
if (collisionSpace) if (collisionSpace)
{ {

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
#include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Graphics/MiddleEnd/Interface/SHRenderable.h"
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h" #include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
#include "Physics/Collision/CollisionShapes/SHSphere.h"
#include "Resource/SHResourceManager.h" #include "Resource/SHResourceManager.h"
#include "Math/Vector/SHVec2.h" #include "Math/Vector/SHVec2.h"
#include "Math/Vector/SHVec3.h" #include "Math/Vector/SHVec3.h"
@ -12,6 +11,7 @@
#include "Physics/Interface/SHColliderComponent.h" #include "Physics/Interface/SHColliderComponent.h"
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h" #include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h"
#include "Graphics/MiddleEnd/TextRendering/SHFont.h" #include "Graphics/MiddleEnd/TextRendering/SHFont.h"
#include "Physics/Collision/SHCompositeCollider.h"
#include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h" #include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h"
namespace YAML namespace YAML
@ -261,7 +261,6 @@ namespace YAML
return false; return false;
auto* collider = rhs.GetCollider(); auto* collider = rhs.GetCollider();
switch (colliderType) switch (colliderType)
{ {
case SHCollisionShape::Type::SPHERE: collider->AddSphereCollisionShape(1.0f); break; case SHCollisionShape::Type::SPHERE: collider->AddSphereCollisionShape(1.0f); break;
@ -269,6 +268,7 @@ namespace YAML
case SHCollisionShape::Type::CAPSULE: break; case SHCollisionShape::Type::CAPSULE: break;
default:; default:;
} }
YAML::convert<SHCollisionShape>::decode(colliderNode, *collider->GetCollisionShape(numColliders++)); YAML::convert<SHCollisionShape>::decode(colliderNode, *collider->GetCollisionShape(numColliders++));
} }
} }