Implemented a custom physics engine #316

Merged
direnbharwani merged 95 commits from SHPhysics into main 2023-01-23 15:55:45 +08:00
49 changed files with 697 additions and 619 deletions
Showing only changes of commit dffdec9d9c - Show all commits

View File

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

View File

@ -13,7 +13,7 @@
#include <DirectXCollision.h>
// Project Headers
#include "SHShape.h"
#include "Math/SHRay.h"
namespace SHADE
{
@ -25,8 +25,7 @@ namespace SHADE
* @brief
* Encapsulates a 3D Axis-Aligned Bounding Box.
*/
class SH_API SHAABB : public SHShape,
private DirectX::BoundingBox
class SH_API SHAABB : private DirectX::BoundingBox
{
public:
/*---------------------------------------------------------------------------------*/
@ -39,7 +38,7 @@ namespace SHADE
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
~SHAABB () override = default;
~SHAABB () noexcept = default;
SHAABB () noexcept;
SHAABB (const SHVec3& center, const SHVec3& halfExtents) noexcept;
@ -85,7 +84,7 @@ namespace SHADE
* @return
* 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
@ -96,7 +95,7 @@ namespace SHADE
* The result of the raycast. <br/>
* 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

View File

@ -11,7 +11,7 @@
#pragma once
// Project Headers
#include "SHShape.h"
#include "Math/SHRay.h"
#include "Math/Vector/SHVec4.h"
namespace SHADE
@ -24,14 +24,14 @@ namespace SHADE
* @brief
* Encapsulates a 3D plane in point-normal form.
*/
class SH_API SHPlane : public SHShape
class SH_API SHPlane
{
public:
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
~SHPlane () override = default;
~SHPlane () noexcept = default;
SHPlane (const SHPlane& rhs) noexcept = default;
SHPlane (SHPlane&& rhs) noexcept = default;
@ -77,7 +77,7 @@ namespace SHADE
* @return
* 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
@ -88,7 +88,7 @@ namespace SHADE
* The result of the raycast. <br/>
* 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

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>
// Project Headers
#include "Physics/Collision/CollisionShapes/SHCollisionShape.h"
#include "Physics/Collision/Shapes/SHCollisionShape.h"
namespace SHADE
{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -15,7 +15,7 @@
// Project Headers
#include "Math/SHMathHelpers.h"
#include "Physics/Collision/CollisionShapes/SHSphere.h"
#include "Physics/Collision/Shapes/SHSphere.h"
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 */
/*-----------------------------------------------------------------------------------*/
void SHCollisionSpace::AddCollider(SHCompositeCollider* collider) noexcept
void SHCollisionSpace::AddCollider(SHCollider* collider) noexcept
{
const bool INSERTED = colliders.emplace(collider->entityID, collider).second;
if (!INSERTED)
@ -56,7 +56,7 @@ namespace SHADE
broadphase.Insert(shape->id, shape->ComputeAABB());
}
void SHCollisionSpace::RemoveCollider(SHCompositeCollider* collider) noexcept
void SHCollisionSpace::RemoveCollider(SHCollider* collider) noexcept
{
colliders.erase(collider->entityID);
@ -85,14 +85,14 @@ namespace SHADE
// Update any colliders that have moved
for (auto& collider : colliders | std::views::values)
{
const bool IS_ACTIVE = collider->active;
const bool HAS_MOVED = collider->hasMoved;
const bool IS_ACTIVE = collider->IsActive();
const bool HAS_MOVED = collider->flags & SHCollider::MOVED_FLAG;
if (!IS_ACTIVE || !HAS_MOVED)
continue;
// Clear hasMoved flag here
collider->hasMoved = false;
collider->flags &= ~SHCollider::MOVED_FLAG;
// Update moved shapes in broadphase
for (auto* shape : collider->shapes)
@ -114,7 +114,7 @@ namespace SHADE
// Colliders without bodies are considered to be static bodies
// This is specific to this engine because of Unity's stupid convention.
const bool IS_IMPLICIT_STATIC = !collider->rigidBody;
const bool IS_ACTIVE = collider->active;
const bool IS_ACTIVE = collider->IsActive();
// Skip inactive colliders
if (!IS_ACTIVE || IS_IMPLICIT_STATIC)
@ -246,7 +246,7 @@ namespace SHADE
/* 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)
{

View File

@ -18,7 +18,7 @@
// Project Headers
#include "Broadphase/SHDynamicAABBTree.h"
#include "Physics/Dynamics/SHContactManager.h"
#include "SHCompositeCollider.h"
#include "SHCollider.h"
#include "SHPhysicsRaycastResult.h"
#include "CollisionTags/SHCollisionTags.h"
#include "CollisionTags/SHCollisionTags.h"
@ -118,7 +118,7 @@ namespace SHADE
* @param collider
* A collider to add. Duplicates will be ignored.
*/
void AddCollider (SHCompositeCollider* collider) noexcept;
void AddCollider (SHCollider* collider) noexcept;
/**
* @brief
@ -127,7 +127,7 @@ namespace SHADE
* @param collider
* 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
@ -165,7 +165,7 @@ namespace SHADE
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>;
/*---------------------------------------------------------------------------------*/
@ -185,7 +185,7 @@ namespace SHADE
// Broadphase helpers
void broadphaseQuery (SHRigidBody::Type rigidBodyType, SHCompositeCollider* collider) noexcept;
void broadphaseQuery (SHRigidBody::Type rigidBodyType, SHCollider* collider) noexcept;
// Narrowphase helpers

View File

@ -1,7 +1,7 @@
/****************************************************************************************
* \file SHCollider.cpp
* \file SHCompositeCollider.cpp
* \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
* disclosure of this file or its contents without the prior written consent
@ -15,12 +15,10 @@
// 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
{
/*-----------------------------------------------------------------------------------*/
@ -28,65 +26,18 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/
SHCompositeCollider::SHCompositeCollider(EntityID eid, const SHTransform& worldTransform) noexcept
: entityID { eid }
, active { true }
, debugDraw { false }
, hasMoved { true }
, rigidBody { nullptr }
, shapeLibrary { nullptr }
, broadphase { nullptr }
, transform { worldTransform }
{}
: SHCollider( eid, worldTransform )
{
flags |= COMPOSITE_FLAG;
}
SHCompositeCollider::SHCompositeCollider(const SHCompositeCollider& rhs) noexcept
: entityID { rhs.entityID }
, 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);
}
: SHCollider( rhs )
{}
SHCompositeCollider::SHCompositeCollider(SHCompositeCollider&& rhs) noexcept
: entityID { rhs.entityID }
, 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);
}
: SHCollider( rhs )
{}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
@ -97,186 +48,22 @@ namespace SHADE
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;
active = rhs.active;
debugDraw = rhs.debugDraw;
hasMoved = rhs.hasMoved;
rigidBody = rhs.rigidBody;
shapeLibrary = rhs.shapeLibrary;
broadphase = rhs.broadphase;
transform = rhs.transform;
copyShapes(rhs);
SHCollider::operator=(rhs);
return *this;
}
SHCompositeCollider& SHCompositeCollider::operator=(SHCompositeCollider&& rhs) noexcept
{
if (!shapeLibrary)
{
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);
SHCollider::operator=(rhs);
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 */
/*-----------------------------------------------------------------------------------*/
const SHMatrix& SHCompositeCollider::ComputeTransformTRS() noexcept
{
return transform.ComputeTRS();
}
int SHCompositeCollider::AddSphereCollisionShape(float relativeRadius, const SHVec3& posOffset, const SHVec3& rotOffset)
{
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

View File

@ -1,7 +1,7 @@
/****************************************************************************************
* \file SHCollider.h
* \file SHCompositeCollider.h
* \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
* disclosure of this file or its contents without the prior written consent
@ -11,63 +11,26 @@
#pragma once
// Project Headers
#include "ECS_Base/Entity/SHEntity.h"
#include "Math/Transform/SHTransform.h"
#include "Physics/Collision/CollisionShapes/SHCollisionShapeLibrary.h"
#include "SHCollider.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
* Encapsulates the behaviour of a collider with composited shapes. <br/>
* 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:
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
/*---------------------------------------------------------------------------------*/
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
*/
SHCompositeCollider (EntityID eid, const SHTransform& worldTransform = SHTransform::Identity) noexcept;
SHCompositeCollider (const SHCompositeCollider& rhs) noexcept;
SHCompositeCollider (SHCompositeCollider&& rhs) noexcept;
~SHCompositeCollider () noexcept;
SHCompositeCollider(EntityID eid, const SHTransform& worldTransform = SHTransform::Identity) noexcept;
SHCompositeCollider(const SHCompositeCollider& rhs) noexcept;
SHCompositeCollider(SHCompositeCollider&& rhs) noexcept;
~SHCompositeCollider () noexcept override = default;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
@ -76,50 +39,10 @@ namespace SHADE
SHCompositeCollider& operator=(const 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 */
/*---------------------------------------------------------------------------------*/
/**
* @brief
* Computes the TRS for the collider's transform
* @return
* The computed TRS.
*/
const SHMatrix& ComputeTransformTRS() noexcept;
/**
* @brief
* 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);
// 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

View File

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

View File

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

View File

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

View File

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

View File

@ -25,30 +25,14 @@ namespace SHADE
{}
SHConvexPolyhedron::SHConvexPolyhedron(const SHConvexPolyhedron& rhs) noexcept
: SHCollisionShape (rhs.id, rhs.GetType())
, halfEdgeStructure { nullptr }
{
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;
}
: SHCollisionShape ( rhs )
, halfEdgeStructure { rhs.halfEdgeStructure }
{}
SHConvexPolyhedron::SHConvexPolyhedron(SHConvexPolyhedron&& rhs) noexcept
: SHCollisionShape (rhs.id, rhs.GetType())
, halfEdgeStructure { nullptr }
{
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;
}
: SHCollisionShape ( rhs )
, halfEdgeStructure { rhs.halfEdgeStructure }
{}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
@ -59,13 +43,7 @@ namespace SHADE
if (this == &rhs)
return *this;
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;
SHCollisionShape::operator=(rhs);
// Local Properties
halfEdgeStructure = rhs.halfEdgeStructure;
@ -75,13 +53,7 @@ namespace SHADE
SHConvexPolyhedron& SHConvexPolyhedron::operator=(SHConvexPolyhedron&& rhs) noexcept
{
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;
SHCollisionShape::operator=(rhs);
// Local Properties
halfEdgeStructure = rhs.halfEdgeStructure;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,7 +11,7 @@
#pragma once
// Project Headers
#include "Physics/Collision/SHCompositeCollider.h"
#include "Physics/Collision/SHCollider.h"
#include "Physics/Dynamics/SHRigidBody.h"
namespace SHADE
@ -33,7 +33,7 @@ namespace SHADE
EntityID entityID = MAX_EID;
SHRigidBody* rigidBody = nullptr;
SHCompositeCollider* collider = nullptr;
SHCollider* collider = nullptr;
/*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor */
@ -61,7 +61,7 @@ namespace SHADE
* @return
* True if the physics object has neither a rigid body nor a collider.
*/
[[nodiscard]] bool IsEmpty () const noexcept;
[[nodiscard]] bool IsEmpty () const noexcept;
/**
* @brief
@ -72,13 +72,13 @@ namespace SHADE
* Pointer to the rigid body that was created. The memory of this rigid body is managed
* by the physics object itself.
*/
SHRigidBody* CreateRigidBody (SHRigidBody::Type bodyType);
SHRigidBody* CreateRigidBody (SHRigidBody::Type bodyType);
/**
* @brief
* Destroys the rigid body of this physics object and frees the memory.
*/
void DestroyRigidBody () noexcept;
void DestroyRigidBody () noexcept;
/**
* @brief
@ -91,19 +91,19 @@ namespace SHADE
* Pointer to the collider that was created. The memory of this collider is managed
* by the physics object itself.
*/
SHCompositeCollider* CreateCollider (const SHTransform& transform = SHTransform::Identity);
SHCollider* CreateCompositeCollider (const SHTransform& transform = SHTransform::Identity);
/**
* @brief
* Destroys the collider of this physics object and frees the memory.
*/
void DestroyCollider () noexcept;
void DestroyCollider () noexcept;
private:
/*-----------------------------------------------------------------------------------*/
/* Member Functions */
/*-----------------------------------------------------------------------------------*/
void deepCopyComponents(const SHRigidBody* rhsRigidBody, const SHCompositeCollider* rhsCollider);
void deepCopyComponents(const SHRigidBody* rhsRigidBody, const SHCollider* rhsCollider);
};
} // namespace SHADE

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -122,7 +122,7 @@ namespace SHADE
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())
{

View File

@ -18,9 +18,9 @@
#include "ECS_Base/System/SHSystemRoutine.h"
#include "Events/SHEvent.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/CollisionShapes/SHSphere.h"
#include "Physics/Collision/Shapes/SHSphere.h"
namespace SHADE
@ -138,7 +138,7 @@ namespace SHADE
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;
};

View File

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

View File

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