Voxel.cpp 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. /******************************************************************************/
  5. // MARCHING CUBES - based on Paul Bourke's - http://paulbourke.net/geometry/polygonise/
  6. /******************************************************************************/
  7. static const VecB VoxelOffset[]=
  8. {
  9. VecB(0, 0, 0), // 0
  10. VecB(1, 0, 0), // 1
  11. VecB(0, 1, 0), // 2
  12. VecB(1, 1, 0), // 3
  13. VecB(0, 0, 1), // 4
  14. VecB(1, 0, 1), // 5
  15. VecB(0, 1, 1), // 6
  16. VecB(1, 1, 1), // 7
  17. };
  18. static struct VoxelTri
  19. {
  20. U16 vtx_mask;
  21. Byte tris, quads, vtx_ind[13];
  22. }const VoxelTris[]=
  23. {
  24. {0x000, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  25. {0x109, 1, 0, {3, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  26. {0x203, 1, 0, {9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  27. {0x30A, 0, 1, {1, 3, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  28. {0x80C, 1, 0, {2, 11, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  29. {0x905, 0, 1, {0, 2, 11, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  30. {0xA0F, 2, 0, {0, 9, 1, 11, 3, 2, 0, 0, 0, 0, 0, 0, 0}},
  31. {0xB06, 3, 0, {2, 11, 1, 11, 9, 1, 11, 8, 9, 0, 0, 0, 0}},
  32. {0x406, 1, 0, {10, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  33. {0x50F, 2, 0, {3, 8, 0, 10, 2, 1, 0, 0, 0, 0, 0, 0, 0}},
  34. {0x605, 0, 1, {9, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  35. {0x70C, 3, 0, {3, 8, 2, 8, 10, 2, 8, 9, 10, 0, 0, 0, 0}},
  36. {0xC0A, 0, 1, {3, 1, 10, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  37. {0xD03, 3, 0, {1, 10, 0, 10, 8, 0, 10, 11, 8, 0, 0, 0, 0}},
  38. {0xE09, 3, 0, {0, 9, 3, 9, 11, 3, 9, 10, 11, 0, 0, 0, 0}},
  39. {0xF00, 2, 0, {10, 8, 9, 11, 8, 10, 0, 0, 0, 0, 0, 0, 0}},
  40. {0x190, 1, 0, {8, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  41. {0x099, 0, 1, {4, 0, 3, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  42. {0x393, 2, 0, {9, 1, 0, 7, 4, 8, 0, 0, 0, 0, 0, 0, 0}},
  43. {0x29A, 3, 0, {9, 1, 4, 1, 7, 4, 1, 3, 7, 0, 0, 0, 0}},
  44. {0x99C, 2, 0, {7, 4, 8, 2, 11, 3, 0, 0, 0, 0, 0, 0, 0}},
  45. {0x895, 3, 0, {7, 4, 11, 4, 2, 11, 4, 0, 2, 0, 0, 0, 0}},
  46. {0xB9F, 3, 0, {1, 0, 9, 7, 4, 8, 11, 3, 2, 0, 0, 0, 0}},
  47. {0xA96, 2, 1, {2, 11, 9, 1, 2, 9, 11, 7, 4, 9, 0, 0, 0}},
  48. {0x596, 2, 0, {10, 2, 1, 7, 4, 8, 0, 0, 0, 0, 0, 0, 0}},
  49. {0x49F, 3, 0, {7, 4, 3, 4, 0, 3, 10, 2, 1, 0, 0, 0, 0}},
  50. {0x795, 3, 0, {10, 2, 9, 2, 0, 9, 7, 4, 8, 0, 0, 0, 0}},
  51. {0x69C, 4, 0, {9, 10, 2, 7, 9, 2, 3, 7, 2, 4, 9, 7, 0}},
  52. {0xD9A, 3, 0, {1, 10, 3, 10, 11, 3, 4, 8, 7, 0, 0, 0, 0}},
  53. {0xC93, 2, 1, {10, 11, 1, 4, 0, 1, 4, 1, 11, 7, 0, 0, 0}},
  54. {0xF99, 4, 0, {8, 7, 4, 11, 0, 9, 10, 11, 9, 3, 0, 11, 0}},
  55. {0xE90, 3, 0, {11, 7, 4, 9, 11, 4, 10, 11, 9, 0, 0, 0, 0}},
  56. {0x230, 1, 0, {4, 5, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  57. {0x339, 2, 0, {4, 5, 9, 3, 8, 0, 0, 0, 0, 0, 0, 0, 0}},
  58. {0x033, 0, 1, {0, 4, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  59. {0x13A, 3, 0, {4, 5, 8, 5, 3, 8, 5, 1, 3, 0, 0, 0, 0}},
  60. {0xA3C, 2, 0, {4, 5, 9, 11, 3, 2, 0, 0, 0, 0, 0, 0, 0}},
  61. {0xB35, 3, 0, {2, 11, 0, 11, 8, 0, 5, 9, 4, 0, 0, 0, 0}},
  62. {0x83F, 3, 0, {4, 5, 0, 5, 1, 0, 11, 3, 2, 0, 0, 0, 0}},
  63. {0x936, 2, 1, {5, 1, 2, 11, 8, 2, 5, 2, 8, 4, 0, 0, 0}},
  64. {0x636, 2, 0, {10, 2, 1, 4, 5, 9, 0, 0, 0, 0, 0, 0, 0}},
  65. {0x73F, 3, 0, {8, 0, 3, 10, 2, 1, 5, 9, 4, 0, 0, 0, 0}},
  66. {0x435, 3, 0, {10, 2, 5, 2, 4, 5, 2, 0, 4, 0, 0, 0, 0}},
  67. {0x53C, 2, 1, {4, 5, 3, 8, 4, 3, 5, 10, 2, 3, 0, 0, 0}},
  68. {0xE3A, 3, 0, {11, 3, 10, 3, 1, 10, 4, 5, 9, 0, 0, 0, 0}},
  69. {0xF33, 4, 0, {5, 9, 4, 1, 8, 0, 1, 10, 8, 10, 11, 8, 0}},
  70. {0xC39, 4, 0, {0, 4, 5, 11, 0, 5, 10, 11, 5, 3, 0, 11, 0}},
  71. {0xD30, 3, 0, {8, 4, 5, 10, 8, 5, 11, 8, 10, 0, 0, 0, 0}},
  72. {0x3A0, 0, 1, {9, 8, 7, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  73. {0x2A9, 3, 0, {0, 3, 9, 3, 5, 9, 3, 7, 5, 0, 0, 0, 0}},
  74. {0x1A3, 3, 0, {8, 7, 0, 7, 1, 0, 7, 5, 1, 0, 0, 0, 0}},
  75. {0x0AA, 2, 0, {3, 5, 1, 7, 5, 3, 0, 0, 0, 0, 0, 0, 0}},
  76. {0xBAC, 3, 0, {5, 9, 7, 9, 8, 7, 2, 11, 3, 0, 0, 0, 0}},
  77. {0xAA5, 4, 0, {7, 5, 9, 2, 7, 9, 0, 2, 9, 11, 7, 2, 0}},
  78. {0x9AF, 4, 0, {11, 3, 2, 8, 1, 0, 8, 7, 1, 7, 5, 1, 0}},
  79. {0x8A6, 3, 0, {1, 2, 11, 7, 1, 11, 5, 1, 7, 0, 0, 0, 0}},
  80. {0x7A6, 3, 0, {8, 7, 9, 7, 5, 9, 2, 1, 10, 0, 0, 0, 0}},
  81. {0x6AF, 4, 0, {2, 1, 10, 0, 5, 9, 0, 3, 5, 3, 7, 5, 0}},
  82. {0x5A5, 2, 1, {2, 0, 8, 7, 5, 8, 2, 8, 5, 10, 0, 0, 0}},
  83. {0x4AC, 3, 0, {5, 10, 2, 3, 5, 2, 7, 5, 3, 0, 0, 0, 0}},
  84. {0xFAA, 4, 0, {8, 5, 9, 7, 5, 8, 3, 1, 10, 11, 3, 10, 0}},
  85. {0xEA3, 3, 1, {0, 7, 5, 9, 0, 5, 0, 11, 7, 0, 1, 10, 11}},
  86. {0xDA9, 3, 1, {0, 10, 11, 3, 0, 11, 0, 5, 10, 0, 8, 7, 5}},
  87. {0xCA0, 0, 1, {5, 10, 11, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  88. {0x8C0, 1, 0, {11, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  89. {0x9C9, 2, 0, {8, 0, 3, 6, 7, 11, 0, 0, 0, 0, 0, 0, 0}},
  90. {0xAC3, 2, 0, {9, 1, 0, 6, 7, 11, 0, 0, 0, 0, 0, 0, 0}},
  91. {0xBCA, 3, 0, {9, 1, 8, 1, 3, 8, 6, 7, 11, 0, 0, 0, 0}},
  92. {0x0CC, 0, 1, {7, 3, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  93. {0x1C5, 3, 0, {8, 0, 7, 0, 6, 7, 0, 2, 6, 0, 0, 0, 0}},
  94. {0x2CF, 3, 0, {6, 7, 2, 7, 3, 2, 9, 1, 0, 0, 0, 0, 0}},
  95. {0x3C6, 4, 0, {2, 6, 1, 6, 8, 1, 8, 9, 1, 6, 7, 8, 0}},
  96. {0xCC6, 2, 0, {2, 1, 10, 7, 11, 6, 0, 0, 0, 0, 0, 0, 0}},
  97. {0xDCF, 3, 0, {10, 2, 1, 8, 0, 3, 7, 11, 6, 0, 0, 0, 0}},
  98. {0xEC5, 3, 0, {0, 9, 2, 9, 10, 2, 7, 11, 6, 0, 0, 0, 0}},
  99. {0xFCC, 4, 0, {7, 11, 6, 3, 10, 2, 3, 8, 10, 8, 9, 10, 0}},
  100. {0x4CA, 3, 0, {6, 7, 10, 7, 1, 10, 7, 3, 1, 0, 0, 0, 0}},
  101. {0x5C3, 2, 1, {7, 8, 1, 8, 0, 1, 10, 6, 7, 1, 0, 0, 0}},
  102. {0x6C9, 2, 1, {7, 3, 0, 9, 10, 0, 7, 0, 10, 6, 0, 0, 0}},
  103. {0x7C0, 3, 0, {10, 6, 7, 8, 10, 7, 9, 10, 8, 0, 0, 0, 0}},
  104. {0x950, 0, 1, {6, 4, 8, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  105. {0x859, 3, 0, {11, 6, 3, 6, 0, 3, 6, 4, 0, 0, 0, 0, 0}},
  106. {0xB53, 3, 0, {11, 6, 8, 6, 4, 8, 1, 0, 9, 0, 0, 0, 0}},
  107. {0xA5A, 2, 1, {6, 4, 9, 1, 3, 9, 6, 9, 3, 11, 0, 0, 0}},
  108. {0x15C, 3, 0, {3, 2, 8, 2, 4, 8, 2, 6, 4, 0, 0, 0, 0}},
  109. {0x055, 2, 0, {2, 4, 0, 2, 6, 4, 0, 0, 0, 0, 0, 0, 0}},
  110. {0x35F, 4, 0, {0, 9, 1, 4, 3, 2, 6, 4, 2, 8, 3, 4, 0}},
  111. {0x256, 3, 0, {4, 9, 1, 2, 4, 1, 6, 4, 2, 0, 0, 0, 0}},
  112. {0xD56, 3, 0, {4, 8, 6, 8, 11, 6, 1, 10, 2, 0, 0, 0, 0}},
  113. {0xC5F, 4, 0, {10, 2, 1, 11, 0, 3, 11, 6, 0, 6, 4, 0, 0}},
  114. {0xF55, 4, 0, {8, 11, 4, 11, 6, 4, 9, 2, 0, 9, 10, 2, 0}},
  115. {0xE5C, 3, 1, {3, 9, 10, 2, 3, 10, 3, 4, 9, 3, 11, 6, 4}},
  116. {0x55A, 4, 0, {3, 1, 8, 1, 6, 8, 6, 4, 8, 1, 10, 6, 0}},
  117. {0x453, 3, 0, {0, 1, 10, 6, 0, 10, 4, 0, 6, 0, 0, 0, 0}},
  118. {0x759, 3, 1, {3, 6, 4, 8, 3, 4, 3, 10, 6, 3, 0, 9, 10}},
  119. {0x650, 0, 1, {4, 9, 10, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  120. {0xAF0, 2, 0, {5, 9, 4, 11, 6, 7, 0, 0, 0, 0, 0, 0, 0}},
  121. {0xBF9, 3, 0, {3, 8, 0, 5, 9, 4, 6, 7, 11, 0, 0, 0, 0}},
  122. {0x8F3, 3, 0, {1, 0, 5, 0, 4, 5, 11, 6, 7, 0, 0, 0, 0}},
  123. {0x9FA, 4, 0, {6, 7, 11, 4, 3, 8, 4, 5, 3, 5, 1, 3, 0}},
  124. {0x2FC, 3, 0, {3, 2, 7, 2, 6, 7, 9, 4, 5, 0, 0, 0, 0}},
  125. {0x3F5, 4, 0, {4, 5, 9, 6, 8, 0, 2, 6, 0, 7, 8, 6, 0}},
  126. {0x0FF, 4, 0, {2, 6, 3, 6, 7, 3, 0, 5, 1, 0, 4, 5, 0}},
  127. {0x1F6, 3, 1, {8, 2, 6, 7, 8, 6, 8, 1, 2, 8, 4, 5, 1}},
  128. {0xEF6, 3, 0, {4, 5, 9, 2, 1, 10, 11, 6, 7, 0, 0, 0, 0}},
  129. {0xFFF, 4, 0, {7, 11, 6, 10, 2, 1, 3, 8, 0, 5, 9, 4, 0}},
  130. {0xCF5, 4, 0, {11, 6, 7, 10, 4, 5, 10, 2, 4, 2, 0, 4, 0}},
  131. {0xDFC, 3, 1, {8, 4, 3, 4, 5, 3, 6, 7, 11, 2, 3, 5, 10}},
  132. {0x6FA, 4, 0, {4, 5, 9, 6, 1, 10, 6, 7, 1, 7, 3, 1, 0}},
  133. {0x7F3, 3, 1, {10, 6, 1, 6, 7, 1, 4, 5, 9, 0, 1, 7, 8}},
  134. {0x4F9, 3, 1, {10, 0, 4, 5, 10, 4, 10, 3, 0, 10, 6, 7, 3}},
  135. {0x5F0, 2, 1, {10, 6, 7, 10, 4, 5, 10, 7, 8, 4, 0, 0, 0}},
  136. {0xB60, 3, 0, {5, 9, 6, 9, 11, 6, 9, 8, 11, 0, 0, 0, 0}},
  137. {0xA69, 2, 1, {6, 5, 0, 5, 9, 0, 3, 11, 6, 0, 0, 0, 0}},
  138. {0x963, 4, 0, {8, 11, 0, 11, 5, 0, 5, 1, 0, 11, 6, 5, 0}},
  139. {0x86A, 3, 0, {3, 11, 6, 5, 3, 6, 1, 3, 5, 0, 0, 0, 0}},
  140. {0x36C, 2, 1, {9, 8, 5, 2, 6, 5, 2, 5, 8, 3, 0, 0, 0}},
  141. {0x265, 3, 0, {6, 5, 9, 0, 6, 9, 2, 6, 0, 0, 0, 0, 0}},
  142. {0x16F, 3, 1, {8, 5, 1, 0, 8, 1, 8, 6, 5, 8, 3, 2, 6}},
  143. {0x066, 0, 1, {6, 5, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  144. {0xF66, 4, 0, {10, 2, 1, 11, 5, 9, 8, 11, 9, 6, 5, 11, 0}},
  145. {0xE6F, 3, 1, {3, 11, 0, 11, 6, 0, 10, 2, 1, 9, 0, 6, 5}},
  146. {0xD65, 3, 1, {5, 8, 11, 6, 5, 11, 5, 0, 8, 5, 10, 2, 0}},
  147. {0xC6C, 2, 1, {3, 11, 6, 3, 10, 2, 3, 6, 5, 10, 0, 0, 0}},
  148. {0x76A, 3, 1, {6, 3, 1, 10, 6, 1, 6, 8, 3, 6, 5, 9, 8}},
  149. {0x663, 2, 1, {0, 1, 10, 0, 5, 9, 0, 10, 6, 5, 0, 0, 0}},
  150. {0x569, 2, 0, {8, 3, 0, 10, 6, 5, 0, 0, 0, 0, 0, 0, 0}},
  151. {0x460, 1, 0, {6, 5, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  152. {0x460, 1, 0, {5, 6, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  153. {0x569, 2, 0, {3, 8, 0, 6, 10, 5, 0, 0, 0, 0, 0, 0, 0}},
  154. {0x663, 2, 0, {1, 0, 9, 6, 10, 5, 0, 0, 0, 0, 0, 0, 0}},
  155. {0x76A, 3, 0, {3, 8, 1, 8, 9, 1, 6, 10, 5, 0, 0, 0, 0}},
  156. {0xC6C, 2, 0, {11, 3, 2, 5, 6, 10, 0, 0, 0, 0, 0, 0, 0}},
  157. {0xD65, 3, 0, {8, 0, 11, 0, 2, 11, 5, 6, 10, 0, 0, 0, 0}},
  158. {0xE6F, 3, 0, {9, 1, 0, 11, 3, 2, 6, 10, 5, 0, 0, 0, 0}},
  159. {0xF66, 4, 0, {6, 10, 5, 2, 9, 1, 2, 11, 9, 11, 8, 9, 0}},
  160. {0x066, 0, 1, {1, 5, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  161. {0x16F, 3, 0, {5, 6, 1, 6, 2, 1, 8, 0, 3, 0, 0, 0, 0}},
  162. {0x265, 3, 0, {5, 6, 9, 6, 0, 9, 6, 2, 0, 0, 0, 0, 0}},
  163. {0x36C, 2, 1, {8, 9, 5, 6, 2, 5, 8, 5, 2, 3, 0, 0, 0}},
  164. {0x86A, 3, 0, {11, 3, 6, 3, 5, 6, 3, 1, 5, 0, 0, 0, 0}},
  165. {0x963, 4, 0, {11, 8, 0, 5, 11, 0, 1, 5, 0, 6, 11, 5, 0}},
  166. {0xA69, 2, 1, {5, 6, 0, 9, 5, 0, 6, 11, 3, 0, 0, 0, 0}},
  167. {0xB60, 3, 0, {9, 5, 6, 11, 9, 6, 8, 9, 11, 0, 0, 0, 0}},
  168. {0x5F0, 2, 0, {6, 10, 5, 8, 7, 4, 0, 0, 0, 0, 0, 0, 0}},
  169. {0x4F9, 3, 0, {0, 3, 4, 3, 7, 4, 10, 5, 6, 0, 0, 0, 0}},
  170. {0x7F3, 3, 0, {0, 9, 1, 6, 10, 5, 7, 4, 8, 0, 0, 0, 0}},
  171. {0x6FA, 4, 0, {5, 6, 10, 7, 9, 1, 3, 7, 1, 4, 9, 7, 0}},
  172. {0xDFC, 3, 0, {2, 11, 3, 4, 8, 7, 5, 6, 10, 0, 0, 0, 0}},
  173. {0xCF5, 4, 0, {6, 10, 5, 2, 7, 4, 0, 2, 4, 11, 7, 2, 0}},
  174. {0xFFF, 4, 0, {9, 1, 0, 8, 7, 4, 11, 3, 2, 6, 10, 5, 0}},
  175. {0xEF6, 3, 1, {1, 2, 9, 2, 11, 9, 6, 10, 5, 4, 9, 11, 7}},
  176. {0x1F6, 3, 0, {2, 1, 6, 1, 5, 6, 8, 7, 4, 0, 0, 0, 0}},
  177. {0x0FF, 4, 0, {5, 2, 1, 6, 2, 5, 4, 0, 3, 7, 4, 3, 0}},
  178. {0x3F5, 4, 0, {7, 4, 8, 5, 0, 9, 5, 6, 0, 6, 2, 0, 0}},
  179. {0x2FC, 3, 1, {9, 3, 7, 4, 9, 7, 9, 2, 3, 9, 5, 6, 2}},
  180. {0x9FA, 4, 0, {7, 4, 8, 5, 11, 3, 1, 5, 3, 6, 11, 5, 0}},
  181. {0x8F3, 3, 1, {11, 1, 5, 6, 11, 5, 11, 0, 1, 11, 7, 4, 0}},
  182. {0xBF9, 3, 1, {9, 5, 0, 5, 6, 0, 7, 4, 8, 3, 0, 6, 11}},
  183. {0xAF0, 2, 1, {9, 5, 6, 9, 7, 4, 9, 6, 11, 7, 0, 0, 0}},
  184. {0x650, 0, 1, {10, 9, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  185. {0x759, 3, 0, {6, 10, 4, 10, 9, 4, 3, 8, 0, 0, 0, 0, 0}},
  186. {0x453, 3, 0, {1, 0, 10, 0, 6, 10, 0, 4, 6, 0, 0, 0, 0}},
  187. {0x55A, 4, 0, {1, 3, 8, 6, 1, 8, 4, 6, 8, 10, 1, 6, 0}},
  188. {0xE5C, 3, 0, {9, 4, 10, 4, 6, 10, 3, 2, 11, 0, 0, 0, 0}},
  189. {0xF55, 4, 0, {2, 8, 0, 11, 8, 2, 10, 9, 4, 6, 10, 4, 0}},
  190. {0xC5F, 4, 0, {2, 11, 3, 6, 1, 0, 4, 6, 0, 10, 1, 6, 0}},
  191. {0xD56, 3, 1, {1, 4, 6, 10, 1, 6, 1, 8, 4, 1, 2, 11, 8}},
  192. {0x256, 3, 0, {9, 4, 1, 4, 2, 1, 4, 6, 2, 0, 0, 0, 0}},
  193. {0x35F, 4, 0, {8, 0, 3, 9, 2, 1, 9, 4, 2, 4, 6, 2, 0}},
  194. {0x055, 2, 0, {4, 2, 0, 6, 2, 4, 0, 0, 0, 0, 0, 0, 0}},
  195. {0x15C, 3, 0, {2, 3, 8, 4, 2, 8, 6, 2, 4, 0, 0, 0, 0}},
  196. {0xA5A, 2, 1, {4, 6, 9, 3, 1, 9, 3, 9, 6, 11, 0, 0, 0}},
  197. {0xB53, 3, 1, {1, 11, 8, 0, 1, 8, 1, 6, 11, 1, 9, 4, 6}},
  198. {0x859, 3, 0, {6, 11, 3, 0, 6, 3, 4, 6, 0, 0, 0, 0, 0}},
  199. {0x950, 0, 1, {8, 4, 6, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  200. {0x7C0, 3, 0, {6, 10, 7, 10, 8, 7, 10, 9, 8, 0, 0, 0, 0}},
  201. {0x6C9, 2, 1, {3, 7, 0, 10, 9, 0, 10, 0, 7, 6, 0, 0, 0}},
  202. {0x5C3, 2, 1, {8, 7, 1, 0, 8, 1, 7, 6, 10, 1, 0, 0, 0}},
  203. {0x4CA, 3, 0, {7, 6, 10, 1, 7, 10, 3, 7, 1, 0, 0, 0, 0}},
  204. {0xFCC, 4, 0, {11, 3, 2, 8, 6, 10, 9, 8, 10, 7, 6, 8, 0}},
  205. {0xEC5, 3, 1, {7, 0, 2, 11, 7, 2, 7, 9, 0, 7, 6, 10, 9}},
  206. {0xDCF, 3, 1, {0, 8, 1, 8, 7, 1, 11, 3, 2, 10, 1, 7, 6}},
  207. {0xCC6, 2, 1, {1, 2, 11, 1, 6, 10, 1, 11, 7, 6, 0, 0, 0}},
  208. {0x3C6, 4, 0, {6, 2, 1, 8, 6, 1, 9, 8, 1, 7, 6, 8, 0}},
  209. {0x2CF, 3, 1, {9, 6, 2, 1, 9, 2, 9, 7, 6, 9, 0, 3, 7}},
  210. {0x1C5, 3, 0, {0, 8, 7, 6, 0, 7, 2, 0, 6, 0, 0, 0, 0}},
  211. {0x0CC, 0, 1, {2, 3, 7, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  212. {0xBCA, 3, 1, {6, 9, 8, 7, 6, 8, 6, 1, 9, 6, 11, 3, 1}},
  213. {0xAC3, 2, 0, {1, 9, 0, 7, 6, 11, 0, 0, 0, 0, 0, 0, 0}},
  214. {0x9C9, 2, 1, {0, 8, 7, 0, 11, 3, 0, 7, 6, 11, 0, 0, 0}},
  215. {0x8C0, 1, 0, {6, 11, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  216. {0xCA0, 0, 1, {11, 10, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  217. {0xDA9, 3, 0, {10, 5, 11, 5, 7, 11, 0, 3, 8, 0, 0, 0, 0}},
  218. {0xEA3, 3, 0, {7, 11, 5, 11, 10, 5, 0, 9, 1, 0, 0, 0, 0}},
  219. {0xFAA, 4, 0, {5, 7, 10, 7, 11, 10, 1, 8, 9, 1, 3, 8, 0}},
  220. {0x4AC, 3, 0, {10, 5, 2, 5, 3, 2, 5, 7, 3, 0, 0, 0, 0}},
  221. {0x5A5, 2, 1, {0, 2, 8, 5, 7, 8, 5, 8, 2, 10, 0, 0, 0}},
  222. {0x6AF, 4, 0, {1, 0, 9, 3, 10, 5, 7, 3, 5, 2, 10, 3, 0}},
  223. {0x7A6, 3, 1, {2, 8, 9, 1, 2, 9, 2, 7, 8, 2, 10, 5, 7}},
  224. {0x8A6, 3, 0, {2, 1, 11, 1, 7, 11, 1, 5, 7, 0, 0, 0, 0}},
  225. {0x9AF, 4, 0, {3, 8, 0, 7, 2, 1, 5, 7, 1, 11, 2, 7, 0}},
  226. {0xAA5, 4, 0, {5, 7, 9, 7, 2, 9, 2, 0, 9, 7, 11, 2, 0}},
  227. {0xBAC, 3, 1, {2, 5, 7, 11, 2, 7, 2, 9, 5, 2, 3, 8, 9}},
  228. {0x0AA, 2, 0, {5, 3, 1, 5, 7, 3, 0, 0, 0, 0, 0, 0, 0}},
  229. {0x1A3, 3, 0, {7, 8, 0, 1, 7, 0, 5, 7, 1, 0, 0, 0, 0}},
  230. {0x2A9, 3, 0, {3, 0, 9, 5, 3, 9, 7, 3, 5, 0, 0, 0, 0}},
  231. {0x3A0, 0, 1, {7, 8, 9, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  232. {0xD30, 3, 0, {4, 8, 5, 8, 10, 5, 8, 11, 10, 0, 0, 0, 0}},
  233. {0xC39, 4, 0, {4, 0, 5, 0, 11, 5, 11, 10, 5, 0, 3, 11, 0}},
  234. {0xF33, 4, 0, {9, 1, 0, 10, 4, 8, 11, 10, 8, 5, 4, 10, 0}},
  235. {0xE3A, 3, 1, {4, 11, 10, 5, 4, 10, 4, 3, 11, 4, 9, 1, 3}},
  236. {0x53C, 2, 1, {5, 4, 3, 4, 8, 3, 2, 10, 5, 3, 0, 0, 0}},
  237. {0x435, 3, 0, {2, 10, 5, 4, 2, 5, 0, 2, 4, 0, 0, 0, 0}},
  238. {0x73F, 3, 1, {2, 10, 3, 10, 5, 3, 9, 1, 0, 8, 3, 5, 4}},
  239. {0x636, 2, 1, {2, 10, 5, 2, 9, 1, 2, 5, 4, 9, 0, 0, 0}},
  240. {0x936, 2, 1, {1, 5, 2, 8, 11, 2, 8, 2, 5, 4, 0, 0, 0}},
  241. {0x83F, 3, 1, {11, 4, 0, 3, 11, 0, 11, 5, 4, 11, 2, 1, 5}},
  242. {0xB35, 3, 1, {5, 2, 0, 9, 5, 0, 5, 11, 2, 5, 4, 8, 11}},
  243. {0xA3C, 2, 0, {5, 4, 9, 3, 11, 2, 0, 0, 0, 0, 0, 0, 0}},
  244. {0x13A, 3, 0, {5, 4, 8, 3, 5, 8, 1, 5, 3, 0, 0, 0, 0}},
  245. {0x033, 0, 1, {5, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  246. {0x339, 2, 1, {5, 4, 8, 5, 0, 9, 5, 8, 3, 0, 0, 0, 0}},
  247. {0x230, 1, 0, {5, 4, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  248. {0xE90, 3, 0, {7, 11, 4, 11, 9, 4, 11, 10, 9, 0, 0, 0, 0}},
  249. {0xF99, 4, 0, {3, 8, 0, 7, 9, 4, 7, 11, 9, 11, 10, 9, 0}},
  250. {0xC93, 2, 1, {11, 10, 1, 0, 4, 1, 11, 1, 4, 7, 0, 0, 0}},
  251. {0xD9A, 3, 1, {4, 1, 3, 8, 4, 3, 4, 10, 1, 4, 7, 11, 10}},
  252. {0x69C, 4, 0, {10, 9, 2, 9, 7, 2, 7, 3, 2, 9, 4, 7, 0}},
  253. {0x795, 3, 1, {7, 10, 9, 4, 7, 9, 7, 2, 10, 7, 8, 0, 2}},
  254. {0x49F, 3, 1, {10, 7, 3, 2, 10, 3, 10, 4, 7, 10, 1, 0, 4}},
  255. {0x596, 2, 0, {2, 10, 1, 4, 7, 8, 0, 0, 0, 0, 0, 0, 0}},
  256. {0xA96, 2, 1, {11, 2, 9, 2, 1, 9, 4, 7, 11, 9, 0, 0, 0}},
  257. {0xB9F, 3, 1, {4, 7, 9, 7, 11, 9, 3, 8, 0, 1, 9, 11, 2}},
  258. {0x895, 3, 0, {4, 7, 11, 2, 4, 11, 0, 4, 2, 0, 0, 0, 0}},
  259. {0x99C, 2, 1, {4, 7, 11, 4, 3, 8, 4, 11, 2, 3, 0, 0, 0}},
  260. {0x29A, 3, 0, {1, 9, 4, 7, 1, 4, 3, 1, 7, 0, 0, 0, 0}},
  261. {0x393, 2, 1, {1, 9, 4, 1, 8, 0, 1, 4, 7, 8, 0, 0, 0}},
  262. {0x099, 0, 1, {3, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  263. {0x190, 1, 0, {7, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  264. {0xF00, 2, 0, {8, 10, 9, 8, 11, 10, 0, 0, 0, 0, 0, 0, 0}},
  265. {0xE09, 3, 0, {9, 0, 3, 11, 9, 3, 10, 9, 11, 0, 0, 0, 0}},
  266. {0xD03, 3, 0, {10, 1, 0, 8, 10, 0, 11, 10, 8, 0, 0, 0, 0}},
  267. {0xC0A, 0, 1, {10, 1, 3, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  268. {0x70C, 3, 0, {8, 3, 2, 10, 8, 2, 9, 8, 10, 0, 0, 0, 0}},
  269. {0x605, 0, 1, {2, 10, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  270. {0x50F, 2, 1, {8, 3, 2, 8, 1, 0, 8, 2, 10, 1, 0, 0, 0}},
  271. {0x406, 1, 0, {2, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  272. {0xB06, 3, 0, {11, 2, 1, 9, 11, 1, 8, 11, 9, 0, 0, 0, 0}},
  273. {0xA0F, 2, 1, {9, 0, 3, 9, 2, 1, 9, 3, 11, 2, 0, 0, 0}},
  274. {0x905, 0, 1, {11, 2, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  275. {0x80C, 1, 0, {11, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  276. {0x30A, 0, 1, {8, 3, 1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  277. {0x203, 1, 0, {1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  278. {0x109, 1, 0, {8, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  279. {0x000, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  280. };
  281. /******************************************************************************/
  282. T1(TYPE) struct VoxelZero
  283. {
  284. static const TYPE value;
  285. };
  286. template<> const SByte VoxelZero<SByte>::value=0;
  287. template<> const Byte VoxelZero< Byte>::value=128;
  288. template<> const Flt VoxelZero< Flt >::value=0;
  289. static Flt VoxelLerp(SByte a_value, SByte b_value) { return (a_value!=b_value) ? Flt(a_value )/(a_value-b_value) : 0.5f;}
  290. static Flt VoxelLerp( Byte a_value, Byte b_value) { return (a_value!=b_value) ? Flt(a_value-128)/(a_value-b_value) : 0.5f;}
  291. static Flt VoxelLerp( Flt a_value, Flt b_value) {Flt d=a_value-b_value; return d ? a_value / d : 0.5f;}
  292. static Vec VoxelLerp(C VecI &a_pos, C VecI &b_pos, SByte a_value, SByte b_value) {return Lerp(a_pos, b_pos, VoxelLerp(a_value, b_value));}
  293. static Vec VoxelLerp(C VecI &a_pos, C VecI &b_pos, Byte a_value, Byte b_value) {return Lerp(a_pos, b_pos, VoxelLerp(a_value, b_value));}
  294. static Vec VoxelLerp(C VecI &a_pos, C VecI &b_pos, Flt a_value, Flt b_value) {return Lerp(a_pos, b_pos, VoxelLerp(a_value, b_value));}
  295. T1(TYPE) void _SetVoxelTris(C VecI &pos, TYPE (&Voxel)(C VecI &pos), MemPtr<Tri> tris)
  296. {
  297. #if 0
  298. VecI val_pos[8];
  299. TYPE val [8]; REPAO(val)=Voxel(val_pos[i]=pos+VoxelOffset[i]);
  300. #else
  301. TYPE val[8]; REPAO(val)=Voxel(pos+VoxelOffset[i]);
  302. #endif
  303. Int case_index=0;
  304. if(val[0]<VoxelZero<TYPE>::value)case_index|= 1;
  305. if(val[1]<VoxelZero<TYPE>::value)case_index|= 2;
  306. if(val[2]<VoxelZero<TYPE>::value)case_index|= 4;
  307. if(val[3]<VoxelZero<TYPE>::value)case_index|= 8;
  308. if(val[4]<VoxelZero<TYPE>::value)case_index|= 16;
  309. if(val[5]<VoxelZero<TYPE>::value)case_index|= 32;
  310. if(val[6]<VoxelZero<TYPE>::value)case_index|= 64;
  311. if(val[7]<VoxelZero<TYPE>::value)case_index|=128;
  312. C VoxelTri &vt=VoxelTris[case_index]; if(UInt vtx_mask=vt.vtx_mask)
  313. {
  314. Vec vtxs[12];
  315. #if 0
  316. if(vtx_mask& 1)vtxs[ 0]=VoxelLerp(val_pos[0], val_pos[1], val[0], val[1]);
  317. if(vtx_mask& 2)vtxs[ 1]=VoxelLerp(val_pos[1], val_pos[3], val[1], val[3]);
  318. if(vtx_mask& 4)vtxs[ 2]=VoxelLerp(val_pos[2], val_pos[3], val[2], val[3]);
  319. if(vtx_mask& 8)vtxs[ 3]=VoxelLerp(val_pos[0], val_pos[2], val[0], val[2]);
  320. if(vtx_mask& 16)vtxs[ 4]=VoxelLerp(val_pos[4], val_pos[5], val[4], val[5]);
  321. if(vtx_mask& 32)vtxs[ 5]=VoxelLerp(val_pos[5], val_pos[7], val[5], val[7]);
  322. if(vtx_mask& 64)vtxs[ 6]=VoxelLerp(val_pos[6], val_pos[7], val[6], val[7]);
  323. if(vtx_mask& 128)vtxs[ 7]=VoxelLerp(val_pos[4], val_pos[6], val[4], val[6]);
  324. if(vtx_mask& 256)vtxs[ 8]=VoxelLerp(val_pos[0], val_pos[4], val[0], val[4]);
  325. if(vtx_mask& 512)vtxs[ 9]=VoxelLerp(val_pos[1], val_pos[5], val[1], val[5]);
  326. if(vtx_mask&1024)vtxs[10]=VoxelLerp(val_pos[3], val_pos[7], val[3], val[7]);
  327. if(vtx_mask&2048)vtxs[11]=VoxelLerp(val_pos[2], val_pos[6], val[2], val[6]);
  328. #else
  329. if(vtx_mask& 1)vtxs[ 0].set(pos.x+VoxelLerp(val[0], val[1]), pos.y , pos.z);
  330. if(vtx_mask& 2)vtxs[ 1].set(pos.x+1 , pos.y+VoxelLerp(val[1], val[3]), pos.z);
  331. if(vtx_mask& 4)vtxs[ 2].set(pos.x+VoxelLerp(val[2], val[3]), pos.y+1 , pos.z);
  332. if(vtx_mask& 8)vtxs[ 3].set(pos.x , pos.y+VoxelLerp(val[0], val[2]), pos.z);
  333. if(vtx_mask& 16)vtxs[ 4].set(pos.x+VoxelLerp(val[4], val[5]), pos.y , pos.z+1);
  334. if(vtx_mask& 32)vtxs[ 5].set(pos.x+1 , pos.y+VoxelLerp(val[5], val[7]), pos.z+1);
  335. if(vtx_mask& 64)vtxs[ 6].set(pos.x+VoxelLerp(val[6], val[7]), pos.y+1 , pos.z+1);
  336. if(vtx_mask& 128)vtxs[ 7].set(pos.x , pos.y+VoxelLerp(val[4], val[6]), pos.z+1);
  337. if(vtx_mask& 256)vtxs[ 8].set(pos.x , pos.y , pos.z+VoxelLerp(val[0], val[4]));
  338. if(vtx_mask& 512)vtxs[ 9].set(pos.x+1 , pos.y , pos.z+VoxelLerp(val[1], val[5]));
  339. if(vtx_mask&1024)vtxs[10].set(pos.x+1 , pos.y+1 , pos.z+VoxelLerp(val[3], val[7]));
  340. if(vtx_mask&2048)vtxs[11].set(pos.x , pos.y+1 , pos.z+VoxelLerp(val[2], val[6]));
  341. #endif
  342. C Byte *src=vt.vtx_ind;
  343. REP(vt.tris)
  344. {
  345. C VecB &s=*(VecB*)src; src+=SIZE(VecB);
  346. Tri &t=tris.New();
  347. t.p[0]=vtxs[s.x];
  348. t.p[1]=vtxs[s.y];
  349. t.p[2]=vtxs[s.z];
  350. }
  351. if(vt.quads) // this can be either 0 or 1 (never anything else), so simple "if" check is enough
  352. {
  353. C VecB4 &s=*(VecB4*)src; //src+=SIZE(VecB4); not needed because it won't be used anymore
  354. Int i=tris.addNum(2);
  355. Tri &t0=tris[i], &t1=tris[i+1];
  356. #if 1 // fast
  357. t0.p[0]=vtxs[s.x];
  358. t0.p[1]=vtxs[s.y];
  359. t0.p[2]=vtxs[s.w];
  360. t1.p[0]=vtxs[s.w];
  361. t1.p[1]=vtxs[s.y];
  362. t1.p[2]=vtxs[s.z];
  363. #else // slower but only slightly better quality
  364. C Vec &a=vtxs[s.x],
  365. &b=vtxs[s.y],
  366. &c=vtxs[s.z],
  367. &d=vtxs[s.w];
  368. // quad can be made from 2 tris: abd+dbc, or abc+acd
  369. #if 0 // prefer option where 2 tris have similar area (and not where one is big and another small)
  370. if(Abs(TriArea2(a, b, d)-TriArea2(d, b, c))
  371. <Abs(TriArea2(a, b, c)-TriArea2(a, c, d)))
  372. #else // prefer option where 2 tris have smaller angle between each other (Cos of that angle is bigger)
  373. if(CosBetween(GetNormalU(a, b, d), GetNormalU(d, b, c))
  374. >CosBetween(GetNormalU(a, b, c), GetNormalU(a, c, d)))
  375. #endif
  376. {
  377. t0.p[0]=a; t0.p[1]=b; t0.p[2]=d;
  378. t1.p[0]=d; t1.p[1]=b; t1.p[2]=c;
  379. }else
  380. {
  381. t0.p[0]=a; t0.p[1]=b; t0.p[2]=c;
  382. t1.p[0]=a; t1.p[1]=c; t1.p[2]=d;
  383. }
  384. #endif
  385. }
  386. }
  387. }
  388. void SetVoxelTris(C VecI &pos, SByte (&Voxel)(C VecI &pos), MemPtr<Tri> tris) {return _SetVoxelTris(pos, Voxel, tris);}
  389. //void SetVoxelTris(C VecI &pos, Flt (&Voxel)(C VecI &pos), MemPtr<Tri> tris) {return _SetVoxelTris(pos, Voxel, tris);}
  390. /******************************************************************************
  391. // based on http://paulbourke.net/geometry/polygonise/marchingsource.cpp
  392. static const SByte VoxelTriEdgePoints[256][16]=
  393. {{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  394. {0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  395. {0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  396. {1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  397. {1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  398. {0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  399. {9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  400. {2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
  401. {3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  402. {0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  403. {1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  404. {1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
  405. {3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  406. {0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
  407. {3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1},
  408. {9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  409. {4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  410. {4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  411. {0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  412. {4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
  413. {1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  414. {3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
  415. {9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
  416. {2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
  417. {8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  418. {11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
  419. {9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
  420. {4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
  421. {3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1},
  422. {1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
  423. {4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1},
  424. {4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
  425. {9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  426. {9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  427. {0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  428. {8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
  429. {1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  430. {3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
  431. {5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1},
  432. {2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
  433. {9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  434. {0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
  435. {0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
  436. {2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
  437. {10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1},
  438. {4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
  439. {5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1},
  440. {5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
  441. {9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  442. {9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
  443. {0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1},
  444. {1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  445. {9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1},
  446. {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
  447. {8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1},
  448. {2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
  449. {7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1},
  450. {9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
  451. {2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1},
  452. {11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
  453. {9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1},
  454. {5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
  455. {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1},
  456. {11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  457. {10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  458. {0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  459. {9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  460. {1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
  461. {1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  462. {1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
  463. {9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1},
  464. {5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
  465. {2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  466. {11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
  467. {0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
  468. {5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
  469. {6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1},
  470. {0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
  471. {3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1},
  472. {6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
  473. {5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  474. {4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
  475. {1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
  476. {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
  477. {6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1},
  478. {1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
  479. {8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1},
  480. {7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
  481. {3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
  482. {5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
  483. {0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1},
  484. {9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
  485. {8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1},
  486. {5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
  487. {0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1},
  488. {6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
  489. {10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  490. {4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
  491. {10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1},
  492. {8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
  493. {1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1},
  494. {3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
  495. {0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  496. {8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
  497. {10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1},
  498. {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
  499. {3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1},
  500. {6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
  501. {9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1},
  502. {8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
  503. {3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1},
  504. {6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  505. {7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1},
  506. {0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
  507. {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1},
  508. {10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
  509. {1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1},
  510. {2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
  511. {7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1},
  512. {7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  513. {2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1},
  514. {2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
  515. {1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1},
  516. {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
  517. {8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1},
  518. {0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  519. {7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1},
  520. {7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  521. {7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  522. {3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  523. {0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  524. {8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
  525. {10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  526. {1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
  527. {2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
  528. {6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
  529. {7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  530. {7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
  531. {2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1},
  532. {1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
  533. {10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1},
  534. {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
  535. {0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1},
  536. {7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
  537. {6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  538. {3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
  539. {8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1},
  540. {9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
  541. {6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1},
  542. {1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
  543. {4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1},
  544. {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
  545. {8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1},
  546. {0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  547. {1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1},
  548. {1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
  549. {8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1},
  550. {10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
  551. {4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1},
  552. {10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  553. {4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  554. {0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
  555. {5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
  556. {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
  557. {9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
  558. {6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
  559. {7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1},
  560. {3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
  561. {7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1},
  562. {9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
  563. {3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1},
  564. {6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
  565. {9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1},
  566. {1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
  567. {4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1},
  568. {7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
  569. {6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1},
  570. {3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
  571. {0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1},
  572. {6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
  573. {1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1},
  574. {0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
  575. {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1},
  576. {6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
  577. {5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1},
  578. {9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
  579. {1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1},
  580. {1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  581. {1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1},
  582. {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
  583. {0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  584. {10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  585. {11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  586. {11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
  587. {5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1},
  588. {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
  589. {11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1},
  590. {0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
  591. {9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1},
  592. {7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
  593. {2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1},
  594. {8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
  595. {9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1},
  596. {9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
  597. {1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  598. {0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
  599. {9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1},
  600. {9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  601. {5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1},
  602. {5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
  603. {0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1},
  604. {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
  605. {2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1},
  606. {0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
  607. {0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1},
  608. {9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  609. {2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1},
  610. {5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
  611. {3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1},
  612. {5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
  613. {8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1},
  614. {0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  615. {8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1},
  616. {9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  617. {4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1},
  618. {0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
  619. {1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1},
  620. {3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
  621. {4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1},
  622. {9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
  623. {11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1},
  624. {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
  625. {2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1},
  626. {9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
  627. {3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1},
  628. {1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  629. {4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1},
  630. {4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
  631. {4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  632. {4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  633. {9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  634. {3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
  635. {0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1},
  636. {3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  637. {1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1},
  638. {3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
  639. {0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  640. {3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  641. {2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1},
  642. {9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  643. {2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1},
  644. {1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  645. {1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  646. {0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  647. {0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  648. {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
  649. };
  650. void GenerateVoxelTris()
  651. {
  652. Mems<VoxelTri> vts; vts.setNumZero(Elms(VoxelTriEdgePoints));
  653. Memc<VecB> tris;
  654. Memc<VecB4> quads;
  655. Int mi=0;
  656. FREPAD(i, vts)
  657. {
  658. Int j=i;
  659. FlagSet(j, 4, FlagTest(i, 8)); FlagSet(j, 8, FlagTest(i, 4)); // swap #2 and #3
  660. FlagSet(j, 64, FlagTest(i, 128)); FlagSet(j, 128, FlagTest(i, 64)); // swap #6 and #7
  661. VoxelTri &vt=vts[j];
  662. vt.vtx_mask=0;
  663. for(Int p=0; VoxelTriEdgePoints[i][p]!=-1; p+=3)
  664. {
  665. VecB &t=tris.New();
  666. t.set(VoxelTriEdgePoints[i][p ],
  667. VoxelTriEdgePoints[i][p+1],
  668. VoxelTriEdgePoints[i][p+2]);
  669. t.reverse(); // reverse order of tris
  670. REPA(t)vt.vtx_mask|=1<<t.c[i];
  671. }
  672. REPA(tris)
  673. {
  674. VecB ti=tris[i];
  675. REPD(j, i)
  676. {
  677. VecB tj=tris[j];
  678. REPD(r, 3)if(ti.x==tj.c[r] && ti.y==tj.c[(r+2)%3])
  679. {
  680. tris.remove(i).remove(j); // remove 'i' first because it has bigger index, so after that, 'j' will be still the same
  681. quads.New().set(ti.x, tj.c[(r+1)%3], ti.y, ti.z);
  682. i--; goto next; // decrease by 1 because we've removed 2 and one "i--" is already called after 'next' automatically in 'REPA'
  683. }
  684. }
  685. next:;
  686. }
  687. MAX(mi, tris.elms()*3 + quads.elms()*4); DYNAMIC_ASSERT(mi<=MEMBER_ELMS(VoxelTri, vtx_ind), "mi out of range");
  688. DYNAMIC_ASSERT(quads.elms()<=1, "codes assume quads<=1");
  689. Byte *vtx_ind=vt.vtx_ind;
  690. vt. tris= tris.elms(); FREPA( tris){Copy(vtx_ind, & tris[i], SIZE(VecB )); vtx_ind+=SIZE(VecB );} tris .clear();
  691. vt.quads=quads.elms(); FREPA(quads){Copy(vtx_ind, &quads[i], SIZE(VecB4)); vtx_ind+=SIZE(VecB4);} quads.clear();
  692. }
  693. Str s;
  694. FREPA(vts)
  695. {
  696. C VoxelTri &vt=vts[i];
  697. s+=S+" {"+TextHex((UInt)vt.vtx_mask, 3, 0, true)+", "+vt.tris+", "+vt.quads+", {";
  698. //FREPA(vt.tri){if(i)s+=", "; s+=S+"{"+vt.tri[i]+"}";}
  699. FREPA(vt.vtx_ind){if(i)s+=", "; s+=vt.vtx_ind[i];}
  700. s+="}},\n";
  701. }
  702. ClipSet(s);
  703. }
  704. /******************************************************************************
  705. // SAMPLE USAGE
  706. /******************************************************************************
  707. SByte GetValue1(C VecI &pos) {return SFltToSByte(pos.length()-6);}
  708. Byte GetValue2(C VecI &pos) {return SFltToUByte(pos.length()-6);}
  709. Flt GetValue3(C VecI &pos) {return pos.length()-6 ;}
  710. {
  711. Memc<Tri> tris;
  712. for(Int x=-8; x<8; x++)
  713. for(Int y=-8; y<8; y++)
  714. for(Int z=-8; z<8; z++)
  715. {
  716. SetVoxelTris(VecI(x,y,z), GetValue3, tris);
  717. }
  718. MeshBase &base=mesh.parts(0).base;
  719. base.create(tris.elms()*3, 0, tris.elms(), 0);
  720. REPA(base.tri)base.tri.ind(i).set(i*3, i*3+1, i*3+2);
  721. REPA(tris)
  722. {
  723. base.vtx.pos(i*3 )=tris[i].p[0];
  724. base.vtx.pos(i*3+1)=tris[i].p[1];
  725. base.vtx.pos(i*3+2)=tris[i].p[2];
  726. }
  727. base.setNormals();
  728. //REPA(base.vtx)base.vtx.pos(i)+=base.vtx.nrm(i)*0.1f; // explode
  729. D.drawNullMaterials(true);
  730. mesh.setBox();
  731. mesh.setRender();
  732. }
  733. /******************************************************************************
  734. SURFACE NETS
  735. Based on:
  736. Mikola Lysenko "Surface Nets" (C) 2012, MIT License - https://github.com/mikolalysenko/mikolalysenko.github.com/blob/master/Isosurface/js/surfacenets.js
  737. S.F. Gibson, "Constrained Elastic Surface Nets". (1998) MERL Tech Report.
  738. /******************************************************************************/
  739. static const VecB2 CubeEdges[24]= // vertex number of each cube edge
  740. {
  741. {0, 1}, {0, 2}, {0, 4}, {1, 3}, {1, 5}, {2, 3}, {2, 6}, {3, 7}, {4, 5}, {4, 6}, {5, 7}, {6, 7}
  742. };
  743. static const U16 EdgeTable[256]= // 2^(cube configuration) -> 2^(edge configuration) map, there is one entry for each possible cube configuration, and the output is a 12-bit vector enumerating all edges crossing the 0-level
  744. {
  745. 0, 7, 25, 30, 98, 101, 123, 124, 168, 175, 177, 182, 202, 205, 211, 212, 772, 771, 797, 794, 870, 865, 895, 888, 940, 939, 949, 946, 974, 969, 983, 976, 1296, 1303, 1289, 1294, 1394, 1397, 1387, 1388, 1464, 1471, 1441, 1446, 1498, 1501, 1475, 1476, 1556, 1555, 1549, 1546, 1654, 1649, 1647, 1640, 1724, 1723, 1701, 1698, 1758, 1753, 1735, 1728, 2624, 2631, 2649, 2654, 2594, 2597, 2619, 2620, 2792, 2799, 2801, 2806, 2698, 2701, 2707, 2708, 2372, 2371, 2397, 2394, 2342, 2337, 2367, 2360, 2540, 2539, 2549, 2546, 2446, 2441, 2455, 2448, 3920, 3927, 3913, 3918, 3890, 3893, 3883, 3884, 4088, 4095, 4065, 4070, 3994, 3997, 3971, 3972, 3156, 3155, 3149, 3146, 3126, 3121, 3119, 3112, 3324, 3323, 3301, 3298, 3230, 3225, 3207, 3200, 3200, 3207, 3225, 3230, 3298, 3301, 3323, 3324, 3112, 3119, 3121, 3126, 3146, 3149, 3155, 3156, 3972, 3971, 3997, 3994, 4070, 4065, 4095, 4088, 3884, 3883, 3893, 3890, 3918, 3913, 3927, 3920, 2448, 2455, 2441, 2446, 2546, 2549, 2539, 2540, 2360, 2367, 2337, 2342, 2394, 2397, 2371, 2372, 2708, 2707, 2701, 2698, 2806, 2801, 2799, 2792, 2620, 2619, 2597, 2594, 2654, 2649, 2631, 2624, 1728, 1735, 1753, 1758, 1698, 1701, 1723, 1724, 1640, 1647, 1649, 1654, 1546, 1549, 1555, 1556, 1476, 1475, 1501, 1498, 1446, 1441, 1471, 1464, 1388, 1387, 1397, 1394, 1294, 1289, 1303, 1296, 976, 983, 969, 974, 946, 949, 939, 940, 888, 895, 865, 870, 794, 797, 771, 772, 212, 211, 205, 202, 182, 177, 175, 168, 124, 123, 101, 98, 30, 25, 7, 0
  746. };
  747. /*static void GenerateTables()
  748. {
  749. VecB2 cube_edges[12]; // vertex number of each cube edge
  750. Int k=0; FREP(8)for(Int j=1; j<=4; j<<=1)
  751. {
  752. Int p=i^j; if(i<=p)cube_edges[k++].set(i, p);
  753. }
  754. U16 edge_table[256];
  755. FREPA(edge_table)
  756. {
  757. UInt em=0;
  758. FREPAD(j, cube_edges)
  759. {
  760. Int a=!(i&(1<<cube_edges[j].x)),
  761. b=!(i&(1<<cube_edges[j].y));
  762. if(a!=b)em|=(1<<j);
  763. }
  764. edge_table[i]=em;
  765. }
  766. Str s ="{\n "; FREPA(cube_edges){if(i)s+=", "; s+=S+'{'+cube_edges[i]+'}';} s+="\n};\n";
  767. s+="{\n "; FREPA(edge_table){if(i)s+=", "; s+= edge_table[i] ;} s+="\n};\n";
  768. ClipSet(s);
  769. }*/
  770. void SetVoxelTris(Flt *data, C VecI &dims, MemPtr<Vec> vtxs, MemPtr<VecI4> quads, Bool smooth)
  771. {
  772. Int n=0, buf_no=1, R[]={1, (dims.x+1), (dims.x+1)*(dims.y+1)}, quad_start=quads.elms();
  773. Flt grid[8];
  774. VecI pos;
  775. Memt<Int> vtx_index_mem; Int *vtx_index=vtx_index_mem.setNum(R[2]*2).data();
  776. // March over the voxel grid
  777. for(pos.z=0; pos.z<dims.z-1; pos.z++, n+=dims.x, buf_no^=1, R[2]=-R[2])
  778. {
  779. // 'm' is the pointer into the 'vtx_index' we are going to use.
  780. // The contents of the buffer will be the indices of the vertices on the previous x/y slice of the volume
  781. Int m=1 + (dims.x+1)*(1 + buf_no*(dims.y+1));
  782. for(pos.y=0; pos.y<dims.y-1; pos.y++, n++, m+=2)
  783. for(pos.x=0; pos.x<dims.x-1; pos.x++, n++, m++)
  784. {
  785. // Read in 8 field values around this vertex and store them in an array
  786. // Also calculate 8-bit mask, like in marching cubes, so we can speed up sign checks later
  787. Int mask=0, g=0, id=n;
  788. for(Int k=0; k<2; k++, id+=dims.x*(dims.y-2))
  789. for(Int j=0; j<2; j++, id+=dims.x-2)
  790. for(Int i=0; i<2; i++, g++, id++)
  791. {
  792. Flt v=data[id];
  793. grid[g]=v;
  794. if(v<0)mask|=1<<g;
  795. }
  796. if(mask==0 || mask==0xFF)continue; // Check for early termination if cell does not intersect boundary
  797. // Sum up edge intersections
  798. Int edge_mask=EdgeTable[mask], e_count=0;
  799. Vec v=0;
  800. FREP(12) // For every edge of the cube...
  801. if(edge_mask&(1<<i)) // Use edge mask to check if it is crossed
  802. {
  803. e_count++; // If it did, increment number of edge crossings
  804. // Now find the point of intersection
  805. VecB2 edge=CubeEdges[i]; // get cube edge vertexes
  806. Flt g0 =grid[edge.x], // get grid values
  807. g1 =grid[edge.y],
  808. d =g0-g1; // Compute point of intersection
  809. if(d)d=g0/d;else continue;
  810. // Interpolate vertices and add up intersections (this can be done without multiplying)
  811. for(Int j=0, k=1; j<3; j++, k<<=1) // iterate all 3 dimensions
  812. {
  813. Int a=edge.x&k, // side of 'edge.x' point in 'j' dimension (left/right, down/up, back/front)
  814. b=edge.y&k; // side of 'edge.y' point in 'j' dimension (left/right, down/up, back/front)
  815. if(a!=b)v.c[j]+=(a ? 1-d : d);else // if sides are different, then we need to interpolate
  816. if(a )v.c[j]++; // if sides are the same, then just check which side is it
  817. }
  818. }
  819. // Add vertex
  820. vtx_index[m]=vtxs.elms(); // store vertex index
  821. vtxs.New()=pos+v/e_count; // Now we just average the edge intersections and add them to coordinate
  822. // Now we need to add faces together, to do this we just loop over 3 basis components
  823. FREP(3)
  824. {
  825. if(!(edge_mask&(1<<i)))continue; // The first three entries of the edge_mask count the crossings along the edge
  826. // i=axes we are point along. iu, iv = orthogonal axes
  827. Int iu=(i+1)%3,
  828. iv=(i+2)%3;
  829. // If we are on a boundary, skip it
  830. if(!pos.c[iu] || !pos.c[iv])continue;
  831. // Otherwise, look up adjacent edges in buffer
  832. Int du=R[iu],
  833. dv=R[iv];
  834. // Remember to flip orientation depending on the sign of the corner.
  835. if(mask&1)quads.New().set(vtx_index[m], vtx_index[m-du], vtx_index[m-du-dv], vtx_index[m-dv]);
  836. else quads.New().set(vtx_index[m], vtx_index[m-dv], vtx_index[m-du-dv], vtx_index[m-du]);
  837. }
  838. }
  839. }
  840. if(smooth)for(Int i=quads.elms(); --i>=quad_start; )
  841. {
  842. VecI4 &q=quads[i];
  843. C Vec &a=vtxs[q.x],
  844. &b=vtxs[q.y],
  845. &c=vtxs[q.z],
  846. &d=vtxs[q.w];
  847. // prefer option where 2 tris have smaller angle between each other (Cos of that angle is bigger)
  848. if(CosBetween(GetNormalU(a, b, d), GetNormalU(d, b, c))
  849. <CosBetween(GetNormalU(a, b, c), GetNormalU(a, c, d)))q.rotateOrder();
  850. }
  851. }
  852. /******************************************************************************/
  853. }
  854. /******************************************************************************/