diff --git a/tests/domain/terrains.test.ts b/tests/domain/terrains.test.ts index 4a4665fe..72757c7e 100644 --- a/tests/domain/terrains.test.ts +++ b/tests/domain/terrains.test.ts @@ -1,8 +1,12 @@ import { describe, expect, it } from "vitest"; import { + createTerrainFoliageMask, getTerrainBounds, + getTerrainFoliageMask, + getTerrainFoliageMaskValueAtSample, getTerrainPaintWeightSampleOffset, + sampleTerrainFoliageMaskAtWorldPosition, updateTerrainBoundsCacheAfterHeightPatch, resizeTerrainGrid, createTerrain @@ -10,6 +14,7 @@ import { describe("terrain grid resizing", () => { it("keeps terrain centered while bilinearly resampling heights and paint weights", () => { + const foliageLayerId = "foliage-layer-resample"; const terrain = createTerrain({ id: "terrain-resample-main", position: { @@ -34,7 +39,15 @@ describe("terrain grid resizing", () => { 0, 0, 0.25 - ] + ], + foliageMasks: { + [foliageLayerId]: createTerrainFoliageMask({ + layerId: foliageLayerId, + resolutionX: 2, + resolutionZ: 2, + values: [0, 1, 0, 0.5] + }) + } }); const resizedTerrain = resizeTerrainGrid(terrain, { @@ -43,6 +56,7 @@ describe("terrain grid resizing", () => { cellSize: 1 }); const centerOffset = getTerrainPaintWeightSampleOffset(resizedTerrain, 1, 1); + const resizedMask = getTerrainFoliageMask(resizedTerrain, foliageLayerId); expect(resizedTerrain.position).toEqual({ x: -0.5, @@ -55,6 +69,9 @@ describe("terrain grid resizing", () => { expect(resizedTerrain.paintWeights[centerOffset]).toBeCloseTo(0.15); expect(resizedTerrain.paintWeights[centerOffset + 1]).toBeCloseTo(0.125); expect(resizedTerrain.paintWeights[centerOffset + 2]).toBeCloseTo(0.0625); + expect(resizedMask?.resolutionX).toBe(3); + expect(resizedMask?.resolutionZ).toBe(3); + expect(resizedMask?.values[4]).toBeCloseTo(0.375); expect(terrain.position).toEqual({ x: 0, y: 1, @@ -64,6 +81,59 @@ describe("terrain grid resizing", () => { }); }); +describe("terrain foliage masks", () => { + it("creates, clones, normalizes, and samples foliage mask values", () => { + const foliageLayerId = "foliage-layer-sample"; + const terrain = createTerrain({ + id: "terrain-foliage-mask-sample", + position: { x: 10, y: 0, z: 20 }, + sampleCountX: 2, + sampleCountZ: 2, + cellSize: 2, + foliageMasks: { + [foliageLayerId]: createTerrainFoliageMask({ + layerId: foliageLayerId, + resolutionX: 2, + resolutionZ: 2, + values: [0, 1.2, -1, 0.5] + }) + } + }); + const clonedTerrain = createTerrain(terrain); + const mask = getTerrainFoliageMask(terrain, foliageLayerId); + + expect(mask).not.toBeNull(); + expect(mask?.values).toEqual([0, 1, 0, 0.5]); + expect(clonedTerrain.foliageMasks[foliageLayerId]).toEqual(mask); + expect(clonedTerrain.foliageMasks[foliageLayerId]).not.toBe(mask); + expect(getTerrainFoliageMaskValueAtSample(mask!, 1, 1)).toBe(0.5); + expect( + sampleTerrainFoliageMaskAtWorldPosition( + terrain, + foliageLayerId, + 11, + 21 + ) + ).toBeCloseTo(0.375); + expect( + sampleTerrainFoliageMaskAtWorldPosition( + terrain, + "missing-layer", + 11, + 21 + ) + ).toBe(0); + expect( + sampleTerrainFoliageMaskAtWorldPosition( + terrain, + foliageLayerId, + 99, + 99 + ) + ).toBeNull(); + }); +}); + describe("terrain bounds cache", () => { it("updates cached bounds after in-place height patches", () => { const terrain = createTerrain({