Improve asset deletion to clean up references to removed foliage prototypes
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import type { ProjectDocument, ProjectScene } from "../document/scene-document";
|
import type { ProjectDocument, ProjectScene } from "../document/scene-document";
|
||||||
import { createDefaultWorldSettings } from "../document/world-settings";
|
import { createDefaultWorldSettings } from "../document/world-settings";
|
||||||
|
import { foliagePrototypeReferencesProjectAsset } from "../foliage/foliage";
|
||||||
|
|
||||||
import type { ProjectAssetRecord } from "./project-assets";
|
import type { ProjectAssetRecord } from "./project-assets";
|
||||||
|
|
||||||
@@ -69,11 +70,13 @@ function removeInvalidatedInteractionLinks(
|
|||||||
|
|
||||||
function cleanupSceneForDeletedAsset(
|
function cleanupSceneForDeletedAsset(
|
||||||
scene: ProjectScene,
|
scene: ProjectScene,
|
||||||
asset: ProjectAssetRecord
|
asset: ProjectAssetRecord,
|
||||||
|
removedFoliagePrototypeIds: ReadonlySet<string>
|
||||||
): ProjectScene {
|
): ProjectScene {
|
||||||
let nextWorld = scene.world;
|
let nextWorld = scene.world;
|
||||||
let nextModelInstances = scene.modelInstances;
|
let nextModelInstances = scene.modelInstances;
|
||||||
let nextEntities = scene.entities;
|
let nextEntities = scene.entities;
|
||||||
|
let nextFoliageLayers = scene.foliageLayers;
|
||||||
const removedModelInstanceIds = new Set<string>();
|
const removedModelInstanceIds = new Set<string>();
|
||||||
const silencedSoundEmitterIds = new Set<string>();
|
const silencedSoundEmitterIds = new Set<string>();
|
||||||
|
|
||||||
@@ -185,10 +188,37 @@ function cleanupSceneForDeletedAsset(
|
|||||||
silencedSoundEmitterIds
|
silencedSoundEmitterIds
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (removedFoliagePrototypeIds.size > 0) {
|
||||||
|
const updatedFoliageLayers: ProjectScene["foliageLayers"] = {};
|
||||||
|
let didChangeFoliageLayers = false;
|
||||||
|
|
||||||
|
for (const [layerId, layer] of Object.entries(scene.foliageLayers)) {
|
||||||
|
const nextPrototypeIds = layer.prototypeIds.filter(
|
||||||
|
(prototypeId) => !removedFoliagePrototypeIds.has(prototypeId)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (nextPrototypeIds.length !== layer.prototypeIds.length) {
|
||||||
|
updatedFoliageLayers[layerId] = {
|
||||||
|
...layer,
|
||||||
|
prototypeIds: nextPrototypeIds
|
||||||
|
};
|
||||||
|
didChangeFoliageLayers = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
updatedFoliageLayers[layerId] = layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (didChangeFoliageLayers) {
|
||||||
|
nextFoliageLayers = updatedFoliageLayers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
nextWorld === scene.world &&
|
nextWorld === scene.world &&
|
||||||
nextModelInstances === scene.modelInstances &&
|
nextModelInstances === scene.modelInstances &&
|
||||||
nextEntities === scene.entities &&
|
nextEntities === scene.entities &&
|
||||||
|
nextFoliageLayers === scene.foliageLayers &&
|
||||||
nextInteractionLinks === scene.interactionLinks
|
nextInteractionLinks === scene.interactionLinks
|
||||||
) {
|
) {
|
||||||
return scene;
|
return scene;
|
||||||
@@ -199,10 +229,46 @@ function cleanupSceneForDeletedAsset(
|
|||||||
world: nextWorld,
|
world: nextWorld,
|
||||||
modelInstances: nextModelInstances,
|
modelInstances: nextModelInstances,
|
||||||
entities: nextEntities,
|
entities: nextEntities,
|
||||||
|
foliageLayers: nextFoliageLayers,
|
||||||
interactionLinks: nextInteractionLinks
|
interactionLinks: nextInteractionLinks
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cleanupFoliagePrototypesForDeletedAsset(
|
||||||
|
foliagePrototypes: ProjectDocument["foliagePrototypes"],
|
||||||
|
asset: ProjectAssetRecord
|
||||||
|
): {
|
||||||
|
foliagePrototypes: ProjectDocument["foliagePrototypes"];
|
||||||
|
removedFoliagePrototypeIds: ReadonlySet<string>;
|
||||||
|
} {
|
||||||
|
if (asset.kind !== "model") {
|
||||||
|
return {
|
||||||
|
foliagePrototypes,
|
||||||
|
removedFoliagePrototypeIds: new Set()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextFoliagePrototypes: ProjectDocument["foliagePrototypes"] = {};
|
||||||
|
const removedFoliagePrototypeIds = new Set<string>();
|
||||||
|
|
||||||
|
for (const [prototypeId, prototype] of Object.entries(foliagePrototypes)) {
|
||||||
|
if (foliagePrototypeReferencesProjectAsset(prototype, asset.id)) {
|
||||||
|
removedFoliagePrototypeIds.add(prototypeId);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextFoliagePrototypes[prototypeId] = prototype;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
foliagePrototypes:
|
||||||
|
removedFoliagePrototypeIds.size > 0
|
||||||
|
? nextFoliagePrototypes
|
||||||
|
: foliagePrototypes,
|
||||||
|
removedFoliagePrototypeIds
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function deleteProjectAssetFromProjectDocument(
|
export function deleteProjectAssetFromProjectDocument(
|
||||||
projectDocument: ProjectDocument,
|
projectDocument: ProjectDocument,
|
||||||
assetId: string
|
assetId: string
|
||||||
@@ -218,11 +284,19 @@ export function deleteProjectAssetFromProjectDocument(
|
|||||||
};
|
};
|
||||||
delete nextAssets[assetId];
|
delete nextAssets[assetId];
|
||||||
|
|
||||||
|
const foliageCleanup = cleanupFoliagePrototypesForDeletedAsset(
|
||||||
|
projectDocument.foliagePrototypes,
|
||||||
|
asset
|
||||||
|
);
|
||||||
const nextScenes: ProjectDocument["scenes"] = {};
|
const nextScenes: ProjectDocument["scenes"] = {};
|
||||||
let didChangeScenes = false;
|
let didChangeScenes = false;
|
||||||
|
|
||||||
for (const [sceneId, scene] of Object.entries(projectDocument.scenes)) {
|
for (const [sceneId, scene] of Object.entries(projectDocument.scenes)) {
|
||||||
const nextScene = cleanupSceneForDeletedAsset(scene, asset);
|
const nextScene = cleanupSceneForDeletedAsset(
|
||||||
|
scene,
|
||||||
|
asset,
|
||||||
|
foliageCleanup.removedFoliagePrototypeIds
|
||||||
|
);
|
||||||
nextScenes[sceneId] = nextScene;
|
nextScenes[sceneId] = nextScene;
|
||||||
didChangeScenes ||= nextScene !== scene;
|
didChangeScenes ||= nextScene !== scene;
|
||||||
}
|
}
|
||||||
@@ -230,6 +304,7 @@ export function deleteProjectAssetFromProjectDocument(
|
|||||||
return {
|
return {
|
||||||
...projectDocument,
|
...projectDocument,
|
||||||
assets: nextAssets,
|
assets: nextAssets,
|
||||||
|
foliagePrototypes: foliageCleanup.foliagePrototypes,
|
||||||
scenes: didChangeScenes ? nextScenes : projectDocument.scenes
|
scenes: didChangeScenes ? nextScenes : projectDocument.scenes
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user