76 lines
2.9 KiB
Lua
76 lines
2.9 KiB
Lua
-- Utility functions for dealing with 3D math and node rotations/facing directions
|
|
|
|
-- "Facing" is the direction the top of the node points, i.e. the axis the node rotates around with a screwdriver.
|
|
-- "Rotation" is the direction the "front" of the node points, i.e. the face that rotates with a screwdriver.
|
|
|
|
-- The 6th texture in "tiles" of a facedir-type node is considered the "front" since that
|
|
-- is the side that faces the player when placed.
|
|
|
|
-- by Terumoc
|
|
|
|
local THIS_VERSION = 2
|
|
-- don't overwrite a later version if its already loaded
|
|
if minetest.global_exists('util3d') and util3d.version >= THIS_VERSION then return end
|
|
|
|
util3d = {}
|
|
util3d.version = THIS_VERSION
|
|
|
|
-- given a node pos plus another pos/offset, add them together
|
|
function util3d.pos_plus(pos, offset)
|
|
return {
|
|
x=pos.x + offset.x,
|
|
y=pos.y + offset.y,
|
|
z=pos.z + offset.z,
|
|
}
|
|
end
|
|
|
|
-- given a node pos plus offset, return the offset pos and node there
|
|
function util3d.get_offset(pos, offset)
|
|
pos = util3d.pos_plus(pos, offset)
|
|
return pos, minetest.get_node_or_nil(pos)
|
|
end
|
|
|
|
-- given a facedir node's param2, return the FACING index
|
|
function util3d.param2_to_facing(param2)
|
|
return math.floor(param2 / 4)
|
|
end
|
|
|
|
-- given a facedir node's param2, return the ROTATION index
|
|
function util3d.param2_to_rotation(param2)
|
|
return param2 % 4
|
|
end
|
|
|
|
-- human-readable directions of facings
|
|
util3d.FACING_DIRECTION = {
|
|
[0]='up', [1]='north', [2]='south', [3]='east', [4]='west', [5]='down'
|
|
}
|
|
|
|
-- x/y/z offsets for each human-readable direction
|
|
util3d.ADJACENT_OFFSETS = {
|
|
east={x=1,y=0,z=0}, west={x=-1,y=0,z=0},
|
|
up={x=0,y=1,z=0}, down={x=0,y=-1,z=0},
|
|
north={x=0,y=0,z=1}, south={x=0,y=0,z=-1}
|
|
}
|
|
|
|
-- auto-generated constants for x/y/z offset in a facing index
|
|
-- ex: FACING_OFFSETS[1]: 1 = facing north so returns offset of {x=0,y=0,z=1} (+1 node north)
|
|
util3d.FACING_OFFSETS = {}
|
|
for facing,dir in pairs(util3d.FACING_DIRECTION) do
|
|
util3d.FACING_OFFSETS[facing] = util3d.ADJACENT_OFFSETS[dir]
|
|
end
|
|
|
|
-- relative x/y/z offset for rotations
|
|
util3d.ROTATION_OFFSETS = {
|
|
[0]={left={x=-1,y=0,z=0}, right={x=1,y=0,z=0}, front={x=0,y=0,z=-1}, back={x=0,y=0,z=1}, top=util3d.ADJACENT_OFFSETS.up, bottom=util3d.ADJACENT_OFFSETS.down},
|
|
[1]={left={x=0,y=0,z=1}, right={x=0,y=0,z=-1}, front={x=-1,y=0,z=0}, back={x=1,y=0,z=0}, top=util3d.ADJACENT_OFFSETS.up, bottom=util3d.ADJACENT_OFFSETS.down},
|
|
[2]={left={x=1,y=0,z=0}, right={x=-1,y=0,z=0}, front={x=0,y=0,z=1}, back={x=0,y=0,z=-1}, top=util3d.ADJACENT_OFFSETS.up, bottom=util3d.ADJACENT_OFFSETS.down},
|
|
[3]={left={x=0,y=0,z=-1}, right={x=0,y=0,z=1}, front={x=1,y=0,z=0}, back={x=-1,y=0,z=0}, top=util3d.ADJACENT_OFFSETS.up, bottom=util3d.ADJACENT_OFFSETS.down},
|
|
}
|
|
|
|
util3d.RELATIVE_SIDES = { 'top', 'bottom', 'left', 'right', 'front', 'back' }
|
|
|
|
function util3d.get_relative_pos(rot, pos, rel)
|
|
if 'number'==type(rel) then rel = util3d.RELATIVE_SIDES[rel] end
|
|
return util3d.pos_plus(pos, util3d.ROTATION_OFFSETS[rot][rel])
|
|
end
|