Merge pull request #137 from SHADE-DP/SP3-2-Physics

SP3-2 Added Contact & Trigger Events + Bugfixes

NEW

Contacts & Trigger events are now reported (not implemented on scripting)
BUGFIXES

Fixed desync of rigidbody velocities
This commit is contained in:
XiaoQiDigipen 2022-10-31 16:32:34 +08:00 committed by GitHub
commit ef506a2ffe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 487 additions and 105 deletions

View File

@ -47,16 +47,14 @@ namespace SHADE
{ {
// Get the current scene graph to traverse and update // Get the current scene graph to traverse and update
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
UpdateEntity(SCENE_GRAPH.GetRoot(), !IsRunInEditorPause);
// TODO(Diren): Consider how to clear dirty in pause / stop mode and update physics, but do not clear in play mode.
UpdateEntity(SCENE_GRAPH.GetRoot(), false);
} }
void SHTransformSystem::TransformPostPhysicsUpdate::Execute(double) noexcept void SHTransformSystem::TransformPostPhysicsUpdate::Execute(double) noexcept
{ {
// Get the current scene graph to traverse and update // Get the current scene graph to traverse and update
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
UpdateEntity(SCENE_GRAPH.GetRoot(), true); UpdateEntity(SCENE_GRAPH.GetRoot(), IsRunInEditorPause);
} }
void SHTransformSystem::Init() void SHTransformSystem::Init()

View File

@ -96,7 +96,7 @@ namespace SHADE
void SetDensity (float density) noexcept; void SetDensity (float density) noexcept;
void SetMaterial (const SHPhysicsMaterial& newMaterial) noexcept; void SetMaterial (const SHPhysicsMaterial& newMaterial) noexcept;
void SetPositionOffset (const SHVec3& positionOffset) noexcept; void SetPositionOffset (const SHVec3& posOffset) noexcept;
private: private:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -172,11 +172,15 @@ namespace SHADE
{ {
SHASSERT(rp3dBody != nullptr, "ReactPhysics body does not exist!") SHASSERT(rp3dBody != nullptr, "ReactPhysics body does not exist!")
if (rb->dirtyFlags == 0)
return;
auto* rigidBody = reinterpret_cast<rp3d::RigidBody*>(rp3dBody); auto* rigidBody = reinterpret_cast<rp3d::RigidBody*>(rp3dBody);
// Sync velocities
rb->linearVelocity = rigidBody->getLinearVelocity();
rb->angularVelocity = rigidBody->getAngularVelocity();
if (rb->dirtyFlags == 0)
return;
const uint16_t RB_FLAGS = rb->dirtyFlags; const uint16_t RB_FLAGS = rb->dirtyFlags;
for (size_t i = 0; i < SHRigidBodyComponent::NUM_DIRTY_FLAGS; ++i) for (size_t i = 0; i < SHRigidBodyComponent::NUM_DIRTY_FLAGS; ++i)
{ {
@ -266,8 +270,12 @@ namespace SHADE
if (!collider.dirty) if (!collider.dirty)
continue; continue;
// Update offsets
auto* rp3dCollider = rp3dBody->getCollider(index); auto* rp3dCollider = rp3dBody->getCollider(index);
// Update trigger flag
rp3dCollider->setIsTrigger(collider.IsTrigger());
// Update offsets
rp3dCollider->setLocalToBodyTransform(rp3d::Transform(collider.GetPositionOffset(), SHQuaternion::Identity)); rp3dCollider->setLocalToBodyTransform(rp3d::Transform(collider.GetPositionOffset(), SHQuaternion::Identity));
switch (collider.GetType()) switch (collider.GetType())
@ -293,6 +301,8 @@ namespace SHADE
default: break; default: break;
} }
// TODO(Diren): Update Material
collider.dirty = false; collider.dirty = false;
++index; ++index;
} }

View File

