ChunkGroundModel.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  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
  213. {
  214. setBlockPartOfModel(blocks()[i], 0);
  215. }
  216. }
  217. }
  218. Model3DTextur* textur = new Model3DTextur();
  219. int pi = 0;
  220. for (GroundModelPart* part : groundPartArray)
  221. {
  222. Polygon3D* polygon = new Polygon3D();
  223. polygon->indexAnz = part->indexCount;
  224. polygon->indexList = part->indexList;
  225. target->zModelData()->addPolygon(polygon);
  226. textur->setPolygonTextur(pi,
  227. uiFactory.initParam.bildschirm->zGraphicsApi()->createOrGetTextur(
  228. part->name));
  229. pi++;
  230. delete part;
  231. }
  232. target->zModelData()->setVertecies(groundVerticies, groundVertexCount);
  233. target->setModelTextur(textur);
  234. target->setVertexLightBuffer(lightBuffer, groundVertexCount);
  235. }
  236. bool ChunkGroundModel::updateLightning() {
  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()
  245. ->getModelInfo()
  246. .getModelName()
  247. .istGleich("cube"))
  248. {
  249. int index = 0;
  250. for (Text* textureName :
  251. *blocks()[i]->zBlockType()->getModelInfo().getTexturNames())
  252. {
  253. Framework::Vec3<int> location(
  254. (i / WORLD_HEIGHT) / CHUNK_SIZE,
  255. (i / WORLD_HEIGHT) % CHUNK_SIZE,
  256. i % WORLD_HEIGHT);
  257. if (isPartOfGroundModel(location, index))
  258. {
  259. const Vertex3D* vBuffer
  260. = blocks()[i]->zModelData()->zVertexBuffer();
  261. Polygon3D* polygon
  262. = blocks()[i]->zModelData()->getPolygon(index);
  263. for (int vi = 0; vi < polygon->indexAnz; vi++)
  264. {
  265. lightBuffer[groundVertexCount++] = calculateLight(
  266. vBuffer[polygon->indexList[vi]].pos,
  267. location,
  268. getDirectionFromIndex(index));
  269. }
  270. }
  271. index++;
  272. }
  273. }
  274. }
  275. }
  276. target->copyLightToGPU();
  277. return 1;
  278. }