Physics2D/RigidBody2D: Add SetStatic method

This commit is contained in:
Jérôme Leclercq 2017-10-16 11:56:41 +02:00
parent ee06fffd03
commit 6e7b78611d
2 changed files with 51 additions and 5 deletions

View File

@ -52,6 +52,7 @@ namespace Nz
bool IsKinematic() const; bool IsKinematic() const;
bool IsSleeping() const; bool IsSleeping() const;
bool IsStatic() const;
void SetAngularVelocity(float angularVelocity); void SetAngularVelocity(float angularVelocity);
void SetGeom(Collider2DRef geom, bool recomputeMoment = true); void SetGeom(Collider2DRef geom, bool recomputeMoment = true);
@ -60,6 +61,7 @@ namespace Nz
void SetMomentOfInertia(float moment); void SetMomentOfInertia(float moment);
void SetPosition(const Vector2f& position); void SetPosition(const Vector2f& position);
void SetRotation(float rotation); void SetRotation(float rotation);
void SetStatic(bool setStaticBody = true);
void SetUserdata(void* ud); void SetUserdata(void* ud);
void SetVelocity(const Vector2f& velocity); void SetVelocity(const Vector2f& velocity);
@ -81,9 +83,10 @@ namespace Nz
cpBody* m_handle; cpBody* m_handle;
void* m_userData; void* m_userData;
PhysWorld2D* m_world; PhysWorld2D* m_world;
bool m_isStatic;
float m_gravityFactor; float m_gravityFactor;
float m_mass; float m_mass;
}; };
} }
#endif // NAZARA_RIGIDBODY3D_HPP #endif // NAZARA_RIGIDBODY2D_HPP

View File

