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:
commit
ef506a2ffe
|
@ -47,16 +47,14 @@ namespace SHADE
|
|||
{
|
||||
// Get the current scene graph to traverse and update
|
||||
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
||||
|
||||
// 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);
|
||||
UpdateEntity(SCENE_GRAPH.GetRoot(), !IsRunInEditorPause);
|
||||
}
|
||||
|
||||
void SHTransformSystem::TransformPostPhysicsUpdate::Execute(double) noexcept
|
||||
{
|
||||
// Get the current scene graph to traverse and update
|
||||
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
||||
UpdateEntity(SCENE_GRAPH.GetRoot(), true);
|
||||
UpdateEntity(SCENE_GRAPH.GetRoot(), IsRunInEditorPause);
|
||||
}
|
||||
|
||||
void SHTransformSystem::Init()
|
||||
|
|
|
@ -96,7 +96,7 @@ namespace SHADE
|
|||
void SetDensity (float density) noexcept;
|
||||
void SetMaterial (const SHPhysicsMaterial& newMaterial) noexcept;
|
||||
|
||||
void SetPositionOffset (const SHVec3& positionOffset) noexcept;
|
||||
void SetPositionOffset (const SHVec3& posOffset) noexcept;
|
||||
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -172,11 +172,15 @@ namespace SHADE
|
|||
{
|
||||
SHASSERT(rp3dBody != nullptr, "ReactPhysics body does not exist!")
|
||||
|
||||
auto* rigidBody = reinterpret_cast<rp3d::RigidBody*>(rp3dBody);
|
||||
|
||||
// Sync velocities
|
||||
rb->linearVelocity = rigidBody->getLinearVelocity();
|
||||
rb->angularVelocity = rigidBody->getAngularVelocity();
|
||||
|
||||
if (rb->dirtyFlags == 0)
|
||||
return;
|
||||
|
||||
auto* rigidBody = reinterpret_cast<rp3d::RigidBody*>(rp3dBody);
|
||||
|
||||
const uint16_t RB_FLAGS = rb->dirtyFlags;
|
||||
for (size_t i = 0; i < SHRigidBodyComponent::NUM_DIRTY_FLAGS; ++i)
|
||||
{
|
||||
|
@ -266,8 +270,12 @@ namespace SHADE
|
|||
if (!collider.dirty)
|
||||
continue;
|
||||
|
||||
// Update offsets
|
||||
auto* rp3dCollider = rp3dBody->getCollider(index);
|
||||
|
||||
// Update trigger flag
|
||||
rp3dCollider->setIsTrigger(collider.IsTrigger());
|
||||
|
||||
// Update offsets
|
||||
rp3dCollider->setLocalToBodyTransform(rp3d::Transform(collider.GetPositionOffset(), SHQuaternion::Identity));
|
||||
|
||||
switch (collider.GetType())
|
||||
|
@ -293,6 +301,8 @@ namespace SHADE
|
|||
default: break;
|
||||
}
|
||||
|
||||
// TODO(Diren): Update Material
|
||||
|
||||
collider.dirty = false;
|
||||
++index;
|
||||
}
|
||||
|
|
|
@ -99,6 +99,16 @@ namespace SHADE
|
|||
return 0;
|
||||
}
|
||||
|
||||
const SHPhysicsSystem::CollisionEvents& SHPhysicsSystem::GetCollisionInfo() const noexcept
|
||||
{
|
||||
return collisionInfo;
|
||||
}
|
||||
|
||||
const SHPhysicsSystem::CollisionEvents& SHPhysicsSystem::GetTriggerInfo() const noexcept
|
||||
{
|
||||
return triggerInfo;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Setter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -187,6 +197,7 @@ namespace SHADE
|
|||
settings.defaultBounciness = 0.0f;
|
||||
|
||||
world = factory.createPhysicsWorld(settings);
|
||||
world->setEventListener(this);
|
||||
|
||||
// Set up solvers
|
||||
world->setContactsPositionCorrectionTechnique(rp3d::ContactsPositionCorrectionTechnique::SPLIT_IMPULSES);
|
||||
|
@ -270,6 +281,14 @@ namespace SHADE
|
|||
rp3dRigidBody->setLinearVelocity(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);
|
||||
|
@ -277,13 +296,17 @@ namespace SHADE
|
|||
{
|
||||
colliderComponent->position = WORLD_POS;
|
||||
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
|
||||
|
@ -316,7 +339,63 @@ namespace SHADE
|
|||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
const auto& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHComponentAddedEvent>*>(addComponentEvent.get());
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "Math/Transform/SHTransformComponent.h"
|
||||
#include "Scene/SHSceneGraph.h"
|
||||
#include "SHPhysicsObject.h"
|
||||
|
||||
#include "SHPhysicsUtils.h"
|
||||
|
||||
|
||||
namespace SHADE
|
||||
|
@ -32,7 +32,8 @@ namespace SHADE
|
|||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
class SH_API SHPhysicsSystem final : public SHSystem
|
||||
class SH_API SHPhysicsSystem final : public SHSystem
|
||||
, public rp3d::EventListener
|
||||
{
|
||||
public:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -47,6 +48,8 @@ namespace SHADE
|
|||
bool sleepingEnabled;
|
||||
};
|
||||
|
||||
using CollisionEvents = std::vector<SHCollisionEvent>;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -57,13 +60,16 @@ namespace SHADE
|
|||
/* 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]] uint16_t GetNumberVelocityIterations () const noexcept;
|
||||
[[nodiscard]] uint16_t GetNumberPositionIterations () const noexcept;
|
||||
[[nodiscard]] SHVec3 GetWorldGravity () const noexcept;
|
||||
[[nodiscard]] uint16_t GetNumberVelocityIterations () 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 */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
void Init () override;
|
||||
void Exit () override;
|
||||
void Init () override;
|
||||
void Exit () override;
|
||||
|
||||
//void AddRigidBody (EntityID entityID) noexcept;
|
||||
//void AddCollider (EntityID entityID) noexcept;
|
||||
//void RemoveRigidBody (EntityID entityID) noexcept;
|
||||
//void RemoveCollider (EntityID entityID) noexcept;
|
||||
void AddCollisionShape (EntityID entityID, SHCollider* collider);
|
||||
void RemoveCollisionShape (EntityID entityID, int index);
|
||||
|
||||
void AddCollisionShape (EntityID entityID, SHCollider* collider);
|
||||
void RemoveCollisionShape (EntityID entityID, int index);
|
||||
void onContact (const rp3d::CollisionCallback::CallbackData& callbackData) override;
|
||||
void onTrigger (const rp3d::OverlapCallback::CallbackData& callbackData) override;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* System Routines */
|
||||
|
@ -156,49 +160,38 @@ namespace SHADE
|
|||
/* Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
bool worldUpdated;
|
||||
bool worldUpdated;
|
||||
|
||||
double interpolationFactor;
|
||||
double fixedDT;
|
||||
|
||||
rp3d::PhysicsWorld* world;
|
||||
rp3d::PhysicsCommon factory;
|
||||
|
||||
EntityObjectMap map;
|
||||
double interpolationFactor;
|
||||
double fixedDT;
|
||||
|
||||
rp3d::PhysicsWorld* world;
|
||||
rp3d::PhysicsCommon factory;
|
||||
|
||||
EntityObjectMap map;
|
||||
CollisionEvents collisionInfo;
|
||||
CollisionEvents triggerInfo;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* 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 SyncRigidBodyComponents (std::vector<SHRigidBodyComponent>& denseArray) noexcept;
|
||||
void SyncColliderComponents (std::vector<SHColliderComponent>& denseArray) 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 RemovePhysicsComponent (SHEventPtr removeComponentEvent);
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Event Data Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
struct SHPhysicsColliderAddedEvent
|
||||
{
|
||||
EntityID entityID;
|
||||
SHCollider::Type colliderType;
|
||||
int colliderIndex;
|
||||
};
|
||||
|
||||
struct SHPhysicsColliderRemovedEvent
|
||||
{
|
||||
EntityID entityID;
|
||||
int colliderIndex;
|
||||
};
|
||||
|
||||
} // namespace SHADE
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue