Sdk/PhysicsComponent2D: Fix copy

This commit is contained in:
Lynix 2019-10-15 09:33:35 +02:00
parent f6bbe396fa
commit 8004c84663
4 changed files with 79 additions and 3 deletions

View File

@ -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:

View File

@ -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<ShapeStates> shapes;
Nz::RadianAnglef angularVelocity;
Nz::Vector2f massCenter;
Nz::Vector2f velocity;
bool valid = false;
float mass;
float momentOfInertia;
};
std::unique_ptr<Nz::RigidBody2D> m_object;
PendingPhysObjectStates m_pendingStates;
bool m_nodeSynchronizationEnabled;
};
}

View File

@ -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();
}
}

View File

@ -53,6 +53,9 @@ namespace Ndk
m_object->SetPositionOffset(positionOffset);
m_object->SetPosition(Nz::Vector2f(matrix.GetTranslation()));
m_object->SetUserdata(reinterpret_cast<void*>(static_cast<std::ptrdiff_t>(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()