You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

voxelmodel.cpp 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. #include <iostream>
  2. #include <glm/glm.hpp>
  3. #include <algorithm>
  4. #include "graphics/voxelmodel.h"
  5. namespace vtk {
  6. VoxelModel::VoxelModel() {
  7. //placeholder, just build a cube
  8. std::vector<unsigned> top = {
  9. 0, 15, 0, 15, 0,
  10. 15, 15, 15, 15, 0,
  11. 0, 0, 0, 15, 15,
  12. 15, 0, 15, 15, 15,
  13. 0, 0, 0, 15, 15,
  14. 15, 15, 15, 15, 0
  15. };
  16. packDataIntoFace(top, 0);
  17. std::vector<unsigned> bottom = {
  18. 0, 15, 0, 0, 15,
  19. 15, 15, 15, 0, 15,
  20. 0, 0, 0, 0, 0,
  21. 15, 0, 15, 0, 0,
  22. 0, 0, 0, 0, 0,
  23. 15, 15, 15, 0, 15
  24. };
  25. packDataIntoFace(bottom, 1);
  26. std::vector<unsigned> north = {
  27. 0, 15, 0, 15, 15,
  28. 15, 15, 15, 15, 15,
  29. 0, 0, 0, 0, 15,
  30. 15, 0, 15, 0, 15,
  31. 0, 0, 0, 0, 15,
  32. 15, 15, 15, 15, 15
  33. };
  34. packDataIntoFace(north, 2);
  35. std::vector<unsigned> south = {
  36. 0, 15, 15, 15, 0,
  37. 15, 15, 0, 15, 0,
  38. 0, 0, 15, 0, 0,
  39. 15, 0, 0, 0, 0,
  40. 0, 0, 15, 0, 0,
  41. 15, 15, 0, 15, 0
  42. };
  43. packDataIntoFace(south, 3);
  44. std::vector<unsigned> east = {
  45. 0, 15, 15, 15, 15,
  46. 15, 15, 15, 15, 0,
  47. 0, 0, 15, 0, 15,
  48. 15, 0, 15, 0, 0,
  49. 0, 0, 15, 0, 15,
  50. 15, 15, 15, 15, 0
  51. };
  52. packDataIntoFace(east, 4);
  53. std::vector<unsigned> west = {
  54. 0, 15, 0, 15, 0,
  55. 15, 15, 0, 15, 15,
  56. 0, 0, 0, 0, 0,
  57. 15, 0, 0, 0, 15,
  58. 0, 0, 0, 0, 0,
  59. 15, 15, 0, 15, 15
  60. };
  61. packDataIntoFace(west, 5);
  62. }
  63. VoxelModel::~VoxelModel() {
  64. }
  65. bool VoxelModel::packDataIntoFace(const std::vector<unsigned>& data, const int& face) {
  66. for (int i = 0; i < data.size(); i += 5) {
  67. unsigned vertex = 0;
  68. vertex = (vertex ) | data[i ];
  69. vertex = (vertex << 4) | data[i + 1];
  70. vertex = (vertex << 4) | data[i + 2];
  71. vertex = (vertex << 4) | data[i + 3];
  72. vertex = (vertex << 4) | data[i + 4];
  73. //std::cout << vertex << " | ";
  74. mGeometry[face].push_back(vertex);
  75. }
  76. return true;
  77. }
  78. bool VoxelModel::uploadFaceToMesh(std::vector<unsigned>& mesh, const int& face) {
  79. auto& faceModel = mGeometry[face];
  80. if (faceModel.empty()) return false;
  81. for (auto& i : faceModel) {
  82. mesh.push_back(i);
  83. }
  84. return true;
  85. }
  86. std::vector<unsigned>& VoxelModel::getFaceMesh(const int& face) {
  87. return mGeometry[face];
  88. }
  89. void VoxelModel::getFaceLighting(std::vector<unsigned short>& lighting, const FaceDirection& face, const std::array<unsigned short, 27>& surrounding_light, const unsigned& zero_weight) {
  90. /*
  91. auto blend = [](unsigned a, unsigned b, unsigned weight) {
  92. unsigned aw = 7 - weight;
  93. unsigned bw = weight;
  94. unsigned newLight = 0;
  95. newLight = std::min(((((a >> 24) & 0xFF) * aw) / 8u) +
  96. ((((b >> 24) & 0xFF) * bw) / 8u), 255u); //feels like lisp
  97. newLight = (newLight << 8) |
  98. std::min(((((a >> 16) & 0xFF) * aw) / 7u) +
  99. ((((b >> 16) & 0xFF) * bw) / 7u), 255u);
  100. newLight = (newLight << 8) |
  101. std::min(((((a >> 8) & 0xFF) * aw) / 7u) +
  102. ((((b >> 8) & 0xFF) * bw) / 7u), 255u);
  103. newLight = (newLight << 8) |
  104. std::min(((((a) & 0xFF) * aw) / 7u) +
  105. ((((b) & 0xFF) * bw) / 7u), 255u);
  106. return newLight;
  107. };
  108. */
  109. auto average4 = [](unsigned short a, unsigned short b, unsigned short c, unsigned short d) {
  110. unsigned short avg = (((a >> 12) & 0xF) +
  111. ((b >> 12) & 0xF) +
  112. ((c >> 12) & 0xF) +
  113. ((d >> 12) & 0xF)) / 4;
  114. avg = (avg << 8) | (((a >> 8) & 0xF) +
  115. ((b >> 8) & 0xF) +
  116. ((c >> 8) & 0xF) +
  117. ((d >> 8) & 0xF)) / 4;
  118. avg = (avg << 8) | (((a >> 4) & 0xF) +
  119. ((b >> 4) & 0xF) +
  120. ((c >> 4) & 0xF) +
  121. ((d >> 4) & 0xF)) / 4;
  122. avg = (avg << 8) | ((a & 0xF) +
  123. (b & 0xF) +
  124. (c & 0xF) +
  125. (d & 0xF)) / 4;
  126. return avg;
  127. };
  128. auto& face_vec = mGeometry.at(static_cast<unsigned>(face));
  129. for (auto& i : face_vec) {
  130. //TODO: Find a more elegant solution that a big switch case with if statements
  131. //TODO: handle interpolation for verts that aren't on an edge
  132. /*
  133. A brief explanation of the following code
  134. it looks at the position of each vertice in the face mesh, checks which corner it is
  135. closeest too, and then ges the average of the 4 adjacent light values with the
  136. average4 lambda
  137. */
  138. unsigned vx = (i >> 8) & 0xF;
  139. unsigned vy = (i >> 4) & 0xF;
  140. unsigned vz = i & 0xF;
  141. switch(face) {
  142. case FaceDirection::TOP:
  143. if (vx > 7) {
  144. if (vz > 7) {
  145. lighting.push_back(average4(surrounding_light[22],
  146. surrounding_light[23],
  147. surrounding_light[25],
  148. surrounding_light[26]));
  149. } else {
  150. lighting.push_back(average4(surrounding_light[22],
  151. surrounding_light[23],
  152. surrounding_light[19],
  153. surrounding_light[20]));
  154. }
  155. } else {
  156. if (vz > 7) {
  157. lighting.push_back(average4(surrounding_light[22],
  158. surrounding_light[21],
  159. surrounding_light[24],
  160. surrounding_light[25]));
  161. } else {
  162. lighting.push_back(average4(surrounding_light[22],
  163. surrounding_light[18],
  164. surrounding_light[19],
  165. surrounding_light[21]));
  166. }
  167. }
  168. break;
  169. case FaceDirection::BOTTOM:
  170. if (vx > 7) {
  171. if (vz > 7) {
  172. lighting.push_back(average4(surrounding_light[4],
  173. surrounding_light[5],
  174. surrounding_light[7],
  175. surrounding_light[8]));
  176. } else {
  177. lighting.push_back(average4(surrounding_light[4],
  178. surrounding_light[5],
  179. surrounding_light[1],
  180. surrounding_light[2]));
  181. }
  182. } else {
  183. if (vz > 7) {
  184. lighting.push_back(average4(surrounding_light[4],
  185. surrounding_light[3],
  186. surrounding_light[6],
  187. surrounding_light[7]));
  188. } else {
  189. lighting.push_back(average4(surrounding_light[4],
  190. surrounding_light[3],
  191. surrounding_light[0],
  192. surrounding_light[1]));
  193. }
  194. }
  195. break;
  196. case FaceDirection::NORTH:
  197. if (vx > 7) {
  198. if (vy > 7) {
  199. lighting.push_back(average4(surrounding_light[16],
  200. surrounding_light[17],
  201. surrounding_light[25],
  202. surrounding_light[26]));
  203. } else {
  204. lighting.push_back(average4(surrounding_light[16],
  205. surrounding_light[17],
  206. surrounding_light[7],
  207. surrounding_light[8]));
  208. }
  209. } else {
  210. if (vy > 7) {
  211. lighting.push_back(average4(surrounding_light[16],
  212. surrounding_light[15],
  213. surrounding_light[24],
  214. surrounding_light[25]));
  215. } else {
  216. lighting.push_back(average4(surrounding_light[16],
  217. surrounding_light[15],
  218. surrounding_light[6],
  219. surrounding_light[7]));
  220. }
  221. }
  222. break;
  223. case FaceDirection::SOUTH:
  224. if (vx > 7) {
  225. if (vy > 7) {
  226. lighting.push_back(average4(surrounding_light[10],
  227. surrounding_light[11],
  228. surrounding_light[19],
  229. surrounding_light[20]));
  230. } else {
  231. lighting.push_back(average4(surrounding_light[10],
  232. surrounding_light[11],
  233. surrounding_light[1],
  234. surrounding_light[2]));
  235. }
  236. } else {
  237. if (vy > 7) {
  238. lighting.push_back(average4(surrounding_light[10],
  239. surrounding_light[9],
  240. surrounding_light[18],
  241. surrounding_light[19]));
  242. } else {
  243. lighting.push_back(average4(surrounding_light[10],
  244. surrounding_light[9],
  245. surrounding_light[0],
  246. surrounding_light[1]));
  247. }
  248. }
  249. break;
  250. case FaceDirection::EAST:
  251. if (vz > 7) {
  252. if (vy > 7) {
  253. lighting.push_back(average4(surrounding_light[14],
  254. surrounding_light[17],
  255. surrounding_light[23],
  256. surrounding_light[26]));
  257. } else {
  258. lighting.push_back(average4(surrounding_light[14],
  259. surrounding_light[17],
  260. surrounding_light[5],
  261. surrounding_light[8]));
  262. }
  263. } else {
  264. if (vy > 7) {
  265. lighting.push_back(average4(surrounding_light[14],
  266. surrounding_light[11],
  267. surrounding_light[20],
  268. surrounding_light[23]));
  269. } else {
  270. lighting.push_back(average4(surrounding_light[14],
  271. surrounding_light[11],
  272. surrounding_light[2],
  273. surrounding_light[5]));
  274. }
  275. }
  276. break;
  277. case FaceDirection::WEST:
  278. if (vz > 7) {
  279. if (vy > 7) {
  280. lighting.push_back(average4(surrounding_light[12],
  281. surrounding_light[15],
  282. surrounding_light[21],
  283. surrounding_light[24]));
  284. } else {
  285. lighting.push_back(average4(surrounding_light[12],
  286. surrounding_light[15],
  287. surrounding_light[3],
  288. surrounding_light[6]));
  289. }
  290. } else {
  291. if (vy > 7) {
  292. lighting.push_back(average4(surrounding_light[12],
  293. surrounding_light[9],
  294. surrounding_light[18],
  295. surrounding_light[21]));
  296. } else {
  297. lighting.push_back(average4(surrounding_light[12],
  298. surrounding_light[9],
  299. surrounding_light[0],
  300. surrounding_light[3]));
  301. }
  302. }
  303. break;
  304. }
  305. }
  306. }
  307. }