mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-11-27 09:33:52 +01:00
initial wea.revolve() implementation
....but it's not tested or hooked up yet. Next up: a chat command definition so we can test it.
This commit is contained in:
parent
87812679d9
commit
392708b190
70
worldeditadditions/lib/revolve.lua
Normal file
70
worldeditadditions/lib/revolve.lua
Normal file
@ -0,0 +1,70 @@
|
||||
local wea_c = worldeditadditions_core
|
||||
local Vector3 = wea_c.Vector3
|
||||
|
||||
-- ██████ ███████ ██ ██ ██████ ██ ██ ██ ███████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ██████ █████ ██ ██ ██ ██ ██ ██ ██ █████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ██ ██ ███████ ████ ██████ ███████ ████ ███████
|
||||
|
||||
--- Make <times> copies of the region defined by pos1-pos2 at equal angles around a circle.
|
||||
-- The defined region works best if it's a thin slice that's 1 or 2 blocks thick.
|
||||
-- For example, if one provided a times value of 3, copies would be rotated 0, 120, and 240 degrees.
|
||||
-- TODO: implement support to rotate around arbitrary axes.
|
||||
-- @param pos1 Vector3 The first position defining the source region.
|
||||
-- @param pos2 Vector3 The second position defining the source region.
|
||||
-- @param origin Vector3 The pivot point to rotate around.
|
||||
-- @param times number The number of equally-spaces copies to make.
|
||||
function worldeditadditions.revolve(pos1, pos2, origin, times)
|
||||
local rotation_radians = wea_c.range(0, 1, 1 / times)
|
||||
|
||||
local pos1_source, pos2_source = Vector3.sort(pos1, pos2)
|
||||
|
||||
-- HACK: with some maths this could be much more efficient.
|
||||
local pos1_target, pos2_target = wea_c.table.unpack(wea_c.table.reduce({
|
||||
Vector3.rotate3d(origin, pos1_source, Vector3.new(0, 0, math.pi / 2)),
|
||||
Vector3.rotate3d(origin, pos2_source, Vector3.new(0, 0, math.pi / 2)),
|
||||
Vector3.rotate3d(origin, pos1_source, Vector3.new(0, 0, math.pi)),
|
||||
Vector3.rotate3d(origin, pos2_source, Vector3.new(0, 0, math.pi)),
|
||||
Vector3.rotate3d(origin, pos1_source, Vector3.new(0, 0, -math.pi / 2)),
|
||||
Vector3.rotate3d(origin, pos2_source, Vector3.new(0, 0, -math.pi / 2)),
|
||||
}, function(acc, next)
|
||||
return { next:expand_region(acc[1], acc[2]) }
|
||||
end, { pos1_source, pos2_source }))
|
||||
|
||||
|
||||
-- Fetch the nodes in the specified area
|
||||
local manip_source, area_source = worldedit.manip_helpers.init(pos1_source, pos2_source)
|
||||
local data_source = manip:get_data()
|
||||
|
||||
local manip_target, area_target = worldedit.manip_helpers.init(pos1_target, pos2_target)
|
||||
local data_target = manip:get_data()
|
||||
|
||||
local changed = 0
|
||||
for z = pos2_source.z, pos1_source.z, -1 do
|
||||
for y = pos2_source.y, pos1_source.y, -1 do
|
||||
for x = pos2_source.x, pos1_source.x, -1 do
|
||||
for index, rotation in ipairs(rotation_radians) do
|
||||
local pos_source = Vector3.new(x, y, z)
|
||||
local pos_target = Vector3.rotate3d(
|
||||
origin,
|
||||
pos_source,
|
||||
Vector3.new(0, 0, rotation) -- rotate on Z axis only
|
||||
)
|
||||
|
||||
local i_source = area_source:index(x, y, z)
|
||||
local i_target = area_target:index(pos_target.x, pos_target.y, pos_target.z)
|
||||
|
||||
-- TODO: Rotate notes as appropriate
|
||||
data_target[i_target] = data_source[i_source]
|
||||
changed = changed + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Save the modified nodes back to disk & return
|
||||
worldedit.manip_helpers.finish(manip_target, data_target)
|
||||
|
||||
return true, changed
|
||||
end
|
Loading…
Reference in New Issue
Block a user