fix(core): LandblockMesh keys atlas lookup on TerrainInfo.Type

Task 1's subagent used the raw ushort as the map key because the test
used raw ushort 7 as the value. But the atlas map is built from
Region.TerrainInfo.LandSurfaces.TexMerge.TerrainDesc which keys on
TerrainTextureType enum values, extracted from bits 2-6 of the
TerrainInfo ushort per DatReaderWriter's Types/TerrainInfo.cs.

Reverts to using block.Terrain[hi].Type so the Task 2 TerrainAtlas can
actually find matching keys against real dat terrain. The test is
updated to encode Type=7 correctly as (7 << 2) in the raw ushort.
This commit is contained in:
Erik 2026-04-10 20:18:09 +02:00
parent 324abed6eb
commit 78ce099440
2 changed files with 13 additions and 10 deletions

View file

@ -34,10 +34,11 @@ public static class LandblockMesh
float height = heightTable[block.Height[hi]]; float height = heightTable[block.Height[hi]];
// TerrainInfo raw ushort value used as the atlas-layer map key. // TerrainInfo is bit-packed: bits 0-1 Road, bits 2-6 Type (5-bit
// The map is keyed on the raw terrain ushort (which encodes Road, // TerrainTextureType enum), bits 11-15 Scenery. The atlas keys on
// Type, and Scenery fields), matching what the test and caller supply. // Type only, matching Region.TerrainInfo.LandSurfaces.TexMerge.TerrainDesc
uint terrainType = (ushort)block.Terrain[hi]; // which lists SurfaceTexture ids per TerrainTextureType.
uint terrainType = (uint)block.Terrain[hi].Type;
if (!terrainTypeToLayer.TryGetValue(terrainType, out var layer)) if (!terrainTypeToLayer.TryGetValue(terrainType, out var layer))
layer = 0; layer = 0;

View file

@ -89,15 +89,17 @@ public class LandblockMeshTests
public void Build_PerVertexTerrainLayer_UsesMappedLayerIndex() public void Build_PerVertexTerrainLayer_UsesMappedLayerIndex()
{ {
var block = BuildFlatLandBlock(); var block = BuildFlatLandBlock();
// TerrainInfo is a struct with implicit conversion from ushort. The low 5 bits // TerrainInfo is bit-packed: bits 0-1 Road, bits 2-6 Type, bits 11-15 Scenery.
// of the ushort encode TerrainTextureType via TerrainInfo.Type. // Raw ushort 0x001C = binary 0011100 → Type field = 7 (bits 2-6).
// Set vertex at x-major index (x=2, y=3) to terrain type 7. // This is what a terrain sample with TerrainTextureType=7 looks like in the
block.Terrain[2 * 9 + 3] = (ushort)7; // low 5 bits = 7 // underlying byte stream. LandblockMesh uses TerrainInfo.Type (not raw) as
// the atlas lookup key.
block.Terrain[2 * 9 + 3] = (ushort)(7 << 2); // Type=7, Road=0, Scenery=0
var map = new Dictionary<uint, uint> var map = new Dictionary<uint, uint>
{ {
[0] = 0u, // default type → atlas layer 0 [0] = 0u, // default type → atlas layer 0
[7] = 4u, // type 7 → atlas layer 4 [7] = 4u, // TerrainTextureType 7 → atlas layer 4
}; };
var mesh = LandblockMesh.Build(block, IdentityHeightTable, map); var mesh = LandblockMesh.Build(block, IdentityHeightTable, map);
@ -105,7 +107,7 @@ public class LandblockMeshTests
// Vertex buffer internal order is y*9+x, so vertex at world (x=2, y=3) is at // Vertex buffer internal order is y*9+x, so vertex at world (x=2, y=3) is at
// index 3*9+2 = 29. // index 3*9+2 = 29.
Assert.Equal(4u, mesh.Vertices[3 * 9 + 2].TerrainLayer); Assert.Equal(4u, mesh.Vertices[3 * 9 + 2].TerrainLayer);
// An untouched vertex still has type 0, maps to layer 0. // An untouched vertex still has Type 0, maps to layer 0.
Assert.Equal(0u, mesh.Vertices[0].TerrainLayer); Assert.Equal(0u, mesh.Vertices[0].TerrainLayer);
} }