Find "ideal way" to split tile into triangles

main
copygirl 3 months ago
parent e65a88e654
commit 397b9ac2d5
  1. 48
      terrain/Terrain.cs

@ -143,17 +143,33 @@ public partial class Terrain
AddPoint(v3, uv3); AddPoint(v3, uv3);
} }
for (var x = 0; x < Size.X; x++) { for (var x = 0; x < Size.X; x++)
for (var z = 0; z < Size.Y; z++) { for (var z = 0; z < Size.Y; z++) {
var corners = GetCornersPosition(new(x, z)); var corners = GetCornersPosition(new(x, z));
AddTriangle(corners.TopLeft , new(0.0f, 0.0f),
corners.TopRight , new(1.0f, 0.0f), // Find the "ideal way" to split the quad for the tile into two triangles.
corners.BottomLeft , new(0.0f, 1.0f)); // This is done by finding the corner with the least variance between its neighboring corners.
AddTriangle(corners.TopRight , new(1.0f, 0.0f), var sorted = corners.ToSorted((a, b) => a.Y.CompareTo(b.Y));
corners.BottomRight, new(1.0f, 1.0f), var minDiff = Abs(sorted[0].Value.Y - sorted[2].Value.Y); // Difference between lowest and 3rd lowest point.
corners.BottomLeft , new(0.0f, 1.0f)); var maxDiff = Abs(sorted[3].Value.Y - sorted[1].Value.Y); // Difference between highest and 3rd highest point.
var first = sorted[(minDiff > maxDiff) ? 0 : 3].Corner;
if (first is Corner.TopLeft or Corner.BottomRight) {
AddTriangle(corners.TopLeft , new(0.0f, 0.0f),
corners.TopRight , new(1.0f, 0.0f),
corners.BottomLeft , new(0.0f, 1.0f));
AddTriangle(corners.TopRight , new(1.0f, 0.0f),
corners.BottomRight, new(1.0f, 1.0f),
corners.BottomLeft , new(0.0f, 1.0f));
} else {
AddTriangle(corners.TopRight , new(1.0f, 0.0f),
corners.BottomRight, new(1.0f, 1.0f),
corners.TopLeft , new(0.0f, 0.0f));
AddTriangle(corners.BottomRight, new(1.0f, 1.0f),
corners.BottomLeft , new(0.0f, 1.0f),
corners.TopLeft , new(0.0f, 0.0f));
}
} }
}
mesh.SurfaceEnd(); mesh.SurfaceEnd();
mesh.SurfaceSetMaterial(0, _terrainMaterial); mesh.SurfaceSetMaterial(0, _terrainMaterial);
@ -213,7 +229,7 @@ public partial class Terrain
(T TopLeft, T TopRight, T BottomRight, T BottomLeft) (T TopLeft, T TopRight, T BottomRight, T BottomLeft)
{ {
public T this[Corner corner] { public T this[Corner corner] {
readonly get => corner switch { get => corner switch {
Corner.TopLeft => TopLeft, Corner.TopLeft => TopLeft,
Corner.TopRight => TopRight, Corner.TopRight => TopRight,
Corner.BottomRight => BottomRight, Corner.BottomRight => BottomRight,
@ -240,8 +256,20 @@ public partial class Terrain
(corner == Corner.BottomRight) ? value : BottomRight, (corner == Corner.BottomRight) ? value : BottomRight,
(corner == Corner.BottomLeft) ? value : BottomLeft); (corner == Corner.BottomLeft) ? value : BottomLeft);
public readonly T[] ToArray() public T[] ToArray()
=> [ TopLeft, TopRight, BottomRight, BottomLeft ]; => [ TopLeft, TopRight, BottomRight, BottomLeft ];
public (Corner Corner, T Value)[] ToSorted(Comparison<T> comparison)
{
var result = new (Corner Corner, T Value)[] {
(Corner.TopLeft , TopLeft ),
(Corner.TopRight , TopRight ),
(Corner.BottomRight , BottomRight),
(Corner.BottomLeft , BottomLeft ),
};
Array.Sort(result, (a, b) => comparison(a.Value, b.Value));
return result;
}
} }
} }

Loading…
Cancel
Save