2
\$\begingroup\$

I've finally managed to implement an infinite chunk loading system for my voxel engine. Since every chunk needs to have information about the border of the neighbouring chunks, I need to access them fast. First some information about how I'm storing the voxel data: I have an Integer array of block information on each chunk (rather than byte because of the read/write access speed), which is stored in an Dictionary(Vector3i chunkPos, Chunk chunk). When building a chunk I have to access the voxel data of the chunk and of the neighbouring chunks several times.

Without information about their neighbours it currently looks like this: enter image description here

So I've tried the following two things:

  1. getting the chunk data every time like this:

    public static int getBlockAt(int x, int y, int z) {
        Vector3i chunkIndex = new Vector3i(
            x >> ChunkManager.logChunkSize,
            y >> ChunkManager.logChunkSize,
            z >> ChunkManager.logChunkSize
        );
    
        if (chunkManager.chunkData.ContainsKey(chunkIndex)) {
            return chunkManager.chunkData[chunkIndex].data[x & ChunkManager.chunkMask, y & ChunkManager.chunkMask, z & ChunkManager.chunkMask]} return 0;
    
  2. storing chunkSize + 2 information on each chunk, which makes editing much, much slower, but improves chunk loading alot

In general I want to implement something like using approach 1 only when the block data isn't on the chunk.

I really don't know how I could do it! Do you have an idea, or experience from writing voxel engines?

Thanks in advance!

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I'm also building a voxel like game, and this is how I do it.

I store a list of Chunks in an array. Each chunk have a position, and an short array of voxel materials.

Heres my local chunk get and set methods:

public short getBlock(byte x, byte y, byte z) {     
    return blocks[y+(x*16)+(z*256)];
}

public void setBlock(byte x, byte y, byte z, short id) {
    blocks[y+(x*16)+(z*256)] = id;
}

To get/set globally you will just get the chunk position, and then call the local methods for the certain chunk.

Hope this inspired you, and sorry for not providing you a more detailed answer.

\$\endgroup\$
1
  • \$\begingroup\$ First of all thanks for the answer! Your method might work in an finite terrain engine well, but since I'm using an Dictionary to store the chunks near the player this doesn't work for me! but your idea to store the block data in a flat array looks nice! I'm going to try it out and compare the performance / memory usage to a 3D array. \$\endgroup\$
    – yxyx136
    Commented Jun 5, 2015 at 21:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .