Physics2D: Handle kinematic objects properly
This commit is contained in:
parent
305a72a7d2
commit
3153af485c
|
|
@ -44,13 +44,14 @@ namespace Nz
|
||||||
const Collider2DRef& GetGeom() const;
|
const Collider2DRef& GetGeom() const;
|
||||||
cpBody* GetHandle() const;
|
cpBody* GetHandle() const;
|
||||||
float GetMass() const;
|
float GetMass() const;
|
||||||
|
float GetMomentOfInertia() const;
|
||||||
Vector2f GetPosition() const;
|
Vector2f GetPosition() const;
|
||||||
float GetRotation() const;
|
float GetRotation() const;
|
||||||
void* GetUserdata() const;
|
void* GetUserdata() const;
|
||||||
Vector2f GetVelocity() const;
|
Vector2f GetVelocity() const;
|
||||||
PhysWorld2D* GetWorld() const;
|
PhysWorld2D* GetWorld() const;
|
||||||
|
|
||||||
bool IsMoveable() const;
|
bool IsKinematic() const;
|
||||||
bool IsSleeping() const;
|
bool IsSleeping() const;
|
||||||
|
|
||||||
void SetAngularVelocity(float angularVelocity);
|
void SetAngularVelocity(float angularVelocity);
|
||||||
|
|
@ -70,7 +71,8 @@ namespace Nz
|
||||||
NazaraSignal(OnRigidBody2DRelease, RigidBody2D* /*rigidBody*/);
|
NazaraSignal(OnRigidBody2DRelease, RigidBody2D* /*rigidBody*/);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Create(float mass = 1.f, float moment = 1.f);
|
void CopyBodyData(cpBody* body);
|
||||||
|
cpBody* Create(float mass = 1.f, float moment = 1.f);
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
std::vector<cpShape*> m_shapes;
|
std::vector<cpShape*> m_shapes;
|
||||||
|
|
|
||||||
|
|
@ -143,9 +143,9 @@ namespace Nz
|
||||||
return ColliderType2D_Null;
|
return ColliderType2D_Null;
|
||||||
}
|
}
|
||||||
|
|
||||||
float NullCollider2D::ComputeMomentOfInertia(float /*mass*/) const
|
float NullCollider2D::ComputeMomentOfInertia(float mass) const
|
||||||
{
|
{
|
||||||
return 0.f;
|
return (mass > 0.f) ? 1.f : 0.f; //< Null inertia is only possible for static/kinematic objects
|
||||||
}
|
}
|
||||||
|
|
||||||
void NullCollider2D::CreateShapes(RigidBody2D* /*body*/, std::vector<cpShape*>& /*shapes*/) const
|
void NullCollider2D::CreateShapes(RigidBody2D* /*body*/, std::vector<cpShape*>& /*shapes*/) const
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,8 @@ namespace Nz
|
||||||
{
|
{
|
||||||
NazaraAssert(m_world, "Invalid world");
|
NazaraAssert(m_world, "Invalid world");
|
||||||
|
|
||||||
Create();
|
m_handle = Create(mass);
|
||||||
|
|
||||||
SetGeom(geom);
|
SetGeom(geom);
|
||||||
SetMass(mass);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RigidBody2D::RigidBody2D(const RigidBody2D& object) :
|
RigidBody2D::RigidBody2D(const RigidBody2D& object) :
|
||||||
|
|
@ -43,30 +41,13 @@ namespace Nz
|
||||||
NazaraAssert(m_world, "Invalid world");
|
NazaraAssert(m_world, "Invalid world");
|
||||||
NazaraAssert(m_geom, "Invalid geometry");
|
NazaraAssert(m_geom, "Invalid geometry");
|
||||||
|
|
||||||
Create();
|
m_handle = Create(object.GetMass(), object.GetMomentOfInertia());
|
||||||
|
SetGeom(object.GetGeom(), false);
|
||||||
|
|
||||||
cpBodySetMass(m_handle, cpBodyGetMass(object.GetHandle()));
|
CopyBodyData(object.GetHandle());
|
||||||
cpBodySetMoment(m_handle, cpBodyGetMoment(object.GetHandle()));
|
|
||||||
|
|
||||||
SetGeom(object.GetGeom());
|
for (int i = 0; i < m_shapes.size(); ++i)
|
||||||
SetMass(object.GetMass());
|
|
||||||
|
|
||||||
cpBodySetForce(m_handle, cpBodyGetForce(object.GetHandle()));
|
|
||||||
cpBodySetTorque(m_handle, cpBodyGetTorque(object.GetHandle()));
|
|
||||||
|
|
||||||
cpBodySetAngle(m_handle, cpBodyGetAngle(object.GetHandle()));
|
|
||||||
cpBodySetAngularVelocity(m_handle, cpBodyGetAngularVelocity(object.GetHandle()));
|
|
||||||
cpBodySetCenterOfGravity(m_handle, cpBodyGetCenterOfGravity(object.GetHandle()));
|
|
||||||
cpBodySetPosition(m_handle, cpBodyGetPosition(object.GetHandle()));
|
|
||||||
cpBodySetVelocity(m_handle, cpBodyGetVelocity(object.GetHandle()));
|
|
||||||
|
|
||||||
for (int i = 0; i != m_shapes.size(); ++i)
|
|
||||||
m_shapes[i]->bb = cpShapeCacheBB(object.m_shapes[i]);
|
m_shapes[i]->bb = cpShapeCacheBB(object.m_shapes[i]);
|
||||||
|
|
||||||
cpBodySetMass(m_handle, cpBodyGetMass(object.GetHandle()));
|
|
||||||
cpBodySetMoment(m_handle, cpBodyGetMoment(object.GetHandle()));
|
|
||||||
|
|
||||||
m_handle->m = object.GetHandle()->m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RigidBody2D::RigidBody2D(RigidBody2D&& object) :
|
RigidBody2D::RigidBody2D(RigidBody2D&& object) :
|
||||||
|
|
@ -172,6 +153,11 @@ namespace Nz
|
||||||
return m_mass;
|
return m_mass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float RigidBody2D::GetMomentOfInertia() const
|
||||||
|
{
|
||||||
|
return float(cpBodyGetMoment(m_handle));
|
||||||
|
}
|
||||||
|
|
||||||
Vector2f RigidBody2D::GetCenterOfGravity(CoordSys coordSys) const
|
Vector2f RigidBody2D::GetCenterOfGravity(CoordSys coordSys) const
|
||||||
{
|
{
|
||||||
cpVect cog = cpBodyGetCenterOfGravity(m_handle);
|
cpVect cog = cpBodyGetCenterOfGravity(m_handle);
|
||||||
|
|
@ -216,9 +202,9 @@ namespace Nz
|
||||||
return m_world;
|
return m_world;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RigidBody2D::IsMoveable() const
|
bool RigidBody2D::IsKinematic() const
|
||||||
{
|
{
|
||||||
return m_mass > 0.f;
|
return m_mass <= 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RigidBody2D::IsSleeping() const
|
bool RigidBody2D::IsSleeping() const
|
||||||
|
|
@ -240,8 +226,12 @@ namespace Nz
|
||||||
cpFloat mass = cpBodyGetMass(m_handle);
|
cpFloat mass = cpBodyGetMass(m_handle);
|
||||||
cpFloat moment = cpBodyGetMoment(m_handle);
|
cpFloat moment = cpBodyGetMoment(m_handle);
|
||||||
|
|
||||||
|
cpBody* newHandle = Create(static_cast<float>(mass), static_cast<float>(moment));
|
||||||
|
|
||||||
|
CopyBodyData(m_handle);
|
||||||
Destroy();
|
Destroy();
|
||||||
Create(static_cast<float>(mass), static_cast<float>(moment));
|
|
||||||
|
m_handle = newHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (geom)
|
if (geom)
|
||||||
|
|
@ -299,7 +289,6 @@ namespace Nz
|
||||||
|
|
||||||
void RigidBody2D::SetMassCenter(const Vector2f& center)
|
void RigidBody2D::SetMassCenter(const Vector2f& center)
|
||||||
{
|
{
|
||||||
if (m_mass > 0.f)
|
|
||||||
cpBodySetCenterOfGravity(m_handle, cpv(center.x, center.y));
|
cpBodySetCenterOfGravity(m_handle, cpv(center.x, center.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -364,12 +353,28 @@ namespace Nz
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody2D::Create(float mass, float moment)
|
void RigidBody2D::CopyBodyData(cpBody* body)
|
||||||
{
|
{
|
||||||
m_handle = cpBodyNew(mass, moment);
|
cpBodySetAngle(m_handle, cpBodyGetAngle(body));
|
||||||
cpBodySetUserData(m_handle, this);
|
cpBodySetAngularVelocity(m_handle, cpBodyGetAngularVelocity(body));
|
||||||
|
cpBodySetCenterOfGravity(m_handle, cpBodyGetCenterOfGravity(body));
|
||||||
|
cpBodySetForce(m_handle, cpBodyGetForce(body));
|
||||||
|
cpBodySetPosition(m_handle, cpBodyGetPosition(body));
|
||||||
|
cpBodySetTorque(m_handle, cpBodyGetTorque(body));
|
||||||
|
cpBodySetVelocity(m_handle, cpBodyGetVelocity(body));
|
||||||
|
}
|
||||||
|
|
||||||
cpSpaceAddBody(m_world->GetHandle(), m_handle);
|
cpBody* RigidBody2D::Create(float mass, float moment)
|
||||||
|
{
|
||||||
|
cpBody* handle = cpBodyNew(mass, moment);
|
||||||
|
cpBodySetUserData(handle, this);
|
||||||
|
|
||||||
|
if (mass <= 0.f)
|
||||||
|
cpBodySetType(handle, CP_BODY_TYPE_KINEMATIC);
|
||||||
|
|
||||||
|
cpSpaceAddBody(m_world->GetHandle(), handle);
|
||||||
|
|
||||||
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody2D::Destroy()
|
void RigidBody2D::Destroy()
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,7 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
||||||
CHECK(body.GetUserdata() == &userData);
|
CHECK(body.GetUserdata() == &userData);
|
||||||
CHECK(body.GetVelocity() == Nz::Vector2f::Zero());
|
CHECK(body.GetVelocity() == Nz::Vector2f::Zero());
|
||||||
|
|
||||||
CHECK(body.IsMoveable() == true);
|
CHECK(body.IsKinematic() == false);
|
||||||
CHECK(body.IsSleeping() == false);
|
CHECK(body.IsSleeping() == false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue