From 1f1af492f66212ce6a7db52ff975edebec583071 Mon Sep 17 00:00:00 2001 From: Victor Giers Date: Wed, 13 May 2026 00:51:06 +0200 Subject: [PATCH] Add tests for terrain layer manipulation (add/remove layers) --- tests/domain/terrains.test.ts | 70 +++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/tests/domain/terrains.test.ts b/tests/domain/terrains.test.ts index a509dd40..9b44c455 100644 --- a/tests/domain/terrains.test.ts +++ b/tests/domain/terrains.test.ts @@ -8,6 +8,8 @@ import { getTerrainFoliageMask, getTerrainFoliageMaskValueAtSample, getTerrainPaintWeightSampleOffset, + createTerrainWithAddedLayer, + createTerrainWithRemovedLayer, sampleTerrainFoliageBlockerMaskAtWorldPosition, sampleTerrainFoliageMaskAtWorldPosition, updateTerrainBoundsCacheAfterHeightPatch, @@ -92,6 +94,74 @@ describe("terrain grid resizing", () => { }); }); +describe("terrain material layers", () => { + it("adds a layer by expanding compact paint weights with zero influence", () => { + const terrain = createTerrain({ + id: "terrain-add-layer", + sampleCountX: 2, + sampleCountZ: 2, + paintWeights: [ + 0.2, + 0.3, + 0.1, + 0.4, + 0.1, + 0, + 0, + 0.5, + 0, + 0.25, + 0.25, + 0.25 + ] + }); + + const nextTerrain = createTerrainWithAddedLayer(terrain, "road-material"); + const firstSampleOffset = getTerrainPaintWeightSampleOffset( + nextTerrain, + 0, + 0 + ); + const secondSampleOffset = getTerrainPaintWeightSampleOffset( + nextTerrain, + 1, + 0 + ); + + expect(nextTerrain.layers).toHaveLength(5); + expect(nextTerrain.layers[4]).toEqual({ materialId: "road-material" }); + expect(nextTerrain.paintWeights.slice(firstSampleOffset, firstSampleOffset + 4)).toEqual([ + 0.2, + 0.3, + 0.1, + 0 + ]); + expect(nextTerrain.paintWeights.slice(secondSampleOffset, secondSampleOffset + 4)).toEqual([ + 0.4, + 0.1, + 0, + 0 + ]); + }); + + it("removes non-base layers by compacting explicit weights", () => { + const terrain = createTerrainWithAddedLayer( + createTerrain({ + id: "terrain-remove-layer", + sampleCountX: 2, + sampleCountZ: 1, + paintWeights: [0.2, 0.3, 0.1, 0.4, 0.1, 0] + }), + "fifth-material" + ); + + const nextTerrain = createTerrainWithRemovedLayer(terrain, 2); + + expect(nextTerrain.layers).toHaveLength(4); + expect(nextTerrain.paintWeights).toEqual([0.2, 0.1, 0, 0.4, 0, 0]); + }); +}); + describe("terrain foliage blocker masks", () => { it("creates, clones, normalizes, and samples blocker mask values", () => { const terrain = createTerrain({