diff --git a/ChangeLog.md b/ChangeLog.md index 1dabe076a..50fce9813 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -207,6 +207,7 @@ Nazara Engine: - ⚠ Node::Get[Position|Rotation|Scale] now defaults to local space - Fixed Node rotation when using a negative scale - Added HandledObject::OnHandledObjectDestruction signal +- Added physics function to control sleeping behavior Nazara Development Kit: - Added ImageWidget (#139) diff --git a/SDK/include/NDK/Components/PhysicsComponent2D.hpp b/SDK/include/NDK/Components/PhysicsComponent2D.hpp index e12d36ebc..3983c26a5 100644 --- a/SDK/include/NDK/Components/PhysicsComponent2D.hpp +++ b/SDK/include/NDK/Components/PhysicsComponent2D.hpp @@ -40,6 +40,7 @@ namespace Ndk inline void EnableNodeSynchronization(bool nodeSynchronization); + inline void ForceSleep(); inline void ForEachArbiter(const std::function& callback); inline Nz::Rectf GetAABB() const; @@ -83,6 +84,8 @@ namespace Ndk inline void UpdateVelocity(const Nz::Vector2f& gravity, float damping, float deltaTime); + inline void Wakeup(); + static ComponentIndex componentIndex; private: diff --git a/SDK/include/NDK/Components/PhysicsComponent2D.inl b/SDK/include/NDK/Components/PhysicsComponent2D.inl index 911751a42..6e0b0b10f 100644 --- a/SDK/include/NDK/Components/PhysicsComponent2D.inl +++ b/SDK/include/NDK/Components/PhysicsComponent2D.inl @@ -137,6 +137,16 @@ namespace Ndk m_entity->Invalidate(); } + /*! + TODO + */ + inline void PhysicsComponent2D::ForceSleep() + { + NazaraAssert(m_object, "Invalid physics object"); + + return m_object->ForceSleep(); + } + /*! TODO */ @@ -648,6 +658,16 @@ namespace Ndk m_object->UpdateVelocity(gravity, damping, deltaTime); } + /*! + TODO + */ + inline void PhysicsComponent2D::Wakeup() + { + NazaraAssert(m_object, "Invalid physics object"); + + return m_object->Wakeup(); + } + inline void PhysicsComponent2D::ApplyPhysicsState(Nz::RigidBody2D& rigidBody) const { assert(m_pendingStates.valid); diff --git a/SDK/include/NDK/Systems/PhysicsSystem2D.hpp b/SDK/include/NDK/Systems/PhysicsSystem2D.hpp index 35579862a..dd10fcd57 100644 --- a/SDK/include/NDK/Systems/PhysicsSystem2D.hpp +++ b/SDK/include/NDK/Systems/PhysicsSystem2D.hpp @@ -65,6 +65,7 @@ namespace Ndk inline void SetGravity(const Nz::Vector2f& gravity); inline void SetIterationCount(std::size_t iterationCount); inline void SetMaxStepCount(std::size_t maxStepCount); + inline void SetSleepTime(float sleepTime); inline void SetStepSize(float stepSize); inline void UseSpatialHash(float cellSize, std::size_t entityCount); diff --git a/SDK/include/NDK/Systems/PhysicsSystem2D.inl b/SDK/include/NDK/Systems/PhysicsSystem2D.inl index b8e7c61a2..64870c092 100644 --- a/SDK/include/NDK/Systems/PhysicsSystem2D.inl +++ b/SDK/include/NDK/Systems/PhysicsSystem2D.inl @@ -2,6 +2,8 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequisites.hpp +#include + namespace Ndk { inline float PhysicsSystem2D::GetDamping() const @@ -49,6 +51,11 @@ namespace Ndk GetPhysWorld().SetMaxStepCount(maxStepCount); } + inline void PhysicsSystem2D::SetSleepTime(float sleepTime) + { + GetPhysWorld().SetSleepTime(sleepTime); + } + inline void PhysicsSystem2D::SetStepSize(float stepSize) { GetPhysWorld().SetStepSize(stepSize); diff --git a/include/Nazara/Physics2D/PhysWorld2D.hpp b/include/Nazara/Physics2D/PhysWorld2D.hpp index 8d3afe07c..e6521b37a 100644 --- a/include/Nazara/Physics2D/PhysWorld2D.hpp +++ b/include/Nazara/Physics2D/PhysWorld2D.hpp @@ -78,6 +78,7 @@ namespace Nz void SetGravity(const Vector2f& gravity); void SetIterationCount(std::size_t iterationCount); void SetMaxStepCount(std::size_t maxStepCount); + void SetSleepTime(float sleepTime); void SetStepSize(float stepSize); void Step(float timestep); diff --git a/include/Nazara/Physics2D/RigidBody2D.hpp b/include/Nazara/Physics2D/RigidBody2D.hpp index bc40ef9c0..f80c0c8cf 100644 --- a/include/Nazara/Physics2D/RigidBody2D.hpp +++ b/include/Nazara/Physics2D/RigidBody2D.hpp @@ -46,6 +46,7 @@ namespace Nz void EnableSimulation(bool simulation); void ForEachArbiter(std::function callback); + void ForceSleep(); Rectf GetAABB() const; inline float GetAngularDamping() const; @@ -99,6 +100,8 @@ namespace Nz void UpdateVelocity(const Nz::Vector2f& gravity, float damping, float deltaTime); + void Wakeup(); + RigidBody2D& operator=(const RigidBody2D& object); RigidBody2D& operator=(RigidBody2D&& object); diff --git a/src/Nazara/Physics2D/PhysWorld2D.cpp b/src/Nazara/Physics2D/PhysWorld2D.cpp index 6e0c9c22a..0296558ec 100644 --- a/src/Nazara/Physics2D/PhysWorld2D.cpp +++ b/src/Nazara/Physics2D/PhysWorld2D.cpp @@ -338,6 +338,14 @@ namespace Nz m_maxStepCount = maxStepCount; } + void PhysWorld2D::SetSleepTime(float sleepTime) + { + if (sleepTime > 0) + cpSpaceSetSleepTimeThreshold(m_handle, cpFloat(sleepTime)); + else + cpSpaceSetSleepTimeThreshold(m_handle, std::numeric_limits::infinity()); + } + void PhysWorld2D::SetStepSize(float stepSize) { m_stepSize = stepSize; diff --git a/src/Nazara/Physics2D/RigidBody2D.cpp b/src/Nazara/Physics2D/RigidBody2D.cpp index e1e98759a..1e3835bdd 100644 --- a/src/Nazara/Physics2D/RigidBody2D.cpp +++ b/src/Nazara/Physics2D/RigidBody2D.cpp @@ -194,6 +194,15 @@ namespace Nz cpBodyEachArbiter(m_handle, RealCallback, &callback); } + void RigidBody2D::ForceSleep() + { + m_world->RegisterPostStep(this, [](Nz::RigidBody2D* body) + { + if (cpBodyGetType(body->GetHandle()) == CP_BODY_TYPE_DYNAMIC) + cpBodySleep(body->GetHandle()); + }); + } + Rectf RigidBody2D::GetAABB() const { if (m_shapes.empty()) @@ -564,6 +573,17 @@ namespace Nz cpBodyUpdateVelocity(m_handle, cpv(gravity.x, gravity.y), damping, deltaTime); } + void RigidBody2D::Wakeup() + { + m_world->RegisterPostStep(this, [](Nz::RigidBody2D* body) + { + if (cpBodyGetType(body->GetHandle()) != CP_BODY_TYPE_STATIC) + cpBodyActivate(body->GetHandle()); + else + cpBodyActivateStatic(body->GetHandle(), nullptr); + }); + } + RigidBody2D& RigidBody2D::operator=(const RigidBody2D& object) { RigidBody2D physObj(object);