-- 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