mirror of https://github.com/bjornbytes/lovr.git
World:raycast;
This commit is contained in:
parent
07ede6b2dc
commit
f3df7aa114
|
@ -22,6 +22,19 @@ 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);
|
||||||
|
luax_pushshape(L, shape);
|
||||||
|
lua_pushnumber(L, x);
|
||||||
|
lua_pushnumber(L, y);
|
||||||
|
lua_pushnumber(L, z);
|
||||||
|
lua_pushnumber(L, nx);
|
||||||
|
lua_pushnumber(L, ny);
|
||||||
|
lua_pushnumber(L, nz);
|
||||||
|
lua_call(L, 7, 0);
|
||||||
|
}
|
||||||
|
|
||||||
int l_lovrWorldNewCollider(lua_State* L) {
|
int l_lovrWorldNewCollider(lua_State* L) {
|
||||||
World* world = luax_checktype(L, 1, World);
|
World* world = luax_checktype(L, 1, World);
|
||||||
Collider* collider = lovrColliderCreate(world);
|
Collider* collider = lovrColliderCreate(world);
|
||||||
|
@ -173,6 +186,20 @@ int l_lovrWorldSetSleepingAllowed(lua_State* L) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int l_lovrWorldRaycast(lua_State* L) {
|
||||||
|
World* world = luax_checktype(L, 1, World);
|
||||||
|
float x1 = luaL_checknumber(L, 2);
|
||||||
|
float y1 = luaL_checknumber(L, 3);
|
||||||
|
float z1 = luaL_checknumber(L, 4);
|
||||||
|
float x2 = luaL_checknumber(L, 5);
|
||||||
|
float y2 = luaL_checknumber(L, 6);
|
||||||
|
float z2 = luaL_checknumber(L, 7);
|
||||||
|
luaL_checktype(L, 8, LUA_TFUNCTION);
|
||||||
|
lua_settop(L, 8);
|
||||||
|
lovrWorldRaycast(world, x1, y1, z1, x2, y2, z2, raycastCallback, L);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
const luaL_Reg lovrWorld[] = {
|
const luaL_Reg lovrWorld[] = {
|
||||||
{ "newCollider", l_lovrWorldNewCollider },
|
{ "newCollider", l_lovrWorldNewCollider },
|
||||||
{ "newBoxCollider", l_lovrWorldNewBoxCollider },
|
{ "newBoxCollider", l_lovrWorldNewBoxCollider },
|
||||||
|
@ -192,5 +219,6 @@ const luaL_Reg lovrWorld[] = {
|
||||||
{ "setAngularDamping", l_lovrWorldSetAngularDamping },
|
{ "setAngularDamping", l_lovrWorldSetAngularDamping },
|
||||||
{ "isSleepingAllowed", l_lovrWorldIsSleepingAllowed },
|
{ "isSleepingAllowed", l_lovrWorldIsSleepingAllowed },
|
||||||
{ "setSleepingAllowed", l_lovrWorldSetSleepingAllowed },
|
{ "setSleepingAllowed", l_lovrWorldSetSleepingAllowed },
|
||||||
|
{ "raycast", l_lovrWorldRaycast },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,6 +12,22 @@ static void customNearCallback(void* data, dGeomID shapeA, dGeomID shapeB) {
|
||||||
vec_push(&world->overlaps, dGeomGetData(shapeB));
|
vec_push(&world->overlaps, dGeomGetData(shapeB));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void raycastCallback(void* data, dGeomID a, dGeomID b) {
|
||||||
|
RaycastCallback callback = ((RaycastData*) data)->callback;
|
||||||
|
void* userdata = ((RaycastData*) data)->userdata;
|
||||||
|
Shape* shape = dGeomGetData(b);
|
||||||
|
|
||||||
|
if (!shape) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dContact contact;
|
||||||
|
if (dCollide(a, b, MAX_CONTACTS, &contact.geom, sizeof(dContact))) {
|
||||||
|
dContactGeom g = contact.geom;
|
||||||
|
callback(shape, g.pos[0], g.pos[1], g.pos[2], g.normal[0], g.normal[1], g.normal[2], userdata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void lovrPhysicsInit() {
|
void lovrPhysicsInit() {
|
||||||
dInitODE();
|
dInitODE();
|
||||||
|
|
||||||
|
@ -165,6 +181,18 @@ void lovrWorldSetSleepingAllowed(World* world, int allowed) {
|
||||||
dWorldSetAutoDisableFlag(world->id, allowed);
|
dWorldSetAutoDisableFlag(world->id, allowed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lovrWorldRaycast(World* world, float x1, float y1, float z1, float x2, float y2, float z2, RaycastCallback callback, void* userdata) {
|
||||||
|
RaycastData data = { .callback = callback, .userdata = userdata };
|
||||||
|
float dx = x2 - x1;
|
||||||
|
float dy = y2 - y1;
|
||||||
|
float dz = z2 - z1;
|
||||||
|
float length = sqrt(dx * dx + dy * dy + dz * dz);
|
||||||
|
dGeomID ray = dCreateRay(world->space, length);
|
||||||
|
dGeomRaySet(ray, x1, y1, z1, dx, dy, dz);
|
||||||
|
dSpaceCollide2(ray, (dGeomID) world->space, &data, raycastCallback);
|
||||||
|
dGeomDestroy(ray);
|
||||||
|
}
|
||||||
|
|
||||||
Collider* lovrColliderCreate(World* world) {
|
Collider* lovrColliderCreate(World* world) {
|
||||||
if (!world) {
|
if (!world) {
|
||||||
error("No world specified");
|
error("No world specified");
|
||||||
|
|
|
@ -60,6 +60,12 @@ typedef struct {
|
||||||
typedef Joint BallJoint;
|
typedef Joint BallJoint;
|
||||||
|
|
||||||
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 struct {
|
||||||
|
RaycastCallback callback;
|
||||||
|
void* userdata;
|
||||||
|
} RaycastData;
|
||||||
|
|
||||||
void lovrPhysicsInit();
|
void lovrPhysicsInit();
|
||||||
void lovrPhysicsDestroy();
|
void lovrPhysicsDestroy();
|
||||||
|
@ -79,6 +85,7 @@ void lovrWorldGetAngularDamping(World* world, float* damping, float* threshold);
|
||||||
void lovrWorldSetAngularDamping(World* world, float damping, float threshold);
|
void lovrWorldSetAngularDamping(World* world, float damping, float threshold);
|
||||||
int lovrWorldIsSleepingAllowed(World* world);
|
int lovrWorldIsSleepingAllowed(World* world);
|
||||||
void lovrWorldSetSleepingAllowed(World* world, int allowed);
|
void lovrWorldSetSleepingAllowed(World* world, int allowed);
|
||||||
|
void lovrWorldRaycast(World* world, float x1, float y1, float z1, float x2, float y2, float z2, RaycastCallback callback, void* userdata);
|
||||||
|
|
||||||
Collider* lovrColliderCreate();
|
Collider* lovrColliderCreate();
|
||||||
void lovrColliderDestroy(const Ref* ref);
|
void lovrColliderDestroy(const Ref* ref);
|
||||||
|
|
Loading…
Reference in New Issue