Chunk.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #include "Chunk.h"
  2. #include "Constants.h"
  3. #include "Globals.h"
  4. #include "Registries.h"
  5. Chunk::Chunk(Framework::Punkt location)
  6. : ReferenceCounter(),
  7. location(location),
  8. isLoading(0)
  9. {}
  10. Chunk::Chunk(Framework::Punkt location, Framework::StreamReader* zReader)
  11. : Chunk(location)
  12. {
  13. load(zReader);
  14. }
  15. Chunk::~Chunk()
  16. {}
  17. void Chunk::api(char* message)
  18. {
  19. // TODO: implement api
  20. }
  21. Block* Chunk::zBlockAt(Framework::Vec3<int> location)
  22. {
  23. cs.lock();
  24. for (Block* b : blocks)
  25. {
  26. if (Framework::Vec3<int>((int)floor(b->getPos().x), (int)floor(b->getPos().y), (int)floor(b->getPos().z)) == location)
  27. {
  28. cs.unlock();
  29. return b;
  30. }
  31. }
  32. cs.unlock();
  33. return 0;
  34. }
  35. void Chunk::setBlock(Block* block)
  36. {
  37. cs.lock();
  38. Framework::Vec3<int> pos = (Framework::Vec3<int>)block->getPos();
  39. for (Framework::Iterator<Block*> iterator = blocks.begin(); iterator; iterator++)
  40. {
  41. if (pos == (Framework::Vec3<int>)iterator->getPos())
  42. {
  43. iterator->release();
  44. iterator.set(block);
  45. cs.unlock();
  46. return;
  47. }
  48. }
  49. blocks.add(block);
  50. cs.unlock();
  51. if (!isLoading)
  52. updateVisibility();
  53. }
  54. void Chunk::removeBlock(Block* zBlock)
  55. {
  56. cs.lock();
  57. int index = 0;
  58. for (Framework::Iterator<Block*> iterator = blocks.begin(); iterator; iterator++, index++)
  59. {
  60. if (zBlock == (Block*)iterator)
  61. {
  62. blocks.remove(index);
  63. cs.unlock();
  64. if (!isLoading)
  65. updateVisibility();
  66. return;
  67. }
  68. }
  69. cs.unlock();
  70. }
  71. void Chunk::load(Framework::StreamReader* zReader)
  72. {
  73. isLoading = 1;
  74. Framework::Vec3<int> pos = { 0, 0, 0 };
  75. unsigned short id;
  76. zReader->lese((char*)&id, 2);
  77. while (id)
  78. {
  79. zReader->lese((char*)&pos.x, 4);
  80. zReader->lese((char*)&pos.y, 4);
  81. zReader->lese((char*)&pos.z, 4);
  82. if (blockTypes[id]->doesNeedInstance())
  83. setBlock(blockTypes[id]->createBlock({ pos.x + location.x - CHUNK_SIZE / 2, pos.y + location.y - CHUNK_SIZE / 2, pos.z }));
  84. zReader->lese((char*)&id, 2);
  85. }
  86. isLoading = 0;
  87. updateVisibility();
  88. }
  89. Framework::Punkt Chunk::getCenter() const
  90. {
  91. return location;
  92. }
  93. Framework::Vec3<int> Chunk::getMin() const
  94. {
  95. return { location.x - CHUNK_SIZE / 2, location.y - CHUNK_SIZE / 2, 0 };
  96. }
  97. Framework::Vec3<int> Chunk::getMax() const
  98. {
  99. return { location.x + CHUNK_SIZE / 2, location.y + CHUNK_SIZE / 2, WORLD_HEIGHT };
  100. }
  101. void Chunk::forAll(std::function<void(Model3D*)> f)
  102. {
  103. cs.lock();
  104. for (Block* b : blocks)
  105. f(b);
  106. cs.unlock();
  107. }
  108. void Chunk::updateVisibility()
  109. {
  110. cs.lock();
  111. for (Block* b : blocks)
  112. {
  113. Framework::Vec3<int> pos = Framework::Vec3<int>((int)floor(b->getPos().x), (int)floor(b->getPos().y), (int)floor(b->getPos().z));
  114. for (int i = 0; i < 6; i++)
  115. {
  116. Block* c = zBlockAt(pos + getDirection(getDirectionFromIndex(i)));
  117. b->setSideVisible(getDirectionFromIndex(i), !c || c->isTransparent());
  118. }
  119. }
  120. cs.unlock();
  121. }