public static MeshData CreateGeosphere(float radius, SubdivisionCount numSubdivisions) {
var tempMesh = new MeshData {
Vertices = IcosahedronVertices.Select(p => new Vertex { Position = p }).ToList(),
Indices = IcosahedronIndices
};
var mh = new Subdivider();
for (var i = 0; i < (int)numSubdivisions; i++) {
mh.Subdivide4(tempMesh);
}
// Project vertices onto sphere and scale.
for (var i = 0; i < tempMesh.Vertices.Count; i++) {
// Project onto unit sphere.
var n = Vector3.Normalize(tempMesh.Vertices[i].Position);
// Project onto sphere.
var p = radius * n;
// Derive texture coordinates from spherical coordinates.
var theta = MathF.AngleFromXY(tempMesh.Vertices[i].Position.X, tempMesh.Vertices[i].Position.Z);
var phi = MathF.Acos(tempMesh.Vertices[i].Position.Y / radius);
var texC = new Vector2(theta / (2 * MathF.PI), phi / MathF.PI);
// Partial derivative of P with respect to theta
var tangent = new Vector3(
-radius * MathF.Sin(phi) * MathF.Sin(theta),
0,
radius * MathF.Sin(phi) * MathF.Cos(theta)
);
tangent.Normalize();
tempMesh.Vertices[i] = new Vertex(p, n, tangent, texC);
}
return tempMesh;
}