mirror of https://github.com/bjornbytes/lovr.git
rm World:overlaps/computeOverlaps/collide;
This commit is contained in:
parent
5c68b701d3
commit
83e11cc264
|
@ -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 },
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
//
|
||||
}
|
||||
|
|
|
@ -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]));
|
||||
|
|
Loading…
Reference in New Issue