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 <stdbool.h>
|
||||||
#include <string.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) {
|
static bool raycastCallback(Collider* collider, float position[3], float normal[3], uint32_t shape, void* userdata) {
|
||||||
lua_State* L = userdata;
|
lua_State* L = userdata;
|
||||||
lua_pushvalue(L, -1);
|
lua_pushvalue(L, -1);
|
||||||
|
@ -258,37 +237,12 @@ static int l_lovrWorldGetJoints(lua_State* L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_lovrWorldUpdate(lua_State* L) {
|
static int l_lovrWorldUpdate(lua_State* L) {
|
||||||
lua_settop(L, 3);
|
|
||||||
World* world = luax_checktype(L, 1, World);
|
World* world = luax_checktype(L, 1, World);
|
||||||
float dt = luax_checkfloat(L, 2);
|
float dt = luax_checkfloat(L, 2);
|
||||||
CollisionResolver resolver = lua_type(L, 3) == LUA_TFUNCTION ? collisionResolver : NULL;
|
lovrWorldUpdate(world, dt);
|
||||||
lovrWorldUpdate(world, dt, resolver, L);
|
|
||||||
return 0;
|
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) {
|
static int l_lovrWorldGetContacts(lua_State* L) {
|
||||||
World* world = luax_checktype(L, 1, World);
|
World* world = luax_checktype(L, 1, World);
|
||||||
Shape* a = luax_checkshape(L, 2);
|
Shape* a = luax_checkshape(L, 2);
|
||||||
|
@ -554,9 +508,6 @@ const luaL_Reg lovrWorld[] = {
|
||||||
{ "getColliders", l_lovrWorldGetColliders },
|
{ "getColliders", l_lovrWorldGetColliders },
|
||||||
{ "getJoints", l_lovrWorldGetJoints },
|
{ "getJoints", l_lovrWorldGetJoints },
|
||||||
{ "update", l_lovrWorldUpdate },
|
{ "update", l_lovrWorldUpdate },
|
||||||
{ "computeOverlaps", l_lovrWorldComputeOverlaps },
|
|
||||||
{ "overlaps", l_lovrWorldOverlaps },
|
|
||||||
{ "collide", l_lovrWorldCollide },
|
|
||||||
{ "getContacts", l_lovrWorldGetContacts },
|
{ "getContacts", l_lovrWorldGetContacts },
|
||||||
{ "raycast", l_lovrWorldRaycast },
|
{ "raycast", l_lovrWorldRaycast },
|
||||||
{ "raycastAny", l_lovrWorldRaycastAny },
|
{ "raycastAny", l_lovrWorldRaycastAny },
|
||||||
|
|
|
@ -27,7 +27,6 @@ typedef Joint DistanceJoint;
|
||||||
typedef Joint HingeJoint;
|
typedef Joint HingeJoint;
|
||||||
typedef Joint SliderJoint;
|
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 (*RaycastCallback)(Collider* collider, float position[3], float normal[3], uint32_t child, void* userdata);
|
||||||
typedef bool (*QueryCallback)(Collider* collider, 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);
|
uint32_t lovrWorldGetJointCount(World* world);
|
||||||
Collider* lovrWorldGetColliders(World* world, Collider* collider);
|
Collider* lovrWorldGetColliders(World* world, Collider* collider);
|
||||||
Joint* lovrWorldGetJoints(World* world, Joint* joint);
|
Joint* lovrWorldGetJoints(World* world, Joint* joint);
|
||||||
void lovrWorldUpdate(World* world, float dt, CollisionResolver resolver, void* userdata);
|
void lovrWorldUpdate(World* world, float dt);
|
||||||
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 lovrWorldGetContacts(World* world, Shape* a, Shape* b, Contact contacts[MAX_CONTACTS], uint32_t* count);
|
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);
|
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);
|
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;
|
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);
|
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) {
|
void lovrWorldGetContacts(World* world, Shape* a, Shape* b, Contact contacts[MAX_CONTACTS], uint32_t* count) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,14 +45,44 @@ struct Joint {
|
||||||
dJointID id;
|
dJointID id;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void defaultNearCallback(void* data, dGeomID a, dGeomID b) {
|
static void defaultNearCallback(void* data, dGeomID ga, dGeomID gb) {
|
||||||
lovrWorldCollide((World*) data, dGeomGetData(a), dGeomGetData(b), -1, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void customNearCallback(void* data, dGeomID shapeA, dGeomID shapeB) {
|
|
||||||
World* world = data;
|
World* world = data;
|
||||||
arr_push(&world->overlaps, dGeomGetData(shapeA));
|
Collider* a = dBodyGetData(dGeomGetBody(ga));
|
||||||
arr_push(&world->overlaps, dGeomGetData(shapeB));
|
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 {
|
typedef struct {
|
||||||
|
@ -228,12 +258,8 @@ Joint* lovrWorldGetJoints(World* world, Joint* joint) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrWorldUpdate(World* world, float dt, CollisionResolver resolver, void* userdata) {
|
void lovrWorldUpdate(World* world, float dt) {
|
||||||
if (resolver) {
|
dSpaceCollide(world->space, world, defaultNearCallback);
|
||||||
resolver(world, userdata);
|
|
||||||
} else {
|
|
||||||
dSpaceCollide(world->space, world, defaultNearCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dt > 0) {
|
if (dt > 0) {
|
||||||
dWorldQuickStep(world->id, dt);
|
dWorldQuickStep(world->id, dt);
|
||||||
|
@ -250,67 +276,6 @@ void lovrWorldSetStepCount(World* world, int iterations) {
|
||||||
dWorldSetQuickStepNumIterations(world->id, 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) {
|
void lovrWorldGetContacts(World* world, Shape* a, Shape* b, Contact contacts[MAX_CONTACTS], uint32_t* count) {
|
||||||
dContactGeom info[MAX_CONTACTS];
|
dContactGeom info[MAX_CONTACTS];
|
||||||
int c = *count = dCollide(a->id, b->id, MAX_CONTACTS, info, sizeof(info[0]));
|
int c = *count = dCollide(a->id, b->id, MAX_CONTACTS, info, sizeof(info[0]));
|
||||||
|
|
Loading…
Reference in New Issue