From 2f220aa2a5f5c64e0ceebb42d7bbf99914b71dbd Mon Sep 17 00:00:00 2001 From: Victor Giers Date: Sat, 2 May 2026 04:22:36 +0200 Subject: [PATCH] Add tests for foliage mask serialization and migration --- .../serialization/scene-document-json.test.ts | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/tests/serialization/scene-document-json.test.ts b/tests/serialization/scene-document-json.test.ts index a3e8c0ad..d4dcee72 100644 --- a/tests/serialization/scene-document-json.test.ts +++ b/tests/serialization/scene-document-json.test.ts @@ -160,6 +160,38 @@ describe("scene document JSON", () => { ); }); + it("round-trips terrain foliage masks for authored foliage layers", () => { + const bundledPrototype = BUNDLED_FOLIAGE_PROTOTYPES[0]; + const layer = createFoliageLayer({ + id: "foliage-layer-mask-roundtrip", + name: "Mask Roundtrip", + prototypeIds: [bundledPrototype.id] + }); + const terrain = createTerrain({ + id: "terrain-foliage-mask-roundtrip", + sampleCountX: 2, + sampleCountZ: 2, + foliageMasks: { + [layer.id]: createTerrainFoliageMask({ + layerId: layer.id, + resolutionX: 2, + resolutionZ: 2, + values: [0, 0.25, 0.5, 1] + }) + } + }); + const document = createEmptySceneDocument({ + name: "Foliage Mask Scene" + }); + + document.foliageLayers[layer.id] = layer; + document.terrains[terrain.id] = terrain; + + expect(parseSceneDocumentJson(serializeSceneDocument(document))).toEqual( + document + ); + }); + it("migrates pre-foliage scene documents with empty foliage state", () => { const document = createEmptySceneDocument({ name: "Legacy Foliage-Free Scene" @@ -181,6 +213,33 @@ describe("scene document JSON", () => { expect(migratedDocument.foliageLayers).toEqual({}); }); + it("migrates pre-foliage-mask terrain documents with empty terrain foliage masks", () => { + const terrain = createTerrain({ + id: "terrain-pre-foliage-mask", + sampleCountX: 2, + sampleCountZ: 2 + }); + const document = createEmptySceneDocument({ + name: "Legacy Terrain Mask-Free Scene" + }); + document.terrains[terrain.id] = terrain; + const legacyDocument = JSON.parse( + serializeSceneDocument(document) + ) as Record; + + legacyDocument.version = FOLIAGE_FOUNDATION_SCENE_DOCUMENT_VERSION; + delete ((legacyDocument.terrains as Record>)[ + terrain.id + ] as Record).foliageMasks; + + const migratedDocument = parseSceneDocumentJson( + JSON.stringify(legacyDocument) + ); + + expect(migratedDocument.version).toBe(SCENE_DOCUMENT_VERSION); + expect(migratedDocument.terrains[terrain.id]?.foliageMasks).toEqual({}); + }); + it("round-trips camera rig control effects in interaction links, sequences, and scheduler routines", () => { const cameraRig = createCameraRigEntity({ id: "entity-camera-rig-main",