diff --git a/worldeditadditions/init.lua b/worldeditadditions/init.lua index e00e5da..42a0d2b 100644 --- a/worldeditadditions/init.lua +++ b/worldeditadditions/init.lua @@ -21,6 +21,7 @@ dofile(worldeditadditions.modpath.."/lib/walls.lua") dofile(worldeditadditions.modpath.."/lib/replacemix.lua") dofile(worldeditadditions.modpath.."/lib/maze2d.lua") dofile(worldeditadditions.modpath.."/lib/maze3d.lua") +dofile(worldeditadditions.modpath.."/lib/conv/convolution.lua") dofile(worldeditadditions.modpath.."/lib/count.lua") diff --git a/worldeditadditions/lib/convolution/convolution.lua b/worldeditadditions/lib/conv/convolution.lua similarity index 93% rename from worldeditadditions/lib/convolution/convolution.lua rename to worldeditadditions/lib/conv/convolution.lua index 9e21276..a31065a 100644 --- a/worldeditadditions/lib/convolution/convolution.lua +++ b/worldeditadditions/lib/conv/convolution.lua @@ -66,10 +66,10 @@ function worldeditadditions.convolve(pos1, pos2, kernel, kernel_size) local hi = z*heightmap_size[1] + x local diff = heightmap_conv[hi] - heightmap[hi] - -- Lua doesn't have a continue statement :-/ if diff ~= 0 then - local node_id = data[area:index(pos1.x + x, pos1.y + heightmap[hi], pos1.z + z)] + -- We subtract one because the heightmap starts at 1 (i.e. 1 = 1 node in the column), but the selected region is inclusive + local node_id = data[area:index(pos1.x + x, pos1.y + (heightmap[hi] - 1), pos1.z + z)] if diff > 0 then stats.added = stats.added + diff for y = pos1.y + heightmap[hi], pos1.y + heightmap_conv[hi], 1 do diff --git a/worldeditadditions/lib/convolution/convolve.lua b/worldeditadditions/lib/conv/convolve.lua similarity index 50% rename from worldeditadditions/lib/convolution/convolve.lua rename to worldeditadditions/lib/conv/convolve.lua index c5d1c71..3e6243c 100644 --- a/worldeditadditions/lib/convolution/convolve.lua +++ b/worldeditadditions/lib/conv/convolve.lua @@ -8,34 +8,41 @@ Note also that the dimensions of the matrix must *only* be odd. @param {number[]} matrix The matrix to convolve with. @param {[number, number]} matrix_size The size of the convolution matrix as [ height, width ] ]]-- -function worldeditadditions.conv.convole(heightmap, heightmap_size, matrix, matrix_size) +function worldeditadditions.conv.convolve(heightmap, heightmap_size, matrix, matrix_size) if matrix_size[0] % 2 ~= 1 or matrix_size[1] % 2 ~= 1 then return false, "Error: The matrix size must contain only odd numbers (even number detected)" end - local border_size = { - (matrix_size[0]-1) / 2, -- height - (matrix_size[1]-1) / 2 -- width - } + local border_size = {} + border_size[0] = (matrix_size[0]-1) / 2 -- height + 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]) -- Convolve over only the bit that allows us to use the full convolution matrix - for y = heightmap_size[0] - border_size[0], border_size[0], -1 do - for x = heightmap_size[1] - border_size[1], border_size[1], -1 do + for y = (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 local total = 0 - for my = matrix_size[0], 0, -1 do - for mx = matrix_size[1], 0, -1 do + + for my = matrix_size[0]-1, 0, -1 do + for mx = matrix_size[1]-1, 0, -1 do local mi = (my * matrix_size[1]) + mx local cy = y + (my - border_size[0]) local cx = x + (mx - border_size[1]) local i = (cy * heightmap_size[1]) + cx - total = total + matrix[mi] * heightmap[i] + -- print("[convolve] i", i, "mi", mi, "matrix[mi]", matrix[mi], "heightmap[i]", heightmap[i]) + -- A value of -1 = nothing in this column (so we should ignore it) + if heightmap[i] ~= -1 then + total = total + (matrix[mi] * heightmap[i]) + end end end - heightmap[(y * heightmap_size[1]) + x] = total + -- Rounding hack - ref https://stackoverflow.com/a/18313481/1460422 + heightmap[(y * heightmap_size[1]) + x] = math.floor(total + 0.5) end end diff --git a/worldeditadditions/lib/convolution/kernel_gaussian.lua b/worldeditadditions/lib/conv/kernel_gaussian.lua similarity index 100% rename from worldeditadditions/lib/convolution/kernel_gaussian.lua rename to worldeditadditions/lib/conv/kernel_gaussian.lua diff --git a/worldeditadditions/lib/convolution/kernels.lua b/worldeditadditions/lib/conv/kernels.lua similarity index 100% rename from worldeditadditions/lib/convolution/kernels.lua rename to worldeditadditions/lib/conv/kernels.lua diff --git a/worldeditadditions/utils/nodes.lua b/worldeditadditions/utils/nodes.lua index 3677fe4..1e144a2 100644 --- a/worldeditadditions/utils/nodes.lua +++ b/worldeditadditions/utils/nodes.lua @@ -63,20 +63,23 @@ function worldeditadditions.make_heightmap(pos1, pos2, manip, area, data) for x = pos1.x, pos2.x, 1 do local found_node = false -- Scan each column top to bottom - for y = pos2.y, pos1.y, -1 do + for y = pos2.y+1, pos1.y, -1 do local i = area:index(x, y, z) if not worldeditadditions.is_airlike(data[i]) then -- It's the first non-airlike node in this column - heightmap[hi] = pos1.y - y + -- Start heightmap values from 1 (i.e. there's at least 1 node in the column) + heightmap[hi] = (y - pos1.y) + 1 found_node = true break end end if not found_node then heightmap[hi] = -1 end - i = i + 1 + hi = hi + 1 end end + worldeditadditions.print_2d(heightmap, (pos2.z - pos1.z) + 1) + return heightmap end diff --git a/worldeditadditions/utils/strings.lua b/worldeditadditions/utils/strings.lua index 5086624..13bfce8 100644 --- a/worldeditadditions/utils/strings.lua +++ b/worldeditadditions/utils/strings.lua @@ -86,9 +86,14 @@ end -- @param tbl number[] The ZERO-indexed list of numbers -- @param width number The width of 2D array. function worldeditadditions.print_2d(tbl, width) + local display_width = 1 + for _i,value in pairs(tbl) do + display_width = math.max(display_width, #tostring(value)) + end + display_width = display_width + 2 local next = {} for i=0, #tbl do - table.insert(next, tbl[i]) + table.insert(next, worldeditadditions.str_padstart(tostring(tbl[i]), display_width)) if #next == width then print(table.concat(next, "\t")) next = {} diff --git a/worldeditadditions_commands/commands/convolve.lua b/worldeditadditions_commands/commands/convolve.lua index 7966143..c05c852 100644 --- a/worldeditadditions_commands/commands/convolve.lua +++ b/worldeditadditions_commands/commands/convolve.lua @@ -25,7 +25,8 @@ worldedit.register_command("convolve", { end if #parts >= 2 then local parts_dimension = worldeditadditions.split(parts[2], ",%s*", false) - width = tonumber(parts[1]) + print("[convolve] [str]width", parts_dimension[1], "[str]height", parts_dimension[2]) + width = tonumber(parts_dimension[1]) if not width then return false, "Error: Invalid width (it must be a positive odd integer)." end @@ -50,9 +51,10 @@ worldedit.register_command("convolve", { nodes_needed = function(name) return worldedit.volume(worldedit.pos1[name], worldedit.pos2[name]) end, - func = function(kernel_name, kernel_width, kernel_height, sigma) + func = function(name, kernel_name, kernel_width, kernel_height, sigma) local start_time = os.clock() + print("[exec] kernel_width", kernel_width, "kernel_height", kernel_height) local success, kernel = worldeditadditions.get_conv_kernel(kernel_name, kernel_width, kernel_height, sigma) if not success then return success, kernel end