TransparentChunkGroundModel.cpp 8.8 KB

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