From 7a04c6f83b0e5b1fc140c22e176f06ccd803f29d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Wed, 17 Jan 2018 17:13:50 +0100 Subject: [PATCH] Physics2D/RigidBody2D: Add EnableSimulation/IsSimulationEnabled --- ChangeLog.md | 1 + include/Nazara/Physics2D/RigidBody2D.hpp | 7 +++ src/Nazara/Physics2D/RigidBody2D.cpp | 70 ++++++++++++++++++++---- 3 files changed, 68 insertions(+), 10 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 27ff205ed..18a8b61c2 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -57,6 +57,7 @@ Nazara Engine: - Add JPEG image saver - Update Constraint2Ds classes (Add : Ref, Library, ConstRef, New function and Update : ctors) - Fix LuaClass not working correctly when Lua stack wasn't empty +- Add RigidBody2D simulation control (via EnableSimulation and IsSimulationEnabled), which allows to disable physics and collisions at will. Nazara Development Kit: - Added ImageWidget (#139) diff --git a/include/Nazara/Physics2D/RigidBody2D.hpp b/include/Nazara/Physics2D/RigidBody2D.hpp index 49517aac3..4ca95717f 100644 --- a/include/Nazara/Physics2D/RigidBody2D.hpp +++ b/include/Nazara/Physics2D/RigidBody2D.hpp @@ -36,6 +36,8 @@ namespace Nz void AddImpulse(const Vector2f& impulse, const Vector2f& point, CoordSys coordSys = CoordSys_Global); void AddTorque(float torque); + void EnableSimulation(bool simulation); + Rectf GetAABB() const; float GetAngularVelocity() const; Vector2f GetCenterOfGravity(CoordSys coordSys = CoordSys_Local) const; @@ -51,6 +53,7 @@ namespace Nz PhysWorld2D* GetWorld() const; bool IsKinematic() const; + bool IsSimulationEnabled() const; bool IsSleeping() const; bool IsStatic() const; @@ -76,6 +79,8 @@ namespace Nz private: cpBody* Create(float mass = 1.f, float moment = 1.f); void Destroy(); + void RegisterToSpace(); + void UnregisterFromSpace(); static void CopyBodyData(cpBody* from, cpBody* to); @@ -84,6 +89,8 @@ namespace Nz cpBody* m_handle; void* m_userData; PhysWorld2D* m_world; + bool m_isRegistered; + bool m_isSimulationEnabled; bool m_isStatic; float m_gravityFactor; float m_mass; diff --git a/src/Nazara/Physics2D/RigidBody2D.cpp b/src/Nazara/Physics2D/RigidBody2D.cpp index fd54909b4..1bb39fbc1 100644 --- a/src/Nazara/Physics2D/RigidBody2D.cpp +++ b/src/Nazara/Physics2D/RigidBody2D.cpp @@ -20,6 +20,8 @@ namespace Nz m_geom(), m_userData(nullptr), m_world(world), + m_isRegistered(false), + m_isSimulationEnabled(true), m_isStatic(false), m_gravityFactor(1.f), m_mass(mass) @@ -34,6 +36,8 @@ namespace Nz m_geom(object.m_geom), m_userData(object.m_userData), m_world(object.m_world), + m_isRegistered(false), + m_isSimulationEnabled(true), m_isStatic(object.m_isStatic), m_gravityFactor(object.m_gravityFactor), m_mass(object.GetMass()) @@ -121,6 +125,19 @@ namespace Nz cpBodySetTorque(m_handle, cpBodyGetTorque(m_handle) + ToRadians(torque)); } + void RigidBody2D::EnableSimulation(bool simulation) + { + if (m_isRegistered != simulation) + { + m_isRegistered = simulation; + + if (simulation) + RegisterToSpace(); + else + UnregisterFromSpace(); + } + } + Rectf RigidBody2D::GetAABB() const { if (m_shapes.empty()) @@ -217,6 +234,11 @@ namespace Nz return m_mass <= 0.f; } + bool RigidBody2D::IsSimulationEnabled() const + { + return m_isRegistered; + } + bool RigidBody2D::IsSleeping() const { return cpBodyIsSleeping(m_handle) != 0; @@ -244,6 +266,7 @@ namespace Nz cpBody* newHandle = Create(static_cast(mass), static_cast(moment)); CopyBodyData(m_handle, newHandle); + Destroy(); m_handle = newHandle; @@ -258,10 +281,10 @@ namespace Nz cpSpace* space = m_world->GetHandle(); for (cpShape* shape : m_shapes) - { cpShapeSetUserData(shape, this); - cpSpaceAddShape(space, shape); - } + + if (m_isSimulationEnabled) + RegisterToSpace(); if (recomputeMoment) { @@ -384,6 +407,7 @@ namespace Nz OnRigidBody2DRelease = std::move(object.OnRigidBody2DRelease); m_handle = object.m_handle; + m_isRegistered = object.m_isRegistered; m_isStatic = object.m_isStatic; m_geom = std::move(object.m_geom); m_gravityFactor = object.m_gravityFactor; @@ -417,28 +441,54 @@ namespace Nz handle = cpBodyNew(mass, moment); cpBodySetUserData(handle, this); - cpSpaceAddBody(m_world->GetHandle(), handle); return handle; } void RigidBody2D::Destroy() { + UnregisterFromSpace(); + cpSpace* space = m_world->GetHandle(); for (cpShape* shape : m_shapes) - { - cpSpaceRemoveShape(space, shape); cpShapeFree(shape); - } if (m_handle) - { - cpSpaceRemoveBody(space, m_handle); cpBodyFree(m_handle); - } + m_shapes.clear(); } + void RigidBody2D::RegisterToSpace() + { + if (!m_isRegistered) + { + cpSpace* space = m_world->GetHandle(); + for (cpShape* shape : m_shapes) + cpSpaceAddShape(space, shape); + + if (m_handle) + cpSpaceAddBody(space, m_handle); + + m_isRegistered = true; + } + } + + void RigidBody2D::UnregisterFromSpace() + { + if (m_isRegistered) + { + cpSpace* space = m_world->GetHandle(); + for (cpShape* shape : m_shapes) + cpSpaceRemoveShape(space, shape); + + if (m_handle) + cpSpaceRemoveBody(space, m_handle); + + m_isRegistered = false; + } + } + void RigidBody2D::CopyBodyData(cpBody* from, cpBody* to) { cpBodySetAngle(to, cpBodyGetAngle(from));