From d49f6d2131770fff94c08e0e6a589dbc38374fa9 Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Tue, 17 Sep 2024 23:18:37 +0100 Subject: [PATCH] Lift orientation functions from screwdriver2 mod Ref @12Me21 https://github.com/12Me21/screwdriver2/blob/master/init.lua#L75-L79 Ref @khonkhortisan https://forum.minetest.net/viewtopic.php?p=73195&sid=1d2d2e4e76ce2ef9c84646481a4b84bc#p73195 ....if either of you have an issue with this, please get in touch! The licence seems to allow this lifting and relicencing like this (given it's WTFPL as of the time of typing), but correct me if I'm wrong. For reference, WorldEditAdditions is currently licenced under the Mozilla Public License Version 2.0. --- worldeditadditions_core/init.lua | 1 + worldeditadditions_core/utils/orientation.lua | 72 +++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 worldeditadditions_core/utils/orientation.lua diff --git a/worldeditadditions_core/init.lua b/worldeditadditions_core/init.lua index 6274a8f..d2463ef 100644 --- a/worldeditadditions_core/init.lua +++ b/worldeditadditions_core/init.lua @@ -30,6 +30,7 @@ wea_c.Set = dofile(wea_c.modpath.."/utils/set.lua") wea_c.Vector3 = dofile(wea_c.modpath.."/utils/vector3.lua") wea_c.Mesh, wea_c.Face = dofile(wea_c.modpath.."/utils/mesh.lua") wea_c.rotation = dofile(wea_c.modpath .. "/utils/rotation.lua") +wea_c.orientation = dofile(wea_c.modpath .. "/utils/orientation.lua") wea_c.param2 = dofile(wea_c.modpath .. "/utils/param2.lua") wea_c.Queue = dofile(wea_c.modpath.."/utils/queue.lua") diff --git a/worldeditadditions_core/utils/orientation.lua b/worldeditadditions_core/utils/orientation.lua new file mode 100644 index 0000000..491670c --- /dev/null +++ b/worldeditadditions_core/utils/orientation.lua @@ -0,0 +1,72 @@ + + +-- This file is based on code from the screwdriver2 mod and a forum post on the Minetest forums. By @12Me21 and @khonkhortisan +-- Edited by @sbrl +-- Ref https://github.com/12Me21/screwdriver2/blob/master/init.lua#L75-L79 +-- Ref https://forum.minetest.net/viewtopic.php?p=73195&sid=1d2d2e4e76ce2ef9c84646481a4b84bc#p73195 + +local facedir_cycles = { + x = { { 12, 13, 14, 15 }, { 16, 19, 18, 17 }, { 0, 4, 22, 8 }, { 1, 5, 23, 9 }, { 2, 6, 20, 10 }, { 3, 7, 21, 11 } }, + y = { { 0, 1, 2, 3 }, { 20, 23, 22, 21 }, { 4, 13, 10, 19 }, { 8, 17, 6, 15 }, { 12, 9, 18, 7 }, { 16, 5, 14, 11 } }, + z = { { 4, 5, 6, 7 }, { 8, 11, 10, 9 }, { 0, 16, 20, 12 }, { 1, 17, 21, 13 }, { 2, 18, 22, 14 }, { 3, 19, 23, 15 } }, +} +local wallmounted_cycles = { + x = { 0, 4, 1, 5 }, + y = { 4, 2, 5, 3 }, + z = { 0, 3, 1, 2 }, +} + +-- We have standardised on radians for other rotation operations, so it wouldn't make sense for the API-facing functions in this file to use a number of times or degrees, as this would be inconsistent +function convert_normalise_rad(rad) + local deg = math.deg(rad) + local times = worldeditadditions_core.round(deg / 90) + return math.floor(times) -- ensure it's an integer and not e.g. a float 1.0 +end + +--- Functions to rotate a facedir/wallmounted value around an axis by a certain amount +-- +-- Code lifted from @12Me21 and @khonkhortisan +-- +-- Ref and +-- @namespace worldeditadditions_core.orientation +local orientation = { + --- Facedir: lower 5 bits used for direction, 0 - 23 + -- @param param2 number `param2` value to rotate. + -- @param axis string The name of the axis to rotate around. Valid values: `x`, `y`, `z` + -- @param amount The number of radians to rotate around the given `axis`. Only right angles are supported (i.e. 90° increments). Any value that isn't a 90° increment will be **rounded**! + -- @returns number A new param2 value that is rotated the given number of degrees around the given `axis` + facedir = function(param2, axis, amount_rad) + local amount = convert_normalise_rad(amount_rad) + print("DEBUG:core/orientation:facedir AMOUNT rad "..tostring(amount_rad).." norm "..tostring(amount)) + local facedir = param2 % 32 + for _, cycle in ipairs(facedir_cycles[axis]) do + -- Find the current facedir + -- Minetest adds table.indexof, but I refuse to use it because it returns -1 rather than nil + for i, fd in ipairs(cycle) do + if fd == facedir then + return param2 - facedir + cycle[1 + (i - 1 + amount) % 4] -- If only Lua didn't use 1 indexing... + end + end + end + return param2 + end, + -- Wallmounted: lower 3 bits used, 0 - 5 + wallmounted = function(param2, axis, amount_rad) + local amount = convert_normalise_rad(amount_rad) + print("DEBUG:core/orientation:wallmounted AMOUNT rad " .. tostring(amount_rad) .. " norm " .. tostring(amount)) + + local wallmounted = param2 % 8 + for i, wm in ipairs(wallmounted_cycles[axis]) do + if wm == wallmounted then + return param2 - wallmounted + wallmounted_cycles[axis][1 + (i - 1 + amount) % 4] + end + end + return param2 + end +} +-- From the original codebase (linked above): +--orientation.colorfacedir = orientation.facedir +--orientation.colorwallmounted = orientation.wallmounted +-- ...we'll need to know this later + +return orientation