diff --git a/packages/dev/core/src/assetContainer.ts b/packages/dev/core/src/assetContainer.ts index 56f2f527e8e..470304875ab 100644 --- a/packages/dev/core/src/assetContainer.ts +++ b/packages/dev/core/src/assetContainer.ts @@ -5,7 +5,7 @@ import { TransformNode } from "./Meshes/transformNode"; import type { Skeleton } from "./Bones/skeleton"; import type { AnimationGroup } from "./Animations/animationGroup"; import type { Animatable } from "./Animations/animatable"; -import type { AbstractMesh } from "./Meshes/abstractMesh"; +import { AbstractMesh } from "./Meshes/abstractMesh"; import type { MultiMaterial } from "./Materials/multiMaterial"; import type { Material } from "./Materials/material"; import { Logger } from "./Misc/logger"; @@ -694,7 +694,7 @@ export class AssetContainer extends AbstractScene { if (predicate && !predicate(o)) { return; } - this.scene.removeMesh(o); + this.scene.removeMesh(o, true); }); this.skeletons.forEach((o) => { if (predicate && !predicate(o)) { @@ -1050,4 +1050,66 @@ export class AssetContainer extends AbstractScene { } }); } + + /** + * @since + * Given a root asset, this method will traverse its hierarchy and add it, its children and any materials/skeletons/animation groups to the container. + * @param root + */ + public addAllAssetsToContainer(root: Node) { + if (!root) { + return; + } + + const nodesToVisit = new Array(); + const visitedNodes = new Set(); + + nodesToVisit.push(root); + + while (nodesToVisit.length > 0) { + const nodeToVisit = nodesToVisit.pop()!; + + if (nodeToVisit instanceof Mesh) { + if (nodeToVisit.geometry && this.geometries.indexOf(nodeToVisit.geometry) === -1) { + this.geometries.push(nodeToVisit.geometry); + } + this.meshes.push(nodeToVisit); + } else if (nodeToVisit instanceof TransformNode) { + this.transformNodes.push(nodeToVisit); + } else if (nodeToVisit instanceof Light) { + this.lights.push(nodeToVisit); + } else if (nodeToVisit instanceof Camera) { + this.cameras.push(nodeToVisit); + } + + if (nodeToVisit instanceof AbstractMesh) { + if (nodeToVisit.material && this.materials.indexOf(nodeToVisit.material) === -1) { + this.materials.push(nodeToVisit.material); + for (const texture of nodeToVisit.material.getActiveTextures()) { + if (this.textures.indexOf(texture) === -1) { + this.textures.push(texture); + } + } + } + + if (nodeToVisit.skeleton && this.skeletons.indexOf(nodeToVisit.skeleton) === -1) { + this.skeletons.push(nodeToVisit.skeleton); + } + + if (nodeToVisit.morphTargetManager && this.morphTargetManagers.indexOf(nodeToVisit.morphTargetManager) === -1) { + this.morphTargetManagers.push(nodeToVisit.morphTargetManager); + } + } + + for (const child of nodeToVisit.getChildren()) { + if (!visitedNodes.has(child)) { + nodesToVisit.push(child); + } + } + + visitedNodes.add(nodeToVisit); + } + + this.populateRootNodes(); + } }