From e87d3ac56443c8b8154d067e9bea8f9f2b17acb7 Mon Sep 17 00:00:00 2001 From: xiejiangzhi Date: Fri, 27 Dec 2024 16:42:18 +0800 Subject: [PATCH] Add getVertices to ConvexShape --- src/api/l_physics_shapes.c | 17 ++++++++++ src/modules/physics/physics.c | 59 +++++++++++++++++++++++++++++++++++ src/modules/physics/physics.h | 2 ++ test/lovr/physics.lua | 1 + 4 files changed, 79 insertions(+) diff --git a/src/api/l_physics_shapes.c b/src/api/l_physics_shapes.c index fbb61c4c3..37ce986be 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,21 @@ static int l_lovrConvexShapeGetFace(lua_State* L) { return 1; } +static int l_lovrConvexShapeGetVertices(lua_State* L) { + ConvexShape* convex = luax_checktype(L, 1, ConvexShape); + uint32_t icount, maxFaceVcount; + lovrConvexShapeGetIndicesCount(convex, &icount, &maxFaceVcount); + // pos + normal + UV + uint32_t size = icount * 8 * sizeof(float); + uint16_t* vertices = lovrMalloc(size); + luax_assert(L, lovrConvexShapeGetVertices(convex, vertices, maxFaceVcount)); + + Blob* blob = lovrBlobCreate(vertices, size, "ConvexIndices"); + luax_pushtype(L, Blob, blob); + lovrRelease(blob, lovrBlobDestroy); + return 1; +} + static int l_lovrConvexShapeGetScale(lua_State* L) { ConvexShape* convex = luax_checktype(L, 1, ConvexShape); float scale = lovrConvexShapeGetScale(convex); @@ -575,6 +591,7 @@ const luaL_Reg lovrConvexShape[] = { { "getPoint", l_lovrConvexShapeGetPoint }, { "getFaceCount", l_lovrConvexShapeGetFaceCount }, { "getFace", l_lovrConvexShapeGetFace }, + { "getVertices", l_lovrConvexShapeGetVertices }, { "getScale", l_lovrConvexShapeGetScale }, { NULL, NULL } }; diff --git a/src/modules/physics/physics.c b/src/modules/physics/physics.c index fea35d761..87771d23b 100644 --- a/src/modules/physics/physics.c +++ b/src/modules/physics/physics.c @@ -2320,6 +2320,65 @@ 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 (uint32_t i = 0; i < JPH_ConvexHullShape_GetNumFaces(hull); i++) { + uint32_t n = JPH_ConvexHullShape_GetNumVerticesInFace(hull, i); + *maxFaceVcount = MAX(*maxFaceVcount, n); + *icount = *icount + (n - 2) * 3; + } + return true; +} + +static void setVertice(float* vertice, float pos[3], float normal[3]) { + vertice[0] = pos[0]; + vertice[1] = pos[1]; + vertice[2] = pos[2]; + vertice[3] = normal[0]; + vertice[4] = normal[1]; + vertice[5] = normal[2]; + vertice[6] = 0.f; + vertice[7] = 0.f; +} + +static void calcTriangleNormal(float p1[3], float p2[3], float p3[3], float outNormal[3]) { + float tmp[3]; + vec3_init(outNormal, p2); + vec3_sub(outNormal, p1); + vec3_init(tmp, p3); + vec3_sub(tmp, p1); + vec3_cross(outNormal, tmp); + vec3_normalize(outNormal); +} + +bool lovrConvexShapeGetVertices(ConvexShape* shape, float* vertices, 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; + JPH_Vec3 v; + for (uint32_t i = 0; i < JPH_ConvexHullShape_GetNumFaces(hull); i++) { + int n = JPH_ConvexHullShape_GetFaceVertices(hull, i, maxFaceVcount, fvs); + float p0[3], p1[3], p2[3], normal[3]; + JPH_ConvexHullShape_GetPoint(hull, fvs[0], &v); + vec3_fromJolt(p0, &v); + for (int i = 2; i < n; i++) { + JPH_ConvexHullShape_GetPoint(hull, fvs[i - 1], &v); + vec3_fromJolt(p1, &v); + JPH_ConvexHullShape_GetPoint(hull, fvs[i], &v); + vec3_fromJolt(p2, &v); + calcTriangleNormal(p0, p1, p2, normal); + setVertice(vertices + idx, p0, normal); + setVertice(vertices + idx + 8, p1, normal); + setVertice(vertices + idx + 16, p2, normal); + idx += 24; + } + } + 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..1123193ce 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 lovrConvexShapeGetVertices(ConvexShape* shape, float* vertices, 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..0c32c0515 100644 --- a/test/lovr/physics.lua +++ b/test/lovr/physics.lua @@ -98,6 +98,7 @@ 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:getVertices():getSize()).to.equal(12 * 8 * 4) end end)