feat(core): add Vertex.TerrainLayer + LandblockMesh layer map
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
bc69f0cdf1
commit
324abed6eb
7 changed files with 64 additions and 29 deletions
|
|
@ -15,6 +15,9 @@ public class LandblockMeshTests
|
|||
private static readonly float[] IdentityHeightTable =
|
||||
Enumerable.Range(0, 256).Select(i => i * 2f).ToArray();
|
||||
|
||||
private static readonly IReadOnlyDictionary<uint, uint> EmptyTerrainMap =
|
||||
new Dictionary<uint, uint>();
|
||||
|
||||
private static LandBlock BuildFlatLandBlock(byte heightIndex = 0)
|
||||
{
|
||||
var block = new LandBlock
|
||||
|
|
@ -36,7 +39,7 @@ public class LandblockMeshTests
|
|||
{
|
||||
var block = BuildFlatLandBlock();
|
||||
|
||||
var mesh = LandblockMesh.Build(block, IdentityHeightTable);
|
||||
var mesh = LandblockMesh.Build(block, IdentityHeightTable, EmptyTerrainMap);
|
||||
|
||||
Assert.Equal(81, mesh.Vertices.Length);
|
||||
Assert.Equal(128 * 3, mesh.Indices.Length);
|
||||
|
|
@ -47,7 +50,7 @@ public class LandblockMeshTests
|
|||
{
|
||||
var block = BuildFlatLandBlock();
|
||||
|
||||
var mesh = LandblockMesh.Build(block, IdentityHeightTable);
|
||||
var mesh = LandblockMesh.Build(block, IdentityHeightTable, EmptyTerrainMap);
|
||||
|
||||
var minX = mesh.Vertices.Min(v => v.Position.X);
|
||||
var maxX = mesh.Vertices.Max(v => v.Position.X);
|
||||
|
|
@ -65,7 +68,7 @@ public class LandblockMeshTests
|
|||
{
|
||||
var block = BuildFlatLandBlock(heightIndex: 10);
|
||||
|
||||
var mesh = LandblockMesh.Build(block, IdentityHeightTable);
|
||||
var mesh = LandblockMesh.Build(block, IdentityHeightTable, EmptyTerrainMap);
|
||||
|
||||
var zs = mesh.Vertices.Select(v => v.Position.Z).Distinct().ToArray();
|
||||
Assert.Single(zs);
|
||||
|
|
@ -76,12 +79,36 @@ public class LandblockMeshTests
|
|||
{
|
||||
var block = BuildFlatLandBlock(heightIndex: 5);
|
||||
|
||||
var mesh = LandblockMesh.Build(block, IdentityHeightTable);
|
||||
var mesh = LandblockMesh.Build(block, IdentityHeightTable, EmptyTerrainMap);
|
||||
|
||||
// AC's Land::LandHeightTable scales height byte index by 2.0f for the simple ramp case.
|
||||
Assert.Equal(10.0f, mesh.Vertices[0].Position.Z);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Build_PerVertexTerrainLayer_UsesMappedLayerIndex()
|
||||
{
|
||||
var block = BuildFlatLandBlock();
|
||||
// TerrainInfo is a struct with implicit conversion from ushort. The low 5 bits
|
||||
// of the ushort encode TerrainTextureType via TerrainInfo.Type.
|
||||
// Set vertex at x-major index (x=2, y=3) to terrain type 7.
|
||||
block.Terrain[2 * 9 + 3] = (ushort)7; // low 5 bits = 7
|
||||
|
||||
var map = new Dictionary<uint, uint>
|
||||
{
|
||||
[0] = 0u, // default type → atlas layer 0
|
||||
[7] = 4u, // type 7 → atlas layer 4
|
||||
};
|
||||
|
||||
var mesh = LandblockMesh.Build(block, IdentityHeightTable, map);
|
||||
|
||||
// Vertex buffer internal order is y*9+x, so vertex at world (x=2, y=3) is at
|
||||
// index 3*9+2 = 29.
|
||||
Assert.Equal(4u, mesh.Vertices[3 * 9 + 2].TerrainLayer);
|
||||
// An untouched vertex still has type 0, maps to layer 0.
|
||||
Assert.Equal(0u, mesh.Vertices[0].TerrainLayer);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Build_HeightmapPackedAsXMajor_NotYMajor()
|
||||
{
|
||||
|
|
@ -98,7 +125,7 @@ public class LandblockMeshTests
|
|||
var block = BuildFlatLandBlock();
|
||||
block.Height[2 * 9 + 0] = 5; // x=2, y=0 in x-major packing
|
||||
|
||||
var mesh = LandblockMesh.Build(block, IdentityHeightTable);
|
||||
var mesh = LandblockMesh.Build(block, IdentityHeightTable, EmptyTerrainMap);
|
||||
|
||||
// Find vertices by position. Vertex buffer uses y*9+x internally.
|
||||
var vAt_x2_y0 = mesh.Vertices[0 * 9 + 2]; // world (48, 0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue