mirror of https://github.com/bjornbytes/lovr.git
World:queryBox; World:querySphere;
This commit is contained in:
parent
9bf2def86d
commit
b268cd1776
|
@ -27,7 +27,6 @@ static int nextOverlap(lua_State* L) {
|
|||
|
||||
static void raycastCallback(Shape* shape, float x, float y, float z, float nx, float ny, float nz, void* userdata) {
|
||||
lua_State* L = userdata;
|
||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||
lua_pushvalue(L, -1);
|
||||
luax_pushshape(L, shape);
|
||||
lua_pushnumber(L, x);
|
||||
|
@ -39,6 +38,13 @@ static void raycastCallback(Shape* shape, float x, float y, float z, float nx, f
|
|||
lua_call(L, 7, 0);
|
||||
}
|
||||
|
||||
static void queryCallback(Shape* shape, void* userdata) {
|
||||
lua_State* L = userdata;
|
||||
lua_pushvalue(L, -1);
|
||||
luax_pushshape(L, shape);
|
||||
lua_call(L, 1, 0);
|
||||
}
|
||||
|
||||
static int l_lovrWorldNewCollider(lua_State* L) {
|
||||
World* world = luax_checktype(L, 1, World);
|
||||
float position[3];
|
||||
|
@ -242,6 +248,29 @@ static int l_lovrWorldRaycast(lua_State* L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrWorldQueryBox(lua_State* L) {
|
||||
World* world = luax_checktype(L, 1, World);
|
||||
float position[3], size[3];
|
||||
int index = 2;
|
||||
index = luax_readvec3(L, index, position, NULL);
|
||||
index = luax_readvec3(L, index, size, NULL);
|
||||
luaL_checktype(L, index, LUA_TFUNCTION);
|
||||
lua_settop(L, index);
|
||||
lovrWorldQueryBox(world, position, size, queryCallback, L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrWorldQuerySphere(lua_State* L) {
|
||||
World* world = luax_checktype(L, 1, World);
|
||||
float position[3];
|
||||
int index = luax_readvec3(L, 2, position, NULL);
|
||||
float radius = luax_checkfloat(L, index++);
|
||||
luaL_checktype(L, index, LUA_TFUNCTION);
|
||||
lua_settop(L, index);
|
||||
lovrWorldQuerySphere(world, position, radius, queryCallback, L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrWorldGetGravity(lua_State* L) {
|
||||
World* world = luax_checktype(L, 1, World);
|
||||
float x, y, z;
|
||||
|
@ -392,6 +421,8 @@ const luaL_Reg lovrWorld[] = {
|
|||
{ "collide", l_lovrWorldCollide },
|
||||
{ "getContacts", l_lovrWorldGetContacts },
|
||||
{ "raycast", l_lovrWorldRaycast },
|
||||
{ "queryBox", l_lovrWorldQueryBox },
|
||||
{ "querySphere", l_lovrWorldQuerySphere },
|
||||
{ "getGravity", l_lovrWorldGetGravity },
|
||||
{ "setGravity", l_lovrWorldSetGravity },
|
||||
{ "getTightness", l_lovrWorldGetTightness },
|
||||
|
|
|
@ -79,6 +79,26 @@ static void raycastCallback(void* data, dGeomID a, dGeomID b) {
|
|||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
QueryCallback callback;
|
||||
void* userdata;
|
||||
} QueryData;
|
||||
|
||||
static void queryCallback(void* data, dGeomID a, dGeomID b) {
|
||||
QueryCallback callback = ((QueryData*) data)->callback;
|
||||
void* userdata = ((QueryData*) data)->userdata;
|
||||
Shape* shape = dGeomGetData(b);
|
||||
|
||||
if (!shape) {
|
||||
return;
|
||||
}
|
||||
|
||||
dContactGeom contact;
|
||||
if (dCollide(a, b, 1 | CONTACTS_UNIMPORTANT, &contact, sizeof(contact))) {
|
||||
callback(shape, userdata);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX slow, but probably fine (tag names are not on any critical path), could switch to hashing if needed
|
||||
static uint32_t findTag(World* world, const char* name) {
|
||||
for (uint32_t i = 0; i < MAX_TAGS && world->tags[i]; i++) {
|
||||
|
@ -288,6 +308,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 };
|
||||
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);
|
||||
}
|
||||
|
||||
void lovrWorldQuerySphere(World* world, float position[3], float radius, QueryCallback callback, void* userdata) {
|
||||
QueryData data = { .callback = callback, .userdata = userdata };
|
||||
dGeomID sphere = dCreateSphere(world->space, fabsf(radius));
|
||||
dGeomSetPosition(sphere, position[0], position[1], position[2]);
|
||||
dSpaceCollide2(sphere, (dGeomID) world->space, &data, queryCallback);
|
||||
dGeomDestroy(sphere);
|
||||
}
|
||||
|
||||
Collider* lovrWorldGetFirstCollider(World* world) {
|
||||
return world->head;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ typedef Joint SliderJoint;
|
|||
|
||||
typedef void (*CollisionResolver)(World* world, void* userdata);
|
||||
typedef void (*RaycastCallback)(Shape* shape, float x, float y, float z, float nx, float ny, float nz, void* userdata);
|
||||
typedef void (*QueryCallback)(Shape* shape, void* userdata);
|
||||
|
||||
bool lovrPhysicsInit(void);
|
||||
void lovrPhysicsDestroy(void);
|
||||
|
@ -50,6 +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);
|
||||
Collider* lovrWorldGetFirstCollider(World* world);
|
||||
void lovrWorldGetGravity(World* world, float* x, float* y, float* z);
|
||||
void lovrWorldSetGravity(World* world, float x, float y, float z);
|
||||
|
|
Loading…
Reference in New Issue