@ -99,6 +99,16 @@ namespace SHADE
return 0; return 0;
} }
const SHPhysicsSystem::CollisionEvents& SHPhysicsSystem::GetCollisionInfo() const noexcept
{
return collisionInfo;
}
const SHPhysicsSystem::CollisionEvents& SHPhysicsSystem::GetTriggerInfo() const noexcept
{
return triggerInfo;
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Setter Function Definitions */ /* Setter Function Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -187,6 +197,7 @@ namespace SHADE
settings.defaultBounciness = 0.0f; settings.defaultBounciness = 0.0f;
world = factory.createPhysicsWorld(settings); world = factory.createPhysicsWorld(settings);
world->setEventListener(this);
// Set up solvers // Set up solvers
world->setContactsPositionCorrectionTechnique(rp3d::ContactsPositionCorrectionTechnique::SPLIT_IMPULSES); world->setContactsPositionCorrectionTechnique(rp3d::ContactsPositionCorrectionTechnique::SPLIT_IMPULSES);
@ -270,6 +281,14 @@ namespace SHADE
rp3dRigidBody->setLinearVelocity(SHVec3::Zero); rp3dRigidBody->setLinearVelocity(SHVec3::Zero);
rp3dRigidBody->setAngularVelocity(SHVec3::Zero); rp3dRigidBody->setAngularVelocity(SHVec3::Zero);
} }
const bool COMPONENT_ACTIVE = rigidBodyComponent->isActive;
system->SyncActiveStates(&physicsObject, COMPONENT_ACTIVE);
if (!COMPONENT_ACTIVE)
continue;
physicsObject.SyncRigidBody(rigidBodyComponent);
} }
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID); auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID);
@ -277,13 +296,17 @@ namespace SHADE
{ {
colliderComponent->position = WORLD_POS; colliderComponent->position = WORLD_POS;
colliderComponent->orientation = WORLD_ROT; colliderComponent->orientation = WORLD_ROT;
const bool COMPONENT_ACTIVE = colliderComponent->isActive;
system->SyncActiveStates(&physicsObject, COMPONENT_ACTIVE);
if (!COMPONENT_ACTIVE)
continue;
physicsObject.SyncColliders(colliderComponent);
} }
} }
} }
// Update bodies and colliders if component is dirty
system->SyncRigidBodyComponents(SHComponentManager::GetDense<SHRigidBodyComponent>());
system->SyncColliderComponents(SHComponentManager::GetDense<SHColliderComponent>());
} }
void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept
@ -316,7 +339,63 @@ namespace SHADE
{ {
system->SyncTransforms(); system->SyncTransforms();
// TODO(Diren): Handle trigger messages for scripting // TODO(Kah Wei): Take Collision & Trigger messages here
system->ClearInvalidCollisions();
}
}
void SHPhysicsSystem::onContact(const CallbackData& callbackData)
{
for (uint32_t i = 0; i < callbackData.getNbContactPairs(); ++i)
{
auto contactPair = callbackData.getContactPair(i);
SHCollisionEvent newCollisionEvent = GenerateCollisionEvent(contactPair);
// Find contact pair in container
auto existingEvent = std::ranges::find_if(collisionInfo.begin(), collisionInfo.end(), [&](const SHCollisionEvent& e)
{
const bool ENTITY_MATCH = e.value[0] == newCollisionEvent.value[0];
const bool COLLIDERS_MATCH = e.value[1] == newCollisionEvent.value[1];
return ENTITY_MATCH && COLLIDERS_MATCH;
});
if (existingEvent == collisionInfo.end())
{
// Add new event
collisionInfo.emplace_back(newCollisionEvent);
}
else
{
existingEvent->collisionState = newCollisionEvent.collisionState;
}
}
}
void SHPhysicsSystem::onTrigger(const rp3d::OverlapCallback::CallbackData& callbackData)
{
for (uint32_t i = 0; i < callbackData.getNbOverlappingPairs(); ++i)
{
auto contactPair = callbackData.getOverlappingPair(i);
SHCollisionEvent newTriggerEvent = GenerateCollisionEvent(contactPair);
// Find contact pair in container
auto existingEvent = std::ranges::find_if(collisionInfo.begin(), collisionInfo.end(), [&](const SHCollisionEvent& e)
{
const bool ENTITY_MATCH = e.value[0] == newTriggerEvent.value[0];
const bool COLLIDERS_MATCH = e.value[1] == newTriggerEvent.value[1];
return ENTITY_MATCH && COLLIDERS_MATCH;
});
if (existingEvent == collisionInfo.end())
{
// Add new event
triggerInfo.emplace_back(newTriggerEvent);
}
else
{
existingEvent->collisionState = newTriggerEvent.collisionState;
}
} }
} }
@ -360,53 +439,6 @@ namespace SHADE
physicsObject->rp3dBody->setIsActive(componentActive); physicsObject->rp3dBody->setIsActive(componentActive);
} }
void SHPhysicsSystem::SyncRigidBodyComponents(std::vector<SHRigidBodyComponent>& denseArray) noexcept
{
if (denseArray.empty())
return;
for (auto& comp : denseArray)
{
const EntityID ENTITY_ID = comp.GetEID();
// Get physicsObject
auto* physicsObject = GetPhysicsObject(ENTITY_ID);
// TODO(Diren): Check if active in hierarchy
const bool COMPONENT_ACTIVE = comp.isActive;
SyncActiveStates(physicsObject, COMPONENT_ACTIVE);
if (!COMPONENT_ACTIVE)
continue;
physicsObject->SyncRigidBody(&comp);
}
}
void SHPhysicsSystem::SyncColliderComponents(std::vector<SHColliderComponent>& denseArray) noexcept
{
if (denseArray.empty())
return;
for (auto& comp : denseArray)
{
const EntityID ENTITY_ID = comp.GetEID();
// Get physicsObject
auto* physicsObject = GetPhysicsObject(ENTITY_ID);
// TODO(Diren): Check if active in hierarchy
const bool COMPONENT_ACTIVE = comp.isActive;
SyncActiveStates(physicsObject, COMPONENT_ACTIVE);
if (!COMPONENT_ACTIVE)
continue;
physicsObject->SyncColliders(&comp);
}
}
void SHPhysicsSystem::SyncTransforms() noexcept void SHPhysicsSystem::SyncTransforms() noexcept
{ {
for (auto& [entityID, physicsObject] : map) for (auto& [entityID, physicsObject] : map)
@ -468,6 +500,146 @@ namespace SHADE
} }
} }
void SHPhysicsSystem::ClearInvalidCollisions() noexcept
{
for (auto collisionInfoIter = collisionInfo.begin(); collisionInfoIter != collisionInfo.end();)
{
if (collisionInfoIter->GetCollisionState() == SHCollisionEvent::State::EXIT
|| collisionInfoIter->GetCollisionState() == SHCollisionEvent::State::INVALID)
{
collisionInfoIter = collisionInfo.erase(collisionInfoIter);
}
else
{
++collisionInfoIter;
}
}
for (auto triggerInfoIter = triggerInfo.begin(); triggerInfoIter != triggerInfo.end();)
{
if (triggerInfoIter->GetCollisionState() == SHCollisionEvent::State::EXIT
|| triggerInfoIter->GetCollisionState() == SHCollisionEvent::State::INVALID)
{
triggerInfoIter = triggerInfo.erase(triggerInfoIter);
}
else
{
++triggerInfoIter;
}
}
}
SHCollisionEvent SHPhysicsSystem::GenerateCollisionEvent(const rp3d::CollisionCallback::ContactPair& cp) noexcept
{
static const auto MATCH_COLLIDER = [](const SHPhysicsObject& physicsObject, const rp3d::Entity colliderID)->uint32_t
{
for (uint32_t i = 0; i < physicsObject.rp3dBody->getNbColliders(); ++i)
{
const auto* collider = physicsObject.rp3dBody->getCollider(i);
if (collider->getEntity() == colliderID)
return i;
}
return std::numeric_limits<uint32_t>::max();
};
SHCollisionEvent cInfo;
// Update collision state
cInfo.collisionState = static_cast<SHCollisionEvent::State>(cp.getEventType());
// Match body and collider for collision event
const rp3d::Entity body1 = cp.getBody1()->getEntity();
const rp3d::Entity body2 = cp.getBody2()->getEntity();
const rp3d::Entity collider1 = cp.getCollider1()->getEntity();
const rp3d::Entity collider2 = cp.getCollider2()->getEntity();
// Find and match both ids
bool matched[2] = { false, false };
for (auto& [entityID, physicsObject] : map)
{
// Match body 1
if (matched[SHCollisionEvent::ENTITY_A] == false && physicsObject.rp3dBody->getEntity() == body1)
{
cInfo.ids[SHCollisionEvent::ENTITY_A] = entityID;
cInfo.ids[SHCollisionEvent::COLLIDER_A] = MATCH_COLLIDER(physicsObject, collider1);
matched[SHCollisionEvent::ENTITY_A] = true;
}
// Match body 2
if (matched[SHCollisionEvent::ENTITY_B] == false && physicsObject.rp3dBody->getEntity() == body2)
{
cInfo.ids[SHCollisionEvent::ENTITY_B] = entityID;
cInfo.ids[SHCollisionEvent::COLLIDER_B] = MATCH_COLLIDER(physicsObject, collider2);
matched[SHCollisionEvent::ENTITY_B] = true;
}
if (matched[SHCollisionEvent::ENTITY_A] == true && matched[SHCollisionEvent::ENTITY_B] == true)
return cInfo;
}
return cInfo;
}
SHCollisionEvent SHPhysicsSystem::GenerateCollisionEvent(const rp3d::OverlapCallback::OverlapPair& cp) noexcept
{
static const auto MATCH_COLLIDER = [](const SHPhysicsObject& physicsObject, const rp3d::Entity colliderID)->uint32_t
{
for (uint32_t i = 0; i < physicsObject.rp3dBody->getNbColliders(); ++i)
{
const auto* collider = physicsObject.rp3dBody->getCollider(i);
if (collider->getEntity() == colliderID)
return i;
}
return std::numeric_limits<uint32_t>::max();
};
SHCollisionEvent cInfo;
// Match body and collider for collision event
const rp3d::Entity body1 = cp.getBody1()->getEntity();
const rp3d::Entity body2 = cp.getBody2()->getEntity();
const rp3d::Entity collider1 = cp.getCollider1()->getEntity();
const rp3d::Entity collider2 = cp.getCollider2()->getEntity();
// Find and match both ids
bool matched[2] = { false, false };
for (auto& [entityID, physicsObject] : map)
{
// Match body 1
if (matched[SHCollisionEvent::ENTITY_A] == false && physicsObject.rp3dBody->getEntity() == body1)
{
cInfo.ids[SHCollisionEvent::ENTITY_A] = entityID;
cInfo.ids[SHCollisionEvent::COLLIDER_A] = MATCH_COLLIDER(physicsObject, collider1);
matched[SHCollisionEvent::ENTITY_A] = true;
}
// Match body 2
if (matched[SHCollisionEvent::ENTITY_B] == false && physicsObject.rp3dBody->getEntity() == body2)
{
cInfo.ids[SHCollisionEvent::ENTITY_B] = entityID;
cInfo.ids[SHCollisionEvent::COLLIDER_B] = MATCH_COLLIDER(physicsObject, collider2);
matched[SHCollisionEvent::ENTITY_B] = true;
}
if (matched[SHCollisionEvent::ENTITY_A] == true && matched[SHCollisionEvent::ENTITY_B] == true)
return cInfo;
}
// Update collision state
cInfo.collisionState = static_cast<SHCollisionEvent::State>(cp.getEventType());
return cInfo;
}
SHEventHandle SHPhysicsSystem::AddPhysicsComponent(SHEventPtr addComponentEvent) SHEventHandle SHPhysicsSystem::AddPhysicsComponent(SHEventPtr addComponentEvent)
{ {
const auto& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHComponentAddedEvent>*>(addComponentEvent.get()); const auto& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHComponentAddedEvent>*>(addComponentEvent.get());

View File

@ -23,7 +23,7 @@
#include "Math/Transform/SHTransformComponent.h" #include "Math/Transform/SHTransformComponent.h"
#include "Scene/SHSceneGraph.h" #include "Scene/SHSceneGraph.h"
#include "SHPhysicsObject.h" #include "SHPhysicsObject.h"
#include "SHPhysicsUtils.h"
namespace SHADE namespace SHADE
@ -32,7 +32,8 @@ namespace SHADE
/* Type Definitions */ /* Type Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
class SH_API SHPhysicsSystem final : public SHSystem class SH_API SHPhysicsSystem final : public SHSystem
, public rp3d::EventListener
{ {
public: public:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -47,6 +48,8 @@ namespace SHADE
bool sleepingEnabled; bool sleepingEnabled;
}; };
using CollisionEvents = std::vector<SHCollisionEvent>;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */ /* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -57,13 +60,16 @@ namespace SHADE
/* Getter Functions */ /* Getter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
[[nodiscard]] double GetFixedDT () const noexcept; [[nodiscard]] double GetFixedDT () const noexcept;
[[nodiscard]] bool IsSleepingEnabled () const noexcept; [[nodiscard]] bool IsSleepingEnabled () const noexcept;
[[nodiscard]] SHVec3 GetWorldGravity () const noexcept; [[nodiscard]] SHVec3 GetWorldGravity () const noexcept;
[[nodiscard]] uint16_t GetNumberVelocityIterations () const noexcept; [[nodiscard]] uint16_t GetNumberVelocityIterations () const noexcept;
[[nodiscard]] uint16_t GetNumberPositionIterations () const noexcept; [[nodiscard]] uint16_t GetNumberPositionIterations () const noexcept;
[[nodiscard]] const CollisionEvents& GetCollisionInfo () const noexcept;
[[nodiscard]] const CollisionEvents& GetTriggerInfo () const noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -82,16 +88,14 @@ namespace SHADE
/* Function Members */ /* Function Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void Init () override; void Init () override;
void Exit () override; void Exit () override;
//void AddRigidBody (EntityID entityID) noexcept; void AddCollisionShape (EntityID entityID, SHCollider* collider);
//void AddCollider (EntityID entityID) noexcept; void RemoveCollisionShape (EntityID entityID, int index);
//void RemoveRigidBody (EntityID entityID) noexcept;
//void RemoveCollider (EntityID entityID) noexcept;
void AddCollisionShape (EntityID entityID, SHCollider* collider); void onContact (const rp3d::CollisionCallback::CallbackData& callbackData) override;
void RemoveCollisionShape (EntityID entityID, int index); void onTrigger (const rp3d::OverlapCallback::CallbackData& callbackData) override;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* System Routines */ /* System Routines */
@ -156,49 +160,38 @@ namespace SHADE
/* Data Members */ /* Data Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
bool worldUpdated; bool worldUpdated;
double interpolationFactor; double interpolationFactor;
double fixedDT; double fixedDT;
rp3d::PhysicsWorld* world;
rp3d::PhysicsCommon factory;
EntityObjectMap map;
rp3d::PhysicsWorld* world;
rp3d::PhysicsCommon factory;
EntityObjectMap map;
CollisionEvents collisionInfo;
CollisionEvents triggerInfo;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Function Members */ /* Function Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept;
SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept;
void DestroyPhysicsObject (EntityID entityID) noexcept; SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept;
SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept;
void DestroyPhysicsObject (EntityID entityID) noexcept;
void SyncActiveStates (SHPhysicsObject* physicsObject, bool componentActive) noexcept; void SyncActiveStates (SHPhysicsObject* physicsObject, bool componentActive) noexcept;
void SyncRigidBodyComponents (std::vector<SHRigidBodyComponent>& denseArray) noexcept;
void SyncColliderComponents (std::vector<SHColliderComponent>& denseArray) noexcept;
void SyncTransforms () noexcept; void SyncTransforms () noexcept;
void ClearInvalidCollisions () noexcept;
SHCollisionEvent GenerateCollisionEvent (const rp3d::CollisionCallback::ContactPair& cp) noexcept;
SHCollisionEvent GenerateCollisionEvent (const rp3d::OverlapCallback::OverlapPair& cp) noexcept;
SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent); SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent);
SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent); SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent);
}; };
/*-----------------------------------------------------------------------------------*/
/* Event Data Definitions */
/*-----------------------------------------------------------------------------------*/
struct SHPhysicsColliderAddedEvent
{
EntityID entityID;
SHCollider::Type colliderType;
int colliderIndex;
};
struct SHPhysicsColliderRemovedEvent
{
EntityID entityID;
int colliderIndex;
};
} // namespace SHADE } // namespace SHADE

