From 0693ac1ad0ab2be1a26617c2bd24549a6fc37863 Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Mon, 1 Apr 2024 13:19:33 -0400 Subject: [PATCH] Added collision callback thread safe queue --- Nuake/src/Physics/DynamicWorld.cpp | 22 ++++++++++++-- Nuake/src/Physics/DynamicWorld.h | 12 ++++++++ Nuake/src/Scene/Systems/PhysicsSystem.cpp | 37 ----------------------- 3 files changed, 32 insertions(+), 39 deletions(-) diff --git a/Nuake/src/Physics/DynamicWorld.cpp b/Nuake/src/Physics/DynamicWorld.cpp index 596c634e..24336592 100644 --- a/Nuake/src/Physics/DynamicWorld.cpp +++ b/Nuake/src/Physics/DynamicWorld.cpp @@ -124,7 +124,15 @@ namespace Nuake // An example contact listener class MyContactListener : public JPH::ContactListener { + private: + Physics::DynamicWorld* _World; + public: + MyContactListener(Physics::DynamicWorld* world) + : _World(world) + { + } + // See: ContactListener virtual JPH::ValidateResult OnContactValidate(const JPH::Body& inBody1, const JPH::Body& inBody2, JPH::RVec3Arg inBaseOffset, const JPH::CollideShapeResult& inCollisionResult) override { @@ -146,6 +154,9 @@ namespace Nuake const std::string entity2Name = entity2.GetComponent().Name; Logger::Log("Collision detected between " + entity1Name + " and " + entity2Name); + + Physics::CollisionCallbackData data; + _World->RegisterCollisionCallback(std::move(data)); } virtual void OnContactPersisted(const JPH::Body& inBody1, const JPH::Body& inBody2, const JPH::ContactManifold& inManifold, JPH::ContactSettings& ioSettings) override @@ -217,7 +228,6 @@ namespace Nuake } }; - BPLayerInterfaceImpl JoltBroadphaseLayerInterface = BPLayerInterfaceImpl(); ObjectVsBroadPhaseLayerFilterImpl JoltObjectVSBroadphaseLayerFilter = ObjectVsBroadPhaseLayerFilterImpl(); ObjectLayerPairFilterImpl JoltObjectVSObjectLayerFilter; @@ -246,7 +256,7 @@ namespace Nuake // A contact listener gets notified when bodies (are about to) collide, and when they separate again. // Note that this is called from a job so whatever you do here needs to be thread safe. // Registering one is entirely optional. - _contactListener = CreateScope(); + _contactListener = CreateScope(this); _JoltPhysicsSystem->SetContactListener(_contactListener.get()); // The main way to interact with the bodies in the physics system is through the body interface. There is a locking and a non-locking @@ -667,6 +677,14 @@ namespace Nuake } } + void DynamicWorld::RegisterCollisionCallback(const CollisionCallbackData& data) + { + // This will be called from multiple threads + std::scoped_lock lock(_CollisionCallbackMutex); + + _CollisionCallbacks.push_back(std::move(data)); + } + void DynamicWorld::MoveAndSlideCharacterController(const Entity& entity, const Vector3& velocity) { const uint32_t entityHandle = entity.GetHandle(); diff --git a/Nuake/src/Physics/DynamicWorld.h b/Nuake/src/Physics/DynamicWorld.h index 78226b9e..5a7b13ae 100644 --- a/Nuake/src/Physics/DynamicWorld.h +++ b/Nuake/src/Physics/DynamicWorld.h @@ -41,6 +41,14 @@ namespace Nuake uint32_t Ghost; }; + struct CollisionCallbackData + { + uint32_t Entity1; + uint32_t Entity2; + Vector3 Normal; + Vector3 Position; + }; + class DynamicWorld { private: @@ -56,6 +64,8 @@ namespace Nuake std::vector _registeredBodies; std::map _registeredCharacters; + std::mutex _CollisionCallbackMutex; + std::vector _CollisionCallbacks; public: DynamicWorld(); @@ -75,6 +85,8 @@ namespace Nuake void StepSimulation(Timestep ts); void Clear(); + void RegisterCollisionCallback(const CollisionCallbackData& data); + private: JPH::Ref GetJoltShape(const Ref shape); void SyncEntitiesTranforms(); diff --git a/Nuake/src/Scene/Systems/PhysicsSystem.cpp b/Nuake/src/Scene/Systems/PhysicsSystem.cpp index bb54d874..3988b325 100644 --- a/Nuake/src/Scene/Systems/PhysicsSystem.cpp +++ b/Nuake/src/Scene/Systems/PhysicsSystem.cpp @@ -52,12 +52,6 @@ namespace Nuake { auto [transform, brush] = brushes.get(e); - for (auto& r : brush.Rigidbody) - { - //r->m_Transform->setOrigin(btVector3(transform.GlobalTranslation.x, transform.GlobalTranslation.y, transform.GlobalTranslation.z)); - //r->UpdateTransform(*r->m_Transform); - } - if (!brush.IsFunc) continue; @@ -73,37 +67,6 @@ namespace Nuake } } } - - //auto bspTriggerView = m_Scene->m_Registry.view(); - //for (auto e : bspTriggerView) - //{ - // auto [transform, brush, trigger] = bspTriggerView.get(e); - // trigger.GhostObject->ScanOverlap(); - - // brush.Targets.clear(); - // auto targetnameView = m_Scene->m_Registry.view(); - // for (auto e2 : targetnameView) - // { - // auto [ttransform, name] = targetnameView.get(e2); - - // if (name.Name == brush.target) { - // brush.Targets.push_back(Entity{ e2, m_Scene }); - // } - // } - //} - - - /*auto physicGroup = m_Scene->m_Registry.view(); - for (auto e : physicGroup) { - auto [transform, rb] = physicGroup.get(e); - rb.SyncTransformComponent(&m_Scene->m_Registry.get(e)); - }*/ - - //auto ccGroup = m_Scene->m_Registry.view(); - //for (auto e : ccGroup) { - // auto [transform, rb] = ccGroup.get(e); - // rb.SyncWithTransform(m_Scene->m_Registry.get(e)); - //} } void PhysicsSystem::FixedUpdate(Timestep ts)