ChunkGroundModel.cpp 11 KB

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