c# – Creating Sphere Triangles from Vertices

First up, our triangle count is…

 int numTriangles = numLatitudeLines * numLongitudeLines * 2;

(That’s a middle section of (numLatitudeLines - 1) * numLongitudeLines quads, doubled to two triangles each, and a row of numLongitudeLines triangles around each pole)

Triple that to get our ultimate count of vertex copies:

Vertex() vertices = new Vertex(numTriangles * 3);

Now we can fill this in row by row. The first row of triangles all start at position 0 (the north pole), and connect two consecutive vertex positions from the top latitude line:

int v = 0;

for (int i = 0; i < numLongitudeLines; i++) {
    vertices(v++) = new Vertex(positions(0));
    vertices(v++) = new Vertex(positions(i + 2));
    vertices(v++) = new Vertex(positions(i + 1));
}

I’m not quite sure what coordinate system you’re using, so you might need to exchange the order of two of those lines to flip the winding of the triangle to ensure it faces outward. The same trick works for the other triangle triplets below.

Next, we can connect up the large rectangular section in the middle, by iterating over each row and column.

// Each row has one more unique vertex than there are lines of longitude,
// since we double a vertex at the texture seam.
int rowLength = numLongitudeLines +1;

for (int latitude = 0; latitude < numLatitudeLines - 1; latitude++) {
    // Plus one for the pole.
    int rowStart = latitude * rowLength + 1;
    for (int longitude = 0; longitude < numLongitudeLines; longitude++) {        
        int firstCorner = rowStart + longitude;

        // First triangle of quad: Top-Left, Bottom-Left, Bottom-Right
        vertices(v++) = new Vertex(positions(firstCorner);
        vertices(v++) = new Vertex(positions(firstCorner + rowLength + 1));
        vertices(v++) = new Vertex(positions(firstCorner + rowLength));

        // Second triangle of quad: Top-Left, Bottom-Right, Top-Right
        vertices(v++) = new Vertex(positions(firstCorner);
        vertices(v++) = new Vertex(positions(firstCorner + 1));
        vertices(v++) = new Vertex(positions(firstCorner + rowLength + 1));
    }
}

And then we finish off with the same loop as we started, but this time for the south pole.

int pole = positions.Length - 1;
int bottomRow = (numLatitudeLines - 1) * rowLength + 1;

for (int i = 0; i < numLongitudeLines; i++) {
    vertices(v++) = new Vertex(positions(pole));
    vertices(v++) = new Vertex(positions(bottomRow + i));
    vertices(v++) = new Vertex(positions(bottomRow + i + 1));
}