mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-09-19 19:38:31 +02:00
b56bd0d84b
At some point we need to move the parser to allow for a `player` reference for relative keywords.... or else pass them through somehow
83 lines
3.2 KiB
Lua
83 lines
3.2 KiB
Lua
local weac = worldeditadditions_core
|
|
local Vector3 = weac.Vector3
|
|
|
|
-- From worldedit_hub_helper.
|
|
-- Written by me, @sbrl and just lifted :-)
|
|
local function calc_rotation_text(rotation)
|
|
if rotation <= math.pi / 4 or rotation >= (7 * math.pi) / 4 then
|
|
return Vector3.new(0, 0, 1) -- +z
|
|
elseif rotation > math.pi / 4 and rotation <= (3 * math.pi) / 4 then
|
|
return Vector3.new(-1, 0, 0) -- -x
|
|
elseif rotation > (3 * math.pi) / 4 and rotation <= (5 * math.pi) / 4 then
|
|
return Vector3.new(0, 0, -1) -- -z
|
|
else
|
|
return Vector3.new(1, 0, 0) -- +x
|
|
end
|
|
end
|
|
|
|
function rot_axis_left(axis)
|
|
if axis.x == 1 or axis.x == -1 then
|
|
axis.x, axis.z = 0, axis.x
|
|
elseif axis.z == 1 or axis.z == -1 then
|
|
axis.x, axis.z = -axis.z, 0
|
|
end
|
|
return axis -- CAUTION, this function mutates!
|
|
end
|
|
|
|
--- Parses an axis name into a string.
|
|
-- Currently handles:
|
|
-- - x/y/z -x/-y/-z
|
|
-- - front → downwards pitch
|
|
-- - back → upwards pitch
|
|
-- - left → rotate around Z to left
|
|
-- - right → rotate around Z to right
|
|
-- - pitch, yaw, roll - clockwise is considered positive.
|
|
-- @param str string The axis to parse, as a single (pre-trimmed) string.
|
|
-- @param [player=nil] Player Optional. A Minetest Player object representing the player to make any relative keywords like front-back/pitch/roll/etc relative to in parsing. Defautls to nil, which disables parsing of relatiive terms. Any object passed just needs to support player:get_look_horizontal(): https://github.com/minetest/minetest/blob/master/doc/lua_api.md#player-only-no-op-for-other-objects
|
|
-- @returns bool,Vector3|string A success bool (false=failure) followed by either an error message (if success=false) or otherwise the axis name, parsed into a Vector3 instance.
|
|
local function parse_rotation_axis_name(str, player)
|
|
local vector = Vector3.new(0, 0, 0)
|
|
|
|
-- At most ONE of these cases is true at a time.
|
|
-- Even if it were possible to handle more than one (which it isn't without quaternions which aren't used in the backend), we would have an undefined ordering problem with the application of such rotations. Rotations ≠ translations in this case!
|
|
if str:find("x", 1, true) then vector.x = 1
|
|
elseif str:find("y", 1, true) then vector.y = 1
|
|
elseif str:find("z", 1, true) then vector.z = 1
|
|
elseif str:find("left", 1, true)
|
|
or str:find("l$") then vector.y = -1
|
|
elseif str:find("right", 1, true)
|
|
or str:find("r$")
|
|
or str:find("yaw") then vector.y = 1
|
|
elseif type(player) ~= "nil" then
|
|
local player_rotation_h = calc_rotation_text(player:get_look_horizontal())
|
|
|
|
-- FRONT BACK
|
|
|
|
if str:find("front", 1, true)
|
|
or str:find("f$")
|
|
or str:find("pitch", 1, true) then
|
|
vector = rot_axis_left(player_rotation_h)
|
|
elseif str:find("back", 1, true)
|
|
or str:find("b$") then
|
|
vector = rot_axis_left(player_rotation_h) * -1
|
|
elseif str:find("roll", 1, true) then
|
|
vector = player_rotation_h
|
|
else
|
|
return false, "Error: Could not understand rotational axis keyword '"..str.."'."
|
|
end
|
|
else
|
|
return false, "Error: Could not understand rotational axis keyword '" .. str .. "'."
|
|
end
|
|
|
|
--- Handle negatives
|
|
if str:sub(1, 1) == "-" then
|
|
vector = vector * -1
|
|
end
|
|
|
|
return true, vector
|
|
end
|
|
|
|
|
|
return {
|
|
axis_name = parse_rotation_axis_name
|
|
} |