diff --git a/src/api/l_physics_collider.c b/src/api/l_physics_collider.c index 52cd93e4..d9ba26fd 100644 --- a/src/api/l_physics_collider.c +++ b/src/api/l_physics_collider.c @@ -24,32 +24,28 @@ static int l_lovrColliderGetWorld(lua_State* L) { return 1; } -static int l_lovrColliderAddShape(lua_State* L) { +static int l_lovrColliderGetShape(lua_State* L) { Collider* collider = luax_checktype(L, 1, Collider); - Shape* shape = luax_checkshape(L, 2); - lovrColliderAddShape(collider, shape); - return 0; -} - -static int l_lovrColliderRemoveShape(lua_State* L) { - Collider* collider = luax_checktype(L, 1, Collider); - Shape* shape = luax_checkshape(L, 2); - lovrColliderRemoveShape(collider, shape); - return 0; -} - -static int l_lovrColliderGetShapes(lua_State* L) { - Collider* collider = luax_checktype(L, 1, Collider); - size_t count; - Shape** shapes = lovrColliderGetShapes(collider, &count); - lua_createtable(L, (int) count, 0); - for (size_t i = 0; i < count; i++) { - luax_pushshape(L, shapes[i]); - lua_rawseti(L, -2, (int) i + 1); + Shape* shape = lovrColliderGetShape(collider); + if (shape) { + luax_pushshape(L, shape); + } else { + lua_pushnil(L); } return 1; } +static int l_lovrColliderSetShape(lua_State* L) { + Collider* collider = luax_checktype(L, 1, Collider); + if (lua_isnoneornil(L, 2)) { + lovrColliderSetShape(collider, NULL); + } else { + Shape* shape = luax_checkshape(L, 2); + lovrColliderSetShape(collider, shape); + } + return 0; +} + static int l_lovrColliderGetJoints(lua_State* L) { Collider* collider = luax_checktype(L, 1, Collider); size_t count; @@ -563,9 +559,8 @@ const luaL_Reg lovrCollider[] = { { "destroy", l_lovrColliderDestroy }, { "isDestroyed", l_lovrColliderIsDestroyed }, { "getWorld", l_lovrColliderGetWorld }, - { "addShape", l_lovrColliderAddShape }, - { "removeShape", l_lovrColliderRemoveShape }, - { "getShapes", l_lovrColliderGetShapes }, + { "getShape", l_lovrColliderGetShape }, + { "setShape", l_lovrColliderSetShape }, { "getJoints", l_lovrColliderGetJoints }, { "getUserData", l_lovrColliderGetUserData }, { "setUserData", l_lovrColliderSetUserData }, diff --git a/src/api/l_physics_shapes.c b/src/api/l_physics_shapes.c index c5f6970e..0614509d 100644 --- a/src/api/l_physics_shapes.c +++ b/src/api/l_physics_shapes.c @@ -147,12 +147,6 @@ static int l_lovrShapeGetType(lua_State* L) { return 1; } -static int l_lovrShapeGetCollider(lua_State* L) { - Shape* shape = luax_checkshape(L, 1); - luax_pushtype(L, Collider, lovrShapeGetCollider(shape)); - return 1; -} - static int l_lovrShapeIsEnabled(lua_State* L) { Shape* shape = luax_checkshape(L, 1); lua_pushboolean(L, lovrShapeIsEnabled(shape)); @@ -214,74 +208,6 @@ static int l_lovrShapeSetUserData(lua_State* L) { return 0; } -static int l_lovrShapeGetPosition(lua_State* L) { - Shape* shape = luax_checkshape(L, 1); - float x, y, z; - lovrShapeGetPosition(shape, &x, &y, &z); - lua_pushnumber(L, x); - lua_pushnumber(L, y); - lua_pushnumber(L, z); - return 3; -} - -static int l_lovrShapeSetPosition(lua_State* L) { - Shape* shape = luax_checkshape(L, 1); - lovrCheck(lovrShapeGetCollider(shape) != NULL, "Shape must be attached to collider"); - float position[3]; - luax_readvec3(L, 2, position, NULL); - lovrShapeSetPosition(shape, position[0], position[1], position[2]); - return 0; -} - -static int l_lovrShapeGetOrientation(lua_State* L) { - Shape* shape = luax_checkshape(L, 1); - float angle, x, y, z, orientation[4]; - lovrShapeGetOrientation(shape, orientation); - quat_getAngleAxis(orientation, &angle, &x, &y, &z); - lua_pushnumber(L, angle); - lua_pushnumber(L, x); - lua_pushnumber(L, y); - lua_pushnumber(L, z); - return 4; -} - -static int l_lovrShapeSetOrientation(lua_State* L) { - Shape* shape = luax_checkshape(L, 1); - lovrCheck(lovrShapeGetCollider(shape) != NULL, "Shape must be attached to collider"); - float orientation[4]; - luax_readquat(L, 2, orientation, NULL); - lovrShapeSetOrientation(shape, orientation); - return 0; -} - -static int l_lovrShapeGetPose(lua_State* L) { - Shape* shape = luax_checkshape(L, 1); - float x, y, z; - lovrShapeGetPosition(shape, &x, &y, &z); - float angle, ax, ay, az, orientation[4]; - lovrShapeGetOrientation(shape, orientation); - quat_getAngleAxis(orientation, &angle, &ax, &ay, &az); - lua_pushnumber(L, x); - lua_pushnumber(L, y); - lua_pushnumber(L, z); - lua_pushnumber(L, angle); - lua_pushnumber(L, ax); - lua_pushnumber(L, ay); - lua_pushnumber(L, az); - return 7; -} - -static int l_lovrShapeSetPose(lua_State* L) { - Shape* shape = luax_checkshape(L, 1); - lovrCheck(lovrShapeGetCollider(shape) != NULL, "Shape must be attached to collider"); - float position[3], orientation[4]; - int index = luax_readvec3(L, 2, position, NULL); - luax_readquat(L, index, orientation, NULL); - lovrShapeSetPosition(shape, position[0], position[1], position[2]); - lovrShapeSetOrientation(shape, orientation); - return 0; -} - static int l_lovrShapeGetMass(lua_State* L) { Shape* shape = luax_checkshape(L, 1); float density = luax_checkfloat(L, 2); @@ -313,19 +239,12 @@ static int l_lovrShapeGetAABB(lua_State* L) { #define lovrShape \ { "destroy", l_lovrShapeDestroy }, \ { "getType", l_lovrShapeGetType }, \ - { "getCollider", l_lovrShapeGetCollider }, \ { "isEnabled", l_lovrShapeIsEnabled }, \ { "setEnabled", l_lovrShapeSetEnabled }, \ { "isSensor", l_lovrShapeIsSensor }, \ { "setSensor", l_lovrShapeSetSensor }, \ { "getUserData", l_lovrShapeGetUserData }, \ { "setUserData", l_lovrShapeSetUserData }, \ - { "getPosition", l_lovrShapeGetPosition }, \ - { "setPosition", l_lovrShapeSetPosition }, \ - { "getOrientation", l_lovrShapeGetOrientation }, \ - { "setOrientation", l_lovrShapeSetOrientation }, \ - { "getPose", l_lovrShapeGetPose }, \ - { "setPose", l_lovrShapeSetPose }, \ { "getMass", l_lovrShapeGetMass }, \ { "getAABB", l_lovrShapeGetAABB } diff --git a/src/api/l_physics_world.c b/src/api/l_physics_world.c index bf1a708b..e530e668 100644 --- a/src/api/l_physics_world.c +++ b/src/api/l_physics_world.c @@ -55,7 +55,7 @@ typedef struct { static bool raycastAnyCallback(Shape* shape, float x, float y, float z, float nx, float ny, float nz, void* userdata) { RaycastData* data = userdata; if (data->tag) { - const char* tag = lovrColliderGetTag(lovrShapeGetCollider(shape)); + const char* tag = NULL; // TODO if (!tag || strcmp(tag, data->tag)) { return false; } @@ -70,7 +70,7 @@ static bool raycastAnyCallback(Shape* shape, float x, float y, float z, float nx static bool raycastClosestCallback(Shape* shape, float x, float y, float z, float nx, float ny, float nz, void* userdata) { RaycastData* data = userdata; if (data->tag) { - const char* tag = lovrColliderGetTag(lovrShapeGetCollider(shape)); + const char* tag = NULL; // TODO if (!tag || strcmp(tag, data->tag)) { return false; } @@ -113,7 +113,7 @@ static int l_lovrWorldNewBoxCollider(lua_State* L) { int index = luax_readvec3(L, 2, position, NULL); Collider* collider = lovrColliderCreate(world, position[0], position[1], position[2]); BoxShape* shape = luax_newboxshape(L, index); - lovrColliderAddShape(collider, shape); + lovrColliderSetShape(collider, shape); lovrColliderInitInertia(collider, shape); luax_pushtype(L, Collider, collider); lovrRelease(collider, lovrColliderDestroy); @@ -127,7 +127,7 @@ static int l_lovrWorldNewCapsuleCollider(lua_State* L) { int index = luax_readvec3(L, 2, position, NULL); Collider* collider = lovrColliderCreate(world, position[0], position[1], position[2]); CapsuleShape* shape = luax_newcapsuleshape(L, index); - lovrColliderAddShape(collider, shape); + lovrColliderSetShape(collider, shape); lovrColliderInitInertia(collider, shape); luax_pushtype(L, Collider, collider); lovrRelease(collider, lovrColliderDestroy); @@ -141,7 +141,7 @@ static int l_lovrWorldNewCylinderCollider(lua_State* L) { int index = luax_readvec3(L, 2, position, NULL); Collider* collider = lovrColliderCreate(world, position[0], position[1], position[2]); CylinderShape* shape = luax_newcylindershape(L, index); - lovrColliderAddShape(collider, shape); + lovrColliderSetShape(collider, shape); lovrColliderInitInertia(collider, shape); luax_pushtype(L, Collider, collider); lovrRelease(collider, lovrColliderDestroy); @@ -155,7 +155,7 @@ static int l_lovrWorldNewSphereCollider(lua_State* L) { int index = luax_readvec3(L, 2, position, NULL); Collider* collider = lovrColliderCreate(world, position[0], position[1], position[2]); SphereShape* shape = luax_newsphereshape(L, index); - lovrColliderAddShape(collider, shape); + lovrColliderSetShape(collider, shape); lovrColliderInitInertia(collider, shape); luax_pushtype(L, Collider, collider); lovrRelease(collider, lovrColliderDestroy); @@ -167,7 +167,7 @@ static int l_lovrWorldNewMeshCollider(lua_State* L) { World* world = luax_checktype(L, 1, World); Collider* collider = lovrColliderCreate(world, 0.f, 0.f, 0.f); MeshShape* shape = luax_newmeshshape(L, 2); - lovrColliderAddShape(collider, shape); + lovrColliderSetShape(collider, shape); lovrColliderInitInertia(collider, shape); luax_pushtype(L, Collider, collider); lovrRelease(collider, lovrColliderDestroy); @@ -179,7 +179,7 @@ static int l_lovrWorldNewTerrainCollider(lua_State* L) { World* world = luax_checktype(L, 1, World); Collider* collider = lovrColliderCreate(world, 0.f, 0.f, 0.f); TerrainShape* shape = luax_newterrainshape(L, 2); - lovrColliderAddShape(collider, shape); + lovrColliderSetShape(collider, shape); lovrColliderSetKinematic(collider, true); luax_pushtype(L, Collider, collider); lovrRelease(collider, lovrColliderDestroy); diff --git a/src/modules/physics/physics.h b/src/modules/physics/physics.h index 0a756f75..827ed898 100644 --- a/src/modules/physics/physics.h +++ b/src/modules/physics/physics.h @@ -92,9 +92,8 @@ bool lovrColliderIsDestroyed(Collider* collider); void lovrColliderInitInertia(Collider* collider, Shape* shape); World* lovrColliderGetWorld(Collider* collider); Collider* lovrColliderGetNext(Collider* collider); -void lovrColliderAddShape(Collider* collider, Shape* shape); -void lovrColliderRemoveShape(Collider* collider, Shape* shape); -Shape** lovrColliderGetShapes(Collider* collider, size_t* count); +Shape* lovrColliderGetShape(Collider* collider); +void lovrColliderSetShape(Collider* collider, Shape* shape); Joint** lovrColliderGetJoints(Collider* collider, size_t* count); const char* lovrColliderGetTag(Collider* collider); bool lovrColliderSetTag(Collider* collider, const char* tag); @@ -157,7 +156,6 @@ typedef enum { void lovrShapeDestroy(void* ref); void lovrShapeDestroyData(Shape* shape); ShapeType lovrShapeGetType(Shape* shape); -Collider* lovrShapeGetCollider(Shape* shape); bool lovrShapeIsEnabled(Shape* shape); void lovrShapeSetEnabled(Shape* shape, bool enabled); bool lovrShapeIsSensor(Shape* shape); diff --git a/src/modules/physics/physics_jolt.c b/src/modules/physics/physics_jolt.c index 290b5d88..23ab7849 100644 --- a/src/modules/physics/physics_jolt.c +++ b/src/modules/physics/physics_jolt.c @@ -22,9 +22,9 @@ struct Collider { JPH_BodyID id; JPH_Body* body; World* world; + Shape* shape; Collider* prev; Collider* next; - arr_t(Shape*) shapes; arr_t(Joint*) joints; uint32_t tag; }; @@ -32,7 +32,6 @@ struct Collider { struct Shape { uint32_t ref; ShapeType type; - Collider* collider; JPH_Shape* shape; }; @@ -184,13 +183,13 @@ void lovrWorldRaycast(World* world, float x1, float y1, float z1, float x2, floa world->bodies, hit_array[i].bodyID); size_t count; - Shape** shape = lovrColliderGetShapes(collider, &count); + Shape* shape = lovrColliderGetShape(collider); const JPH_RVec3 position = { x, y, z }; JPH_Vec3 normal; JPH_Body_GetWorldSpaceSurfaceNormal(collider->body, hit_array[i].subShapeID2, &position, &normal); bool shouldStop = callback( - shape[0], // assumes one shape per collider; todo: compound shapes + shape, // assumes one shape per collider; todo: compound shapes x, y, z, normal.x, normal.y, normal.z, userdata); @@ -222,8 +221,8 @@ static bool lovrWorldQueryShape(World* world, JPH_Shape* shape, float position[3 world->bodies, id); size_t count; - Shape** shape = lovrColliderGetShapes(collider, &count); - bool shouldStop = callback(shape[0], userdata); + Shape* shape = lovrColliderGetShape(collider); + bool shouldStop = callback(shape, userdata); if (shouldStop) { break; } @@ -341,7 +340,6 @@ Collider* lovrColliderCreate(World* world, float x, float y, float z) { lovrColliderSetAngularDamping(collider, world->defaultAngularDamping, 0.f); lovrColliderSetSleepingAllowed(collider, world->defaultIsSleepingAllowed); - arr_init(&collider->shapes); arr_init(&collider->joints); // Adjust the world's collider list @@ -361,7 +359,6 @@ Collider* lovrColliderCreate(World* world, float x, float y, float z) { void lovrColliderDestroy(void* ref) { Collider* collider = ref; lovrColliderDestroyData(collider); - arr_free(&collider->shapes); arr_free(&collider->joints); lovrFree(collider); } @@ -371,13 +368,9 @@ void lovrColliderDestroyData(Collider* collider) { return; } + lovrRelease(collider->shape, lovrShapeDestroy); + 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); for (size_t i = 0; i < count; i++) { lovrRelease(joints[i], lovrJointDestroy); @@ -411,29 +404,24 @@ Collider* lovrColliderGetNext(Collider* collider) { return collider->next; } -void lovrColliderAddShape(Collider* collider, Shape* shape) { - lovrRetain(shape); - shape->collider = collider; - arr_push(&collider->shapes, shape); - bool isMeshOrTerrain = (shape->type == SHAPE_TERRAIN) || (shape->type == SHAPE_MESH); - bool shouldUpdateMass = !isMeshOrTerrain; - if (isMeshOrTerrain) { - lovrColliderSetKinematic(shape->collider, true); - } - JPH_BodyInterface_SetShape(collider->world->bodies, collider->id, shape->shape, shouldUpdateMass, JPH_Activation_Activate); +Shape* lovrColliderGetShape(Collider* collider) { + return collider->shape; } -void lovrColliderRemoveShape(Collider* collider, Shape* shape) { - if (shape->collider == collider) { - // todo: actions necessary for compound shapes - shape->collider = NULL; - lovrRelease(shape, lovrShapeDestroy); - } -} +void lovrColliderSetShape(Collider* collider, Shape* shape) { + if (shape != collider->shape) { + lovrRelease(collider->shape, lovrShapeDestroy); + collider->shape = shape; + lovrRetain(shape); -Shape** lovrColliderGetShapes(Collider* collider, size_t* count) { - *count = collider->shapes.length; - return collider->shapes.data; + bool updateMass = true; + if (shape->type == SHAPE_MESH || shape->type == SHAPE_TERRAIN) { + lovrColliderSetKinematic(collider, true); + updateMass = false; + } + + JPH_BodyInterface_SetShape(collider->world->bodies, collider->id, shape->shape, updateMass, JPH_Activation_Activate); + } } Joint** lovrColliderGetJoints(Collider* collider, size_t* count) { @@ -538,17 +526,15 @@ void lovrColliderSetAwake(Collider* collider, bool awake) { } float lovrColliderGetMass(Collider* collider) { - if (collider->shapes.length > 0) { - JPH_MotionProperties* motionProperties = JPH_Body_GetMotionProperties(collider->body); - return 1.f / JPH_MotionProperties_GetInverseMassUnchecked(motionProperties); - } - return 0.f; + if (!collider->shape) return 0.f; + JPH_MotionProperties* motionProperties = JPH_Body_GetMotionProperties(collider->body); + return 1.f / JPH_MotionProperties_GetInverseMassUnchecked(motionProperties); } void lovrColliderSetMass(Collider* collider, float mass) { - if (collider->shapes.length > 0) { + if (collider->shape) { JPH_MotionProperties* motionProperties = JPH_Body_GetMotionProperties(collider->body); - Shape* shape = collider->shapes.data[0]; + Shape* shape = collider->shape; JPH_MassProperties* massProperties; JPH_Shape_GetMassProperties(shape->shape, massProperties); JPH_MassProperties_ScaleToMass(massProperties, mass); @@ -782,10 +768,6 @@ ShapeType lovrShapeGetType(Shape* shape) { return shape->type; } -Collider* lovrShapeGetCollider(Shape* shape) { - return shape->collider; -} - bool lovrShapeIsEnabled(Shape* shape) { return true; } @@ -797,43 +779,19 @@ void lovrShapeSetEnabled(Shape* shape, bool enabled) { } bool lovrShapeIsSensor(Shape* shape) { - lovrLog(LOG_WARN, "PHY", "Jolt sensor property fetched from collider, not shape"); - return JPH_Body_IsSensor(shape->collider->body); + lovrThrow("NYI"); } void lovrShapeSetSensor(Shape* shape, bool sensor) { - lovrLog(LOG_WARN, "PHY", "Jolt sensor property is applied to collider, not shape"); - JPH_Body_SetIsSensor(shape->collider->body, sensor); + lovrThrow("NYI"); } -void lovrShapeGetPosition(Shape* shape, float* x, float* y, float* z) { - // todo: compound shapes - *x = 0.f; - *y = 0.f; - *z = 0.f; +void lovrShapeGetMass(Shape* shape, float density, float* cx, float* cy, float* cz, float* mass, float inertia[6]) { + // } -void lovrShapeSetPosition(Shape* shape, float x, float y, float z) { - // todo: compound shapes -} - -void lovrShapeGetOrientation(Shape* shape, float* orientation) { - // todo: compound shapes - orientation[0] = 0.f; - orientation[1] = 0.f; - orientation[2] = 0.f; - orientation[3] = 1.f; -} - -void lovrShapeSetOrientation(Shape* shape, float* orientation) { - // todo: compound shapes -} - -void lovrShapeGetMass(Shape* shape, float density, float* cx, float* cy, float* cz, float* mass, float inertia[6]) {} - void lovrShapeGetAABB(Shape* shape, float aabb[6]) { - // todo: with compound shapes this is no longer correct - lovrColliderGetAABB(shape->collider, aabb); + // TODO } SphereShape* lovrSphereShapeCreate(float radius) {