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) {
|
static void raycastCallback(Shape* shape, float x, float y, float z, float nx, float ny, float nz, void* userdata) {
|
||||||
lua_State* L = userdata;
|
lua_State* L = userdata;
|
||||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
|
||||||
lua_pushvalue(L, -1);
|
lua_pushvalue(L, -1);
|
||||||
luax_pushshape(L, shape);
|
luax_pushshape(L, shape);
|
||||||
lua_pushnumber(L, x);
|
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);
|
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) {
|
static int l_lovrWorldNewCollider(lua_State* L) {
|
||||||
World* world = luax_checktype(L, 1, World);
|
World* world = luax_checktype(L, 1, World);
|
||||||
float position[3];
|
float position[3];
|
||||||
|
@ -242,6 +248,29 @@ static int l_lovrWorldRaycast(lua_State* L) {
|
||||||
return 0;
|
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) {
|
static int l_lovrWorldGetGravity(lua_State* L) {
|
||||||
World* world = luax_checktype(L, 1, World);
|
World* world = luax_checktype(L, 1, World);
|
||||||
float x, y, z;
|
float x, y, z;
|
||||||
|
@ -392,6 +421,8 @@ const luaL_Reg lovrWorld[] = {
|
||||||
{ "collide", l_lovrWorldCollide },
|
{ "collide", l_lovrWorldCollide },
|
||||||
{ "getContacts", l_lovrWorldGetContacts },
|
{ "getContacts", l_lovrWorldGetContacts },
|
||||||
{ "raycast", l_lovrWorldRaycast },
|
{ "raycast", l_lovrWorldRaycast },
|
||||||
|
{ "queryBox", l_lovrWorldQueryBox },
|
||||||
|
{ "querySphere", l_lovrWorldQuerySphere },
|
||||||
{ "getGravity", l_lovrWorldGetGravity },
|
{ "getGravity", l_lovrWorldGetGravity },
|
||||||
{ "setGravity", l_lovrWorldSetGravity },
|
{ "setGravity", l_lovrWorldSetGravity },
|
||||||
{ "getTightness", l_lovrWorldGetTightness },
|
{ "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
|
// 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) {
|
static uint32_t findTag(World* world, const char* name) {
|
||||||
for (uint32_t i = 0; i < MAX_TAGS && world->tags[i]; i++) {
|
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);
|
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) {
|
Collider* lovrWorldGetFirstCollider(World* world) {
|
||||||
return world->head;
|
return world->head;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ typedef Joint SliderJoint;
|
||||||
|
|
||||||
typedef void (*CollisionResolver)(World* world, void* userdata);
|
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 (*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);
|
bool lovrPhysicsInit(void);
|
||||||
void lovrPhysicsDestroy(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);
|
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 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 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);
|
Collider* lovrWorldGetFirstCollider(World* world);
|
||||||
void lovrWorldGetGravity(World* world, float* x, float* y, float* z);
|
void lovrWorldGetGravity(World* world, float* x, float* y, float* z);
|
||||||
void lovrWorldSetGravity(World* world, float x, float y, float z);
|
void lovrWorldSetGravity(World* world, float x, float y, float z);
|
||||||
|
|
Loading…
Reference in New Issue