Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public static GraphicsMesh GenerateSphere(Device device, int numLatitudeLines, int numLongitudeLines, int radius)
- {
- // One vertex at every latitude-longitude intersection,
- // plus one for the north pole and one for the south.
- // One meridian serves as a UV seam, so we double the vertices there.
- int numVertices = (numLatitudeLines * (numLongitudeLines + 1)) + 2;
- Vector3[] positions = new Vector3[numVertices];
- Vector2[] texcoords = new Vector2[numVertices]; // Not needed for me; just don't care to delete it.
- // North pole.
- positions[0] = new Vector3(0, radius, 0);
- texcoords[0] = new Vector2(0, 1);
- // South pole.
- positions[numVertices - 1] = new Vector3(0, -radius, 0);
- texcoords[numVertices - 1] = new Vector2(0, 0);
- // +1.0f because there's a gap between the poles and the first parallel.
- float latitudeSpacing = 1.0f / (numLatitudeLines + 1.0f);
- float longitudeSpacing = 1.0f / numLongitudeLines;
- // start writing new vertices at position 1
- int v = 1;
- for (int latitude = 0; latitude < numLatitudeLines; latitude++)
- {
- for (int longitude = 0; longitude <= numLongitudeLines; longitude++)
- {
- // Scale coordinates into the 0...1 texture coordinate range,
- // with north at the top (y = 1).
- texcoords[v] = new Vector2(
- longitude * longitudeSpacing,
- 1.0f - ((latitude + 1) * latitudeSpacing)
- );
- // Convert to spherical coordinates:
- // theta is a longitude angle (around the equator) in radians.
- // phi is a latitude angle (north or south of the equator).
- float theta = (float)(texcoords[v].X * 2.0f * Math.PI);
- float phi = (float)((texcoords[v].Y - 0.5f) * Math.PI);
- // This determines the radius of the ring of this line of latitude.
- // It's widest at the equator, and narrows as phi increases/decreases.
- float c = (float)Math.Cos(phi);
- // Usual formula for a vector in spherical coordinates.
- // You can exchange x & z to wind the opposite way around the sphere.
- positions[v] = new Vector3(
- (float)(c * Math.Cos(theta)),
- (float)Math.Sin(phi),
- (float)(c * Math.Sin(theta))) * radius;
- // Proceed to the next vertex.
- v++;
- }
- }
- // Convert Vertices to triangles
- int numTriangles = numLatitudeLines * numLongitudeLines * 2;
- Vertex[] vertices = new Vertex[numTriangles * 3];
- 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]);
- }
- // 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]);
- }
- }
- 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]);
- }
- return new GraphicsMesh(device, vertices);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement