diff --git a/ChangeLog.md b/ChangeLog.md index 90403a1b5..353910cb0 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -290,6 +290,7 @@ Nazara Development Kit: - ⚠️ Added RichTextAreaWidget - ⚠️ Console now supports text color in history - Added World::CloneEntity overload taking an EntityHandle const reference, allowing to copy entities from other worlds +- Fixed PhysicsComponent2D copy not copying physics attributes # 0.4: diff --git a/SDK/include/NDK/Components/PhysicsComponent2D.hpp b/SDK/include/NDK/Components/PhysicsComponent2D.hpp index 93383d707..e12d36ebc 100644 --- a/SDK/include/NDK/Components/PhysicsComponent2D.hpp +++ b/SDK/include/NDK/Components/PhysicsComponent2D.hpp @@ -86,7 +86,10 @@ namespace Ndk static ComponentIndex componentIndex; private: + inline void ApplyPhysicsState(Nz::RigidBody2D& rigidBody) const; + inline void CopyPhysicsState(const Nz::RigidBody2D& rigidBody); Nz::RigidBody2D* GetRigidBody(); + const Nz::RigidBody2D* GetRigidBody() const; void OnAttached() override; void OnComponentAttached(BaseComponent& component) override; @@ -94,7 +97,27 @@ namespace Ndk void OnDetached() override; void OnEntityDestruction() override; + struct PendingPhysObjectStates + { + struct ShapeStates + { + Nz::Vector2f surfaceVelocity; + float elasticity; + float friction; + }; + + VelocityFunc velocityFunc; + std::vector shapes; + Nz::RadianAnglef angularVelocity; + Nz::Vector2f massCenter; + Nz::Vector2f velocity; + bool valid = false; + float mass; + float momentOfInertia; + }; + std::unique_ptr m_object; + PendingPhysObjectStates m_pendingStates; bool m_nodeSynchronizationEnabled; }; } diff --git a/SDK/include/NDK/Components/PhysicsComponent2D.inl b/SDK/include/NDK/Components/PhysicsComponent2D.inl index f30dd8618..911751a42 100644 --- a/SDK/include/NDK/Components/PhysicsComponent2D.inl +++ b/SDK/include/NDK/Components/PhysicsComponent2D.inl @@ -22,8 +22,7 @@ namespace Ndk */ inline PhysicsComponent2D::PhysicsComponent2D(const PhysicsComponent2D& physics) { - // No copy of physical object (because we only create it when attached to an entity) - NazaraUnused(physics); + CopyPhysicsState(*physics.GetRigidBody()); } /*! @@ -649,6 +648,47 @@ namespace Ndk m_object->UpdateVelocity(gravity, damping, deltaTime); } + inline void PhysicsComponent2D::ApplyPhysicsState(Nz::RigidBody2D& rigidBody) const + { + assert(m_pendingStates.valid); + + rigidBody.SetAngularVelocity(m_pendingStates.angularVelocity); + rigidBody.SetMass(m_pendingStates.mass); + rigidBody.SetMassCenter(m_pendingStates.massCenter); + rigidBody.SetMomentOfInertia(m_pendingStates.momentOfInertia); + rigidBody.SetVelocity(m_pendingStates.velocity); + rigidBody.SetVelocityFunction(m_pendingStates.velocityFunc); + + for (std::size_t i = 0; i < m_pendingStates.shapes.size(); ++i) + { + auto& shapeData = m_pendingStates.shapes[i]; + rigidBody.SetElasticity(i, shapeData.elasticity); + rigidBody.SetFriction(i, shapeData.friction); + rigidBody.SetSurfaceVelocity(i, shapeData.surfaceVelocity); + } + } + + inline void PhysicsComponent2D::CopyPhysicsState(const Nz::RigidBody2D& rigidBody) + { + m_pendingStates.valid = true; + + m_pendingStates.angularVelocity = rigidBody.GetAngularVelocity(); + m_pendingStates.mass = rigidBody.GetMass(); + m_pendingStates.massCenter = rigidBody.GetMassCenter(); + m_pendingStates.momentOfInertia = rigidBody.GetMomentOfInertia(); + m_pendingStates.velocity = rigidBody.GetVelocity(); + m_pendingStates.velocityFunc = rigidBody.GetVelocityFunction(); + + m_pendingStates.shapes.resize(rigidBody.GetShapeCount()); + for (std::size_t i = 0; i < m_pendingStates.shapes.size(); ++i) + { + auto& shapeData = m_pendingStates.shapes[i]; + shapeData.elasticity = rigidBody.GetElasticity(i); + shapeData.friction = rigidBody.GetFriction(i); + shapeData.surfaceVelocity = rigidBody.GetSurfaceVelocity(i); + } + } + /*! * \brief Gets the underlying physics object * \return A reference to the physics object @@ -657,4 +697,9 @@ namespace Ndk { return m_object.get(); } + + inline const Nz::RigidBody2D* PhysicsComponent2D::GetRigidBody() const + { + return m_object.get(); + } } diff --git a/SDK/src/NDK/Components/PhysicsComponent2D.cpp b/SDK/src/NDK/Components/PhysicsComponent2D.cpp index f9feaff6e..871fa762e 100644 --- a/SDK/src/NDK/Components/PhysicsComponent2D.cpp +++ b/SDK/src/NDK/Components/PhysicsComponent2D.cpp @@ -53,6 +53,9 @@ namespace Ndk m_object->SetPositionOffset(positionOffset); m_object->SetPosition(Nz::Vector2f(matrix.GetTranslation())); m_object->SetUserdata(reinterpret_cast(static_cast(m_entity->GetId()))); + + if (m_pendingStates.valid) + ApplyPhysicsState(*m_object); } /*! @@ -95,7 +98,11 @@ namespace Ndk void PhysicsComponent2D::OnDetached() { - m_object.reset(); + if (m_object) + { + CopyPhysicsState(*m_object); + m_object.reset(); + } } void PhysicsComponent2D::OnEntityDestruction()