diff --git a/src/api/types/world.c b/src/api/types/world.c index e26568a7..69610b7f 100644 --- a/src/api/types/world.c +++ b/src/api/types/world.c @@ -69,6 +69,42 @@ int l_lovrWorldNewSphereCollider(lua_State* L) { return 1; } +int l_lovrWorldDestroy(lua_State* L) { + World* world = luax_checktype(L, 1, World); + lovrWorldDestroyData(world); + return 0; +} + +int l_lovrWorldUpdate(lua_State* L) { + lua_settop(L, 3); + World* world = luax_checktype(L, 1, World); + float dt = luaL_checknumber(L, 2); + CollisionResolver resolver = lua_type(L, 3) == LUA_TFUNCTION ? collisionResolver : NULL; + lovrWorldUpdate(world, dt, resolver, L); + return 0; +} + +int l_lovrWorldComputeOverlaps(lua_State* L) { + World* world = luax_checktype(L, 1, World); + lovrWorldComputeOverlaps(world); + return 0; +} + +int l_lovrWorldOverlaps(lua_State* L) { + luax_checktype(L, 1, World); + lua_settop(L, 1); + lua_pushcclosure(L, nextOverlap, 1); + return 1; +} + +int l_lovrWorldCollide(lua_State* L) { + World* world = luax_checktype(L, 1, World); + Shape* a = luax_checktypeof(L, 2, Shape); + Shape* b = luax_checktypeof(L, 3, Shape); + lua_pushboolean(L, lovrWorldCollide(world, a, b)); + return 1; +} + int l_lovrWorldGetGravity(lua_State* L) { World* world = luax_checktype(L, 1, World); float x, y, z; @@ -135,42 +171,17 @@ int l_lovrWorldSetSleepingAllowed(lua_State* L) { return 0; } -int l_lovrWorldUpdate(lua_State* L) { - lua_settop(L, 3); - World* world = luax_checktype(L, 1, World); - float dt = luaL_checknumber(L, 2); - CollisionResolver resolver = lua_type(L, 3) == LUA_TFUNCTION ? collisionResolver : NULL; - lovrWorldUpdate(world, dt, resolver, L); - return 0; -} - -int l_lovrWorldComputeOverlaps(lua_State* L) { - World* world = luax_checktype(L, 1, World); - lovrWorldComputeOverlaps(world); - return 0; -} - -int l_lovrWorldOverlaps(lua_State* L) { - luax_checktype(L, 1, World); - lua_settop(L, 1); - lua_pushcclosure(L, nextOverlap, 1); - return 1; -} - -int l_lovrWorldCollide(lua_State* L) { - World* world = luax_checktype(L, 1, World); - Shape* a = luax_checktypeof(L, 2, Shape); - Shape* b = luax_checktypeof(L, 3, Shape); - lua_pushboolean(L, lovrWorldCollide(world, a, b)); - return 1; -} - const luaL_Reg lovrWorld[] = { { "newCollider", l_lovrWorldNewCollider }, { "newBoxCollider", l_lovrWorldNewBoxCollider }, { "newCapsuleCollider", l_lovrWorldNewCapsuleCollider }, { "newCylinderCollider", l_lovrWorldNewCylinderCollider }, { "newSphereCollider", l_lovrWorldNewSphereCollider }, + { "destroy", l_lovrWorldDestroy }, + { "update", l_lovrWorldUpdate }, + { "computeOverlaps", l_lovrWorldComputeOverlaps }, + { "overlaps", l_lovrWorldOverlaps }, + { "collide", l_lovrWorldCollide }, { "getGravity", l_lovrWorldGetGravity }, { "setGravity", l_lovrWorldSetGravity }, { "getLinearDamping", l_lovrWorldGetLinearDamping }, @@ -179,9 +190,5 @@ const luaL_Reg lovrWorld[] = { { "setAngularDamping", l_lovrWorldSetAngularDamping }, { "isSleepingAllowed", l_lovrWorldIsSleepingAllowed }, { "setSleepingAllowed", l_lovrWorldSetSleepingAllowed }, - { "update", l_lovrWorldUpdate }, - { "computeOverlaps", l_lovrWorldComputeOverlaps }, - { "overlaps", l_lovrWorldOverlaps }, - { "collide", l_lovrWorldCollide }, { NULL, NULL } }; diff --git a/src/physics/physics.c b/src/physics/physics.c index 737a429d..46f6e749 100644 --- a/src/physics/physics.c +++ b/src/physics/physics.c @@ -41,49 +41,26 @@ World* lovrWorldCreate() { void lovrWorldDestroy(const Ref* ref) { World* world = containerof(ref, World); - dWorldDestroy(world->id); + lovrWorldDestroyData(world); vec_deinit(&world->overlaps); free(world); } -void lovrWorldGetGravity(World* world, float* x, float* y, float* z) { - dReal gravity[3]; - dWorldGetGravity(world->id, gravity); - *x = gravity[0]; - *y = gravity[1]; - *z = gravity[2]; -} +void lovrWorldDestroyData(World* world) { + if (world->contactGroup) { + dJointGroupEmpty(world->contactGroup); + world->contactGroup = NULL; + } -void lovrWorldSetGravity(World* world, float x, float y, float z) { - dWorldSetGravity(world->id, x, y, z); -} + if (world->space) { + dSpaceDestroy(world->space); + world->space = NULL; + } -void lovrWorldGetLinearDamping(World* world, float* damping, float* threshold) { - *damping = dWorldGetLinearDamping(world->id); - *threshold = dWorldGetLinearDampingThreshold(world->id); -} - -void lovrWorldSetLinearDamping(World* world, float damping, float threshold) { - dWorldSetLinearDamping(world->id, damping); - dWorldSetLinearDampingThreshold(world->id, threshold); -} - -void lovrWorldGetAngularDamping(World* world, float* damping, float* threshold) { - *damping = dWorldGetAngularDamping(world->id); - *threshold = dWorldGetAngularDampingThreshold(world->id); -} - -void lovrWorldSetAngularDamping(World* world, float damping, float threshold) { - dWorldSetAngularDamping(world->id, damping); - dWorldSetAngularDampingThreshold(world->id, threshold); -} - -int lovrWorldIsSleepingAllowed(World* world) { - return dWorldGetAutoDisableFlag(world->id); -} - -void lovrWorldSetSleepingAllowed(World* world, int allowed) { - dWorldSetAutoDisableFlag(world->id, allowed); + if (world->id) { + dWorldDestroy(world->id); + world->id = NULL; + } } void lovrWorldUpdate(World* world, float dt, CollisionResolver resolver, void* userdata) { @@ -135,6 +112,46 @@ int lovrWorldCollide(World* world, Shape* a, Shape* b) { return contactCount; } +void lovrWorldGetGravity(World* world, float* x, float* y, float* z) { + dReal gravity[3]; + dWorldGetGravity(world->id, gravity); + *x = gravity[0]; + *y = gravity[1]; + *z = gravity[2]; +} + +void lovrWorldSetGravity(World* world, float x, float y, float z) { + dWorldSetGravity(world->id, x, y, z); +} + +void lovrWorldGetLinearDamping(World* world, float* damping, float* threshold) { + *damping = dWorldGetLinearDamping(world->id); + *threshold = dWorldGetLinearDampingThreshold(world->id); +} + +void lovrWorldSetLinearDamping(World* world, float damping, float threshold) { + dWorldSetLinearDamping(world->id, damping); + dWorldSetLinearDampingThreshold(world->id, threshold); +} + +void lovrWorldGetAngularDamping(World* world, float* damping, float* threshold) { + *damping = dWorldGetAngularDamping(world->id); + *threshold = dWorldGetAngularDampingThreshold(world->id); +} + +void lovrWorldSetAngularDamping(World* world, float damping, float threshold) { + dWorldSetAngularDamping(world->id, damping); + dWorldSetAngularDampingThreshold(world->id, threshold); +} + +int lovrWorldIsSleepingAllowed(World* world) { + return dWorldGetAutoDisableFlag(world->id); +} + +void lovrWorldSetSleepingAllowed(World* world, int allowed) { + dWorldSetAutoDisableFlag(world->id, allowed); +} + Collider* lovrColliderCreate(World* world) { if (!world) { error("No world specified"); diff --git a/src/physics/physics.h b/src/physics/physics.h index b12138b8..148c8b86 100644 --- a/src/physics/physics.h +++ b/src/physics/physics.h @@ -49,6 +49,11 @@ void lovrPhysicsDestroy(); World* lovrWorldCreate(); void lovrWorldDestroy(const Ref* ref); +void lovrWorldDestroyData(World* world); +void lovrWorldUpdate(World* world, float dt, CollisionResolver resolver, void* userdata); +void lovrWorldComputeOverlaps(World* world); +int lovrWorldGetNextOverlap(World* world, Shape** a, Shape** b); +int lovrWorldCollide(World* world, Shape* a, Shape* b); void lovrWorldGetGravity(World* world, float* x, float* y, float* z); void lovrWorldSetGravity(World* world, float x, float y, float z); void lovrWorldGetLinearDamping(World* world, float* damping, float* threshold); @@ -57,10 +62,6 @@ void lovrWorldGetAngularDamping(World* world, float* damping, float* threshold); void lovrWorldSetAngularDamping(World* world, float damping, float threshold); int lovrWorldIsSleepingAllowed(World* world); void lovrWorldSetSleepingAllowed(World* world, int allowed); -void lovrWorldUpdate(World* world, float dt, CollisionResolver resolver, void* userdata); -void lovrWorldComputeOverlaps(World* world); -int lovrWorldGetNextOverlap(World* world, Shape** a, Shape** b); -int lovrWorldCollide(World* world, Shape* a, Shape* b); Collider* lovrColliderCreate(); void lovrColliderDestroy(const Ref* ref);