public class SphereMesh
{
public Mesh Mesh => new Mesh()
{
vertices = Vertices,
normals = Normals,
triangles = Triangles,
uv = UVs
};
public readonly Vector3[] Vertices;
public readonly Vector3[] Normals;
public readonly Vector2[] UVs;
public readonly int[] Triangles;
private readonly int latitudeLines;
private readonly int longitudeLines;
private const float PI = 3.14159265f;
public SphereMesh(Vector2Int resolution)
{
this.latitudeLines = resolution.x;
this.longitudeLines = resolution.y;
Vertices = GenerateVertices(out UVs);
Normals = GenerateNormals();
Triangles = GenerateTriangles();
}
private Vector3[] GenerateVertices(out Vector2[] uvs)
{
Vector3[] vertices = new Vector3[latitudeLines * longitudeLines];
Vector2[] nUVs = new Vector2[latitudeLines * longitudeLines];
int vertexIndex = 0;
for (int y = 0; y < latitudeLines; y++)
{
float latitude = Mathf.Lerp(-PI, PI, (float)y / (latitudeLines - 1));
for (int x = 0; x < longitudeLines; x++)
{
float longitude = Mathf.Lerp(-PI, PI, (float)x / (longitudeLines - 1));
Vector3 vertex = new()
{
x = Mathf.Cos(latitude) * Mathf.Cos(longitude),
y = Mathf.Sin(latitude),
z = Mathf.Cos(latitude) * Mathf.Sin(longitude),
};
Vector2 uv = new()
{
x = (float)x / (longitudeLines - 1),
y = (float)y / (latitudeLines - 1),
};
vertices[vertexIndex] = vertex;
nUVs[vertexIndex] = uv;
vertexIndex += 1;
}
}
uvs = nUVs;
return vertices;
}
private Vector3[] GenerateNormals()
{
Vector3[] normals = new Vector3[Vertices.Length];
for (int i = 0; i < Vertices.Length; i++)
{
normals[i] = Vertices[i];
}
return normals;
}
private int[] GenerateTriangles()
{
int triangleIndex = 0;
int[] triangles = new int[(latitudeLines - 1) * (longitudeLines - 1) * 6];
for (int y = 0; y < latitudeLines - 1; y++)
{
int offset = y * longitudeLines;
for (int x = 0; x < longitudeLines - 1; x++)
{
int index = offset + x;
triangles[triangleIndex++] = index;
triangles[triangleIndex++] = index + longitudeLines;
triangles[triangleIndex++] = index + longitudeLines + 1;
triangles[triangleIndex++] = index + longitudeLines + 1;
triangles[triangleIndex++] = index + 1;
triangles[triangleIndex++] = index;
}
}
return triangles;
}
}