Skip to content

Commit 049b71d

Browse files
authored
fix: fix a memory leak issue on Model.removeFromScene() API (#7)
1 parent 1920bf7 commit 049b71d

File tree

1 file changed

+34
-36
lines changed

1 file changed

+34
-36
lines changed

src/model/modelLoader.ts

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,10 @@
1717
import '@babylonjs/core/Materials/Textures/Loaders/basisTextureLoader';
1818
import '@babylonjs/core/Materials/Textures/Loaders/ktxTextureLoader';
1919
import '@babylonjs/loaders/glTF';
20-
import { AssetContainer } from '@babylonjs/core/assetContainer';
21-
import { SceneLoader } from '@babylonjs/core/Loading/sceneLoader';
20+
import { LoadAssetContainerAsync, LoadAssetContainerOptions } from '@babylonjs/core/Loading/sceneLoader';
2221
import { AbstractMesh } from '@babylonjs/core/Meshes/abstractMesh';
2322
import { IDisposable } from '@babylonjs/core/scene';
24-
import { GLTFFileLoader, GLTFLoaderAnimationStartMode } from '@babylonjs/loaders/glTF/glTFFileLoader';
23+
import { GLTFLoaderAnimationStartMode } from '@babylonjs/loaders/glTF/glTFFileLoader';
2524

2625
import { ObservableManager } from '../manager/observableManager';
2726
import { SceneManager } from '../manager/sceneManager';
@@ -74,64 +73,63 @@ export class ModelLoader implements IDisposable {
7473
throw Error('No glTF content or url provided');
7574
}
7675

77-
let rootUrl = url;
78-
let contents = '';
7976
let pluginExtension = '.glb';
8077
let isBase64 = false;
8178
let isBlobUrl = false;
8279
const extensionRegEx = /\.(glb|gltf|babylon|obj|stl)$/;
8380

8481
if (url.startsWith('data:')) {
85-
rootUrl = '';
86-
contents = url;
8782
isBase64 = true;
8883
} else if (url.startsWith('blob:')) {
8984
isBlobUrl = true;
9085
} else if (extensionRegEx.test(url.toLowerCase())) {
9186
pluginExtension = url.toLowerCase().match(extensionRegEx)?.at(0) ?? pluginExtension;
9287
}
9388

94-
SceneLoader.OnPluginActivatedObservable.addOnce(function (loader) {
95-
if (loader.name === 'gltf' && loader instanceof GLTFFileLoader) {
96-
// Use HTTP range requests to load the glTF binary (GLB) in parts.
97-
loader.useRangeRequests = !isBase64 && !isBlobUrl;
89+
const loadAssetContainerOptions: LoadAssetContainerOptions = {
90+
pluginOptions: {
91+
gltf: {
92+
// Use HTTP range requests to load the glTF binary (GLB) in parts.
93+
useRangeRequests: !isBase64 && !isBlobUrl,
94+
extensionOptions: {
95+
/* For debugging MSFT_lod extension */
96+
// MSFT_lod: {
97+
// maxLODsToLoad: 1,
98+
// },
99+
},
100+
},
101+
},
102+
pluginExtension: pluginExtension,
103+
};
104+
105+
if (disableAnimation) {
106+
loadAssetContainerOptions.pluginOptions!.gltf!.animationStartMode = GLTFLoaderAnimationStartMode.NONE;
107+
}
98108

99-
if (disableAnimation) {
100-
loader.animationStartMode = GLTFLoaderAnimationStartMode.NONE;
101-
}
109+
if (options?.targetFps) {
110+
loadAssetContainerOptions.pluginOptions!.gltf!.targetFps = options.targetFps;
111+
}
102112

103-
if (options?.targetFps) {
104-
loader.targetFps = options.targetFps;
105-
}
106-
}
107-
});
113+
/* For debugging MSFT_lod extension */
114+
// SceneLoader.OnPluginActivatedObservable.addOnce(function (loader) {
115+
// if (loader.name === 'gltf' && loader instanceof GLTFFileLoader) {
116+
// loader.loggingEnabled = true;
117+
// }
118+
// });
108119

109120
if (this._sceneManager.config.sceneConfig?.useLoadingUI) {
110121
this._sceneManager.scene.getEngine().displayLoadingUI();
111122
}
112123

113-
const sceneLoaderAsyncResult = await SceneLoader.ImportMeshAsync(
114-
'',
115-
rootUrl,
116-
contents,
117-
this._sceneManager.scene,
118-
undefined,
119-
pluginExtension,
120-
);
124+
const container = await LoadAssetContainerAsync(url, this._sceneManager.scene, loadAssetContainerOptions);
125+
126+
// Add everything from the container into the scene
127+
container.addAllToScene();
121128

122129
if (this._sceneManager.config.sceneConfig?.useLoadingUI) {
123130
this._sceneManager.scene.getEngine().hideLoadingUI();
124131
}
125132

126-
const container = new AssetContainer(this._sceneManager.scene);
127-
container.meshes = sceneLoaderAsyncResult.meshes;
128-
container.lights = sceneLoaderAsyncResult.lights;
129-
container.geometries = sceneLoaderAsyncResult.geometries;
130-
container.skeletons = sceneLoaderAsyncResult.skeletons;
131-
container.particleSystems = sceneLoaderAsyncResult.particleSystems;
132-
container.animationGroups = sceneLoaderAsyncResult.animationGroups;
133-
container.transformNodes = sceneLoaderAsyncResult.transformNodes;
134-
135133
// Avoid frustum clipping for all meshes
136134
container.meshes.forEach((mesh: AbstractMesh) => {
137135
mesh.alwaysSelectAsActiveMesh = true;

0 commit comments

Comments
 (0)