diff --git a/include/utils.hpp b/include/utils.hpp index 21b1699..d7b19a3 100644 --- a/include/utils.hpp +++ b/include/utils.hpp @@ -9,7 +9,7 @@ namespace utils // https://stackoverflow.com/questions/20266201/3d-array-1d-flat-indexing // flatten 3d coords to 1d array cords int coord3DTo1D(int x, int y, int z, int maxX, int maxY, int maxZ); - std::array coord1DTo3D(int idx, int maxX, int maxY, int mazZ); + void coord1DTo3D(int idx, int maxX, int maxY, int mazZ, int* x, int* y, int* z); } #endif \ No newline at end of file diff --git a/src/chunk.cpp b/src/chunk.cpp index 73a3047..859b002 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -27,12 +27,14 @@ namespace Chunk Block Chunk::getBlock(int x, int y, int z) { - return blocks.at(HILBERT_XYZ_ENCODE[x][y][z]); + return blocks.at(coord3DTo1D(x, y, z)); + // return blocks.at(HILBERT_XYZ_ENCODE[x][y][z]); } void Chunk::setBlock(Block b, int x, int y, int z) { - int coord = HILBERT_XYZ_ENCODE[x][y][z]; + // return blocks.insert(HILBERT_XYZ_ENCODE[x][y][z], HILBERT_XYZ_ENCODE[x][y][z]+1, b); + int coord = coord3DTo1D(x, y, z); blocks.insert(coord <= 0 ? 0 : coord, coord+1 >= CHUNK_VOLUME ? CHUNK_VOLUME : coord+1, b); } diff --git a/src/chunkgenerator.cpp b/src/chunkgenerator.cpp index e114354..852c50c 100644 --- a/src/chunkgenerator.cpp +++ b/src/chunkgenerator.cpp @@ -4,7 +4,6 @@ #include "block.hpp" #include "chunkgenerator.hpp" -#include "globals.hpp" #include "OpenSimplexNoise.h" #include "utils.hpp" @@ -44,40 +43,47 @@ void generateNoise(Chunk::Chunk *chunk) Block block_prev{Block::AIR}; int block_prev_start{0}; - // A space filling curve is continuous, so there is no particular order - for (int s = 0; s < CHUNK_VOLUME; s++) + // The order of iteration MUST RESPECT the order in which the array is transformed from 3d to 1d + for (int k = 0; k < CHUNK_SIZE; k++) { - - int x = HILBERT_XYZ_DECODE[s][0] + CHUNK_SIZE * chunk->getPosition().x; - int y = HILBERT_XYZ_DECODE[s][1] + CHUNK_SIZE * chunk->getPosition().y; - int z = HILBERT_XYZ_DECODE[s][2] + CHUNK_SIZE * chunk->getPosition().z; - int d2 = HILBERT_XYZ_DECODE[s][0] * CHUNK_SIZE + HILBERT_XYZ_DECODE[s][2]; - - if (grassNoiseLUT[d2] == -1) - grassNoiseLUT[d2] = GRASS_OFFSET + (int)((0.5 + noiseGen1.eval(x * NOISE_GRASS_X_MULT, z * NOISE_GRASS_Z_MULT) * NOISE_GRASS_MULT)); - if (dirtNoiseLUT[d2] == -1) - dirtNoiseLUT[d2] = NOISE_DIRT_MIN + (int)((0.5 + noiseGen2.eval(x * NOISE_DIRT_X_MULT, z * NOISE_DIRT_Z_MULT) * NOISE_DIRT_MULT)); - - int grassNoise = grassNoiseLUT[d2]; - int dirtNoise = dirtNoiseLUT[d2]; - int stoneLevel = grassNoise - dirtNoise; - - if (y < stoneLevel) - block = Block::STONE; - else if (y >= stoneLevel && y < grassNoise) - block = Block::DIRT; - else if (y == grassNoise) - block = Block::GRASS; - else - block = Block::AIR; - - if (block != block_prev) + for (int i = 0; i < CHUNK_SIZE; i++) { - chunk->setBlocks(block_prev_start, s, block_prev); - block_prev_start = s; - } + for (int j = 0; j < CHUNK_SIZE; j++) + { + int x = i + CHUNK_SIZE * chunk->getPosition().x; + int y = j + CHUNK_SIZE * chunk->getPosition().y; + int z = k + CHUNK_SIZE * chunk->getPosition().z; + int d2 = k * CHUNK_SIZE + i; - block_prev = block; + if (grassNoiseLUT[d2] == -1) + grassNoiseLUT[d2] = GRASS_OFFSET + (int)((0.5 + noiseGen1.eval(x * NOISE_GRASS_X_MULT, z * NOISE_GRASS_Z_MULT) * NOISE_GRASS_MULT)); + if (dirtNoiseLUT[d2] == -1) + dirtNoiseLUT[d2] = NOISE_DIRT_MIN + (int)((0.5 + noiseGen2.eval(x * NOISE_DIRT_X_MULT, z * NOISE_DIRT_Z_MULT) * NOISE_DIRT_MULT)); + + int grassNoise = grassNoiseLUT[d2]; + int dirtNoise = dirtNoiseLUT[d2]; + int stoneLevel = grassNoise - dirtNoise; + + if (y < stoneLevel) + block = Block::STONE; + else if (y >= stoneLevel && y < grassNoise) + block = Block::DIRT; + else if (y == grassNoise) + block = Block::GRASS; + else + block = Block::AIR; + + int index = Chunk::coord3DTo1D(i, j, k); + int min = index > block_prev_start ? block_prev_start : index, max = index > block_prev_start ? index : block_prev_start; + if (block != block_prev) + { + chunk->setBlocks(block_prev_start, index, block_prev); + block_prev_start = index; + } + + block_prev = block; + } + } } chunk->setBlocks(block_prev_start, CHUNK_VOLUME, block_prev); diff --git a/src/chunkmesh.cpp b/src/chunkmesh.cpp index b3d737e..1df8b32 100755 --- a/src/chunkmesh.cpp +++ b/src/chunkmesh.cpp @@ -99,10 +99,10 @@ void ChunkMesh::mesh() { for (x[u] = 0; x[u] < CHUNK_SIZE; x[u]++) { - Block b1 = (x[dim] >= 0) ? blocks[HILBERT_XYZ_ENCODE[x[0]][x[1]][x[2]]] : Block::NULLBLK; + Block b1 = (x[dim] >= 0) ? blocks[Chunk::coord3DTo1D(x[0], x[1], x[2])] : Block::NULLBLK; /*blocks[SpaceFilling::HILBERT_XYZ_ENCODE[x[0]][x[1]][x[2]]]*/ Block b2 = (x[dim] < CHUNK_SIZE - 1) - ? blocks[HILBERT_XYZ_ENCODE[x[0] + q[0]][x[1] + q[1]][x[2] + q[2]]] - : Block::NULLBLK; + ? blocks[Chunk::coord3DTo1D(x[0] + q[0], x[1] + q[1], x[2] + q[2])] + : Block::NULLBLK; /*blocks[SpaceFilling::HILBERT_XYZ_ENCODE[x[0] + q[0]][x[1] + q[1]][x[2] + q[2]]]*/ // This is the original line taken from rob's code, readapted (replace voxelFace // with b1 and b2). diff --git a/src/main.cpp b/src/main.cpp index 3b38088..fc6dd77 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,6 +10,7 @@ #include "chunkmanager.hpp" #include "main.hpp" #include "spacefilling.hpp" +#include "utils.hpp" float deltaTime = 0.0f; // Time between current frame and last frame float lastFrame = 0.0f; // Time of last frame @@ -50,9 +51,9 @@ int main() glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwSetCursorPosCallback(window, mouse_callback); glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); //GL_BACK GL_CCW by default + glEnable(GL_CULL_FACE); // GL_BACK GL_CCW by default - SpaceFilling::initLUT(); + // SpaceFilling::initLUT(); chunkmanager::init(); while (!glfwWindowShouldClose(window)) @@ -64,7 +65,8 @@ int main() // FPS Counter frames++; - if(currentFrame - lastFPSFrame >= 1.0f){ + if (currentFrame - lastFPSFrame >= 1.0f) + { std::cout << "FPS: " << frames << " Frametime: " << deltaTime << std::endl; frames = 0; lastFPSFrame = currentFrame; diff --git a/src/spacefilling.cpp b/src/spacefilling.cpp index 1f0bc4c..9753e7d 100644 --- a/src/spacefilling.cpp +++ b/src/spacefilling.cpp @@ -188,16 +188,15 @@ namespace SpaceFilling void initLUT() { - uint32_t morton, hilbert,j; + uint32_t morton, hilbert; for (uint32_t i = 0; i < CHUNK_SIZE; i++) { - for (uint32_t y = 0; y < CHUNK_SIZE; y++) + for (uint32_t j = 0; j < CHUNK_SIZE; j++) { for (uint32_t k = 0; k < CHUNK_SIZE; k++) { - j = CHUNK_SIZE - 1 - y; morton = Morton_3D_Encode_10bit(i, j, k); - hilbert = MortonToHilbert3D(morton, 2); // 4 hilbert bits + hilbert = MortonToHilbert3D(morton, 4); // 4 hilbert bits MORTON_XYZ_ENCODE[i][j][k] = morton; MORTON_XYZ_DECODE[morton][0] = i; diff --git a/src/utils.cpp b/src/utils.cpp index 8f98c2d..d6e5d2e 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -7,13 +7,12 @@ bool utils::withinDistance(int startx, int starty, int startz, int x, int y, int // https://stackoverflow.com/questions/20266201/3d-array-1d-flat-indexing //flatten 3d coords to 1d array cords int utils::coord3DTo1D (int x, int y, int z, int maxX, int maxY, int maxZ){ - return x + maxX * (y + z * maxY); + return y + maxY * (x + z * maxX); } -std::array utils::coord1DTo3D(int idx, int maxX, int maxY, int mazZ){ - int z = idx / (maxX * maxY); - idx -= (z * maxX* maxY); - int y = idx / maxX; - int x = idx % maxX; - return std::array {x, y, z}; +void utils::coord1DTo3D(int idx, int maxX, int maxY, int mazZ, int* x, int* y, int* z){ + *z = idx / (maxX * maxY); + idx -= (*z * maxX* maxY); + *x = idx / maxY; + *y = idx % maxY; }