use hilbert curve instead of flatten array
Using valgrind heap memory tracker, this does not seem to bring any advantage on heap memory usage. To be tested more in depthintervalmaps-array-y
parent
b724640384
commit
8116791dcf
|
@ -2,6 +2,7 @@
|
||||||
#define GLOBALS_H
|
#define GLOBALS_H
|
||||||
|
|
||||||
#include "camera.hpp"
|
#include "camera.hpp"
|
||||||
|
#include "chunk.hpp"
|
||||||
|
|
||||||
#ifdef GLOBALS_DEFINER
|
#ifdef GLOBALS_DEFINER
|
||||||
#define extr
|
#define extr
|
||||||
|
@ -9,13 +10,13 @@
|
||||||
#define extr extern
|
#define extr extern
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define RENDER_DISTANCE 4
|
#define RENDER_DISTANCE 8
|
||||||
|
|
||||||
extr Camera theCamera;
|
extr Camera theCamera;
|
||||||
|
|
||||||
extr uint32_t MORTON_XYZ_ENCODE[CHUNK_SIZE][CHUNK_SIZE][CHUNK_SIZE];
|
extr uint32_t MORTON_XYZ_ENCODE[CHUNK_SIZE][CHUNK_SIZE][CHUNK_SIZE];
|
||||||
extr uint32_t MORTON_XYZ_DECODE[CHUNK_SIZE][3];
|
extr uint32_t MORTON_XYZ_DECODE[CHUNK_VOLUME][3];
|
||||||
extr uint32_t HILBERT_XYZ_ENCODE[CHUNK_SIZE][CHUNK_SIZE][CHUNK_SIZE];
|
extr uint32_t HILBERT_XYZ_ENCODE[CHUNK_SIZE][CHUNK_SIZE][CHUNK_SIZE];
|
||||||
extr uint32_t HILBERT_XYZ_DECODE[CHUNK_SIZE][3];
|
extr uint32_t HILBERT_XYZ_DECODE[CHUNK_VOLUME][3];
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -27,14 +27,12 @@ namespace Chunk
|
||||||
|
|
||||||
Block Chunk::getBlock(int x, int y, int z)
|
Block Chunk::getBlock(int x, int y, int z)
|
||||||
{
|
{
|
||||||
return blocks.at(coord3DTo1D(x, y, z));
|
return blocks.at(HILBERT_XYZ_ENCODE[x][y][z]);
|
||||||
// return blocks.at(HILBERT_XYZ_ENCODE[x][y][z]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chunk::setBlock(Block b, int x, int y, int z)
|
void Chunk::setBlock(Block b, int x, int y, int z)
|
||||||
{
|
{
|
||||||
// return blocks.insert(HILBERT_XYZ_ENCODE[x][y][z], HILBERT_XYZ_ENCODE[x][y][z]+1, b);
|
int coord = HILBERT_XYZ_ENCODE[x][y][z];
|
||||||
int coord = coord3DTo1D(x, y, z);
|
|
||||||
blocks.insert(coord <= 0 ? 0 : coord, coord+1 >= CHUNK_VOLUME ? CHUNK_VOLUME : coord+1, b);
|
blocks.insert(coord <= 0 ? 0 : coord, coord+1 >= CHUNK_VOLUME ? CHUNK_VOLUME : coord+1, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "block.hpp"
|
#include "block.hpp"
|
||||||
#include "chunkgenerator.hpp"
|
#include "chunkgenerator.hpp"
|
||||||
|
#include "globals.hpp"
|
||||||
#include "OpenSimplexNoise.h"
|
#include "OpenSimplexNoise.h"
|
||||||
#include "utils.hpp"
|
#include "utils.hpp"
|
||||||
|
|
||||||
|
@ -43,17 +44,14 @@ void generateNoise(Chunk::Chunk *chunk)
|
||||||
Block block_prev{Block::AIR};
|
Block block_prev{Block::AIR};
|
||||||
int block_prev_start{0};
|
int block_prev_start{0};
|
||||||
|
|
||||||
// The order of iteration MUST RESPECT the order in which the array is transformed from 3d to 1d
|
// A space filling curve is continuous, so there is no particular order
|
||||||
for (int k = 0; k < CHUNK_SIZE; k++)
|
for (int s = 0; s < CHUNK_VOLUME; s++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < CHUNK_SIZE; j++)
|
|
||||||
{
|
int x = HILBERT_XYZ_DECODE[s][0] + CHUNK_SIZE * chunk->getPosition().x;
|
||||||
for (int i = 0; i < CHUNK_SIZE; i++)
|
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 x = i + CHUNK_SIZE * chunk->getPosition().x;
|
int d2 = HILBERT_XYZ_DECODE[s][0] * CHUNK_SIZE + HILBERT_XYZ_DECODE[s][2];
|
||||||
int y = j + CHUNK_SIZE * chunk->getPosition().y;
|
|
||||||
int z = k + CHUNK_SIZE * chunk->getPosition().z;
|
|
||||||
int d2 = k * CHUNK_SIZE + i;
|
|
||||||
|
|
||||||
if (grassNoiseLUT[d2] == -1)
|
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));
|
grassNoiseLUT[d2] = GRASS_OFFSET + (int)((0.5 + noiseGen1.eval(x * NOISE_GRASS_X_MULT, z * NOISE_GRASS_Z_MULT) * NOISE_GRASS_MULT));
|
||||||
|
@ -73,18 +71,14 @@ void generateNoise(Chunk::Chunk *chunk)
|
||||||
else
|
else
|
||||||
block = Block::AIR;
|
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)
|
if (block != block_prev)
|
||||||
{
|
{
|
||||||
chunk->setBlocks(block_prev_start, index, block_prev);
|
chunk->setBlocks(block_prev_start, s, block_prev);
|
||||||
block_prev_start = index;
|
block_prev_start = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
block_prev = block;
|
block_prev = block;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
chunk->setBlocks(block_prev_start, CHUNK_VOLUME, block_prev);
|
chunk->setBlocks(block_prev_start, CHUNK_VOLUME, block_prev);
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,10 +99,10 @@ void ChunkMesh::mesh()
|
||||||
{
|
{
|
||||||
for (x[u] = 0; x[u] < CHUNK_SIZE; x[u]++)
|
for (x[u] = 0; x[u] < CHUNK_SIZE; x[u]++)
|
||||||
{
|
{
|
||||||
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 b1 = (x[dim] >= 0) ? blocks[HILBERT_XYZ_ENCODE[x[0]][x[1]][x[2]]]: Block::NULLBLK;
|
||||||
Block b2 = (x[dim] < CHUNK_SIZE - 1)
|
Block b2 = (x[dim] < CHUNK_SIZE - 1)
|
||||||
? blocks[Chunk::coord3DTo1D(x[0] + q[0], x[1] + q[1], x[2] + q[2])]
|
? blocks[HILBERT_XYZ_ENCODE[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]]]*/
|
: Block::NULLBLK;
|
||||||
|
|
||||||
// This is the original line taken from rob's code, readapted (replace voxelFace
|
// This is the original line taken from rob's code, readapted (replace voxelFace
|
||||||
// with b1 and b2).
|
// with b1 and b2).
|
||||||
|
|
|
@ -51,7 +51,7 @@ int main()
|
||||||
glfwSetCursorPosCallback(window, mouse_callback);
|
glfwSetCursorPosCallback(window, mouse_callback);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
// SpaceFilling::initLUT();
|
SpaceFilling::initLUT();
|
||||||
chunkmanager::init();
|
chunkmanager::init();
|
||||||
|
|
||||||
while (!glfwWindowShouldClose(window))
|
while (!glfwWindowShouldClose(window))
|
||||||
|
|
|
@ -188,15 +188,16 @@ namespace SpaceFilling
|
||||||
|
|
||||||
void initLUT()
|
void initLUT()
|
||||||
{
|
{
|
||||||
uint32_t morton, hilbert;
|
uint32_t morton, hilbert,j;
|
||||||
for (uint32_t i = 0; i < CHUNK_SIZE; i++)
|
for (uint32_t i = 0; i < CHUNK_SIZE; i++)
|
||||||
{
|
{
|
||||||
for (uint32_t j = 0; j < CHUNK_SIZE; j++)
|
for (uint32_t y = 0; y < CHUNK_SIZE; y++)
|
||||||
{
|
{
|
||||||
for (uint32_t k = 0; k < CHUNK_SIZE; k++)
|
for (uint32_t k = 0; k < CHUNK_SIZE; k++)
|
||||||
{
|
{
|
||||||
|
j = CHUNK_SIZE - 1 - y;
|
||||||
morton = Morton_3D_Encode_10bit(i, j, k);
|
morton = Morton_3D_Encode_10bit(i, j, k);
|
||||||
hilbert = MortonToHilbert3D(morton, 4); // 4 hilbert bits
|
hilbert = MortonToHilbert3D(morton, 2); // 4 hilbert bits
|
||||||
|
|
||||||
MORTON_XYZ_ENCODE[i][j][k] = morton;
|
MORTON_XYZ_ENCODE[i][j][k] = morton;
|
||||||
MORTON_XYZ_DECODE[morton][0] = i;
|
MORTON_XYZ_DECODE[morton][0] = i;
|
||||||
|
|
Loading…
Reference in New Issue