45 lines
2 KiB
C#
45 lines
2 KiB
C#
using System;
|
|
using System.Linq;
|
|
|
|
namespace CultMath;
|
|
|
|
public readonly record struct PlanetaryPatchVertex(float2 LocalCoordinate, float3 UnitDirection);
|
|
|
|
public readonly record struct PlanetaryPatchMesh(
|
|
PlanetaryCubeFace Face,
|
|
int CellsPerAxis,
|
|
PlanetaryPatchVertex[] Vertices,
|
|
int[] Indices);
|
|
|
|
public static class PlanetaryPatch
|
|
{
|
|
public static PlanetaryPatchMesh CreateFace(PlanetaryCubeFace face, int cellsPerAxis)
|
|
{
|
|
if (!Enum.IsDefined(typeof(PlanetaryCubeFace), face)) throw new ArgumentOutOfRangeException(nameof(face));
|
|
if (cellsPerAxis < 1 || cellsPerAxis > 4096) throw new ArgumentOutOfRangeException(nameof(cellsPerAxis));
|
|
var axisVertices = cellsPerAxis + 1;
|
|
var vertices = new PlanetaryPatchVertex[checked(axisVertices * axisVertices)];
|
|
for (var y = 0; y < axisVertices; y++)
|
|
for (var x = 0; x < axisVertices; x++)
|
|
{
|
|
var local = new float2(x / (float)cellsPerAxis, y / (float)cellsPerAxis);
|
|
vertices[y * axisVertices + x] = new(local, PlanetaryTopology.Direction(new(face, local.x * 2 - 1, local.y * 2 - 1)));
|
|
}
|
|
var indices = new int[checked(cellsPerAxis * cellsPerAxis * 6)];
|
|
var write = 0;
|
|
for (var y = 0; y < cellsPerAxis; y++)
|
|
for (var x = 0; x < cellsPerAxis; x++)
|
|
{
|
|
var lowerLeft = y * axisVertices + x;
|
|
var lowerRight = lowerLeft + 1;
|
|
var upperLeft = lowerLeft + axisVertices;
|
|
var upperRight = upperLeft + 1;
|
|
indices[write++] = lowerLeft; indices[write++] = lowerRight; indices[write++] = upperRight;
|
|
indices[write++] = lowerLeft; indices[write++] = upperRight; indices[write++] = upperLeft;
|
|
}
|
|
return new(face, cellsPerAxis, vertices, indices);
|
|
}
|
|
|
|
public static PlanetaryPatchMesh[] CreateCubeSphere(int cellsPerAxis)
|
|
=> ((PlanetaryCubeFace[])Enum.GetValues(typeof(PlanetaryCubeFace))).Select(face => CreateFace(face, cellsPerAxis)).ToArray();
|
|
}
|