public static MeshData CreateSphere(float radius, int sliceCount, int stackCount) { var ret = new MeshData(); ret.Vertices.Add(new Vertex(0, radius, 0, 0, 1, 0, 1, 0, 0, 0, 0)); var phiStep = MathF.PI / stackCount; var thetaStep = 2.0f * MathF.PI / sliceCount; for (var i = 1; i <= stackCount - 1; i++) { var phi = i * phiStep; for (var j = 0; j <= sliceCount; j++) { var theta = j * thetaStep; var p = new Vector3( (radius * MathF.Sin(phi) * MathF.Cos(theta)), (radius * MathF.Cos(phi)), (radius * MathF.Sin(phi) * MathF.Sin(theta)) ); var t = new Vector3(-radius * MathF.Sin(phi) * MathF.Sin(theta), 0, radius * MathF.Sin(phi) * MathF.Cos(theta)); t.Normalize(); var n = Vector3.Normalize(p); var uv = new Vector2(theta / (MathF.PI * 2), phi / MathF.PI); ret.Vertices.Add(new Vertex(p, n, t, uv)); } } ret.Vertices.Add(new Vertex(0, -radius, 0, 0, -1, 0, 1, 0, 0, 0, 1)); for (var i = 1; i <= sliceCount; i++) { ret.Indices.Add(0); ret.Indices.Add((ushort)(i + 1)); ret.Indices.Add((ushort)i); } var baseIndex = 1; var ringVertexCount = sliceCount + 1; for (var i = 0; i < stackCount - 2; i++) { for (var j = 0; j < sliceCount; j++) { ret.Indices.Add((ushort)(baseIndex + i * ringVertexCount + j)); ret.Indices.Add((ushort)(baseIndex + i * ringVertexCount + j + 1)); ret.Indices.Add((ushort)(baseIndex + (i + 1) * ringVertexCount + j)); ret.Indices.Add((ushort)(baseIndex + (i + 1) * ringVertexCount + j)); ret.Indices.Add((ushort)(baseIndex + i * ringVertexCount + j + 1)); ret.Indices.Add((ushort)(baseIndex + (i + 1) * ringVertexCount + j + 1)); } } var southPoleIndex = ret.Vertices.Count - 1; baseIndex = southPoleIndex - ringVertexCount; for (var i = 0; i < sliceCount; i++) { ret.Indices.Add((ushort)southPoleIndex); ret.Indices.Add((ushort)(baseIndex + i)); ret.Indices.Add((ushort)(baseIndex + i + 1)); } return(ret); }