View File

@ -0,0 +1,93 @@
/****************************************************************************************
* \file SHPhysicsUtils.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for some Physics Utilities
*
* \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 "SHPhysicsUtils.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHCollisionEvent::SHCollisionEvent() noexcept
: collisionState { State::INVALID }
{
ids[ENTITY_A] = MAX_EID;
ids[ENTITY_B] = MAX_EID;
ids[COLLIDER_A] = std::numeric_limits<uint32_t>::max();
ids[COLLIDER_B] = std::numeric_limits<uint32_t>::max();
}
SHCollisionEvent::SHCollisionEvent(EntityID entityA, EntityID entityB) noexcept
: collisionState { State::INVALID }
{
ids[ENTITY_A] = entityA;
ids[ENTITY_B] = entityB;
ids[COLLIDER_A] = std::numeric_limits<uint32_t>::max();
ids[COLLIDER_B] = std::numeric_limits<uint32_t>::max();
}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/
bool SHCollisionEvent::operator==(const SHCollisionEvent& rhs) const noexcept
{
return value[0] == rhs.value[0] && value[1] == rhs.value[1];
}
bool SHCollisionEvent::operator!=(const SHCollisionEvent& rhs) const noexcept
{
return value[0] != rhs.value[0] || value[1] != rhs.value[1];
}
/*-----------------------------------------------------------------------------------*/
/* Getter Function Definitions */
/*-----------------------------------------------------------------------------------*/
EntityID SHCollisionEvent::GetEntityA() const noexcept
{
return ids[ENTITY_A];
}
EntityID SHCollisionEvent::GetEntityB() const noexcept
{
return ids[ENTITY_B];
}
const SHRigidBodyComponent* SHCollisionEvent::GetRigidBodyA() const noexcept
{
return SHComponentManager::GetComponent_s<SHRigidBodyComponent>(ids[ENTITY_A]);
}
const SHRigidBodyComponent* SHCollisionEvent::GetRigidBodyB() const noexcept
{
return SHComponentManager::GetComponent_s<SHRigidBodyComponent>(ids[ENTITY_B]);
}
const SHCollider* SHCollisionEvent::GetColliderA() const noexcept
{
return &SHComponentManager::GetComponent<SHColliderComponent>(ids[ENTITY_A])->GetCollider(ids[COLLIDER_A]);
}
const SHCollider* SHCollisionEvent::GetColliderB() const noexcept
{
return &SHComponentManager::GetComponent<SHColliderComponent>(ids[ENTITY_B])->GetCollider(ids[COLLIDER_B]);
}
SHCollisionEvent::State SHCollisionEvent::GetCollisionState() const noexcept
{
return collisionState;
}
} // namespace SHADE

