mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-11-23 23:53:44 +01: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
|
--- Overlap command. Places a specified node on top of
|
||||||
-- @module worldeditadditions.overlay
|
-- @module worldeditadditions.overlay
|
||||||
|
|
||||||
function worldedit.ellipsoid(position, radius, target_node)
|
function worldedit.ellipsoid(position, radius, target_node, hollow)
|
||||||
-- position = { x, y, z }
|
-- 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
|
-- Fetch the nodes in the specified area
|
||||||
-- OPTIMIZE: We should be able to calculate a more efficient box-area here
|
-- 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
|
-- 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
|
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
|
data[i] = node_id
|
||||||
count = count + 1
|
count = count + 1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -117,13 +117,7 @@ local function parse_params_ellipsoid(params_text)
|
|||||||
z = tonumber(radius_z)
|
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)
|
replace_node = worldedit.normalize_nodename(replace_node)
|
||||||
minetest.log("action", "Normalised target node: " .. replace_node)
|
|
||||||
|
|
||||||
return replace_node, radius
|
return replace_node, radius
|
||||||
end
|
end
|
||||||
@ -145,7 +139,7 @@ minetest.register_chatcommand("/ellipsoid", {
|
|||||||
end
|
end
|
||||||
|
|
||||||
local start_time = os.clock()
|
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
|
local time_taken = os.clock() - start_time
|
||||||
|
|
||||||
worldedit.player_notify(name, replaced .. " nodes replaced in " .. time_taken .. "s")
|
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)
|
return math.ceil(4/3 * math.pi * radius.x * radius.y * radius.z)
|
||||||
end)
|
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