From 534d47904eddf90b062b1f1dfa4211653c36a5aa Mon Sep 17 00:00:00 2001 From: bjorn Date: Mon, 17 Jul 2023 13:23:57 -0700 Subject: [PATCH] World:queryBox/World:querySphere callback is optional; They also return a bool indicating if any intersections occurred. --- src/api/l_physics_world.c | 14 ++++++++------ src/modules/physics/physics.c | 19 +++++++++++-------- src/modules/physics/physics.h | 4 ++-- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/api/l_physics_world.c b/src/api/l_physics_world.c index 71869069..a97271d8 100644 --- a/src/api/l_physics_world.c +++ b/src/api/l_physics_world.c @@ -254,10 +254,11 @@ static int l_lovrWorldQueryBox(lua_State* L) { int index = 2; index = luax_readvec3(L, index, position, NULL); index = luax_readvec3(L, index, size, NULL); - luaL_checktype(L, index, LUA_TFUNCTION); + bool function = lua_type(L, index) == LUA_TFUNCTION; lua_settop(L, index); - lovrWorldQueryBox(world, position, size, queryCallback, L); - return 0; + bool any = lovrWorldQueryBox(world, position, size, function ? queryCallback : NULL, L); + lua_pushboolean(L, any); + return 1; } static int l_lovrWorldQuerySphere(lua_State* L) { @@ -265,10 +266,11 @@ static int l_lovrWorldQuerySphere(lua_State* L) { float position[3]; int index = luax_readvec3(L, 2, position, NULL); float radius = luax_checkfloat(L, index++); - luaL_checktype(L, index, LUA_TFUNCTION); + bool function = lua_type(L, index) == LUA_TFUNCTION; lua_settop(L, index); - lovrWorldQuerySphere(world, position, radius, queryCallback, L); - return 0; + bool any = lovrWorldQuerySphere(world, position, radius, function ? queryCallback : NULL, L); + lua_pushboolean(L, any); + return 1; } static int l_lovrWorldGetGravity(lua_State* L) { diff --git a/src/modules/physics/physics.c b/src/modules/physics/physics.c index 5e87ce6f..c4f695a6 100644 --- a/src/modules/physics/physics.c +++ b/src/modules/physics/physics.c @@ -82,20 +82,21 @@ static void raycastCallback(void* data, dGeomID a, dGeomID b) { typedef struct { QueryCallback callback; void* userdata; + bool called; } QueryData; -static void queryCallback(void* data, dGeomID a, dGeomID b) { - QueryCallback callback = ((QueryData*) data)->callback; - void* userdata = ((QueryData*) data)->userdata; +static void queryCallback(void* d, dGeomID a, dGeomID b) { Shape* shape = dGeomGetData(b); if (!shape) { return; } + QueryData* data = d; dContactGeom contact; if (dCollide(a, b, 1 | CONTACTS_UNIMPORTANT, &contact, sizeof(contact))) { - callback(shape, userdata); + if (data->callback) data->callback(shape, data->userdata); + data->called = true; } } @@ -308,20 +309,22 @@ void lovrWorldRaycast(World* world, float x1, float y1, float z1, float x2, floa dGeomDestroy(ray); } -void lovrWorldQueryBox(World* world, float position[3], float size[3], QueryCallback callback, void* userdata) { - QueryData data = { .callback = callback, .userdata = userdata }; +bool lovrWorldQueryBox(World* world, float position[3], float size[3], QueryCallback callback, void* userdata) { + QueryData data = { .callback = callback, .userdata = userdata, .called = false }; dGeomID box = dCreateBox(world->space, fabsf(size[0]), fabsf(size[1]), fabsf(size[2])); dGeomSetPosition(box, position[0], position[1], position[2]); dSpaceCollide2(box, (dGeomID) world->space, &data, queryCallback); dGeomDestroy(box); + return data.called; } -void lovrWorldQuerySphere(World* world, float position[3], float radius, QueryCallback callback, void* userdata) { - QueryData data = { .callback = callback, .userdata = userdata }; +bool lovrWorldQuerySphere(World* world, float position[3], float radius, QueryCallback callback, void* userdata) { + QueryData data = { .callback = callback, .userdata = userdata, .called = false }; dGeomID sphere = dCreateSphere(world->space, fabsf(radius)); dGeomSetPosition(sphere, position[0], position[1], position[2]); dSpaceCollide2(sphere, (dGeomID) world->space, &data, queryCallback); dGeomDestroy(sphere); + return data.called; } Collider* lovrWorldGetFirstCollider(World* world) { diff --git a/src/modules/physics/physics.h b/src/modules/physics/physics.h index 39ea296b..54a204ed 100644 --- a/src/modules/physics/physics.h +++ b/src/modules/physics/physics.h @@ -51,8 +51,8 @@ int lovrWorldGetNextOverlap(World* world, Shape** a, Shape** b); int lovrWorldCollide(World* world, Shape* a, Shape* b, float friction, float restitution); void lovrWorldGetContacts(World* world, Shape* a, Shape* b, Contact contacts[MAX_CONTACTS], uint32_t* count); void lovrWorldRaycast(World* world, float x1, float y1, float z1, float x2, float y2, float z2, RaycastCallback callback, void* userdata); -void lovrWorldQueryBox(World* world, float position[3], float size[3], QueryCallback callback, void* userdata); -void lovrWorldQuerySphere(World* world, float position[3], float radius, QueryCallback callback, void* userdata); +bool lovrWorldQueryBox(World* world, float position[3], float size[3], QueryCallback callback, void* userdata); +bool lovrWorldQuerySphere(World* world, float position[3], float radius, QueryCallback callback, void* userdata); Collider* lovrWorldGetFirstCollider(World* world); void lovrWorldGetGravity(World* world, float* x, float* y, float* z); void lovrWorldSetGravity(World* world, float x, float y, float z);