k_smallblocks/util.lua

287 lines
7.2 KiB
Lua

--[[
k_smallblocks is a Minetest mod that adds smaller blocks to minetest aswell as
its own node placement prediction/system
Copyright (C) 2019 Kurtzmusch
This file is part of k_smallblocks
k_smallblocks is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at your option) any
later version.
k_smallblocks is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with k_smallblocks. If not, see <https://www.gnu.org/licenses/>.
--]]
-- bitmap is an array of 8 integers that can be either 0 or 1
-- it is used to indicate wich part of the node is filled with a smallblock
util = {}
util.table_invert = function(t)
local s={}
for k,v in pairs(t) do
s[v]=k
end
return s
end
util.table_shallow_copy = function(t)
local t2 = {}
for k,v in pairs(t) do
t2[k] = v
end
return t2
end
-- does the equivalent of a bitwise OR with 2 bitmaps
util.or_bitmap = function( array1, array2 )
local result = { [7] = nil }
local index = 0
while (index < 8 ) do
if( (array1[index] == 1) or (array2[index] == 1) ) then
result[index] = 1
else
result[index] = 0
end
index = index + 1
end
return result
end
util.xor_bitmap = function( bitmap1, bitmap2 )
local result = {}
local index = 0
while(index<8) do
if(
( (bitmap1[index] == 1) or (bitmap2[index] == 1 ) )
and
( (bitmap1[index] == 0) or (bitmap2[index] == 0 ) )
) then
result[index] = 1
else
result[index] = 0
end
index = index + 1
end
return result
end
-- convert world coordinates into node coordinates, ranging from 0 to 1
util.worldPoint_to_nodePoint = function( point )
point.x = point.x + 65536.5
point.y = point.y + 65536.5
point.z = point.z + 65536.5
return { x=point.x%1, y=point.y%1, z=point.z%1 }
end
-- converts a point in a node into a bitmap
-- input coords must be between 0 and 1
-- the bitmap is empty, except for the smallblock in the given coordinate
util.nodePoint_to_bitmap = function( point )
local size = 2 -- lenght of a node in smallblocks
-- floored components are indexes of a 3d array
local floored_point = {}
floored_point.x = math.floor( point.x+0.5 )
floored_point.y = math.floor( point.y+0.5 )
floored_point.z = math.floor( point.z+0.5 )
bitmap = {}
local index = 0
while (index < 8) do
bitmap[index] = 0
index = index + 1
end
-- this is like converting a 3d array to a 1d array
index =
(floored_point.x) +
(floored_point.y*size) +
(floored_point.z*(size*size))
bitmap[index] = 1
return bitmap
end
util.integer_to_bitmap = function( integer )
local bitmap = { [0] = nil, [7] = nil }
local value = 128
for i = 7, 0, -1 do
if(integer >= value) then
bitmap[i] = 1
integer = integer - value
else
bitmap[i] = 0
end
value = value/2
end
return bitmap
end
util.bitmap_to_integer = function( bitmap )
local integer = 0
local value = 1
for index = 0, 7, 1 do
integer = integer + (bitmap[index] * value)
value = value * 2
end
return integer
end
--TODO delete this if not used
util.mirror_bitmap_across_y = function( bitmap )
local new_array = { [0] = { [0]={}, [1]={}}, [1]={[0]={}, [1]={}} }
local max_index = 1
local my = max_index
for iy = 0, max_index, 1 do
for ix = 0, max_index, 1 do
for iz = 0, max_index, 1 do
new_array[ix][my][iz] = bitmap[ ix + (iy*2) + (iz*4) ]
end
end
my = my - 1
end
return util.array3d_to_bitmap( new_array )
end
--bitmap rotation: rotation of the 3d array that represents the bitmap
--rotates the array clockwise by 90 degress around the given axis
util.rotate_bitmap_around_plus_y = function( bitmap )
local new_bitmap = { [0] = { [0]={}, [1]={}}, [1]={[0]={}, [1]={}} }
local max_index = 1
for ix = 0, max_index, 1 do
for iy = 0, max_index, 1 do
for iz = 0, max_index, 1 do
new_bitmap[iz][iy][max_index-ix] = bitmap[ ix + (iy*2) + (iz*4) ]
end
end
end
return util.array3d_to_bitmap( new_bitmap )
end
util.rotate_bitmap_around_minus_y = function( bitmap )
local new_bitmap = { [0] = { [0]={}, [1]={}}, [1]={[0]={}, [1]={}} }
local max_index = 1
for ix = 0, max_index, 1 do
for iy = 0, max_index, 1 do
for iz = 0, max_index, 1 do
new_bitmap[max_index-iz][iy][ix] = bitmap[ ix + (iy*2) + (iz*4) ]
end
end
end
return util.array3d_to_bitmap( new_bitmap )
end
util.rotate_bitmap_around_plus_z = function( bitmap )
local new_bitmap = { [0] = { [0]={}, [1]={}}, [1]={[0]={}, [1]={}} }
local max_index = 1
for ix = 0, max_index, 1 do
for iy = 0, max_index, 1 do
for iz = 0, max_index, 1 do
new_bitmap[max_index-iy][ix][iz] = bitmap[ ix + (iy*2) + (iz*4) ]
end
end
end
return util.array3d_to_bitmap( new_bitmap )
end
util.rotate_bitmap_around_minus_z = function( bitmap )
local new_bitmap = { [0] = { [0]={}, [1]={}}, [1]={[0]={}, [1]={}} }
local max_index = 1
for ix = 0, max_index, 1 do
for iy = 0, max_index, 1 do
for iz = 0, max_index, 1 do
new_bitmap[iy][max_index-ix][iz] = bitmap[ ix + (iy*2) + (iz*4) ]
end
end
end
return util.array3d_to_bitmap( new_bitmap )
end
util.rotate_bitmap_around_plus_x = function( bitmap )
local new_bitmap = { [0] = { [0]={}, [1]={}}, [1]={[0]={}, [1]={}} }
local max_index = 1
for ix = 0, max_index, 1 do
for iy = 0, max_index, 1 do
for iz = 0, max_index, 1 do
new_bitmap[ix][max_index-iz][iy] = bitmap[ ix + (iy*2) + (iz*4) ]
end
end
end
return util.array3d_to_bitmap( new_bitmap )
end
util.rotate_bitmap_around_minus_x = function( bitmap )
local new_bitmap = { [0] = { [0]={}, [1]={}}, [1]={[0]={}, [1]={}} }
local max_index = 1
for ix = 0, max_index, 1 do
for iy = 0, max_index, 1 do
for iz = 0, max_index, 1 do
new_bitmap[ix][iz][max_index-iy] = bitmap[ ix + (iy*2) + (iz*4) ]
end
end
end
return util.array3d_to_bitmap( new_bitmap )
end
-- bitmap orientation assumes the current bitmap orientation is plus y
util.orient_bitmap_towards_plus_z = function( bitmap )
return util.rotate_bitmap_around_plus_x( bitmap )
end
util.orient_bitmap_towards_minus_z = function( bitmap )
return util.rotate_bitmap_around_minus_x( bitmap )
end
util.orient_bitmap_towards_plus_x = function( bitmap )
return util.rotate_bitmap_around_minus_z( bitmap )
end
util.orient_bitmap_towards_minus_x = function( bitmap )
return util.rotate_bitmap_around_plus_z( bitmap )
end
util.orient_bitmap_towards_minus_y = function( bitmap )
return util.rotate_bitmap_around_plus_z( util.rotate_bitmap_around_plus_z( bitmap ) )
end
util.bitmap_to_array3d = function( bitmap )
local array = { [0] = { [0]={}, [1]={}}, [1]={[0]={}, [1]={}} }
local max_index = 1
for ix = 0, max_index, 1 do
for iy = 0, max_index, 1 do
for iz = 0, max_index, 1 do
array[ix][iy][iz] = bitmap[ ix + (iy*2) + (iz*4)]
end
end
end
return array
end
util.array3d_to_bitmap = function( array )
local bitmap = {}
local max_index = 1
for ix = 0, max_index, 1 do
for iy = 0, max_index, 1 do
for iz = 0, max_index, 1 do
bitmap[ ix + (iy*2) + (iz*4) ] = array[ix][iy][iz]
end
end
end
return bitmap
end