mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-11-26 09:03:01 +00:00
Add optimised radius checking
This commit is contained in:
parent
7288347479
commit
9412a1bf30
4 changed files with 32 additions and 28 deletions
|
@ -43,39 +43,22 @@ end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
-- These really should be in a utilities file, but Lua is being stupid and preventing access to it (and minetest is also being stupid, as we can't modularise our code the way you ought to be able to - or at least the documentation on dofile() is so poor I've no idea at this point)
|
|
||||||
local function vector2string(v)
|
|
||||||
return "(" .. v.x ..", " .. v.y ..", " .. v.z ..")"
|
|
||||||
end
|
|
||||||
|
|
||||||
local clock = os.clock
|
|
||||||
function sleep(n) -- seconds
|
|
||||||
local t0 = clock()
|
|
||||||
while clock() - t0 <= n do end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function worldedit.floodfill(start_pos, radius, replace_node)
|
function worldedit.floodfill(start_pos, radius, replace_node)
|
||||||
-- Calculate the area we want to modify
|
-- Calculate the area we want to modify
|
||||||
local pos1 = vector.add(start_pos, { x = radius, y = 0, z = radius })
|
local pos1 = vector.add(start_pos, { x = radius, y = 0, z = radius })
|
||||||
local pos2 = vector.subtract(start_pos, { x = radius, y = radius, z = radius })
|
local pos2 = vector.subtract(start_pos, { x = radius, y = radius, z = radius })
|
||||||
pos1, pos2 = worldedit.sort_pos(pos1, pos2) -- Just in case
|
pos1, pos2 = worldedit.sort_pos(pos1, pos2) -- Just in case
|
||||||
|
|
||||||
minetest.log("action", "radius: " .. radius)
|
|
||||||
minetest.log("action", "pos1: " .. vector2string(pos1))
|
|
||||||
minetest.log("action", "pos2: " .. vector2string(pos2))
|
|
||||||
|
|
||||||
-- Fetch the nodes in the specified area
|
-- Fetch the nodes in the specified area
|
||||||
local manip, area = worldedit.manip_helpers.init(pos1, pos2)
|
local manip, area = worldedit.manip_helpers.init(pos1, pos2)
|
||||||
local data = manip:get_data()
|
local data = manip:get_data()
|
||||||
|
|
||||||
-- Setup for the floodfill operation itself
|
-- Setup for the floodfill operation itself
|
||||||
local start_pos_index = area:index(start_pos.x, start_pos.y, start_pos.z);
|
local start_pos_index = area:index(start_pos.x, start_pos.y, start_pos.z)
|
||||||
|
|
||||||
local search_id = data[start_pos_index]
|
local search_id = data[start_pos_index]
|
||||||
local replace_id = minetest.get_content_id(replace_node)
|
local replace_id = minetest.get_content_id(replace_node)
|
||||||
|
local radius_sq = radius*radius
|
||||||
minetest.log("action", "ids: " .. search_id .. " -> " .. replace_id)
|
|
||||||
|
|
||||||
local count = 0
|
local count = 0
|
||||||
local remaining_nodes = Queue.new()
|
local remaining_nodes = Queue.new()
|
||||||
|
@ -94,27 +77,37 @@ function worldedit.floodfill(start_pos, radius, replace_node)
|
||||||
-- Check all the nearby nodes
|
-- Check all the nearby nodes
|
||||||
-- We don't need to go upwards here, since we're filling in lake-style
|
-- We don't need to go upwards here, since we're filling in lake-style
|
||||||
local xplus = cur + 1 -- +X
|
local xplus = cur + 1 -- +X
|
||||||
if data[xplus] == search_id and not Queue.contains(remaining_nodes, xplus) then
|
if data[xplus] == search_id and
|
||||||
|
worldeditadditions.vector.lengthsquared(vector.subtract(area:position(xplus), start_pos)) < radius_sq and
|
||||||
|
not Queue.contains(remaining_nodes, xplus) then
|
||||||
-- minetest.log("action", "[floodfill] [+X] index " .. xplus .. " is a " .. data[xplus] .. ", searching for a " .. search_id)
|
-- minetest.log("action", "[floodfill] [+X] index " .. xplus .. " is a " .. data[xplus] .. ", searching for a " .. search_id)
|
||||||
Queue.enqueue(remaining_nodes, xplus)
|
Queue.enqueue(remaining_nodes, xplus)
|
||||||
end
|
end
|
||||||
local xminus = cur - 1 -- -X
|
local xminus = cur - 1 -- -X
|
||||||
if data[xminus] == search_id and not Queue.contains(remaining_nodes, xminus) then
|
if data[xminus] == search_id and
|
||||||
|
worldeditadditions.vector.lengthsquared(vector.subtract(area:position(xminus), start_pos)) < radius_sq and
|
||||||
|
not Queue.contains(remaining_nodes, xminus) then
|
||||||
-- minetest.log("action", "[floodfill] [-X] index " .. xminus .. " is a " .. data[xminus] .. ", searching for a " .. search_id)
|
-- minetest.log("action", "[floodfill] [-X] index " .. xminus .. " is a " .. data[xminus] .. ", searching for a " .. search_id)
|
||||||
Queue.enqueue(remaining_nodes, xminus)
|
Queue.enqueue(remaining_nodes, xminus)
|
||||||
end
|
end
|
||||||
local zplus = cur + area.zstride -- +Z
|
local zplus = cur + area.zstride -- +Z
|
||||||
if data[zplus] == search_id and not Queue.contains(remaining_nodes, zplus) then
|
if data[zplus] == search_id and
|
||||||
|
worldeditadditions.vector.lengthsquared(vector.subtract(area:position(zplus), start_pos)) < radius_sq and
|
||||||
|
not Queue.contains(remaining_nodes, zplus) then
|
||||||
-- minetest.log("action", "[floodfill] [+Z] index " .. zplus .. " is a " .. data[zplus] .. ", searching for a " .. search_id)
|
-- minetest.log("action", "[floodfill] [+Z] index " .. zplus .. " is a " .. data[zplus] .. ", searching for a " .. search_id)
|
||||||
Queue.enqueue(remaining_nodes, zplus)
|
Queue.enqueue(remaining_nodes, zplus)
|
||||||
end
|
end
|
||||||
local zminus = cur - area.zstride -- -Z
|
local zminus = cur - area.zstride -- -Z
|
||||||
if data[zminus] == search_id and not Queue.contains(remaining_nodes, zminus) then
|
if data[zminus] == search_id and
|
||||||
|
worldeditadditions.vector.lengthsquared(vector.subtract(area:position(zminus), start_pos)) < radius_sq and
|
||||||
|
not Queue.contains(remaining_nodes, zminus) then
|
||||||
-- minetest.log("action", "[floodfill] [-Z] index " .. zminus .. " is a " .. data[zminus] .. ", searching for a " .. search_id)
|
-- minetest.log("action", "[floodfill] [-Z] index " .. zminus .. " is a " .. data[zminus] .. ", searching for a " .. search_id)
|
||||||
Queue.enqueue(remaining_nodes, zminus)
|
Queue.enqueue(remaining_nodes, zminus)
|
||||||
end
|
end
|
||||||
local yminus = cur - area.ystride -- -Y
|
local yminus = cur - area.ystride -- -Y
|
||||||
if data[yminus] == search_id and not Queue.contains(remaining_nodes, yminus) then
|
if data[yminus] == search_id and
|
||||||
|
worldeditadditions.vector.lengthsquared(vector.subtract(area:position(yminus), start_pos)) < radius_sq and
|
||||||
|
not Queue.contains(remaining_nodes, yminus) then
|
||||||
-- minetest.log("action", "[floodfill] [-Y] index " .. yminus .. " is a " .. data[yminus] .. ", searching for a " .. search_id)
|
-- minetest.log("action", "[floodfill] [-Y] index " .. yminus .. " is a " .. data[yminus] .. ", searching for a " .. search_id)
|
||||||
Queue.enqueue(remaining_nodes, yminus)
|
Queue.enqueue(remaining_nodes, yminus)
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,4 +5,7 @@
|
||||||
-- @license Mozilla Public License, 2.0
|
-- @license Mozilla Public License, 2.0
|
||||||
-- @author Starbeamrainbowlabs
|
-- @author Starbeamrainbowlabs
|
||||||
|
|
||||||
|
worldeditadditions = {}
|
||||||
|
|
||||||
|
dofile(minetest.get_modpath("worldeditadditions") .. "/utils.lua")
|
||||||
dofile(minetest.get_modpath("worldeditadditions") .. "/floodfill.lua")
|
dofile(minetest.get_modpath("worldeditadditions") .. "/floodfill.lua")
|
||||||
|
|
9
worldeditadditions/utils.lua
Normal file
9
worldeditadditions/utils.lua
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
worldeditadditions.vector = {}
|
||||||
|
|
||||||
|
function worldeditadditions.vector.tostring(v)
|
||||||
|
return "(" .. v.x ..", " .. v.y ..", " .. v.z ..")"
|
||||||
|
end
|
||||||
|
|
||||||
|
function worldeditadditions.vector.lengthsquared(v)
|
||||||
|
return v.x*v.x + v.y*v.y + v.z*v.z
|
||||||
|
end
|
|
@ -24,11 +24,10 @@ minetest.register_chatcommand("/floodfill", {
|
||||||
|
|
||||||
replace_node = worldedit.normalize_nodename(replace_node)
|
replace_node = worldedit.normalize_nodename(replace_node)
|
||||||
|
|
||||||
minetest.log("action", "Floodfill settings - node: " .. replace_node .. ", radius: " .. radius)
|
local start_time = os.clock()
|
||||||
|
|
||||||
local nodes_replaced = worldedit.floodfill(worldedit.pos1[name], radius, replace_node)
|
local nodes_replaced = worldedit.floodfill(worldedit.pos1[name], radius, replace_node)
|
||||||
|
|
||||||
worldedit.player_notify(name, nodes_replaced .. " replaced")
|
worldedit.player_notify(name, nodes_replaced .. " nodes replaced in " .. (os.clock() - start_time) .. "s")
|
||||||
minetest.log("action", name .. "used floodfill at (" .. worldedit.pos1[name].x .. "," .. worldedit.pos1[name].y .. "," .. worldedit.pos1[name].z .. "), replacing " .. nodes_replaced .. " nodes")
|
minetest.log("action", name .. " used floodfill at " .. worldeditadditions.vector.tostring(worldedit.pos1[name]) .. ", replacing " .. nodes_replaced .. " nodes in " .. (os.clock() - start_time) .. "s")
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue