Implemented a custom physics engine #316

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

View File

@ -49,7 +49,7 @@ namespace SHADE
friend class SHCollider; friend class SHCollider;
friend class SHCollision; friend class SHCollision;
friend class SHCompositeCollider; friend class SHCompositeCollider;
friend class SHCollisionShapeFactory; friend class SHCollisionShapeLibrary;
public: public:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -42,7 +42,7 @@ namespace SHADE
friend class SHCollider; friend class SHCollider;
friend class SHColliderComponent; friend class SHColliderComponent;
friend class SHCollisionShapeFactory; friend class SHCollisionShapeLibrary;
friend class SHCollisionSpace; friend class SHCollisionSpace;
friend struct SHManifold; friend struct SHManifold;
@ -65,7 +65,7 @@ namespace SHADE
/* Constructors & Destructor */ /* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHCollisionShape (SHCollisionShapeID id, Type colliderType = Type::BOX); SHCollisionShape (SHCollisionShapeID id, Type colliderType = Type::SPHERE);
SHCollisionShape (const SHCollisionShape& rhs) noexcept = default; SHCollisionShape (const SHCollisionShape& rhs) noexcept = default;
SHCollisionShape (SHCollisionShape&& rhs) noexcept = default; SHCollisionShape (SHCollisionShape&& rhs) noexcept = default;

View File

@ -1,5 +1,5 @@
/**************************************************************************************** /****************************************************************************************
* \file SHCollisionShapeFactory.cpp * \file SHCollisionShapeLibrary.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520 * \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for a Collison Shape Factory Class. * \brief Implementation for a Collison Shape Factory Class.
* *
@ -11,7 +11,7 @@
#include <SHpch.h> #include <SHpch.h>
// Primary Header // Primary Header
#include "SHCollisionShapeFactory.h" #include "SHCollisionShapeLibrary.h"
namespace SHADE namespace SHADE
{ {
@ -19,7 +19,12 @@ namespace SHADE
/* Constructors & Destructor Definitions */ /* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHCollisionShapeFactory::~SHCollisionShapeFactory() noexcept SHCollisionShapeLibrary::SHCollisionShapeLibrary() noexcept
{
createBoxPolyhedron();
}
SHCollisionShapeLibrary::~SHCollisionShapeLibrary() noexcept
{ {
// Free all shapes in each container // Free all shapes in each container
for (auto* sphereCollisionShape : spheres | std::views::values) for (auto* sphereCollisionShape : spheres | std::views::values)
@ -34,7 +39,7 @@ namespace SHADE
/* Public Member Function Definitions */ /* Public Member Function Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHSphereCollisionShape* SHCollisionShapeFactory::CreateSphere(SHCollisionShapeID id, const SHSphereCreateInfo& createInfo) SHSphereCollisionShape* SHCollisionShapeLibrary::CreateSphere(SHCollisionShapeID id, const SHSphereCreateInfo& createInfo)
{ {
const auto RESULT = spheres.emplace(id, new SHSphereCollisionShape{ id }); const auto RESULT = spheres.emplace(id, new SHSphereCollisionShape{ id });
if (RESULT.second) if (RESULT.second)
@ -52,7 +57,7 @@ namespace SHADE
return spheres.find(id)->second; return spheres.find(id)->second;
} }
SHBoxCollisionShape* SHCollisionShapeFactory::CreateBox(SHCollisionShapeID id, const SHBoxCreateInfo& createInfo) SHBoxCollisionShape* SHCollisionShapeLibrary::CreateBox(SHCollisionShapeID id, const SHBoxCreateInfo& createInfo)
{ {
const auto RESULT = boxes.emplace(id, new SHBoxCollisionShape{ id }); const auto RESULT = boxes.emplace(id, new SHBoxCollisionShape{ id });
if (RESULT.second) if (RESULT.second)
@ -72,7 +77,7 @@ namespace SHADE
} }
void SHCollisionShapeFactory::DestroyShape(SHCollisionShape* shape) void SHCollisionShapeLibrary::DestroyShape(SHCollisionShape* shape)
{ {
switch (shape->GetType()) switch (shape->GetType())
{ {
@ -97,4 +102,34 @@ namespace SHADE
default: break; default: break;
} }
} }
/*-----------------------------------------------------------------------------------*/
/* Private Member Function Definitions */
/*-----------------------------------------------------------------------------------*/
void SHCollisionShapeLibrary::createBoxPolyhedron() noexcept
{
/*
* Vertices (Front/Back Face):
*
* 3/7 ---------- 2/6
* | |
* | |
* | |
* 0/4 ---------- 1/5
*
* Faces:
*
* Front: 0 (0,1,2,3)
* Right: 1 (1,5,6,2)
* Back: 2 (5,4,7,6)
* Left: 3 (4,0,3,7)
* Top: 4 (3,2,6,7)
* Bottom: 5 (4,5,1,0)
*
*/
// Create face data
}
} // namespace SHADE } // namespace SHADE

