TransparentChunkGroundModel.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  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 (blocks()[i]
  103. ->zBlockType()
  104. ->getModelInfo()
  105. .getModelName()
  106. .istGleich("grass"))
  107. {
  108. setBlockPartOfModel(blocks()[i], 1);
  109. __int64 light = blocks()[i]->getMaxLight();
  110. int index = 0;
  111. for (Text* textureName :
  112. *blocks()[i]->zBlockType()->getModelInfo().getTexturNames())
  113. {
  114. if (!groundModelBuidler.get(
  115. *textureName, textureName->getLength()))
  116. {
  117. GroundModelPart* part = new GroundModelPart();
  118. part->indexList = new int[10000];
  119. part->indexCount = 0;
  120. part->indexArraySize = 10000;
  121. part->name = *textureName;
  122. groundModelBuidler.set(
  123. *textureName, textureName->getLength(), part);
  124. groundPartArray.add(part);
  125. }
  126. GroundModelPart* part = groundModelBuidler.get(
  127. *textureName, textureName->getLength());
  128. const Vertex3D* vBuffer
  129. = blocks()[i]->zModelData()->zVertexBuffer();
  130. Polygon3D* polygon
  131. = blocks()[i]->zModelData()->getPolygon(index);
  132. if (part->indexCount + polygon->indexAnz
  133. > part->indexArraySize)
  134. {
  135. int* tmp = new int[part->indexArraySize + 10000];
  136. memcpy(tmp, part->indexList, part->indexCount * 4);
  137. delete[] part->indexList;
  138. part->indexList = tmp;
  139. part->indexArraySize += 10000;
  140. }
  141. if (groundVertexCount + polygon->indexAnz
  142. > groundVertexArraySize)
  143. {
  144. Vertex3D* tmp
  145. = new Vertex3D[groundVertexArraySize + 10000];
  146. memcpy(tmp,
  147. groundVerticies,
  148. groundVertexCount * sizeof(Vertex3D));
  149. delete[] groundVerticies;
  150. groundVerticies = tmp;
  151. groundVertexArraySize += 10000;
  152. __int64* lTmp = new __int64[groundVertexArraySize];
  153. memcpy(lTmp,
  154. lightBuffer,
  155. groundVertexCount * sizeof(__int64));
  156. delete[] lightBuffer;
  157. lightBuffer = lTmp;
  158. }
  159. for (int vi = 0; vi < polygon->indexAnz; vi++)
  160. {
  161. lightBuffer[groundVertexCount] = light;
  162. part->indexList[part->indexCount++] = groundVertexCount;
  163. groundVerticies[groundVertexCount++]
  164. = vBuffer[polygon->indexList[vi]];
  165. groundVerticies[groundVertexCount - 1].pos
  166. += blocks()[i]->getPos()
  167. - Vec3<float>((float)chunkCenter().x,
  168. (float)chunkCenter().y,
  169. (float)WORLD_HEIGHT / 2.f);
  170. groundVerticies[groundVertexCount - 1].id
  171. = groundVertexCount - 1;
  172. }
  173. index++;
  174. }
  175. }
  176. else
  177. {
  178. setBlockPartOfModel(blocks()[i], 0);
  179. }
  180. }
  181. }
  182. Model3DTextur* textur = new Model3DTextur();
  183. int pi = 0;
  184. for (GroundModelPart* part : groundPartArray)
  185. {
  186. Polygon3D* polygon = new Polygon3D();
  187. polygon->indexAnz = part->indexCount;
  188. polygon->indexList = part->indexList;
  189. target->zModelData()->addPolygon(polygon);
  190. textur->setPolygonTextur(pi,
  191. uiFactory.initParam.bildschirm->zGraphicsApi()->createOrGetTextur(
  192. part->name));
  193. pi++;
  194. delete part;
  195. }
  196. target->zModelData()->setVertecies(groundVerticies, groundVertexCount);
  197. target->setModelTextur(textur);
  198. target->setVertexLightBuffer(lightBuffer, groundVertexCount);
  199. }
  200. bool TransparentChunkGroundModel::updateLightning()
  201. {
  202. __int64* lightBuffer = target->zLightBuffer();
  203. int groundVertexCount = 0;
  204. for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++)
  205. {
  206. if (blocks()[i])
  207. {
  208. if (blocks()[i]
  209. ->zBlockType()
  210. ->getModelInfo()
  211. .getModelName()
  212. .istGleich("grass"))
  213. {
  214. __int64 light = blocks()[i]->getMaxLight();
  215. int index = 0;
  216. for (Text* textureName :
  217. *blocks()[i]->zBlockType()->getModelInfo().getTexturNames())
  218. {
  219. const Vertex3D* vBuffer
  220. = blocks()[i]->zModelData()->zVertexBuffer();
  221. Polygon3D* polygon
  222. = blocks()[i]->zModelData()->getPolygon(index);
  223. for (int vi = 0; vi < polygon->indexAnz; vi++)
  224. {
  225. lightBuffer[groundVertexCount++] = light;
  226. }
  227. }
  228. }
  229. }
  230. }
  231. target->copyLightToGPU();
  232. return 1;
  233. }