From 2c0c8ef0a0fc07d3a23b45076bc5dc4e7390e375 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 24 Oct 2018 20:38:20 +0200 Subject: [PATCH] SDK/PhysicsComponent2D: Add node synchronization --- ChangeLog.md | 1 + .../NDK/Components/PhysicsComponent2D.hpp | 6 ++- .../NDK/Components/PhysicsComponent2D.inl | 37 ++++++++++++++++++- SDK/src/NDK/Systems/PhysicsSystem2D.cpp | 21 +++++++---- 4 files changed, 54 insertions(+), 11 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 669f8cc9e..f821d1910 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -223,6 +223,7 @@ Nazara Development Kit: - ⚠️ Use of the new Angle class instead of floating point angle - Added EntityOwner::Release - Add missing `recomputeMoment` parameter to PhysicsComponent2D::SetMass +- Added possibility of disabling synchronization between PhysicsComponent2D and NodeComponent # 0.4: diff --git a/SDK/include/NDK/Components/PhysicsComponent2D.hpp b/SDK/include/NDK/Components/PhysicsComponent2D.hpp index 7d040c5a7..696a8f99d 100644 --- a/SDK/include/NDK/Components/PhysicsComponent2D.hpp +++ b/SDK/include/NDK/Components/PhysicsComponent2D.hpp @@ -24,7 +24,7 @@ namespace Ndk friend class ConstraintComponent2D; public: - PhysicsComponent2D() = default; + PhysicsComponent2D(); PhysicsComponent2D(const PhysicsComponent2D& physics); ~PhysicsComponent2D() = default; @@ -36,6 +36,8 @@ namespace Ndk inline bool ClosestPointQuery(const Nz::Vector2f& position, Nz::Vector2f* closestPoint, float* closestDistance) const; + inline void EnableNodeSynchronization(bool nodeSynchronization); + inline Nz::Rectf GetAABB() const; inline float GetAngularDamping() const; inline Nz::RadianAnglef GetAngularVelocity() const; @@ -52,6 +54,7 @@ namespace Ndk inline std::size_t GetShapeCount() const; inline Nz::Vector2f GetVelocity() const; + inline bool IsNodeSynchronizationEnabled() const; inline bool IsSleeping() const; inline void SetAngularDamping(float angularDamping); @@ -81,6 +84,7 @@ namespace Ndk void OnEntityDestruction() override; std::unique_ptr m_object; + bool m_nodeSynchronizationEnabled; }; } diff --git a/SDK/include/NDK/Components/PhysicsComponent2D.inl b/SDK/include/NDK/Components/PhysicsComponent2D.inl index 387e50469..dd90b5f9a 100644 --- a/SDK/include/NDK/Components/PhysicsComponent2D.inl +++ b/SDK/include/NDK/Components/PhysicsComponent2D.inl @@ -7,12 +7,19 @@ namespace Ndk { + /*! + * \brief Constructs a PhysicsComponent2D object by default + */ + inline PhysicsComponent2D::PhysicsComponent2D() : + m_nodeSynchronizationEnabled(true) + { + } + /*! * \brief Constructs a PhysicsComponent2D object by copy semantic * * \param physics PhysicsComponent2D to copy */ - inline PhysicsComponent2D::PhysicsComponent2D(const PhysicsComponent2D& physics) { // No copy of physical object (because we only create it when attached to an entity) @@ -115,6 +122,22 @@ namespace Ndk return m_object->ClosestPointQuery(position, closestPoint, closestDistance); } + /*! + * \brief Enables position/rotation synchronization with the NodeComponent + * + * By default, at every update of the PhysicsSystem2D, the NodeComponent's position and rotation (if any) will be synchronized with + * the values of the PhysicsComponent2D. This function allows to enable/disable this behavior on a per-entity basis. + * + * \param nodeSynchronization Should synchronization occur between NodeComponent and PhysicsComponent2D + */ + inline void PhysicsComponent2D::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 @@ -314,13 +337,23 @@ namespace Ndk return m_object->GetVelocity(); } + /*! + * \brief Checks if position & rotation are synchronized with NodeComponent + * \return true If synchronization is enabled + * + * \see EnableNodeSynchronization + */ + inline bool PhysicsComponent2D::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 PhysicsComponent2D::IsSleeping() const { NazaraAssert(m_object, "Invalid physics object"); diff --git a/SDK/src/NDK/Systems/PhysicsSystem2D.cpp b/SDK/src/NDK/Systems/PhysicsSystem2D.cpp index 69d6a99b1..29baeb6a1 100644 --- a/SDK/src/NDK/Systems/PhysicsSystem2D.cpp +++ b/SDK/src/NDK/Systems/PhysicsSystem2D.cpp @@ -147,16 +147,21 @@ namespace Ndk void PhysicsSystem2D::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_physWorld) CreatePhysWorld();