Added physics function to control sleeping behavior

This commit is contained in:
Lynix 2019-12-19 21:33:56 +01:00
parent 86fbae554c
commit 3b43f57192
9 changed files with 64 additions and 0 deletions

View File

@ -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)

View File

@ -40,6 +40,7 @@ namespace Ndk
inline void EnableNodeSynchronization(bool nodeSynchronization);
inline void ForceSleep();
inline void ForEachArbiter(const std::function<void(Nz::Arbiter2D&)>& 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:

View File

@ -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);

View File

@ -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);

View File

@ -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 <NDK/Systems/PhysicsSystem2D.hpp>
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);

View File

@ -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);

View File

@ -46,6 +46,7 @@ namespace Nz
void EnableSimulation(bool simulation);
void ForEachArbiter(std::function<void(Nz::Arbiter2D& /*arbiter*/)> 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);

View File

@ -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<cpFloat>::infinity());
}
void PhysWorld2D::SetStepSize(float stepSize)
{
m_stepSize = stepSize;

View File

@ -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);