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 4f484984..206bcf90 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 } }; @@ -178,6 +179,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 }, @@ -190,6 +198,7 @@ static const luaL_Reg lovrPhysics[] = { { "newSliderJoint", l_lovrPhysicsNewSliderJoint }, { "newSphereShape", l_lovrPhysicsNewSphereShape }, { "newTerrainShape", l_lovrPhysicsNewTerrainShape }, + { "newCompoundShape", l_lovrPhysicsNewCompoundShape }, { NULL, NULL } }; @@ -205,6 +214,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); @@ -221,6 +231,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 0614509d..497f45a9 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 827ed898..2d0f59ce 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; @@ -150,7 +151,8 @@ typedef enum { SHAPE_CAPSULE, SHAPE_CYLINDER, SHAPE_MESH, - SHAPE_TERRAIN + SHAPE_TERRAIN, + SHAPE_COMPOUND } ShapeType; void lovrShapeDestroy(void* ref); @@ -191,6 +193,9 @@ MeshShape* lovrMeshShapeCreate(int vertexCount, float vertices[], int indexCount TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t n, float scaleXZ, float scaleY); +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 @@ -198,6 +203,7 @@ TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t n, float scaleXZ, #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 23ab7849..aad06eae 100644 --- a/src/modules/physics/physics_jolt.c +++ b/src/modules/physics/physics_jolt.c @@ -751,6 +751,8 @@ void lovrColliderGetAABB(Collider* collider, float aabb[6]) { aabb[5] = box.max.z; } +// Shapes + void lovrShapeDestroy(void* ref) { Shape* shape = ref; lovrShapeDestroyData(shape); @@ -938,6 +940,34 @@ TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t n, float scaleXZ, 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);