From 4eb3520be8d95caf0f44d3c8a46550456b3f0be1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Wed, 13 Dec 2017 10:36:27 +0100 Subject: [PATCH] Sdk/PhysicsComponent3D: Add node synchronization control --- .../NDK/Components/PhysicsComponent3D.hpp | 5 ++- .../NDK/Components/PhysicsComponent3D.inl | 40 ++++++++++++++++--- SDK/src/NDK/Systems/PhysicsSystem3D.cpp | 20 ++++++---- 3 files changed, 51 insertions(+), 14 deletions(-) diff --git a/SDK/include/NDK/Components/PhysicsComponent3D.hpp b/SDK/include/NDK/Components/PhysicsComponent3D.hpp index 292c5f9ab..fe5e2f28a 100644 --- a/SDK/include/NDK/Components/PhysicsComponent3D.hpp +++ b/SDK/include/NDK/Components/PhysicsComponent3D.hpp @@ -19,7 +19,7 @@ namespace Ndk friend class PhysicsSystem3D; public: - PhysicsComponent3D() = default; + inline PhysicsComponent3D(); PhysicsComponent3D(const PhysicsComponent3D& physics); ~PhysicsComponent3D() = default; @@ -28,6 +28,7 @@ namespace Ndk void AddTorque(const Nz::Vector3f& torque, Nz::CoordSys coordSys = Nz::CoordSys_Global); void EnableAutoSleep(bool autoSleep); + void EnableNodeSynchronization(bool nodeSynchronization); Nz::Boxf GetAABB() const; Nz::Vector3f GetAngularDamping() const; @@ -43,6 +44,7 @@ namespace Ndk bool IsAutoSleepEnabled() const; bool IsMoveable() const; + bool IsNodeSynchronizationEnabled() const; bool IsSleeping() const; void SetAngularDamping(const Nz::Vector3f& angularDamping); @@ -69,6 +71,7 @@ namespace Ndk void OnEntityEnabled() override; std::unique_ptr m_object; + bool m_nodeSynchronizationEnabled; }; } diff --git a/SDK/include/NDK/Components/PhysicsComponent3D.inl b/SDK/include/NDK/Components/PhysicsComponent3D.inl index 741655387..319bb88dd 100644 --- a/SDK/include/NDK/Components/PhysicsComponent3D.inl +++ b/SDK/include/NDK/Components/PhysicsComponent3D.inl @@ -7,13 +7,18 @@ namespace Ndk { + inline PhysicsComponent3D::PhysicsComponent3D() : + m_nodeSynchronizationEnabled(true) + { + } + /*! * \brief Constructs a PhysicsComponent3D object by copy semantic * * \param physics PhysicsComponent3D to copy */ - - inline PhysicsComponent3D::PhysicsComponent3D(const PhysicsComponent3D& physics) + inline PhysicsComponent3D::PhysicsComponent3D(const PhysicsComponent3D& physics) : + m_nodeSynchronizationEnabled(physics.m_nodeSynchronizationEnabled) { // No copy of physical object (because we only create it when attached to an entity) NazaraUnused(physics); @@ -75,7 +80,6 @@ namespace Ndk * * \remark Produces a NazaraAssert if the physics object is invalid */ - inline void PhysicsComponent3D::EnableAutoSleep(bool autoSleep) { NazaraAssert(m_object, "Invalid physics object"); @@ -83,6 +87,22 @@ namespace Ndk m_object->EnableAutoSleep(autoSleep); } + /*! + * \brief Enables position/rotation synchronization with the NodeComponent + * + * By default, at every update of the PhysicsSystem3D, the NodeComponent's position and rotation (if any) will be synchronized with + * the values of the PhysicsComponent3D. This function allows to enable/disable this behavior on a per-entity basis. + * + * \param nodeSynchronization Should synchronization occur between NodeComponent and PhysicsComponent3D + */ + inline void PhysicsComponent3D::EnableNodeSynchronization(bool nodeSynchronization) + { + m_nodeSynchronizationEnabled = nodeSynchronization; + + if (m_entity) + m_entity->Invalidate(); + } + /*! * \brief Gets the AABB of the physics object * \return AABB of the object @@ -178,7 +198,7 @@ namespace Ndk * \brief Gets the gravity center of the physics object * \return Gravity center of the object * - * \param coordSys System coordinates to consider + * \param coordSys System coordinates to consider * * \remark Produces a NazaraAssert if the physics object is invalid */ @@ -258,13 +278,23 @@ namespace Ndk return m_object->IsMoveable(); } + /*! + * \brief Checks if position & rotation are synchronized with NodeComponent + * \return true If synchronization is enabled + * + * \see EnableNodeSynchronization + */ + inline bool PhysicsComponent3D::IsNodeSynchronizationEnabled() const + { + return m_nodeSynchronizationEnabled; + } + /*! * \brief Checks whether the entity is currently sleeping * \return true If it is the case * * \remark Produces a NazaraAssert if the physics object is invalid */ - inline bool PhysicsComponent3D::IsSleeping() const { NazaraAssert(m_object, "Invalid physics object"); diff --git a/SDK/src/NDK/Systems/PhysicsSystem3D.cpp b/SDK/src/NDK/Systems/PhysicsSystem3D.cpp index efb2a0554..8aec2d8e2 100644 --- a/SDK/src/NDK/Systems/PhysicsSystem3D.cpp +++ b/SDK/src/NDK/Systems/PhysicsSystem3D.cpp @@ -47,16 +47,20 @@ namespace Ndk void PhysicsSystem3D::OnEntityValidation(Entity* entity, bool justAdded) { - // It's possible our entity got revalidated because of the addition/removal of a PhysicsComponent3D - if (!justAdded) + if (entity->HasComponent()) { - // We take the opposite array from which the entity should belong to - auto& entities = (entity->HasComponent()) ? m_staticObjects : m_dynamicObjects; - entities.Remove(entity); - } + if (entity->GetComponent().IsNodeSynchronizationEnabled()) + m_dynamicObjects.Insert(entity); + else + m_dynamicObjects.Remove(entity); - auto& entities = (entity->HasComponent()) ? m_dynamicObjects : m_staticObjects; - entities.Insert(entity); + m_staticObjects.Remove(entity); + } + else + { + m_dynamicObjects.Remove(entity); + m_staticObjects.Insert(entity); + } if (!m_world) CreatePhysWorld();