From 46c2a02adeda4f27b39df707fa043f71bcc192d8 Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Mon, 12 Jul 2021 02:45:32 +0100 Subject: [PATCH] //noise2d: add white algorithm; fix nasty bug in apply_2d --- worldeditadditions/lib/noise/apply_2d.lua | 15 +++++++++-- worldeditadditions/lib/noise/engines/init.lua | 5 ++-- worldeditadditions/lib/noise/engines/sin.lua | 1 - .../lib/noise/engines/white.lua | 27 +++++++++++++++++++ worldeditadditions/lib/noise/make_2d.lua | 19 ++++++++++--- .../lib/noise/params_apply_default.lua | 11 +++++--- .../commands/noise2d.lua | 6 ++--- 7 files changed, 67 insertions(+), 17 deletions(-) create mode 100644 worldeditadditions/lib/noise/engines/white.lua diff --git a/worldeditadditions/lib/noise/apply_2d.lua b/worldeditadditions/lib/noise/apply_2d.lua index 4ac888a..d0cd7eb 100644 --- a/worldeditadditions/lib/noise/apply_2d.lua +++ b/worldeditadditions/lib/noise/apply_2d.lua @@ -16,11 +16,13 @@ function worldeditadditions.noise.apply_2d(heightmap, noise, heightmap_size, pos local region_height = pos2.y - pos1.y - -- print("NOISE\n") - -- worldeditadditions.format.array_2d(noise, heightmap_size.x) + + print("NOISE APPLY_2D\n") + worldeditadditions.format.array_2d(noise, heightmap_size.x) local height = tonumber(apply_mode) + print("DEBUG apply_mode", apply_mode, "as height", height) for z = heightmap_size.z - 1, 0, -1 do for x = heightmap_size.x - 1, 0, -1 do @@ -46,5 +48,14 @@ function worldeditadditions.noise.apply_2d(heightmap, noise, heightmap_size, pos end end + -- for z = heightmap_size.z - 1, 0, -1 do + -- x = 0 + -- heightmap[(z * heightmap_size.x) + x] = z + -- end + + print("HEIGHTMAP\n") + worldeditadditions.format.array_2d(heightmap, heightmap_size.x) + + return true end diff --git a/worldeditadditions/lib/noise/engines/init.lua b/worldeditadditions/lib/noise/engines/init.lua index 198b11e..921117e 100644 --- a/worldeditadditions/lib/noise/engines/init.lua +++ b/worldeditadditions/lib/noise/engines/init.lua @@ -2,8 +2,9 @@ local wea = worldeditadditions return { + available = { "perlin", "sin", "white" }, Perlin = dofile(wea.modpath.."/lib/noise/engines/perlin.lua"), - Sin = dofile(wea.modpath.."/lib/noise/engines/sin.lua") - + Sin = dofile(wea.modpath.."/lib/noise/engines/sin.lua"), + White = dofile(wea.modpath.."/lib/noise/engines/white.lua") -- TODO: Follow https://www.redblobgames.com/articles/noise/introduction.html and implement different colours of noise (*especially* red and pink noise) } diff --git a/worldeditadditions/lib/noise/engines/sin.lua b/worldeditadditions/lib/noise/engines/sin.lua index ea7c7d4..1db6b7e 100644 --- a/worldeditadditions/lib/noise/engines/sin.lua +++ b/worldeditadditions/lib/noise/engines/sin.lua @@ -16,7 +16,6 @@ function Sin:noise( x, y, z ) local value = (math.sin(x) + math.sin(y) + math.sin(z)) / 3 -- Rescale from -1 - +1 to 0 - 1 return (value + 1) / 2 - -- return ( end return Sin diff --git a/worldeditadditions/lib/noise/engines/white.lua b/worldeditadditions/lib/noise/engines/white.lua new file mode 100644 index 0000000..773fd12 --- /dev/null +++ b/worldeditadditions/lib/noise/engines/white.lua @@ -0,0 +1,27 @@ +local wea = worldeditadditions + + +local White = {} +White.__index = White + + +function White.new(seed) + local result = { + seed = seed or math.random() + } + setmetatable(result, White) + return result +end + +function White:noise( x, y, z ) + if x == 0 then x = 1 end + if y == 0 then y = 1 end + if z == 0 then z = 1 end + local seed = ((self.seed + (x * y * z)) * 1506359) % 1113883 + + math.randomseed(seed) + local value = math.random() + return value +end + +return White diff --git a/worldeditadditions/lib/noise/make_2d.lua b/worldeditadditions/lib/noise/make_2d.lua index 9d07570..d05db9d 100644 --- a/worldeditadditions/lib/noise/make_2d.lua +++ b/worldeditadditions/lib/noise/make_2d.lua @@ -13,18 +13,20 @@ local wea = worldeditadditions function worldeditadditions.noise.make_2d(size, start_pos, params) local result = {} - for i, layer in ipairs(params) do + for layer_i, layer in ipairs(params) do local generator if layer.algorithm == "perlin" then generator = wea.noise.engines.Perlin.new() elseif layer.algorithm == "sin" then generator = wea.noise.engines.Sin.new() + elseif layer.algorithm == "white" then + generator = wea.noise.engines.White.new() else -- We don't have any other generators just yet - return false, "Error: Unknown noise algorithm '"..tostring(layer.algorithm).."' in layer "..i.." of "..#params.." (available algorithms: perlin)." + return false, "Error: Unknown noise algorithm '"..tostring(layer.algorithm).."' in layer "..layer_i.." of "..#params.." (available algorithms: "..table.concat(wea.noise.engines.available, ", ")..")." end - for x = 0, size.x do - for y = 0, size.z do + for x = 0, size.x - 1 do + for y = 0, size.z - 1 do local i = y*size.x + x local noise_x = (x + 100000+start_pos.x+layer.offset.x) * layer.scale.x @@ -32,12 +34,21 @@ function worldeditadditions.noise.make_2d(size, start_pos, params) local noise_value = generator:noise(noise_x, noise_y, 0) if type(result[i]) ~= "number" then result[i] = 0 end + local result_before = result[i] result[i] = result[i] + (noise_value ^ layer.exponent) * layer.multiply + layer.add + -- if layer_i == 1 and result[i] > 1 then + -- print("NOISE TOO BIG noise_value", noise_value, "noise_x", noise_x, "noise_y", noise_y, "i", i, "result[i]: BEFORE", result_before, "AFTER", result[i]) + -- end end end end + + print("NOISE MAKE_2D\n") + worldeditadditions.format.array_2d(result, size.x) + + -- We don't round here, because otherwise when we apply it it'll be inaccurate return true, result diff --git a/worldeditadditions/lib/noise/params_apply_default.lua b/worldeditadditions/lib/noise/params_apply_default.lua index 0ae6c19..cd00852 100644 --- a/worldeditadditions/lib/noise/params_apply_default.lua +++ b/worldeditadditions/lib/noise/params_apply_default.lua @@ -34,14 +34,17 @@ function worldeditadditions.noise.params_apply_default(params) -- If params[1] is thing, this is a list of params -- This might be a thing if we're dealing with multiple octaves for i,params_el in ipairs(params) do - local default_copy = worldeditadditions.table.shallowcopy(params_default) + local default_copy = wea.table.shallowcopy(params_default) -- Keyword support - if params_el.perlin then params_el.algorithm = "perlin" end - if params_el.sin then params_el.algorithm = "sin" end + for i, keyword in ipairs(wea.noise.engines.available) do + if params_el[keyword] ~= nil then + params_el.algorithm = keyword + end + end -- Apply this table to fill in the gaps - worldeditadditions.table.apply( + wea.table.apply( params_el, default_copy ) diff --git a/worldeditadditions_commands/commands/noise2d.lua b/worldeditadditions_commands/commands/noise2d.lua index 8ae0973..ce2f287 100644 --- a/worldeditadditions_commands/commands/noise2d.lua +++ b/worldeditadditions_commands/commands/noise2d.lua @@ -12,10 +12,8 @@ worldedit.register_command("noise2d", { if params_text == "" then return true, {} end - local success, map = worldeditadditions.parse.map(params_text, { - -- Keywords - "perlin", "sin" - }) + local success, map = worldeditadditions.parse.map(params_text, + wea.noise.engines.available) -- Keywords if not success then return success, map end if map.scale then