InsaneProtestor/mods/ip_terumet/util3d.lua

76 lines
2.9 KiB
Lua
Raw Normal View History

2022-11-21 22:12:22 +01:00
-- 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