mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-11-25 16:43:05 +00:00
Add backend functionality for metaballs
Implementing a frontend command sounds like a headache to me
This commit is contained in:
parent
03fb033b70
commit
f34617a3d3
2 changed files with 64 additions and 0 deletions
|
@ -59,6 +59,7 @@ dofile(wea.modpath.."/lib/scale.lua")
|
||||||
dofile(wea.modpath.."/lib/spiral_square.lua")
|
dofile(wea.modpath.."/lib/spiral_square.lua")
|
||||||
dofile(wea.modpath.."/lib/spiral_circle.lua")
|
dofile(wea.modpath.."/lib/spiral_circle.lua")
|
||||||
dofile(wea.modpath.."/lib/dome.lua")
|
dofile(wea.modpath.."/lib/dome.lua")
|
||||||
|
dofile(wea.modpath.."/lib/metaballs.lua")
|
||||||
dofile(wea.modpath.."/lib/conv/conv.lua")
|
dofile(wea.modpath.."/lib/conv/conv.lua")
|
||||||
dofile(wea.modpath.."/lib/erode/erode.lua")
|
dofile(wea.modpath.."/lib/erode/erode.lua")
|
||||||
dofile(wea.modpath.."/lib/noise/init.lua")
|
dofile(wea.modpath.."/lib/noise/init.lua")
|
||||||
|
|
63
worldeditadditions/lib/metaballs.lua
Normal file
63
worldeditadditions/lib/metaballs.lua
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
local wea = worldeditadditions
|
||||||
|
local Vector3 = wea.Vector3
|
||||||
|
|
||||||
|
-- ███ ███ ███████ ████████ █████ ██████ █████ ██ ██ ███████
|
||||||
|
-- ████ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
|
-- ██ ████ ██ █████ ██ ███████ ██████ ███████ ██ ██ ███████
|
||||||
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
|
-- ██ ██ ███████ ██ ██ ██ ██████ ██ ██ ███████ ███████ ███████
|
||||||
|
--- Renders 2 or more metaballs with the given node and threshold value.
|
||||||
|
-- direction the point should point.
|
||||||
|
-- @param metaballs [{pos: Vector3, radius: number}] Aa list of metaballs to render. Each metaball should be a table with 2 properties: pos - the position of the centre of the metaball as a Vector3, and radius - the radius of the metaball.
|
||||||
|
-- @param replace_node string The fully qualified name of the node to use to make the dome with.
|
||||||
|
function worldeditadditions.metaballs(metaballs, replace_node, threshold)
|
||||||
|
local pos1, pos2
|
||||||
|
if not threshold then threshold = 1 end
|
||||||
|
|
||||||
|
for i,metaball in ipairs(metaballs) do
|
||||||
|
local pos1_c = metaball.pos - metaball.radius
|
||||||
|
local pos2_c = metaball.pos + metaball.radius
|
||||||
|
if i == 1 then
|
||||||
|
pos1 = pos1_c
|
||||||
|
pos2 = pos2_c
|
||||||
|
end
|
||||||
|
pos1 = Vector3.min(pos1, pos1_c)
|
||||||
|
pos2 = Vector3.max(pos2, pos2_c)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- pos2 will always have the highest co-ordinates now
|
||||||
|
|
||||||
|
-- Fetch the nodes in the specified area
|
||||||
|
local manip, area = worldedit.manip_helpers.init(pos1, pos2)
|
||||||
|
local data = manip:get_data()
|
||||||
|
|
||||||
|
local node_id_replace = minetest.get_content_id(replace_node)
|
||||||
|
|
||||||
|
|
||||||
|
local replaced = 0
|
||||||
|
for z = pos2.z, pos1.z, -1 do
|
||||||
|
for y = pos2.y, pos1.y, -1 do
|
||||||
|
for x = pos2.x, pos1.x, -1 do
|
||||||
|
local pos_here = Vector3.new(x, y, z)
|
||||||
|
|
||||||
|
local metaball_sum = 0
|
||||||
|
for i,metaball in ipairs(metaballs) do
|
||||||
|
local distance_sq = (metaball.pos - pos_here):length_squared()
|
||||||
|
local radius_sq = metaball.radius * metaball.radius
|
||||||
|
local falloff = (1 / (distance_sq/radius_sq)) ^ 2
|
||||||
|
metaball_sum = metaball_sum + falloff
|
||||||
|
end
|
||||||
|
|
||||||
|
if metaball_sum <= threshold then
|
||||||
|
data[area:index(x, y, z)] = node_id_replace
|
||||||
|
replaced = replaced + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Save the modified nodes back to disk & return
|
||||||
|
worldedit.manip_helpers.finish(manip, data)
|
||||||
|
|
||||||
|
return true, replaced
|
||||||
|
end
|
Loading…
Reference in a new issue