diff --git a/src/api/l_physics_shapes.c b/src/api/l_physics_shapes.c index 015d221b..c5f6970e 100644 --- a/src/api/l_physics_shapes.c +++ b/src/api/l_physics_shapes.c @@ -91,17 +91,17 @@ Shape* luax_newmeshshape(lua_State* L, int index) { } Shape* luax_newterrainshape(lua_State* L, int index) { - float horizontalScale = luax_checkfloat(L, index++); + float scaleXZ = luax_checkfloat(L, index++); int type = lua_type(L, index); if (type == LUA_TNIL || type == LUA_TNONE) { float vertices[4] = { 0.f }; - return lovrTerrainShapeCreate(vertices, 2, 2, horizontalScale, 1.f); + return lovrTerrainShapeCreate(vertices, 2, scaleXZ, 1.f); } else if (type == LUA_TFUNCTION) { - uint32_t samples = luax_optu32(L, index + 1, 100); - float* vertices = lovrMalloc(sizeof(float) * samples * samples); - for (uint32_t i = 0; i < samples * samples; i++) { - float x = horizontalScale * (-.5f + ((float) (i % samples)) / samples); - float z = horizontalScale * (-.5f + ((float) (i / samples)) / samples); + uint32_t n = luax_optu32(L, index + 1, 100); + float* vertices = lovrMalloc(sizeof(float) * n * n); + for (uint32_t i = 0; i < n * n; i++) { + float x = scaleXZ * (-.5f + ((float) (i % n)) / n); + float z = scaleXZ * (-.5f + ((float) (i / n)) / n); lua_pushvalue(L, index); lua_pushnumber(L, x); lua_pushnumber(L, z); @@ -110,23 +110,23 @@ Shape* luax_newterrainshape(lua_State* L, int index) { vertices[i] = luax_tofloat(L, -1); lua_pop(L, 1); } - TerrainShape* shape = lovrTerrainShapeCreate(vertices, samples, samples, horizontalScale, 1.f); + TerrainShape* shape = lovrTerrainShapeCreate(vertices, n, scaleXZ, 1.f); lovrFree(vertices); return shape; } else if (type == LUA_TUSERDATA) { Image* image = luax_checktype(L, index, Image); - uint32_t imageWidth = lovrImageGetWidth(image, 0); - uint32_t imageHeight = lovrImageGetHeight(image, 0); - float verticalScale = luax_optfloat(L, index + 1, 1.f); - float* vertices = lovrMalloc(sizeof(float) * imageWidth * imageHeight); - for (uint32_t y = 0; y < imageHeight; y++) { - for (uint32_t x = 0; x < imageWidth; x++) { + uint32_t n = lovrImageGetWidth(image, 0); + lovrCheck(lovrImageGetHeight(image, 0) == n, "TerrainShape images must be square"); + float scaleY = luax_optfloat(L, index + 1, 1.f); + float* vertices = lovrMalloc(sizeof(float) * n * n); + for (uint32_t y = 0; y < n; y++) { + for (uint32_t x = 0; x < n; x++) { float pixel[4]; lovrImageGetPixel(image, x, y, pixel); - vertices[x + y * imageWidth] = pixel[0]; + vertices[x + y * n] = pixel[0]; } } - TerrainShape* shape = lovrTerrainShapeCreate(vertices, imageWidth, imageHeight, horizontalScale, verticalScale); + TerrainShape* shape = lovrTerrainShapeCreate(vertices, n, scaleXZ, scaleY); lovrFree(vertices); return shape; } else { diff --git a/src/modules/physics/physics.h b/src/modules/physics/physics.h index 4f298581..0a756f75 100644 --- a/src/modules/physics/physics.h +++ b/src/modules/physics/physics.h @@ -191,7 +191,7 @@ void lovrCylinderShapeSetLength(CylinderShape* cylinder, float length); MeshShape* lovrMeshShapeCreate(int vertexCount, float vertices[], int indexCount, uint32_t indices[]); -TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t widthSamples, uint32_t depthSamples, float horizontalScale, float verticalScale); +TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t n, float scaleXZ, float scaleY); // These tokens need to exist for Lua bindings #define lovrSphereShapeDestroy lovrShapeDestroy diff --git a/src/modules/physics/physics_jolt.c b/src/modules/physics/physics_jolt.c index e8bb6d1f..2662f375 100644 --- a/src/modules/physics/physics_jolt.c +++ b/src/modules/physics/physics_jolt.c @@ -956,24 +956,22 @@ MeshShape* lovrMeshShapeCreate(int vertexCount, float vertices[], int indexCount return mesh; } -TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t widthSamples, uint32_t depthSamples, float horizontalScale, float verticalScale) { - lovrCheck(widthSamples == depthSamples, "Jolt needs terrain width and depth to be the same"); +TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t n, float scaleXZ, float scaleY) { TerrainShape* terrain = lovrCalloc(sizeof(TerrainShape)); terrain->ref = 1; terrain->type = SHAPE_TERRAIN; const JPH_Vec3 offset = { - .x = -.5f * horizontalScale, + .x = -.5f * scaleXZ, .y = 0.f, - .z = -.5f * horizontalScale + .z = -.5f * scaleXZ }; const JPH_Vec3 scale = { - .x = horizontalScale / widthSamples, - .y = verticalScale, - .z = horizontalScale / depthSamples + .x = scaleXZ / n, + .y = scaleY, + .z = scaleXZ / n }; - JPH_HeightFieldShapeSettings* shape_settings = JPH_HeightFieldShapeSettings_Create( - vertices, &offset, &scale, widthSamples); + JPH_HeightFieldShapeSettings* shape_settings = JPH_HeightFieldShapeSettings_Create(vertices, &offset, &scale, n); terrain->shape = (JPH_Shape*) JPH_HeightFieldShapeSettings_CreateShape(shape_settings); JPH_ShapeSettings_Destroy((JPH_ShapeSettings*) shape_settings); return terrain; diff --git a/src/modules/physics/physics_ode.c b/src/modules/physics/physics_ode.c index 342bffed..f3124ba2 100644 --- a/src/modules/physics/physics_ode.c +++ b/src/modules/physics/physics_ode.c @@ -1119,13 +1119,12 @@ MeshShape* lovrMeshShapeCreate(int vertexCount, float* vertices, int indexCount, return mesh; } -TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t widthSamples, uint32_t depthSamples, float horizontalScale, float verticalScale) { +TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t n, float scaleXZ, float scaleY) { const float thickness = 10.f; TerrainShape* terrain = lovrCalloc(sizeof(TerrainShape)); terrain->ref = 1; dHeightfieldDataID dataID = dGeomHeightfieldDataCreate(); - dGeomHeightfieldDataBuildSingle(dataID, vertices, 1, horizontalScale, horizontalScale, - widthSamples, depthSamples, verticalScale, 0.f, thickness, 0); + dGeomHeightfieldDataBuildSingle(dataID, vertices, 1, scaleXZ, scaleXZ, n, n, scaleY, 0.f, thickness, 0); terrain->id = dCreateHeightfield(0, dataID, 1); terrain->type = SHAPE_TERRAIN; dGeomSetData(terrain->id, terrain);