diff --git a/examples/PhysicsPlayground/main.cpp b/examples/PhysicsPlayground/main.cpp index b19d4169c..94c053721 100644 --- a/examples/PhysicsPlayground/main.cpp +++ b/examples/PhysicsPlayground/main.cpp @@ -128,7 +128,7 @@ int main() Nz::JoltRigidBody3D::StaticSettings settings; settings.geom = boxCollider; - boxColliderEntity.emplace(physSystem.CreateRigidBody(settings)); + boxColliderEntity.emplace(settings); #else auto& boxBody = boxColliderEntity.emplace(physSystem.CreateRigidBody(boxCollider)); boxBody.SetMass(0.f); @@ -186,7 +186,7 @@ int main() settings.geom = sphereCollider; settings.mass = 4.f / 3.f * Nz::Pi * Nz::IntegralPow(radius, 3); - ballEntity.emplace(physSystem.CreateRigidBody(settings)); + ballEntity.emplace(settings); #else ballEntity.emplace(physSystem.CreateRigidBody(sphereCollider)); #endif @@ -231,7 +231,7 @@ int main() settings.geom = boxCollider; settings.mass = width * height * depth; - boxEntity.emplace(physSystem.CreateRigidBody(settings)); + boxEntity.emplace(settings); #else boxEntity.emplace(physSystem.CreateRigidBody(boxCollider)); #endif @@ -309,7 +309,7 @@ int main() settings.geom = shipCollider; settings.mass = 100.f; - shipEntity.emplace(physSystem.CreateRigidBody(settings)); + shipEntity.emplace(settings); #else shipEntity.emplace(physSystem.CreateRigidBody(shipCollider)); #endif diff --git a/examples/Showcase/main.cpp b/examples/Showcase/main.cpp index 5c76942ff..076478d67 100644 --- a/examples/Showcase/main.cpp +++ b/examples/Showcase/main.cpp @@ -66,7 +66,11 @@ int main() //auto& playerBody = playerEntity.emplace(physSytem.CreateRigidBody(playerCollider)); //playerBody.SetMass(42.f); - character.emplace(physSytem.GetPhysWorld(), playerCollider, Nz::Vector3f::Up() * 5.f); + Nz::JoltCharacter::Settings characterSettings; + characterSettings.collider = playerCollider; + characterSettings.position = Nz::Vector3f::Up() * 5.f; + + character.emplace(physSytem.GetPhysWorld(), characterSettings); app.AddUpdaterFunc([&] { @@ -351,7 +355,7 @@ int main() Nz::JoltRigidBody3D::StaticSettings floorSettings; floorSettings.geom = translatedFloorCollider; - floorEntity.emplace(physSytem.CreateRigidBody(floorSettings)); + floorEntity.emplace(floorSettings); std::shared_ptr boxMeshGfx = Nz::GraphicalMesh::Build(Nz::Primitive::Box(Nz::Vector3f(0.5f, 0.5f, 0.5f)), meshPrimitiveParams); diff --git a/include/Nazara/JoltPhysics3D/Components/JoltCharacterComponent.hpp b/include/Nazara/JoltPhysics3D/Components/JoltCharacterComponent.hpp index 4c9f6af41..2bd297366 100644 --- a/include/Nazara/JoltPhysics3D/Components/JoltCharacterComponent.hpp +++ b/include/Nazara/JoltPhysics3D/Components/JoltCharacterComponent.hpp @@ -17,16 +17,21 @@ namespace Nz friend class JoltPhysics3DSystem; public: - using JoltCharacter::JoltCharacter; + inline JoltCharacterComponent(const JoltCharacter::Settings& settings); JoltCharacterComponent(const JoltCharacterComponent&) = default; JoltCharacterComponent(JoltCharacterComponent&&) noexcept = default; ~JoltCharacterComponent() = default; JoltCharacterComponent& operator=(const JoltCharacterComponent&) = default; JoltCharacterComponent& operator=(JoltCharacterComponent&&) noexcept = default; + + private: + inline void Construct(JoltPhysWorld3D& world); + + std::unique_ptr m_settings; }; } -#include +#include #endif // NAZARA_JOLTPHYSICS3D_COMPONENTS_JOLTCHARACTERCOMPONENT_HPP diff --git a/include/Nazara/JoltPhysics3D/Components/JoltCharacterComponent.inl b/include/Nazara/JoltPhysics3D/Components/JoltCharacterComponent.inl index 30a08e779..67cb919dc 100644 --- a/include/Nazara/JoltPhysics3D/Components/JoltCharacterComponent.inl +++ b/include/Nazara/JoltPhysics3D/Components/JoltCharacterComponent.inl @@ -6,6 +6,17 @@ namespace Nz { + inline JoltCharacterComponent::JoltCharacterComponent(const JoltCharacter::Settings& settings) + { + m_settings = std::make_unique(settings); + } + + inline void JoltCharacterComponent::Construct(JoltPhysWorld3D& world) + { + assert(m_settings); + Create(world, *m_settings); + m_settings.reset(); + } } #include diff --git a/include/Nazara/JoltPhysics3D/Components/JoltRigidBody3DComponent.hpp b/include/Nazara/JoltPhysics3D/Components/JoltRigidBody3DComponent.hpp index a32217d8f..585d40022 100644 --- a/include/Nazara/JoltPhysics3D/Components/JoltRigidBody3DComponent.hpp +++ b/include/Nazara/JoltPhysics3D/Components/JoltRigidBody3DComponent.hpp @@ -9,6 +9,7 @@ #include #include +#include namespace Nz { @@ -17,13 +18,20 @@ namespace Nz friend class JoltPhysics3DSystem; public: - using JoltRigidBody3D::JoltRigidBody3D; + inline JoltRigidBody3DComponent(const JoltRigidBody3D::DynamicSettings& settings); + inline JoltRigidBody3DComponent(const JoltRigidBody3D::StaticSettings& settings); JoltRigidBody3DComponent(const JoltRigidBody3DComponent&) = default; JoltRigidBody3DComponent(JoltRigidBody3DComponent&&) noexcept = default; ~JoltRigidBody3DComponent() = default; JoltRigidBody3DComponent& operator=(const JoltRigidBody3DComponent&) = default; JoltRigidBody3DComponent& operator=(JoltRigidBody3DComponent&&) noexcept = default; + + private: + inline void Construct(JoltPhysWorld3D& world); + + using Setting = std::variant; + std::unique_ptr m_settings; }; } diff --git a/include/Nazara/JoltPhysics3D/Components/JoltRigidBody3DComponent.inl b/include/Nazara/JoltPhysics3D/Components/JoltRigidBody3DComponent.inl index 30a08e779..c77a97462 100644 --- a/include/Nazara/JoltPhysics3D/Components/JoltRigidBody3DComponent.inl +++ b/include/Nazara/JoltPhysics3D/Components/JoltRigidBody3DComponent.inl @@ -3,9 +3,29 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include namespace Nz { + inline JoltRigidBody3DComponent::JoltRigidBody3DComponent(const JoltRigidBody3D::DynamicSettings& settings) + { + m_settings = std::make_unique(settings); + } + + inline JoltRigidBody3DComponent::JoltRigidBody3DComponent(const JoltRigidBody3D::StaticSettings& settings) + { + m_settings = std::make_unique(settings); + } + + inline void JoltRigidBody3DComponent::Construct(JoltPhysWorld3D& world) + { + assert(m_settings); + std::visit([&](auto&& arg) + { + Create(world, arg); + }, *m_settings); + m_settings.reset(); + } } #include diff --git a/include/Nazara/JoltPhysics3D/JoltCharacter.hpp b/include/Nazara/JoltPhysics3D/JoltCharacter.hpp index 7e2ad087a..cad95a7e4 100644 --- a/include/Nazara/JoltPhysics3D/JoltCharacter.hpp +++ b/include/Nazara/JoltPhysics3D/JoltCharacter.hpp @@ -32,7 +32,9 @@ namespace Nz friend JoltPhysWorld3D; public: - JoltCharacter(JoltPhysWorld3D& physWorld, std::shared_ptr collider, const Vector3f& position = Vector3f::Zero(), const Quaternionf& rotation = Quaternionf::Identity()); + struct Settings; + + JoltCharacter(JoltPhysWorld3D& physWorld, const Settings& settings); JoltCharacter(const JoltCharacter&) = delete; JoltCharacter(JoltCharacter&& character) noexcept; ~JoltCharacter(); @@ -62,7 +64,17 @@ namespace Nz JoltCharacter& operator=(const JoltCharacter&) = delete; JoltCharacter& operator=(JoltCharacter&& character) noexcept; + struct Settings + { + std::shared_ptr collider; + Quaternionf rotation = Quaternionf::Identity(); + Vector3f position = Vector3f::Zero(); + }; + protected: + JoltCharacter(); + + void Create(JoltPhysWorld3D& physWorld, const Settings& settings); void Destroy(); private: diff --git a/include/Nazara/JoltPhysics3D/JoltRigidBody3D.hpp b/include/Nazara/JoltPhysics3D/JoltRigidBody3D.hpp index b234b1d0b..da772a559 100644 --- a/include/Nazara/JoltPhysics3D/JoltRigidBody3D.hpp +++ b/include/Nazara/JoltPhysics3D/JoltRigidBody3D.hpp @@ -32,8 +32,8 @@ namespace Nz struct DynamicSettings; struct StaticSettings; - JoltRigidBody3D(JoltPhysWorld3D& world, const DynamicSettings& settings); - JoltRigidBody3D(JoltPhysWorld3D& world, const StaticSettings& settings); + inline JoltRigidBody3D(JoltPhysWorld3D& world, const DynamicSettings& settings); + inline JoltRigidBody3D(JoltPhysWorld3D& world, const StaticSettings& settings); JoltRigidBody3D(const JoltRigidBody3D& object) = delete; JoltRigidBody3D(JoltRigidBody3D&& object) noexcept; ~JoltRigidBody3D(); @@ -123,6 +123,9 @@ namespace Nz }; protected: + JoltRigidBody3D() = default; + void Create(JoltPhysWorld3D& world, const DynamicSettings& settings); + void Create(JoltPhysWorld3D& world, const StaticSettings& settings); void Destroy(bool worldDestruction = false); private: diff --git a/include/Nazara/JoltPhysics3D/JoltRigidBody3D.inl b/include/Nazara/JoltPhysics3D/JoltRigidBody3D.inl index b6067690b..e231de3e9 100644 --- a/include/Nazara/JoltPhysics3D/JoltRigidBody3D.inl +++ b/include/Nazara/JoltPhysics3D/JoltRigidBody3D.inl @@ -6,6 +6,16 @@ namespace Nz { + inline JoltRigidBody3D::JoltRigidBody3D(JoltPhysWorld3D& world, const DynamicSettings& settings) + { + Create(world, settings); + } + + inline JoltRigidBody3D::JoltRigidBody3D(JoltPhysWorld3D& world, const StaticSettings& settings) + { + Create(world, settings); + } + inline void JoltRigidBody3D::DisableSimulation() { return EnableSimulation(false); diff --git a/include/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.hpp b/include/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.hpp index 06afdfb7a..01f280cde 100644 --- a/include/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.hpp +++ b/include/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.hpp @@ -32,9 +32,6 @@ namespace Nz JoltPhysics3DSystem(JoltPhysics3DSystem&&) = delete; ~JoltPhysics3DSystem(); - template JoltCharacterComponent CreateCharacter(Args&&... args); - template JoltRigidBody3DComponent CreateRigidBody(Args&&... args); - void Dump(); inline JoltPhysWorld3D& GetPhysWorld(); @@ -55,6 +52,7 @@ namespace Nz private: void OnBodyConstruct(entt::registry& registry, entt::entity entity); + void OnCharacterConstruct(entt::registry& registry, entt::entity entity); void OnBodyDestruct(entt::registry& registry, entt::entity entity); std::size_t m_stepCount; @@ -62,8 +60,9 @@ namespace Nz entt::registry& m_registry; entt::observer m_characterConstructObserver; entt::observer m_rigidBodyConstructObserver; - entt::scoped_connection m_constructConnection; - entt::scoped_connection m_destructConnection; + entt::scoped_connection m_bodyConstructConnection; + entt::scoped_connection m_characterConstructConnection; + entt::scoped_connection m_bodyDestructConnection; JoltPhysWorld3D m_physWorld; Time m_physicsTime; Time m_updateTime; diff --git a/include/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.inl b/include/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.inl index d072ed37c..6c235edd1 100644 --- a/include/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.inl +++ b/include/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.inl @@ -6,18 +6,6 @@ namespace Nz { - template - JoltCharacterComponent JoltPhysics3DSystem::CreateCharacter(Args&& ...args) - { - return JoltCharacterComponent(m_physWorld, std::forward(args)...); - } - - template - JoltRigidBody3DComponent JoltPhysics3DSystem::CreateRigidBody(Args&&... args) - { - return JoltRigidBody3DComponent(m_physWorld, std::forward(args)...); - } - inline JoltPhysWorld3D& JoltPhysics3DSystem::GetPhysWorld() { return m_physWorld; diff --git a/src/Nazara/JoltPhysics3D/JoltCharacter.cpp b/src/Nazara/JoltPhysics3D/JoltCharacter.cpp index 2d4bcde5b..140d63dea 100644 --- a/src/Nazara/JoltPhysics3D/JoltCharacter.cpp +++ b/src/Nazara/JoltPhysics3D/JoltCharacter.cpp @@ -14,25 +14,11 @@ namespace Nz { - JoltCharacter::JoltCharacter(JoltPhysWorld3D& physWorld, std::shared_ptr collider, const Vector3f& position, const Quaternionf& rotation) : - m_impl(physWorld.GetDefaultCharacterImpl()), - m_collider(std::move(collider)), - m_world(&physWorld) + JoltCharacter::JoltCharacter() = default; + + JoltCharacter::JoltCharacter(JoltPhysWorld3D& physWorld, const Settings& settings) { - auto shapeResult = m_collider->GetShapeSettings()->Create(); - if (!shapeResult.IsValid()) - throw std::runtime_error("invalid shape"); - - JPH::CharacterSettings settings; - settings.mShape = shapeResult.Get(); - settings.mLayer = 1; - - m_character = std::make_unique(&settings, ToJolt(position), ToJolt(rotation), 0, m_world->GetPhysicsSystem()); - m_character->AddToPhysicsSystem(); - - m_bodyIndex = m_character->GetBodyID().GetIndex(); - - m_world->RegisterStepListener(this); + Create(physWorld, settings); } JoltCharacter::JoltCharacter(JoltCharacter&& character) noexcept : @@ -152,6 +138,28 @@ namespace Nz return *this; } + void JoltCharacter::Create(JoltPhysWorld3D& physWorld, const Settings& settings) + { + m_collider = settings.collider; + m_impl = physWorld.GetDefaultCharacterImpl(); + m_world = &physWorld; + + auto shapeResult = m_collider->GetShapeSettings()->Create(); + if (!shapeResult.IsValid()) + throw std::runtime_error("invalid shape"); + + JPH::CharacterSettings characterSettings; + characterSettings.mShape = shapeResult.Get(); + characterSettings.mLayer = 1; + + m_character = std::make_unique(&characterSettings, ToJolt(settings.position), ToJolt(settings.rotation), 0, m_world->GetPhysicsSystem()); + m_character->AddToPhysicsSystem(); + + m_bodyIndex = m_character->GetBodyID().GetIndex(); + + m_world->RegisterStepListener(this); + } + void JoltCharacter::Destroy() { if (m_character) diff --git a/src/Nazara/JoltPhysics3D/JoltRigidBody3D.cpp b/src/Nazara/JoltPhysics3D/JoltRigidBody3D.cpp index 9d7e90b36..87569c520 100644 --- a/src/Nazara/JoltPhysics3D/JoltRigidBody3D.cpp +++ b/src/Nazara/JoltPhysics3D/JoltRigidBody3D.cpp @@ -16,44 +16,6 @@ namespace Nz { - JoltRigidBody3D::JoltRigidBody3D(JoltPhysWorld3D& world, const DynamicSettings& settings) : - m_geom(settings.geom), - m_world(&world), - m_isSimulationEnabled(false), - m_isTrigger(settings.isTrigger) - { - JPH::BodyInterface& bodyInterface = m_world->GetPhysicsSystem()->GetBodyInterface(); - - JPH::BodyCreationSettings creationSettings; - BuildSettings(settings, creationSettings); - - m_body = bodyInterface.CreateBody(creationSettings); - JPH::BodyID bodyId = m_body->GetID(); - m_bodyIndex = bodyId.GetIndex(); - - if (settings.isSimulationEnabled) - m_world->RegisterBody(bodyId, !settings.initiallySleeping, false); - } - - JoltRigidBody3D::JoltRigidBody3D(JoltPhysWorld3D& world, const StaticSettings& settings) : - m_geom(settings.geom), - m_world(&world), - m_isSimulationEnabled(false), - m_isTrigger(settings.isTrigger) - { - JPH::BodyInterface& bodyInterface = m_world->GetPhysicsSystem()->GetBodyInterface(); - - JPH::BodyCreationSettings creationSettings; - BuildSettings(settings, creationSettings); - - m_body = bodyInterface.CreateBody(creationSettings); - JPH::BodyID bodyId = m_body->GetID(); - m_bodyIndex = bodyId.GetIndex(); - - if (settings.isSimulationEnabled) - m_world->RegisterBody(bodyId, false, false); //< static bodies cannot be activated - } - JoltRigidBody3D::JoltRigidBody3D(JoltRigidBody3D&& body) noexcept : m_geom(std::move(body.m_geom)), m_body(std::move(body.m_body)), @@ -357,6 +319,47 @@ namespace Nz return *this; } + + void JoltRigidBody3D::Create(JoltPhysWorld3D& world, const DynamicSettings& settings) + { + m_geom = settings.geom; + m_isSimulationEnabled = settings.isSimulationEnabled; + m_isTrigger = settings.isTrigger; + m_world = &world; + + JPH::BodyCreationSettings creationSettings; + BuildSettings(settings, creationSettings); + + JPH::BodyInterface& bodyInterface = m_world->GetPhysicsSystem()->GetBodyInterface(); + m_body = bodyInterface.CreateBody(creationSettings); + + JPH::BodyID bodyId = m_body->GetID(); + m_bodyIndex = bodyId.GetIndex(); + + if (settings.isSimulationEnabled) + m_world->RegisterBody(bodyId, !settings.initiallySleeping, false); + } + + void JoltRigidBody3D::Create(JoltPhysWorld3D& world, const StaticSettings& settings) + { + m_geom = settings.geom; + m_isSimulationEnabled = settings.isSimulationEnabled; + m_isTrigger = settings.isTrigger; + m_world = &world; + + JPH::BodyCreationSettings creationSettings; + BuildSettings(settings, creationSettings); + + JPH::BodyInterface& bodyInterface = m_world->GetPhysicsSystem()->GetBodyInterface(); + m_body = bodyInterface.CreateBody(creationSettings); + + JPH::BodyID bodyId = m_body->GetID(); + m_bodyIndex = bodyId.GetIndex(); + + if (settings.isSimulationEnabled) + m_world->RegisterBody(bodyId, false, false); //< static bodies cannot be activated + } + void JoltRigidBody3D::Destroy(bool worldDestruction) { if (m_body) diff --git a/src/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.cpp b/src/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.cpp index bfac3f54b..4e406a27c 100644 --- a/src/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.cpp +++ b/src/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.cpp @@ -15,8 +15,9 @@ namespace Nz 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::OnBodyConstruct>(this); - m_destructConnection = registry.on_destroy().connect<&JoltPhysics3DSystem::OnBodyDestruct>(this); + m_bodyConstructConnection = registry.on_construct().connect<&JoltPhysics3DSystem::OnBodyConstruct>(this); + m_characterConstructConnection = registry.on_construct().connect<&JoltPhysics3DSystem::OnCharacterConstruct>(this); + m_bodyDestructConnection = registry.on_destroy().connect<&JoltPhysics3DSystem::OnBodyDestruct>(this); m_stepCount = 0; m_physicsTime = Time::Zero(); @@ -161,6 +162,8 @@ namespace Nz { // Register rigid body owning entity JoltRigidBody3DComponent& rigidBody = registry.get(entity); + rigidBody.Construct(m_physWorld); + std::size_t uniqueIndex = rigidBody.GetBodyIndex(); if (uniqueIndex >= m_physicsEntities.size()) m_physicsEntities.resize(uniqueIndex + 1); @@ -168,6 +171,12 @@ namespace Nz m_physicsEntities[uniqueIndex] = entity; } + void JoltPhysics3DSystem::OnCharacterConstruct(entt::registry& registry, entt::entity entity) + { + JoltCharacterComponent& character = registry.get(entity); + character.Construct(m_physWorld); + } + void JoltPhysics3DSystem::OnBodyDestruct(entt::registry& registry, entt::entity entity) { // Unregister owning entity