Reduce number of laser nodes from 63 to 7

master
Wuzzy 2021-12-27 16:55:04 +01:00
parent d4c02b4353
commit 29a8222d46
3 changed files with 20 additions and 29 deletions

View File

@ -6,9 +6,9 @@ local LASER_RADIUS = -1/16
-- Returns a nodebox for the given dirs table -- Returns a nodebox for the given dirs table
local function dirs_to_nodebox(dirs) local function dirs_to_nodebox(dirs)
local boxes = {} local boxes = {}
local x = dirs[1] == 1 or dirs[4] == 1 local x = dirs[1] == 1
local y = dirs[2] == 1 or dirs[5] == 1 local y = dirs[2] == 1
local z = dirs[3] == 1 or dirs[6] == 1 local z = dirs[3] == 1
-- True if 2 or more axes are used -- True if 2 or more axes are used
local multidir = (x and y) or (x and z) or (y and z) local multidir = (x and y) or (x and z) or (y and z)
@ -47,9 +47,9 @@ local function dirs_to_nodebox(dirs)
end end
-- Register laser nodes -- Register laser nodes
-- 64 nodes because 2^6 (6 directions with on/off state) -- 7 nodes because (2^3)-1 (2 states for each of 3 axes, minus the state when there's no laser (=air))
for i=1, 64 do for i=1, 7 do
local dirstring = lzr_laser.dec2bin(i, 6) local dirstring = lzr_laser.dec2bin(i, 3)
local dirs = lzr_laser.dirstring_to_dirs(dirstring) local dirs = lzr_laser.dirstring_to_dirs(dirstring)
-- Check which textures to render. -- Check which textures to render.
@ -59,7 +59,7 @@ for i=1, 64 do
local axes = 0 local axes = 0
local axes_active = {x=false,y=false,z=false} local axes_active = {x=false,y=false,z=false}
for a=1,3 do for a=1,3 do
if dirs[a] ~= 0 or dirs[a+3] ~= 0 then if dirs[a] ~= 0 then
axes = axes + 1 axes = axes + 1
if a == 1 then if a == 1 then
axes_active.x = true axes_active.x = true

View File

@ -15,7 +15,7 @@ function lzr_laser.add_laser(pos, dir)
-- Laser through laser (laser intersection) -- Laser through laser (laser intersection)
elseif minetest.get_item_group(node.name, "laser") > 0 then elseif minetest.get_item_group(node.name, "laser") > 0 then
local dirnum = minetest.get_item_group(node.name, "laser") local dirnum = minetest.get_item_group(node.name, "laser")
local dirstring_old = lzr_laser.dec2bin(dirnum, 6) local dirstring_old = lzr_laser.dec2bin(dirnum, 3)
local dirs_new = lzr_laser.vector_to_dirs(dir) local dirs_new = lzr_laser.vector_to_dirs(dir)
local dirstring_new = lzr_laser.dirs_to_dirstring(dirs_new) local dirstring_new = lzr_laser.dirs_to_dirstring(dirs_new)

View File

@ -2,22 +2,22 @@
local LASER_RADIUS = -1/16 local LASER_RADIUS = -1/16
-- DATA FORMATS: -- DATA FORMATS:
--[[ dirstring: A representation of 6 cardinal directions which are either --[[ dirstring: A representation of 3 axes (XYZ) which are either
'active' (1) or 'inactive' (0) 'active' (1) or 'inactive' (0)
Each direction has the character "1" or "0". Each direction has the character "1" or "0".
The characters stand for these directions, in order: -X, -Y, -Z, +X, +Y, +Z The characters stand for these directions, in order: X, Y, Z
Example: "101010" Example: "101"
]] ]]
--[[ dirs table: Like dirstring, but in table format. It's a table --[[ dirs table: Like dirstring, but in table format. It's a table
with 6 numbers, each of them being either 1 or 0. The same order of with 3 numbers, each of them being either 1 or 0. The same order of
directions is used like for dirstring. axes is used like for dirstring.
Example: { 1, 0, 1, 0, 1, 0 } Example: { 1, 0, 1 }
]] ]]
-- Converts a dirstring to a dirs table -- Converts a dirstring to a dirs table
function lzr_laser.dirstring_to_dirs(dirstring) function lzr_laser.dirstring_to_dirs(dirstring)
local dirs = {} local dirs = {}
for d=1, 6 do for d=1, 3 do
if string.sub(dirstring, d, d) == "1" then if string.sub(dirstring, d, d) == "1" then
dirs[d] = 1 dirs[d] = 1
elseif string.sub(dirstring, d, d) == "0" then elseif string.sub(dirstring, d, d) == "0" then
@ -32,7 +32,7 @@ end
-- Converts a dirs table to a dirstring -- Converts a dirs table to a dirstring
function lzr_laser.dirs_to_dirstring(dirs) function lzr_laser.dirs_to_dirstring(dirs)
local dirstring = "" local dirstring = ""
for d=1, 6 do for d=1, 3 do
if dirs[d] == 0 then if dirs[d] == 0 then
dirstring = dirstring .. "0" dirstring = dirstring .. "0"
elseif dirs[d] == 1 then elseif dirs[d] == 1 then
@ -45,23 +45,14 @@ function lzr_laser.dirs_to_dirstring(dirs)
end end
function lzr_laser.vector_to_dirs(dir_vector) function lzr_laser.vector_to_dirs(dir_vector)
local dirs = {0,0,0,0,0,0} local dirs = {0,0,0}
if dir_vector.x > 0 then if dir_vector.x ~= 0 then
dirs[4] = 1
end
if dir_vector.x < 0 then
dirs[1] = 1 dirs[1] = 1
end end
if dir_vector.y > 0 then if dir_vector.y ~= 0 then
dirs[5] = 1
end
if dir_vector.y < 0 then
dirs[2] = 1 dirs[2] = 1
end end
if dir_vector.z > 0 then if dir_vector.z ~= 0 then
dirs[6] = 1
end
if dir_vector.z < 0 then
dirs[3] = 1 dirs[3] = 1
end end
return dirs return dirs