Add `World:setStepIterations(num)` and its getter

Physics world's "quick step" is executed in multiple iteration steps.
The getter and setter for this value is now made available as two new
methods in the World object.

This is allows user to balance between the less accurate but quick
simulations, and more stable behavior of physics.

Something similar was already possible, by reducing the delta time and
running the sim multiple times per frame. However, any force user applies
to collider is zeroed after each step. User would thus have to keep track
of applied forces, and re-apply them inside the physics iteration loop.

By default ODE uses 20 iterations in quick step.
This commit is contained in:
Josip Miskovic 2022-03-28 18:33:11 +02:00 committed by Bjorn
parent 51d96f6fa2
commit 24a0751c16
3 changed files with 26 additions and 0 deletions

View File

@ -367,6 +367,20 @@ static int l_lovrWorldIsCollisionEnabledBetween(lua_State* L) {
return 1;
}
static int l_lovrWorldGetStepCount(lua_State* L) {
World* world = luax_checktype(L, 1, World);
int iterations = lovrWorldGetStepCount(world);
lua_pushnumber(L, iterations);
return 1;
}
static int l_lovrWorldSetStepCount(lua_State* L) {
World* world = luax_checktype(L, 1, World);
int iterations = luaL_checkinteger(L, 2);
lovrWorldSetStepCount(world, iterations);
return 0;
}
const luaL_Reg lovrWorld[] = {
{ "newCollider", l_lovrWorldNewCollider },
{ "newBoxCollider", l_lovrWorldNewBoxCollider },
@ -397,5 +411,7 @@ const luaL_Reg lovrWorld[] = {
{ "disableCollisionBetween", l_lovrWorldDisableCollisionBetween },
{ "enableCollisionBetween", l_lovrWorldEnableCollisionBetween },
{ "isCollisionEnabledBetween", l_lovrWorldIsCollisionEnabledBetween },
{ "getStepCount", l_lovrWorldGetStepCount },
{ "setStepCount", l_lovrWorldSetStepCount },
{ NULL, NULL }
};

View File

@ -191,6 +191,14 @@ void lovrWorldUpdate(World* world, float dt, CollisionResolver resolver, void* u
dJointGroupEmpty(world->contactGroup);
}
int lovrWorldGetStepCount(World* world) {
return dWorldGetQuickStepNumIterations(world->id);
}
void lovrWorldSetStepCount(World* world, int iterations) {
dWorldSetQuickStepNumIterations(world->id, iterations);
}
void lovrWorldComputeOverlaps(World* world) {
arr_clear(&world->overlaps);
dSpaceCollide(world->space, world, customNearCallback);

View File

@ -42,6 +42,8 @@ World* lovrWorldCreate(float xg, float yg, float zg, bool allowSleep, const char
void lovrWorldDestroy(void* ref);
void lovrWorldDestroyData(World* world);
void lovrWorldUpdate(World* world, float dt, CollisionResolver resolver, void* userdata);
int lovrWorldGetStepCount(World* world);
void lovrWorldSetStepCount(World* world, int iterations);
void lovrWorldComputeOverlaps(World* world);
int lovrWorldGetNextOverlap(World* world, Shape** a, Shape** b);
int lovrWorldCollide(World* world, Shape* a, Shape* b, float friction, float restitution);