Merge pull request #140 from SHADE-DP/SP3-2-Physics
SP3-2 Physics Bugfixes BUGFIXES Fixed the same velocity bug from before :< Trigger Info are now stored in the correct container
This commit is contained in:
commit
13c8928828
|
@ -173,14 +173,8 @@ 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);
|
auto* rigidBody = reinterpret_cast<rp3d::RigidBody*>(rp3dBody);
|
||||||
|
if (rb->dirtyFlags != 0)
|
||||||
// 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)
|
||||||
{
|
{
|
||||||
|
@ -261,6 +255,12 @@ namespace SHADE
|
||||||
|
|
||||||
rb->dirtyFlags = 0;
|
rb->dirtyFlags = 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rb->linearVelocity = rigidBody->getLinearVelocity();
|
||||||
|
rb->angularVelocity = rigidBody->getAngularVelocity();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept
|
void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept
|
||||||
{
|
{
|
||||||
|
|
|
@ -258,6 +258,9 @@ namespace SHADE
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
|
const auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
|
||||||
|
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID);
|
||||||
|
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID);
|
||||||
|
|
||||||
if (transformComponent && transformComponent->HasChanged())
|
if (transformComponent && transformComponent->HasChanged())
|
||||||
{
|
{
|
||||||
const auto WORLD_POS = transformComponent->GetWorldPosition();
|
const auto WORLD_POS = transformComponent->GetWorldPosition();
|
||||||
|
@ -266,12 +269,25 @@ namespace SHADE
|
||||||
physicsObject.SetPosition(WORLD_POS);
|
physicsObject.SetPosition(WORLD_POS);
|
||||||
physicsObject.SetOrientation(WORLD_ROT);
|
physicsObject.SetOrientation(WORLD_ROT);
|
||||||
|
|
||||||
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID);
|
// Sync physics component transforms
|
||||||
|
|
||||||
if (rigidBodyComponent)
|
if (rigidBodyComponent)
|
||||||
{
|
{
|
||||||
rigidBodyComponent->position = WORLD_POS;
|
rigidBodyComponent->position = WORLD_POS;
|
||||||
rigidBodyComponent->orientation = WORLD_ROT;
|
rigidBodyComponent->orientation = WORLD_ROT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colliderComponent)
|
||||||
|
{
|
||||||
|
colliderComponent->position = WORLD_POS;
|
||||||
|
colliderComponent->orientation = WORLD_ROT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sync rigid bodies
|
||||||
|
|
||||||
|
if (rigidBodyComponent)
|
||||||
|
{
|
||||||
// Clear all forces and velocities if editor is stopped
|
// Clear all forces and velocities if editor is stopped
|
||||||
if (SHSystemManager::GetSystem<SHEditor>()->editorState == SHEditor::State::STOP)
|
if (SHSystemManager::GetSystem<SHEditor>()->editorState == SHEditor::State::STOP)
|
||||||
{
|
{
|
||||||
|
@ -282,8 +298,9 @@ namespace SHADE
|
||||||
rp3dRigidBody->setAngularVelocity(SHVec3::Zero);
|
rp3dRigidBody->setAngularVelocity(SHVec3::Zero);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sync active states
|
||||||
const bool COMPONENT_ACTIVE = rigidBodyComponent->isActive;
|
const bool COMPONENT_ACTIVE = rigidBodyComponent->isActive;
|
||||||
system->SyncActiveStates(&physicsObject, COMPONENT_ACTIVE);
|
SyncActiveStates(physicsObject, COMPONENT_ACTIVE);
|
||||||
|
|
||||||
if (!COMPONENT_ACTIVE)
|
if (!COMPONENT_ACTIVE)
|
||||||
continue;
|
continue;
|
||||||
|
@ -291,14 +308,12 @@ namespace SHADE
|
||||||
physicsObject.SyncRigidBody(rigidBodyComponent);
|
physicsObject.SyncRigidBody(rigidBodyComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID);
|
// Sync colliders
|
||||||
|
|
||||||
if (colliderComponent)
|
if (colliderComponent)
|
||||||
{
|
{
|
||||||
colliderComponent->position = WORLD_POS;
|
|
||||||
colliderComponent->orientation = WORLD_ROT;
|
|
||||||
|
|
||||||
const bool COMPONENT_ACTIVE = colliderComponent->isActive;
|
const bool COMPONENT_ACTIVE = colliderComponent->isActive;
|
||||||
system->SyncActiveStates(&physicsObject, COMPONENT_ACTIVE);
|
SyncActiveStates(physicsObject, colliderComponent->isActive);
|
||||||
|
|
||||||
if (!COMPONENT_ACTIVE)
|
if (!COMPONENT_ACTIVE)
|
||||||
continue;
|
continue;
|
||||||
|
@ -307,7 +322,6 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept
|
void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept
|
||||||
{
|
{
|
||||||
|
@ -349,26 +363,10 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < callbackData.getNbContactPairs(); ++i)
|
for (uint32_t i = 0; i < callbackData.getNbContactPairs(); ++i)
|
||||||
{
|
{
|
||||||
auto contactPair = callbackData.getContactPair(i);
|
const auto CONTACT_PAIR = callbackData.getContactPair(i);
|
||||||
SHCollisionEvent newCollisionEvent = GenerateCollisionEvent(contactPair);
|
const SHCollisionEvent NEW_EVENT = GenerateCollisionEvent(CONTACT_PAIR);
|
||||||
|
|
||||||
// Find contact pair in container
|
UpdateEventContainers(NEW_EVENT, collisionInfo);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,26 +374,10 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < callbackData.getNbOverlappingPairs(); ++i)
|
for (uint32_t i = 0; i < callbackData.getNbOverlappingPairs(); ++i)
|
||||||
{
|
{
|
||||||
auto contactPair = callbackData.getOverlappingPair(i);
|
const auto& OVERLAP_PAIR = callbackData.getOverlappingPair(i);
|
||||||
SHCollisionEvent newTriggerEvent = GenerateCollisionEvent(contactPair);
|
const SHCollisionEvent NEW_EVENT = GenerateCollisionEvent(OVERLAP_PAIR);
|
||||||
|
|
||||||
// Find contact pair in container
|
UpdateEventContainers(NEW_EVENT, triggerInfo);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,11 +414,11 @@ namespace SHADE
|
||||||
map.erase(entityID);
|
map.erase(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPhysicsSystem::SyncActiveStates(SHPhysicsObject* physicsObject, bool componentActive) noexcept
|
void SHPhysicsSystem::SyncActiveStates(SHPhysicsObject& physicsObject, bool componentActive) noexcept
|
||||||
{
|
{
|
||||||
const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive();
|
const bool RP3D_ACTIVE = physicsObject.rp3dBody->isActive();
|
||||||
if (RP3D_ACTIVE != componentActive)
|
if (RP3D_ACTIVE != componentActive)
|
||||||
physicsObject->rp3dBody->setIsActive(componentActive);
|
physicsObject.rp3dBody->setIsActive(componentActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPhysicsSystem::SyncTransforms() noexcept
|
void SHPhysicsSystem::SyncTransforms() noexcept
|
||||||
|
@ -491,155 +473,54 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert RP3D Transform to SHADE
|
// Convert RP3D Transform to SHADE
|
||||||
auto* transformComponent = SHComponentManager::GetComponent<SHTransformComponent>(entityID);
|
auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
|
||||||
|
|
||||||
|
if (transformComponent != nullptr)
|
||||||
|
{
|
||||||
transformComponent->SetWorldPosition(rp3dPos);
|
transformComponent->SetWorldPosition(rp3dPos);
|
||||||
transformComponent->SetWorldOrientation(rp3dRot);
|
transformComponent->SetWorldOrientation(rp3dRot);
|
||||||
|
}
|
||||||
|
|
||||||
// Cache transforms
|
// Cache transforms
|
||||||
physicsObject.prevTransform = CURRENT_TF;
|
physicsObject.prevTransform = CURRENT_TF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHPhysicsSystem::UpdateEventContainers(const SHCollisionEvent& collisionEvent, CollisionEvents& container) noexcept
|
||||||
|
{
|
||||||
|
const auto IT = std::ranges::find_if(container.begin(), container.end(), [&](const SHCollisionEvent& e)
|
||||||
|
{
|
||||||
|
const bool ENTITY_MATCH = e.value[0] == collisionEvent.value[0];
|
||||||
|
const bool COLLIDERS_MATCH = e.value[1] == collisionEvent.value[1];
|
||||||
|
return ENTITY_MATCH && COLLIDERS_MATCH;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (IT == container.end())
|
||||||
|
container.emplace_back(collisionEvent);
|
||||||
|
else
|
||||||
|
IT->collisionState = collisionEvent.collisionState;
|
||||||
|
}
|
||||||
|
|
||||||
void SHPhysicsSystem::ClearInvalidCollisions() noexcept
|
void SHPhysicsSystem::ClearInvalidCollisions() noexcept
|
||||||
{
|
{
|
||||||
for (auto collisionInfoIter = collisionInfo.begin(); collisionInfoIter != collisionInfo.end();)
|
static const auto CLEAR = [](CollisionEvents& container)
|
||||||
{
|
{
|
||||||
if (collisionInfoIter->GetCollisionState() == SHCollisionEvent::State::EXIT
|
for (auto eventIter = container.begin(); eventIter != container.end();)
|
||||||
|| collisionInfoIter->GetCollisionState() == SHCollisionEvent::State::INVALID)
|
|
||||||
{
|
{
|
||||||
collisionInfoIter = collisionInfo.erase(collisionInfoIter);
|
const bool CLEAR_EVENT = eventIter->GetCollisionState() == SHCollisionEvent::State::EXIT
|
||||||
}
|
|| eventIter->GetCollisionState() == SHCollisionEvent::State::INVALID;
|
||||||
|
|
||||||
|
if (CLEAR_EVENT)
|
||||||
|
eventIter = container.erase(eventIter);
|
||||||
else
|
else
|
||||||
{
|
++eventIter;
|
||||||
++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;
|
CLEAR(collisionInfo);
|
||||||
// Update collision state
|
CLEAR(triggerInfo);
|
||||||
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());
|
||||||
|
@ -728,6 +609,9 @@ namespace SHADE
|
||||||
const EntityID ENTITY_ID = EVENT_DATA->data->eid;
|
const EntityID ENTITY_ID = EVENT_DATA->data->eid;
|
||||||
auto* physicsObject = GetPhysicsObject(ENTITY_ID);
|
auto* physicsObject = GetPhysicsObject(ENTITY_ID);
|
||||||
|
|
||||||
|
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(ENTITY_ID);
|
||||||
|
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(ENTITY_ID);
|
||||||
|
|
||||||
SHASSERT(physicsObject != nullptr, "Physics object has been lost from the world!")
|
SHASSERT(physicsObject != nullptr, "Physics object has been lost from the world!")
|
||||||
|
|
||||||
if (REMOVED_ID == RIGID_BODY_ID)
|
if (REMOVED_ID == RIGID_BODY_ID)
|
||||||
|
@ -735,7 +619,6 @@ namespace SHADE
|
||||||
world->destroyRigidBody(reinterpret_cast<rp3d::RigidBody*>(physicsObject->rp3dBody));
|
world->destroyRigidBody(reinterpret_cast<rp3d::RigidBody*>(physicsObject->rp3dBody));
|
||||||
physicsObject->rp3dBody = nullptr;
|
physicsObject->rp3dBody = nullptr;
|
||||||
|
|
||||||
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(ENTITY_ID);
|
|
||||||
if (colliderComponent != nullptr)
|
if (colliderComponent != nullptr)
|
||||||
{
|
{
|
||||||
// Preserve colliders as a collision body
|
// Preserve colliders as a collision body
|
||||||
|
@ -766,6 +649,10 @@ namespace SHADE
|
||||||
auto* collider = physicsObject->rp3dBody->getCollider(i);
|
auto* collider = physicsObject->rp3dBody->getCollider(i);
|
||||||
physicsObject->rp3dBody->removeCollider(collider);
|
physicsObject->rp3dBody->removeCollider(collider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for a rigidbody component
|
||||||
|
if (rigidBodyComponent == nullptr)
|
||||||
|
physicsObject->rp3dBody = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (physicsObject->rp3dBody == nullptr)
|
if (physicsObject->rp3dBody == nullptr)
|
||||||
|
|
|
@ -28,6 +28,12 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Concepts */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -176,22 +182,24 @@ namespace SHADE
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept;
|
SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept;
|
||||||
SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept;
|
SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept;
|
||||||
void DestroyPhysicsObject (EntityID entityID) noexcept;
|
void DestroyPhysicsObject (EntityID entityID) noexcept;
|
||||||
|
|
||||||
void SyncActiveStates (SHPhysicsObject* physicsObject, bool componentActive) noexcept;
|
static void SyncActiveStates (SHPhysicsObject& physicsObject, bool componentActive) noexcept;
|
||||||
void SyncTransforms () noexcept;
|
void SyncTransforms () noexcept;
|
||||||
void ClearInvalidCollisions () noexcept;
|
|
||||||
|
|
||||||
SHCollisionEvent GenerateCollisionEvent (const rp3d::CollisionCallback::ContactPair& cp) noexcept;
|
static void UpdateEventContainers (const SHCollisionEvent& collisionEvent, CollisionEvents& container) noexcept;
|
||||||
SHCollisionEvent GenerateCollisionEvent (const rp3d::OverlapCallback::OverlapPair& cp) noexcept;
|
void ClearInvalidCollisions () noexcept;
|
||||||
|
|
||||||
SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent);
|
SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent);
|
||||||
SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent);
|
SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent);
|
||||||
|
|
||||||
|
template <typename RP3DCollisionPair, typename = std::enable_if_t
|
||||||
|
<std::is_same_v<RP3DCollisionPair, rp3d::CollisionCallback::ContactPair>
|
||||||
|
|| std::is_same_v<RP3DCollisionPair, rp3d::OverlapCallback::OverlapPair>>>
|
||||||
|
SHCollisionEvent GenerateCollisionEvent (const RP3DCollisionPair& cp) noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
||||||
|
|
||||||
|
#include "SHPhysicsSystem.hpp"
|
|
@ -0,0 +1,84 @@
|
||||||
|
/****************************************************************************************
|
||||||
|
* \file SHPhysicsSystem.hpp
|
||||||
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
|
* \brief Implementation for templated functions the Physics System
|
||||||
|
*
|
||||||
|
* \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
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
// Primary Header
|
||||||
|
#include "SHPhysicsSystem.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Private Function Member Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
template <typename RP3DCollisionPair, typename Condition>
|
||||||
|
SHCollisionEvent SHPhysicsSystem::GenerateCollisionEvent(const RP3DCollisionPair& 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;
|
||||||
|
}
|
||||||
|
} // namespace SHADE
|
Loading…
Reference in New Issue