@ -20,8 +20,9 @@ namespace Nz
m_geom(), m_geom(),
m_userData(nullptr), m_userData(nullptr),
m_world(world), m_world(world),
m_isStatic(false),
m_gravityFactor(1.f), m_gravityFactor(1.f),
m_mass(1.f) m_mass(mass)
{ {
NazaraAssert(m_world, "Invalid world"); NazaraAssert(m_world, "Invalid world");
@ -33,6 +34,7 @@ namespace Nz
m_geom(object.m_geom), m_geom(object.m_geom),
m_userData(object.m_userData), m_userData(object.m_userData),
m_world(object.m_world), m_world(object.m_world),
m_isStatic(object.m_isStatic),
m_gravityFactor(object.m_gravityFactor), m_gravityFactor(object.m_gravityFactor),
m_mass(object.GetMass()) m_mass(object.GetMass())
{ {
@ -56,6 +58,7 @@ namespace Nz
m_userData(object.m_userData), m_userData(object.m_userData),
m_handle(object.m_handle), m_handle(object.m_handle),
m_world(object.m_world), m_world(object.m_world),
m_isStatic(object.m_isStatic),
m_gravityFactor(object.m_gravityFactor), m_gravityFactor(object.m_gravityFactor),
m_mass(object.m_mass) m_mass(object.m_mass)
{ {
@ -219,6 +222,11 @@ namespace Nz
return cpBodyIsSleeping(m_handle) != 0; return cpBodyIsSleeping(m_handle) != 0;
} }
bool RigidBody2D::IsStatic() const
{
return m_isStatic;
}
void RigidBody2D::SetAngularVelocity(float angularVelocity) void RigidBody2D::SetAngularVelocity(float angularVelocity)
{ {
cpBodySetAngularVelocity(m_handle, ToRadians(angularVelocity)); cpBodySetAngularVelocity(m_handle, ToRadians(angularVelocity));
@ -256,7 +264,10 @@ namespace Nz
} }
if (recomputeMoment) if (recomputeMoment)
cpBodySetMoment(m_handle, m_geom->ComputeMomentOfInertia(m_mass)); {
if (!IsStatic() && !IsKinematic())
cpBodySetMoment(m_handle, m_geom->ComputeMomentOfInertia(m_mass));
}
} }
void RigidBody2D::SetMass(float mass, bool recomputeMoment) void RigidBody2D::SetMass(float mass, bool recomputeMoment)
@ -274,13 +285,13 @@ namespace Nz
}); });
} }
else else
m_world->RegisterPostStep(this, [](Nz::RigidBody2D* body) { cpBodySetType(body->GetHandle(), CP_BODY_TYPE_KINEMATIC); } ); m_world->RegisterPostStep(this, [](Nz::RigidBody2D* body) { cpBodySetType(body->GetHandle(), (body->IsStatic()) ? CP_BODY_TYPE_STATIC : CP_BODY_TYPE_KINEMATIC); } );
} }
else if (mass > 0.f) else if (mass > 0.f)
{ {
m_world->RegisterPostStep(this, [mass, recomputeMoment](Nz::RigidBody2D* body) m_world->RegisterPostStep(this, [mass, recomputeMoment](Nz::RigidBody2D* body)
{ {
if (cpBodyGetType(body->GetHandle()) == CP_BODY_TYPE_KINEMATIC) if (cpBodyGetType(body->GetHandle()) != CP_BODY_TYPE_DYNAMIC)
{ {
cpBodySetType(body->GetHandle(), CP_BODY_TYPE_DYNAMIC); cpBodySetType(body->GetHandle(), CP_BODY_TYPE_DYNAMIC);
cpBodySetMass(body->GetHandle(), mass); cpBodySetMass(body->GetHandle(), mass);
@ -311,11 +322,42 @@ namespace Nz
void RigidBody2D::SetPosition(const Vector2f& position) void RigidBody2D::SetPosition(const Vector2f& position)
{ {
cpBodySetPosition(m_handle, cpv(position.x, position.y)); cpBodySetPosition(m_handle, cpv(position.x, position.y));
if (m_isStatic)
{
m_world->RegisterPostStep(this, [](Nz::RigidBody2D* body)
{
cpSpaceReindexShapesForBody(body->GetWorld()->GetHandle(), body->GetHandle());
});
}
} }
void RigidBody2D::SetRotation(float rotation) void RigidBody2D::SetRotation(float rotation)
{ {
cpBodySetAngle(m_handle, ToRadians(rotation)); cpBodySetAngle(m_handle, ToRadians(rotation));
if (m_isStatic)
{
m_world->RegisterPostStep(this, [](Nz::RigidBody2D* body)
{
cpSpaceReindexShapesForBody(body->GetWorld()->GetHandle(), body->GetHandle());
});
}
}
void RigidBody2D::SetStatic(bool setStaticBody)
{
m_isStatic = setStaticBody;
m_world->RegisterPostStep(this, [](Nz::RigidBody2D* body)
{
if (body->IsStatic())
{
cpBodySetType(body->GetHandle(), CP_BODY_TYPE_STATIC);
cpSpaceReindexShapesForBody(body->GetWorld()->GetHandle(), body->GetHandle());
}
else if (cpBodyGetMass(body->GetHandle()) > 0.f)
cpBodySetType(body->GetHandle(), CP_BODY_TYPE_KINEMATIC);
else
cpBodySetType(body->GetHandle(), CP_BODY_TYPE_DYNAMIC);
});
} }
void RigidBody2D::SetUserdata(void* ud) void RigidBody2D::SetUserdata(void* ud)
@ -342,6 +384,7 @@ namespace Nz
OnRigidBody2DRelease = std::move(object.OnRigidBody2DRelease); OnRigidBody2DRelease = std::move(object.OnRigidBody2DRelease);
m_handle = object.m_handle; m_handle = object.m_handle;
m_isStatic = object.m_isStatic;
m_geom = std::move(object.m_geom); m_geom = std::move(object.m_geom);
m_gravityFactor = object.m_gravityFactor; m_gravityFactor = object.m_gravityFactor;
m_mass = object.m_mass; m_mass = object.m_mass;