From 6f15400d01b0c4d5b87970519928af9590ce58d8 Mon Sep 17 00:00:00 2001 From: SirLynix Date: Mon, 15 May 2023 19:03:28 +0200 Subject: [PATCH] JoltPhysics3D: Rework Character class --- include/Nazara/JoltPhysics3D.hpp | 1 + include/Nazara/JoltPhysics3D/Components.hpp | 1 + .../Components/JoltCharacterComponent.hpp | 32 +++++++ .../Components/JoltCharacterComponent.inl | 11 +++ .../Nazara/JoltPhysics3D/JoltCharacter.hpp | 40 +++++++-- .../Nazara/JoltPhysics3D/JoltCharacter.inl | 10 +++ .../Nazara/JoltPhysics3D/JoltPhysWorld3D.hpp | 12 ++- .../Nazara/JoltPhysics3D/JoltPhysWorld3D.inl | 14 +-- .../JoltPhysics3D/JoltPhysicsStepListener.hpp | 33 +++++++ .../JoltPhysics3D/JoltPhysicsStepListener.inl | 11 +++ .../Nazara/JoltPhysics3D/JoltRigidBody3D.hpp | 4 +- .../Systems/JoltPhysics3DSystem.hpp | 11 ++- .../Systems/JoltPhysics3DSystem.inl | 6 ++ .../Systems/BulletPhysics3DSystem.cpp | 3 +- src/Nazara/JoltPhysics3D/JoltCharacter.cpp | 87 ++++++++++++++++--- src/Nazara/JoltPhysics3D/JoltPhysWorld3D.cpp | 18 ++-- .../JoltPhysics3D/JoltPhysicsStepListener.cpp | 19 ++++ src/Nazara/JoltPhysics3D/JoltRigidBody3D.cpp | 15 ++-- .../Systems/JoltPhysics3DSystem.cpp | 81 ++++++++++++----- 19 files changed, 339 insertions(+), 70 deletions(-) create mode 100644 include/Nazara/JoltPhysics3D/Components/JoltCharacterComponent.hpp create mode 100644 include/Nazara/JoltPhysics3D/Components/JoltCharacterComponent.inl create mode 100644 include/Nazara/JoltPhysics3D/JoltPhysicsStepListener.hpp create mode 100644 include/Nazara/JoltPhysics3D/JoltPhysicsStepListener.inl create mode 100644 src/Nazara/JoltPhysics3D/JoltPhysicsStepListener.cpp diff --git a/include/Nazara/JoltPhysics3D.hpp b/include/Nazara/JoltPhysics3D.hpp index 8c27707b6..cdbd82160 100644 --- a/include/Nazara/JoltPhysics3D.hpp +++ b/include/Nazara/JoltPhysics3D.hpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include diff --git a/include/Nazara/JoltPhysics3D/Components.hpp b/include/Nazara/JoltPhysics3D/Components.hpp index 535114e54..9e18fb87e 100644 --- a/include/Nazara/JoltPhysics3D/Components.hpp +++ b/include/Nazara/JoltPhysics3D/Components.hpp @@ -29,6 +29,7 @@ #ifndef NAZARA_JOLTPHYSICS3D_COMPONENTS_HPP #define NAZARA_JOLTPHYSICS3D_COMPONENTS_HPP +#include #include #endif // NAZARA_JOLTPHYSICS3D_COMPONENTS_HPP diff --git a/include/Nazara/JoltPhysics3D/Components/JoltCharacterComponent.hpp b/include/Nazara/JoltPhysics3D/Components/JoltCharacterComponent.hpp new file mode 100644 index 000000000..4c9f6af41 --- /dev/null +++ b/include/Nazara/JoltPhysics3D/Components/JoltCharacterComponent.hpp @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com) +// This file is part of the "Nazara Engine - JoltPhysics3D module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_JOLTPHYSICS3D_COMPONENTS_JOLTCHARACTERCOMPONENT_HPP +#define NAZARA_JOLTPHYSICS3D_COMPONENTS_JOLTCHARACTERCOMPONENT_HPP + +#include +#include + +namespace Nz +{ + class NAZARA_JOLTPHYSICS3D_API JoltCharacterComponent : public JoltCharacter + { + friend class JoltPhysics3DSystem; + + public: + using JoltCharacter::JoltCharacter; + JoltCharacterComponent(const JoltCharacterComponent&) = default; + JoltCharacterComponent(JoltCharacterComponent&&) noexcept = default; + ~JoltCharacterComponent() = default; + + JoltCharacterComponent& operator=(const JoltCharacterComponent&) = default; + JoltCharacterComponent& operator=(JoltCharacterComponent&&) noexcept = default; + }; +} + +#include + +#endif // NAZARA_JOLTPHYSICS3D_COMPONENTS_JOLTCHARACTERCOMPONENT_HPP diff --git a/include/Nazara/JoltPhysics3D/Components/JoltCharacterComponent.inl b/include/Nazara/JoltPhysics3D/Components/JoltCharacterComponent.inl new file mode 100644 index 000000000..30a08e779 --- /dev/null +++ b/include/Nazara/JoltPhysics3D/Components/JoltCharacterComponent.inl @@ -0,0 +1,11 @@ +// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com) +// This file is part of the "Nazara Engine - JoltPhysics3D module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include + +namespace Nz +{ +} + +#include diff --git a/include/Nazara/JoltPhysics3D/JoltCharacter.hpp b/include/Nazara/JoltPhysics3D/JoltCharacter.hpp index 289b68e51..7e2ad087a 100644 --- a/include/Nazara/JoltPhysics3D/JoltCharacter.hpp +++ b/include/Nazara/JoltPhysics3D/JoltCharacter.hpp @@ -9,8 +9,10 @@ #include #include +#include #include #include +#include #include namespace JPH @@ -21,22 +23,24 @@ namespace JPH namespace Nz { + class JoltCharacterImpl; class JoltCollider3D; class JoltPhysWorld3D; - class NAZARA_JOLTPHYSICS3D_API JoltCharacter + class NAZARA_JOLTPHYSICS3D_API JoltCharacter : public JoltPhysicsStepListener { friend JoltPhysWorld3D; public: - JoltCharacter(JoltPhysWorld3D& physWorld, std::shared_ptr collider, const Vector3f& position, const Quaternionf& rotation = Quaternionf::Identity()); + JoltCharacter(JoltPhysWorld3D& physWorld, std::shared_ptr collider, const Vector3f& position = Vector3f::Zero(), const Quaternionf& rotation = Quaternionf::Identity()); JoltCharacter(const JoltCharacter&) = delete; - JoltCharacter(JoltCharacter&&) = delete; + JoltCharacter(JoltCharacter&& character) noexcept; ~JoltCharacter(); inline void DisableSleeping(); void EnableSleeping(bool enable); + inline UInt32 GetBodyIndex() const; Vector3f GetLinearVelocity() const; Quaternionf GetRotation() const; Vector3f GetPosition() const; @@ -46,23 +50,45 @@ namespace Nz bool IsOnGround() const; void SetFriction(float friction); + inline void SetImpl(std::shared_ptr characterImpl); void SetLinearVelocity(const Vector3f& linearVel); void SetRotation(const Quaternionf& rotation); void SetUp(const Vector3f& up); + void TeleportTo(const Vector3f& position, const Quaternionf& rotation); + void WakeUp(); JoltCharacter& operator=(const JoltCharacter&) = delete; - JoltCharacter& operator=(JoltCharacter&&) = delete; + JoltCharacter& operator=(JoltCharacter&& character) noexcept; protected: - virtual void PreSimulate(float elapsedTime); - virtual void PostSimulate(); + void Destroy(); private: + void PostSimulate() override; + void PreSimulate(float elapsedTime) override; + + std::shared_ptr m_impl; std::shared_ptr m_collider; std::unique_ptr m_character; - JoltPhysWorld3D& m_physicsWorld; + MovablePtr m_world; + UInt32 m_bodyIndex; + }; + + class NAZARA_JOLTPHYSICS3D_API JoltCharacterImpl + { + public: + JoltCharacterImpl() = default; + JoltCharacterImpl(const JoltCharacterImpl&) = delete; + JoltCharacterImpl(JoltCharacterImpl&&) = delete; + virtual ~JoltCharacterImpl(); + + virtual void PostSimulate(JoltCharacter& character); + virtual void PreSimulate(JoltCharacter& character, float elapsedTime); + + JoltCharacterImpl& operator=(const JoltCharacterImpl&) = delete; + JoltCharacterImpl& operator=(JoltCharacterImpl&&) = delete; }; } diff --git a/include/Nazara/JoltPhysics3D/JoltCharacter.inl b/include/Nazara/JoltPhysics3D/JoltCharacter.inl index 6d391fd48..aaeba430a 100644 --- a/include/Nazara/JoltPhysics3D/JoltCharacter.inl +++ b/include/Nazara/JoltPhysics3D/JoltCharacter.inl @@ -10,6 +10,16 @@ namespace Nz { return EnableSleeping(false); } + + inline UInt32 JoltCharacter::GetBodyIndex() const + { + return m_bodyIndex; + } + + inline void JoltCharacter::SetImpl(std::shared_ptr characterImpl) + { + m_impl = std::move(characterImpl); + } } #include diff --git a/include/Nazara/JoltPhysics3D/JoltPhysWorld3D.hpp b/include/Nazara/JoltPhysics3D/JoltPhysWorld3D.hpp index 320e90277..6994e62ae 100644 --- a/include/Nazara/JoltPhysics3D/JoltPhysWorld3D.hpp +++ b/include/Nazara/JoltPhysics3D/JoltPhysWorld3D.hpp @@ -28,6 +28,8 @@ namespace JPH namespace Nz { class JoltCharacter; + class JoltCharacterImpl; + class JoltPhysicsStepListener; class JoltRigidBody3D; class NAZARA_JOLTPHYSICS3D_API JoltPhysWorld3D @@ -57,12 +59,16 @@ namespace Nz void RefreshBodies(); + inline void RegisterStepListener(JoltPhysicsStepListener* character); + void SetGravity(const Vector3f& gravity); void SetMaxStepCount(std::size_t maxStepCount); void SetStepSize(Time stepSize); void Step(Time timestep); + inline void UnregisterStepListener(JoltPhysicsStepListener* character); + JoltPhysWorld3D& operator=(const JoltPhysWorld3D&) = delete; JoltPhysWorld3D& operator=(JoltPhysWorld3D&&) = delete; @@ -83,21 +89,21 @@ namespace Nz struct JoltWorld; + std::shared_ptr GetDefaultCharacterImpl(); const JPH::Shape* GetNullShape() const; void OnPreStep(float deltatime); void RegisterBody(const JPH::BodyID& bodyID, bool activate, bool removeFromDeactivationList); - inline void RegisterCharacter(JoltCharacter* character); void UnregisterBody(const JPH::BodyID& bodyID, bool destroy, bool removeFromRegisterList); - inline void UnregisterCharacter(JoltCharacter* character); std::size_t m_maxStepCount; + std::shared_ptr m_defaultCharacterImpl; std::unique_ptr m_activeBodies; std::unique_ptr m_registeredBodies; std::unique_ptr m_world; - std::vector m_characters; + std::vector m_stepListeners; Vector3f m_gravity; Time m_stepSize; Time m_timestepAccumulator; diff --git a/include/Nazara/JoltPhysics3D/JoltPhysWorld3D.inl b/include/Nazara/JoltPhysics3D/JoltPhysWorld3D.inl index 17a4e6473..dd5f37d0f 100644 --- a/include/Nazara/JoltPhysics3D/JoltPhysWorld3D.inl +++ b/include/Nazara/JoltPhysics3D/JoltPhysWorld3D.inl @@ -22,17 +22,17 @@ namespace Nz return m_registeredBodies[blockIndex] & (UInt64(1u) << localIndex); } - inline void JoltPhysWorld3D::RegisterCharacter(JoltCharacter* character) + inline void JoltPhysWorld3D::RegisterStepListener(JoltPhysicsStepListener* stepListener) { - auto it = std::lower_bound(m_characters.begin(), m_characters.end(), character); - m_characters.insert(it, character); + auto it = std::lower_bound(m_stepListeners.begin(), m_stepListeners.end(), stepListener); + m_stepListeners.insert(it, stepListener); } - inline void JoltPhysWorld3D::UnregisterCharacter(JoltCharacter* character) + inline void JoltPhysWorld3D::UnregisterStepListener(JoltPhysicsStepListener* stepListener) { - auto it = std::lower_bound(m_characters.begin(), m_characters.end(), character); - assert(*it == character); - m_characters.erase(it); + auto it = std::lower_bound(m_stepListeners.begin(), m_stepListeners.end(), stepListener); + assert(*it == stepListener); + m_stepListeners.erase(it); } } diff --git a/include/Nazara/JoltPhysics3D/JoltPhysicsStepListener.hpp b/include/Nazara/JoltPhysics3D/JoltPhysicsStepListener.hpp new file mode 100644 index 000000000..0675b1b59 --- /dev/null +++ b/include/Nazara/JoltPhysics3D/JoltPhysicsStepListener.hpp @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com) +// This file is part of the "Nazara Engine - JoltPhysics3D module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_JOLTPHYSICS3D_JOLTPHYSICSSTEPLISTENER_HPP +#define NAZARA_JOLTPHYSICS3D_JOLTPHYSICSSTEPLISTENER_HPP + +#include +#include + +namespace Nz +{ + class NAZARA_JOLTPHYSICS3D_API JoltPhysicsStepListener + { + public: + JoltPhysicsStepListener() = default; + JoltPhysicsStepListener(const JoltPhysicsStepListener&) = delete; + JoltPhysicsStepListener(JoltPhysicsStepListener&&) = delete; + virtual ~JoltPhysicsStepListener(); + + virtual void PostSimulate(); + virtual void PreSimulate(float elapsedTime); + + JoltPhysicsStepListener& operator=(const JoltPhysicsStepListener&) = delete; + JoltPhysicsStepListener& operator=(JoltPhysicsStepListener&&) = delete; + }; +} + +#include + +#endif // NAZARA_JOLTPHYSICS3D_JOLTPHYSICSSTEPLISTENER_HPP diff --git a/include/Nazara/JoltPhysics3D/JoltPhysicsStepListener.inl b/include/Nazara/JoltPhysics3D/JoltPhysicsStepListener.inl new file mode 100644 index 000000000..30a08e779 --- /dev/null +++ b/include/Nazara/JoltPhysics3D/JoltPhysicsStepListener.inl @@ -0,0 +1,11 @@ +// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com) +// This file is part of the "Nazara Engine - JoltPhysics3D module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include + +namespace Nz +{ +} + +#include diff --git a/include/Nazara/JoltPhysics3D/JoltRigidBody3D.hpp b/include/Nazara/JoltPhysics3D/JoltRigidBody3D.hpp index ae062afb8..b234b1d0b 100644 --- a/include/Nazara/JoltPhysics3D/JoltRigidBody3D.hpp +++ b/include/Nazara/JoltPhysics3D/JoltRigidBody3D.hpp @@ -133,8 +133,8 @@ namespace Nz bool ShouldActivate() const; std::shared_ptr m_geom; - JPH::Body* m_body; - JoltPhysWorld3D* m_world; + MovablePtr m_body; + MovablePtr m_world; UInt32 m_bodyIndex; bool m_isSimulationEnabled; bool m_isTrigger; diff --git a/include/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.hpp b/include/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.hpp index 4a406ee05..06afdfb7a 100644 --- a/include/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.hpp +++ b/include/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -22,7 +23,7 @@ namespace Nz { public: static constexpr Int64 ExecutionOrder = 0; - using Components = TypeList; + using Components = TypeList; struct RaycastHit; @@ -31,6 +32,7 @@ namespace Nz JoltPhysics3DSystem(JoltPhysics3DSystem&&) = delete; ~JoltPhysics3DSystem(); + template JoltCharacterComponent CreateCharacter(Args&&... args); template JoltRigidBody3DComponent CreateRigidBody(Args&&... args); void Dump(); @@ -52,13 +54,14 @@ namespace Nz }; private: - void OnConstruct(entt::registry& registry, entt::entity entity); - void OnDestruct(entt::registry& registry, entt::entity entity); + void OnBodyConstruct(entt::registry& registry, entt::entity entity); + void OnBodyDestruct(entt::registry& registry, entt::entity entity); std::size_t m_stepCount; std::vector m_physicsEntities; entt::registry& m_registry; - entt::observer m_physicsConstructObserver; + entt::observer m_characterConstructObserver; + entt::observer m_rigidBodyConstructObserver; entt::scoped_connection m_constructConnection; entt::scoped_connection m_destructConnection; JoltPhysWorld3D m_physWorld; diff --git a/include/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.inl b/include/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.inl index f9df021ec..d072ed37c 100644 --- a/include/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.inl +++ b/include/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.inl @@ -6,6 +6,12 @@ namespace Nz { + template + JoltCharacterComponent JoltPhysics3DSystem::CreateCharacter(Args&& ...args) + { + return JoltCharacterComponent(m_physWorld, std::forward(args)...); + } + template JoltRigidBody3DComponent JoltPhysics3DSystem::CreateRigidBody(Args&&... args) { diff --git a/src/Nazara/BulletPhysics3D/Systems/BulletPhysics3DSystem.cpp b/src/Nazara/BulletPhysics3D/Systems/BulletPhysics3DSystem.cpp index ef531e8a7..9f9c50dd6 100644 --- a/src/Nazara/BulletPhysics3D/Systems/BulletPhysics3DSystem.cpp +++ b/src/Nazara/BulletPhysics3D/Systems/BulletPhysics3DSystem.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include namespace Nz @@ -37,11 +36,13 @@ namespace Nz if (m_stepCount == 0) m_stepCount = 1; +/* std::cout << "Physics time: " << (m_physicsTime / Time::Nanoseconds(m_stepCount)) << std::endl; std::cout << "Update time: " << (m_updateTime / Time::Nanoseconds(m_stepCount)) << std::endl; std::cout << "Active body count: " << m_activeObjectCount << std::endl; std::cout << "--" << std::endl; +*/ m_stepCount = 0; m_physicsTime = Time::Zero(); m_updateTime = Time::Zero(); diff --git a/src/Nazara/JoltPhysics3D/JoltCharacter.cpp b/src/Nazara/JoltPhysics3D/JoltCharacter.cpp index 29822eac7..c5205b8b7 100644 --- a/src/Nazara/JoltPhysics3D/JoltCharacter.cpp +++ b/src/Nazara/JoltPhysics3D/JoltCharacter.cpp @@ -16,7 +16,7 @@ namespace Nz { JoltCharacter::JoltCharacter(JoltPhysWorld3D& physWorld, std::shared_ptr collider, const Vector3f& position, const Quaternionf& rotation) : m_collider(std::move(collider)), - m_physicsWorld(physWorld) + m_world(&physWorld) { auto shapeResult = m_collider->GetShapeSettings()->Create(); if (!shapeResult.IsValid()) @@ -26,22 +26,35 @@ namespace Nz settings.mShape = shapeResult.Get(); settings.mLayer = 1; - m_character = std::make_unique(&settings, ToJolt(position), ToJolt(rotation), 0, m_physicsWorld.GetPhysicsSystem()); + m_character = std::make_unique(&settings, ToJolt(position), ToJolt(rotation), 0, m_world->GetPhysicsSystem()); m_character->AddToPhysicsSystem(); - m_physicsWorld.RegisterCharacter(this); + m_bodyIndex = m_character->GetBodyID().GetIndex(); + + m_world->RegisterStepListener(this); + } + + JoltCharacter::JoltCharacter(JoltCharacter&& character) noexcept : + m_impl(std::move(character.m_impl)), + m_collider(std::move(character.m_collider)), + m_character(std::move(character.m_character)), + m_world(std::move(character.m_world)), + m_bodyIndex(character.m_bodyIndex) + { + character.m_bodyIndex = std::numeric_limits::max(); + + if (m_world) + m_world->RegisterStepListener(this); } JoltCharacter::~JoltCharacter() { - m_character->RemoveFromPhysicsSystem(); - - m_physicsWorld.UnregisterCharacter(this); + Destroy(); } void JoltCharacter::EnableSleeping(bool enable) { - const JPH::BodyLockInterfaceNoLock& bodyInterface = m_physicsWorld.GetPhysicsSystem()->GetBodyLockInterfaceNoLock(); + const JPH::BodyLockInterfaceNoLock& bodyInterface = m_world->GetPhysicsSystem()->GetBodyLockInterfaceNoLock(); JPH::BodyLockWrite bodyLock(bodyInterface, m_character->GetBodyID()); if (!bodyLock.Succeeded()) return; @@ -85,7 +98,7 @@ namespace Nz void JoltCharacter::SetFriction(float friction) { - JPH::BodyInterface& bodyInterface = m_physicsWorld.GetPhysicsSystem()->GetBodyInterfaceNoLock(); + JPH::BodyInterface& bodyInterface = m_world->GetPhysicsSystem()->GetBodyInterfaceNoLock(); bodyInterface.SetFriction(m_character->GetBodyID(), friction); } @@ -104,17 +117,71 @@ namespace Nz m_character->SetUp(ToJolt(up)); } + void JoltCharacter::TeleportTo(const Vector3f& position, const Quaternionf& rotation) + { + m_character->SetPositionAndRotation(ToJolt(position), ToJolt(rotation), JPH::EActivation::Activate, false); + } + void JoltCharacter::WakeUp() { m_character->Activate(false); } - - void JoltCharacter::PreSimulate(float /*elapsedTime*/) + + JoltCharacter& JoltCharacter::operator=(JoltCharacter&& character) noexcept { + if (m_world) + m_world->UnregisterStepListener(this); + + m_impl = std::move(character.m_impl); + m_collider = std::move(character.m_collider); + m_character = std::move(character.m_character); + m_bodyIndex = character.m_bodyIndex; + m_world = std::move(character.m_world); + + if (m_world) + m_world->RegisterStepListener(this); + + character.m_bodyIndex = std::numeric_limits::max(); + + return *this; + } + + void JoltCharacter::Destroy() + { + if (m_character) + { + m_character->RemoveFromPhysicsSystem(); + m_character = nullptr; + } + + if (m_world) + { + m_world->UnregisterStepListener(this); + m_world = nullptr; + } + + m_collider.reset(); } void JoltCharacter::PostSimulate() { m_character->PostSimulation(0.05f); + m_impl->PostSimulate(*this); + } + + void JoltCharacter::PreSimulate(float elapsedTime) + { + m_impl->PreSimulate(*this, elapsedTime); + } + + + JoltCharacterImpl::~JoltCharacterImpl() = default; + + void JoltCharacterImpl::PostSimulate(JoltCharacter& /*character*/) + { + } + + void JoltCharacterImpl::PreSimulate(JoltCharacter& /*character*/, float /*elapsedTime*/) + { } } diff --git a/src/Nazara/JoltPhysics3D/JoltPhysWorld3D.cpp b/src/Nazara/JoltPhysics3D/JoltPhysWorld3D.cpp index d44250ea7..e1ed0fdc1 100644 --- a/src/Nazara/JoltPhysics3D/JoltPhysWorld3D.cpp +++ b/src/Nazara/JoltPhysics3D/JoltPhysWorld3D.cpp @@ -3,9 +3,9 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include #include #include +#include #include #include #include @@ -469,8 +469,8 @@ namespace Nz { m_world->physicsSystem.Update(stepSize, 1, 1, &m_world->tempAllocator, &jobSystem); - for (JoltCharacter* character : m_characters) - character->PostSimulate(); + for (JoltPhysicsStepListener* stepListener : m_stepListeners) + stepListener->PostSimulate(); m_timestepAccumulator -= m_stepSize; stepCount++; @@ -523,6 +523,14 @@ namespace Nz } } + std::shared_ptr JoltPhysWorld3D::GetDefaultCharacterImpl() + { + if (!m_defaultCharacterImpl) + m_defaultCharacterImpl = std::make_shared(); + + return m_defaultCharacterImpl; + } + const JPH::Shape* JoltPhysWorld3D::GetNullShape() const { if (!m_world->nullShape) @@ -536,7 +544,7 @@ namespace Nz void JoltPhysWorld3D::OnPreStep(float deltatime) { - for (JoltCharacter* character : m_characters) - character->PreSimulate(deltatime); + for (JoltPhysicsStepListener* stepListener : m_stepListeners) + stepListener->PreSimulate(deltatime); } } diff --git a/src/Nazara/JoltPhysics3D/JoltPhysicsStepListener.cpp b/src/Nazara/JoltPhysics3D/JoltPhysicsStepListener.cpp new file mode 100644 index 000000000..6436fd5bd --- /dev/null +++ b/src/Nazara/JoltPhysics3D/JoltPhysicsStepListener.cpp @@ -0,0 +1,19 @@ +// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com) +// This file is part of the "Nazara Engine - JoltPhysics3D module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ + JoltPhysicsStepListener::~JoltPhysicsStepListener() = default; + + void JoltPhysicsStepListener::PostSimulate() + { + } + + void JoltPhysicsStepListener::PreSimulate(float /*elapsedTime*/) + { + } +} diff --git a/src/Nazara/JoltPhysics3D/JoltRigidBody3D.cpp b/src/Nazara/JoltPhysics3D/JoltRigidBody3D.cpp index a0997a8b6..45082cadb 100644 --- a/src/Nazara/JoltPhysics3D/JoltRigidBody3D.cpp +++ b/src/Nazara/JoltPhysics3D/JoltRigidBody3D.cpp @@ -56,13 +56,12 @@ namespace Nz JoltRigidBody3D::JoltRigidBody3D(JoltRigidBody3D&& body) noexcept : m_geom(std::move(body.m_geom)), - m_body(body.m_body), - m_world(body.m_world), + m_body(std::move(body.m_body)), + m_world(std::move(body.m_world)), m_bodyIndex(body.m_bodyIndex), m_isSimulationEnabled(body.m_isSimulationEnabled), m_isTrigger(body.m_isTrigger) { - body.m_body = nullptr; body.m_bodyIndex = std::numeric_limits::max(); if (m_body) @@ -343,14 +342,13 @@ namespace Nz { Destroy(); - m_body = body.m_body; + m_body = std::move(body.m_body); m_bodyIndex = body.m_bodyIndex; m_geom = std::move(body.m_geom); - m_world = body.m_world; + m_world = std::move(body.m_world); m_isSimulationEnabled = body.m_isSimulationEnabled; m_isTrigger = body.m_isTrigger; - body.m_body = nullptr; body.m_bodyIndex = std::numeric_limits::max(); if (m_body) @@ -417,9 +415,10 @@ namespace Nz { creationSettings.SetShape(m_world->GetNullShape()); creationSettings.mIsSensor = true; //< not the best solution but enough for now - creationSettings.mPosition = ToJolt(settings.position); - creationSettings.mRotation = ToJolt(settings.rotation); } + + creationSettings.mPosition = ToJolt(settings.position); + creationSettings.mRotation = ToJolt(settings.rotation); } bool JoltRigidBody3D::ShouldActivate() const diff --git a/src/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.cpp b/src/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.cpp index f254cac45..bfac3f54b 100644 --- a/src/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.cpp +++ b/src/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.cpp @@ -3,19 +3,20 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include -#include #include namespace Nz { JoltPhysics3DSystem::JoltPhysics3DSystem(entt::registry& registry) : m_registry(registry), - m_physicsConstructObserver(m_registry, entt::collector.group()) + m_characterConstructObserver(m_registry, entt::collector.group(entt::exclude)), + m_rigidBodyConstructObserver(m_registry, entt::collector.group(entt::exclude)) { - m_constructConnection = registry.on_construct().connect<&JoltPhysics3DSystem::OnConstruct>(this); - m_destructConnection = registry.on_destroy().connect<&JoltPhysics3DSystem::OnDestruct>(this); + m_constructConnection = registry.on_construct().connect<&JoltPhysics3DSystem::OnBodyConstruct>(this); + m_destructConnection = registry.on_destroy().connect<&JoltPhysics3DSystem::OnBodyDestruct>(this); m_stepCount = 0; m_physicsTime = Time::Zero(); @@ -24,9 +25,14 @@ namespace Nz JoltPhysics3DSystem::~JoltPhysics3DSystem() { - m_physicsConstructObserver.disconnect(); + m_characterConstructObserver.disconnect(); + m_rigidBodyConstructObserver.disconnect(); // Ensure every RigidBody3D is destroyed before world is + auto characterView = m_registry.view(); + for (auto [entity, characterComponent] : characterView.each()) + characterComponent.Destroy(); + auto rigidBodyView = m_registry.view(); for (auto [entity, rigidBodyComponent] : rigidBodyView.each()) rigidBodyComponent.Destroy(true); @@ -37,10 +43,12 @@ namespace Nz if (m_stepCount == 0) m_stepCount = 1; - std::cout << "Physics time: " << (m_physicsTime / Time::Nanoseconds(m_stepCount)) << std::endl; - std::cout << "Replication time: " << (m_updateTime / Time::Nanoseconds(m_stepCount)) << std::endl; - std::cout << "Active entity count: " << m_physWorld.GetActiveBodyCount() << std::endl; - std::cout << "--" << std::endl; +/* + NazaraDebug("Physics time: " << (m_physicsTime / Time::Nanoseconds(m_stepCount))); + NazaraDebug("Replication time: " << (m_updateTime / Time::Nanoseconds(m_stepCount))); + NazaraDebug("Active entity count: " << m_physWorld.GetActiveBodyCount())); + NazaraDebug("--"); +*/ m_stepCount = 0; m_physicsTime = Time::Zero(); @@ -86,14 +94,23 @@ namespace Nz void JoltPhysics3DSystem::Update(Time elapsedTime) { // Move newly-created physics entities to their node position/rotation - m_physicsConstructObserver.each([&](entt::entity entity) + m_characterConstructObserver.each([this](entt::entity entity) { - JoltRigidBody3DComponent& entityPhysics = m_registry.get(entity); + JoltCharacterComponent& entityCharacter = m_registry.get(entity); NodeComponent& entityNode = m_registry.get(entity); - entityPhysics.TeleportTo(entityNode.GetPosition(), entityNode.GetRotation()); + entityCharacter.TeleportTo(entityNode.GetPosition(), entityNode.GetRotation()); }); + m_rigidBodyConstructObserver.each([this](entt::entity entity) + { + JoltRigidBody3DComponent& entityBody = m_registry.get(entity); + NodeComponent& entityNode = m_registry.get(entity); + + entityBody.TeleportTo(entityNode.GetPosition(), entityNode.GetRotation()); + }); + + Time t1 = GetElapsedNanoseconds(); // Update the physics world @@ -102,18 +119,36 @@ namespace Nz Time t2 = GetElapsedNanoseconds(); - // Replicate active rigid body position to their node components - auto view = m_registry.view(entt::exclude); - for (auto entity : view) + // Replicate characters to their NodeComponent { - auto& rigidBodyComponent = view.get(entity); - if (!m_physWorld.IsBodyActive(rigidBodyComponent.GetBodyIndex())) - continue; + auto view = m_registry.view(entt::exclude); + for (auto entity : view) + { + auto& characterComponent = view.get(entity); + if (!m_physWorld.IsBodyActive(characterComponent.GetBodyIndex())) + continue; - auto& nodeComponent = view.get(entity); + auto& nodeComponent = view.get(entity); - auto [position, rotation] = rigidBodyComponent.GetPositionAndRotation(); - nodeComponent.SetTransform(position, rotation); + auto [position, rotation] = characterComponent.GetPositionAndRotation(); + nodeComponent.SetTransform(position, rotation); + } + } + + // Replicate active rigid body position to their node components + { + auto view = m_registry.view(entt::exclude); + for (auto entity : m_registry.view(entt::exclude)) + { + auto& rigidBodyComponent = view.get(entity); + if (!m_physWorld.IsBodyActive(rigidBodyComponent.GetBodyIndex())) + continue; + + auto& nodeComponent = view.get(entity); + + auto [position, rotation] = rigidBodyComponent.GetPositionAndRotation(); + nodeComponent.SetTransform(position, rotation); + } } Time t3 = GetElapsedNanoseconds(); @@ -122,7 +157,7 @@ namespace Nz m_updateTime += (t3 - t2); } - void JoltPhysics3DSystem::OnConstruct(entt::registry& registry, entt::entity entity) + void JoltPhysics3DSystem::OnBodyConstruct(entt::registry& registry, entt::entity entity) { // Register rigid body owning entity JoltRigidBody3DComponent& rigidBody = registry.get(entity); @@ -133,7 +168,7 @@ namespace Nz m_physicsEntities[uniqueIndex] = entity; } - void JoltPhysics3DSystem::OnDestruct(entt::registry& registry, entt::entity entity) + void JoltPhysics3DSystem::OnBodyDestruct(entt::registry& registry, entt::entity entity) { // Unregister owning entity JoltRigidBody3DComponent& rigidBody = registry.get(entity);