util.lua 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. --[[
  2. k_smallblocks is a Minetest mod that adds smaller blocks to minetest aswell as
  3. its own node placement prediction/system
  4. Copyright (C) 2019 Kurtzmusch
  5. This file is part of k_smallblocks
  6. k_smallblocks is free software; you can redistribute it and/or modify it under
  7. the terms of the GNU Lesser General Public License as published by the Free
  8. Software Foundation; either version 2.1 of the License, or (at your option) any
  9. later version.
  10. k_smallblocks is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  12. PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public License along
  14. with k_smallblocks. If not, see <https://www.gnu.org/licenses/>.
  15. --]]
  16. -- bitmap is an array of 8 integers that can be either 0 or 1
  17. -- it is used to indicate wich part of the node is filled with a smallblock
  18. util = {}
  19. util.table_invert = function(t)
  20. local s={}
  21. for k,v in pairs(t) do
  22. s[v]=k
  23. end
  24. return s
  25. end
  26. util.table_shallow_copy = function(t)
  27. local t2 = {}
  28. for k,v in pairs(t) do
  29. t2[k] = v
  30. end
  31. return t2
  32. end
  33. -- does the equivalent of a bitwise OR with 2 bitmaps
  34. util.or_bitmap = function( array1, array2 )
  35. local result = { [7] = nil }
  36. local index = 0
  37. while (index < 8 ) do
  38. if( (array1[index] == 1) or (array2[index] == 1) ) then
  39. result[index] = 1
  40. else
  41. result[index] = 0
  42. end
  43. index = index + 1
  44. end
  45. return result
  46. end
  47. util.xor_bitmap = function( bitmap1, bitmap2 )
  48. local result = {}
  49. local index = 0
  50. while(index<8) do
  51. if(
  52. ( (bitmap1[index] == 1) or (bitmap2[index] == 1 ) )
  53. and
  54. ( (bitmap1[index] == 0) or (bitmap2[index] == 0 ) )
  55. ) then
  56. result[index] = 1
  57. else
  58. result[index] = 0
  59. end
  60. index = index + 1
  61. end
  62. return result
  63. end
  64. -- convert world coordinates into node coordinates, ranging from 0 to 1
  65. util.worldPoint_to_nodePoint = function( point )
  66. point.x = point.x + 65536.5
  67. point.y = point.y + 65536.5
  68. point.z = point.z + 65536.5
  69. return { x=point.x%1, y=point.y%1, z=point.z%1 }
  70. end
  71. -- converts a point in a node into a bitmap
  72. -- input coords must be between 0 and 1
  73. -- the bitmap is empty, except for the smallblock in the given coordinate
  74. util.nodePoint_to_bitmap = function( point )
  75. local size = 2 -- lenght of a node in smallblocks
  76. -- floored components are indexes of a 3d array
  77. local floored_point = {}
  78. floored_point.x = math.floor( point.x*2 )
  79. floored_point.y = math.floor( point.y*2 )
  80. floored_point.z = math.floor( point.z*2 )
  81. bitmap = {}
  82. local index = 0
  83. while (index < 8) do
  84. bitmap[index] = 0
  85. index = index + 1
  86. end
  87. -- this is like converting a 3d array to a 1d array
  88. index =
  89. (floored_point.x) +
  90. (floored_point.y*size) +
  91. (floored_point.z*(size*size))
  92. bitmap[index] = 1
  93. return bitmap
  94. end
  95. util.nodePoint_to_bitmap4x4 = function( point )
  96. local result = {}
  97. for x=0, 3, 1 do
  98. result[x] = {}
  99. for y=0, 3, 1 do
  100. result[x][y] = {}
  101. for z=0, 3, 1 do
  102. result[x][y][z] = 0
  103. end
  104. end
  105. end
  106. local size = 4
  107. minetest.log( "warning", point.x.."|"..point.y.."|"..point.z )
  108. local floored_point = {}
  109. floored_point.x = math.floor( point.x*size )
  110. floored_point.y = math.floor( point.y*size )
  111. floored_point.z = math.floor( point.z*size )
  112. minetest.log( "warning", point.x.."|"..point.y.."|"..point.z )
  113. minetest.log( "error", floored_point.x.."|"..floored_point.y.."|"..floored_point.z )
  114. result[floored_point.x][floored_point.y][floored_point.z] = 1
  115. return result
  116. end
  117. -- this assumes only one of the values is 1
  118. util.bitmap4x4_to_facetype = function( bitmap4x4 )
  119. --find indexes
  120. local ix
  121. local iy
  122. local iz
  123. for x=0, 3, 1 do
  124. for y=0, 3, 1 do
  125. for z=0, 3, 1 do
  126. if( bitmap4x4[x][y][z] == 1 ) then
  127. ix = x
  128. iy = y
  129. iz = z
  130. end
  131. end
  132. end
  133. end
  134. -- count indexes at edge of array
  135. local edge_indexes = 0
  136. if( ( ix == 0) or (ix == 3) ) then edge_indexes = edge_indexes + 1 end
  137. if( ( iy == 0) or (iy == 3) ) then edge_indexes = edge_indexes + 1 end
  138. if( ( iz == 0) or (iz == 3) ) then edge_indexes = edge_indexes + 1 end
  139. minetest.chat_send_all( ix.." "..iy.." "..iz )
  140. if( edge_indexes == 3 ) then return "corner" end
  141. if( edge_indexes == 2 ) then return "edge" end
  142. if( edge_indexes == 1 ) then return "face" end
  143. return "unsuported"
  144. end
  145. util.bitmap4x4_to_bitmap2x2 = function( bitmap4x4 )
  146. local result = {}
  147. local point_list = {}
  148. local i = 0
  149. for ix=0, 3, 1 do
  150. for iy=0, 3, 1 do
  151. for iz=0, 3, 1 do
  152. if( bitmap4x4[ix][iy][iz] == 1 ) then
  153. point_list[i] = { x=ix/4.0,y=iy/4.0,z=iz/4.0 }
  154. i = i + 1
  155. end
  156. end
  157. end
  158. end
  159. local new_point_list = {}
  160. for k, v in pairs(point_list) do
  161. minetest.log( "warning", v.x..":"..math.floor(v.x*2).." ".. v.y..":"..math.floor(v.y*2).." ".. v.z..":"..math.floor(v.z*2) )
  162. new_point_list[k] = { x=math.floor(v.x*2), y=math.floor(v.y*2), z=math.floor(v.z*2) }
  163. end
  164. for ix=0, 1, 1 do
  165. result[ix] = {}
  166. for iy=0, 1, 1 do
  167. result[ix][iy] = {}
  168. for iz=0, 1, 1 do
  169. result[ix][iy][iz] = 0
  170. end
  171. end
  172. end
  173. for k, v in pairs(new_point_list) do
  174. minetest.log( "none", v.x..v.y..v.z )
  175. result[v.x][v.y][v.z] = 1
  176. end
  177. return result
  178. end
  179. -- assumes you give it a bitmap of type edge-expanded
  180. util.bitmap4x4_expand_faces = function( bitmap4x4 )
  181. -- remove corners
  182. for x=0, 3, 1 do
  183. for y=0, 3, 1 do
  184. for z=0, 3, 1 do
  185. if( bitmap4x4[x][y][z] == 1 ) then
  186. if( -- if its a corner
  187. ( (x==0) or (x==3) )
  188. and ( (y==0) or (y==3) )
  189. and ( (z==0) or (z==3) )
  190. ) then
  191. bitmap4x4[x][y][z] = 0
  192. end
  193. end
  194. end
  195. end
  196. end
  197. --find faces
  198. local ix
  199. local iy
  200. local iz
  201. local dimension = {}
  202. for x=0, 3, 1 do
  203. for y=0, 3, 1 do
  204. for z=0, 3, 1 do
  205. if( bitmap4x4[x][y][z] == 1 ) then
  206. ix = x
  207. iy = y
  208. iz = z
  209. end
  210. end
  211. end
  212. end
  213. local index = 0
  214. if( (ix == 0) or (ix == 3) ) then
  215. dimension[index] = 'x'
  216. index = index + 1
  217. end
  218. if( (iy == 0) or (iy == 3) ) then
  219. dimension[index] = 'y'
  220. index = index + 1
  221. end
  222. if( (iz == 0) or (iz == 3) ) then
  223. dimension[index] = 'z'
  224. index = index + 1
  225. end
  226. for k, v in pairs(dimension) do
  227. minetest.chat_send_all( v )
  228. if( v == 'x' ) then
  229. for z=0, 3, 1 do
  230. for y=0, 3, 1 do
  231. bitmap4x4[ix][y][z] = 1
  232. end
  233. end
  234. end
  235. if( v == 'y' ) then
  236. for x=0, 3, 1 do
  237. for z=0, 3, 1 do
  238. bitmap4x4[x][iy][z] = 1
  239. end
  240. end
  241. end
  242. if( v == 'z' ) then
  243. for x=0, 3, 1 do
  244. for y=0, 3, 1 do
  245. bitmap4x4[x][y][iz] = 1
  246. end
  247. end
  248. end
  249. end
  250. end
  251. -- assumes you give it a bitmap of type face
  252. util.bitmap4x4_expand_face = function( bitmap4x4 )
  253. --find face
  254. local ix
  255. local iy
  256. local iz
  257. local dimension
  258. for x=0, 3, 1 do
  259. for y=0, 3, 1 do
  260. for z=0, 3, 1 do
  261. if( bitmap4x4[x][y][z] == 1 ) then
  262. ix = x
  263. iy = y
  264. iz = z
  265. end
  266. end
  267. end
  268. end
  269. if( (ix == 0) or (ix == 3) ) then dimension = 'x' end
  270. if( (iy == 0) or (iy == 3) ) then dimension = 'y' end
  271. if( (iz == 0) or (iz == 3) ) then dimension = 'z' end
  272. if( dimension == 'x' ) then
  273. for z=0, 3, 1 do
  274. for y=0, 3, 1 do
  275. bitmap4x4[ix][y][z] = 1
  276. end
  277. end
  278. end
  279. if( dimension == 'y' ) then
  280. for x=0, 3, 1 do
  281. for z=0, 3, 1 do
  282. bitmap4x4[x][iy][z] = 1
  283. end
  284. end
  285. end
  286. if( dimension == 'z' ) then
  287. for x=0, 3, 1 do
  288. for y=0, 3, 1 do
  289. bitmap4x4[x][y][iz] = 1
  290. end
  291. end
  292. end
  293. end
  294. util.bitmap4x4_expand_normal = function( bitmap4x4, normal )
  295. --find dimension of normal that isn't 0
  296. local dimension = ""
  297. if( normal.x ~= 0 ) then dimension = 'x' end
  298. if( normal.y ~= 0 ) then dimension = 'y' end
  299. if( normal.z ~= 0 ) then dimension = 'z' end
  300. -- find positions that are 1 and set all positions across the normal to 1
  301. for x=0, 3, 1 do
  302. for y=0, 3, 1 do
  303. for z=0, 3, 1 do
  304. if( bitmap4x4[x][y][z] == 1 ) then
  305. if( dimension == 'x' ) then
  306. for i=0, 3, 1 do
  307. bitmap4x4[i][y][z] = 1
  308. end
  309. end
  310. if( dimension == 'y' ) then
  311. for i=0, 3, 1 do
  312. bitmap4x4[x][i][z] = 1
  313. end
  314. end
  315. if( dimension == 'z' ) then
  316. for i=0, 3, 1 do
  317. bitmap4x4[x][y][i] = 1
  318. end
  319. end
  320. end
  321. end
  322. end
  323. end
  324. end
  325. util.bitmap4x4_expand_edge = function( bitmap4x4 )
  326. local print_string = ""
  327. for i=0, 3, 1 do
  328. for ii=0, 3, 1 do
  329. for iii=0, 3, 1 do
  330. print_string = print_string..bitmap4x4[i][ii][iii]
  331. end
  332. end
  333. end
  334. minetest.log( "warning", print_string )
  335. --find index dimension not on the edge
  336. local ix
  337. local iy
  338. local iz
  339. local dimension
  340. for x=0, 3, 1 do
  341. for y=0, 3, 1 do
  342. for z=0, 3, 1 do
  343. if( bitmap4x4[x][y][z] == 1 ) then
  344. ix = x
  345. iy = y
  346. iz = z
  347. end
  348. end
  349. end
  350. end
  351. if( (ix ~= 0) and (ix ~= 3) ) then dimension = 'x' end
  352. if( (iy ~= 0) and (iy ~= 3) ) then dimension = 'y' end
  353. if( (iz ~= 0) and (iz ~= 3) ) then dimension = 'z' end
  354. if( dimension == 'x' ) then
  355. for i=0, 3, 1 do
  356. bitmap4x4[i][iy][iz] = 1
  357. end
  358. end
  359. if( dimension == 'y' ) then
  360. for i=0, 3, 1 do
  361. bitmap4x4[ix][i][iz] = 1
  362. end
  363. end
  364. if( dimension == 'z' ) then
  365. for i=0, 3, 1 do
  366. bitmap4x4[ix][iy][i] = 1
  367. end
  368. end
  369. print_string = ""
  370. for i=0, 3, 1 do
  371. for ii=0, 3, 1 do
  372. for iii=0, 3, 1 do
  373. print_string = print_string..bitmap4x4[i][ii][iii]
  374. end
  375. end
  376. end
  377. minetest.log( "warning", print_string )
  378. end
  379. util.integer_to_bitmap = function( integer )
  380. local bitmap = { [0] = nil, [7] = nil }
  381. local value = 128
  382. for i = 7, 0, -1 do
  383. if(integer >= value) then
  384. bitmap[i] = 1
  385. integer = integer - value
  386. else
  387. bitmap[i] = 0
  388. end
  389. value = value/2
  390. end
  391. return bitmap
  392. end
  393. util.bitmap_to_integer = function( bitmap )
  394. local integer = 0
  395. local value = 1
  396. for index = 0, 7, 1 do
  397. integer = integer + (bitmap[index] * value)
  398. value = value * 2
  399. end
  400. return integer
  401. end
  402. --TODO delete this if not used
  403. util.mirror_bitmap_across_y = function( bitmap )
  404. local new_array = { [0] = { [0]={}, [1]={}}, [1]={[0]={}, [1]={}} }
  405. local max_index = 1
  406. local my = max_index
  407. for iy = 0, max_index, 1 do
  408. for ix = 0, max_index, 1 do
  409. for iz = 0, max_index, 1 do
  410. new_array[ix][my][iz] = bitmap[ ix + (iy*2) + (iz*4) ]
  411. end
  412. end
  413. my = my - 1
  414. end
  415. return util.array3d_to_bitmap( new_array )
  416. end
  417. --bitmap rotation: rotation of the 3d array that represents the bitmap
  418. --rotates the array clockwise by 90 degress around the given axis
  419. util.rotate_bitmap_around_plus_y = function( bitmap )
  420. local new_bitmap = { [0] = { [0]={}, [1]={}}, [1]={[0]={}, [1]={}} }
  421. local max_index = 1
  422. for ix = 0, max_index, 1 do
  423. for iy = 0, max_index, 1 do
  424. for iz = 0, max_index, 1 do
  425. new_bitmap[iz][iy][max_index-ix] = bitmap[ ix + (iy*2) + (iz*4) ]
  426. end
  427. end
  428. end
  429. return util.array3d_to_bitmap( new_bitmap )
  430. end
  431. util.rotate_bitmap_around_minus_y = function( bitmap )
  432. local new_bitmap = { [0] = { [0]={}, [1]={}}, [1]={[0]={}, [1]={}} }
  433. local max_index = 1
  434. for ix = 0, max_index, 1 do
  435. for iy = 0, max_index, 1 do
  436. for iz = 0, max_index, 1 do
  437. new_bitmap[max_index-iz][iy][ix] = bitmap[ ix + (iy*2) + (iz*4) ]
  438. end
  439. end
  440. end
  441. return util.array3d_to_bitmap( new_bitmap )
  442. end
  443. util.rotate_bitmap_around_plus_z = function( bitmap )
  444. local new_bitmap = { [0] = { [0]={}, [1]={}}, [1]={[0]={}, [1]={}} }
  445. local max_index = 1
  446. for ix = 0, max_index, 1 do
  447. for iy = 0, max_index, 1 do
  448. for iz = 0, max_index, 1 do
  449. new_bitmap[max_index-iy][ix][iz] = bitmap[ ix + (iy*2) + (iz*4) ]
  450. end
  451. end
  452. end
  453. return util.array3d_to_bitmap( new_bitmap )
  454. end
  455. util.rotate_bitmap_around_minus_z = function( bitmap )
  456. local new_bitmap = { [0] = { [0]={}, [1]={}}, [1]={[0]={}, [1]={}} }
  457. local max_index = 1
  458. for ix = 0, max_index, 1 do
  459. for iy = 0, max_index, 1 do
  460. for iz = 0, max_index, 1 do
  461. new_bitmap[iy][max_index-ix][iz] = bitmap[ ix + (iy*2) + (iz*4) ]
  462. end
  463. end
  464. end
  465. return util.array3d_to_bitmap( new_bitmap )
  466. end
  467. util.rotate_bitmap_around_plus_x = function( bitmap )
  468. local new_bitmap = { [0] = { [0]={}, [1]={}}, [1]={[0]={}, [1]={}} }
  469. local max_index = 1
  470. for ix = 0, max_index, 1 do
  471. for iy = 0, max_index, 1 do
  472. for iz = 0, max_index, 1 do
  473. new_bitmap[ix][max_index-iz][iy] = bitmap[ ix + (iy*2) + (iz*4) ]
  474. end
  475. end
  476. end
  477. return util.array3d_to_bitmap( new_bitmap )
  478. end
  479. util.rotate_bitmap_around_minus_x = function( bitmap )
  480. local new_bitmap = { [0] = { [0]={}, [1]={}}, [1]={[0]={}, [1]={}} }
  481. local max_index = 1
  482. for ix = 0, max_index, 1 do
  483. for iy = 0, max_index, 1 do
  484. for iz = 0, max_index, 1 do
  485. new_bitmap[ix][iz][max_index-iy] = bitmap[ ix + (iy*2) + (iz*4) ]
  486. end
  487. end
  488. end
  489. return util.array3d_to_bitmap( new_bitmap )
  490. end
  491. -- bitmap orientation assumes the current bitmap orientation is plus y
  492. util.orient_bitmap_towards_plus_z = function( bitmap )
  493. return util.rotate_bitmap_around_plus_x( bitmap )
  494. end
  495. util.orient_bitmap_towards_minus_z = function( bitmap )
  496. return util.rotate_bitmap_around_minus_x( bitmap )
  497. end
  498. util.orient_bitmap_towards_plus_x = function( bitmap )
  499. return util.rotate_bitmap_around_minus_z( bitmap )
  500. end
  501. util.orient_bitmap_towards_minus_x = function( bitmap )
  502. return util.rotate_bitmap_around_plus_z( bitmap )
  503. end
  504. util.orient_bitmap_towards_minus_y = function( bitmap )
  505. return util.rotate_bitmap_around_plus_z( util.rotate_bitmap_around_plus_z( bitmap ) )
  506. end
  507. util.bitmap_to_array3d = function( bitmap )
  508. local array = { [0] = { [0]={}, [1]={}}, [1]={[0]={}, [1]={}} }
  509. local max_index = 1
  510. for ix = 0, max_index, 1 do
  511. for iy = 0, max_index, 1 do
  512. for iz = 0, max_index, 1 do
  513. array[ix][iy][iz] = bitmap[ ix + (iy*2) + (iz*4)]
  514. end
  515. end
  516. end
  517. return array
  518. end
  519. util.array3d_to_bitmap = function( array )
  520. local bitmap = {}
  521. local max_index = 1
  522. for ix = 0, max_index, 1 do
  523. for iy = 0, max_index, 1 do
  524. for iz = 0, max_index, 1 do
  525. bitmap[ ix + (iy*2) + (iz*4) ] = array[ix][iy][iz]
  526. end
  527. end
  528. end
  529. return bitmap
  530. end