Physics[2|3]D/PhysWorld[2|3]D: Add max step count
This commit is contained in:
parent
bb7c97ed9a
commit
45af15d802
|
|
@ -65,6 +65,7 @@ Nazara Engine:
|
||||||
- Clock::Restart now returns the elapsed microseconds since construction or last Restart call
|
- Clock::Restart now returns the elapsed microseconds since construction or last Restart call
|
||||||
- Add PhysWorld2D::[Get|Set]IterationCount to control how many iterations chipmunk will perform per step.
|
- Add PhysWorld2D::[Get|Set]IterationCount to control how many iterations chipmunk will perform per step.
|
||||||
- Add PhysWorld2D::UseSpatialHash to use spatial hashing instead of bounding box trees, which may speedup simulation in some cases.
|
- Add PhysWorld2D::UseSpatialHash to use spatial hashing instead of bounding box trees, which may speedup simulation in some cases.
|
||||||
|
- Add PhysWorld[2D|3D] max step count per Step call (default: 50), to avoid spirals of death when the physics engine simulation time is over step size.
|
||||||
|
|
||||||
Nazara Development Kit:
|
Nazara Development Kit:
|
||||||
- Added ImageWidget (#139)
|
- Added ImageWidget (#139)
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ namespace Nz
|
||||||
Vector2f GetGravity() const;
|
Vector2f GetGravity() const;
|
||||||
cpSpace* GetHandle() const;
|
cpSpace* GetHandle() const;
|
||||||
std::size_t GetIterationCount() const;
|
std::size_t GetIterationCount() const;
|
||||||
|
std::size_t GetMaxStepCount() const;
|
||||||
float GetStepSize() const;
|
float GetStepSize() const;
|
||||||
|
|
||||||
bool NearestBodyQuery(const Vector2f& from, float maxDistance, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, RigidBody2D** nearestBody = nullptr);
|
bool NearestBodyQuery(const Vector2f& from, float maxDistance, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, RigidBody2D** nearestBody = nullptr);
|
||||||
|
|
@ -71,6 +72,7 @@ namespace Nz
|
||||||
void SetDamping(float dampingValue);
|
void SetDamping(float dampingValue);
|
||||||
void SetGravity(const Vector2f& gravity);
|
void SetGravity(const Vector2f& gravity);
|
||||||
void SetIterationCount(std::size_t iterationCount);
|
void SetIterationCount(std::size_t iterationCount);
|
||||||
|
void SetMaxStepCount(std::size_t maxStepCount);
|
||||||
void SetStepSize(float stepSize);
|
void SetStepSize(float stepSize);
|
||||||
|
|
||||||
void Step(float timestep);
|
void Step(float timestep);
|
||||||
|
|
@ -144,6 +146,7 @@ namespace Nz
|
||||||
|
|
||||||
static_assert(std::is_nothrow_move_constructible<PostStepContainer>::value, "PostStepContainer should be noexcept MoveConstructible");
|
static_assert(std::is_nothrow_move_constructible<PostStepContainer>::value, "PostStepContainer should be noexcept MoveConstructible");
|
||||||
|
|
||||||
|
std::size_t m_maxStepCount;
|
||||||
std::unordered_map<cpCollisionHandler*, std::unique_ptr<Callback>> m_callbacks;
|
std::unordered_map<cpCollisionHandler*, std::unique_ptr<Callback>> m_callbacks;
|
||||||
std::unordered_map<RigidBody2D*, PostStepContainer> m_rigidPostSteps;
|
std::unordered_map<RigidBody2D*, PostStepContainer> m_rigidPostSteps;
|
||||||
cpSpace* m_handle;
|
cpSpace* m_handle;
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,11 @@ namespace Nz
|
||||||
|
|
||||||
Vector3f GetGravity() const;
|
Vector3f GetGravity() const;
|
||||||
NewtonWorld* GetHandle() const;
|
NewtonWorld* GetHandle() const;
|
||||||
|
std::size_t GetMaxStepCount() const;
|
||||||
float GetStepSize() const;
|
float GetStepSize() const;
|
||||||
|
|
||||||
void SetGravity(const Vector3f& gravity);
|
void SetGravity(const Vector3f& gravity);
|
||||||
|
void SetMaxStepCount(std::size_t maxStepCount);
|
||||||
void SetSolverModel(unsigned int model);
|
void SetSolverModel(unsigned int model);
|
||||||
void SetStepSize(float stepSize);
|
void SetStepSize(float stepSize);
|
||||||
|
|
||||||
|
|
@ -37,6 +39,7 @@ namespace Nz
|
||||||
PhysWorld3D& operator=(PhysWorld3D&&) = delete; ///TODO
|
PhysWorld3D& operator=(PhysWorld3D&&) = delete; ///TODO
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::size_t m_maxStepCount;
|
||||||
Vector3f m_gravity;
|
Vector3f m_gravity;
|
||||||
NewtonWorld* m_world;
|
NewtonWorld* m_world;
|
||||||
float m_stepSize;
|
float m_stepSize;
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,7 @@ namespace Nz
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysWorld2D::PhysWorld2D() :
|
PhysWorld2D::PhysWorld2D() :
|
||||||
|
m_maxStepCount(50),
|
||||||
m_stepSize(0.005f),
|
m_stepSize(0.005f),
|
||||||
m_timestepAccumulator(0.f)
|
m_timestepAccumulator(0.f)
|
||||||
{
|
{
|
||||||
|
|
@ -149,6 +150,11 @@ namespace Nz
|
||||||
return cpSpaceGetIterations(m_handle);
|
return cpSpaceGetIterations(m_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::size_t PhysWorld2D::GetMaxStepCount() const
|
||||||
|
{
|
||||||
|
return m_maxStepCount;
|
||||||
|
}
|
||||||
|
|
||||||
float PhysWorld2D::GetStepSize() const
|
float PhysWorld2D::GetStepSize() const
|
||||||
{
|
{
|
||||||
return m_stepSize;
|
return m_stepSize;
|
||||||
|
|
@ -291,6 +297,11 @@ namespace Nz
|
||||||
cpSpaceSetIterations(m_handle, int(iterationCount));
|
cpSpaceSetIterations(m_handle, int(iterationCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PhysWorld2D::SetMaxStepCount(std::size_t maxStepCount)
|
||||||
|
{
|
||||||
|
m_maxStepCount = maxStepCount;
|
||||||
|
}
|
||||||
|
|
||||||
void PhysWorld2D::SetStepSize(float stepSize)
|
void PhysWorld2D::SetStepSize(float stepSize)
|
||||||
{
|
{
|
||||||
m_stepSize = stepSize;
|
m_stepSize = stepSize;
|
||||||
|
|
@ -300,7 +311,8 @@ namespace Nz
|
||||||
{
|
{
|
||||||
m_timestepAccumulator += timestep;
|
m_timestepAccumulator += timestep;
|
||||||
|
|
||||||
while (m_timestepAccumulator >= m_stepSize)
|
std::size_t stepCount = 0;
|
||||||
|
while (m_timestepAccumulator >= m_stepSize && stepCount < m_maxStepCount)
|
||||||
{
|
{
|
||||||
OnPhysWorld2DPreStep(this);
|
OnPhysWorld2DPreStep(this);
|
||||||
|
|
||||||
|
|
@ -319,6 +331,7 @@ namespace Nz
|
||||||
}
|
}
|
||||||
|
|
||||||
m_timestepAccumulator -= m_stepSize;
|
m_timestepAccumulator -= m_stepSize;
|
||||||
|
stepCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
PhysWorld3D::PhysWorld3D() :
|
PhysWorld3D::PhysWorld3D() :
|
||||||
m_gravity(Vector3f::Zero()),
|
m_gravity(Vector3f::Zero()),
|
||||||
|
m_maxStepCount(50),
|
||||||
m_stepSize(0.005f),
|
m_stepSize(0.005f),
|
||||||
m_timestepAccumulator(0.f)
|
m_timestepAccumulator(0.f)
|
||||||
{
|
{
|
||||||
|
|
@ -32,6 +33,11 @@ namespace Nz
|
||||||
return m_world;
|
return m_world;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::size_t PhysWorld3D::GetMaxStepCount() const
|
||||||
|
{
|
||||||
|
return m_maxStepCount;
|
||||||
|
}
|
||||||
|
|
||||||
float PhysWorld3D::GetStepSize() const
|
float PhysWorld3D::GetStepSize() const
|
||||||
{
|
{
|
||||||
return m_stepSize;
|
return m_stepSize;
|
||||||
|
|
@ -42,6 +48,11 @@ namespace Nz
|
||||||
m_gravity = gravity;
|
m_gravity = gravity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PhysWorld3D::SetMaxStepCount(std::size_t maxStepCount)
|
||||||
|
{
|
||||||
|
m_maxStepCount = maxStepCount;
|
||||||
|
}
|
||||||
|
|
||||||
void PhysWorld3D::SetSolverModel(unsigned int model)
|
void PhysWorld3D::SetSolverModel(unsigned int model)
|
||||||
{
|
{
|
||||||
NewtonSetSolverModel(m_world, model);
|
NewtonSetSolverModel(m_world, model);
|
||||||
|
|
@ -56,10 +67,12 @@ namespace Nz
|
||||||
{
|
{
|
||||||
m_timestepAccumulator += timestep;
|
m_timestepAccumulator += timestep;
|
||||||
|
|
||||||
while (m_timestepAccumulator >= m_stepSize)
|
std::size_t stepCount = 0;
|
||||||
|
while (m_timestepAccumulator >= m_stepSize && stepCount < m_maxStepCount)
|
||||||
{
|
{
|
||||||
NewtonUpdate(m_world, m_stepSize);
|
NewtonUpdate(m_world, m_stepSize);
|
||||||
m_timestepAccumulator -= m_stepSize;
|
m_timestepAccumulator -= m_stepSize;
|
||||||
|
stepCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue