Implemented a custom physics engine #316
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************************
|
||||
* \file SHCollisionID.h
|
||||
* \file SHCollisionKey.h
|
||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||
* \brief Interface for Collision Information for Collision & Triggers.
|
||||
*
|
||||
|
@ -11,7 +11,7 @@
|
|||
#pragma once
|
||||
|
||||
// Project Headers
|
||||
#include "SHCollisionID.h"
|
||||
#include "SHCollisionKey.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -37,7 +37,7 @@ namespace SHADE
|
|||
struct SH_API SHTriggerEvent
|
||||
{
|
||||
public:
|
||||
SHCollisionID info;
|
||||
SHCollisionKey info;
|
||||
SHCollisionState state;
|
||||
};
|
||||
|
||||
|
@ -51,7 +51,7 @@ namespace SHADE
|
|||
public:
|
||||
static constexpr int MAX_NUM_CONTACTS = 4;
|
||||
|
||||
SHCollisionID info;
|
||||
SHCollisionKey info;
|
||||
SHCollisionState state;
|
||||
SHVec3 normal;
|
||||
SHVec3 contactPoints[MAX_NUM_CONTACTS];
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include <SHpch.h>
|
||||
|
||||
// Primary Header
|
||||
#include "SHCollisionID.h"
|
||||
#include "SHCollisionKey.h"
|
||||
|
||||
// Project Headers
|
||||
#include "Physics/Collision/SHCollider.h"
|
||||
|
@ -24,7 +24,7 @@ namespace SHADE
|
|||
/* Constructors & Destructor Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHCollisionID::SHCollisionID() noexcept
|
||||
SHCollisionKey::SHCollisionKey() noexcept
|
||||
{
|
||||
ids[ENTITY_A] = MAX_EID;
|
||||
ids[ENTITY_B] = MAX_EID;
|
||||
|
@ -32,13 +32,13 @@ namespace SHADE
|
|||
ids[SHAPE_INDEX_B] = std::numeric_limits<uint32_t>::max();
|
||||
}
|
||||
|
||||
SHCollisionID::SHCollisionID(const SHCollisionID& rhs) noexcept
|
||||
SHCollisionKey::SHCollisionKey(const SHCollisionKey& rhs) noexcept
|
||||
{
|
||||
value[0] = rhs.value[0];
|
||||
value[1] = rhs.value[1];
|
||||
}
|
||||
|
||||
SHCollisionID::SHCollisionID(SHCollisionID&& rhs) noexcept
|
||||
SHCollisionKey::SHCollisionKey(SHCollisionKey&& rhs) noexcept
|
||||
{
|
||||
value[0] = rhs.value[0];
|
||||
value[1] = rhs.value[1];
|
||||
|
@ -48,7 +48,7 @@ namespace SHADE
|
|||
/* Operator Overload Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHCollisionID& SHCollisionID::operator=(const SHCollisionID& rhs) noexcept
|
||||
SHCollisionKey& SHCollisionKey::operator=(const SHCollisionKey& rhs) noexcept
|
||||
{
|
||||
if (this == &rhs)
|
||||
return *this;
|
||||
|
@ -59,7 +59,7 @@ namespace SHADE
|
|||
return *this;
|
||||
}
|
||||
|
||||
SHCollisionID& SHCollisionID::operator=(SHCollisionID&& rhs) noexcept
|
||||
SHCollisionKey& SHCollisionKey::operator=(SHCollisionKey&& rhs) noexcept
|
||||
{
|
||||
value[0] = rhs.value[0];
|
||||
value[1] = rhs.value[1];
|
||||
|
@ -67,7 +67,7 @@ namespace SHADE
|
|||
return *this;
|
||||
}
|
||||
|
||||
bool SHCollisionID::operator==(const SHCollisionID& rhs) const
|
||||
bool SHCollisionKey::operator==(const SHCollisionKey& rhs) const
|
||||
{
|
||||
// When checking for equal, check both ways.
|
||||
// Exact Match (A, idxA, B, idxB)
|
||||
|
@ -83,43 +83,43 @@ namespace SHADE
|
|||
/* Getter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
EntityID SHCollisionID::GetEntityA() const noexcept
|
||||
EntityID SHCollisionKey::GetEntityA() const noexcept
|
||||
{
|
||||
return ids[ENTITY_A];
|
||||
}
|
||||
|
||||
EntityID SHCollisionID::GetEntityB() const noexcept
|
||||
EntityID SHCollisionKey::GetEntityB() const noexcept
|
||||
{
|
||||
return ids[ENTITY_B];
|
||||
}
|
||||
|
||||
uint32_t SHCollisionID::GetShapeIndexA() const noexcept
|
||||
uint32_t SHCollisionKey::GetShapeIndexA() const noexcept
|
||||
{
|
||||
return ids[SHAPE_INDEX_A];
|
||||
}
|
||||
|
||||
uint32_t SHCollisionID::GetShapeIndexB() const noexcept
|
||||
uint32_t SHCollisionKey::GetShapeIndexB() const noexcept
|
||||
{
|
||||
return ids[SHAPE_INDEX_B];
|
||||
}
|
||||
|
||||
const SHRigidBodyComponent* SHCollisionID::GetRigidBodyA() const noexcept
|
||||
const SHRigidBodyComponent* SHCollisionKey::GetRigidBodyA() const noexcept
|
||||
{
|
||||
return SHComponentManager::GetComponent_s<SHRigidBodyComponent>(ids[ENTITY_A]);
|
||||
}
|
||||
|
||||
const SHRigidBodyComponent* SHCollisionID::GetRigidBodyB() const noexcept
|
||||
const SHRigidBodyComponent* SHCollisionKey::GetRigidBodyB() const noexcept
|
||||
{
|
||||
return SHComponentManager::GetComponent_s<SHRigidBodyComponent>(ids[ENTITY_B]);
|
||||
}
|
||||
|
||||
const SHCollisionShape* SHCollisionID::GetCollisionShapeA() const noexcept
|
||||
const SHCollisionShape* SHCollisionKey::GetCollisionShapeA() const noexcept
|
||||
{
|
||||
const auto* COLLIDER_COMPONENT = SHComponentManager::GetComponent<SHColliderComponent>(ids[ENTITY_A]);
|
||||
return COLLIDER_COMPONENT->GetCollider()->GetCollisionShape(ids[SHAPE_INDEX_A]);
|
||||
}
|
||||
|
||||
const SHCollisionShape* SHCollisionID::GetCollisionShapeB() const noexcept
|
||||
const SHCollisionShape* SHCollisionKey::GetCollisionShapeB() const noexcept
|
||||
{
|
||||
const auto* COLLIDER_COMPONENT = SHComponentManager::GetComponent<SHColliderComponent>(ids[ENTITY_B]);
|
||||
return COLLIDER_COMPONENT->GetCollider()->GetCollisionShape(ids[SHAPE_INDEX_B]);
|
||||
|
@ -129,24 +129,38 @@ namespace SHADE
|
|||
/* Setter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
void SHCollisionID::SetEntityA(EntityID entityID) noexcept
|
||||
void SHCollisionKey::SetEntityA(EntityID entityID) noexcept
|
||||
{
|
||||
ids[ENTITY_A] = entityID;
|
||||
}
|
||||
|
||||
void SHCollisionID::SetEntityB(EntityID entityID) noexcept
|
||||
void SHCollisionKey::SetEntityB(EntityID entityID) noexcept
|
||||
{
|
||||
ids[ENTITY_B] = entityID;
|
||||
}
|
||||
|
||||
void SHCollisionID::SetCollisionShapeA(uint32_t shapeIndexA) noexcept
|
||||
void SHCollisionKey::SetCollisionShapeA(uint32_t shapeIndexA) noexcept
|
||||
{
|
||||
ids[SHAPE_INDEX_A] = shapeIndexA;
|
||||
}
|
||||
|
||||
void SHCollisionID::SetCollisionShapeB(uint32_t shapeIndexB) noexcept
|
||||
void SHCollisionKey::SetCollisionShapeB(uint32_t shapeIndexB) noexcept
|
||||
{
|
||||
ids[SHAPE_INDEX_B] = shapeIndexB;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Public Function Member Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
std::size_t SHCollisionKeyHash::operator()(const SHCollisionKey& id) const
|
||||
{
|
||||
static constexpr int NUM_IDS = ARRAYSIZE(id.ids);
|
||||
|
||||
// Hashable is not a word. Sue me.
|
||||
auto hashablePtr = reinterpret_cast<std::basic_string_view<char32_t>::const_pointer>(id.ids);
|
||||
return std::hash<std::u32string_view>{}(std::u32string_view(hashablePtr, NUM_IDS));
|
||||
}
|
||||
|
||||
|
||||
} // namespace SHADE
|
|
@ -21,7 +21,7 @@ namespace SHADE
|
|||
/* Forward Declarations */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
struct SHCollisionIDHash;
|
||||
struct SHCollisionKeyHash;
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
|
@ -29,37 +29,36 @@ namespace SHADE
|
|||
|
||||
/**
|
||||
* @brief
|
||||
* Encapsulates the information when two colliders intersect and do not have physical
|
||||
* resolution.
|
||||
* Encapsulates the information when two collision shapes intersect.
|
||||
*/
|
||||
class SH_API SHCollisionID
|
||||
class SH_API SHCollisionKey
|
||||
{
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Friends */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
friend struct SHCollisionIDHash;
|
||||
friend struct SHCollisionKeyHash;
|
||||
|
||||
public:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
SHCollisionID () noexcept;
|
||||
SHCollisionID (const SHCollisionID& rhs) noexcept;
|
||||
SHCollisionID (SHCollisionID&& rhs) noexcept;
|
||||
SHCollisionKey () noexcept;
|
||||
SHCollisionKey (const SHCollisionKey& rhs) noexcept;
|
||||
SHCollisionKey (SHCollisionKey&& rhs) noexcept;
|
||||
|
||||
~SHCollisionID () noexcept = default;
|
||||
~SHCollisionKey () noexcept = default;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Operator Overloads */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
SHCollisionID& operator= (const SHCollisionID& rhs) noexcept;
|
||||
SHCollisionID& operator= (SHCollisionID&& rhs) noexcept;
|
||||
SHCollisionKey& operator= (const SHCollisionKey& rhs) noexcept;
|
||||
SHCollisionKey& operator= (SHCollisionKey&& rhs) noexcept;
|
||||
|
||||
bool operator==(const SHCollisionID& rhs) const;
|
||||
bool operator==(const SHCollisionKey& rhs) const;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Getter Functions */
|
||||
|
@ -103,19 +102,16 @@ namespace SHADE
|
|||
|
||||
/**
|
||||
* @brief
|
||||
* Encapsulates a functor to hash a CollisionID
|
||||
* Encapsulates a functor to hash a CollisionKey
|
||||
*/
|
||||
struct SHCollisionIDHash
|
||||
struct SHCollisionKeyHash
|
||||
{
|
||||
public:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Member Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
inline std::size_t operator()(const SHCollisionID& id) const
|
||||
{
|
||||
return std::hash<std::u32string_view>{}(std::u32string_view(reinterpret_cast<std::basic_string_view<char32_t>::const_pointer>(id.ids), 4));
|
||||
}
|
||||
std::size_t operator()(const SHCollisionKey& id) const;
|
||||
};
|
||||
|
||||
} // namespace SHADE
|
|
@ -13,7 +13,7 @@
|
|||
// Project Headers
|
||||
#include "Physics/Collision/CollisionShapes/SHCollisionShape.h"
|
||||
#include "Physics/Collision/Contacts/SHManifold.h"
|
||||
#include "Physics/Collision/Contacts/SHCollisionID.h"
|
||||
#include "Physics/Collision/Contacts/SHCollisionKey.h"
|
||||
|
||||
|
||||
namespace SHADE
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
// Project Headers
|
||||
#include "Physics/Collision/Contacts/SHManifold.h"
|
||||
#include "Physics/Collision/Contacts/SHCollisionID.h"
|
||||
#include "Physics/Collision/Contacts/SHCollisionKey.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
|
|
@ -326,7 +326,7 @@ namespace SHADE
|
|||
auto* shapeB = colliders[ID_B]->GetCollisionShape(INDEX_B);
|
||||
|
||||
// Build collision ID
|
||||
SHCollisionID collisionKey;
|
||||
SHCollisionKey collisionKey;
|
||||
collisionKey.SetEntityA(ID_A);
|
||||
collisionKey.SetEntityB(ID_B);
|
||||
collisionKey.SetCollisionShapeA(INDEX_A);
|
||||
|
@ -361,7 +361,7 @@ namespace SHADE
|
|||
auto* shapeB = colliders[ID_B]->GetCollisionShape(INDEX_B);
|
||||
|
||||
// Build collision ID
|
||||
SHCollisionID collisionKey;
|
||||
SHCollisionKey collisionKey;
|
||||
collisionKey.SetEntityA(ID_A);
|
||||
collisionKey.SetEntityB(ID_B);
|
||||
collisionKey.SetCollisionShapeA(INDEX_A);
|
||||
|
@ -396,7 +396,7 @@ namespace SHADE
|
|||
narrowphaseBatch.clear();
|
||||
}
|
||||
|
||||
void SHPhysicsWorld::collideTriggers(const SHCollisionID& id, NarrowphasePair& narrowphasePair) noexcept
|
||||
void SHPhysicsWorld::collideTriggers(const SHCollisionKey& id, NarrowphasePair& narrowphasePair) noexcept
|
||||
{
|
||||
const auto* A = narrowphasePair.A;
|
||||
const auto* B = narrowphasePair.B;
|
||||
|
@ -419,7 +419,7 @@ namespace SHADE
|
|||
trigger = triggers.erase(trigger);
|
||||
}
|
||||
|
||||
void SHPhysicsWorld::collideManifolds(const SHCollisionID& id, NarrowphasePair& narrowphasePair) noexcept
|
||||
void SHPhysicsWorld::collideManifolds(const SHCollisionKey& id, NarrowphasePair& narrowphasePair) noexcept
|
||||
{
|
||||
auto* A = narrowphasePair.A;
|
||||
auto* B = narrowphasePair.B;
|
||||
|
|
|
@ -113,9 +113,9 @@ namespace SHADE
|
|||
|
||||
// Collisions
|
||||
|
||||
using NarrowphaseBatch = std::unordered_map<SHCollisionID, NarrowphasePair, SHCollisionIDHash>;
|
||||
using Manifolds = std::unordered_map<SHCollisionID, SHManifold, SHCollisionIDHash>;
|
||||
using Triggers = std::unordered_map<SHCollisionID, SHCollisionState, SHCollisionIDHash>;
|
||||
using NarrowphaseBatch = std::unordered_map<SHCollisionKey, NarrowphasePair, SHCollisionKeyHash>;
|
||||
using Manifolds = std::unordered_map<SHCollisionKey, SHManifold, SHCollisionKeyHash>;
|
||||
using Triggers = std::unordered_map<SHCollisionKey, SHCollisionState, SHCollisionKeyHash>;
|
||||
|
||||
|
||||
|
||||
|
@ -155,8 +155,8 @@ namespace SHADE
|
|||
// Narrowphase helpers
|
||||
|
||||
void runNarrowphase () noexcept;
|
||||
void collideTriggers (const SHCollisionID& id, NarrowphasePair& narrowphasePair) noexcept;
|
||||
void collideManifolds (const SHCollisionID& id, NarrowphasePair& narrowphasePair) noexcept;
|
||||
void collideTriggers (const SHCollisionKey& id, NarrowphasePair& narrowphasePair) noexcept;
|
||||
void collideManifolds (const SHCollisionKey& id, NarrowphasePair& narrowphasePair) noexcept;
|
||||
void updateCollisionState (bool isColliding, SHCollisionState& state) noexcept;
|
||||
|
||||
void updateEvents () noexcept;
|
||||
|
|
|
@ -40,10 +40,6 @@ namespace SHADE
|
|||
eventFunctions[1] = { &SHPhysicsSystem::onComponentRemoved, SH_COMPONENT_REMOVED_EVENT };
|
||||
eventFunctions[2] = { &SHPhysicsSystem::onSceneInit , SH_SCENE_INIT_POST };
|
||||
eventFunctions[3] = { &SHPhysicsSystem::onSceneExit , SH_SCENE_EXIT_POST };
|
||||
|
||||
//#ifdef SHEDITOR
|
||||
// eventFunctions[4] = { &SHPhysicsSystem::onEditorPlay , SH_EDITOR_ON_PLAY_EVENT };
|
||||
//#endif
|
||||
}
|
||||
|
||||
SHPhysicsSystem::~SHPhysicsSystem() noexcept
|
||||
|
@ -178,6 +174,10 @@ namespace SHADE
|
|||
// Create the physics world
|
||||
physicsWorld = new SHPhysicsWorld;
|
||||
|
||||
// Immediately add all existing bodies and colliders to the world.
|
||||
// Since we recreated the scene and the world, the initial data has been reset and determinism is guaranteed.
|
||||
// Only if the current scene data changes, then so would the results of the simulation.
|
||||
|
||||
for (const auto& PHYSICS_OBJECT : physicsObjectManager.GetPhysicsObjects() | std::views::values)
|
||||
{
|
||||
if (PHYSICS_OBJECT.rigidBody)
|
||||
|
@ -187,26 +187,6 @@ namespace SHADE
|
|||
physicsWorld->AddCollider(PHYSICS_OBJECT.collider);
|
||||
}
|
||||
|
||||
//#ifdef SHEDITOR
|
||||
|
||||
// // Link all entities with the world if editor is already playing.
|
||||
// // This is for handling scene changes while the editor is active.
|
||||
//
|
||||
// const auto* EDITOR = SHSystemManager::GetSystem<SHEditor>();
|
||||
// if (!EDITOR || EDITOR->editorState != SHEditor::State::PLAY)
|
||||
// return onSceneInitEvent.get()->handle;
|
||||
|
||||
// for (const auto& PHYSICS_OBJECT : physicsObjectManager.GetPhysicsObjects() | std::views::values)
|
||||
// {
|
||||
// if (PHYSICS_OBJECT.rigidBody)
|
||||
// physicsWorld->AddRigidBody(PHYSICS_OBJECT.rigidBody);
|
||||
|
||||
// if (PHYSICS_OBJECT.collider)
|
||||
// physicsWorld->AddCollider(PHYSICS_OBJECT.collider);
|
||||
// }
|
||||
|
||||
//#endif
|
||||
|
||||
return onSceneInitEvent.get()->handle;
|
||||
}
|
||||
|
||||
|
@ -262,7 +242,6 @@ namespace SHADE
|
|||
physicsWorld->AddRigidBody(rigidBody);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (IS_COLLIDER)
|
||||
{
|
||||
|
@ -323,24 +302,4 @@ namespace SHADE
|
|||
return onComponentRemovedEvent.get()->handle;
|
||||
}
|
||||
|
||||
#ifdef SHEDITOR
|
||||
|
||||
SHEventHandle SHPhysicsSystem::onEditorPlay(SHEventPtr onEditorPlayEvent)
|
||||
{
|
||||
// Add all physics components to the physics world
|
||||
for (const auto& PHYSICS_OBJECT : physicsObjectManager.GetPhysicsObjects() | std::views::values)
|
||||
{
|
||||
// Add rigid body if it exists
|
||||
if (PHYSICS_OBJECT.rigidBody)
|
||||
physicsWorld->AddRigidBody(PHYSICS_OBJECT.rigidBody);
|
||||
|
||||
if (PHYSICS_OBJECT.collider)
|
||||
physicsWorld->AddCollider(PHYSICS_OBJECT.collider);
|
||||
}
|
||||
|
||||
return onEditorPlayEvent.get()->handle;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace SHADE
|
|
@ -124,11 +124,7 @@ namespace SHADE
|
|||
/* Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
//#ifdef SHEDITOR
|
||||
// static constexpr int NUM_EVENT_FUNCTIONS = 5;
|
||||
//#else
|
||||
static constexpr int NUM_EVENT_FUNCTIONS = 4;
|
||||
//#endif
|
||||
|
||||
// Event function container for cleanly registering to events
|
||||
EventFunctionPair eventFunctions[NUM_EVENT_FUNCTIONS];
|
||||
|
@ -152,14 +148,5 @@ namespace SHADE
|
|||
|
||||
SHEventHandle onComponentAdded (SHEventPtr onComponentAddedEvent);
|
||||
SHEventHandle onComponentRemoved (SHEventPtr onComponentRemovedEvent);
|
||||
|
||||
|
||||
#ifdef SHEDITOR
|
||||
|
||||
SHEventHandle onEditorPlay (SHEventPtr onEditorPlayEvent);
|
||||
// We don't need an onEditorStop because on stop exits the scene, which is already handled above.
|
||||
|
||||
#endif
|
||||
|
||||
};
|
||||
} // namespace SHADE
|
Loading…
Reference in New Issue