mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-12-22 11:45:00 +00:00
Finish initial implementation of //revolve
it's not quite done yet - got docs to go
This commit is contained in:
parent
d1b9d1c1c1
commit
e942e4fb2f
4 changed files with 91 additions and 12 deletions
|
@ -31,6 +31,7 @@ dofile(wea.modpath.."/lib/spiral_square.lua")
|
|||
dofile(wea.modpath.."/lib/spiral_circle.lua")
|
||||
dofile(wea.modpath.."/lib/dome.lua")
|
||||
dofile(wea.modpath.."/lib/spline.lua")
|
||||
dofile(wea.modpath.."/lib/revolve.lua")
|
||||
dofile(wea.modpath.."/lib/conv/conv.lua")
|
||||
dofile(wea.modpath.."/lib/erode/erode.lua")
|
||||
dofile(wea.modpath.."/lib/noise/init.lua")
|
||||
|
|
|
@ -16,29 +16,31 @@ local Vector3 = wea_c.Vector3
|
|||
-- @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 rotation_radians = wea_c.table.filter(
|
||||
wea_c.range(0, 1, 1 / times),
|
||||
function (val) return val ~= 0 and val ~= 1 end
|
||||
)
|
||||
|
||||
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)),
|
||||
Vector3.rotate3d(origin, pos1_source, Vector3.new(0, math.pi / 2, 0)),
|
||||
Vector3.rotate3d(origin, pos2_source, Vector3.new(0, math.pi / 2, 0)),
|
||||
Vector3.rotate3d(origin, pos1_source, Vector3.new(0, math.pi, 0)),
|
||||
Vector3.rotate3d(origin, pos2_source, Vector3.new(0, math.pi, 0)),
|
||||
Vector3.rotate3d(origin, pos1_source, Vector3.new(0, -math.pi / 2, 0)),
|
||||
Vector3.rotate3d(origin, pos2_source, Vector3.new(0, -math.pi / 2, 0)),
|
||||
}, 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 data_source = manip_source:get_data()
|
||||
|
||||
local manip_target, area_target = worldedit.manip_helpers.init(pos1_target, pos2_target)
|
||||
local data_target = manip:get_data()
|
||||
local data_target = manip_target:get_data()
|
||||
|
||||
local changed = 0
|
||||
for z = pos2_source.z, pos1_source.z, -1 do
|
||||
|
@ -49,8 +51,10 @@ function worldeditadditions.revolve(pos1, pos2, origin, times)
|
|||
local pos_target = Vector3.rotate3d(
|
||||
origin,
|
||||
pos_source,
|
||||
Vector3.new(0, 0, rotation) -- rotate on Z axis only
|
||||
)
|
||||
-- rotate on Z axis only, convert 0..1 → radians
|
||||
-- TEST on Y axis, 'cause I'm confused
|
||||
Vector3.new(0, rotation * math.pi * 2, 0)
|
||||
):floor()
|
||||
|
||||
local i_source = area_source:index(x, y, z)
|
||||
local i_target = area_target:index(pos_target.x, pos_target.y, pos_target.z)
|
||||
|
|
73
worldeditadditions_commands/commands/revolve.lua
Normal file
73
worldeditadditions_commands/commands/revolve.lua
Normal file
|
@ -0,0 +1,73 @@
|
|||
local wea_c = worldeditadditions_core
|
||||
local Vector3 = wea_c.Vector3
|
||||
|
||||
|
||||
|
||||
-- ██████ ███████ ██ ██ ██████ ██ ██ ██ ███████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ██████ █████ ██ ██ ██ ██ ██ ██ ██ █████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ██ ██ ███████ ████ ██████ ███████ ████ ███████
|
||||
worldeditadditions_core.register_command("revolve", {
|
||||
params = "<times> [<pivot_point_number=last_point>]",
|
||||
description = "Creates a number of copies of the defined region rotated at equal intervals.",
|
||||
privs = { worldedit = true },
|
||||
require_pos = 2,
|
||||
parse = function (params_text)
|
||||
if not params_text then params_text = "" end
|
||||
local parts = wea_c.split_shell(params_text)
|
||||
|
||||
if #parts < 1 then
|
||||
return false, "Error: No number of times specified. times should be a positive integer greater than 1"
|
||||
end
|
||||
|
||||
local times = tonumber(parts[1])
|
||||
local origin = -1 -- -1 = last point
|
||||
|
||||
if not times or times < 2 then
|
||||
return false, "Error: Invalid number of times. The value for times must be a positive integer greater than 1."
|
||||
end
|
||||
|
||||
if #parts > 1 then
|
||||
origin = tonumber(parts[2])
|
||||
if not origin then
|
||||
return false, "Error: Invalid pivot point number. The pivot point number must be a positive integer greater than 2."
|
||||
end
|
||||
if origin == 1 or origin == 2 then
|
||||
return false, "Error: Point numbers 1 and 2 are reserved for defining the region that should be cloned."
|
||||
end
|
||||
end
|
||||
|
||||
return true, times, origin
|
||||
end,
|
||||
nodes_needed = function(name, times)
|
||||
-- TODO: Calculate the bounding box for everything, since we'll be grabbing a VoxelManip for the for entire area and then operating on that
|
||||
return worldedit.volume(worldedit.pos1[name], worldedit.pos2[name]) * times
|
||||
end,
|
||||
func = function(name, times, origin_point_number)
|
||||
local start_time = wea_c.get_ms_time()
|
||||
local pos1, pos2 = Vector3.sort(worldedit.pos1[name], worldedit.pos2[name])
|
||||
|
||||
local pos_count = wea_c.pos.count(name)
|
||||
if pos_count < origin_point_number then
|
||||
return false, "Error: You only have "..pos_count.." points defined, yet requested the origin/pivot point be point "..origin_point_number.."."
|
||||
end
|
||||
|
||||
if origin_point_number == -1 then
|
||||
origin_point_number = pos_count
|
||||
end
|
||||
local origin = wea_c.pos.get(name, origin_point_number)
|
||||
|
||||
local success, changed = worldeditadditions.revolve(
|
||||
pos1, pos2,
|
||||
origin,
|
||||
times
|
||||
)
|
||||
if not success then return success, changed end
|
||||
|
||||
local time_taken = wea_c.get_ms_time() - start_time
|
||||
|
||||
minetest.log("action", name .. " used //revolve at "..pos1.." - "..pos2.." with origin "..origin..", replacing "..changed.." nodes in "..time_taken.."s")
|
||||
return true, changed.." nodes replaced in "..wea_c.format.human_time(time_taken)
|
||||
end
|
||||
})
|
|
@ -37,6 +37,7 @@ dofile(wea_cmd.modpath.."/commands/metaball.lua")
|
|||
dofile(wea_cmd.modpath.."/commands/count.lua")
|
||||
dofile(wea_cmd.modpath.."/commands/sculpt.lua")
|
||||
dofile(wea_cmd.modpath.."/commands/spline.lua")
|
||||
dofile(wea_cmd.modpath.."/commands/revolve.lua")
|
||||
|
||||
-- Meta Commands
|
||||
dofile(wea_cmd.modpath.."/commands/meta/init.lua")
|
||||
|
|
Loading…
Reference in a new issue