mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-12-22 19:45:02 +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)
|
||||
-- Calculate the area we want to modify
|
||||
local pos1 = vector.add(start_pos, { x = radius, y = 0, z = radius })
|
||||
local pos2 = vector.subtract(start_pos, { x = radius, y = radius, z = radius })
|
||||
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
|
||||
local manip, area = worldedit.manip_helpers.init(pos1, pos2)
|
||||
local data = manip:get_data()
|
||||
|
||||
-- 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 replace_id = minetest.get_content_id(replace_node)
|
||||
|
||||
minetest.log("action", "ids: " .. search_id .. " -> " .. replace_id)
|
||||
local radius_sq = radius*radius
|
||||
|
||||
local count = 0
|
||||
local remaining_nodes = Queue.new()
|
||||
|
@ -94,27 +77,37 @@ function worldedit.floodfill(start_pos, radius, replace_node)
|
|||
-- Check all the nearby nodes
|
||||
-- We don't need to go upwards here, since we're filling in lake-style
|
||||
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)
|
||||
Queue.enqueue(remaining_nodes, xplus)
|
||||
end
|
||||
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)
|
||||
Queue.enqueue(remaining_nodes, xminus)
|
||||
end
|
||||
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)
|
||||
Queue.enqueue(remaining_nodes, zplus)
|
||||
end
|
||||
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)
|
||||
Queue.enqueue(remaining_nodes, zminus)
|
||||
end
|
||||
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)
|
||||
Queue.enqueue(remaining_nodes, yminus)
|
||||
end
|
||||
|
|
|
@ -5,4 +5,7 @@
|
|||
-- @license Mozilla Public License, 2.0
|
||||
-- @author Starbeamrainbowlabs
|
||||
|
||||
worldeditadditions = {}
|
||||
|
||||
dofile(minetest.get_modpath("worldeditadditions") .. "/utils.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)
|
||||
|
||||
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)
|
||||
|
||||
worldedit.player_notify(name, nodes_replaced .. " replaced")
|
||||
minetest.log("action", name .. "used floodfill at (" .. worldedit.pos1[name].x .. "," .. worldedit.pos1[name].y .. "," .. worldedit.pos1[name].z .. "), replacing " .. nodes_replaced .. " nodes")
|
||||
worldedit.player_notify(name, nodes_replaced .. " nodes replaced in " .. (os.clock() - start_time) .. "s")
|
||||
minetest.log("action", name .. " used floodfill at " .. worldeditadditions.vector.tostring(worldedit.pos1[name]) .. ", replacing " .. nodes_replaced .. " nodes in " .. (os.clock() - start_time) .. "s")
|
||||
end
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue