diff --git a/worldeditadditions/lib/conv/conv.lua b/worldeditadditions/lib/conv/conv.lua index 93b0dbc..9489058 100644 --- a/worldeditadditions/lib/conv/conv.lua +++ b/worldeditadditions/lib/conv/conv.lua @@ -57,13 +57,9 @@ function worldeditadditions.convolve(pos1, pos2, kernel, kernel_size) local node_id_air = minetest.get_content_id("air") - local heightmap = worldeditadditions.make_heightmap(pos1, pos2, manip, area, data) + local heightmap, heightmap_size = worldeditadditions.make_heightmap(pos1, pos2, manip, area, data) local heightmap_conv = worldeditadditions.shallowcopy(heightmap) - local heightmap_size = {} - heightmap_size[0] = (pos2.z - pos1.z) + 1 - heightmap_size[1] = (pos2.x - pos1.x) + 1 - worldeditadditions.conv.convolve( heightmap_conv, heightmap_size, diff --git a/worldeditadditions/lib/conv/convolve.lua b/worldeditadditions/lib/conv/convolve.lua index 9404bf0..bcf3e4b 100644 --- a/worldeditadditions/lib/conv/convolve.lua +++ b/worldeditadditions/lib/conv/convolve.lua @@ -18,18 +18,18 @@ function worldeditadditions.conv.convolve(heightmap, heightmap_size, matrix, mat border_size[1] = (matrix_size[1]-1) / 2 -- width -- print("[convolve] matrix_size", matrix_size[0], matrix_size[1]) -- print("[convolve] border_size", border_size[0], border_size[1]) - -- print("[convolve] heightmap_size: ", heightmap_size[0], heightmap_size[1]) + -- print("[convolve] heightmap_size: ", heightmap_size.z, heightmap_size.x) -- - -- print("[convolve] z: from", (heightmap_size[0]-border_size[0]) - 1, "to", border_size[0], "step", -1) - -- print("[convolve] x: from", (heightmap_size[1]-border_size[1]) - 1, "to", border_size[1], "step", -1) + -- print("[convolve] z: from", (heightmap_size.z-border_size[0]) - 1, "to", border_size[0], "step", -1) + -- print("[convolve] x: from", (heightmap_size.x-border_size[1]) - 1, "to", border_size[1], "step", -1) -- Convolve over only the bit that allows us to use the full convolution matrix - for z = (heightmap_size[0]-border_size[0]) - 1, border_size[0], -1 do - for x = (heightmap_size[1]-border_size[1]) - 1, border_size[1], -1 do + for z = (heightmap_size.z-border_size[0]) - 1, border_size[0], -1 do + for x = (heightmap_size.x-border_size[1]) - 1, border_size[1], -1 do local total = 0 - local hi = (z * heightmap_size[1]) + x + local hi = (z * heightmap_size.x) + x -- print("[convolve/internal] z", z, "x", x, "hi", hi) -- No continue statement in Lua :-/ @@ -40,7 +40,7 @@ function worldeditadditions.conv.convolve(heightmap, heightmap_size, matrix, mat local cz = z + (mz - border_size[0]) local cx = x + (mx - border_size[1]) - local i = (cz * heightmap_size[1]) + cx + local i = (cz * heightmap_size.x) + cx -- A value of -1 = nothing in this column (so we should ignore it) if heightmap[i] ~= -1 then diff --git a/worldeditadditions/lib/erode/erode.lua b/worldeditadditions/lib/erode/erode.lua index f85e51b..4fb5127 100644 --- a/worldeditadditions/lib/erode/erode.lua +++ b/worldeditadditions/lib/erode/erode.lua @@ -9,9 +9,10 @@ function worldeditadditions.erode.run(pos1, pos2, algorithm, params) local manip, area = worldedit.manip_helpers.init(pos1, pos2) local data = manip:get_data() - local heightmap_size = {} - heightmap_size[0] = (pos2.z - pos1.z) + 1 - heightmap_size[1] = (pos2.x - pos1.x) + 1 + local heightmap_size = { + z = (pos2.z - pos1.z) + 1, + x = (pos2.x - pos1.x) + 1 + } local region_height = (pos2.y - pos1.y) + 1 @@ -20,7 +21,7 @@ function worldeditadditions.erode.run(pos1, pos2, algorithm, params) -- print("[erode.run] algorithm: "..algorithm..", params:"); -- print(worldeditadditions.map_stringify(params)) - -- worldeditadditions.print_2d(heightmap, heightmap_size[1]) + -- worldeditadditions.print_2d(heightmap, heightmap_size.x) local success, msg, stats if algorithm == "snowballs" then success, msg = worldeditadditions.erode.snowballs(heightmap, heightmap_eroded, heightmap_size, region_height, params) diff --git a/worldeditadditions/lib/erode/snowballs.lua b/worldeditadditions/lib/erode/snowballs.lua index 7fcc646..ced0766 100644 --- a/worldeditadditions/lib/erode/snowballs.lua +++ b/worldeditadditions/lib/erode/snowballs.lua @@ -18,11 +18,11 @@ local function snowball(heightmap, normalmap, heightmap_size, startpos, params) for i = 1, params.max_steps do local x = pos.x local z = pos.z - local hi = math.floor(z+0.5)*heightmap_size[1] + math.floor(x+0.5) + local hi = math.floor(z+0.5)*heightmap_size.x + math.floor(x+0.5) -- Stop if we go out of bounds if x < 0 or z < 0 - or x >= heightmap_size[1]-1 or z >= heightmap_size[0]-1 then - -- print("[snowball] hit edge; stopping at ("..x..", "..z.."), (bounds @ "..(heightmap_size[1]-1)..", "..(heightmap_size[0]-1)..")", "x", x, "/", heightmap_size[1]-1, "z", z, "/", heightmap_size[0]-1) + or x >= heightmap_size.x-1 or z >= heightmap_size.z-1 then + -- print("[snowball] hit edge; stopping at ("..x..", "..z.."), (bounds @ "..(heightmap_size.x-1)..", "..(heightmap_size.z-1)..")", "x", x, "/", heightmap_size.x-1, "z", z, "/", heightmap_size.z-1) return true, i end @@ -100,8 +100,8 @@ function worldeditadditions.erode.snowballs(heightmap_initial, heightmap, height local success, steps = snowball( heightmap, normals, heightmap_size, { - x = math.random() * (heightmap_size[1] - 1), - z = math.random() * (heightmap_size[0] - 1) + x = math.random() * (heightmap_size.x - 1), + z = math.random() * (heightmap_size.z - 1) }, params ) diff --git a/worldeditadditions/utils/terrain.lua b/worldeditadditions/utils/terrain.lua index e54b254..4e42d94 100644 --- a/worldeditadditions/utils/terrain.lua +++ b/worldeditadditions/utils/terrain.lua @@ -7,7 +7,7 @@ -- @param manip VoxelManip The VoxelManip object. -- @param area area The associated area object. -- @param data table The associated data object. --- @return table The ZERO-indexed heightmap data (as 1 single flat array). +-- @return table,table The ZERO-indexed heightmap data (as 1 single flat array), followed by the size of the heightmap in the form { 0 = size_z, 1 = size_x }. function worldeditadditions.make_heightmap(pos1, pos2, manip, area, data) -- z y x (in reverse for little-endian machines) is the preferred loop order, but that isn't really possible here @@ -34,7 +34,12 @@ function worldeditadditions.make_heightmap(pos1, pos2, manip, area, data) end end - return heightmap + local heightmap_size = { + z = (pos2.z - pos1.z) + 1, + x = (pos2.x - pos1.x) + 1 + } + + return heightmap, heightmap_size end --- Calculates a normal map for the given heightmap. @@ -45,27 +50,27 @@ end -- @param heightmap_size int[] The size of the heightmap in the form [ z, x ] -- @return Vector[] The calculated normal map, in the same form as the input heightmap. Each element of the array is a 3D Vector (i.e. { x, y, z }) representing a normal. function worldeditadditions.calculate_normals(heightmap, heightmap_size) - -- print("heightmap_size: "..heightmap_size[1].."x"..heightmap_size[0]) + -- print("heightmap_size: "..heightmap_size.x.."x"..heightmap_size.z) local result = {} - for z = heightmap_size[0]-1, 0, -1 do - for x = heightmap_size[1]-1, 0, -1 do + for z = heightmap_size.z-1, 0, -1 do + for x = heightmap_size.x-1, 0, -1 do -- Algorithm ref https://stackoverflow.com/a/13983431/1460422 -- Also ref Vector.mjs, which I implemented myself (available upon request) - local hi = z*heightmap_size[1] + x + local hi = z*heightmap_size.x + x -- Default to this pixel's height local up = heightmap[hi] local down = heightmap[hi] local left = heightmap[hi] local right = heightmap[hi] - if z - 1 > 0 then up = heightmap[(z-1)*heightmap_size[1] + x] end - if z + 1 < heightmap_size[0]-1 then down = heightmap[(z+1)*heightmap_size[1] + x] end - if x - 1 > 0 then left = heightmap[z*heightmap_size[1] + (x-1)] end - if x + 1 < heightmap_size[1]-1 then right = heightmap[z*heightmap_size[1] + (x+1)] end + if z - 1 > 0 then up = heightmap[(z-1)*heightmap_size.x + x] end + if z + 1 < heightmap_size.z-1 then down = heightmap[(z+1)*heightmap_size.x + x] end + if x - 1 > 0 then left = heightmap[z*heightmap_size.x + (x-1)] end + if x + 1 < heightmap_size.x-1 then right = heightmap[z*heightmap_size.x + (x+1)] end - -- print("[normals] UP | index", (z-1)*heightmap_size[1] + x, "z", z, "z-1", z - 1, "up", up, "limit", 0) - -- print("[normals] DOWN | index", (z+1)*heightmap_size[1] + x, "z", z, "z+1", z + 1, "down", down, "limit", heightmap_size[1]-1) - -- print("[normals] LEFT | index", z*heightmap_size[1] + (x-1), "x", x, "x-1", x - 1, "left", left, "limit", 0) - -- print("[normals] RIGHT | index", z*heightmap_size[1] + (x+1), "x", x, "x+1", x + 1, "right", right, "limit", heightmap_size[1]-1) + -- print("[normals] UP | index", (z-1)*heightmap_size.x + x, "z", z, "z-1", z - 1, "up", up, "limit", 0) + -- print("[normals] DOWN | index", (z+1)*heightmap_size.x + x, "z", z, "z+1", z + 1, "down", down, "limit", heightmap_size.x-1) + -- print("[normals] LEFT | index", z*heightmap_size.x + (x-1), "x", x, "x-1", x - 1, "left", left, "limit", 0) + -- print("[normals] RIGHT | index", z*heightmap_size.x + (x+1), "x", x, "x+1", x + 1, "right", right, "limit", heightmap_size.x-1) result[hi] = worldeditadditions.vector.normalize({ x = left - right, @@ -84,9 +89,9 @@ function worldeditadditions.apply_heightmap_changes(pos1, pos2, area, data, heig local node_id_air = minetest.get_content_id("air") local node_id_ignore = minetest.get_content_id("ignore") - for z = heightmap_size[0], 0, -1 do - for x = heightmap_size[1], 0, -1 do - local hi = z*heightmap_size[1] + x + for z = heightmap_size.z, 0, -1 do + for x = heightmap_size.x, 0, -1 do + local hi = z*heightmap_size.x + x local height_old = heightmap_old[hi] local height_new = heightmap_new[hi]