diff --git a/src/api/l_physics_shapes.c b/src/api/l_physics_shapes.c index fbb61c4c3..703e7c927 100644 --- a/src/api/l_physics_shapes.c +++ b/src/api/l_physics_shapes.c @@ -1,6 +1,7 @@ #include "api.h" #include "physics/physics.h" #include "data/image.h" +#include "data/blob.h" #include "core/maf.h" #include "util.h" #include @@ -562,6 +563,29 @@ static int l_lovrConvexShapeGetFace(lua_State* L) { return 1; } +static int l_lovrConvexShapeGetIndices(lua_State* L) { + ConvexShape* convex = luax_checktype(L, 1, ConvexShape); + uint32_t icount, maxFaceVcount; + lovrConvexShapeGetIndicesCount(convex, &icount, &maxFaceVcount); + uint32_t size = icount * sizeof(uint16_t); + uint16_t* indices = lovrMalloc(size); + luax_assert(L, lovrConvexShapeGetIndices(convex, indices, maxFaceVcount)); + + if (lua_gettop(L) > 1 && lua_toboolean(L, 2)) { + Blob* blob = lovrBlobCreate(indices, size, "ConvexIndices"); + luax_pushtype(L, Blob, blob); + lovrRelease(blob, lovrBlobDestroy); + } else { + lua_createtable(L, (int)icount, 0); + for (uint32_t i = 0; i < icount; i++) { + lua_pushinteger(L, indices[i] + 1); + lua_rawseti(L, -2, i + 1); + } + lovrFree(indices); + } + return 1; +} + static int l_lovrConvexShapeGetScale(lua_State* L) { ConvexShape* convex = luax_checktype(L, 1, ConvexShape); float scale = lovrConvexShapeGetScale(convex); @@ -575,6 +599,7 @@ const luaL_Reg lovrConvexShape[] = { { "getPoint", l_lovrConvexShapeGetPoint }, { "getFaceCount", l_lovrConvexShapeGetFaceCount }, { "getFace", l_lovrConvexShapeGetFace }, + { "getIndices", l_lovrConvexShapeGetIndices }, { "getScale", l_lovrConvexShapeGetScale }, { NULL, NULL } }; diff --git a/src/modules/physics/physics.c b/src/modules/physics/physics.c index fea35d761..a75e79d3c 100644 --- a/src/modules/physics/physics.c +++ b/src/modules/physics/physics.c @@ -2320,6 +2320,35 @@ uint32_t lovrConvexShapeGetFace(ConvexShape* shape, uint32_t index, uint32_t* po return JPH_ConvexHullShape_GetFaceVertices(hull, index, capacity, pointIndices); } +bool lovrConvexShapeGetIndicesCount(ConvexShape* shape, uint32_t* icount, uint32_t* maxFaceVcount) { + const JPH_ConvexHullShape* hull = (const JPH_ConvexHullShape*) JPH_DecoratedShape_GetInnerShape((const JPH_DecoratedShape*) shape->handle); + *icount = 0; + *maxFaceVcount = 0; + for (int i = 0; i < JPH_ConvexHullShape_GetNumFaces(hull); i++) { + int n = JPH_ConvexHullShape_GetNumVerticesInFace(hull, i); + *maxFaceVcount = MAX(*maxFaceVcount, n); + *icount = *icount + (n - 2) * 3; + } + return true; +} + +bool lovrConvexShapeGetIndices(ConvexShape* shape, uint16_t* indices, uint32_t maxFaceVcount) { + const JPH_ConvexHullShape* hull = (const JPH_ConvexHullShape*) JPH_DecoratedShape_GetInnerShape((const JPH_DecoratedShape*) shape->handle); + uint32_t* fvs = lovrMalloc(maxFaceVcount * sizeof(uint32_t)); + uint32_t idx = 0; + for (int i = 0; i < JPH_ConvexHullShape_GetNumFaces(hull); i++) { + int n = JPH_ConvexHullShape_GetFaceVertices(hull, i, maxFaceVcount, fvs); + for (int i = 2; i < n; i++) { + indices[idx] = fvs[0]; + indices[idx + 1] = fvs[i - 1]; + indices[idx + 2] = fvs[i]; + idx += 3; + } + } + lovrFree(fvs); + return true; +} + float lovrConvexShapeGetScale(ConvexShape* shape) { JPH_Vec3 v; JPH_ScaledShape_GetScale((JPH_ScaledShape*) shape->handle, &v); diff --git a/src/modules/physics/physics.h b/src/modules/physics/physics.h index a055cf537..00455340e 100644 --- a/src/modules/physics/physics.h +++ b/src/modules/physics/physics.h @@ -260,6 +260,8 @@ uint32_t lovrConvexShapeGetPointCount(ConvexShape* shape); bool lovrConvexShapeGetPoint(ConvexShape* shape, uint32_t index, float point[3]); uint32_t lovrConvexShapeGetFaceCount(ConvexShape* shape); uint32_t lovrConvexShapeGetFace(ConvexShape* shape, uint32_t index, uint32_t* pointIndices, uint32_t capacity); +bool lovrConvexShapeGetIndicesCount(ConvexShape* shape, uint32_t* icount, uint32_t* maxFaceVcount); +bool lovrConvexShapeGetIndices(ConvexShape* shape, uint16_t* indices, uint32_t maxFaceVcount); float lovrConvexShapeGetScale(ConvexShape* shape); MeshShape* lovrMeshShapeCreate(uint32_t vertexCount, float vertices[], uint32_t indexCount, uint32_t indices[], float scale); diff --git a/test/lovr/physics.lua b/test/lovr/physics.lua index 6707383e8..4400f2123 100644 --- a/test/lovr/physics.lua +++ b/test/lovr/physics.lua @@ -98,6 +98,12 @@ group('physics', function() mesh:setIndices({ 1, 2, 3, 1, 3, 4, 1, 2, 4, 2, 3, 4 }) shape = lovr.physics.newConvexShape(mesh) expect(shape:getPointCount()).to.equal(4) + expect(shape:getIndices()).to.equal({ + 1, 2, 3, + 2, 4, 3, + 4, 1, 3, + 1, 4, 2 + }) end end)