View File

@ -0,0 +1,116 @@
/****************************************************************************************
* \file SHPhysicsUtils.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for some Physics Utilities
*
* \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 "Components/SHColliderComponent.h"
#include "Components/SHRigidBodyComponent.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
struct SHPhysicsColliderAddedEvent
{
EntityID entityID;
SHCollider::Type colliderType;
int colliderIndex;
};
struct SHPhysicsColliderRemovedEvent
{
EntityID entityID;
int colliderIndex;
};
class SH_API SHCollisionEvent
{
private:
/*---------------------------------------------------------------------------------*/
/* Friends */
/*---------------------------------------------------------------------------------*/
friend class SHPhysicsSystem;
public:
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
/*---------------------------------------------------------------------------------*/
enum class State
{
ENTER
, STAY
, EXIT
, TOTAL
, INVALID = -1
};
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
SHCollisionEvent () noexcept;
SHCollisionEvent (EntityID entityA, EntityID entityB) noexcept;
SHCollisionEvent (const SHCollisionEvent& rhs) = default;
SHCollisionEvent (SHCollisionEvent&& rhs) = default;
~SHCollisionEvent () = default;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
/*---------------------------------------------------------------------------------*/
bool operator== (const SHCollisionEvent& rhs) const noexcept;
bool operator!= (const SHCollisionEvent& rhs) const noexcept;
SHCollisionEvent& operator= (const SHCollisionEvent& rhs) = default;
SHCollisionEvent& operator= (SHCollisionEvent&& rhs) = default;
/*---------------------------------------------------------------------------------*/
/* Getter Functions */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] EntityID GetEntityA () const noexcept;
[[nodiscard]] EntityID GetEntityB () const noexcept;
[[nodiscard]] const SHRigidBodyComponent* GetRigidBodyA () const noexcept;
[[nodiscard]] const SHRigidBodyComponent* GetRigidBodyB () const noexcept;
[[nodiscard]] const SHCollider* GetColliderA () const noexcept;
[[nodiscard]] const SHCollider* GetColliderB () const noexcept;
[[nodiscard]] State GetCollisionState () const noexcept;
private:
static constexpr uint32_t ENTITY_A = 0;
static constexpr uint32_t ENTITY_B = 1;
static constexpr uint32_t COLLIDER_A = 2;
static constexpr uint32_t COLLIDER_B = 3;
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
union
{
uint64_t value[2]; // EntityValue, ColliderIndexValue
uint32_t ids [4]; // EntityA, EntityB, ColliderIndexA, ColliderIndexB
};
State collisionState;
};
} // namespace SHADE