mirror of
https://github.com/Uberi/Minetest-WorldEdit.git
synced 2025-07-14 05:40:23 +02:00
Added 6D facedir management and changed rotate and flip behavior concerning orientation
This commit is contained in:
@ -4,6 +4,56 @@
|
||||
local mh = worldedit.manip_helpers
|
||||
|
||||
|
||||
local facedir_substitutions = {
|
||||
['flip'] = {
|
||||
['x'] = {[0]=0, 3, 2, 1, 4, 5, 6, 7, 8, 11, 10, 9, 16, 19, 18, 17, 12, 15, 14, 13, 20, 23, 22, 21},
|
||||
['y'] = {[0]=20, 23, 22, 21, 6, 5, 4, 7, 10, 9, 8, 11, 12, 15, 14, 13, 16, 19, 18, 17, 0, 3, 2, 1},
|
||||
['z'] = {[0]=2, 1, 0, 3, 10, 9, 8, 11, 6, 5, 4, 7, 14, 13, 12, 15, 18, 17, 16, 19, 22, 21, 20, 23}
|
||||
},
|
||||
['rotate'] = {
|
||||
['x'] = {
|
||||
[90] = {[0]=8, 9, 10, 11, 0, 1, 2, 3, 22, 23, 20, 21, 15, 12, 13, 14, 17, 18, 19, 16, 6, 7, 4, 5},
|
||||
[180] = {[0]=22, 23, 20, 21, 8, 9, 10, 11, 4, 5, 6, 7, 14, 15, 12, 13, 18, 19, 16, 17, 2, 3, 0, 1},
|
||||
[270] = {[0]=4, 5, 6, 7, 22, 23, 20, 21, 0, 1, 2, 3, 13, 14, 15, 12, 19, 16, 17, 18, 10, 11, 8, 9}
|
||||
},
|
||||
['y'] = {
|
||||
[90] = {[0]=1, 2, 3, 0, 13, 14, 15, 12, 17, 18, 18, 16, 9, 10, 11, 8, 5, 6, 7, 4, 23, 20, 21, 22},
|
||||
[180] = {[0]=2, 3, 0, 1, 10, 11, 8, 9, 6, 7, 7, 5, 18, 18, 16, 17, 14, 15, 12, 13, 22, 23, 20, 21},
|
||||
[270] = {[0]=3, 0, 1, 2, 18, 16, 17, 18, 15, 12, 12, 14, 7, 7, 5, 6, 11, 8, 9, 10, 21, 22, 23, 20}
|
||||
},
|
||||
['z'] = {
|
||||
[90] = {[0]=12, 13, 14, 15, 7, 4, 5, 6, 9, 10, 11, 8, 20, 21, 22, 23, 0, 1, 2, 3, 16, 17, 18, 19},
|
||||
[180] = {[0]=20, 21, 22, 23, 6, 7, 4, 5, 10, 11, 8, 9, 16, 17, 18, 19, 12, 13, 14, 15, 0, 1, 2, 3},
|
||||
[270] = {[0]=16, 17, 18, 19, 5, 6, 7, 4, 11, 8, 9, 10, 0, 1, 2, 3, 20, 21, 22, 23, 12, 13, 14, 15}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
local wallmounted_substitutions = {
|
||||
['flip'] = {
|
||||
['x'] = {[0]=1, 0, 3, 2, 4, 5},
|
||||
['y'] = {[0]=0, 1, 2, 3, 4, 5},
|
||||
['z'] = {[0]=0, 1, 2, 3, 5, 4}
|
||||
},
|
||||
['rotate'] = {
|
||||
['x'] = {
|
||||
[90] = {[0]=5, 4, 2, 3, 0, 1},
|
||||
[180] = {[0]=1, 0, 2, 3, 5, 4},
|
||||
[270] = {[0]=4, 5, 2, 3, 1, 0}
|
||||
},
|
||||
['y'] = {
|
||||
[90] = {[0]=0, 1, 5, 4, 2, 3},
|
||||
[180] = {[0]=0, 1, 3, 2, 5, 4},
|
||||
[270] = {[0]=0, 1, 4, 5, 3, 2}
|
||||
},
|
||||
['z'] = {
|
||||
[90] = {[0]=2, 3, 1, 0, 4, 5},
|
||||
[180] = {[0]=1, 0, 3, 2, 4, 5},
|
||||
[270] = {[0]=3, 2, 0, 1, 4, 5}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
--- Sets a region to `node_names`.
|
||||
-- @param pos1
|
||||
-- @param pos2
|
||||
@ -336,7 +386,6 @@ function worldedit.stretch(pos1, pos2, stretch_x, stretch_y, stretch_z)
|
||||
return worldedit.volume(pos1, pos2) * stretch_x * stretch_y * stretch_z, pos1, new_pos2
|
||||
end
|
||||
|
||||
|
||||
--- Transposes a region between two axes.
|
||||
-- @return The number of nodes transposed.
|
||||
-- @return The new transposed position 1.
|
||||
@ -399,9 +448,9 @@ function worldedit.transpose(pos1, pos2, axis1, axis2)
|
||||
end
|
||||
|
||||
|
||||
--- Flips a region along `axis`.
|
||||
--- Flips a region along `axis`. Flips only nodes, no change on nodes orientations
|
||||
-- @return The number of nodes flipped.
|
||||
function worldedit.flip(pos1, pos2, axis)
|
||||
function worldedit.flipnodes(pos1, pos2, axis)
|
||||
local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
|
||||
|
||||
worldedit.keep_loaded(pos1, pos2)
|
||||
@ -437,68 +486,42 @@ function worldedit.flip(pos1, pos2, axis)
|
||||
return worldedit.volume(pos1, pos2)
|
||||
end
|
||||
|
||||
|
||||
--- Rotates a region clockwise around an axis.
|
||||
-- @param pos1
|
||||
-- @param pos2
|
||||
-- @param axis Axis ("x", "y", or "z").
|
||||
-- @param angle Angle in degrees (90 degree increments only).
|
||||
-- @return The number of nodes rotated.
|
||||
-- @return The new first position.
|
||||
-- @return The new second position.
|
||||
function worldedit.rotate(pos1, pos2, axis, angle)
|
||||
local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
|
||||
|
||||
local other1, other2 = worldedit.get_axis_others(axis)
|
||||
angle = angle % 360
|
||||
|
||||
local count
|
||||
if angle == 90 then
|
||||
worldedit.flip(pos1, pos2, other1)
|
||||
count, pos1, pos2 = worldedit.transpose(pos1, pos2, other1, other2)
|
||||
elseif angle == 180 then
|
||||
worldedit.flip(pos1, pos2, other1)
|
||||
count = worldedit.flip(pos1, pos2, other2)
|
||||
elseif angle == 270 then
|
||||
worldedit.flip(pos1, pos2, other2)
|
||||
count, pos1, pos2 = worldedit.transpose(pos1, pos2, other1, other2)
|
||||
else
|
||||
error("Only 90 degree increments are supported!")
|
||||
end
|
||||
return count, pos1, pos2
|
||||
end
|
||||
|
||||
|
||||
--- Rotates all oriented nodes in a region clockwise around the Y axis.
|
||||
--- Change orientation of all oriented nodes in a region.
|
||||
-- @param pos1
|
||||
-- @param pos2
|
||||
-- @param operation Kind of operation : flip or rotate.
|
||||
-- @param axis Orientation axis : x, y or z
|
||||
-- @param angle Angle in degrees (90 degree increments only).
|
||||
-- @return The number of nodes oriented.
|
||||
-- TODO: Support 6D facedir rotation along arbitrary axis.
|
||||
function worldedit.orient(pos1, pos2, angle)
|
||||
--- TODO : When flipping, try to manage diametral symetric nodes (should be rotated instead of flipped)
|
||||
function worldedit.orient(pos1, pos2, operation, axis, angle)
|
||||
local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
|
||||
local registered_nodes = minetest.registered_nodes
|
||||
|
||||
local wallmounted = {
|
||||
[90] = {[0]=0, 1, 5, 4, 2, 3},
|
||||
[180] = {[0]=0, 1, 3, 2, 5, 4},
|
||||
[270] = {[0]=0, 1, 4, 5, 3, 2}
|
||||
}
|
||||
local facedir = {
|
||||
[90] = {[0]=1, 2, 3, 0},
|
||||
[180] = {[0]=2, 3, 0, 1},
|
||||
[270] = {[0]=3, 0, 1, 2}
|
||||
}
|
||||
if axis ~= 'x' and axis ~= 'y' and axis ~= 'z' then
|
||||
error("Axis should be 'x', 'y' or 'z'!")
|
||||
end
|
||||
|
||||
angle = angle % 360
|
||||
if angle == 0 then
|
||||
return 0
|
||||
local facedir_substitution
|
||||
local wallmounted_substitution
|
||||
|
||||
if operation == "rotate" then
|
||||
angle = angle % 360
|
||||
if angle == 0 then
|
||||
return
|
||||
else
|
||||
if angle % 90 ~= 0 then
|
||||
error("Only 90 degree increments are supported!")
|
||||
end
|
||||
facedir_substitution = facedir_substitutions[operation][axis][angle]
|
||||
wallmounted_substitution = wallmounted_substitutions[operation][axis][angle]
|
||||
end
|
||||
elseif operation == "flip" then
|
||||
facedir_substitution = facedir_substitutions[operation][axis]
|
||||
wallmounted_substitution = wallmounted_substitutions[operation][axis]
|
||||
else
|
||||
error("Operation should be 'rotate' or 'flip'!")
|
||||
end
|
||||
if angle % 90 ~= 0 then
|
||||
error("Only 90 degree increments are supported!")
|
||||
end
|
||||
local wallmounted_substitution = wallmounted[angle]
|
||||
local facedir_substitution = facedir[angle]
|
||||
|
||||
worldedit.keep_loaded(pos1, pos2)
|
||||
|
||||
@ -537,6 +560,48 @@ function worldedit.orient(pos1, pos2, angle)
|
||||
return count
|
||||
end
|
||||
|
||||
--- Rotates a region clockwise around an axis. Oriented nodes are rotated accordingly.
|
||||
-- @param pos1
|
||||
-- @param pos2
|
||||
-- @param axis Axis ("x", "y", or "z").
|
||||
-- @param angle Angle in degrees (90 degree increments only).
|
||||
-- @return The number of nodes rotated.
|
||||
-- @return The new first position.
|
||||
-- @return The new second position.
|
||||
function worldedit.rotate(pos1, pos2, axis, angle)
|
||||
local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
|
||||
|
||||
local other1, other2 = worldedit.get_axis_others(axis)
|
||||
angle = angle % 360
|
||||
|
||||
local count
|
||||
if angle == 90 then
|
||||
worldedit.flipnodes(pos1, pos2, other1)
|
||||
count, pos1, pos2 = worldedit.transpose(pos1, pos2, other1, other2)
|
||||
elseif angle == 180 then
|
||||
worldedit.flipnodes(pos1, pos2, other1)
|
||||
count = worldedit.flipnodes(pos1, pos2, other2)
|
||||
elseif angle == 270 then
|
||||
worldedit.flipnodes(pos1, pos2, other2)
|
||||
count, pos1, pos2 = worldedit.transpose(pos1, pos2, other1, other2)
|
||||
else
|
||||
error("Only 90 degree increments are supported!")
|
||||
end
|
||||
worldedit.orient(pos1, pos2, "rotate", axis, angle)
|
||||
return count, pos1, pos2
|
||||
end
|
||||
|
||||
--- Flips a region along `axis`. Oriented nodes are flipped accordingly.
|
||||
-- @param pos1
|
||||
-- @param pos2
|
||||
-- @param axis Axis ("x", "y", or "z").
|
||||
-- @return The number of nodes flipped.
|
||||
function worldedit.flip(pos1, pos2, axis)
|
||||
local count
|
||||
count = worldedit.flipnodes(pos1, pos2, axis)
|
||||
worldedit.orient(pos1, pos2, "flip", axis, 0)
|
||||
return count
|
||||
end
|
||||
|
||||
--- Attempts to fix the lighting in a region.
|
||||
-- @return The number of nodes updated.
|
||||
|
Reference in New Issue
Block a user