7
\$\begingroup\$

I've decided a while ago to make my own voxel engine. To start, I coded my own basic 3D engine in Java using minimal OpenGL bindings for things such as SRGB ect. I set up my own VBA and VBOS and had it working with .obj files. I already have transformations and Quaternions set up.

I've recently started to implement my attempt at a voxel engine. Last night I set up a very crude jury-rigged attempt that actually worked well enough with perlin noise to draw random 1x1x1 blocks on the screen that resembled a world.

The issue is that I've used immediate mode and block-by block-rendering with no chunks. So today I've decided to start writing my chunk class, and was hoping someone could tell me if it seems correctly set up.

Edit: I forgot to mention that I currently am trying to figure out how to handle vertices, so that's why there is no code.

package cam.base.engine;
public class Chunk
{
 public static final int X_CHUNK_SIZE = 16;
 public static final int Y_CHUNK_SIZE = 128;
 public static final int Z_CHUNK_SIZE = 16;
 public int chunkXNumber;
 public int chunkZNumber;
 private Block [][][] blocks = new Block[X_CHUNK_SIZE][Y_CHUNK_SIZE][Z_CHUNK_SIZE];
 public Chunk(int chunkXNumber, int chunkZNumber)
 {
 this.chunkXNumber = chunkXNumber;
 this.chunkZNumber = chunkZNumber;
 createBlocks(chunkXNumber, chunkZNumber);
 Vertex [][][] vertices = createVertices(getActiveBlocks(), chunkXNumber, chunkZNumber);
 int[] = createIndices(vertices);
 }
 private void createBlocks(int chunkXNum, int chunkZNum)
 {
 for(int i = 1; i <= X_CHUNK_SIZE; i++)
 {
 for(int j = 1; j <= Y_CHUNK_SIZE; j++)
 {
 for(int k = 1; k <= Z_CHUNK_SIZE; k++)
 {
 float density = getDensity(new Vector3(i,j,k), chunkXNum, chunkZNum);
 byte material = getMaterial(density,j);
 boolean isActive = checkBlockActive(material);
 blocks[i - 1][j - 1][k - 1] = new Block(material, isActive);
 }
 }
 } 
 } 
 private boolean[][][] getActiveBlocks()
 {
 boolean [][][] activeBlocks = new boolean[X_CHUNK_SIZE][Y_CHUNK_SIZE][Z_CHUNK_SIZE];
 for(int i = 0; i < X_CHUNK_SIZE; i++)
 {
 for(int j = 0; j < Y_CHUNK_SIZE; j++)
 {
 for(int k = 0; k < Z_CHUNK_SIZE; k++)
 {
 activeBlocks[i][j][k] = blocks[i][j][k].isBlockEnabled();
 } 
 } 
 } 
 return activeBlocks;
 }
 private float getDensity(Vector3 chunkPos, int chunkXNum, int chunkZNum)
 {
 float density = 0;
 int x = chunkPos.getX() * chunkXNum;
 int y = chunkPos.getY() * chunkZNum;
 int z = chunkPos.getZ() * chunkZNum;
 //TODO check to see if double is necessary
 for(double i = 1; i <= Game.octaveLimit; i *= 2)
 {
 density += (1/i) * (Noise.noise((x / 160.0f) * i, (y / 160.0f) * i,( z / 160.0f) * i));
 density = Math.abs(density);
 }
 return density;
 }
 private byte getMaterial(float density, int yVal)
 { 
 byte material;
 if(density > .2)
 {
 if(yVal >= 80)
 {
 material = 0;
 }
 else
 {
 material = 1;
 }
 }
 else
 {
 if(yVal >= 64)
 {
 material = 0;
 }
 else
 {
 material = 2;
 }
 }
 return material;
 }
 private boolean checkBlockActive(byte material)
 {
 if(material == 0)
 {
 return false;
 }
 else
 {
 return true;
 }
 }
 private Vertex[][][] createVertices(boolean[][][] activeBlocks, int chunkXNum, int chunkZNum)
 {
 boolean[][][] verticesActive = new boolean[X_CHUNK_SIZE][Y_CHUNK_SIZE][Z_CHUNK_SIZE];
 Vertex[][][] vertices = new Vertex[X_CHUNK_SIZE][Y_CHUNK_SIZE][Z_CHUNK_SIZE];
 for(int i = 1; i <= X_CHUNK_SIZE; i++)
 {
 for(int j = 1; j <= Y_CHUNK_SIZE; j++)
 {
 for(int k = 1; k <= Z_CHUNK_SIZE; k++)
 {
 if(activeBlocks[i - 1][j - 1][k - 1])
 {
 if(verticesActive[i - 1][j - 1][k - 1] == false)
 {
 vertices[i - 1][j - 1][k - 1] = new Vertex(new Vector3(i * chunkXNum, j , k * chunkZNum));
 }
 continue;
 }
 continue;
 }
 }
 }
 return vertices;
 }
 private int[] createIndices(Vertex[][][] vertices)
 {
 }
}
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Nov 5, 2013 at 0:41
\$\endgroup\$

1 Answer 1

6
\$\begingroup\$
  1. createBlocks actually fills the blocks array, creation happens before that, so this name is a little bit misleading. I'd move the array creation inside the method and use it as a return value:

    private Block[][][] blocks;
    public Chunk(int chunkXNumber, int chunkZNumber) {
     ..
     blocks = createBlocks(chunkXNumber, chunkZNumber);
    }
    private Block[][][] createBlocks(int chunkXNum, int chunkZNum) {
     final Block[][][] blocks = new Block[X_CHUNK_SIZE][Y_CHUNK_SIZE][Z_CHUNK_SIZE];
     // loops here
     return blocks;
    }
    
  2. private boolean checkBlockActive(byte material) {
     if (material == 0) {
     return false;
     }
     else {
     return true;
     }
    }
    

    It could be simply

    private boolean checkBlockActive(byte material) {
     return material != 0;
    }
    
  3. In the getMaterial method you could use multiple returns and get rid of the result variable:

    private byte getMaterial(final float density, final int yVal) {
     if (density > .2) {
     if (yVal >= 80) {
     return 0;
     } else {
     return 1;
     }
     } else {
     if (yVal >= 64) {
     return 0;
     } else {
     return 2;
     }
     }
    }
    
  4. 160.0f is used multiple times and it's a magic number. It would deserve a named constant.

  5. The code should follow the Code Conventions for the Java Programming Language.

  6. Some of the loops runs from 1 to <= X_CHUNK_SIZE, some of them 0 to < X_CHUNK_SIZE. It should be consistent.

  7. The two continue is unnecessary here:

    for (int k = 1; k <= Z_CHUNK_SIZE; k++) {
     if (activeBlocks[i - 1][j - 1][k - 1]) {
     if (verticesActive[i - 1][j - 1][k - 1] == false) {
     vertices[i - 1][j - 1][k - 1] = new Vertex(new Vector3(i * chunkXNum, j, k * chunkZNum));
     }
     continue;
     }
     continue;
    }
    
answered Feb 22, 2014 at 16:01
\$\endgroup\$
1
  • 2
    \$\begingroup\$ Hahaha thanks for the reply. I actually made this a while ago and have since become less bad. My entire engine is in c++ now and actually lets you choose between using a Sparsevoxel octree, linear memory or hashing. Looking back a lot of the crap I was doing was bad :(. Here's a couple semi recent pics.imgur.com/JWkX6Va,MXj3mN8,9miaW8Z \$\endgroup\$ Commented Feb 28, 2014 at 5:11

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.