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 SHCollision;
friend class SHCompositeCollider;
friend class SHCollisionShapeFactory;
friend class SHCollisionShapeLibrary;
public:
/*---------------------------------------------------------------------------------*/

View File

@ -42,7 +42,7 @@ namespace SHADE
friend class SHCollider;
friend class SHColliderComponent;
friend class SHCollisionShapeFactory;
friend class SHCollisionShapeLibrary;
friend class SHCollisionSpace;
friend struct SHManifold;
@ -65,7 +65,7 @@ namespace SHADE
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
SHCollisionShape (SHCollisionShapeID id, Type colliderType = Type::BOX);
SHCollisionShape (SHCollisionShapeID id, Type colliderType = Type::SPHERE);
SHCollisionShape (const 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
* \brief Implementation for a Collison Shape Factory Class.
*
@ -11,7 +11,7 @@
#include <SHpch.h>
// Primary Header
#include "SHCollisionShapeFactory.h"
#include "SHCollisionShapeLibrary.h"
namespace SHADE
{
@ -19,7 +19,12 @@ namespace SHADE
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHCollisionShapeFactory::~SHCollisionShapeFactory() noexcept
SHCollisionShapeLibrary::SHCollisionShapeLibrary() noexcept
{
createBoxPolyhedron();
}
SHCollisionShapeLibrary::~SHCollisionShapeLibrary() noexcept
{
// Free all shapes in each container
for (auto* sphereCollisionShape : spheres | std::views::values)
@ -34,7 +39,7 @@ namespace SHADE
/* 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 });
if (RESULT.second)
@ -52,7 +57,7 @@ namespace SHADE
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 });
if (RESULT.second)
@ -72,7 +77,7 @@ namespace SHADE
}
void SHCollisionShapeFactory::DestroyShape(SHCollisionShape* shape)
void SHCollisionShapeLibrary::DestroyShape(SHCollisionShape* shape)
{
switch (shape->GetType())
{
@ -97,4 +102,34 @@ namespace SHADE
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

View File

@ -1,7 +1,7 @@
/****************************************************************************************
* \file SHCollisionShapeFactory.h
* \file SHCollisionShapeLibrary.h
* \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
* disclosure of this file or its contents without the prior written consent
@ -24,19 +24,18 @@ namespace SHADE
/**
* @brief
* Encapsulates a class for Creating and Destroying Collision Shapes. <br/>
* All memory for collision shapes are handled in this factory class. <br/>
* TODO: Support instancing of shapes
* Encapsulates a class for Creating, Storing and Destroying Collision Shapes. <br/>
* All memory for collision shapes are stored in this factory class. <br/>
*/
class SH_API SHCollisionShapeFactory final
class SH_API SHCollisionShapeLibrary final
{
public:
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
SHCollisionShapeFactory () noexcept = default;
~SHCollisionShapeFactory () noexcept;
SHCollisionShapeLibrary () noexcept;
~SHCollisionShapeLibrary () noexcept;
/*---------------------------------------------------------------------------------*/
/* Function Members */
@ -92,10 +91,18 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
SHConvexPolyhedron boxPolyhedron;
Spheres spheres;
Boxes boxes;
// TODO: Add capsules and hulls
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
void createBoxPolyhedron() noexcept;
};
} // namespace SHADE

View File

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

View File

@ -33,7 +33,7 @@ namespace SHADE
, debugDraw { false }
, hasMoved { true }
, rigidBody { nullptr }
, shapeFactory { nullptr }
, shapeLibrary { nullptr }
, broadphase { nullptr }
, transform { worldTransform }
{}
@ -44,11 +44,11 @@ namespace SHADE
, debugDraw { rhs.debugDraw }
, hasMoved { rhs.hasMoved }
, rigidBody { rhs.rigidBody }
, shapeFactory { rhs.shapeFactory }
, shapeLibrary { rhs.shapeLibrary }
, broadphase { rhs.broadphase }
, transform { rhs.transform }
{
if (!shapeFactory)
if (!shapeLibrary)
{
SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add copy shapes!", entityID)
return;
@ -63,11 +63,11 @@ namespace SHADE
, debugDraw { rhs.debugDraw }
, hasMoved { rhs.hasMoved }
, rigidBody { rhs.rigidBody }
, shapeFactory { rhs.shapeFactory }
, shapeLibrary { rhs.shapeLibrary }
, broadphase { rhs.broadphase }
, transform { rhs.transform }
{
if (!shapeFactory)
if (!shapeLibrary)
{
SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add copy shapes!", entityID)
return;
@ -78,14 +78,14 @@ namespace SHADE
SHCollider::~SHCollider() noexcept
{
if (!shapeFactory)
if (!shapeLibrary)
{
SHLOGV_ERROR("Shape factory is unlinked with Composite Collider {}. Unable to add destroy collider!", entityID)
return;
}
for (auto* shape : shapes)
shapeFactory->DestroyShape(shape);
shapeLibrary->DestroyShape(shape);
}
/*-----------------------------------------------------------------------------------*/
@ -97,7 +97,7 @@ namespace SHADE
if (this == &rhs)
return *this;
if (!shapeFactory)
if (!shapeLibrary)
{
SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add copy shapes!", entityID)
return *this;
@ -108,7 +108,7 @@ namespace SHADE
debugDraw = rhs.debugDraw;
hasMoved = rhs.hasMoved;
rigidBody = rhs.rigidBody;
shapeFactory = rhs.shapeFactory;
shapeLibrary = rhs.shapeLibrary;
broadphase = rhs.broadphase;
transform = rhs.transform;
@ -119,7 +119,7 @@ namespace SHADE
SHCollider& SHCollider::operator=(SHCollider&& rhs) noexcept
{
if (!shapeFactory)
if (!shapeLibrary)
{
SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add copy shapes!", entityID)
return *this;
@ -130,7 +130,7 @@ namespace SHADE
debugDraw = rhs.debugDraw;
hasMoved = rhs.hasMoved;
rigidBody = rhs.rigidBody;
shapeFactory = rhs.shapeFactory;
shapeLibrary = rhs.shapeLibrary;
broadphase = rhs.broadphase;
transform = rhs.transform;
@ -263,9 +263,9 @@ namespace SHADE
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)
{
if (!shapeFactory)
if (!shapeLibrary)
{
SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add new shape!", entityID)
return -1;
@ -304,7 +304,7 @@ namespace SHADE
const uint32_t NEW_INDEX = static_cast<uint32_t>(shapes.size());
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
sphere->collider = this;
@ -334,7 +334,7 @@ namespace SHADE
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)
return -1;
@ -357,7 +357,7 @@ namespace SHADE
const uint32_t NEW_INDEX = static_cast<uint32_t>(shapes.size());
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
box->collider = this;
@ -388,7 +388,7 @@ namespace SHADE
void SHCollider::RemoveCollisionShape(int index)
{
if (!shapeFactory)
if (!shapeLibrary)
{
SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add remove shape!", entityID)
return;
@ -417,7 +417,7 @@ namespace SHADE
if (broadphase)
broadphase->Remove((*shape)->id);
shapeFactory->DestroyShape(*shape);
shapeLibrary->DestroyShape(*shape);
*shape = 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 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;
shapes.emplace_back(sphere);

View File

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

View File

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

View File

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