diff --git a/zeus/world/BlockChunk.cpp b/zeus/world/BlockChunk.cpp index 620d869b..4dccbdf8 100644 --- a/zeus/world/BlockChunk.cpp +++ b/zeus/world/BlockChunk.cpp @@ -8,6 +8,14 @@ BlockChunk::BlockChunk(std::vector* blocks) { this->blocks = blocks; + this->empty = true; + + for (int i : *blocks) { + if (i != 0) { + empty = false; + break; + } + } } int BlockChunk::getBlock(glm::vec3* pos) { @@ -25,4 +33,8 @@ int BlockChunk::getBlock(int x, int y, int z) { unsigned int ind = ArrayTrans3D::vecToInd(x, y, z); if (ind < 0 || ind >= 4096) return -1; return blocks->at(ind); +} + +bool BlockChunk::isEmpty() { + return empty; } \ No newline at end of file diff --git a/zeus/world/BlockChunk.h b/zeus/world/BlockChunk.h index 863c6095..74e8caad 100644 --- a/zeus/world/BlockChunk.h +++ b/zeus/world/BlockChunk.h @@ -17,9 +17,12 @@ public: int getBlock(glm::vec3* pos); int getBlock(int x, int y, int z); + bool isEmpty(); + //TODO: Add block setting methods as well private: std::vector* blocks; + bool empty; }; #endif //GLPROJECT_BLOCKCHUNK_H \ No newline at end of file diff --git a/zeus/world/GameInstance.cpp b/zeus/world/GameInstance.cpp index e0c2eaac..d429b72e 100644 --- a/zeus/world/GameInstance.cpp +++ b/zeus/world/GameInstance.cpp @@ -50,7 +50,7 @@ void GameInstance::update(GLfloat deltaTime) { chunk.y = round(chunk.y / 16); chunk.z = round(chunk.z / 16); - int SIZE = 32; + int SIZE = 16; for (int i = -SIZE; i < SIZE; i++) { for (int j = -4; j < 4; j++) { for (int k = -SIZE; k < SIZE; k++) { diff --git a/zeus/world/World.cpp b/zeus/world/World.cpp index 4576a6b4..029b91c9 100644 --- a/zeus/world/World.cpp +++ b/zeus/world/World.cpp @@ -22,11 +22,14 @@ void World::genChunk(glm::vec3 pos) { void World::newChunk(glm::vec3 pos, BlockChunk *c) { blockChunks.insert(std::pair(pos, c)); - meshGenQueue.insert(pos); + if (!c->isEmpty()) { + meshGenQueue.insert(pos); + } } void chunkGenThread(World::ChunkThreadData *t) { PerlinNoise p(0); + PerlinNoise p2(10); auto* blocks = new std::vector(); blocks->reserve(4096); @@ -40,7 +43,11 @@ void chunkGenThread(World::ChunkThreadData *t) { pos.y = innerPos.y + t->pos.y * CHUNK_SIZE; pos.z = innerPos.z + t->pos.z * CHUNK_SIZE; - double val = p.noise(pos.x / (double) 32, pos.z / (double) 32, 0) * 16 - pos.y; + double val = p.noise(pos.x / (double) 32, pos.z / (double) 32, 0) * 16; + val *= p2.noise((pos.x + 16) / (double) 48, (pos.z + 16) / (double) 48, 0) * 8; + val /= 16; + val *= pow(p.noise(pos.x / (double) 64, pos.z / (double) 64, 0), 2) * 40 + 1; + val -= pos.y; int block = (val > 0) ? (val > 1 ) ? (val > 4) ? 3 : 2 : 1 : 0; blocks->push_back(block); @@ -55,32 +62,27 @@ void meshGenThread(World::MeshThreadData *t) { t->done = true; } -//Generate block chunks void World::handleChunkGenQueue() { - //Finish Block Gen threads + //Finalize finished threads by added the BlockChunks to the world via newChunk(). for (auto iter = chunkGenThreads.begin(); iter != chunkGenThreads.end(); ) { ChunkThreadData* threadData = (*iter); - //If the threadData is done, create a BlockChunk and delete the threadData. if (threadData->done) { newChunk(threadData->pos, threadData->chunk); delete threadData; iter = chunkGenThreads.erase(iter); } - //Otherwise ignore it and move to the next BlockChunk else { iter++; } } - //Create threads for the chunk generation. + //Create new chunk gen threads if there are chunks to be generated. while (!chunkGenQueue.empty() && chunkGenThreads.size() < MAX_CHUNK_GEN_THREADS) { - //Get and remove the first position from the vector. auto it = chunkGenQueue.begin(); chunkGenQueue.erase(chunkGenQueue.begin()); glm::vec3 pos = (*it); - //Create a thread for it and add the threadData to the chunkGenThreads vector auto t = new ChunkThreadData(pos, blockAtlas); auto thread = new std::thread(chunkGenThread, t); thread->detach(); @@ -90,49 +92,35 @@ void World::handleChunkGenQueue() { } void World::handleMeshGenQueue() { - //Run through all of the active generation threads, and finish and remove the ones that are ready to be finished. - //Then, spin up new threads when there is space in the meshGenThreads array and there are chunks waiting to be meshed. - - //Create MeshChunks for the finished threads. - Timer applyGlobal("Applying Meshes"); - + //Finalize finished threads by creating a MeshChunk object from the thread data. for (auto iter = meshGenThreads.begin(); iter != meshGenThreads.end(); ) { MeshThreadData* threadData = (*iter); - //If the threadData is done, create a MeshChunk and delete the threadData. if (threadData->done) { - Timer apply("Applying Mesh"); + //Only create the MeshChunk object if there's vertices in it. + if (!threadData->vertices->empty()) { + auto meshChunk = new MeshChunk(); + meshChunk->build(threadData->vertices, threadData->indices); - auto meshChunk = new MeshChunk(); - meshChunk->build(threadData->vertices, threadData->indices); - - glm::vec3 pos = glm::vec3(threadData->pos.x * CHUNK_SIZE, threadData->pos.y * CHUNK_SIZE, threadData->pos.z * CHUNK_SIZE); - meshChunk->setPosition(pos); - - meshChunks.insert(std::pair(threadData->pos, meshChunk)); - -// apply.printElapsedMs(); + glm::vec3 pos = threadData->pos * glm::vec3(CHUNK_SIZE); + meshChunk->setPosition(pos); + meshChunks.insert(std::pair(threadData->pos, meshChunk)); + } delete threadData; iter = meshGenThreads.erase(iter); } - //Otherwise ignore it and move to the next MeshChunk else { iter++; } } -// applyGlobal.printElapsedMs(); - - //Begin processing queued chunks if there are chunks to be processed and there's room for more threads. + //Create new mesh gen threads if there are meshes to be made. while (!meshGenQueue.empty() && meshGenThreads.size() < MAX_MESH_GEN_THREADS) { - - //Get and remove the first position from the vector. auto it = meshGenQueue.begin(); meshGenQueue.erase(meshGenQueue.begin()); glm::vec3 pos = (*it); - //Create a thread for it and add the threadData to the meshGenThreads vector auto t = new MeshThreadData(pos, blockChunks.at(pos), blockAtlas); auto thread = new std::thread(meshGenThread, t); thread->detach(); @@ -142,7 +130,10 @@ void World::handleMeshGenQueue() { } void World::update() { + //Create / Finalize BlockChunks handleChunkGenQueue(); + + //Create / Finalize MeshChunks handleMeshGenQueue(); } @@ -150,6 +141,9 @@ std::unordered_map* World::getMeshChunks( return &meshChunks; } +// +//Constructors and Destructors for the MeshThreadData / ChunkThreadData structs. +// World::MeshThreadData::MeshThreadData(glm::vec3 pos, BlockChunk *chunk, BlockAtlas *atlas) { this->pos = pos; this->chunk = chunk;