HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Meshing algorithm for generating faces in Minecraft

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
meshingfacesminecraftalgorithmgeneratingfor

Problem

To generate faces of a Minecraft-like world from a three dimensional array, I developed the following meshing algorithm. The faces are given vertices and indices. A vertex consists of a position in space, a normal vector and a texture coordinate. Indices point to vertices to consecutively define faces.

Those variables are used:

// dimensions of the world
#define SIZE 32

// voxel grid representing the world, where 0 means air
uint8_t data[SIZE][SIZE][SIZE];

// results are stored in those vectors
vector positions, normals, texcoords;
vector elements;


This is the algorithm:

int n = 0;
for(int X = 0; X  0); }
    }
}


And here are the two helper functions.

bool Inside(ivec3 Position, ivec3 Min, ivec3 Max)
{
    if(Position.x  Max.x || Position.y > Max.y || Position.z > Max.z) return false;
    return true;
}

ivec3 Shift(int Dimension, ivec3 Vector)
{
    if      (Dimension % 3 == 1) return ivec3(Vector.z, Vector.x, Vector.y);
    else if (Dimension % 3 == 2) return ivec3(Vector.y, Vector.z, Vector.x);
    else                         return Vector;
}


As you can see, the algorithm uses a goto statement to skip faces which adjacent blocks first, are inside the world bounds and second, are not filled with air. Those faces shouldn't be generated since they are not visible to the player.

How can I restructure the statement to not use goto anymore?

Solution

First of all, the way you're formatting your code is horribly confusing.

if(Inside(neigh, ivec3(0), ivec3(SIZE) - 1))
    if(data[neigh.x][neigh.y][neigh.z])
        goto skip;

{
    ...
}


The block here looks a lot like it's in the if condition but it's not (it's just a C-like block without any condition attached to it). I really suggest using braces for your ifs to avoid confusion. Another confusing part is for(int dim = 0; dim < 3; ++dim) { int dir = -1; do {: when I see a for loop, I don't expect to see another loop at the end of it.

Now, about your question. Some languages (such as Java) support naming loop, which allows you to break to outer loops. This doesn't exist in C++, and the best option is to use a goto.

Code Snippets

if(Inside(neigh, ivec3(0), ivec3(SIZE) - 1))
    if(data[neigh.x][neigh.y][neigh.z])
        goto skip;

{
    ...
}

Context

StackExchange Code Review Q#26363, answer score: 3

Revisions (0)

No revisions yet.