179 lines
6.6 KiB
Lua
179 lines
6.6 KiB
Lua
|
--[[
|
||
|
Copyright (c) 2015, Robert 'Bobby' Zenz
|
||
|
All rights reserved.
|
||
|
|
||
|
Redistribution and use in source and binary forms, with or without
|
||
|
modification, are permitted provided that the following conditions are met:
|
||
|
|
||
|
* Redistributions of source code must retain the above copyright notice, this
|
||
|
list of conditions and the following disclaimer.
|
||
|
|
||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||
|
this list of conditions and the following disclaimer in the documentation
|
||
|
and/or other materials provided with the distribution.
|
||
|
|
||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
--]]
|
||
|
|
||
|
|
||
|
--- Various functions for rotating nodes.
|
||
|
--
|
||
|
-- The internal mechanics of Minetest are as follows: It uses the facedir value
|
||
|
-- to apply an rotation. It is value with the minimum of 0 (no rotation) to
|
||
|
-- the maximum of 23 (1 0 1 1 1). It consists of two parts, the lower two bits
|
||
|
-- are the amount of rotation applied:
|
||
|
--
|
||
|
-- Bits Value Description
|
||
|
-- 0 0 0 No rotation
|
||
|
-- 0 1 1 90 degrees (sign depending on axis, + for z+ x- y-)
|
||
|
-- 1 0 2 180 degrees
|
||
|
-- 1 1 3 -90 degrees (sign depending on axis, + for z- x+ y+)
|
||
|
--
|
||
|
-- These values correspond to the ROT_* constants.
|
||
|
--
|
||
|
-- The upper three bits are the axis that is used:
|
||
|
--
|
||
|
-- Bits Value Shifted Description
|
||
|
-- 0 0 0 0 0 y+, no rotation
|
||
|
-- 0 0 1 1 4 z+, 90 degrees clockwise around x
|
||
|
-- 0 1 0 2 8 z-, 90 degrees counter-clockwise around x
|
||
|
-- 0 1 1 3 12 x+, 90 degrees counter-clockwise around z
|
||
|
-- 1 0 0 4 16 x-, 90 degrees clockwise around z
|
||
|
-- 1 0 1 5 20 y-, 180 degrees counter-clockwise around x
|
||
|
--
|
||
|
-- These values correspond to the POS_* and NEG_* constants.
|
||
|
--
|
||
|
-- The rotation is a two step process, first the rotation of the axis/upper
|
||
|
-- three bits are applied, after that the rotation/lower two bits.
|
||
|
--
|
||
|
-- See the mapnode.cpp/transformNodeBox function for even more details.
|
||
|
rotationutil = {
|
||
|
--- The negative X Axis. Will rotate the node around the Z axis by
|
||
|
-- 90 degrees clockwise before the additional rotation is applied.
|
||
|
--
|
||
|
-- Minetest internal it has the value 4, within facedir it is 16 (1 0 0 R R).
|
||
|
NEG_X = 16,
|
||
|
--- The negative Z Axis. Will rotate the node around the X axis by
|
||
|
-- 90 degrees counter-clockwise before the additional rotation is applied.
|
||
|
--
|
||
|
-- Minetest internal it has the value 2, within facedir it is 8 (0 1 0 R R).
|
||
|
NEG_Z = 8,
|
||
|
--- The negative Y Axis. Will rotate the node around the Z axis by
|
||
|
-- 180 degrees counter-clockwise before the additional rotation is applied.
|
||
|
--
|
||
|
-- Minetest internal it has the value 5, within the bitmask of facedir it
|
||
|
-- is 20 (1 0 1 R R).
|
||
|
NEG_Y = 20,
|
||
|
--- The positive X Axis. Will rotate the node around the Z axis by
|
||
|
-- 90 degrees counter-clockwise before the additional rotation is applied.
|
||
|
--
|
||
|
-- Minetest internal it has the value 3, within facedir it is 12 (0 1 1 R R).
|
||
|
POS_X = 12,
|
||
|
--- The positive Y Axis. Will not rotate the node before the additional
|
||
|
-- rotation is applied.
|
||
|
--
|
||
|
-- Minetest internal it has the value 0, within of facedir it is 0 (0 0 0 R R).
|
||
|
POS_Y = 0,
|
||
|
--- The positive Z Axis. Will rotate the node around the X axis by
|
||
|
-- 90 degrees clockwise before the additional rotation is applied.
|
||
|
--
|
||
|
-- Minetest internal it has the value 1, within facedir it is 4 (0 0 1 R R).
|
||
|
POS_Z = 4,
|
||
|
--- No rotation.
|
||
|
ROT_0 = 0,
|
||
|
--- Rotation 90 degrees, sign depends on the axis.
|
||
|
ROT_90 = 1,
|
||
|
--- Rotation 180 degrees.
|
||
|
ROT_180 = 2,
|
||
|
--- Rotation 270/-90 degrees, sign depends on the axis.
|
||
|
ROT_270 = 3
|
||
|
}
|
||
|
|
||
|
|
||
|
--- Returns the decremented rotation, so given rotation - 90 degrees.
|
||
|
--
|
||
|
-- @param rotation The rotation to decrement.
|
||
|
-- @return The decremented rotation, or the given value if it was not valid.
|
||
|
function rotationutil.decrement(rotation)
|
||
|
if rotation == rotationutil.ROT_0 then
|
||
|
return rotationutil.ROT_270
|
||
|
elseif rotation == rotationutil.ROT_90 then
|
||
|
return rotationutil.ROT_0
|
||
|
elseif rotation == rotationutil.ROT_180 then
|
||
|
return rotationutil.ROT_90
|
||
|
elseif rotation == rotationutil.ROT_270 then
|
||
|
return rotationutil.ROT_180
|
||
|
end
|
||
|
|
||
|
return rotation
|
||
|
end
|
||
|
|
||
|
--- Creates the facedir value from the given axis and rotation.
|
||
|
--
|
||
|
-- @param axis The axis, one of the POS_* or NEG_* constants.
|
||
|
-- @param rotation The rotation, one of the ROT_* constants.
|
||
|
-- @return The facedir value.
|
||
|
function rotationutil.facedir(axis, rotation)
|
||
|
return axis + rotation
|
||
|
end
|
||
|
|
||
|
--- Returns the incremented rotation, so given rotation + 90 degrees.
|
||
|
--
|
||
|
-- @param rotation The rotation to increment.
|
||
|
-- @return The incremented rotation, or the given value if it was not valid.
|
||
|
function rotationutil.increment(rotation)
|
||
|
if rotation == rotationutil.ROT_0 then
|
||
|
return rotationutil.ROT_90
|
||
|
elseif rotation == rotationutil.ROT_90 then
|
||
|
return rotationutil.ROT_180
|
||
|
elseif rotation == rotationutil.ROT_180 then
|
||
|
return rotationutil.ROT_270
|
||
|
elseif rotation == rotationutil.ROT_270 then
|
||
|
return rotationutil.ROT_0
|
||
|
end
|
||
|
|
||
|
return rotation
|
||
|
end
|
||
|
|
||
|
--- Inverts the given axis or rotation.
|
||
|
-- @param axis_or_rotation The axis or rotation, one of the POS_*, NEG_* or
|
||
|
-- ROT_* constants.
|
||
|
-- @return The inverted value, or the given value if it was not valid.
|
||
|
function rotationutil.invert(axis_or_rotation)
|
||
|
if axis_or_rotation == rotationutil.NEG_X then
|
||
|
return rotationutil.POS_X
|
||
|
elseif axis_or_rotation == rotationutil.NEG_Y then
|
||
|
return rotationutil.POS_Y
|
||
|
elseif axis_or_rotation == rotationutil.NEG_Z then
|
||
|
return rotationutil.POS_Z
|
||
|
elseif axis_or_rotation == rotationutil.POS_X then
|
||
|
return rotationutil.NEG_X
|
||
|
elseif axis_or_rotation == rotationutil.POS_Y then
|
||
|
return rotationutil.NEG_Y
|
||
|
elseif axis_or_rotation == rotationutil.POS_Y then
|
||
|
return rotationutil.NEG_Z
|
||
|
end
|
||
|
|
||
|
if axis_or_rotation == rotationutil.ROT_0 then
|
||
|
return rotationutil.ROT_180
|
||
|
elseif axis_or_rotation == rotationutil.ROT_90 then
|
||
|
return rotationutil.ROT_270
|
||
|
elseif axis_or_rotation == rotationutil.ROT_180 then
|
||
|
return rotationutil.ROT_0
|
||
|
elseif axis_or_rotation == rotationutil.ROT_270 then
|
||
|
return rotationutil.ROT_90
|
||
|
end
|
||
|
|
||
|
return axis_or_rotation
|
||
|
end
|
||
|
|