View File

@ -1,7 +1,7 @@
/**************************************************************************************** /****************************************************************************************
* \file SHCollisionShapeFactory.h * \file SHCollisionShapeLibrary.h
* \author Diren D Bharwani, diren.dbharwani, 390002520 * \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for a Collison Shape Factory Class. * \brief Interface for a Collison Shape Library.
* *
* \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
@ -24,19 +24,18 @@ namespace SHADE
/** /**
* @brief * @brief
* Encapsulates a class for Creating and Destroying Collision Shapes. <br/> * Encapsulates a class for Creating, Storing and Destroying Collision Shapes. <br/>
* All memory for collision shapes are handled in this factory class. <br/> * All memory for collision shapes are stored in this factory class. <br/>
* TODO: Support instancing of shapes
*/ */
class SH_API SHCollisionShapeFactory final class SH_API SHCollisionShapeLibrary final
{ {
public: public:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */ /* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHCollisionShapeFactory () noexcept = default; SHCollisionShapeLibrary () noexcept;
~SHCollisionShapeFactory () noexcept; ~SHCollisionShapeLibrary () noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Function Members */ /* Function Members */
@ -93,9 +92,17 @@ namespace SHADE
/* Data Members */ /* Data Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHConvexPolyhedron boxPolyhedron;
Spheres spheres; Spheres spheres;
Boxes boxes; Boxes boxes;
// TODO: Add capsules and hulls // TODO: Add capsules and hulls
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
void createBoxPolyhedron() noexcept;
}; };
} // namespace SHADE } // namespace SHADE

View File

@ -48,7 +48,7 @@ namespace SHADE
friend class SHCollider; friend class SHCollider;
friend class SHCollision; friend class SHCollision;
friend class SHCompositeCollider; friend class SHCompositeCollider;
friend class SHCollisionShapeFactory; friend class SHCollisionShapeLibrary;
public: public:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -33,7 +33,7 @@ namespace SHADE
, debugDraw { false } , debugDraw { false }
, hasMoved { true } , hasMoved { true }
, rigidBody { nullptr } , rigidBody { nullptr }
, shapeFactory { nullptr } , shapeLibrary { nullptr }
, broadphase { nullptr } , broadphase { nullptr }
, transform { worldTransform } , transform { worldTransform }
{} {}
@ -44,11 +44,11 @@ namespace SHADE
, debugDraw { rhs.debugDraw } , debugDraw { rhs.debugDraw }
, hasMoved { rhs.hasMoved } , hasMoved { rhs.hasMoved }
, rigidBody { rhs.rigidBody } , rigidBody { rhs.rigidBody }
, shapeFactory { rhs.shapeFactory } , shapeLibrary { rhs.shapeLibrary }
, broadphase { rhs.broadphase } , broadphase { rhs.broadphase }
, transform { rhs.transform } , transform { rhs.transform }
{ {
if (!shapeFactory) if (!shapeLibrary)
{ {
SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add copy shapes!", entityID) SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add copy shapes!", entityID)
return; return;
@ -63,11 +63,11 @@ namespace SHADE
, debugDraw { rhs.debugDraw } , debugDraw { rhs.debugDraw }
, hasMoved { rhs.hasMoved } , hasMoved { rhs.hasMoved }
, rigidBody { rhs.rigidBody } , rigidBody { rhs.rigidBody }
, shapeFactory { rhs.shapeFactory } , shapeLibrary { rhs.shapeLibrary }
, broadphase { rhs.broadphase } , broadphase { rhs.broadphase }
, transform { rhs.transform } , transform { rhs.transform }
{ {
if (!shapeFactory) if (!shapeLibrary)
{ {
SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add copy shapes!", entityID) SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add copy shapes!", entityID)
return; return;
@ -78,14 +78,14 @@ namespace SHADE
SHCollider::~SHCollider() noexcept SHCollider::~SHCollider() noexcept
{ {
if (!shapeFactory) if (!shapeLibrary)
{ {
SHLOGV_ERROR("Shape factory is unlinked with Composite Collider {}. Unable to add destroy collider!", entityID) SHLOGV_ERROR("Shape factory is unlinked with Composite Collider {}. Unable to add destroy collider!", entityID)
return; return;
} }
for (auto* shape : shapes) for (auto* shape : shapes)
shapeFactory->DestroyShape(shape); shapeLibrary->DestroyShape(shape);
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -97,7 +97,7 @@ namespace SHADE
if (this == &rhs) if (this == &rhs)
return *this; return *this;
if (!shapeFactory) if (!shapeLibrary)
{ {
SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add copy shapes!", entityID) SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add copy shapes!", entityID)
return *this; return *this;
@ -108,7 +108,7 @@ namespace SHADE
debugDraw = rhs.debugDraw; debugDraw = rhs.debugDraw;
hasMoved = rhs.hasMoved; hasMoved = rhs.hasMoved;
rigidBody = rhs.rigidBody; rigidBody = rhs.rigidBody;
shapeFactory = rhs.shapeFactory; shapeLibrary = rhs.shapeLibrary;
broadphase = rhs.broadphase; broadphase = rhs.broadphase;
transform = rhs.transform; transform = rhs.transform;
@ -119,7 +119,7 @@ namespace SHADE
SHCollider& SHCollider::operator=(SHCollider&& rhs) noexcept SHCollider& SHCollider::operator=(SHCollider&& rhs) noexcept
{ {
if (!shapeFactory) if (!shapeLibrary)
{ {
SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add copy shapes!", entityID) SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add copy shapes!", entityID)
return *this; return *this;
@ -130,7 +130,7 @@ namespace SHADE
debugDraw = rhs.debugDraw; debugDraw = rhs.debugDraw;
hasMoved = rhs.hasMoved; hasMoved = rhs.hasMoved;
rigidBody = rhs.rigidBody; rigidBody = rhs.rigidBody;
shapeFactory = rhs.shapeFactory; shapeLibrary = rhs.shapeLibrary;
broadphase = rhs.broadphase; broadphase = rhs.broadphase;
transform = rhs.transform; transform = rhs.transform;
@ -263,9 +263,9 @@ namespace SHADE
transform.scale = newScale; transform.scale = newScale;
} }
void SHCollider::SetFactory(SHCollisionShapeFactory* factory) noexcept void SHCollider::SetFactory(SHCollisionShapeLibrary* factory) noexcept
{ {
shapeFactory = factory; shapeLibrary = factory;
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -279,7 +279,7 @@ namespace SHADE
int SHCollider::AddSphereCollisionShape(float relativeRadius, const SHVec3& posOffset, const SHVec3& rotOffset) int SHCollider::AddSphereCollisionShape(float relativeRadius, const SHVec3& posOffset, const SHVec3& rotOffset)
{ {
if (!shapeFactory) if (!shapeLibrary)
{ {
SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add new shape!", entityID) SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add new shape!", entityID)
return -1; return -1;
@ -304,7 +304,7 @@ namespace SHADE
const uint32_t NEW_INDEX = static_cast<uint32_t>(shapes.size()); const uint32_t NEW_INDEX = static_cast<uint32_t>(shapes.size());
const SHCollisionShapeID NEW_SHAPE_ID{ entityID, NEW_INDEX }; const SHCollisionShapeID NEW_SHAPE_ID{ entityID, NEW_INDEX };
SHSphereCollisionShape* sphere = shapeFactory->CreateSphere(NEW_SHAPE_ID, SPHERE_CREATE_INFO); SHSphereCollisionShape* sphere = shapeLibrary->CreateSphere(NEW_SHAPE_ID, SPHERE_CREATE_INFO);
// Set offsets // Set offsets
sphere->collider = this; sphere->collider = this;
@ -334,7 +334,7 @@ namespace SHADE
int SHCollider::AddBoxCollisionShape(const SHVec3& relativeExtents, const SHVec3& posOffset, const SHVec3& rotOffset) int SHCollider::AddBoxCollisionShape(const SHVec3& relativeExtents, const SHVec3& posOffset, const SHVec3& rotOffset)
{ {
if (!shapeFactory) if (!shapeLibrary)
{ {
SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add new shape!", entityID) SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add new shape!", entityID)
return -1; return -1;
@ -357,7 +357,7 @@ namespace SHADE
const uint32_t NEW_INDEX = static_cast<uint32_t>(shapes.size()); const uint32_t NEW_INDEX = static_cast<uint32_t>(shapes.size());
const SHCollisionShapeID NEW_SHAPE_ID{ entityID, NEW_INDEX }; const SHCollisionShapeID NEW_SHAPE_ID{ entityID, NEW_INDEX };
SHBoxCollisionShape* box = shapeFactory->CreateBox(NEW_SHAPE_ID, BOX_CREATE_INFO); SHBoxCollisionShape* box = shapeLibrary->CreateBox(NEW_SHAPE_ID, BOX_CREATE_INFO);
// Set offsets // Set offsets
box->collider = this; box->collider = this;
@ -388,7 +388,7 @@ namespace SHADE
void SHCollider::RemoveCollisionShape(int index) void SHCollider::RemoveCollisionShape(int index)
{ {
if (!shapeFactory) if (!shapeLibrary)
{ {
SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add remove shape!", entityID) SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add remove shape!", entityID)
return; return;
@ -417,7 +417,7 @@ namespace SHADE
if (broadphase) if (broadphase)
broadphase->Remove((*shape)->id); broadphase->Remove((*shape)->id);
shapeFactory->DestroyShape(*shape); shapeLibrary->DestroyShape(*shape);
*shape = nullptr; *shape = nullptr;
// Remove the shape from the container to prevent accessing a nullptr // Remove the shape from the container to prevent accessing a nullptr
@ -473,7 +473,7 @@ namespace SHADE
const uint32_t NEW_INDEX = static_cast<uint32_t>(shapes.size()); const uint32_t NEW_INDEX = static_cast<uint32_t>(shapes.size());
const SHCollisionShapeID NEW_SHAPE_ID{ entityID, NEW_INDEX }; const SHCollisionShapeID NEW_SHAPE_ID{ entityID, NEW_INDEX };
SHSphereCollisionShape* sphere = shapeFactory->CreateSphere(NEW_SHAPE_ID, SPHERE_CREATE_INFO); SHSphereCollisionShape* sphere = shapeLibrary->CreateSphere(NEW_SHAPE_ID, SPHERE_CREATE_INFO);
*sphere = *RHS_SPHERE; *sphere = *RHS_SPHERE;
shapes.emplace_back(sphere); shapes.emplace_back(sphere);

View File

@ -13,7 +13,7 @@
// Project Headers // Project Headers
#include "ECS_Base/Entity/SHEntity.h" #include "ECS_Base/Entity/SHEntity.h"
#include "Math/Transform/SHTransform.h" #include "Math/Transform/SHTransform.h"
#include "Physics/Collision/CollisionShapes/SHCollisionShapeFactory.h" #include "Physics/Collision/CollisionShapes/SHCollisionShapeLibrary.h"
namespace SHADE namespace SHADE
{ {
@ -106,7 +106,7 @@ namespace SHADE
void SetOrientation (const SHQuaternion& newOrientation) noexcept; void SetOrientation (const SHQuaternion& newOrientation) noexcept;
void SetScale (const SHVec3& newScale) noexcept; void SetScale (const SHVec3& newScale) noexcept;
void SetFactory (SHCollisionShapeFactory* factory) noexcept; void SetFactory (SHCollisionShapeLibrary* factory) noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Member Functions */ /* Member Functions */
@ -181,7 +181,7 @@ namespace SHADE
bool hasMoved; bool hasMoved;
SHRigidBody* rigidBody; SHRigidBody* rigidBody;
SHCollisionShapeFactory* shapeFactory; SHCollisionShapeLibrary* shapeLibrary;
SHAABBTree* broadphase; SHAABBTree* broadphase;
SHTransform transform; SHTransform transform;

View File

@ -67,15 +67,17 @@ namespace SHADE
auto* rigidBody = physicsObject->CreateRigidBody(RIGID_BODY_TYPE); auto* rigidBody = physicsObject->CreateRigidBody(RIGID_BODY_TYPE);
SHVec3 worldPos = SHVec3::Zero; SHVec3 worldPos = SHVec3::Zero;
// TODO: Force orientation SHQuaternion worldRot = SHQuaternion::Identity;
if (const auto* TRANSFORM_COMPONENT = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID); TRANSFORM_COMPONENT) if (const auto* TRANSFORM_COMPONENT = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID); TRANSFORM_COMPONENT)
{ {
worldPos = TRANSFORM_COMPONENT->GetWorldPosition(); worldPos = TRANSFORM_COMPONENT->GetWorldPosition();
worldRot = TRANSFORM_COMPONENT->GetWorldOrientation();
} }
SHMotionState& motionState = rigidBody->GetMotionState(); SHMotionState& motionState = rigidBody->GetMotionState();
motionState.ForcePosition(worldPos); motionState.ForcePosition(worldPos);
motionState.ForceOrientation(worldRot);
// Link with the component // Link with the component
rigidBodyComponent->SetRigidBody(rigidBody); rigidBodyComponent->SetRigidBody(rigidBody);
@ -115,7 +117,7 @@ namespace SHADE
// Create a new composite collider in the physics object // Create a new composite collider in the physics object
physicsObject->CreateCollider(worldTransform); physicsObject->CreateCollider(worldTransform);
physicsObject->collider->SetFactory(&shapeFactory); physicsObject->collider->SetFactory(&shapeLibrary);
// Link with the component // Link with the component
colliderComponent->SetCollider(physicsObject->collider); colliderComponent->SetCollider(physicsObject->collider);

View File

@ -14,7 +14,7 @@
// Project Headers // Project Headers
#include "SHPhysicsObject.h" #include "SHPhysicsObject.h"
#include "Physics/Collision/CollisionShapes/SHCollisionShapeFactory.h" #include "Physics/Collision/CollisionShapes/SHCollisionShapeLibrary.h"
namespace SHADE namespace SHADE
{ {
@ -100,7 +100,7 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
EntityObjectMap physicsObjects; EntityObjectMap physicsObjects;
SHCollisionShapeFactory shapeFactory; SHCollisionShapeLibrary shapeLibrary;
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Member Functions */ /* Member Functions */