rotate facedir refactoring/test

This commit is contained in:
BuckarooBanzay 2022-04-01 13:53:46 +02:00
parent 56237af170
commit dce4804789
4 changed files with 78 additions and 51 deletions

View File

@ -15,6 +15,7 @@ dofile(MP .. "/context/dome.lua")
dofile(MP .. "/context/slope.lua")
dofile(MP .. "/context/cylinder.lua")
dofile(MP .. "/origin.lua")
dofile(MP .. "/rotate_facedir.lua")
dofile(MP .. "/transform.lua")
dofile(MP .. "/chat/load.lua")
dofile(MP .. "/chat/origin.lua")

50
rotate_facedir.lua Normal file
View File

@ -0,0 +1,50 @@
-- https://github.com/minetest/minetest/pull/11932 / https://github.com/aerkiaga
-- Map each facedir to the result of applying
-- right-hand rotation around y+ or z+ vector
local rotated_facedir_map = {
["y+"] = {
[0] = 3, 0, 1, 2,
19, 16, 17, 18,
15, 12, 13, 14,
7, 4, 5, 6,
11, 8, 9, 10,
21, 22, 23, 20
},
["z+"] = {
[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,
},
}
-- Map rotations on all 6 orthogonal vectors to
-- rotations around just y+ and z+
local vector_lambda_map = {
["x+"] = function (f, r, x)
return f(3, "y+", f(r, "z+", f(1, "y+", x))) end,
["x-"] = function (f, r, x)
return f(1, "y+", f(r, "z+", f(3, "y+", x))) end,
["y+"] = function (f, r, x)
return f(r, "y+", x) end,
["y-"] = function (f, r, x)
return f(4 - r, "y+", x) end,
["z+"] = function (f, r, x)
return f(r, "z+", x) end,
["z-"] = function (f, r, x)
return f(4 - r, "z+", x) end,
}
function mtscad.rotate_facedir(rotation, vector_name, facedir)
facedir = facedir or 0
local function lookup_function(r, n, x)
if r == 0 then return x end
return lookup_function(r - 1, n, rotated_facedir_map[n][x])
end
local translation_function = vector_lambda_map[vector_name]
or function () return nil end
return translation_function(lookup_function, rotation % 4, facedir)
end

View File

@ -0,0 +1,26 @@
require("mineunit")
mineunit("core")
sourcefile("init")
describe("mtscad.rotate_facedir() test", function()
it("various rotation tests", function()
-- y axis
assert.equal(3, mtscad.rotate_facedir(1, "y+", 0)) -- 90° ccw
assert.equal(2, mtscad.rotate_facedir(2, "y+", 0)) -- 180° ccw
assert.equal(1, mtscad.rotate_facedir(3, "y+", 0)) -- 270° ccw
assert.equal(0, mtscad.rotate_facedir(4, "y+", 0)) -- 360° ccw
-- x axis
assert.equal(8, mtscad.rotate_facedir(1, "x+", 0)) -- 90° ccw
assert.equal(22, mtscad.rotate_facedir(2, "x+", 0)) -- 180° ccw
assert.equal(4, mtscad.rotate_facedir(3, "x+", 0)) -- 270° ccw
assert.equal(0, mtscad.rotate_facedir(4, "x+", 0)) -- 360° ccw
-- z axis
assert.equal(12, mtscad.rotate_facedir(1, "z+", 0)) -- 90° ccw
assert.equal(20, mtscad.rotate_facedir(2, "z+", 0)) -- 180° ccw
assert.equal(16, mtscad.rotate_facedir(3, "z+", 0)) -- 270° ccw
assert.equal(0, mtscad.rotate_facedir(4, "z+", 0)) -- 360° ccw
end)
end)

View File

@ -56,56 +56,6 @@ local wallmounted = {
[270] = {0, 1, 4, 5, 3, 2, 0, 0}
}
-- https://github.com/minetest/minetest/pull/11932 / https://github.com/aerkiaga
-- Map each facedir to the result of applying
-- right-hand rotation around y+ or z+ vector
local rotated_facedir_map = {
["y+"] = {
[0] = 3, 0, 1, 2,
19, 16, 17, 18,
15, 12, 13, 14,
7, 4, 5, 6,
11, 8, 9, 10,
21, 22, 23, 20
},
["z+"] = {
[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,
},
}
-- Map rotations on all 6 orthogonal vectors to
-- rotations around just y+ and z+
local vector_lambda_map = {
["x+"] = function (f, r, x)
return f(3, "y+", f(r, "z+", f(1, "y+", x))) end,
["x-"] = function (f, r, x)
return f(1, "y+", f(r, "z+", f(3, "y+", x))) end,
["y+"] = function (f, r, x)
return f(r, "y+", x) end,
["y-"] = function (f, r, x)
return f(4 - r, "y+", x) end,
["z+"] = function (f, r, x)
return f(r, "z+", x) end,
["z-"] = function (f, r, x)
return f(4 - r, "z+", x) end,
}
local function rotate_facedir(rotation, vector_name, facedir)
facedir = facedir or 0
local function lookup_function(r, n, x)
if r == 0 then return x end
return lookup_function(r - 1, n, rotated_facedir_map[n][x])
end
local translation_function = vector_lambda_map[vector_name]
or function () return nil end
return translation_function(lookup_function, rotation % 4, facedir)
end
local function transform_node_axis(node, axis, angle)
angle = angle % 360
if angle == 0 then
@ -125,7 +75,7 @@ local function transform_node_axis(node, axis, angle)
wallmounted_substitution[orient + 1]
elseif paramtype2 == "facedir" or paramtype2 == "colorfacedir" then
node.param2 = rotate_facedir(math.floor(angle / 90), axis, node.param2)
node.param2 = mtscad.rotate_facedir(math.floor(angle / 90), axis, node.param2)
end
end