ChunkFluidModel.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. #include "ChunkFluidModel.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. ChunkFluidModel::ChunkFluidModel(FactoryCraftModel* target, Chunk* zChunk)
  9. : ChunkModelBuilder(target, zChunk, Chunk::CombinedModels::FLUID)
  10. {}
  11. __int64 ChunkFluidModel::calculateLight(Framework::Vec3<float> vertexPos,
  12. Framework::Vec3<int> blockPos,
  13. Direction direction)
  14. {
  15. __int64 result = 0;
  16. int sumCount = 1;
  17. short lightSum[6];
  18. Block* current = blocks()[Chunk::index(blockPos)];
  19. const unsigned char* light = current->getLightData(direction);
  20. for (int i = 0; i < 6; i++)
  21. {
  22. lightSum[i] = (short)light[i];
  23. }
  24. Vec3<int> vertexDirs(vertexPos.x < 0 ? -1 : 1,
  25. vertexPos.y < 0 ? -1 : 1,
  26. vertexPos.z < 0 ? -1 : 1);
  27. Directions dirs = getDirectionsFromVector(vertexDirs) & ~direction;
  28. Vec3<int> neighborDirs[3];
  29. int neighborIndex = 0;
  30. for (int i = 0; i < 6; i++)
  31. {
  32. Direction dir = getDirectionFromIndex(i);
  33. if ((dirs | dir) == dirs)
  34. {
  35. neighborDirs[neighborIndex++] = getDirection(dir);
  36. if (neighborIndex == 2) break;
  37. }
  38. }
  39. neighborDirs[2] = neighborDirs[0] + neighborDirs[1];
  40. for (int i = 0; i < 3; i++)
  41. {
  42. neighborDirs[i] += blockPos;
  43. if (neighborDirs[i].x >= 0 && neighborDirs[i].y >= 0
  44. && neighborDirs[i].z >= 0 && neighborDirs[i].x < CHUNK_SIZE
  45. && neighborDirs[i].y < CHUNK_SIZE
  46. && neighborDirs[i].z < WORLD_HEIGHT)
  47. {
  48. int neighborIndex = Chunk::index(neighborDirs[i]);
  49. Block* neighbor = blocks()[neighborIndex];
  50. if (neighbor)
  51. {
  52. const unsigned char* neighborLight
  53. = neighbor->getLightData(direction);
  54. if ((neighborLight[0] | neighborLight[1] | neighborLight[2]
  55. | neighborLight[3] | neighborLight[4]
  56. | neighborLight[5])
  57. != 0)
  58. {
  59. sumCount++;
  60. for (int j = 0; j < 6; j++)
  61. {
  62. lightSum[j] += (short)neighborLight[j];
  63. }
  64. }
  65. }
  66. }
  67. else
  68. { // TODO: get light from neighbor chunk
  69. }
  70. }
  71. for (int i = 0; i < 6; i++)
  72. {
  73. lightSum[i] = (lightSum[i] / sumCount) & 0xFF;
  74. }
  75. result = ((__int64)lightSum[0] << 24) | ((__int64)lightSum[1] << 16)
  76. | ((__int64)lightSum[2] << 8) | ((__int64)lightSum[3] << 56)
  77. | ((__int64)lightSum[4] << 48) | ((__int64)lightSum[5] << 40);
  78. return result;
  79. }
  80. bool ChunkFluidModel::isPartOfGroundModel(
  81. Framework::Vec3<int> location, int directionIndex)
  82. {
  83. Framework::Vec3<int> neighborLocation
  84. = location + getDirection(getDirectionFromIndex(directionIndex));
  85. bool needed = 0;
  86. if (neighborLocation.x < 0 || neighborLocation.y < 0
  87. || neighborLocation.z < 0 || neighborLocation.x >= CHUNK_SIZE
  88. || neighborLocation.y >= CHUNK_SIZE
  89. || neighborLocation.z >= WORLD_HEIGHT)
  90. {
  91. needed = 1;
  92. }
  93. else
  94. {
  95. int naighborIndex = Chunk::index(neighborLocation);
  96. if (!blocks()[naighborIndex]
  97. || !blocks()[naighborIndex]
  98. ->zBlockType()
  99. ->isFluid())
  100. {
  101. needed = 1;
  102. }
  103. }
  104. return needed;
  105. }
  106. void ChunkFluidModel::buildModel()
  107. {
  108. Model3DData* chunkModel = target->zModelData();
  109. // remove old model
  110. while (chunkModel->getPolygonAnzahl() > 0)
  111. {
  112. chunkModel->removePolygon(0);
  113. }
  114. // calculate verticies
  115. Trie<GroundModelPart*> groundModelBuidler;
  116. Array<GroundModelPart*> groundPartArray;
  117. Vertex3D* groundVerticies = new Vertex3D[10000];
  118. __int64* lightBuffer = new __int64[10000];
  119. int groundVertexCount = 0;
  120. int groundVertexArraySize = 10000;
  121. for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++)
  122. {
  123. if (blocks()[i])
  124. {
  125. if (blocks()[i]
  126. ->zBlockType()->isFluid())
  127. {
  128. setBlockPartOfModel(blocks()[i], 1);
  129. int index = 0;
  130. for (Text* textureName :
  131. *blocks()[i]->zBlockType()->getModelInfo().getTexturNames())
  132. {
  133. Framework::Vec3<int> location(
  134. (i / WORLD_HEIGHT) / CHUNK_SIZE,
  135. (i / WORLD_HEIGHT) % CHUNK_SIZE,
  136. i % WORLD_HEIGHT);
  137. if (isPartOfGroundModel(location, index))
  138. {
  139. if (!groundModelBuidler.get(
  140. *textureName, textureName->getLength()))
  141. {
  142. GroundModelPart* part = new GroundModelPart();
  143. part->indexList = new int[10000];
  144. part->indexCount = 0;
  145. part->indexArraySize = 10000;
  146. part->name = *textureName;
  147. groundModelBuidler.set(
  148. *textureName, textureName->getLength(), part);
  149. groundPartArray.add(part);
  150. }
  151. GroundModelPart* part = groundModelBuidler.get(
  152. *textureName, textureName->getLength());
  153. const Vertex3D* vBuffer
  154. = blocks()[i]->zModelData()->zVertexBuffer();
  155. Polygon3D* polygon
  156. = blocks()[i]->zModelData()->getPolygon(index);
  157. if (part->indexCount + polygon->indexAnz
  158. > part->indexArraySize)
  159. {
  160. int* tmp = new int[part->indexArraySize + 10000];
  161. memcpy(tmp, part->indexList, part->indexCount * 4);
  162. delete[] part->indexList;
  163. part->indexList = tmp;
  164. part->indexArraySize += 10000;
  165. }
  166. if (groundVertexCount + polygon->indexAnz
  167. > groundVertexArraySize)
  168. {
  169. Vertex3D* tmp
  170. = new Vertex3D[groundVertexArraySize + 10000];
  171. memcpy(tmp,
  172. groundVerticies,
  173. groundVertexCount * sizeof(Vertex3D));
  174. delete[] groundVerticies;
  175. groundVerticies = tmp;
  176. groundVertexArraySize += 10000;
  177. __int64* lTmp = new __int64[groundVertexArraySize];
  178. memcpy(lTmp,
  179. lightBuffer,
  180. groundVertexCount * sizeof(__int64));
  181. delete[] lightBuffer;
  182. lightBuffer = lTmp;
  183. }
  184. for (int vi = 0; vi < polygon->indexAnz; vi++)
  185. {
  186. lightBuffer[groundVertexCount] = calculateLight(
  187. vBuffer[polygon->indexList[vi]].pos,
  188. location,
  189. getDirectionFromIndex(index));
  190. part->indexList[part->indexCount++]
  191. = groundVertexCount;
  192. groundVerticies[groundVertexCount++]
  193. = vBuffer[polygon->indexList[vi]];
  194. if (getDirectionFromIndex(index) == TOP)
  195. {
  196. groundVerticies[groundVertexCount - 1].pos.z
  197. -= (1 - blocks()[i]->getFill() / 1000.f);
  198. }
  199. groundVerticies[groundVertexCount - 1].pos
  200. += blocks()[i]->getPos()
  201. - Vec3<float>((float)chunkCenter().x,
  202. (float)chunkCenter().y,
  203. (float)WORLD_HEIGHT / 2.f);
  204. groundVerticies[groundVertexCount - 1].id
  205. = groundVertexCount - 1;
  206. }
  207. }
  208. index++;
  209. }
  210. }
  211. else
  212. {
  213. setBlockPartOfModel(blocks()[i], 0);
  214. }
  215. }
  216. }
  217. Model3DTextur* textur = new Model3DTextur();
  218. int pi = 0;
  219. for (GroundModelPart* part : groundPartArray)
  220. {
  221. Polygon3D* polygon = new Polygon3D();
  222. polygon->indexAnz = part->indexCount;
  223. polygon->indexList = part->indexList;
  224. target->zModelData()->addPolygon(polygon);
  225. textur->setPolygonTextur(pi,
  226. uiFactory.initParam.bildschirm->zGraphicsApi()->createOrGetTextur(
  227. part->name));
  228. pi++;
  229. delete part;
  230. }
  231. target->zModelData()->setVertecies(groundVerticies, groundVertexCount);
  232. target->setModelTextur(textur);
  233. target->setVertexLightBuffer(lightBuffer, groundVertexCount);
  234. }
  235. bool ChunkFluidModel::updateLightning()
  236. {
  237. __int64* lightBuffer = target->zLightBuffer();
  238. int groundVertexCount = 0;
  239. for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++)
  240. {
  241. if (blocks()[i])
  242. {
  243. if (blocks()[i]
  244. ->zBlockType()->isFluid())
  245. {
  246. int index = 0;
  247. for (Text* textureName :
  248. *blocks()[i]->zBlockType()->getModelInfo().getTexturNames())
  249. {
  250. Framework::Vec3<int> location(
  251. (i / WORLD_HEIGHT) / CHUNK_SIZE,
  252. (i / WORLD_HEIGHT) % CHUNK_SIZE,
  253. i % WORLD_HEIGHT);
  254. if (isPartOfGroundModel(location, index))
  255. {
  256. const Vertex3D* vBuffer
  257. = blocks()[i]->zModelData()->zVertexBuffer();
  258. Polygon3D* polygon
  259. = blocks()[i]->zModelData()->getPolygon(index);
  260. for (int vi = 0; vi < polygon->indexAnz; vi++)
  261. {
  262. lightBuffer[groundVertexCount++] = calculateLight(
  263. vBuffer[polygon->indexList[vi]].pos,
  264. location,
  265. getDirectionFromIndex(index));
  266. }
  267. }
  268. index++;
  269. }
  270. }
  271. }
  272. }
  273. target->copyLightToGPU();
  274. return 1;
  275. }