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
|
// 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()
|
||||||
|
|
|
@ -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:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -172,11 +172,15 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHASSERT(rp3dBody != nullptr, "ReactPhysics body does not exist!")
|
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)
|
if (rb->dirtyFlags == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto* rigidBody = reinterpret_cast<rp3d::RigidBody*>(rp3dBody);
|
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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
|
|
@ -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