Convert physac module from static steps to fixed time steps
Old physics update system used a static number of steps to calculate physics (450 for desktop and 64 for android). It was too much and it was limited by target frame time... Now physics update runs in a secondary thread using a fixed delta time value to update steps. Collisions are perfectly detected and resolved and performance has been improved so much.
This commit is contained in:
parent
1a60f376a4
commit
c10c49e44f
1 changed files with 321 additions and 330 deletions
45
src/physac.h
45
src/physac.h
|
@ -146,7 +146,7 @@ typedef struct PhysicBodyData {
|
|||
// Module Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
PHYSACDEF void InitPhysics(Vector2 gravity); // Initializes pointers array (just pointers, fixed size)
|
||||
PHYSACDEF void UpdatePhysics(); // Update physic objects, calculating physic behaviours and collisions detection
|
||||
PHYSACDEF void UpdatePhysics(double deltaTime); // Update physic objects, calculating physic behaviours and collisions detection
|
||||
PHYSACDEF void ClosePhysics(); // Unitialize all physic objects and empty the objects pool
|
||||
|
||||
PHYSACDEF PhysicBody CreatePhysicBody(Vector2 position, float rotation, Vector2 scale); // Create a new physic body dinamically, initialize it and add to pool
|
||||
|
@ -182,7 +182,7 @@ PHYSACDEF Rectangle TransformToRectangle(Transform transform);
|
|||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
#define MAX_PHYSIC_BODIES 256 // Maximum available physic bodies slots in bodies pool
|
||||
#define PHYSICS_STEPS 64 // Physics update steps per frame for improved collision-detection
|
||||
#define PHYSICS_TIMESTEP 0.016666 // Physics fixed time step (1/fps)
|
||||
#define PHYSICS_ACCURACY 0.0001f // Velocity subtract operations round filter (friction)
|
||||
#define PHYSICS_ERRORPERCENT 0.001f // Collision resolve position fix
|
||||
|
||||
|
@ -218,13 +218,8 @@ PHYSACDEF void InitPhysics(Vector2 gravity)
|
|||
}
|
||||
|
||||
// Update physic objects, calculating physic behaviours and collisions detection
|
||||
PHYSACDEF void UpdatePhysics()
|
||||
PHYSACDEF void UpdatePhysics(double deltaTime)
|
||||
{
|
||||
// Reset all physic objects is grounded state
|
||||
for (int i = 0; i < physicBodiesCount; i++) physicBodies[i]->rigidbody.isGrounded = false;
|
||||
|
||||
for (int steps = 0; steps < PHYSICS_STEPS; steps++)
|
||||
{
|
||||
for (int i = 0; i < physicBodiesCount; i++)
|
||||
{
|
||||
if (physicBodies[i]->enabled)
|
||||
|
@ -233,39 +228,39 @@ PHYSACDEF void UpdatePhysics()
|
|||
if (physicBodies[i]->rigidbody.enabled)
|
||||
{
|
||||
// Apply friction to acceleration in X axis
|
||||
if (physicBodies[i]->rigidbody.acceleration.x > PHYSICS_ACCURACY) physicBodies[i]->rigidbody.acceleration.x -= physicBodies[i]->rigidbody.friction/PHYSICS_STEPS;
|
||||
else if (physicBodies[i]->rigidbody.acceleration.x < PHYSICS_ACCURACY) physicBodies[i]->rigidbody.acceleration.x += physicBodies[i]->rigidbody.friction/PHYSICS_STEPS;
|
||||
if (physicBodies[i]->rigidbody.acceleration.x > PHYSICS_ACCURACY) physicBodies[i]->rigidbody.acceleration.x -= physicBodies[i]->rigidbody.friction*deltaTime;
|
||||
else if (physicBodies[i]->rigidbody.acceleration.x < PHYSICS_ACCURACY) physicBodies[i]->rigidbody.acceleration.x += physicBodies[i]->rigidbody.friction*deltaTime;
|
||||
else physicBodies[i]->rigidbody.acceleration.x = 0.0f;
|
||||
|
||||
// Apply friction to acceleration in Y axis
|
||||
if (physicBodies[i]->rigidbody.acceleration.y > PHYSICS_ACCURACY) physicBodies[i]->rigidbody.acceleration.y -= physicBodies[i]->rigidbody.friction/PHYSICS_STEPS;
|
||||
else if (physicBodies[i]->rigidbody.acceleration.y < PHYSICS_ACCURACY) physicBodies[i]->rigidbody.acceleration.y += physicBodies[i]->rigidbody.friction/PHYSICS_STEPS;
|
||||
if (physicBodies[i]->rigidbody.acceleration.y > PHYSICS_ACCURACY) physicBodies[i]->rigidbody.acceleration.y -= physicBodies[i]->rigidbody.friction*deltaTime;
|
||||
else if (physicBodies[i]->rigidbody.acceleration.y < PHYSICS_ACCURACY) physicBodies[i]->rigidbody.acceleration.y += physicBodies[i]->rigidbody.friction*deltaTime;
|
||||
else physicBodies[i]->rigidbody.acceleration.y = 0.0f;
|
||||
|
||||
// Apply friction to velocity in X axis
|
||||
if (physicBodies[i]->rigidbody.velocity.x > PHYSICS_ACCURACY) physicBodies[i]->rigidbody.velocity.x -= physicBodies[i]->rigidbody.friction/PHYSICS_STEPS;
|
||||
else if (physicBodies[i]->rigidbody.velocity.x < PHYSICS_ACCURACY) physicBodies[i]->rigidbody.velocity.x += physicBodies[i]->rigidbody.friction/PHYSICS_STEPS;
|
||||
if (physicBodies[i]->rigidbody.velocity.x > PHYSICS_ACCURACY) physicBodies[i]->rigidbody.velocity.x -= physicBodies[i]->rigidbody.friction*deltaTime;
|
||||
else if (physicBodies[i]->rigidbody.velocity.x < PHYSICS_ACCURACY) physicBodies[i]->rigidbody.velocity.x += physicBodies[i]->rigidbody.friction*deltaTime;
|
||||
else physicBodies[i]->rigidbody.velocity.x = 0.0f;
|
||||
|
||||
// Apply friction to velocity in Y axis
|
||||
if (physicBodies[i]->rigidbody.velocity.y > PHYSICS_ACCURACY) physicBodies[i]->rigidbody.velocity.y -= physicBodies[i]->rigidbody.friction/PHYSICS_STEPS;
|
||||
else if (physicBodies[i]->rigidbody.velocity.y < PHYSICS_ACCURACY) physicBodies[i]->rigidbody.velocity.y += physicBodies[i]->rigidbody.friction/PHYSICS_STEPS;
|
||||
if (physicBodies[i]->rigidbody.velocity.y > PHYSICS_ACCURACY) physicBodies[i]->rigidbody.velocity.y -= physicBodies[i]->rigidbody.friction*deltaTime;
|
||||
else if (physicBodies[i]->rigidbody.velocity.y < PHYSICS_ACCURACY) physicBodies[i]->rigidbody.velocity.y += physicBodies[i]->rigidbody.friction*deltaTime;
|
||||
else physicBodies[i]->rigidbody.velocity.y = 0.0f;
|
||||
|
||||
// Apply gravity to velocity
|
||||
if (physicBodies[i]->rigidbody.applyGravity)
|
||||
{
|
||||
physicBodies[i]->rigidbody.velocity.x += gravityForce.x/PHYSICS_STEPS;
|
||||
physicBodies[i]->rigidbody.velocity.y += gravityForce.y/PHYSICS_STEPS;
|
||||
physicBodies[i]->rigidbody.velocity.x += gravityForce.x*deltaTime;
|
||||
physicBodies[i]->rigidbody.velocity.y += gravityForce.y*deltaTime;
|
||||
}
|
||||
|
||||
// Apply acceleration to velocity
|
||||
physicBodies[i]->rigidbody.velocity.x += physicBodies[i]->rigidbody.acceleration.x/PHYSICS_STEPS;
|
||||
physicBodies[i]->rigidbody.velocity.y += physicBodies[i]->rigidbody.acceleration.y/PHYSICS_STEPS;
|
||||
physicBodies[i]->rigidbody.velocity.x += physicBodies[i]->rigidbody.acceleration.x*deltaTime;
|
||||
physicBodies[i]->rigidbody.velocity.y += physicBodies[i]->rigidbody.acceleration.y*deltaTime;
|
||||
|
||||
// Apply velocity to position
|
||||
physicBodies[i]->transform.position.x += physicBodies[i]->rigidbody.velocity.x/PHYSICS_STEPS;
|
||||
physicBodies[i]->transform.position.y -= physicBodies[i]->rigidbody.velocity.y/PHYSICS_STEPS;
|
||||
physicBodies[i]->transform.position.x += physicBodies[i]->rigidbody.velocity.x*deltaTime;
|
||||
physicBodies[i]->transform.position.y -= physicBodies[i]->rigidbody.velocity.y*deltaTime;
|
||||
}
|
||||
|
||||
// Update collision detection
|
||||
|
@ -507,10 +502,7 @@ PHYSACDEF void UpdatePhysics()
|
|||
}
|
||||
|
||||
// Update rigidbody grounded state
|
||||
if (physicBodies[i]->rigidbody.enabled)
|
||||
{
|
||||
if (contactNormal.y < 0.0f) physicBodies[i]->rigidbody.isGrounded = true;
|
||||
}
|
||||
if (physicBodies[i]->rigidbody.enabled) physicBodies[i]->rigidbody.isGrounded = (contactNormal.y < 0.0f);
|
||||
|
||||
// 2. Calculate collision impulse
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -595,7 +587,6 @@ PHYSACDEF void UpdatePhysics()
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unitialize all physic objects and empty the objects pool
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue