mirror of https://github.com/bjornbytes/lovr.git
World queries return collider/shapeindex instead of Shape;
This commit is contained in:
parent
e842c2b772
commit
8f40d98074
|
@ -27,17 +27,18 @@ static int nextOverlap(lua_State* L) {
|
|||
}
|
||||
}
|
||||
|
||||
static bool raycastCallback(Shape* shape, float x, float y, float z, float nx, float ny, float nz, void* userdata) {
|
||||
static bool raycastCallback(Collider* collider, uint32_t shape, float position[3], float normal[3], void* userdata) {
|
||||
lua_State* L = userdata;
|
||||
lua_pushvalue(L, -1);
|
||||
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, 1);
|
||||
luax_pushtype(L, Collider, collider);
|
||||
lua_pushinteger(L, shape);
|
||||
lua_pushnumber(L, position[0]);
|
||||
lua_pushnumber(L, position[1]);
|
||||
lua_pushnumber(L, position[2]);
|
||||
lua_pushnumber(L, normal[0]);
|
||||
lua_pushnumber(L, normal[1]);
|
||||
lua_pushnumber(L, normal[2]);
|
||||
lua_call(L, 8, 1);
|
||||
bool shouldStop = lua_type(L, -1) == LUA_TBOOLEAN && !lua_toboolean(L, -1);
|
||||
lua_pop(L, 1);
|
||||
return shouldStop;
|
||||
|
@ -45,53 +46,55 @@ static bool raycastCallback(Shape* shape, float x, float y, float z, float nx, f
|
|||
|
||||
typedef struct {
|
||||
const char* tag;
|
||||
Shape* shape;
|
||||
Collider* collider;
|
||||
uint32_t shape;
|
||||
float distance;
|
||||
float origin[3];
|
||||
float position[3];
|
||||
float normal[3];
|
||||
} RaycastData;
|
||||
|
||||
static bool raycastAnyCallback(Shape* shape, float x, float y, float z, float nx, float ny, float nz, void* userdata) {
|
||||
static bool raycastAnyCallback(Collider* collider, uint32_t shape, float position[3], float normal[3], void* userdata) {
|
||||
RaycastData* data = userdata;
|
||||
if (data->tag) {
|
||||
const char* tag = NULL; // TODO
|
||||
const char* tag = lovrColliderGetTag(collider);
|
||||
if (!tag || strcmp(tag, data->tag)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
data->collider = collider;
|
||||
data->shape = shape;
|
||||
vec3_set(data->position, x, y, z);
|
||||
vec3_set(data->normal, nx, ny, nz);
|
||||
vec3_init(data->position, position);
|
||||
vec3_init(data->normal, normal);
|
||||
data->distance = vec3_distance(data->origin, data->position);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool raycastClosestCallback(Shape* shape, float x, float y, float z, float nx, float ny, float nz, void* userdata) {
|
||||
static bool raycastClosestCallback(Collider* collider, uint32_t shape, float position[3], float normal[3], void* userdata) {
|
||||
RaycastData* data = userdata;
|
||||
if (data->tag) {
|
||||
const char* tag = NULL; // TODO
|
||||
const char* tag = lovrColliderGetTag(collider);
|
||||
if (!tag || strcmp(tag, data->tag)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
float position[3];
|
||||
vec3_set(position, x, y, z);
|
||||
float distance = vec3_distance(data->origin, position);
|
||||
if (distance < data->distance) {
|
||||
vec3_init(data->position, position);
|
||||
vec3_set(data->normal, nx, ny, nz);
|
||||
vec3_init(data->normal, normal);
|
||||
data->distance = distance;
|
||||
data->collider = collider;
|
||||
data->shape = shape;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool queryCallback(Shape* shape, void* userdata) {
|
||||
static bool queryCallback(Collider* collider, uint32_t shape, void* userdata) {
|
||||
lua_State* L = userdata;
|
||||
lua_pushvalue(L, -1);
|
||||
luax_pushshape(L, shape);
|
||||
lua_call(L, 1, 1);
|
||||
luax_pushtype(L, Collider, collider);
|
||||
lua_pushinteger(L, shape);
|
||||
lua_call(L, 2, 1);
|
||||
bool shouldStop = lua_type(L, -1) == LUA_TBOOLEAN && !lua_toboolean(L, -1);
|
||||
lua_pop(L, 1);
|
||||
return shouldStop;
|
||||
|
@ -309,15 +312,16 @@ static int l_lovrWorldRaycastAny(lua_State* L) {
|
|||
RaycastData data = { 0 };
|
||||
data.tag = lua_tostring(L, index);
|
||||
lovrWorldRaycast(world, start[0], start[1], start[2], end[0], end[1], end[2], raycastAnyCallback, &data);
|
||||
if (data.shape) {
|
||||
luax_pushshape(L, data.shape);
|
||||
if (data.collider) {
|
||||
luax_pushtype(L, Collider, data.collider);
|
||||
lua_pushinteger(L, data.shape);
|
||||
lua_pushnumber(L, data.position[0]);
|
||||
lua_pushnumber(L, data.position[1]);
|
||||
lua_pushnumber(L, data.position[2]);
|
||||
lua_pushnumber(L, data.normal[0]);
|
||||
lua_pushnumber(L, data.normal[1]);
|
||||
lua_pushnumber(L, data.normal[2]);
|
||||
return 7;
|
||||
return 8;
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
|
@ -334,14 +338,15 @@ static int l_lovrWorldRaycastClosest(lua_State* L) {
|
|||
data.tag = lua_tostring(L, index);
|
||||
lovrWorldRaycast(world, start[0], start[1], start[2], end[0], end[1], end[2], raycastClosestCallback, &data);
|
||||
if (data.shape) {
|
||||
luax_pushshape(L, data.shape);
|
||||
luax_pushtype(L, Collider, data.collider);
|
||||
lua_pushinteger(L, data.shape);
|
||||
lua_pushnumber(L, data.position[0]);
|
||||
lua_pushnumber(L, data.position[1]);
|
||||
lua_pushnumber(L, data.position[2]);
|
||||
lua_pushnumber(L, data.normal[0]);
|
||||
lua_pushnumber(L, data.normal[1]);
|
||||
lua_pushnumber(L, data.normal[2]);
|
||||
return 7;
|
||||
return 8;
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
|
|
|
@ -27,8 +27,8 @@ typedef Joint HingeJoint;
|
|||
typedef Joint SliderJoint;
|
||||
|
||||
typedef void (*CollisionResolver)(World* world, void* userdata);
|
||||
typedef bool (*RaycastCallback)(Shape* shape, float x, float y, float z, float nx, float ny, float nz, void* userdata);
|
||||
typedef bool (*QueryCallback)(Shape* shape, void* userdata);
|
||||
typedef bool (*RaycastCallback)(Collider* collider, uint32_t shape, float position[3], float normal[3], void* userdata);
|
||||
typedef bool (*QueryCallback)(Collider* collider, uint32_t shape, void* userdata);
|
||||
|
||||
bool lovrPhysicsInit(void);
|
||||
void lovrPhysicsDestroy(void);
|
||||
|
|
|
@ -172,32 +172,34 @@ void lovrWorldRaycast(World* world, float x1, float y1, float z1, float x2, floa
|
|||
const JPH_Vec3 direction = { x2 - x1, y2 - y1, z2 - z1 };
|
||||
JPH_AllHit_CastRayCollector* collector = JPH_AllHit_CastRayCollector_Create();
|
||||
JPH_NarrowPhaseQuery_CastRayAll(query, &origin, &direction, collector, NULL, NULL, NULL);
|
||||
size_t hit_count;
|
||||
JPH_RayCastResult* hit_array = JPH_AllHit_CastRayCollector_GetHits(collector, &hit_count);
|
||||
for (int i = 0; i < hit_count; i++) {
|
||||
float x = x1 + hit_array[i].fraction * (x2 - x1);
|
||||
float y = y1 + hit_array[i].fraction * (y2 - y1);
|
||||
float z = z1 + hit_array[i].fraction * (z2 - z1);
|
||||
// todo: assuming one shape per collider; doesn't support compound shape
|
||||
Collider* collider = (Collider*) JPH_BodyInterface_GetUserData(
|
||||
world->bodies,
|
||||
hit_array[i].bodyID);
|
||||
size_t count;
|
||||
Shape* shape = lovrColliderGetShape(collider);
|
||||
const JPH_RVec3 position = { x, y, z };
|
||||
|
||||
size_t count;
|
||||
JPH_RayCastResult* hits = JPH_AllHit_CastRayCollector_GetHits(collector, &count);
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
Collider* collider = (Collider*) (uintptr_t) JPH_BodyInterface_GetUserData(world->bodies, hits[i].bodyID);
|
||||
|
||||
uint32_t shape = 0;
|
||||
if (collider->shape->type == SHAPE_COMPOUND) {
|
||||
JPH_SubShapeID id = hits[i].subShapeID2;
|
||||
JPH_SubShapeID remainder;
|
||||
shape = JPH_CompoundShape_GetSubShapeIndexFromID((JPH_CompoundShape*) collider->shape, id, &remainder);
|
||||
}
|
||||
|
||||
JPH_RVec3 position = {
|
||||
x1 + hits[i].fraction * (x2 - x1),
|
||||
y1 + hits[i].fraction * (y2 - y1),
|
||||
z1 + hits[i].fraction * (z2 - z1)
|
||||
};
|
||||
|
||||
JPH_Vec3 normal;
|
||||
JPH_Body_GetWorldSpaceSurfaceNormal(collider->body, hit_array[i].subShapeID2, &position, &normal);
|
||||
JPH_Body_GetWorldSpaceSurfaceNormal(collider->body, hits[i].subShapeID2, &position, &normal);
|
||||
|
||||
bool shouldStop = callback(
|
||||
shape, // assumes one shape per collider; todo: compound shapes
|
||||
x, y, z,
|
||||
normal.x, normal.y, normal.z,
|
||||
userdata);
|
||||
|
||||
if (shouldStop) {
|
||||
if (callback(collider, shape, &position.x, &normal.x, userdata)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
JPH_AllHit_CastRayCollector_Destroy(collector);
|
||||
}
|
||||
|
||||
|
@ -208,26 +210,25 @@ static bool lovrWorldQueryShape(World* world, JPH_Shape* shape, float position[3
|
|||
mat4_translate(m, position[0], position[1], position[2]);
|
||||
mat4_scale(m, scale[0], scale[1], scale[2]);
|
||||
|
||||
JPH_Vec3 direction = { 0.f };
|
||||
JPH_RVec3 base_offset = { 0.f };
|
||||
JPH_Vec3 direction = { 0.f, 0.f, 0.f };
|
||||
JPH_RVec3 base_offset = { 0.f, 0.f, 0.f };
|
||||
const JPH_NarrowPhaseQuery* query = JPC_PhysicsSystem_GetNarrowPhaseQueryNoLock(world->system);
|
||||
JPH_AllHit_CastShapeCollector_Reset(state.castShapeCollector);
|
||||
JPH_NarrowPhaseQuery_CastShape(query, shape, &transform, &direction, &base_offset, state.castShapeCollector);
|
||||
size_t hit_count;
|
||||
JPH_ShapeCastResult* hit_array = JPH_AllHit_CastShapeCollector_GetHits(state.castShapeCollector, &hit_count);
|
||||
for (int i = 0; i < hit_count; i++) {
|
||||
|
||||
size_t count;
|
||||
JPH_AllHit_CastShapeCollector_GetHits(state.castShapeCollector, &count);
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
JPH_BodyID id = JPH_AllHit_CastShapeCollector_GetBodyID2(state.castShapeCollector, i);
|
||||
Collider* collider = (Collider*) JPH_BodyInterface_GetUserData(
|
||||
world->bodies,
|
||||
id);
|
||||
size_t count;
|
||||
Shape* shape = lovrColliderGetShape(collider);
|
||||
bool shouldStop = callback(shape, userdata);
|
||||
if (shouldStop) {
|
||||
Collider* collider = (Collider*) (uintptr_t) JPH_BodyInterface_GetUserData(world->bodies, id);
|
||||
|
||||
if (callback(collider, 0, userdata)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return hit_count > 0;
|
||||
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
bool lovrWorldQueryBox(World* world, float position[3], float size[3], QueryCallback callback, void* userdata) {
|
||||
|
|
Loading…
Reference in New Issue