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) {
|
||||
World* world = luax_checktype(L, 1, World);
|
||||
Collider* collider = lovrColliderCreate(world);
|
||||
|
@ -173,6 +186,20 @@ int l_lovrWorldSetSleepingAllowed(lua_State* L) {
|
|||
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[] = {
|
||||
{ "newCollider", l_lovrWorldNewCollider },
|
||||
{ "newBoxCollider", l_lovrWorldNewBoxCollider },
|
||||
|
@ -192,5 +219,6 @@ const luaL_Reg lovrWorld[] = {
|
|||
{ "setAngularDamping", l_lovrWorldSetAngularDamping },
|
||||
{ "isSleepingAllowed", l_lovrWorldIsSleepingAllowed },
|
||||
{ "setSleepingAllowed", l_lovrWorldSetSleepingAllowed },
|
||||
{ "raycast", l_lovrWorldRaycast },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
|
|
@ -12,6 +12,22 @@ static void customNearCallback(void* data, dGeomID shapeA, dGeomID 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() {
|
||||
dInitODE();
|
||||
|
||||
|
@ -165,6 +181,18 @@ void lovrWorldSetSleepingAllowed(World* world, int 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) {
|
||||
if (!world) {
|
||||
error("No world specified");
|
||||
|
|
|
@ -60,6 +60,12 @@ typedef struct {
|
|||
typedef Joint BallJoint;
|
||||
|
||||
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 lovrPhysicsDestroy();
|
||||
|
@ -79,6 +85,7 @@ void lovrWorldGetAngularDamping(World* world, float* damping, float* threshold);
|
|||
void lovrWorldSetAngularDamping(World* world, float damping, float threshold);
|
||||
int lovrWorldIsSleepingAllowed(World* world);
|
||||
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();
|
||||
void lovrColliderDestroy(const Ref* ref);
|
||||
|
|
Loading…
Reference in New Issue