TransparentChunkGroundModel.cpp 8.8 KB

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