rm World:overlaps/computeOverlaps/collide;

This commit is contained in:
bjorn 2024-04-19 19:45:59 -07:00
parent 5c68b701d3
commit 83e11cc264
4 changed files with 42 additions and 142 deletions

View File

@ -6,27 +6,6 @@
#include <stdbool.h>
#include <string.h>
static void collisionResolver(World* world, void* userdata) {
lua_State* L = userdata;
luaL_checktype(L, -1, LUA_TFUNCTION);
luax_pushtype(L, World, world);
lua_call(L, 1, 0);
}
static int nextOverlap(lua_State* L) {
World* world = luax_checktype(L, lua_upvalueindex(1), World);
Shape* a;
Shape* b;
if (lovrWorldGetNextOverlap(world, &a, &b)) {
luax_pushshape(L, a);
luax_pushshape(L, b);
return 2;
} else {
lua_pushnil(L);
return 1;
}
}
static bool raycastCallback(Collider* collider, float position[3], float normal[3], uint32_t shape, void* userdata) {
lua_State* L = userdata;
lua_pushvalue(L, -1);
@ -258,37 +237,12 @@ static int l_lovrWorldGetJoints(lua_State* L) {
}
static int l_lovrWorldUpdate(lua_State* L) {
lua_settop(L, 3);
World* world = luax_checktype(L, 1, World);
float dt = luax_checkfloat(L, 2);
CollisionResolver resolver = lua_type(L, 3) == LUA_TFUNCTION ? collisionResolver : NULL;
lovrWorldUpdate(world, dt, resolver, L);
lovrWorldUpdate(world, dt);
return 0;
}
static int l_lovrWorldComputeOverlaps(lua_State* L) {
World* world = luax_checktype(L, 1, World);
lovrWorldComputeOverlaps(world);
return 0;
}
static int l_lovrWorldOverlaps(lua_State* L) {
luax_checktype(L, 1, World);
lua_settop(L, 1);
lua_pushcclosure(L, nextOverlap, 1);
return 1;
}
static int l_lovrWorldCollide(lua_State* L) {
World* world = luax_checktype(L, 1, World);
Shape* a = luax_checkshape(L, 2);
Shape* b = luax_checkshape(L, 3);
float friction = luax_optfloat(L, 4, -1.f);
float restitution = luax_optfloat(L, 5, -1.f);
lua_pushboolean(L, lovrWorldCollide(world, a, b, friction, restitution));
return 1;
}
static int l_lovrWorldGetContacts(lua_State* L) {
World* world = luax_checktype(L, 1, World);
Shape* a = luax_checkshape(L, 2);
@ -554,9 +508,6 @@ const luaL_Reg lovrWorld[] = {
{ "getColliders", l_lovrWorldGetColliders },
{ "getJoints", l_lovrWorldGetJoints },
{ "update", l_lovrWorldUpdate },
{ "computeOverlaps", l_lovrWorldComputeOverlaps },
{ "overlaps", l_lovrWorldOverlaps },
{ "collide", l_lovrWorldCollide },
{ "getContacts", l_lovrWorldGetContacts },
{ "raycast", l_lovrWorldRaycast },
{ "raycastAny", l_lovrWorldRaycastAny },

View File

@ -27,7 +27,6 @@ typedef Joint DistanceJoint;
typedef Joint HingeJoint;
typedef Joint SliderJoint;
typedef void (*CollisionResolver)(World* world, void* userdata);
typedef bool (*RaycastCallback)(Collider* collider, float position[3], float normal[3], uint32_t child, void* userdata);
typedef bool (*QueryCallback)(Collider* collider, uint32_t child, void* userdata);
@ -58,10 +57,7 @@ uint32_t lovrWorldGetColliderCount(World* world);
uint32_t lovrWorldGetJointCount(World* world);
Collider* lovrWorldGetColliders(World* world, Collider* collider);
Joint* lovrWorldGetJoints(World* world, Joint* joint);
void lovrWorldUpdate(World* world, float dt, CollisionResolver resolver, void* userdata);
void lovrWorldComputeOverlaps(World* world);
int lovrWorldGetNextOverlap(World* world, Shape** a, Shape** b);
int lovrWorldCollide(World* world, Shape* a, Shape* b, float friction, float restitution);
void lovrWorldUpdate(World* world, float dt);
void lovrWorldGetContacts(World* world, Shape* a, Shape* b, Contact contacts[MAX_CONTACTS], uint32_t* count);
void lovrWorldRaycast(World* world, float start[3], float end[3], RaycastCallback callback, void* userdata);
bool lovrWorldQueryBox(World* world, float position[3], float size[3], QueryCallback callback, void* userdata);

View File

@ -177,22 +177,10 @@ Joint* lovrWorldGetJoints(World* world, Joint* joint) {
return joint ? joint->world.next : world->joints;
}
void lovrWorldUpdate(World* world, float dt, CollisionResolver resolver, void* userdata) {
void lovrWorldUpdate(World* world, float dt) {
JPH_PhysicsSystem_Step(world->system, dt, world->collisionSteps);
}
void lovrWorldComputeOverlaps(World* world) {
//
}
int lovrWorldGetNextOverlap(World* world, Shape** a, Shape** b) {
return 0;
}
int lovrWorldCollide(World* world, Shape* a, Shape* b, float friction, float restitution) {
return 0;
}
void lovrWorldGetContacts(World* world, Shape* a, Shape* b, Contact contacts[MAX_CONTACTS], uint32_t* count) {
//
}

View File

@ -45,14 +45,44 @@ struct Joint {
dJointID id;
};
static void defaultNearCallback(void* data, dGeomID a, dGeomID b) {
lovrWorldCollide((World*) data, dGeomGetData(a), dGeomGetData(b), -1, -1);
}
static void customNearCallback(void* data, dGeomID shapeA, dGeomID shapeB) {
static void defaultNearCallback(void* data, dGeomID ga, dGeomID gb) {
World* world = data;
arr_push(&world->overlaps, dGeomGetData(shapeA));
arr_push(&world->overlaps, dGeomGetData(shapeB));
Collider* a = dBodyGetData(dGeomGetBody(ga));
Collider* b = dBodyGetData(dGeomGetBody(gb));
if (!a || !b) {
return;
}
uint32_t i = a->tag;
uint32_t j = b->tag;
if (i != NO_TAG && j != NO_TAG && !((world->masks[i] & (1 << j)) && (world->masks[j] & (1 << i)))) {
return;
}
float friction = sqrtf(a->friction * b->friction);
float restitution = MAX(a->restitution, b->restitution);
dContact contacts[MAX_CONTACTS];
for (int c = 0; c < MAX_CONTACTS; c++) {
contacts[c].surface.mode = 0;
contacts[c].surface.mu = friction;
contacts[c].surface.bounce = restitution;
if (restitution > 0) {
contacts[c].surface.mode |= dContactBounce;
}
}
int contactCount = dCollide(ga, gb, MAX_CONTACTS, &contacts[0].geom, sizeof(dContact));
if (!a->sensor && !b->sensor) {
for (int c = 0; c < contactCount; c++) {
dJointID joint = dJointCreateContact(world->id, world->contactGroup, &contacts[c]);
dJointAttach(joint, a->body, b->body);
}
}
}
typedef struct {
@ -228,12 +258,8 @@ Joint* lovrWorldGetJoints(World* world, Joint* joint) {
return NULL;
}
void lovrWorldUpdate(World* world, float dt, CollisionResolver resolver, void* userdata) {
if (resolver) {
resolver(world, userdata);
} else {
dSpaceCollide(world->space, world, defaultNearCallback);
}
void lovrWorldUpdate(World* world, float dt) {
dSpaceCollide(world->space, world, defaultNearCallback);
if (dt > 0) {
dWorldQuickStep(world->id, dt);
@ -250,67 +276,6 @@ void lovrWorldSetStepCount(World* world, int iterations) {
dWorldSetQuickStepNumIterations(world->id, iterations);
}
void lovrWorldComputeOverlaps(World* world) {
arr_clear(&world->overlaps);
dSpaceCollide(world->space, world, customNearCallback);
}
int lovrWorldGetNextOverlap(World* world, Shape** a, Shape** b) {
if (world->overlaps.length == 0) {
*a = *b = NULL;
return 0;
}
*a = arr_pop(&world->overlaps);
*b = arr_pop(&world->overlaps);
return 1;
}
int lovrWorldCollide(World* world, Shape* a, Shape* b, float friction, float restitution) {
if (!a || !b) {
return false;
}
Collider* colliderA = a->collider;
Collider* colliderB = b->collider;
uint32_t i = colliderA->tag;
uint32_t j = colliderB->tag;
if (i != NO_TAG && j != NO_TAG && !((world->masks[i] & (1 << j)) && (world->masks[j] & (1 << i)))) {
return false;
}
if (friction < 0.f) {
friction = sqrtf(colliderA->friction * colliderB->friction);
}
if (restitution < 0.f) {
restitution = MAX(colliderA->restitution, colliderB->restitution);
}
dContact contacts[MAX_CONTACTS];
for (int c = 0; c < MAX_CONTACTS; c++) {
contacts[c].surface.mode = 0;
contacts[c].surface.mu = friction;
contacts[c].surface.bounce = restitution;
if (restitution > 0) {
contacts[c].surface.mode |= dContactBounce;
}
}
int contactCount = dCollide(a->id, b->id, MAX_CONTACTS, &contacts[0].geom, sizeof(dContact));
if (!colliderA->sensor && !colliderB->sensor) {
for (int c = 0; c < contactCount; c++) {
dJointID joint = dJointCreateContact(world->id, world->contactGroup, &contacts[c]);
dJointAttach(joint, colliderA->body, colliderB->body);
}
}
return contactCount;
}
void lovrWorldGetContacts(World* world, Shape* a, Shape* b, Contact contacts[MAX_CONTACTS], uint32_t* count) {
dContactGeom info[MAX_CONTACTS];
int c = *count = dCollide(a->id, b->id, MAX_CONTACTS, info, sizeof(info[0]));