From 6cf9f8082e955b58db3328051b6971df92ec1d88 Mon Sep 17 00:00:00 2001 From: bjorn Date: Thu, 4 Apr 2024 13:38:41 -0700 Subject: [PATCH] CompoundShape fixes; --- src/api/l_physics_shapes.c | 27 +++++++++++---------- src/modules/physics/physics_jolt.c | 39 +++++++++++++++++++++--------- 2 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/api/l_physics_shapes.c b/src/api/l_physics_shapes.c index 8fea2311..62cc375e 100644 --- a/src/api/l_physics_shapes.c +++ b/src/api/l_physics_shapes.c @@ -158,7 +158,7 @@ Shape* luax_newcompoundshape(lua_State* L, int index) { lovrCheck(lua_istable(L, -1), "Expected table of tables for compound shape"); lua_rawgeti(L, -1, 1); - shapes[i] = luax_totype(L, -1, Shape); + shapes[i] = luax_checkshape(L, -1); lovrCheck(shapes[i], "Expected a Shape for CompoundShape entry #%d", i + 1); lua_pop(L, 1); @@ -170,10 +170,11 @@ Shape* luax_newcompoundshape(lua_State* L, int index) { lua_pop(L, 1); break; case LUA_TNUMBER: - lua_rawgeti(L, -2, index++); - lua_rawgeti(L, -3, index++); + lua_rawgeti(L, -2, index + 1); + lua_rawgeti(L, -3, index + 2); vec3_set(&positions[3 * i], luax_tofloat(L, -3), luax_tofloat(L, -2), luax_tofloat(L, -1)); lua_pop(L, 3); + index += 3; break; default: { float* v = luax_checkvector(L, -1, V_VEC3, "nil, number, or vec3"); @@ -190,9 +191,9 @@ Shape* luax_newcompoundshape(lua_State* L, int index) { lua_pop(L, 1); break; case LUA_TNUMBER: - lua_rawgeti(L, -2, index++); - lua_rawgeti(L, -3, index++); - lua_rawgeti(L, -4, index++); + lua_rawgeti(L, -2, index); + lua_rawgeti(L, -3, index); + lua_rawgeti(L, -4, index); quat_set(&orientations[4 * i], luax_tofloat(L, -4), luax_tofloat(L, -3), luax_tofloat(L, -2), luax_tofloat(L, -1)); lua_pop(L, 4); break; @@ -486,14 +487,14 @@ static int l_lovrCompoundShapeReplaceShape(lua_State* L) { static int l_lovrCompoundShapeRemoveShape(lua_State* L) { CompoundShape* shape = luax_checktype(L, 1, CompoundShape); - uint32_t index = luax_checku32(L, 2); + uint32_t index = luax_checku32(L, 2) - 1; lovrCompoundShapeRemoveShape(shape, index); return 0; } static int l_lovrCompoundShapeGetShape(lua_State* L) { CompoundShape* shape = luax_checktype(L, 1, CompoundShape); - uint32_t index = luax_checku32(L, 2); + uint32_t index = luax_checku32(L, 2) - 1; Shape* child = lovrCompoundShapeGetShape(shape, index); luax_pushshape(L, child); return 1; @@ -504,8 +505,8 @@ static int l_lovrCompoundShapeGetShapes(lua_State* L) { int count = (int) lovrCompoundShapeGetShapeCount(shape); lua_createtable(L, count, 0); for (int i = 0; i < count; i++) { - Shape* shape = lovrCompoundShapeGetShape(shape, (uint32_t) i); - luax_pushshape(L, shape); + Shape* child = lovrCompoundShapeGetShape(shape, (uint32_t) i); + luax_pushshape(L, child); lua_rawseti(L, -2, i + 1); } return 1; @@ -520,7 +521,7 @@ static int l_lovrCompoundShapeGetShapeCount(lua_State* L) { static int l_lovrCompoundShapeGetShapeOffset(lua_State* L) { CompoundShape* shape = luax_checktype(L, 1, CompoundShape); - uint32_t index = luax_checku32(L, 2); + uint32_t index = luax_checku32(L, 2) - 1; float position[3], orientation[4], angle, ax, ay, az; lovrCompoundShapeGetShapeOffset(shape, index, position, orientation); quat_getAngleAxis(orientation, &angle, &ax, &ay, &az); @@ -536,7 +537,7 @@ static int l_lovrCompoundShapeGetShapeOffset(lua_State* L) { static int l_lovrCompoundShapeSetShapeOffset(lua_State* L) { CompoundShape* shape = luax_checktype(L, 1, CompoundShape); - uint32_t index = luax_checku32(L, 2); + uint32_t index = luax_checku32(L, 2) - 1; float position[3], orientation[4]; int i = 3; i = luax_readvec3(L, i, position, NULL); @@ -553,7 +554,7 @@ const luaL_Reg lovrCompoundShape[] = { { "removeShape", l_lovrCompoundShapeRemoveShape }, { "getShape", l_lovrCompoundShapeGetShape }, { "getShapes", l_lovrCompoundShapeGetShapes }, - { "getShapeCount", l_lovrCompoundShapeGetShapes }, + { "getShapeCount", l_lovrCompoundShapeGetShapeCount }, { "getShapeOffset", l_lovrCompoundShapeGetShapeOffset }, { "setShapeOffset", l_lovrCompoundShapeSetShapeOffset }, { "__len", l_lovrCompoundShapeGetShapeCount }, // :) diff --git a/src/modules/physics/physics_jolt.c b/src/modules/physics/physics_jolt.c index cb15d79e..36b6bc89 100644 --- a/src/modules/physics/physics_jolt.c +++ b/src/modules/physics/physics_jolt.c @@ -953,23 +953,30 @@ TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t n, float scaleXZ, } CompoundShape* lovrCompoundShapeCreate(Shape** shapes, vec3 positions, quat orientations, uint32_t count, bool freeze) { + lovrCheck(!freeze || count > 0, "A frozen CompoundShape must contain at least one shape"); + CompoundShape* parent = lovrCalloc(sizeof(CompoundShape)); parent->ref = 1; parent->type = SHAPE_COMPOUND; - JPH_MutableCompoundShapeSettings* settings = JPH_MutableCompoundShapeSettings_Create(); - JPH_CompoundShapeSettings* superSettings = (JPH_CompoundShapeSettings*) settings; + JPH_CompoundShapeSettings* settings = freeze ? + (JPH_CompoundShapeSettings*) JPH_StaticCompoundShapeSettings_Create() : + (JPH_CompoundShapeSettings*) JPH_MutableCompoundShapeSettings_Create(); 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(superSettings, &position, &rotation, shapes[i]->shape, 0); + lovrCheck(shapes[i]->type != SHAPE_COMPOUND, "Currently, nesting compound shapes is not supported"); + JPH_Vec3 position = { positions[3 * i + 0], positions[3 * i + 1], positions[3 * i + 2] }; + JPH_Quat rotation = { orientations[4 * i + 0], orientations[4 * i + 1], orientations[4 * i + 2], orientations[4 * i + 3] }; + JPH_CompoundShapeSettings_AddShape2(settings, &position, &rotation, shapes[i]->shape, 0); lovrRetain(shapes[i]); } - parent->shape = (JPH_Shape*) JPH_MutableCompoundShape_Create(settings); + if (freeze) { + parent->shape = (JPH_Shape*) JPH_StaticCompoundShape_Create((JPH_StaticCompoundShapeSettings*) settings); + } else { + parent->shape = (JPH_Shape*) JPH_MutableCompoundShape_Create((JPH_MutableCompoundShapeSettings*) settings); + } + JPH_ShapeSettings_Destroy((JPH_ShapeSettings*) settings); return parent; } @@ -981,6 +988,7 @@ bool lovrCompoundShapeIsFrozen(CompoundShape* shape) { void lovrCompoundShapeAddShape(CompoundShape* shape, Shape* child, float* position, float* orientation) { lovrCheck(!lovrCompoundShapeIsFrozen(shape), "CompoundShape is frozen and can not be changed"); lovrCheck(child->type != SHAPE_COMPOUND, "Currently, nesting compound shapes is not supported"); + lovrCheck(child != shape, "Don't put a CompoundShape inside itself! lol"); JPH_Vec3 pos = { position[0], position[1], position[2] }; JPH_Quat rot = { orientation[0], orientation[1], orientation[2], orientation[3] }; JPH_MutableCompoundShape_AddShape((JPH_MutableCompoundShape*) shape->shape, &pos, &rot, child->shape, 0); @@ -990,6 +998,8 @@ void lovrCompoundShapeAddShape(CompoundShape* shape, Shape* child, float* positi void lovrCompoundShapeReplaceShape(CompoundShape* shape, uint32_t index, Shape* child, float* position, float* orientation) { lovrCheck(!lovrCompoundShapeIsFrozen(shape), "CompoundShape is frozen and can not be changed"); lovrCheck(child->type != SHAPE_COMPOUND, "Currently, nesting compound shapes is not supported"); + lovrCheck(index < lovrCompoundShapeGetShapeCount(shape), "CompoundShape has no shape at index %d", index + 1); + lovrCheck(child != shape, "Don't put a CompoundShape inside itself! lol"); JPH_Vec3 pos = { position[0], position[1], position[2] }; JPH_Quat rot = { orientation[0], orientation[1], orientation[2], orientation[3] }; JPH_MutableCompoundShape_ModifyShape2((JPH_MutableCompoundShape*) shape->shape, index, &pos, &rot, child->shape); @@ -998,15 +1008,20 @@ void lovrCompoundShapeReplaceShape(CompoundShape* shape, uint32_t index, Shape* void lovrCompoundShapeRemoveShape(CompoundShape* shape, uint32_t index) { lovrCheck(!lovrCompoundShapeIsFrozen(shape), "CompoundShape is frozen and can not be changed"); + lovrCheck(index < lovrCompoundShapeGetShapeCount(shape), "CompoundShape has no shape at index %d", index + 1); Shape* child = lovrCompoundShapeGetShape(shape, index); JPH_MutableCompoundShape_RemoveShape((JPH_MutableCompoundShape*) shape->shape, index); lovrRelease(child, lovrShapeDestroy); } Shape* lovrCompoundShapeGetShape(CompoundShape* shape, uint32_t index) { - const JPH_Shape* child; - JPH_CompoundShape_GetSubShape((JPH_CompoundShape*) shape->shape, index, &child, NULL, NULL, NULL); - return (Shape*) (uintptr_t) JPH_Shape_GetUserData(child); + if (index < lovrCompoundShapeGetShapeCount(shape)) { + const JPH_Shape* child; + JPH_CompoundShape_GetSubShape((JPH_CompoundShape*) shape->shape, index, &child, NULL, NULL, NULL); + return (Shape*) (uintptr_t) JPH_Shape_GetUserData(child); + } else { + return NULL; + } } uint32_t lovrCompoundShapeGetShapeCount(CompoundShape* shape) { @@ -1014,6 +1029,7 @@ uint32_t lovrCompoundShapeGetShapeCount(CompoundShape* shape) { } void lovrCompoundShapeGetShapeOffset(CompoundShape* shape, uint32_t index, float* position, float* orientation) { + lovrCheck(index < lovrCompoundShapeGetShapeCount(shape), "CompoundShape has no shape at index %d", index + 1); const JPH_Shape* child; JPH_Vec3 pos; JPH_Quat rot; @@ -1025,6 +1041,7 @@ void lovrCompoundShapeGetShapeOffset(CompoundShape* shape, uint32_t index, float void lovrCompoundShapeSetShapeOffset(CompoundShape* shape, uint32_t index, float* position, float* orientation) { lovrCheck(!lovrCompoundShapeIsFrozen(shape), "CompoundShape is frozen and can not be changed"); + lovrCheck(index < lovrCompoundShapeGetShapeCount(shape), "CompoundShape has no shape at index %d", index + 1); JPH_Vec3 pos = { position[0], position[1], position[2] }; JPH_Quat rot = { orientation[0], orientation[1], orientation[2], orientation[3] }; JPH_MutableCompoundShape_ModifyShape((JPH_MutableCompoundShape*) shape->shape, index, &pos, &rot);