From f1ba4d1a1e54dfd7f0e1a9d38640dfbffcfea4fa Mon Sep 17 00:00:00 2001 From: bjorn Date: Mon, 8 Apr 2024 11:11:28 -0700 Subject: [PATCH] Clean up Joint lists further; --- src/api/l_physics_collider.c | 3 +- src/api/l_physics_joints.c | 5 +- src/api/l_physics_world.c | 40 ++++---- src/modules/physics/physics.h | 14 ++- src/modules/physics/physics_jolt.c | 146 +++++++++++++---------------- src/modules/physics/physics_ode.c | 49 ++++------ 6 files changed, 111 insertions(+), 146 deletions(-) diff --git a/src/api/l_physics_collider.c b/src/api/l_physics_collider.c index 6e9eeff8..41f38756 100644 --- a/src/api/l_physics_collider.c +++ b/src/api/l_physics_collider.c @@ -86,9 +86,8 @@ static int l_lovrColliderGetJoints(lua_State* L) { Collider* collider = luax_checktype(L, 1, Collider); lua_newtable(L); int index = 1; - void* private; Joint* joint = NULL; - while ((joint = lovrColliderEnumerateJoints(collider, joint, &private)) != NULL) { + while ((joint = lovrColliderGetJoints(collider, joint)) != NULL) { luax_pushjoint(L, joint); lua_rawseti(L, -2, index++); } diff --git a/src/api/l_physics_joints.c b/src/api/l_physics_joints.c index 4e035001..768f6d42 100644 --- a/src/api/l_physics_joints.c +++ b/src/api/l_physics_joints.c @@ -56,9 +56,8 @@ static int l_lovrJointGetType(lua_State* L) { static int l_lovrJointGetColliders(lua_State* L) { Joint* joint = luax_checkjoint(L, 1); - Collider* a; - Collider* b; - lovrJointGetColliders(joint, &a, &b); + Collider* a = lovrJointGetColliderA(joint); + Collider* b = lovrJointGetColliderB(joint); luax_pushtype(L, Collider, a); luax_pushtype(L, Collider, b); return 2; diff --git a/src/api/l_physics_world.c b/src/api/l_physics_world.c index c8e5ff5c..0a23fc12 100644 --- a/src/api/l_physics_world.c +++ b/src/api/l_physics_world.c @@ -206,18 +206,6 @@ static int l_lovrWorldGetTags(lua_State* L) { return 1; } -static int l_lovrWorldGetColliders(lua_State* L) { - World* world = luax_checktype(L, 1, World); - lua_createtable(L, (int) lovrWorldGetColliderCount(world), 0); - Collider* collider = NULL; - int index = 1; - while ((collider = lovrWorldEnumerateColliders(world, collider)) != NULL) { - luax_pushtype(L, Collider, collider); - lua_rawseti(L, -2, index++); - } - return 1; -} - static int l_lovrWorldGetColliderCount(lua_State* L) { World* world = luax_checktype(L, 1, World); uint32_t count = lovrWorldGetColliderCount(world); @@ -225,22 +213,34 @@ static int l_lovrWorldGetColliderCount(lua_State* L) { return 1; } -static int l_lovrWorldGetJoints(lua_State* L) { +static int l_lovrWorldGetJointCount(lua_State* L) { + World* world = luax_checktype(L, 1, World); + uint32_t count = lovrWorldGetJointCount(world); + lua_pushinteger(L, count); + return 1; +} + +static int l_lovrWorldGetColliders(lua_State* L) { World* world = luax_checktype(L, 1, World); - lua_createtable(L, (int) lovrWorldGetJointCount(world), 0); - Joint* joint = NULL; int index = 1; - while ((joint = lovrWorldEnumerateJoints(world, joint)) != NULL) { - luax_pushjoint(L, joint); + Collider* collider = NULL; + lua_createtable(L, (int) lovrWorldGetColliderCount(world), 0); + while ((collider = lovrWorldGetColliders(world, collider)) != NULL) { + luax_pushtype(L, Collider, collider); lua_rawseti(L, -2, index++); } return 1; } -static int l_lovrWorldGetJointCount(lua_State* L) { +static int l_lovrWorldGetJoints(lua_State* L) { World* world = luax_checktype(L, 1, World); - uint32_t count = lovrWorldGetJointCount(world); - lua_pushinteger(L, count); + int index = 1; + Joint* joint = NULL; + lua_createtable(L, (int) lovrWorldGetJointCount(world), 0); + while ((joint = lovrWorldGetJoints(world, joint)) != NULL) { + luax_pushjoint(L, joint); + lua_rawseti(L, -2, index++); + } return 1; } diff --git a/src/modules/physics/physics.h b/src/modules/physics/physics.h index 417efcba..a696c3fa 100644 --- a/src/modules/physics/physics.h +++ b/src/modules/physics/physics.h @@ -55,8 +55,8 @@ void lovrWorldDestroy(void* ref); void lovrWorldDestroyData(World* world); uint32_t lovrWorldGetColliderCount(World* world); uint32_t lovrWorldGetJointCount(World* world); -Collider* lovrWorldEnumerateColliders(World* world, Collider* collider); -Joint* lovrWorldEnumerateJoints(World* world, Joint* joint); +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); @@ -96,11 +96,11 @@ bool lovrColliderIsEnabled(Collider* collider); void lovrColliderSetEnabled(Collider* collider, bool enable); void lovrColliderInitInertia(Collider* collider, Shape* shape); World* lovrColliderGetWorld(Collider* collider); +Joint* lovrColliderGetJoints(Collider* collider, Joint* joint); Shape* lovrColliderGetShape(Collider* collider, uint32_t child); void lovrColliderSetShape(Collider* collider, Shape* shape); void lovrColliderGetShapeOffset(Collider* collider, float position[3], float orientation[4]); void lovrColliderSetShapeOffset(Collider* collider, float position[3], float orientation[4]); -Joint* lovrColliderEnumerateJoints(Collider* collider, Joint* joint, void** private); const char* lovrColliderGetTag(Collider* collider); bool lovrColliderSetTag(Collider* collider, const char* tag); float lovrColliderGetFriction(Collider* collider); @@ -218,11 +218,9 @@ void lovrJointDestroy(void* ref); void lovrJointDestroyData(Joint* joint); bool lovrJointIsDestroyed(Joint* joint); JointType lovrJointGetType(Joint* joint); -float lovrJointGetCFM(Joint* joint); -void lovrJointSetCFM(Joint* joint, float cfm); -float lovrJointGetERP(Joint* joint); -void lovrJointSetERP(Joint* joint, float erp); -void lovrJointGetColliders(Joint* joint, Collider** a, Collider** b); +Collider* lovrJointGetColliderA(Joint* joint); +Collider* lovrJointGetColliderB(Joint* joint); +Joint* lovrJointGetNext(Joint* joint, Collider* collider); bool lovrJointIsEnabled(Joint* joint); void lovrJointSetEnabled(Joint* joint, bool enable); diff --git a/src/modules/physics/physics_jolt.c b/src/modules/physics/physics_jolt.c index e7916519..e8e8fb33 100644 --- a/src/modules/physics/physics_jolt.c +++ b/src/modules/physics/physics_jolt.c @@ -4,12 +4,6 @@ #include #include -typedef struct JointNode { - struct JointNode* prev; - struct JointNode* next; - Joint* joint; -} JointNode; - struct World { uint32_t ref; JPH_PhysicsSystem* system; @@ -30,10 +24,10 @@ struct Collider { JPH_BodyID id; JPH_Body* body; World* world; + Joint* joints; Shape* shape; Collider* prev; Collider* next; - JointNode* joints; uint32_t tag; }; @@ -43,14 +37,16 @@ struct Shape { JPH_Shape* shape; }; +typedef struct { + Joint* prev; + Joint* next; +} JointNode; + struct Joint { uint32_t ref; JointType type; JPH_Constraint* constraint; - JointNode a; - JointNode b; - Joint* prev; - Joint* next; + JointNode a, b, world; }; static struct { @@ -168,12 +164,12 @@ uint32_t lovrWorldGetJointCount(World* world) { return world->jointCount; // Jolt doesn't expose this } -Collider* lovrWorldEnumerateColliders(World* world, Collider* collider) { +Collider* lovrWorldGetColliders(World* world, Collider* collider) { return collider ? collider->next : world->colliders; } -Joint* lovrWorldEnumerateJoints(World* world, Joint* joint) { - return joint ? joint->next : world->joints; +Joint* lovrWorldGetJoints(World* world, Joint* joint) { + return joint ? joint->world.next : world->joints; } void lovrWorldUpdate(World* world, float dt, CollisionResolver resolver, void* userdata) { @@ -394,11 +390,12 @@ void lovrColliderDestroyData(Collider* collider) { lovrRelease(collider->shape, lovrShapeDestroy); - JointNode* node = collider->joints; - while (node) { - JointNode* next = node->next; - lovrJointDestroyData(node->joint); - node = next; + Joint* joint = collider->joints; + + while (joint) { + Joint* next = lovrJointGetNext(joint, collider); + lovrJointDestroyData(joint); + joint = next; } World* world = collider->world; @@ -439,8 +436,8 @@ World* lovrColliderGetWorld(Collider* collider) { return collider->world; } -Collider* lovrColliderGetNext(Collider* collider) { - return collider->next; +Joint* lovrColliderGetJoints(Collider* collider, Joint* joint) { + return joint ? lovrJointGetNext(joint, collider) : collider->joints; } Shape* lovrColliderGetShape(Collider* collider, uint32_t child) { @@ -514,19 +511,6 @@ void lovrColliderSetShapeOffset(Collider* collider, float position[3], float ori JPH_BodyInterface_SetShape(collider->world->bodies, collider->id, shape, updateMass, JPH_Activation_Activate); } -Joint* lovrColliderEnumerateJoints(Collider* collider, Joint* joint, void** private) { - if (!joint) { - JointNode* node = collider->joints; - *private = collider->joints; - return node ? node->joint : NULL; - } else { - JointNode* node = *private; - node = node ? node->next : NULL; - *private = node; - return node ? node->joint : NULL; - } -} - const char* lovrColliderGetTag(Collider* collider) { return lovrWorldGetTagName(collider->world, collider->tag); } @@ -1098,32 +1082,30 @@ static void lovrJointGetAnchors(Joint* joint, float anchor1[3], float anchor2[3] anchor2[2] = constraintToBody2.m43; } +static JointNode* lovrJointGetNode(Joint* joint, Collider* collider) { + return collider == lovrJointGetColliderA(joint) ? &joint->a : &joint->b; +} + void lovrJointInit(Joint* joint, Collider* a, Collider* b) { - JointNode* nodeA = &joint->a; - JointNode* nodeB = &joint->b; - - nodeA->joint = joint; - nodeB->joint = joint; - - if (a->joints) { - nodeA->next = a->joints; - a->joints->prev = nodeA; - } - - a->joints = nodeA; - - if (b->joints) { - nodeB->next = b->joints; - b->joints->prev = nodeB; - } - - b->joints = nodeB; - World* world = a->world; + if (a->joints) { + joint->a.next = a->joints; + lovrJointGetNode(a->joints, a)->prev = joint; + } + + a->joints = joint; + + if (b->joints) { + joint->b.next = b->joints; + lovrJointGetNode(b->joints, b)->prev = joint; + } + + b->joints = joint; + if (world->joints) { - joint->next = world->joints; - joint->next->prev = joint; + joint->world.next = world->joints; + world->joints->world.prev = joint; } world->joints = joint; @@ -1144,27 +1126,28 @@ void lovrJointDestroyData(Joint* joint) { JPH_TwoBodyConstraint* constraint = (JPH_TwoBodyConstraint*) joint->constraint; Collider* a = (Collider*) (uintptr_t) JPH_Body_GetUserData(JPH_TwoBodyConstraint_GetBody1(constraint)); Collider* b = (Collider*) (uintptr_t) JPH_Body_GetUserData(JPH_TwoBodyConstraint_GetBody2(constraint)); - - JointNode* nodeA = &joint->a; - if (nodeA->next) nodeA->next->prev = nodeA->prev; - if (nodeA->prev) nodeA->prev->next = nodeA->next; - if (nodeA == a->joints) a->joints = nodeA->next; - - JointNode* nodeB = &joint->b; - if (nodeB->next) nodeB->next->prev = nodeB->prev; - if (nodeB->prev) nodeB->prev->next = nodeB->next; - if (nodeB == b->joints) b->joints = nodeB->next; - World* world = a->world; - if (joint->next) joint->next->prev = joint->prev; - if (joint->prev) joint->prev->next = joint->next; - if (world->joints == joint) world->joints = joint->next; - joint->next = joint->prev = NULL; - world->jointCount--; + JointNode* node; + + node = &joint->a; + if (node->next) lovrJointGetNode(node->next, a)->prev = node->prev; + if (node->prev) lovrJointGetNode(node->prev, a)->next = node->next; + else a->joints = node->next; + + node = &joint->b; + if (node->next) lovrJointGetNode(node->next, b)->prev = node->prev; + if (node->prev) lovrJointGetNode(node->prev, b)->next = node->next; + else b->joints = node->next; + + node = &joint->world; + if (node->next) node->next->world.prev = node->prev; + if (node->prev) node->prev->world.next = node->next; + else world->joints = joint->world.next; JPH_PhysicsSystem_RemoveConstraint(world->system, joint->constraint); JPH_Constraint_Destroy(joint->constraint); joint->constraint = NULL; + world->jointCount--; lovrRelease(joint, lovrJointDestroy); } @@ -1177,17 +1160,18 @@ JointType lovrJointGetType(Joint* joint) { return joint->type; } -void lovrJointGetColliders(Joint* joint, Collider** a, Collider** b) { - JPH_Body* bodyA = JPH_TwoBodyConstraint_GetBody1((JPH_TwoBodyConstraint*) joint->constraint); - JPH_Body* bodyB = JPH_TwoBodyConstraint_GetBody2((JPH_TwoBodyConstraint*) joint->constraint); +Collider* lovrJointGetColliderA(Joint* joint) { + JPH_TwoBodyConstraint* constraint = (JPH_TwoBodyConstraint*) joint->constraint; + return (Collider*) (uintptr_t) JPH_Body_GetUserData(JPH_TwoBodyConstraint_GetBody1(constraint)); +} - if (bodyA) { - *a = (Collider*) JPH_Body_GetUserData(bodyA); - } +Collider* lovrJointGetColliderB(Joint* joint) { + JPH_TwoBodyConstraint* constraint = (JPH_TwoBodyConstraint*) joint->constraint; + return (Collider*) (uintptr_t) JPH_Body_GetUserData(JPH_TwoBodyConstraint_GetBody2(constraint)); +} - if (bodyB) { - *b = (Collider*) JPH_Body_GetUserData(bodyB); - } +Joint* lovrJointGetNext(Joint* joint, Collider* collider) { + return lovrJointGetNode(joint, collider)->next; } bool lovrJointIsEnabled(Joint* joint) { diff --git a/src/modules/physics/physics_ode.c b/src/modules/physics/physics_ode.c index 757df7c8..c44871d5 100644 --- a/src/modules/physics/physics_ode.c +++ b/src/modules/physics/physics_ode.c @@ -220,11 +220,11 @@ uint32_t lovrWorldGetJointCount(World* world) { return 0; } -Collider* lovrWorldEnumerateColliders(World* world, Collider* collider) { +Collider* lovrWorldGetColliders(World* world, Collider* collider) { return collider ? collider->next : world->head; } -Joint* lovrWorldEnumerateJoints(World* world, Joint* joint) { +Joint* lovrWorldGetJoints(World* world, Joint* joint) { return NULL; } @@ -538,10 +538,6 @@ World* lovrColliderGetWorld(Collider* collider) { return collider->world; } -Collider* lovrColliderGetNext(Collider* collider) { - return collider->next; -} - Shape* lovrColliderGetShape(Collider* collider, uint32_t child) { return collider->shape; } @@ -588,26 +584,18 @@ void lovrColliderSetShapeOffset(Collider* collider, float position[3], float ori dGeomSetOffsetQuaternion(collider->shape->id, q); } -Joint** lovrColliderGetJoints(Collider* collider, size_t* count) { - arr_clear(&collider->joints); - int jointCount = dBodyGetNumJoints(collider->body); - for (int i = 0; i < jointCount; i++) { - Joint* joint = dJointGetData(dBodyGetJoint(collider->body, i)); - if (joint) { - arr_push(&collider->joints, joint); +Joint* lovrColliderGetJoints(Collider* collider, Joint* joint) { + if (joint == NULL) { + return collider->joints.length ? NULL : collider->joints.data[0]; + } + + for (size_t i = 0; i < collider->joints.length; i++) { + if (collider->joints.data[i] == joint) { + return i == collider->joints.length - 1 ? NULL : collider->joints.data[i + 1]; } } - *count = collider->joints.length; - return collider->joints.data; -} -Joint* lovrColliderEnumerateJoints(Collider* collider, Joint* joint, void** private) { - if (!joint) { - *private = NULL; - } - - uintptr_t index = (uintptr_t) *private; - return index < collider->joints.length ? collider->joints.data[index] : NULL; + return NULL; } const char* lovrColliderGetTag(Collider* collider) { @@ -1143,17 +1131,14 @@ JointType lovrJointGetType(Joint* joint) { return joint->type; } -void lovrJointGetColliders(Joint* joint, Collider** a, Collider** b) { +Collider* lovrJointGetColliderA(Joint* joint) { dBodyID bodyA = dJointGetBody(joint->id, 0); + return bodyA ? dBodyGetData(bodyA) : NULL; +} + +Collider* lovrJointGetColliderB(Joint* joint) { dBodyID bodyB = dJointGetBody(joint->id, 1); - - if (bodyA) { - *a = dBodyGetData(bodyA); - } - - if (bodyB) { - *b = dBodyGetData(bodyB); - } + return bodyB ? dBodyGetData(bodyB) : NULL; } bool lovrJointIsEnabled(Joint* joint) {