World:queryBox/World:querySphere callback is optional;

They also return a bool indicating if any intersections occurred.
This commit is contained in:
bjorn 2023-07-17 13:23:57 -07:00
parent 9b7433c1de
commit 534d47904e
3 changed files with 21 additions and 16 deletions

View File

@ -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) {

View File

@ -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) {

View File

@ -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);