From 773b7999d46746f3238839d0f3ed0df31466d49f Mon Sep 17 00:00:00 2001 From: emamaker Date: Thu, 1 Dec 2022 23:27:22 +0100 Subject: [PATCH] chunkmgr: do not update same chunk multiple times Iterating on radius from 0 up to RENDER_DISTANCE made the algorithm check the same "sphere" multiple times --- src/chunkmanager.cpp | 80 +++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/src/chunkmanager.cpp b/src/chunkmanager.cpp index 8480814..6eedb5f 100644 --- a/src/chunkmanager.cpp +++ b/src/chunkmanager.cpp @@ -21,6 +21,7 @@ namespace chunkmanager } int total{0}, toGpu{0}; + int rr{RENDER_DISTANCE * RENDER_DISTANCE}; void update(float deltaTime) { // Iterate over all chunks, in concentric spheres starting fron the player and going outwards @@ -28,55 +29,52 @@ namespace chunkmanager glm::vec3 cameraPos = theCamera.getPos(); int chunkX{(static_cast(cameraPos.x)) / CHUNK_SIZE}, chunkY{(static_cast(cameraPos.y)) / CHUNK_SIZE}, chunkZ{(static_cast(cameraPos.z)) / CHUNK_SIZE}; - // std::cout << "Player at: " << chunkX << ", " << chunkY << ", " << chunkZ << "\n"; - - for (int r = 0; r <= RENDER_DISTANCE; r++) + + // Possible change: coordinates everything at the origin, then translate later? + // Step 1. Eq. of a circle. Fix the x coordinate, get the 2 possible y's + for (int x = chunkX - RENDER_DISTANCE; x <= chunkX + RENDER_DISTANCE; x++) { - // Step 1. Eq. of a circle. Fix the x coordinate, get the 2 possible y's - for (int x = chunkX - r; x <= chunkX + r; x++) + + // Possible optimization: use sqrt lookup + int y1 = sqrt((rr) - (x - chunkX) * (x - chunkX)) + chunkY; + int y2 = -sqrt((rr) - (x - chunkX) * (x - chunkX)) + chunkY; + + for (int y = y2 + 1; y <= y1; y++) { + // Step 2. At both y's, get the corresponding z values + int z1 = sqrt((rr) - (x - chunkX) * (x - chunkX) - (y - chunkY) * (y - chunkY)) + chunkZ; + int z2 = -sqrt((rr) - (x - chunkX) * (x - chunkX) - (y - chunkY) * (y - chunkY)) + chunkZ; - // Possible optimization: use sqrt lookup - int y1 = sqrt((r * r) - (x - chunkX) * (x - chunkX)) + chunkY; - int y2 = -sqrt((r * r) - (x - chunkX) * (x - chunkX)) + chunkY; + // std::cout << "RENDER DISTANCE " << RENDER_DISTANCE << " Current radius: " << r << " X: " << x << " Y Limits: " << y1 << " - " << y2 << "(" << y << ") Z Limits: " << z1 << " - " << z2 << std::endl; - for (int y = y2 + 1; y <= y1; y++) + for (int z = z2; z <= z1; z++) { - // Step 2. At both y's, get the corresponding z values - int z1 = sqrt((r * r) - (x - chunkX) * (x - chunkX) - (y - chunkY) * (y - chunkY)) + chunkZ; - int z2 = -sqrt((r * r) - (x - chunkX) * (x - chunkX) - (y - chunkY) * (y - chunkY)) + chunkZ; - // std::cout << "RENDER DISTANCE " << RENDER_DISTANCE << " Current radius: " << r << " X: " << x << " Y Limits: " << y1 << " - " << y2 << "(" << y << ") Z Limits: " << z1 << " - " << z2 << std::endl; + uint16_t i{}, j{}, k{}; - for (int z = z2; z <= z1; z++) - { + if (x < 0) + i = 0; + else if (x >= 1024) + i = 1023; + else + i = x; - uint16_t i{}, j{}, k{}; + if (y < 0) + j = 0; + else if (y >= 1024) + j = 1023; + else + j = y; - if (x < 0) - i = 0; - else if (x >= 1024) - i = 1023; - else - i = x; + if (z < 0) + k = 0; + else if (z >= 1024) + k = 1023; + else + k = z; - if (y < 0) - j = 0; - else if (y >= 1024) - j = 1023; - else - j = y; - - if (z < 0) - k = 0; - else if (z >= 1024) - k = 1023; - else - k = z; - - uint32_t in = i | (j << 10) | (k << 20); // uint32_t is fine, since i'm limiting the coordinate to only use up to ten bits (1024). There's actually two spare bits - chunkmanager::updateChunk(in, i, j, k); - } + uint32_t in = i | (j << 10) | (k << 20); // uint32_t is fine, since i'm limiting the coordinate to only use up to ten bits (1024). There's actually two spare bits + chunkmanager::updateChunk(in, i, j, k); } } } @@ -98,7 +96,7 @@ namespace chunkmanager else { glm::vec3 chunk = chunks.at(index)->chunk->getPosition() /*+ glm::vec3(static_cast(CHUNK_SIZE))*/; - + total++; int a{0}; @@ -106,7 +104,7 @@ namespace chunkmanager { glm::vec4 vertex = glm::vec4(chunk.x + (float)(i & 1), chunk.y + (float)((i & 2) >> 1), chunk.z + (float)((i & 4) >> 2), 500.0f) * (theCamera.getProjection() * theCamera.getView() * chunks.at(index)->model); vertex = glm::normalize(vertex); - + a += (-vertex.w <= vertex.x && vertex.x <= vertex.w && -vertex.w <= vertex.y && vertex.y <= vertex.w /*&& -vertex.w < vertex.z && vertex.z < vertex.w*/); } if (a)