Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

world.cpp 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /*
  2. * =====================================================================================
  3. *
  4. * Filename: world.cpp
  5. *
  6. * Description:
  7. *
  8. * Version: 1.0
  9. * Created: 04/03/2014 09:53:00 PM
  10. * Revision: none
  11. * Compiler: gcc
  12. *
  13. * Author: YOUR NAME (),
  14. * Organization:
  15. *
  16. * =====================================================================================
  17. */
  18. #include "world.h"
  19. #include "chunk.h"
  20. #include <cmath>
  21. #include <iostream>
  22. #include <thread>
  23. #include <GL/glew.h>
  24. #include <GL/gl.h>
  25. #define GLM_FORCE_RADIANS
  26. #include <glm/glm.hpp>
  27. #include <glm/gtc/type_ptr.hpp>
  28. #include <glm/gtc/matrix_transform.hpp>
  29. namespace vtk {
  30. World::World() {
  31. chunkSize = 16;
  32. voxelSize = 1.0f;
  33. voxelInfo.linkedWorld = this;
  34. voxelMath.linkedWorld = this;
  35. }
  36. bool World::isVoxelSolid(const int& x, const int& y, const int& z) {
  37. auto chunkPos = std::make_tuple(floor((float)x / (float)chunkSize),
  38. floor((float)y / (float)chunkSize),
  39. floor((float)z / (float)chunkSize));
  40. if (chunks.find(chunkPos) == chunks.end()) { //block is in nonexistant chunk
  41. return true;
  42. }
  43. int relPosX = x - std::get<0>(chunkPos) * chunkSize;
  44. int relPosY = y - std::get<1>(chunkPos) * chunkSize;
  45. int relPosZ = z - std::get<2>(chunkPos) * chunkSize;
  46. return chunks[chunkPos]->isVoxelSolid(relPosX, relPosY, relPosZ);
  47. }
  48. bool World::setVoxelType(const int& x, const int& y, const int& z, const unsigned& type, const bool& updateChunk) {
  49. auto chunkPos = std::make_tuple(floor((float)x / (float)chunkSize), floor((float)y / (float)chunkSize), floor((float)z / (float)chunkSize));
  50. if (chunks.find(chunkPos) == chunks.end()) { //block is in nonexistant chunk
  51. return false;
  52. }
  53. int relPosX = x - std::get<0>(chunkPos) * chunkSize;
  54. int relPosY = y - std::get<1>(chunkPos) * chunkSize;
  55. int relPosZ = z - std::get<2>(chunkPos) * chunkSize;
  56. chunks[chunkPos]->setVoxelType(relPosX, relPosY, relPosZ, type);
  57. if (updateChunk) queueChunkUpdate(chunkPos);
  58. return true;
  59. }
  60. unsigned World::getVoxelType(const glm::ivec3& pos) {
  61. auto chunkPos = std::make_tuple(floor((float)pos.x / (float)chunkSize),
  62. floor((float)pos.y / (float)chunkSize),
  63. floor((float)pos.z / (float)chunkSize));
  64. if (chunks.find(chunkPos) == chunks.end()) {
  65. return 0;
  66. }
  67. int relPosX = pos.x - std::get<0>(chunkPos) * chunkSize;
  68. int relPosY = pos.y - std::get<1>(chunkPos) * chunkSize;
  69. int relPosZ = pos.z - std::get<2>(chunkPos) * chunkSize;
  70. return chunks[chunkPos]->getVoxelType((unsigned)relPosX, (unsigned)relPosY, (unsigned)relPosZ);
  71. }
  72. bool World::makeChunk(const int& x, const int& y, const int& z) {
  73. auto pos = std::make_tuple(x, y, z);
  74. auto posvec = glm::ivec3(x, y, z);
  75. if (chunks.find(pos) != chunks.end()) { //chunk already exists
  76. return false;
  77. }
  78. auto newChunk = new Chunk(*this);
  79. chunks[pos] = newChunk;
  80. newChunk->setPos(posvec);
  81. //newChunk->renderer.linkedWorld = this;
  82. newChunk->renderer.init();
  83. newChunk->renderer.setChunkPosition(x,y,z);
  84. mChunkMeshes.emplace(posvec, ChunkMesh(*this, posvec));
  85. return true;
  86. }
  87. bool World::generateChunk(const int& x, const int& y, const int& z) {
  88. bool chunkMade = makeChunk(x,y,z);
  89. if (chunkMade) {
  90. terrain.generateChunk(chunks[std::make_tuple(x,y,z)]);
  91. }
  92. return chunkMade;
  93. }
  94. Chunk* World::getChunk(const glm::ivec3& pos) {
  95. return chunks[std::make_tuple(pos.x, pos.y, pos.z)];
  96. }
  97. void World::queueChunkUpdate(const int& x, const int& y, const int& z) {
  98. queueChunkUpdate(std::make_tuple(x,y,z));
  99. }
  100. void World::queueChunkUpdate(const iPos& pos) {
  101. if (chunks.find(pos) == chunks.end()) return; //chunk doesn't exist
  102. for (auto& i : chunkUpdateQueue) {
  103. if (i == pos) return; //chunk is already in queue, we don't need to update multiple times
  104. }
  105. chunkUpdateQueue.push_back(pos);
  106. }
  107. void World::draw() {
  108. /*
  109. for (auto& i : chunks) {
  110. glm::mat4 modelMat = glm::translate(glm::mat4(), glm::vec3(
  111. (float)i.second->getPos().x * 16,
  112. (float)i.second->getPos().y * 16,
  113. (float)i.second->getPos().z * 16
  114. ));
  115. glUniformMatrix4fv(modelMatUni, 1, GL_FALSE, glm::value_ptr(modelMat));
  116. i.second->renderer.drawChunk();
  117. }
  118. */
  119. for (auto& i : mChunkMeshes) {
  120. glm::mat4 modelMat = glm::translate(glm::mat4(), glm::vec3(
  121. (float)i.first.x * 16,
  122. (float)i.first.y * 16,
  123. (float)i.first.z * 16
  124. ));
  125. glUniformMatrix4fv(modelMatUni, 1, GL_FALSE, glm::value_ptr(modelMat));
  126. i.second.draw();
  127. }
  128. }
  129. void World::update() {
  130. while (!chunkUpdateQueue.empty()) {
  131. /*
  132. auto chunk = chunks[chunkUpdateQueue.back()];
  133. chunkUpdateQueue.pop_back();
  134. std::thread(&ChunkRenderer::updateGeometry, &chunk->renderer).detach();
  135. */
  136. auto& pos = chunkUpdateQueue.back();
  137. auto posVec = glm::ivec3(std::get<0>(pos), std::get<1>(pos), std::get<2>(pos));
  138. auto& mesh = mChunkMeshes.find(posVec)->second;
  139. chunkUpdateQueue.pop_back();
  140. //mesh.rebuildChunkGeometry();
  141. std::thread(&ChunkMesh::rebuildChunkGeometry, &mesh).detach();
  142. mChunkGeometryUpdateQueue.push_back(posVec);
  143. }
  144. /*
  145. for (auto& i : chunks) {
  146. i.second->renderer.updateVertexData();
  147. }
  148. auto it = mChunkGeometryUpdateQueue.begin();
  149. while (it != mChunkGeometryUpdateQueue.end()) {
  150. if (mChunkMeshes.find(*it)->second.updateGeometry()) {
  151. std::cout << "updated chunk " << it->x << "," << it->y << "," << it->z;
  152. mChunkGeometryUpdateQueue.erase(it);
  153. }
  154. else ++it;
  155. }
  156. */
  157. }
  158. void World::forceGlobalGeometryUpdate() {
  159. int chunkCount = 1;
  160. /*
  161. for (auto& i : chunks) {
  162. std::cout << "\rUpdating chunk geometry (" << chunkCount << "/" << chunks.size() << ")" << std::flush;
  163. i.second->renderer.updateGeometry();
  164. chunkCount++;
  165. //i.second->renderer.updateVertexData();
  166. }
  167. */
  168. chunkCount = 1;
  169. for (auto& i : mChunkMeshes) {
  170. std::cout << "\rUpdating chunk geometry, but better (" << chunkCount << "/" << mChunkMeshes.size() << ")" << std::flush;
  171. i.second.rebuildChunkGeometry();
  172. i.second.updateGeometry();
  173. ++chunkCount;
  174. }
  175. }
  176. }