Meshing algorithm for generating faces in Minecraft 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&lt;float&gt; positions, normals, texcoords;
vector&lt;unsigned int&gt; elements;


This is the algorithm:

int n = 0;
for(int X = 0; X &lt; SIZE; ++X)
for(int Y = 0; Y &lt; SIZE; ++Y)
for(int Z = 0; Z &lt; SIZE; ++Z)
{
    if(data[X][Y][Z])
    {
        uint8_t tile = clamp((int)data[X][Y][Z], 0, TILES_U * TILES_V - 1);
        for(int dim = 0; dim &lt; 3; ++dim) { int dir = -1; do {
            ivec3 neigh = Shift(dim, ivec3(dir, 0, 0)) + ivec3(X, Y, Z);

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

            {
                for(float i = 0; i &lt;= 1; ++i)
                for(float j = 0; j &lt;= 1; ++j)
                {
                    vec3 vertex = vec3(X, Y, Z) + vec3(Shift(dim, ivec3((dir+1)/2, i, j)));
                    positions.push_back(vertex.x); positions.push_back(vertex.y); positions.push_back(vertex.z);
                }

                /*
                 * the normal vector is not important for this question
                 *
                 * vec3 normal = normalize(vec3(Shift(dim, ivec3(dir, 0, 0))));
                 * for(int i = 0; i &lt; 4; ++i)
                 * {
                 *  normals.push_back(normal.x); normals.push_back(normal.y); normals.push_back(normal.z);
                 * }
                 */

                /*
                 * texture coordinates are not important for this question
                 *
                 * vec2 coords(tile % TILES_U, tile / TILES_U);
                 * vec2 position = coords * GRID;
                 * texcoords.push_back(position.x          + GAP); texcoords.push_back(position.y          + GAP);
                 * texcoords.push_back(position.x + GRID.x - GAP); texcoords.push_back(position.y          + GAP);
                 * texcoords.push_back(position.x          + GAP); texcoords.push_back(position.y + GRID.y - GAP);
                 * texcoords.push_back(position.x + GRID.x - GAP); texcoords.push_back(position.y + GRID.y - GAP);
                 */

                if(dir == -1) {
                    elements.push_back(n+0); elements.push_back(n+1); elements.push_back(n+2);
                    elements.push_back(n+1); elements.push_back(n+3); elements.push_back(n+2);
                } else {
                    elements.push_back(n+0); elements.push_back(n+2); elements.push_back(n+1);
                    elements.push_back(n+1); elements.push_back(n+2); elements.push_back(n+3);
                }
                n += 4;
            }

        skip: dir *= -1; } while(dir &gt; 0); }
    }
}


And here are the two helper functions.

bool Inside(ivec3 Position, ivec3 Min, ivec3 Max)
{
    if(Position.x &lt; Min.x || Position.y &lt; Min.y || Position.z &lt; Min.z) return false;
    if(Position.x &gt; Max.x || Position.y &gt; Max.y || Position.z &gt; 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?
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 &lt; 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.