ChunkGroundModel.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. #include "ChunkGroundModel.h"
  2. #include <Trie.h>
  3. #include "Area.h"
  4. #include "Block.h"
  5. #include "Constants.h"
  6. #include "FactoryCraftModel.h"
  7. #include "Globals.h"
  8. using namespace Framework;
  9. ChunkGroundModel::ChunkGroundModel(FactoryCraftModel* target, Chunk* zChunk)
  10. : ChunkModelBuilder(target, zChunk, Chunk::CombinedModels::GROUND)
  11. {}
  12. __int64 ChunkGroundModel::calculateLight(Framework::Vec3<float> vertexPos,
  13. Framework::Vec3<int> blockPos,
  14. Direction direction)
  15. {
  16. __int64 result = 0;
  17. int sumCount = 1;
  18. short lightSum[6];
  19. Block* current = blocks()[Chunk::index(blockPos)];
  20. const unsigned char* light = current->getLightData(direction);
  21. for (int i = 0; i < 6; i++)
  22. {
  23. lightSum[i] = (short)light[i];
  24. }
  25. Vec3<int> vertexDirs(vertexPos.x < 0 ? -1 : 1,
  26. vertexPos.y < 0 ? -1 : 1,
  27. vertexPos.z < 0 ? -1 : 1);
  28. Directions dirs = getDirectionsFromVector(vertexDirs) & ~direction;
  29. Vec3<int> neighborDirs[3];
  30. int neighborIndex = 0;
  31. for (int i = 0; i < 6; i++)
  32. {
  33. Direction dir = getDirectionFromIndex(i);
  34. if ((dirs | dir) == dirs)
  35. {
  36. neighborDirs[neighborIndex++] = getDirection(dir);
  37. if (neighborIndex == 2) break;
  38. }
  39. }
  40. neighborDirs[2] = neighborDirs[0] + neighborDirs[1];
  41. for (int i = 0; i < 3; i++)
  42. {
  43. neighborDirs[i] += blockPos;
  44. if (neighborDirs[i].x >= 0 && neighborDirs[i].y >= 0
  45. && neighborDirs[i].z >= 0 && neighborDirs[i].x < CHUNK_SIZE
  46. && neighborDirs[i].y < CHUNK_SIZE
  47. && neighborDirs[i].z < WORLD_HEIGHT)
  48. {
  49. int neighborIndex = Chunk::index(neighborDirs[i]);
  50. Block* neighbor = blocks()[neighborIndex];
  51. if (neighbor)
  52. {
  53. const unsigned char* neighborLight
  54. = neighbor->getLightData(direction);
  55. if ((neighborLight[0] | neighborLight[1] | neighborLight[2]
  56. | neighborLight[3] | neighborLight[4]
  57. | neighborLight[5])
  58. != 0)
  59. {
  60. sumCount++;
  61. for (int j = 0; j < 6; j++)
  62. {
  63. lightSum[j] += (short)neighborLight[j];
  64. }
  65. }
  66. }
  67. }
  68. else
  69. { // TODO: get light from neighbor chunk
  70. }
  71. }
  72. for (int i = 0; i < 6; i++)
  73. {
  74. lightSum[i] = (lightSum[i] / sumCount) & 0xFF;
  75. }
  76. result = ((__int64)lightSum[0] << 24) | ((__int64)lightSum[1] << 16)
  77. | ((__int64)lightSum[2] << 8) | ((__int64)lightSum[3] << 56)
  78. | ((__int64)lightSum[4] << 48) | ((__int64)lightSum[5] << 40);
  79. return result;
  80. }
  81. bool ChunkGroundModel::isPartOfGroundModel(
  82. Framework::Vec3<int> location, int directionIndex)
  83. {
  84. Framework::Vec3<int> neighborLocation
  85. = location + getDirection(getDirectionFromIndex(directionIndex));
  86. bool needed = 0;
  87. if (neighborLocation.x < 0 || neighborLocation.y < 0
  88. || neighborLocation.z < 0 || neighborLocation.x >= CHUNK_SIZE
  89. || neighborLocation.y >= CHUNK_SIZE
  90. || neighborLocation.z >= WORLD_HEIGHT)
  91. {
  92. needed = 1;
  93. }
  94. else
  95. {
  96. int naighborIndex = Chunk::index(neighborLocation);
  97. if (!blocks()[naighborIndex]
  98. || !blocks()[naighborIndex]
  99. ->zBlockType()
  100. ->getModelInfo()
  101. .getModelName()
  102. .istGleich("cube"))
  103. {
  104. needed = 1;
  105. }
  106. }
  107. return needed;
  108. }
  109. void ChunkGroundModel::buildModel()
  110. {
  111. Model3DData* chunkModel = target->zModelData();
  112. // remove old model
  113. while (chunkModel->getPolygonAnzahl() > 0)
  114. {
  115. chunkModel->removePolygon(0);
  116. }
  117. // calculate verticies
  118. Trie<GroundModelPart*> groundModelBuidler;
  119. Array<GroundModelPart*> groundPartArray;
  120. Vertex3D* groundVerticies = new Vertex3D[10000];
  121. __int64* lightBuffer = new __int64[10000];
  122. int groundVertexCount = 0;
  123. int groundVertexArraySize = 10000;
  124. for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++)
  125. {
  126. if (blocks()[i])
  127. {
  128. if (blocks()[i]
  129. ->zBlockType()
  130. ->getModelInfo()
  131. .getModelName()
  132. .istGleich("cube"))
  133. {
  134. setBlockPartOfModel(blocks()[i], 1);
  135. int index = 0;
  136. for (Text* textureName :
  137. *blocks()[i]->zBlockType()->getModelInfo().getTexturNames())
  138. {
  139. Framework::Vec3<int> location(
  140. (i / WORLD_HEIGHT) / CHUNK_SIZE,
  141. (i / WORLD_HEIGHT) % CHUNK_SIZE,
  142. i % WORLD_HEIGHT);
  143. if (isPartOfGroundModel(location, index))
  144. {
  145. if (!groundModelBuidler.get(
  146. *textureName, textureName->getLength()))
  147. {
  148. GroundModelPart* part = new GroundModelPart();
  149. part->indexList = new int[10000];
  150. part->indexCount = 0;
  151. part->indexArraySize = 10000;
  152. part->name = *textureName;
  153. groundModelBuidler.set(
  154. *textureName, textureName->getLength(), part);
  155. groundPartArray.add(part);
  156. }
  157. GroundModelPart* part = groundModelBuidler.get(
  158. *textureName, textureName->getLength());
  159. const Vertex3D* vBuffer
  160. = blocks()[i]->zModelData()->zVertexBuffer();
  161. Polygon3D* polygon
  162. = blocks()[i]->zModelData()->getPolygon(index);
  163. if (part->indexCount + polygon->indexAnz
  164. > part->indexArraySize)
  165. {
  166. int* tmp = new int[part->indexArraySize + 10000];
  167. memcpy(tmp, part->indexList, part->indexCount * 4);
  168. delete[] part->indexList;
  169. part->indexList = tmp;
  170. part->indexArraySize += 10000;
  171. }
  172. if (groundVertexCount + polygon->indexAnz
  173. > groundVertexArraySize)
  174. {
  175. Vertex3D* tmp
  176. = new Vertex3D[groundVertexArraySize + 10000];
  177. memcpy(tmp,
  178. groundVerticies,
  179. groundVertexCount * sizeof(Vertex3D));
  180. delete[] groundVerticies;
  181. groundVerticies = tmp;
  182. groundVertexArraySize += 10000;
  183. __int64* lTmp = new __int64[groundVertexArraySize];
  184. memcpy(lTmp,
  185. lightBuffer,
  186. groundVertexCount * sizeof(__int64));
  187. delete[] lightBuffer;
  188. lightBuffer = lTmp;
  189. }
  190. for (int vi = 0; vi < polygon->indexAnz; vi++)
  191. {
  192. lightBuffer[groundVertexCount] = calculateLight(
  193. vBuffer[polygon->indexList[vi]].pos,
  194. location,
  195. getDirectionFromIndex(index));
  196. part->indexList[part->indexCount++]
  197. = groundVertexCount;
  198. groundVerticies[groundVertexCount++]
  199. = vBuffer[polygon->indexList[vi]];
  200. groundVerticies[groundVertexCount - 1].pos
  201. += blocks()[i]->getPos()
  202. - Vec3<float>((float)chunkCenter().x,
  203. (float)chunkCenter().y,
  204. (float)WORLD_HEIGHT / 2.f);
  205. groundVerticies[groundVertexCount - 1].id
  206. = groundVertexCount - 1;
  207. }
  208. }
  209. index++;
  210. }
  211. }
  212. else if (blocks()[i]
  213. ->zBlockType()
  214. ->getModelInfo()
  215. .getModelName()
  216. .istGleich("grass"))
  217. {
  218. setBlockPartOfModel(blocks()[i], 1);
  219. __int64 light = blocks()[i]->getMaxLight();
  220. int index = 0;
  221. for (Text* textureName :
  222. *blocks()[i]->zBlockType()->getModelInfo().getTexturNames())
  223. {
  224. if (!groundModelBuidler.get(
  225. *textureName, textureName->getLength()))
  226. {
  227. GroundModelPart* part = new GroundModelPart();
  228. part->indexList = new int[10000];
  229. part->indexCount = 0;
  230. part->indexArraySize = 10000;
  231. part->name = *textureName;
  232. groundModelBuidler.set(
  233. *textureName, textureName->getLength(), part);
  234. groundPartArray.add(part);
  235. }
  236. GroundModelPart* part = groundModelBuidler.get(
  237. *textureName, textureName->getLength());
  238. const Vertex3D* vBuffer
  239. = blocks()[i]->zModelData()->zVertexBuffer();
  240. Polygon3D* polygon
  241. = blocks()[i]->zModelData()->getPolygon(index);
  242. if (part->indexCount + polygon->indexAnz
  243. > part->indexArraySize)
  244. {
  245. int* tmp = new int[part->indexArraySize + 10000];
  246. memcpy(tmp, part->indexList, part->indexCount * 4);
  247. delete[] part->indexList;
  248. part->indexList = tmp;
  249. part->indexArraySize += 10000;
  250. }
  251. if (groundVertexCount + polygon->indexAnz
  252. > groundVertexArraySize)
  253. {
  254. Vertex3D* tmp
  255. = new Vertex3D[groundVertexArraySize + 10000];
  256. memcpy(tmp,
  257. groundVerticies,
  258. groundVertexCount * sizeof(Vertex3D));
  259. delete[] groundVerticies;
  260. groundVerticies = tmp;
  261. groundVertexArraySize += 10000;
  262. __int64* lTmp = new __int64[groundVertexArraySize];
  263. memcpy(lTmp,
  264. lightBuffer,
  265. groundVertexCount * sizeof(__int64));
  266. delete[] lightBuffer;
  267. lightBuffer = lTmp;
  268. }
  269. for (int vi = 0; vi < polygon->indexAnz; vi++)
  270. {
  271. lightBuffer[groundVertexCount] = light;
  272. part->indexList[part->indexCount++] = groundVertexCount;
  273. groundVerticies[groundVertexCount++]
  274. = vBuffer[polygon->indexList[vi]];
  275. groundVerticies[groundVertexCount - 1].pos
  276. += blocks()[i]->getPos()
  277. - Vec3<float>((float)chunkCenter().x,
  278. (float)chunkCenter().y,
  279. (float)WORLD_HEIGHT / 2.f);
  280. groundVerticies[groundVertexCount - 1].id
  281. = groundVertexCount - 1;
  282. }
  283. index++;
  284. }
  285. }
  286. else
  287. {
  288. setBlockPartOfModel(blocks()[i], 0);
  289. }
  290. }
  291. }
  292. Model3DTextur* textur = new Model3DTextur();
  293. int pi = 0;
  294. for (GroundModelPart* part : groundPartArray)
  295. {
  296. Polygon3D* polygon = new Polygon3D();
  297. polygon->indexAnz = part->indexCount;
  298. polygon->indexList = part->indexList;
  299. target->zModelData()->addPolygon(polygon);
  300. textur->setPolygonTextur(pi,
  301. uiFactory.initParam.bildschirm->zGraphicsApi()->createOrGetTextur(
  302. part->name));
  303. pi++;
  304. delete part;
  305. }
  306. target->zModelData()->setVertecies(groundVerticies, groundVertexCount);
  307. target->setModelTextur(textur);
  308. target->setVertexLightBuffer(lightBuffer, groundVertexCount);
  309. }
  310. bool ChunkGroundModel::updateLightning() {
  311. __int64* lightBuffer = target->zLightBuffer();
  312. int groundVertexCount = 0;
  313. for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++)
  314. {
  315. if (blocks()[i])
  316. {
  317. if (blocks()[i]
  318. ->zBlockType()
  319. ->getModelInfo()
  320. .getModelName()
  321. .istGleich("cube"))
  322. {
  323. int index = 0;
  324. for (Text* textureName :
  325. *blocks()[i]->zBlockType()->getModelInfo().getTexturNames())
  326. {
  327. Framework::Vec3<int> location(
  328. (i / WORLD_HEIGHT) / CHUNK_SIZE,
  329. (i / WORLD_HEIGHT) % CHUNK_SIZE,
  330. i % WORLD_HEIGHT);
  331. if (isPartOfGroundModel(location, index))
  332. {
  333. const Vertex3D* vBuffer
  334. = blocks()[i]->zModelData()->zVertexBuffer();
  335. Polygon3D* polygon
  336. = blocks()[i]->zModelData()->getPolygon(index);
  337. for (int vi = 0; vi < polygon->indexAnz; vi++)
  338. {
  339. lightBuffer[groundVertexCount++] = calculateLight(
  340. vBuffer[polygon->indexList[vi]].pos,
  341. location,
  342. getDirectionFromIndex(index));
  343. }
  344. }
  345. index++;
  346. }
  347. }
  348. else if (blocks()[i]
  349. ->zBlockType()
  350. ->getModelInfo()
  351. .getModelName()
  352. .istGleich("grass"))
  353. {
  354. __int64 light = blocks()[i]->getMaxLight();
  355. int index = 0;
  356. for (Text* textureName :
  357. *blocks()[i]->zBlockType()->getModelInfo().getTexturNames())
  358. {
  359. const Vertex3D* vBuffer
  360. = blocks()[i]->zModelData()->zVertexBuffer();
  361. Polygon3D* polygon
  362. = blocks()[i]->zModelData()->getPolygon(index);
  363. for (int vi = 0; vi < polygon->indexAnz; vi++)
  364. {
  365. lightBuffer[groundVertexCount++] = light;
  366. }
  367. }
  368. }
  369. }
  370. }
  371. target->copyLightToGPU();
  372. return 1;
  373. }