Physics2D: Handle kinematic objects properly
This commit is contained in:
parent
305a72a7d2
commit
3153af485c
|
|
@ -44,13 +44,14 @@ namespace Nz
|
|||
const Collider2DRef& GetGeom() const;
|
||||
cpBody* GetHandle() const;
|
||||
float GetMass() const;
|
||||
float GetMomentOfInertia() const;
|
||||
Vector2f GetPosition() const;
|
||||
float GetRotation() const;
|
||||
void* GetUserdata() const;
|
||||
Vector2f GetVelocity() const;
|
||||
PhysWorld2D* GetWorld() const;
|
||||
|
||||
bool IsMoveable() const;
|
||||
bool IsKinematic() const;
|
||||
bool IsSleeping() const;
|
||||
|
||||
void SetAngularVelocity(float angularVelocity);
|
||||
|
|
@ -70,7 +71,8 @@ namespace Nz
|
|||
NazaraSignal(OnRigidBody2DRelease, RigidBody2D* /*rigidBody*/);
|
||||
|
||||
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();
|
||||
|
||||
std::vector<cpShape*> m_shapes;
|
||||
|
|
|
|||
|
|
@ -143,9 +143,9 @@ namespace Nz
|
|||
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
|
||||
|
|
|
|||
|
|
@ -27,10 +27,8 @@ namespace Nz
|
|||
{
|
||||
NazaraAssert(m_world, "Invalid world");
|
||||
|
||||
Create();
|
||||
|
||||
m_handle = Create(mass);
|
||||
SetGeom(geom);
|
||||
SetMass(mass);
|
||||
}
|
||||
|
||||
RigidBody2D::RigidBody2D(const RigidBody2D& object) :
|
||||
|
|
@ -43,30 +41,13 @@ namespace Nz
|
|||
NazaraAssert(m_world, "Invalid world");
|
||||
NazaraAssert(m_geom, "Invalid geometry");
|
||||
|
||||
Create();
|
||||
m_handle = Create(object.GetMass(), object.GetMomentOfInertia());
|
||||
SetGeom(object.GetGeom(), false);
|
||||
|
||||
cpBodySetMass(m_handle, cpBodyGetMass(object.GetHandle()));
|
||||
cpBodySetMoment(m_handle, cpBodyGetMoment(object.GetHandle()));
|
||||
CopyBodyData(object.GetHandle());
|
||||
|
||||
SetGeom(object.GetGeom());
|
||||
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)
|
||||
for (int i = 0; i < m_shapes.size(); ++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) :
|
||||
|
|
@ -172,6 +153,11 @@ namespace Nz
|
|||
return m_mass;
|
||||
}
|
||||
|
||||
float RigidBody2D::GetMomentOfInertia() const
|
||||
{
|
||||
return float(cpBodyGetMoment(m_handle));
|
||||
}
|
||||
|
||||
Vector2f RigidBody2D::GetCenterOfGravity(CoordSys coordSys) const
|
||||
{
|
||||
cpVect cog = cpBodyGetCenterOfGravity(m_handle);
|
||||
|
|
@ -216,9 +202,9 @@ namespace Nz
|
|||
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
|
||||
|
|
@ -240,8 +226,12 @@ namespace Nz
|
|||
cpFloat mass = cpBodyGetMass(m_handle);
|
||||
cpFloat moment = cpBodyGetMoment(m_handle);
|
||||
|
||||
cpBody* newHandle = Create(static_cast<float>(mass), static_cast<float>(moment));
|
||||
|
||||
CopyBodyData(m_handle);
|
||||
Destroy();
|
||||
Create(static_cast<float>(mass), static_cast<float>(moment));
|
||||
|
||||
m_handle = newHandle;
|
||||
}
|
||||
|
||||
if (geom)
|
||||
|
|
@ -299,8 +289,7 @@ namespace Nz
|
|||
|
||||
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));
|
||||
}
|
||||
|
||||
void RigidBody2D::SetMomentOfInertia(float moment)
|
||||
|
|
@ -364,12 +353,28 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
void RigidBody2D::Create(float mass, float moment)
|
||||
void RigidBody2D::CopyBodyData(cpBody* body)
|
||||
{
|
||||
m_handle = cpBodyNew(mass, moment);
|
||||
cpBodySetUserData(m_handle, this);
|
||||
cpBodySetAngle(m_handle, cpBodyGetAngle(body));
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
|||
CHECK(body.GetUserdata() == &userData);
|
||||
CHECK(body.GetVelocity() == Nz::Vector2f::Zero());
|
||||
|
||||
CHECK(body.IsMoveable() == true);
|
||||
CHECK(body.IsKinematic() == false);
|
||||
CHECK(body.IsSleeping() == false);
|
||||
}
|
||||
}
|
||||
|
|
@ -315,4 +315,4 @@ void EQUALITY(const Nz::RigidBody2D& left, const Nz::RigidBody2D& right)
|
|||
CHECK(left.GetRotation() == right.GetRotation());
|
||||
CHECK(left.GetUserdata() == right.GetUserdata());
|
||||
CHECK(left.GetVelocity() == right.GetVelocity());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue