From f863f57466ad9887805f5e7357f7eb839afaed01 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Mon, 31 Oct 2022 16:49:09 +0800 Subject: [PATCH 1/4] Triggers were being stored in the wrong container --- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 211 +++++-------------- SHADE_Engine/src/Physics/SHPhysicsSystem.h | 22 +- SHADE_Engine/src/Physics/SHPhysicsSystem.hpp | 84 ++++++++ 3 files changed, 150 insertions(+), 167 deletions(-) create mode 100644 SHADE_Engine/src/Physics/SHPhysicsSystem.hpp diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 454759e4..4939323e 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -257,7 +257,10 @@ namespace SHADE if (physicsObject.rp3dBody == nullptr) continue; - const auto* transformComponent = SHComponentManager::GetComponent_s(entityID); + const auto* transformComponent = SHComponentManager::GetComponent_s(entityID); + auto* rigidBodyComponent = SHComponentManager::GetComponent_s(entityID); + auto* colliderComponent = SHComponentManager::GetComponent_s(entityID); + if (transformComponent && transformComponent->HasChanged()) { const auto WORLD_POS = transformComponent->GetWorldPosition(); @@ -266,46 +269,57 @@ namespace SHADE physicsObject.SetPosition(WORLD_POS); physicsObject.SetOrientation(WORLD_ROT); - auto* rigidBodyComponent = SHComponentManager::GetComponent_s(entityID); + // Sync physics component transforms + if (rigidBodyComponent) { rigidBodyComponent->position = WORLD_POS; rigidBodyComponent->orientation = WORLD_ROT; - - // Clear all forces and velocities if editor is stopped - if (SHSystemManager::GetSystem()->editorState == SHEditor::State::STOP) - { - auto* rp3dRigidBody = reinterpret_cast(physicsObject.rp3dBody); - rp3dRigidBody->resetForce(); - rp3dRigidBody->resetTorque(); - 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(entityID); if (colliderComponent) { 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); } } + + // Sync rigid bodies + + if (rigidBodyComponent) + { + // Clear all forces and velocities if editor is stopped + if (SHSystemManager::GetSystem()->editorState == SHEditor::State::STOP) + { + auto* rp3dRigidBody = reinterpret_cast(physicsObject.rp3dBody); + rp3dRigidBody->resetForce(); + rp3dRigidBody->resetTorque(); + rp3dRigidBody->setLinearVelocity(SHVec3::Zero); + rp3dRigidBody->setAngularVelocity(SHVec3::Zero); + } + + // Sync active states + const bool COMPONENT_ACTIVE = rigidBodyComponent->isActive; + SyncActiveStates(physicsObject, COMPONENT_ACTIVE); + + if (!COMPONENT_ACTIVE) + continue; + + physicsObject.SyncRigidBody(rigidBodyComponent); + } + + // Sync colliders + + if (colliderComponent) + { + const bool COMPONENT_ACTIVE = colliderComponent->isActive; + SyncActiveStates(physicsObject, colliderComponent->isActive); + + if (!COMPONENT_ACTIVE) + continue; + + physicsObject.SyncColliders(colliderComponent); + } } } @@ -350,25 +364,20 @@ namespace SHADE for (uint32_t i = 0; i < callbackData.getNbContactPairs(); ++i) { auto contactPair = callbackData.getContactPair(i); - SHCollisionEvent newCollisionEvent = GenerateCollisionEvent(contactPair); + 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] == newCollisionEvent.value[0]; - const bool COLLIDERS_MATCH = e.value[1] == newCollisionEvent.value[1]; + 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 - collisionInfo.emplace_back(newCollisionEvent); - } + collisionInfo.emplace_back(newTriggerEvent); else - { - existingEvent->collisionState = newCollisionEvent.collisionState; - } + existingEvent->collisionState = newTriggerEvent.collisionState; } } @@ -387,15 +396,10 @@ namespace SHADE return ENTITY_MATCH && COLLIDERS_MATCH; }); - if (existingEvent == collisionInfo.end()) - { - // Add new event + if (existingEvent == triggerInfo.end()) triggerInfo.emplace_back(newTriggerEvent); - } else - { existingEvent->collisionState = newTriggerEvent.collisionState; - } } } @@ -432,11 +436,11 @@ namespace SHADE 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) - physicsObject->rp3dBody->setIsActive(componentActive); + physicsObject.rp3dBody->setIsActive(componentActive); } void SHPhysicsSystem::SyncTransforms() noexcept @@ -529,117 +533,6 @@ namespace SHADE } } - 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::max(); - }; - - SHCollisionEvent cInfo; - // Update collision state - cInfo.collisionState = static_cast(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::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(cp.getEventType()); - - return cInfo; - } - - SHEventHandle SHPhysicsSystem::AddPhysicsComponent(SHEventPtr addComponentEvent) { const auto& EVENT_DATA = reinterpret_cast*>(addComponentEvent.get()); diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index 744615d1..01f633a8 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -28,6 +28,12 @@ namespace SHADE { + /*-----------------------------------------------------------------------------------*/ + /* Concepts */ + /*-----------------------------------------------------------------------------------*/ + + + /*-----------------------------------------------------------------------------------*/ /* Type Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -176,22 +182,22 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept; SHPhysicsObject* GetPhysicsObject (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 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); + + template + || std::is_same_v>> + SHCollisionEvent GenerateCollisionEvent (const RP3DCollisionPair& cp) noexcept; }; +} // namespace SHADE - - -} // namespace SHADE \ No newline at end of file +#include "SHPhysicsSystem.hpp" \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.hpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.hpp new file mode 100644 index 00000000..02569d14 --- /dev/null +++ b/SHADE_Engine/src/Physics/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 + +// Primary Header +#include "SHPhysicsSystem.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Private Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + template + 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::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(cp.getEventType()); + + return cInfo; + } +} // namespace SHADE \ No newline at end of file -- 2.40.1 From c6cc327141979a12b33c437dae2845351ef0808a Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Mon, 31 Oct 2022 16:53:34 +0800 Subject: [PATCH 2/4] M dumb. --- SHADE_Engine/src/Physics/SHPhysicsObject.cpp | 148 +++++++++---------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp index 36836404..8b556409 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp @@ -173,93 +173,93 @@ namespace SHADE SHASSERT(rp3dBody != nullptr, "ReactPhysics body does not exist!") auto* rigidBody = reinterpret_cast(rp3dBody); - - // Sync velocities - rb->linearVelocity = rigidBody->getLinearVelocity(); - rb->angularVelocity = rigidBody->getAngularVelocity(); - - if (rb->dirtyFlags == 0) - return; - - const uint16_t RB_FLAGS = rb->dirtyFlags; - for (size_t i = 0; i < SHRigidBodyComponent::NUM_DIRTY_FLAGS; ++i) + if (rb->dirtyFlags != 0) { - // Check if current dirty flag has been set to true - if (RB_FLAGS & 1U << i) + const uint16_t RB_FLAGS = rb->dirtyFlags; + for (size_t i = 0; i < SHRigidBodyComponent::NUM_DIRTY_FLAGS; ++i) { - switch (i) + // Check if current dirty flag has been set to true + if (RB_FLAGS & 1U << i) { - case 0: // Gravity + switch (i) { - rigidBody->enableGravity(rb->IsGravityEnabled()); - break; - } - case 1: // Sleeping - { - rigidBody->setIsAllowedToSleep(rb->IsAllowedToSleep()); - break; - } - case 2: // Linear Constraints - { - const rp3d::Vector3 CONSTRAINTS + case 0: // Gravity { - rb->flags & 1U << 2 ? 0.0f : 1.0f, - rb->flags & 1U << 3 ? 0.0f : 1.0f, - rb->flags & 1U << 4 ? 0.0f : 1.0f - }; + rigidBody->enableGravity(rb->IsGravityEnabled()); + break; + } + case 1: // Sleeping + { + rigidBody->setIsAllowedToSleep(rb->IsAllowedToSleep()); + break; + } + case 2: // Linear Constraints + { + const rp3d::Vector3 CONSTRAINTS + { + rb->flags & 1U << 2 ? 0.0f : 1.0f, + rb->flags & 1U << 3 ? 0.0f : 1.0f, + rb->flags & 1U << 4 ? 0.0f : 1.0f + }; - rigidBody->setLinearLockAxisFactor(CONSTRAINTS); - break; - } - case 3: // Angular Constraints - { - const rp3d::Vector3 CONSTRAINTS + rigidBody->setLinearLockAxisFactor(CONSTRAINTS); + break; + } + case 3: // Angular Constraints { - rb->flags & 1U << 5 ? 0.0f : 1.0f, - rb->flags & 1U << 6 ? 0.0f : 1.0f, - rb->flags & 1U << 7 ? 0.0f : 1.0f - }; + const rp3d::Vector3 CONSTRAINTS + { + rb->flags & 1U << 5 ? 0.0f : 1.0f, + rb->flags & 1U << 6 ? 0.0f : 1.0f, + rb->flags & 1U << 7 ? 0.0f : 1.0f + }; - rigidBody->setAngularLockAxisFactor(CONSTRAINTS); - break; + rigidBody->setAngularLockAxisFactor(CONSTRAINTS); + break; + } + case 4: // Type + { + rigidBody->setType(static_cast(rb->GetType())); + break; + } + case 5: // Mass + { + rigidBody->setMass(rb->GetMass()); + break; + } + case 6: // Drag + { + rigidBody->setLinearDamping(rb->GetDrag()); + break; + } + case 7: // Angular Drag + { + rigidBody->setAngularDamping(rb->GetAngularDrag()); + break; + } + case 8: // Linear Velocity + { + rigidBody->setLinearVelocity(rb->GetLinearVelocity()); + break; + } + case 9: // Angular Velocity + { + rigidBody->setAngularVelocity(rb->GetAngularVelocity()); + break; + } + default: break; } - case 4: // Type - { - rigidBody->setType(static_cast(rb->GetType())); - break; - } - case 5: // Mass - { - rigidBody->setMass(rb->GetMass()); - break; - } - case 6: // Drag - { - rigidBody->setLinearDamping(rb->GetDrag()); - break; - } - case 7: // Angular Drag - { - rigidBody->setAngularDamping(rb->GetAngularDrag()); - break; - } - case 8: // Linear Velocity - { - rigidBody->setLinearVelocity(rb->GetLinearVelocity()); - break; - } - case 9: // Angular Velocity - { - rigidBody->setAngularVelocity(rb->GetAngularVelocity()); - break; - } - default: break; } } - } - rb->dirtyFlags = 0; + rb->dirtyFlags = 0; + } + else + { + rb->linearVelocity = rigidBody->getLinearVelocity(); + rb->angularVelocity = rigidBody->getAngularVelocity(); + } } void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept -- 2.40.1 From a9c1bd7e7a4c92ed967719c5c87330ecdaea7ceb Mon Sep 17 00:00:00 2001 From: maverickdgg Date: Mon, 31 Oct 2022 17:25:17 +0800 Subject: [PATCH 3/4] Added remove component broadcast to removeComponentOfEntity --- SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.cpp b/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.cpp index be78a146..75a86f37 100644 --- a/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.cpp +++ b/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.cpp @@ -40,6 +40,12 @@ namespace SHADE { comp->OnDestroy(); } + SHComponentRemovedEvent eventData; + eventData.eid = entityID; + eventData.removedComponentType = i; + + SHEventManager::BroadcastEvent(eventData, SH_COMPONENT_REMOVED_EVENT); + } @@ -53,6 +59,7 @@ namespace SHADE //entityHandle.RemoveHandle(entityID); + } -- 2.40.1 From dc20317a70837800ef53872004fe67614f0f96d3 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Mon, 31 Oct 2022 17:25:31 +0800 Subject: [PATCH 4/4] M dumb again. --- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 100 +++++++++---------- SHADE_Engine/src/Physics/SHPhysicsSystem.h | 4 +- 2 files changed, 50 insertions(+), 54 deletions(-) diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 4939323e..ac0eb792 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -363,21 +363,10 @@ namespace SHADE { for (uint32_t i = 0; i < callbackData.getNbContactPairs(); ++i) { - auto contactPair = callbackData.getContactPair(i); - SHCollisionEvent newTriggerEvent = GenerateCollisionEvent(contactPair); + const auto CONTACT_PAIR = callbackData.getContactPair(i); + const SHCollisionEvent NEW_EVENT = GenerateCollisionEvent(CONTACT_PAIR); - // 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()) - collisionInfo.emplace_back(newTriggerEvent); - else - existingEvent->collisionState = newTriggerEvent.collisionState; + UpdateEventContainers(NEW_EVENT, collisionInfo); } } @@ -385,21 +374,10 @@ namespace SHADE { for (uint32_t i = 0; i < callbackData.getNbOverlappingPairs(); ++i) { - auto contactPair = callbackData.getOverlappingPair(i); - SHCollisionEvent newTriggerEvent = GenerateCollisionEvent(contactPair); + const auto& OVERLAP_PAIR = callbackData.getOverlappingPair(i); + const SHCollisionEvent NEW_EVENT = GenerateCollisionEvent(OVERLAP_PAIR); - // 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 == triggerInfo.end()) - triggerInfo.emplace_back(newTriggerEvent); - else - existingEvent->collisionState = newTriggerEvent.collisionState; + UpdateEventContainers(NEW_EVENT, triggerInfo); } } @@ -495,42 +473,52 @@ namespace SHADE } // Convert RP3D Transform to SHADE - auto* transformComponent = SHComponentManager::GetComponent(entityID); - transformComponent->SetWorldPosition(rp3dPos); - transformComponent->SetWorldOrientation(rp3dRot); + auto* transformComponent = SHComponentManager::GetComponent_s(entityID); + + if (transformComponent != nullptr) + { + transformComponent->SetWorldPosition(rp3dPos); + transformComponent->SetWorldOrientation(rp3dRot); + } // Cache transforms 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 { - for (auto collisionInfoIter = collisionInfo.begin(); collisionInfoIter != collisionInfo.end();) + static const auto CLEAR = [](CollisionEvents& container) { - if (collisionInfoIter->GetCollisionState() == SHCollisionEvent::State::EXIT - || collisionInfoIter->GetCollisionState() == SHCollisionEvent::State::INVALID) + for (auto eventIter = container.begin(); eventIter != container.end();) { - collisionInfoIter = collisionInfo.erase(collisionInfoIter); - } - else - { - ++collisionInfoIter; - } - } + const bool CLEAR_EVENT = eventIter->GetCollisionState() == SHCollisionEvent::State::EXIT + || eventIter->GetCollisionState() == SHCollisionEvent::State::INVALID; - for (auto triggerInfoIter = triggerInfo.begin(); triggerInfoIter != triggerInfo.end();) - { - if (triggerInfoIter->GetCollisionState() == SHCollisionEvent::State::EXIT - || triggerInfoIter->GetCollisionState() == SHCollisionEvent::State::INVALID) - { - triggerInfoIter = triggerInfo.erase(triggerInfoIter); + if (CLEAR_EVENT) + eventIter = container.erase(eventIter); + else + ++eventIter; } - else - { - ++triggerInfoIter; - } - } + }; + + CLEAR(collisionInfo); + CLEAR(triggerInfo); } SHEventHandle SHPhysicsSystem::AddPhysicsComponent(SHEventPtr addComponentEvent) @@ -621,6 +609,9 @@ namespace SHADE const EntityID ENTITY_ID = EVENT_DATA->data->eid; auto* physicsObject = GetPhysicsObject(ENTITY_ID); + auto* rigidBodyComponent = SHComponentManager::GetComponent_s(ENTITY_ID); + auto* colliderComponent = SHComponentManager::GetComponent_s(ENTITY_ID); + SHASSERT(physicsObject != nullptr, "Physics object has been lost from the world!") if (REMOVED_ID == RIGID_BODY_ID) @@ -628,7 +619,6 @@ namespace SHADE world->destroyRigidBody(reinterpret_cast(physicsObject->rp3dBody)); physicsObject->rp3dBody = nullptr; - auto* colliderComponent = SHComponentManager::GetComponent_s(ENTITY_ID); if (colliderComponent != nullptr) { // Preserve colliders as a collision body @@ -659,6 +649,10 @@ namespace SHADE auto* collider = physicsObject->rp3dBody->getCollider(i); physicsObject->rp3dBody->removeCollider(collider); } + + // Check for a rigidbody component + if (rigidBodyComponent == nullptr) + physicsObject->rp3dBody = nullptr; } if (physicsObject->rp3dBody == nullptr) diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index 01f633a8..f564dc2d 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -188,7 +188,9 @@ namespace SHADE static void SyncActiveStates (SHPhysicsObject& physicsObject, bool componentActive) noexcept; void SyncTransforms () noexcept; - void ClearInvalidCollisions () noexcept; + + static void UpdateEventContainers (const SHCollisionEvent& collisionEvent, CollisionEvents& container) noexcept; + void ClearInvalidCollisions () noexcept; SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent); SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent); -- 2.40.1