123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595 |
- --[[
- 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*2 )
- floored_point.y = math.floor( point.y*2 )
- floored_point.z = math.floor( point.z*2 )
- 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.nodePoint_to_bitmap4x4 = function( point )
- local result = {}
- for x=0, 3, 1 do
- result[x] = {}
- for y=0, 3, 1 do
- result[x][y] = {}
- for z=0, 3, 1 do
- result[x][y][z] = 0
- end
- end
- end
- local size = 4
- minetest.log( "warning", point.x.."|"..point.y.."|"..point.z )
- local floored_point = {}
- floored_point.x = math.floor( point.x*size )
- floored_point.y = math.floor( point.y*size )
- floored_point.z = math.floor( point.z*size )
- minetest.log( "warning", point.x.."|"..point.y.."|"..point.z )
- minetest.log( "error", floored_point.x.."|"..floored_point.y.."|"..floored_point.z )
- result[floored_point.x][floored_point.y][floored_point.z] = 1
- return result
- end
- -- this assumes only one of the values is 1
- util.bitmap4x4_to_facetype = function( bitmap4x4 )
- --find indexes
- local ix
- local iy
- local iz
- for x=0, 3, 1 do
- for y=0, 3, 1 do
- for z=0, 3, 1 do
- if( bitmap4x4[x][y][z] == 1 ) then
- ix = x
- iy = y
- iz = z
- end
- end
- end
- end
- -- count indexes at edge of array
- local edge_indexes = 0
- if( ( ix == 0) or (ix == 3) ) then edge_indexes = edge_indexes + 1 end
- if( ( iy == 0) or (iy == 3) ) then edge_indexes = edge_indexes + 1 end
- if( ( iz == 0) or (iz == 3) ) then edge_indexes = edge_indexes + 1 end
- minetest.chat_send_all( ix.." "..iy.." "..iz )
-
- if( edge_indexes == 3 ) then return "corner" end
- if( edge_indexes == 2 ) then return "edge" end
- if( edge_indexes == 1 ) then return "face" end
- return "unsuported"
- end
- util.bitmap4x4_to_bitmap2x2 = function( bitmap4x4 )
- local result = {}
- local point_list = {}
- local i = 0
- for ix=0, 3, 1 do
- for iy=0, 3, 1 do
- for iz=0, 3, 1 do
- if( bitmap4x4[ix][iy][iz] == 1 ) then
- point_list[i] = { x=ix/4.0,y=iy/4.0,z=iz/4.0 }
- i = i + 1
- end
- end
- end
- end
- local new_point_list = {}
- for k, v in pairs(point_list) do
- minetest.log( "warning", v.x..":"..math.floor(v.x*2).." ".. v.y..":"..math.floor(v.y*2).." ".. v.z..":"..math.floor(v.z*2) )
- new_point_list[k] = { x=math.floor(v.x*2), y=math.floor(v.y*2), z=math.floor(v.z*2) }
- end
- for ix=0, 1, 1 do
- result[ix] = {}
- for iy=0, 1, 1 do
- result[ix][iy] = {}
- for iz=0, 1, 1 do
- result[ix][iy][iz] = 0
- end
- end
- end
- for k, v in pairs(new_point_list) do
- minetest.log( "none", v.x..v.y..v.z )
- result[v.x][v.y][v.z] = 1
- end
- return result
- end
- -- assumes you give it a bitmap of type edge-expanded
- util.bitmap4x4_expand_faces = function( bitmap4x4 )
- -- remove corners
- for x=0, 3, 1 do
- for y=0, 3, 1 do
- for z=0, 3, 1 do
- if( bitmap4x4[x][y][z] == 1 ) then
- if( -- if its a corner
- ( (x==0) or (x==3) )
- and ( (y==0) or (y==3) )
- and ( (z==0) or (z==3) )
- ) then
- bitmap4x4[x][y][z] = 0
- end
- end
- end
- end
- end
- --find faces
- local ix
- local iy
- local iz
- local dimension = {}
- for x=0, 3, 1 do
- for y=0, 3, 1 do
- for z=0, 3, 1 do
- if( bitmap4x4[x][y][z] == 1 ) then
- ix = x
- iy = y
- iz = z
- end
- end
- end
- end
- local index = 0
- if( (ix == 0) or (ix == 3) ) then
- dimension[index] = 'x'
- index = index + 1
- end
- if( (iy == 0) or (iy == 3) ) then
- dimension[index] = 'y'
- index = index + 1
- end
- if( (iz == 0) or (iz == 3) ) then
- dimension[index] = 'z'
- index = index + 1
- end
-
- for k, v in pairs(dimension) do
- minetest.chat_send_all( v )
- if( v == 'x' ) then
- for z=0, 3, 1 do
- for y=0, 3, 1 do
- bitmap4x4[ix][y][z] = 1
- end
- end
- end
- if( v == 'y' ) then
- for x=0, 3, 1 do
- for z=0, 3, 1 do
- bitmap4x4[x][iy][z] = 1
- end
- end
- end
- if( v == 'z' ) then
- for x=0, 3, 1 do
- for y=0, 3, 1 do
- bitmap4x4[x][y][iz] = 1
- end
- end
- end
- end
- end
- -- assumes you give it a bitmap of type face
- util.bitmap4x4_expand_face = function( bitmap4x4 )
-
- --find face
- local ix
- local iy
- local iz
- local dimension
- for x=0, 3, 1 do
- for y=0, 3, 1 do
- for z=0, 3, 1 do
- if( bitmap4x4[x][y][z] == 1 ) then
- ix = x
- iy = y
- iz = z
- end
- end
- end
- end
- if( (ix == 0) or (ix == 3) ) then dimension = 'x' end
- if( (iy == 0) or (iy == 3) ) then dimension = 'y' end
- if( (iz == 0) or (iz == 3) ) then dimension = 'z' end
- if( dimension == 'x' ) then
- for z=0, 3, 1 do
- for y=0, 3, 1 do
- bitmap4x4[ix][y][z] = 1
- end
- end
- end
- if( dimension == 'y' ) then
- for x=0, 3, 1 do
- for z=0, 3, 1 do
- bitmap4x4[x][iy][z] = 1
- end
- end
- end
- if( dimension == 'z' ) then
- for x=0, 3, 1 do
- for y=0, 3, 1 do
- bitmap4x4[x][y][iz] = 1
- end
- end
- end
-
- end
- util.bitmap4x4_expand_normal = function( bitmap4x4, normal )
- --find dimension of normal that isn't 0
- local dimension = ""
- if( normal.x ~= 0 ) then dimension = 'x' end
- if( normal.y ~= 0 ) then dimension = 'y' end
- if( normal.z ~= 0 ) then dimension = 'z' end
- -- find positions that are 1 and set all positions across the normal to 1
- for x=0, 3, 1 do
- for y=0, 3, 1 do
- for z=0, 3, 1 do
- if( bitmap4x4[x][y][z] == 1 ) then
- if( dimension == 'x' ) then
- for i=0, 3, 1 do
- bitmap4x4[i][y][z] = 1
- end
- end
- if( dimension == 'y' ) then
- for i=0, 3, 1 do
- bitmap4x4[x][i][z] = 1
- end
- end
- if( dimension == 'z' ) then
- for i=0, 3, 1 do
- bitmap4x4[x][y][i] = 1
- end
- end
- end
- end
- end
- end
-
- end
- util.bitmap4x4_expand_edge = function( bitmap4x4 )
- local print_string = ""
- for i=0, 3, 1 do
- for ii=0, 3, 1 do
- for iii=0, 3, 1 do
- print_string = print_string..bitmap4x4[i][ii][iii]
- end
- end
- end
- minetest.log( "warning", print_string )
- --find index dimension not on the edge
- local ix
- local iy
- local iz
- local dimension
- for x=0, 3, 1 do
- for y=0, 3, 1 do
- for z=0, 3, 1 do
- if( bitmap4x4[x][y][z] == 1 ) then
- ix = x
- iy = y
- iz = z
- end
- end
- end
- end
- if( (ix ~= 0) and (ix ~= 3) ) then dimension = 'x' end
- if( (iy ~= 0) and (iy ~= 3) ) then dimension = 'y' end
- if( (iz ~= 0) and (iz ~= 3) ) then dimension = 'z' end
-
- if( dimension == 'x' ) then
- for i=0, 3, 1 do
- bitmap4x4[i][iy][iz] = 1
- end
- end
-
- if( dimension == 'y' ) then
- for i=0, 3, 1 do
- bitmap4x4[ix][i][iz] = 1
- end
- end
-
- if( dimension == 'z' ) then
- for i=0, 3, 1 do
- bitmap4x4[ix][iy][i] = 1
- end
- end
- print_string = ""
- for i=0, 3, 1 do
- for ii=0, 3, 1 do
- for iii=0, 3, 1 do
- print_string = print_string..bitmap4x4[i][ii][iii]
- end
- end
- end
- minetest.log( "warning", print_string )
- 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
|