mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-11-22 15:33:00 +00:00
convolve: fix a bunch of bugs.
It's still behaving reeaallllly strangely though
This commit is contained in:
parent
868052f945
commit
2dbbeef9c9
8 changed files with 37 additions and 19 deletions
|
@ -21,6 +21,7 @@ dofile(worldeditadditions.modpath.."/lib/walls.lua")
|
||||||
dofile(worldeditadditions.modpath.."/lib/replacemix.lua")
|
dofile(worldeditadditions.modpath.."/lib/replacemix.lua")
|
||||||
dofile(worldeditadditions.modpath.."/lib/maze2d.lua")
|
dofile(worldeditadditions.modpath.."/lib/maze2d.lua")
|
||||||
dofile(worldeditadditions.modpath.."/lib/maze3d.lua")
|
dofile(worldeditadditions.modpath.."/lib/maze3d.lua")
|
||||||
|
dofile(worldeditadditions.modpath.."/lib/conv/convolution.lua")
|
||||||
|
|
||||||
dofile(worldeditadditions.modpath.."/lib/count.lua")
|
dofile(worldeditadditions.modpath.."/lib/count.lua")
|
||||||
|
|
||||||
|
|
|
@ -66,10 +66,10 @@ function worldeditadditions.convolve(pos1, pos2, kernel, kernel_size)
|
||||||
local hi = z*heightmap_size[1] + x
|
local hi = z*heightmap_size[1] + x
|
||||||
local diff = heightmap_conv[hi] - heightmap[hi]
|
local diff = heightmap_conv[hi] - heightmap[hi]
|
||||||
|
|
||||||
|
|
||||||
-- Lua doesn't have a continue statement :-/
|
-- Lua doesn't have a continue statement :-/
|
||||||
if diff ~= 0 then
|
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
|
if diff > 0 then
|
||||||
stats.added = stats.added + diff
|
stats.added = stats.added + diff
|
||||||
for y = pos1.y + heightmap[hi], pos1.y + heightmap_conv[hi], 1 do
|
for y = pos1.y + heightmap[hi], pos1.y + heightmap_conv[hi], 1 do
|
|
@ -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[]} matrix The matrix to convolve with.
|
||||||
@param {[number, number]} matrix_size The size of the convolution matrix as [ height, width ]
|
@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
|
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)"
|
return false, "Error: The matrix size must contain only odd numbers (even number detected)"
|
||||||
end
|
end
|
||||||
|
|
||||||
local border_size = {
|
local border_size = {}
|
||||||
(matrix_size[0]-1) / 2, -- height
|
border_size[0] = (matrix_size[0]-1) / 2 -- height
|
||||||
(matrix_size[1]-1) / 2 -- width
|
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
|
-- 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 y = (heightmap_size[0]-border_size[0]) - 1, border_size[0], -1 do
|
||||||
for x = heightmap_size[1] - border_size[1], border_size[1], -1 do
|
for x = (heightmap_size[1]-border_size[1]) - 1, border_size[1], -1 do
|
||||||
local total = 0
|
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 mi = (my * matrix_size[1]) + mx
|
||||||
local cy = y + (my - border_size[0])
|
local cy = y + (my - border_size[0])
|
||||||
local cx = x + (mx - border_size[1])
|
local cx = x + (mx - border_size[1])
|
||||||
|
|
||||||
local i = (cy * heightmap_size[1]) + cx
|
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
|
||||||
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
|
||||||
end
|
end
|
||||||
|
|
|
@ -63,20 +63,23 @@ function worldeditadditions.make_heightmap(pos1, pos2, manip, area, data)
|
||||||
for x = pos1.x, pos2.x, 1 do
|
for x = pos1.x, pos2.x, 1 do
|
||||||
local found_node = false
|
local found_node = false
|
||||||
-- Scan each column top to bottom
|
-- 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)
|
local i = area:index(x, y, z)
|
||||||
if not worldeditadditions.is_airlike(data[i]) then
|
if not worldeditadditions.is_airlike(data[i]) then
|
||||||
-- It's the first non-airlike node in this column
|
-- 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
|
found_node = true
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if not found_node then heightmap[hi] = -1 end
|
if not found_node then heightmap[hi] = -1 end
|
||||||
i = i + 1
|
hi = hi + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
worldeditadditions.print_2d(heightmap, (pos2.z - pos1.z) + 1)
|
||||||
|
|
||||||
return heightmap
|
return heightmap
|
||||||
end
|
end
|
||||||
|
|
|
@ -86,9 +86,14 @@ end
|
||||||
-- @param tbl number[] The ZERO-indexed list of numbers
|
-- @param tbl number[] The ZERO-indexed list of numbers
|
||||||
-- @param width number The width of 2D array.
|
-- @param width number The width of 2D array.
|
||||||
function worldeditadditions.print_2d(tbl, width)
|
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 = {}
|
local next = {}
|
||||||
for i=0, #tbl do
|
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
|
if #next == width then
|
||||||
print(table.concat(next, "\t"))
|
print(table.concat(next, "\t"))
|
||||||
next = {}
|
next = {}
|
||||||
|
|
|
@ -25,7 +25,8 @@ worldedit.register_command("convolve", {
|
||||||
end
|
end
|
||||||
if #parts >= 2 then
|
if #parts >= 2 then
|
||||||
local parts_dimension = worldeditadditions.split(parts[2], ",%s*", false)
|
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
|
if not width then
|
||||||
return false, "Error: Invalid width (it must be a positive odd integer)."
|
return false, "Error: Invalid width (it must be a positive odd integer)."
|
||||||
end
|
end
|
||||||
|
@ -50,9 +51,10 @@ worldedit.register_command("convolve", {
|
||||||
nodes_needed = function(name)
|
nodes_needed = function(name)
|
||||||
return worldedit.volume(worldedit.pos1[name], worldedit.pos2[name])
|
return worldedit.volume(worldedit.pos1[name], worldedit.pos2[name])
|
||||||
end,
|
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()
|
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)
|
local success, kernel = worldeditadditions.get_conv_kernel(kernel_name, kernel_width, kernel_height, sigma)
|
||||||
if not success then return success, kernel end
|
if not success then return success, kernel end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue