ODE compatibility;

This commit is contained in:
bjorn 2024-04-05 00:35:03 -07:00
parent 0f2717850e
commit 348a96ee69
1 changed files with 85 additions and 66 deletions

View File

@ -22,7 +22,7 @@ struct Collider {
Collider* prev; Collider* prev;
Collider* next; Collider* next;
uint32_t tag; uint32_t tag;
arr_t(Shape*) shapes; Shape* shape;
arr_t(Joint*) joints; arr_t(Joint*) joints;
float friction; float friction;
float restitution; float restitution;
@ -66,8 +66,9 @@ static void raycastCallback(void* d, dGeomID a, dGeomID b) {
RaycastCallback callback = data->callback; RaycastCallback callback = data->callback;
void* userdata = data->userdata; void* userdata = data->userdata;
Shape* shape = dGeomGetData(b); Shape* shape = dGeomGetData(b);
Collider* collider = dBodyGetData(dGeomGetBody(b));
if (!shape) { if (!shape || !collider) {
return; return;
} }
@ -75,9 +76,7 @@ static void raycastCallback(void* d, dGeomID a, dGeomID b) {
int count = dCollide(a, b, MAX_CONTACTS, &contact->geom, sizeof(dContact)); int count = dCollide(a, b, MAX_CONTACTS, &contact->geom, sizeof(dContact));
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
dContactGeom g = contact[i].geom; dContactGeom g = contact[i].geom;
data->shouldStop = callback( data->shouldStop = callback(collider, 0, g.pos, g.normal, userdata);
shape, g.pos[0], g.pos[1], g.pos[2], g.normal[0], g.normal[1], g.normal[2], userdata
);
} }
} }
@ -93,14 +92,15 @@ static void queryCallback(void* d, dGeomID a, dGeomID b) {
if (data->shouldStop) return; if (data->shouldStop) return;
Shape* shape = dGeomGetData(b); Shape* shape = dGeomGetData(b);
if (!shape) { Collider* collider = dBodyGetData(dGeomGetBody(b));
if (!shape || !collider) {
return; return;
} }
dContactGeom contact; dContactGeom contact;
if (dCollide(a, b, 1 | CONTACTS_UNIMPORTANT, &contact, sizeof(contact))) { if (dCollide(a, b, 1 | CONTACTS_UNIMPORTANT, &contact, sizeof(contact))) {
if (data->callback) { if (data->callback) {
data->shouldStop = data->callback(shape, data->userdata); data->shouldStop = data->callback(collider, 0, data->userdata);
} else { } else {
data->shouldStop = true; data->shouldStop = true;
} }
@ -445,7 +445,6 @@ Collider* lovrColliderCreate(World* world, float x, float y, float z) {
collider->restitution = 0; collider->restitution = 0;
collider->tag = NO_TAG; collider->tag = NO_TAG;
dBodySetData(collider->body, collider); dBodySetData(collider->body, collider);
arr_init(&collider->shapes);
arr_init(&collider->joints); arr_init(&collider->joints);
lovrColliderSetPosition(collider, x, y, z); lovrColliderSetPosition(collider, x, y, z);
@ -467,7 +466,6 @@ Collider* lovrColliderCreate(World* world, float x, float y, float z) {
void lovrColliderDestroy(void* ref) { void lovrColliderDestroy(void* ref) {
Collider* collider = ref; Collider* collider = ref;
lovrColliderDestroyData(collider); lovrColliderDestroyData(collider);
arr_free(&collider->shapes);
arr_free(&collider->joints); arr_free(&collider->joints);
lovrFree(collider); lovrFree(collider);
} }
@ -477,13 +475,9 @@ void lovrColliderDestroyData(Collider* collider) {
return; return;
} }
lovrColliderSetShape(collider, NULL);
size_t count; size_t count;
Shape** shapes = lovrColliderGetShapes(collider, &count);
for (size_t i = 0; i < count; i++) {
lovrColliderRemoveShape(collider, shapes[i]);
}
Joint** joints = lovrColliderGetJoints(collider, &count); Joint** joints = lovrColliderGetJoints(collider, &count);
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
lovrRelease(joints[i], lovrJointDestroy); lovrRelease(joints[i], lovrJointDestroy);
@ -521,38 +515,50 @@ Collider* lovrColliderGetNext(Collider* collider) {
return collider->next; return collider->next;
} }
void lovrColliderAddShape(Collider* collider, Shape* shape) { Shape* lovrColliderGetShape(Collider* collider) {
lovrRetain(shape); return collider->shape;
if (shape->collider) {
lovrColliderRemoveShape(shape->collider, shape);
}
shape->collider = collider;
dGeomSetBody(shape->id, collider->body);
dSpaceID newSpace = collider->world->space;
dSpaceAdd(newSpace, shape->id);
} }
void lovrColliderRemoveShape(Collider* collider, Shape* shape) { void lovrColliderSetShape(Collider* collider, Shape* shape) {
if (shape->collider == collider) { if (collider->shape) {
dSpaceRemove(collider->world->space, shape->id); dSpaceRemove(collider->world->space, collider->shape->id);
dGeomSetBody(shape->id, 0); dGeomSetBody(collider->shape->id, 0);
shape->collider = NULL; collider->shape->collider = NULL;
lovrRelease(shape, lovrShapeDestroy); lovrRelease(collider->shape, lovrShapeDestroy);
} }
}
Shape** lovrColliderGetShapes(Collider* collider, size_t* count) { collider->shape = shape;
arr_clear(&collider->shapes);
for (dGeomID geom = dBodyGetFirstGeom(collider->body); geom; geom = dBodyGetNextGeom(geom)) { if (shape) {
Shape* shape = dGeomGetData(geom); if (shape->collider) {
if (shape) { lovrColliderSetShape(shape->collider, NULL);
arr_push(&collider->shapes, shape);
} }
shape->collider = collider;
dGeomSetBody(shape->id, collider->body);
dSpaceID newSpace = collider->world->space;
dSpaceAdd(newSpace, shape->id);
lovrRetain(shape);
} }
*count = collider->shapes.length; }
return collider->shapes.data;
void lovrColliderGetShapeOffset(Collider* collider, float* position, float* orientation) {
const dReal* p = dGeomGetOffsetPosition(collider->shape->id);
position[0] = p[0];
position[1] = p[1];
position[2] = p[2];
dReal q[4];
dGeomGetOffsetQuaternion(collider->shape->id, q);
orientation[0] = q[1];
orientation[1] = q[2];
orientation[2] = q[3];
orientation[3] = q[0];
}
void lovrColliderSetShapeOffset(Collider* collider, float* position, float* orientation) {
dGeomSetOffsetPosition(collider->shape->id, position[0], position[1], position[2]);
dReal q[4] = { orientation[3], orientation[0], orientation[1], orientation[2] };
dGeomSetOffsetQuaternion(collider->shape->id, q);
} }
Joint** lovrColliderGetJoints(Collider* collider, size_t* count) { Joint** lovrColliderGetJoints(Collider* collider, size_t* count) {
@ -888,31 +894,6 @@ void lovrShapeSetSensor(Shape* shape, bool sensor) {
shape->sensor = sensor; shape->sensor = sensor;
} }
void lovrShapeGetPosition(Shape* shape, float* x, float* y, float* z) {
const dReal* position = dGeomGetOffsetPosition(shape->id);
*x = position[0];
*y = position[1];
*z = position[2];
}
void lovrShapeSetPosition(Shape* shape, float x, float y, float z) {
dGeomSetOffsetPosition(shape->id, x, y, z);
}
void lovrShapeGetOrientation(Shape* shape, float* orientation) {
dReal q[4];
dGeomGetOffsetQuaternion(shape->id, q);
orientation[0] = q[1];
orientation[1] = q[2];
orientation[2] = q[3];
orientation[3] = q[0];
}
void lovrShapeSetOrientation(Shape* shape, float* orientation) {
dReal q[4] = { orientation[3], orientation[0], orientation[1], orientation[2] };
dGeomSetOffsetQuaternion(shape->id, q);
}
void lovrShapeGetMass(Shape* shape, float density, float* cx, float* cy, float* cz, float* mass, float inertia[6]) { void lovrShapeGetMass(Shape* shape, float density, float* cx, float* cy, float* cz, float* mass, float inertia[6]) {
dMass m; dMass m;
dMassSetZero(&m); dMassSetZero(&m);
@ -953,6 +934,8 @@ void lovrShapeGetMass(Shape* shape, float density, float* cx, float* cy, float*
case SHAPE_TERRAIN: { case SHAPE_TERRAIN: {
break; break;
} }
default: break;
} }
const dReal* position = dGeomGetOffsetPosition(shape->id); const dReal* position = dGeomGetOffsetPosition(shape->id);
@ -1112,6 +1095,42 @@ TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t widthSamples, uin
return terrain; return terrain;
} }
CompoundShape* lovrCompoundShapeCreate(Shape** shapes, float* positions, float* orientations, uint32_t count, bool freeze) {
lovrThrow("ODE does not support compound shape");
}
bool lovrCompoundShapeIsFrozen(CompoundShape* shape) {
return false;
}
void lovrCompoundShapeAddShape(CompoundShape* shape, Shape* child, float* position, float* orientation) {
//
}
void lovrCompoundShapeReplaceShape(CompoundShape* shape, uint32_t index, Shape* child, float* position, float* orientation) {
//
}
void lovrCompoundShapeRemoveShape(CompoundShape* shape, uint32_t index) {
//
}
Shape* lovrCompoundShapeGetShape(CompoundShape* shape, uint32_t index) {
return NULL;
}
uint32_t lovrCompoundShapeGetShapeCount(CompoundShape* shape) {
return 0;
}
void lovrCompoundShapeGetShapeOffset(CompoundShape* shape, uint32_t index, float* position, float* orientation) {
//
}
void lovrCompoundShapeSetShapeOffset(CompoundShape* shape, uint32_t index, float* position, float* orientation) {
//
}
void lovrJointDestroy(void* ref) { void lovrJointDestroy(void* ref) {
Joint* joint = ref; Joint* joint = ref;
lovrJointDestroyData(joint); lovrJointDestroyData(joint);