Compare commits

...

3 Commits

Author SHA1 Message Date
HybridDog c2fad91282
Merge 95c29eadb3 into 8f60e6f729 2023-10-11 02:40:01 -05:00
sfan5 8f60e6f729 Fix clear_objects not working 2023-10-08 18:21:15 +02:00
HybridDog 95c29eadb3 Add a hollowcuboid iteration helper 2023-06-17 12:15:04 +02:00
3 changed files with 85 additions and 21 deletions

View File

@ -117,3 +117,72 @@ function mh.finish(manip, data)
manip:update_map()
end
-- returns an iterator that returns voxelarea indices for a hollow cuboid
function mh.iter_hollowcuboid(area, minx, miny, minz, maxx, maxy, maxz)
local i = area:index(minx, miny, minz) - 1
local xrange = maxx - minx + 1
local nextaction = i + 1 + xrange
local do_hole = false
local y = 0
local ydiff = maxy - miny
local ystride = area.ystride
local ymultistride = ydiff * ystride
local z = 0
local zdiff = maxz - minz
local zstride = area.zstride
local zcorner = true
return function()
-- continue i until it needs to jump ystride
i = i + 1
if i ~= nextaction then
return i
end
-- add the x offset if y (and z) are not 0 or maxy (or maxz)
if do_hole then
do_hole = false
i = i + xrange - 2
nextaction = i + 1
return i
end
-- continue y until maxy is exceeded
y = y+1
if y ~= ydiff + 1 then
i = i + ystride - xrange
if zcorner
or y == ydiff then
nextaction = i + xrange
else
nextaction = i + 1
do_hole = true
end
return i
end
-- continue z until maxz is exceeded
z = z+1
if z == zdiff + 1 then
-- hollowcuboid finished, return nil
return
end
-- set i to index(minx, miny, minz + z) - 1
i = i + zstride - (ymultistride + xrange)
zcorner = z == zdiff
-- y is 0, so traverse the xs
y = 0
nextaction = i + xrange
return i
end
end
function mh.iterp_hollowcuboid(area, minp, maxp)
return mh.iter_hollowcuboid(area, minp.x, minp.y, minp.z,
maxp.x, maxp.y, maxp.z)
end

View File

@ -649,7 +649,7 @@ function worldedit.clear_objects(pos1, pos2)
-- Offset positions to include full nodes (positions are in the center of nodes)
pos1 = vector.add(pos1, -0.5)
pos2 = vector.add(pos1, 0.5)
pos2 = vector.add(pos2, 0.5)
local count = 0
if minetest.get_objects_in_area then
@ -676,7 +676,8 @@ function worldedit.clear_objects(pos1, pos2)
(center.x - pos1.x) ^ 2 +
(center.y - pos1.y) ^ 2 +
(center.z - pos1.z) ^ 2)
for _, obj in pairs(minetest.get_objects_inside_radius(center, radius)) do
local objects = minetest.get_objects_inside_radius(center, radius)
for _, obj in pairs(objects) do
if should_delete(obj) then
local pos = obj:get_pos()
if pos.x >= pos1.x and pos.x <= pos2.x and

View File

@ -14,31 +14,25 @@ local mh = worldedit.manip_helpers
-- @return The number of nodes added.
function worldedit.cube(pos, width, height, length, node_name, hollow)
-- Set up voxel manipulator
local basepos = vector.subtract(pos, {x=math.floor(width/2), y=0, z=math.floor(length/2)})
local manip, area = mh.init(basepos, vector.add(basepos, {x=width, y=height, z=length}))
local basepos = vector.subtract(pos,
{x = math.floor(width / 2), y = 0, z = math.floor(length / 2)})
local endpos = vector.add(basepos, {x=width, y=height, z=length})
local manip, area = mh.init(basepos, endpos)
local data = mh.get_empty_data(area)
-- Add cube
local node_id = minetest.get_content_id(node_name)
local stride = vector.new(1, area.ystride, area.zstride)
local offset = vector.subtract(basepos, area.MinEdge)
local count = 0
local iterfunc
if hollow then
iterfunc = mh.iterp_hollowcuboid(area, basepos, endpos)
else
iterfunc = area:iter(basepos, endpos)
end
for z = 0, length-1 do
local index_z = (offset.z + z) * stride.z + 1 -- +1 for 1-based indexing
for y = 0, height-1 do
local index_y = index_z + (offset.y + y) * stride.y
for x = 0, width-1 do
local is_wall = z == 0 or z == length-1
or y == 0 or y == height-1
or x == 0 or x == width-1
if not hollow or is_wall then
local i = index_y + (offset.x + x)
data[i] = node_id
count = count + 1
end
end
end
for vi in iterfunc do
data[vi] = node_id
count = count+1
end
mh.finish(manip, data)