|
|
@ -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; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|