mesecons_x/mesecons_autotools/book/m3.lua
2022-01-28 14:53:26 +01:00

307 lines
7.7 KiB
Lua

function m3_get(m,x,y,z)
if m == nil then return nil end
if m[x] == nil then return nil end
if m[x][y] == nil then return nil end
if m[x][y][z] == nil then return nil end
return m[x][y][z]
end
function m3_set(m,x,y,z,value)
if m == nil then m = {} end
if m[x] == nil then m[x] = {} end
if m[x][y] == nil then m[x][y] = {} end
if m[x][y][z] == nil then m[x][y][z] = {} end
m[x][y][z] = value
end
--[[
function m3_set_pos(m,pos1,pos2)
m.pos1 = pos1
m.pos2 = pos2
end
]]--
function m3_flip_xy(m)
local new_m = {}
for ix=1,m.sx do
for iz=1,m.sz do
for iy=1,m.sy do
m3_set(new_m,iz,iy,ix, m3_get(m,ix,iy,iz))
end
end
end
--[[
-- Rotate node
for ix=1,m.sx do
for iz=1,m.sz do
for iy=1,m.sy do
local node = m3_get(m,ix,iy,iz)
local rotated_node =
rotate_node_to_direction(node,{x=1,y=0,z=0})
m3_set(m,ix,iy,iz,rotated_node)
end
end
end
]]--
new_m.sx = m.sz
new_m.sz = m.sx
new_m.sy = m.sy
return new_m
end
function m3_flip_x(m)
local new_m = {}
for ix=1,m.sx do
for iz=1,m.sz do
for iy=1,m.sy do
m3_set(new_m,ix,iy,m.sz-iz+1, m3_get(m,ix,iy,iz))
end
end
end
--[[
for ix=1,m.sx do
for iz=1,m.sz do
for iy=1,m.sy do
local node = m3_get(m,ix,iy,iz)
local rotated_node =
rotate_node_to_direction(node,{x=0,y=0,z=-1})
m3_set(m,ix,iy,iz,rotated_node)
end
end
end
]]--
new_m.sx = m.sx
new_m.sz = m.sz
new_m.sy = m.sy
return new_m
end
function m3_rotate90(m)
return m3_flip_x( m3_flip_xy (m))
end
function m3_rotate180(m)
return m3_rotate90(m3_rotate90(m))
end
function m3_rotate270(m)
return m3_rotate90(m3_rotate90(m3_rotate90(m)))
end
function rotate_m3(m,direction)
if direction.x == 1 then
return m3_rotate270(m)
end
if direction.x == -1 then
return m3_rotate90(m)
end
if direction.z == 1 then
return m
end
if direction.z == -1 then
return m3_rotate180(m)
end
return m
end
function m3_move_to_000(m)
local new_m = {}
local pos1 = m.pos1
local pos2 = m.pos2
local xmin = math.min(pos1.x,pos2.x)
local ymin = math.min(pos1.y,pos2.y)
local zmin = math.min(pos1.z,pos2.z)
local xmax = math.max(pos1.x,pos2.x)
local ymax = math.max(pos1.y,pos2.y)
local zmax = math.max(pos1.z,pos2.z)
local sx = xmax - xmin + 1
local sy = ymax - ymin + 1
local sz = zmax - zmin + 1
for x=1,sx,1 do
for y=1,sy,1 do
for z=1,sz,1 do
m3_set(new_m,x,y,z,
m3_get(m, x-1 + xmin, y-1 + ymin, z-1+zmin))
end
end
end
new_m.sx = sx
new_m.sy = sy
new_m.sz = sz
return new_m
end
function selection_to_m3(pos1,pos2,direction)
local m = {}
iterate_selection(pos1,pos2,function(pos)
local node = minetest.get_node(pos)
m3_set(m,pos.x,pos.y,pos.z,node)
end)
m.pos1 = pos1
m.pos2 = pos2
m = m3_move_to_000(m)
m = rotate_m3(m,direction)
for ix=1,m.sx do
for iz=1,m.sz do
for iy=m.sy,1,-1 do
local node = m3_get(m,ix,iy,iz)
local rotated_node = rotate_node_to_direction(node,direction)
m3_set(m,ix,iy,iz,rotated_node)
end
end
end
return m
end
function selection_to_m3_meta(pos1,pos2,direction)
local m = {}
iterate_selection(pos1,pos2,function(pos)
local meta = minetest.get_meta(pos):to_table()
m3_set(m,pos.x,pos.y,pos.z,meta)
end)
m.pos1 = pos1
m.pos2 = pos2
m = m3_move_to_000(m)
m = rotate_m3(m,direction)
return m
end
function m3_to_mx(m)
local mx={}
for ix=1,m.sx do
for iz=1,m.sz do
for iy=m.sy,1,-1 do
local pos = { x = ix, y=iy, z = iz }
local node = m3_get(m,ix,iy,iz)
if node.name ~= "air" then
mx_set(mx,ix,iz,node)
break
end
end
end
end
mx.w = m.sx
mx.h = m.sz
return mx
end
local function lmin(a,b)
if a == nil then
return b
else
if b == nil then
return a
else
return math.min(a,b)
end
end
end
local function lmax(a,b)
if a == nil then
return b
else
if b == nil then
return a
else
return math.max(a,b)
end
end
end
function list_to_m3(list)
local m = {}
local xmin,xmax,ymin,ymax,zmin,zmax
for _,v in pairs(list) do
local pos = v.pos
local node = v.node
m3_set(m,pos.x,pos.y,pos.z, node)
xmin = lmin(xmin, pos.x)
ymin = lmin(ymin, pos.y)
zmin = lmin(zmin, pos.z)
xmax = lmax(xmax, pos.x)
ymax = lmax(ymax, pos.y)
zmax = lmax(zmax, pos.z)
end
m.pos1 = {x=xmin,y=ymin,z=zmin}
m.pos2 = {x=xmax,y=ymax,z=zmax}
return m
end
function iterate_m3(m,action)
for x=1,m.sx do
for y=1,m.sy do
for z=1,m.sz do
action(m3_get(m,x,y,z))
end
end
end
end
function m3_insert(mbase, melement, x,y,z)
local sx = melement.sx
local sy = melement.sy
local sz = melement.sz
for xi=1,sx do
for yi=1,sy do
for zi=1,sz do
if m3_get(melement,xi,yi,zi) ~= nil then
m3_set(mbase,x+xi-1,y+yi-1,z+zi-1, m3_get(melement,xi,yi,zi))
end
end
end
end
mbase.sx = math.max(mbase.sx, x+sx-1)
mbase.sy = math.max(mbase.sy, y+sy-1)
mbase.sz = math.max(mbase.sz, z+sz-1)
end