diff --git a/src/api/api.h b/src/api/api.h index 527f4a6d..5593edf2 100644 --- a/src/api/api.h +++ b/src/api/api.h @@ -203,4 +203,5 @@ struct Shape* luax_newcapsuleshape(lua_State* L, int index); struct Shape* luax_newcylindershape(lua_State* L, int index); struct Shape* luax_newmeshshape(lua_State* L, int index); struct Shape* luax_newterrainshape(lua_State* L, int index); +struct Shape* luax_newcompoundshape(lua_State* L, int index); #endif diff --git a/src/api/l_physics.c b/src/api/l_physics.c index 8b2edc5f..0b986b6c 100644 --- a/src/api/l_physics.c +++ b/src/api/l_physics.c @@ -9,6 +9,7 @@ StringEntry lovrShapeType[] = { [SHAPE_CYLINDER] = ENTRY("cylinder"), [SHAPE_MESH] = ENTRY("mesh"), [SHAPE_TERRAIN] = ENTRY("terrain"), + [SHAPE_COMPOUND] = ENTRY("compound"), { 0 } }; @@ -136,6 +137,13 @@ static int l_lovrPhysicsNewTerrainShape(lua_State* L) { return 1; } +static int l_lovrPhysicsNewCompoundShape(lua_State* L) { + CompoundShape* shape = luax_newcompoundshape(L, 1); + luax_pushtype(L, CompoundShape, shape); + lovrRelease(shape, lovrShapeDestroy); + return 1; +} + static const luaL_Reg lovrPhysics[] = { { "newWorld", l_lovrPhysicsNewWorld }, { "newBallJoint", l_lovrPhysicsNewBallJoint }, @@ -148,6 +156,7 @@ static const luaL_Reg lovrPhysics[] = { { "newSliderJoint", l_lovrPhysicsNewSliderJoint }, { "newSphereShape", l_lovrPhysicsNewSphereShape }, { "newTerrainShape", l_lovrPhysicsNewTerrainShape }, + { "newCompoundShape", l_lovrPhysicsNewCompoundShape }, { NULL, NULL } }; @@ -163,6 +172,7 @@ extern const luaL_Reg lovrCapsuleShape[]; extern const luaL_Reg lovrCylinderShape[]; extern const luaL_Reg lovrMeshShape[]; extern const luaL_Reg lovrTerrainShape[]; +extern const luaL_Reg lovrCompoundShape[]; int luaopen_lovr_physics(lua_State* L) { lua_newtable(L); @@ -179,6 +189,7 @@ int luaopen_lovr_physics(lua_State* L) { luax_registertype(L, CylinderShape); luax_registertype(L, MeshShape); luax_registertype(L, TerrainShape); + luax_registertype(L, CompoundShape); lovrPhysicsInit(); luax_atexit(L, lovrPhysicsDestroy); return 1; diff --git a/src/api/l_physics_shapes.c b/src/api/l_physics_shapes.c index 586765b6..46eb5fa7 100644 --- a/src/api/l_physics_shapes.c +++ b/src/api/l_physics_shapes.c @@ -14,6 +14,7 @@ void luax_pushshape(lua_State* L, Shape* shape) { case SHAPE_CYLINDER: luax_pushtype(L, CylinderShape, shape); break; case SHAPE_MESH: luax_pushtype(L, MeshShape, shape); break; case SHAPE_TERRAIN: luax_pushtype(L, TerrainShape, shape); break; + case SHAPE_COMPOUND: luax_pushtype(L, CompoundShape, shape); break; default: lovrUnreachable(); } } @@ -28,7 +29,8 @@ Shape* luax_checkshape(lua_State* L, int index) { hash64("CapsuleShape", strlen("CapsuleShape")), hash64("CylinderShape", strlen("CylinderShape")), hash64("MeshShape", strlen("MeshShape")), - hash64("TerrainShape", strlen("TerrainShape")) + hash64("TerrainShape", strlen("TerrainShape")), + hash64("CompoundShape", strlen("CompoundShape")) }; for (size_t i = 0; i < COUNTOF(hashes); i++) { @@ -135,6 +137,10 @@ Shape* luax_newterrainshape(lua_State* L, int index) { } } +Shape* luax_newcompoundshape(lua_State* L, int index) { + return NULL; // TODO +} + static int l_lovrShapeDestroy(lua_State* L) { Shape* shape = luax_checkshape(L, 1); lovrShapeDestroyData(shape); @@ -372,3 +378,16 @@ const luaL_Reg lovrTerrainShape[] = { lovrShape, { NULL, NULL } }; + +static int l_lovrCompoundShapeGetShapeCount(lua_State* L) { + CompoundShape* shape = luax_checktype(L, 1, CompoundShape); + uint32_t count = lovrCompoundShapeGetShapeCount(shape); + lua_pushinteger(L, count); + return 1; +} + +const luaL_Reg lovrCompoundShape[] = { + lovrShape, + { "getShapeCount", l_lovrCompoundShapeGetShapeCount }, + { NULL, NULL } +}; diff --git a/src/modules/physics/physics.h b/src/modules/physics/physics.h index 08118f02..9bf490f5 100644 --- a/src/modules/physics/physics.h +++ b/src/modules/physics/physics.h @@ -19,6 +19,7 @@ typedef Shape CapsuleShape; typedef Shape CylinderShape; typedef Shape MeshShape; typedef Shape TerrainShape; +typedef Shape CompoundShape; typedef Joint BallJoint; typedef Joint DistanceJoint; @@ -133,7 +134,8 @@ typedef enum { SHAPE_CAPSULE, SHAPE_CYLINDER, SHAPE_MESH, - SHAPE_TERRAIN + SHAPE_TERRAIN, + SHAPE_COMPOUND } ShapeType; void lovrShapeDestroy(void* ref); @@ -174,6 +176,9 @@ MeshShape* lovrMeshShapeCreate(int vertexCount, float vertices[], int indexCount TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t widthSamples, uint32_t depthSamples, float horizontalScale, float verticalScale); +CompoundShape* lovrCompoundShapeCreate(Shape** shapes, float* positions, float* orientations, uint32_t count); +uint32_t lovrCompoundShapeGetShapeCount(CompoundShape* shape); + // These tokens need to exist for Lua bindings #define lovrSphereShapeDestroy lovrShapeDestroy #define lovrBoxShapeDestroy lovrShapeDestroy @@ -181,6 +186,7 @@ TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t widthSamples, uin #define lovrCylinderShapeDestroy lovrShapeDestroy #define lovrMeshShapeDestroy lovrShapeDestroy #define lovrTerrainShapeDestroy lovrShapeDestroy +#define lovrCompoundShapeDestroy lovrShapeDestroy // Joints diff --git a/src/modules/physics/physics_jolt.c b/src/modules/physics/physics_jolt.c index 8ebb9de1..a4407b45 100644 --- a/src/modules/physics/physics_jolt.c +++ b/src/modules/physics/physics_jolt.c @@ -777,6 +777,8 @@ void lovrColliderGetAABB(Collider* collider, float aabb[6]) { aabb[5] = box.max.z; } +// Shapes + void lovrShapeDestroy(void* ref) { Shape* shape = ref; lovrShapeDestroyData(shape); @@ -970,6 +972,34 @@ TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t widthSamples, uin return terrain; } +CompoundShape* lovrCompoundShapeCreate(Shape** shapes, vec3 positions, quat orientations, uint32_t count) { + CompoundShape* parent = lovrCalloc(sizeof(CompoundShape)); + parent->ref = 1; + parent->type = SHAPE_COMPOUND; + + JPH_MutableCompoundShapeSettings* settings = JPH_MutableCompoundShapeSettings_Create(); + JPH_CompoundShapeSettings* settingsSuper = (JPH_CompoundShapeSettings*) settings; + + for (uint32_t i = 0; i < count; i++) { + JPH_Vec3 position; + JPH_Quat rotation; + vec3_init(&position.x, positions + 3 * i); + quat_init(&rotation.x, orientations + 3 * i); + JPH_CompoundShapeSettings_AddShape2(settingsSuper, &position, &rotation, shapes[i]->shape, 0); + lovrRetain(shapes[i]); + } + + parent->shape = (JPH_Shape*) JPH_MutableCompoundShape_Create(settings); + JPH_ShapeSettings_Destroy((JPH_ShapeSettings*) settings); + return parent; +} + +uint32_t lovrCompoundShapeGetShapeCount(CompoundShape* shape) { + return JPH_CompoundShape_GetNumSubShapes((JPH_CompoundShape*) shape->shape); +} + +// Joints + void lovrJointGetAnchors(Joint* joint, float anchor1[3], float anchor2[3]) { JPH_Body* body1 = JPH_TwoBodyConstraint_GetBody1((JPH_TwoBodyConstraint*) joint->constraint); JPH_Body* body2 = JPH_TwoBodyConstraint_GetBody2((JPH_TwoBodyConstraint*) joint->constraint);