mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-08-20 13:34:05 +02:00
Add a hollowellipsoid command
This commit is contained in:
parent
2fd63fcb25
commit
429beb2e52
@ -1,9 +1,13 @@
|
||||
--- Overlap command. Places a specified node on top of
|
||||
-- @module worldeditadditions.overlay
|
||||
|
||||
function worldedit.ellipsoid(position, radius, target_node)
|
||||
function worldedit.ellipsoid(position, radius, target_node, hollow)
|
||||
-- position = { x, y, z }
|
||||
|
||||
local hollow_inner_radius = {
|
||||
x = radius.x - 1,
|
||||
y = radius.y - 1,
|
||||
z = radius.z - 1
|
||||
}
|
||||
|
||||
-- Fetch the nodes in the specified area
|
||||
-- OPTIMIZE: We should be able to calculate a more efficient box-area here
|
||||
@ -30,11 +34,24 @@ function worldedit.ellipsoid(position, radius, target_node)
|
||||
|
||||
-- If we're inside the ellipse, then fill it in
|
||||
local x_comp, y_comp, z_comp = x/radius.x, y/radius.y, z/radius.z
|
||||
if x_comp*x_comp + y_comp*y_comp + z_comp*z_comp <= 1 then
|
||||
local ellipsoid_dist = x_comp*x_comp + y_comp*y_comp + z_comp*z_comp
|
||||
if ellipsoid_dist <= 1 then
|
||||
local place_ok = not hollow;
|
||||
|
||||
if not place_ok then
|
||||
-- It must be hollow! Do some additional calculations.
|
||||
local hx_comp = x/hollow_inner_radius.x
|
||||
local hy_comp = y/hollow_inner_radius.y
|
||||
local hz_comp = z/hollow_inner_radius.z
|
||||
|
||||
-- It's only ok to place it if it's outside our inner ellipse
|
||||
place_ok = hx_comp*hx_comp + hy_comp*hy_comp + hz_comp*hz_comp >= 1
|
||||
end
|
||||
|
||||
if place_ok then
|
||||
data[i] = node_id
|
||||
count = count + 1
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
@ -117,13 +117,7 @@ local function parse_params_ellipsoid(params_text)
|
||||
z = tonumber(radius_z)
|
||||
}
|
||||
|
||||
minetest.log("action", "Radius x: " .. radius_x)
|
||||
minetest.log("action", "Radius y: " .. radius_y)
|
||||
minetest.log("action", "Radius z: " .. radius_z)
|
||||
|
||||
minetest.log("action", "Raw target node: " .. replace_node)
|
||||
replace_node = worldedit.normalize_nodename(replace_node)
|
||||
minetest.log("action", "Normalised target node: " .. replace_node)
|
||||
|
||||
return replace_node, radius
|
||||
end
|
||||
@ -145,7 +139,7 @@ minetest.register_chatcommand("/ellipsoid", {
|
||||
end
|
||||
|
||||
local start_time = os.clock()
|
||||
local replaced = worldedit.ellipsoid(worldedit.pos1[name], radius, target_node)
|
||||
local replaced = worldedit.ellipsoid(worldedit.pos1[name], radius, target_node, false)
|
||||
local time_taken = os.clock() - start_time
|
||||
|
||||
worldedit.player_notify(name, replaced .. " nodes replaced in " .. time_taken .. "s")
|
||||
@ -160,3 +154,37 @@ minetest.register_chatcommand("/ellipsoid", {
|
||||
return math.ceil(4/3 * math.pi * radius.x * radius.y * radius.z)
|
||||
end)
|
||||
})
|
||||
|
||||
-- TODO: This duplicates a lot of code. Perhaps we can trim it down a bit?
|
||||
minetest.register_chatcommand("/hollowellipsoid", {
|
||||
params = "<rx> <ry> <rz> <replace_node>",
|
||||
description = "Creates a 3D hollow ellipsoid with a radius of (rx, ry, rz) at pos1, filled with <replace_node>.",
|
||||
privs = { worldedit = true },
|
||||
func = safe_region(function(name, params_text)
|
||||
local target_node, radius = parse_params_ellipsoid(params_text)
|
||||
|
||||
if not target_node then
|
||||
worldedit.player_notify(name, "Error: Invalid node name.")
|
||||
return false
|
||||
end
|
||||
if not radius then
|
||||
worldedit.player_notify(name, "Error: Invalid radius(es).")
|
||||
return false
|
||||
end
|
||||
|
||||
local start_time = os.clock()
|
||||
local replaced = worldedit.ellipsoid(worldedit.pos1[name], radius, target_node, true)
|
||||
local time_taken = os.clock() - start_time
|
||||
|
||||
worldedit.player_notify(name, replaced .. " nodes replaced in " .. time_taken .. "s")
|
||||
minetest.log("action", name .. " used //hollowellipsoid at " .. worldeditadditions.vector.tostring(worldedit.pos1[name]) .. ", replacing " .. replaced .. " nodes in " .. time_taken .. "s")
|
||||
end, function(name, params_text)
|
||||
local target_node, radius = parse_params_ellipsoid(params_text)
|
||||
if not target_node or not radius then
|
||||
worldedit.player_notify(name, "Error: Invalid input '" .. params_text .. "'. Try '/help /ellipsoid' to learn how to use this command.")
|
||||
return 0
|
||||
end
|
||||
|
||||
return math.ceil(4/3 * math.pi * radius.x * radius.y * radius.z)
|
||||
end)
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user