ChunkGroundModel.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  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 (isPartOfModel(blocks()[i]))
  129. {
  130. setBlockPartOfModel(blocks()[i], 1);
  131. int index = 0;
  132. for (Text* textureName :
  133. *blocks()[i]->zBlockType()->getModelInfo().getTexturNames())
  134. {
  135. Framework::Vec3<int> location(
  136. (i / WORLD_HEIGHT) / CHUNK_SIZE,
  137. (i / WORLD_HEIGHT) % CHUNK_SIZE,
  138. i % WORLD_HEIGHT);
  139. if (isPartOfGroundModel(location, index))
  140. {
  141. if (!groundModelBuidler.get(
  142. *textureName, textureName->getLength()))
  143. {
  144. GroundModelPart* part = new GroundModelPart();
  145. part->indexList = new int[10000];
  146. part->indexCount = 0;
  147. part->indexArraySize = 10000;
  148. part->name = *textureName;
  149. groundModelBuidler.set(
  150. *textureName, textureName->getLength(), part);
  151. groundPartArray.add(part);
  152. }
  153. GroundModelPart* part = groundModelBuidler.get(
  154. *textureName, textureName->getLength());
  155. const Vertex3D* vBuffer
  156. = blocks()[i]->zModelData()->zVertexBuffer();
  157. Polygon3D* polygon
  158. = blocks()[i]->zModelData()->getPolygon(index);
  159. if (part->indexCount + polygon->indexAnz
  160. > part->indexArraySize)
  161. {
  162. int* tmp = new int[part->indexArraySize + 10000];
  163. memcpy(tmp, part->indexList, part->indexCount * 4);
  164. delete[] part->indexList;
  165. part->indexList = tmp;
  166. part->indexArraySize += 10000;
  167. }
  168. if (groundVertexCount + polygon->indexAnz
  169. > groundVertexArraySize)
  170. {
  171. Vertex3D* tmp
  172. = new Vertex3D[groundVertexArraySize + 10000];
  173. memcpy(tmp,
  174. groundVerticies,
  175. groundVertexCount * sizeof(Vertex3D));
  176. delete[] groundVerticies;
  177. groundVerticies = tmp;
  178. groundVertexArraySize += 10000;
  179. __int64* lTmp = new __int64[groundVertexArraySize];
  180. memcpy(lTmp,
  181. lightBuffer,
  182. groundVertexCount * sizeof(__int64));
  183. delete[] lightBuffer;
  184. lightBuffer = lTmp;
  185. }
  186. for (int vi = 0; vi < polygon->indexAnz; vi++)
  187. {
  188. lightBuffer[groundVertexCount] = calculateLight(
  189. vBuffer[polygon->indexList[vi]].pos,
  190. location,
  191. getDirectionFromIndex(index));
  192. part->indexList[part->indexCount++]
  193. = groundVertexCount;
  194. groundVerticies[groundVertexCount++]
  195. = vBuffer[polygon->indexList[vi]];
  196. groundVerticies[groundVertexCount - 1].pos
  197. += blocks()[i]->getPos()
  198. - Vec3<float>((float)chunkCenter().x,
  199. (float)chunkCenter().y,
  200. (float)WORLD_HEIGHT / 2.f);
  201. groundVerticies[groundVertexCount - 1].id
  202. = groundVertexCount - 1;
  203. }
  204. }
  205. index++;
  206. }
  207. }
  208. else
  209. {
  210. setBlockPartOfModel(blocks()[i], 0);
  211. }
  212. }
  213. }
  214. Model3DTextur* textur = new Model3DTextur();
  215. int pi = 0;
  216. for (GroundModelPart* part : groundPartArray)
  217. {
  218. Polygon3D* polygon = new Polygon3D();
  219. polygon->indexAnz = part->indexCount;
  220. polygon->indexList = part->indexList;
  221. target->zModelData()->addPolygon(polygon);
  222. textur->setPolygonTextur(pi,
  223. uiFactory.initParam.bildschirm->zGraphicsApi()->createOrGetTextur(
  224. part->name));
  225. pi++;
  226. delete part;
  227. }
  228. target->zModelData()->setVertecies(groundVerticies, groundVertexCount);
  229. target->setModelTextur(textur);
  230. target->setVertexLightBuffer(lightBuffer, groundVertexCount);
  231. }
  232. bool ChunkGroundModel::updateLightning()
  233. {
  234. __int64* lightBuffer = target->zLightBuffer();
  235. int groundVertexCount = 0;
  236. for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++)
  237. {
  238. if (blocks()[i])
  239. {
  240. if (isPartOfModel(blocks()[i]))
  241. {
  242. int index = 0;
  243. for (Text* textureName :
  244. *blocks()[i]->zBlockType()->getModelInfo().getTexturNames())
  245. {
  246. Framework::Vec3<int> location(
  247. (i / WORLD_HEIGHT) / CHUNK_SIZE,
  248. (i / WORLD_HEIGHT) % CHUNK_SIZE,
  249. i % WORLD_HEIGHT);
  250. if (isPartOfGroundModel(location, index))
  251. {
  252. const Vertex3D* vBuffer
  253. = blocks()[i]->zModelData()->zVertexBuffer();
  254. Polygon3D* polygon
  255. = blocks()[i]->zModelData()->getPolygon(index);
  256. for (int vi = 0; vi < polygon->indexAnz; vi++)
  257. {
  258. lightBuffer[groundVertexCount++] = calculateLight(
  259. vBuffer[polygon->indexList[vi]].pos,
  260. location,
  261. getDirectionFromIndex(index));
  262. }
  263. }
  264. index++;
  265. }
  266. }
  267. }
  268. }
  269. target->copyLightToGPU();
  270. return 1;
  271. }
  272. bool ChunkGroundModel::isTransparent() const
  273. {
  274. return false;
  275. }
  276. bool ChunkGroundModel::isPartOfModel(Block* zBlock) const
  277. {
  278. return zBlock->zBlockType()->getModelInfo().getModelName().istGleich(
  279. "cube");
  280. }