@babylonjs/core 9.12.1 → 9.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Animations/runtimeAnimation.js +11 -0
- package/Animations/runtimeAnimation.js.map +1 -1
- package/AudioV2/abstractAudio/abstractSound.d.ts +2 -1
- package/AudioV2/abstractAudio/abstractSound.js +3 -2
- package/AudioV2/abstractAudio/abstractSound.js.map +1 -1
- package/AudioV2/abstractAudio/abstractSoundInstance.d.ts +1 -1
- package/AudioV2/abstractAudio/abstractSoundInstance.js.map +1 -1
- package/AudioV2/abstractAudio/staticSound.d.ts +6 -0
- package/AudioV2/abstractAudio/staticSound.js +9 -1
- package/AudioV2/abstractAudio/staticSound.js.map +1 -1
- package/AudioV2/abstractAudio/streamingSound.d.ts +6 -0
- package/AudioV2/abstractAudio/streamingSound.js +9 -1
- package/AudioV2/abstractAudio/streamingSound.js.map +1 -1
- package/AudioV2/webAudio/webAudioStaticSound.d.ts +1 -1
- package/AudioV2/webAudio/webAudioStaticSound.js +6 -3
- package/AudioV2/webAudio/webAudioStaticSound.js.map +1 -1
- package/AudioV2/webAudio/webAudioStreamingSound.d.ts +1 -1
- package/AudioV2/webAudio/webAudioStreamingSound.js +7 -4
- package/AudioV2/webAudio/webAudioStreamingSound.js.map +1 -1
- package/Cameras/arcRotateCamera.pure.js +9 -3
- package/Cameras/arcRotateCamera.pure.js.map +1 -1
- package/Cameras/targetCamera.pure.js +18 -18
- package/Cameras/targetCamera.pure.js.map +1 -1
- package/Collisions/gpuPicker.d.ts +111 -4
- package/Collisions/gpuPicker.js +696 -119
- package/Collisions/gpuPicker.js.map +1 -1
- package/Engines/Native/nativeInterfaces.d.ts +4 -2
- package/Engines/Native/nativeInterfaces.js.map +1 -1
- package/Engines/Native/nativeRenderTargetWrapper.d.ts +3 -0
- package/Engines/Native/nativeRenderTargetWrapper.js +24 -1
- package/Engines/Native/nativeRenderTargetWrapper.js.map +1 -1
- package/Engines/WebGPU/Extensions/engine.videoTexture.pure.js +16 -3
- package/Engines/WebGPU/Extensions/engine.videoTexture.pure.js.map +1 -1
- package/Engines/abstractEngine.pure.d.ts +8 -1
- package/Engines/abstractEngine.pure.js +4 -3
- package/Engines/abstractEngine.pure.js.map +1 -1
- package/Engines/engine.d.ts +113 -0
- package/Engines/nullEngine.pure.js +5 -1
- package/Engines/nullEngine.pure.js.map +1 -1
- package/Engines/thinNativeEngine.pure.d.ts +5 -0
- package/Engines/thinNativeEngine.pure.js +158 -13
- package/Engines/thinNativeEngine.pure.js.map +1 -1
- package/FlowGraph/flowGraph.js +9 -0
- package/FlowGraph/flowGraph.js.map +1 -1
- package/FlowGraph/flowGraphDataConnection.pure.d.ts +14 -0
- package/FlowGraph/flowGraphDataConnection.pure.js +38 -1
- package/FlowGraph/flowGraphDataConnection.pure.js.map +1 -1
- package/FlowGraph/serialization.d.ts +11 -0
- package/FlowGraph/serialization.js +11 -1
- package/FlowGraph/serialization.js.map +1 -1
- package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsAccumulationTask.d.ts +2 -2
- package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsAccumulationTask.js +43 -51
- package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsAccumulationTask.js.map +1 -1
- package/FrameGraph/Tasks/Rendering/iblShadowsRendererTask.pure.d.ts +0 -1
- package/FrameGraph/Tasks/Rendering/iblShadowsRendererTask.pure.js +63 -35
- package/FrameGraph/Tasks/Rendering/iblShadowsRendererTask.pure.js.map +1 -1
- package/Lights/Clustered/clusteredLightContainer.pure.d.ts +1 -1
- package/Lights/Clustered/clusteredLightContainer.pure.js +2 -2
- package/Lights/Clustered/clusteredLightContainer.pure.js.map +1 -1
- package/Lights/areaLight.pure.js +5 -0
- package/Lights/areaLight.pure.js.map +1 -1
- package/Lights/light.d.ts +4 -2
- package/Lights/light.js +10 -4
- package/Lights/light.js.map +1 -1
- package/Lights/rectAreaLight.pure.d.ts +17 -0
- package/Lights/rectAreaLight.pure.js +67 -0
- package/Lights/rectAreaLight.pure.js.map +1 -1
- package/Loading/Plugins/babylonFileLoader.pure.js +1 -1
- package/Loading/Plugins/babylonFileLoader.pure.js.map +1 -1
- package/Loading/sceneLoader.d.ts +5 -1
- package/Loading/sceneLoader.js +298 -401
- package/Loading/sceneLoader.js.map +1 -1
- package/Materials/GaussianSplatting/gaussianSplattingGpuPickingMaterialPlugin.pure.d.ts +15 -0
- package/Materials/GaussianSplatting/gaussianSplattingGpuPickingMaterialPlugin.pure.js +34 -1
- package/Materials/GaussianSplatting/gaussianSplattingGpuPickingMaterialPlugin.pure.js.map +1 -1
- package/Materials/GaussianSplatting/gaussianSplattingMaterial.pure.d.ts +9 -0
- package/Materials/GaussianSplatting/gaussianSplattingMaterial.pure.js +26 -2
- package/Materials/GaussianSplatting/gaussianSplattingMaterial.pure.js.map +1 -1
- package/Materials/Node/Blocks/GaussianSplatting/gaussianSplattingBlock.pure.js +3 -1
- package/Materials/Node/Blocks/GaussianSplatting/gaussianSplattingBlock.pure.js.map +1 -1
- package/Materials/Textures/HTML/htmlInCanvasPolyfill.d.ts +43 -0
- package/Materials/Textures/HTML/htmlInCanvasPolyfill.js +64 -0
- package/Materials/Textures/HTML/htmlInCanvasPolyfill.js.map +1 -0
- package/Materials/Textures/HTML/htmlInteractionManager.d.ts +69 -0
- package/Materials/Textures/HTML/htmlInteractionManager.js +130 -0
- package/Materials/Textures/HTML/htmlInteractionManager.js.map +1 -0
- package/Materials/Textures/HTML/htmlRaycastInteractionManager.d.ts +84 -0
- package/Materials/Textures/HTML/htmlRaycastInteractionManager.js +246 -0
- package/Materials/Textures/HTML/htmlRaycastInteractionManager.js.map +1 -0
- package/Materials/Textures/HTML/htmlTexture.d.ts +148 -0
- package/Materials/Textures/HTML/htmlTexture.js +455 -0
- package/Materials/Textures/HTML/htmlTexture.js.map +1 -0
- package/Materials/Textures/HTML/index.d.ts +4 -0
- package/Materials/Textures/HTML/index.js +5 -0
- package/Materials/Textures/HTML/index.js.map +1 -0
- package/Materials/Textures/HTML/pure.d.ts +5 -0
- package/Materials/Textures/HTML/pure.js +6 -0
- package/Materials/Textures/HTML/pure.js.map +1 -0
- package/Materials/Textures/index.d.ts +1 -0
- package/Materials/Textures/index.js +1 -1
- package/Materials/Textures/index.js.map +1 -1
- package/Materials/Textures/pure.d.ts +1 -0
- package/Materials/Textures/pure.js +1 -0
- package/Materials/Textures/pure.js.map +1 -1
- package/Materials/Textures/videoTexture.pure.d.ts +3 -0
- package/Materials/Textures/videoTexture.pure.js +30 -0
- package/Materials/Textures/videoTexture.pure.js.map +1 -1
- package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.d.ts +36 -0
- package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js +56 -0
- package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js.map +1 -1
- package/Meshes/GaussianSplatting/gaussianSplattingSortWorker.d.ts +3 -1
- package/Meshes/GaussianSplatting/gaussianSplattingSortWorker.js +210 -48
- package/Meshes/GaussianSplatting/gaussianSplattingSortWorker.js.map +1 -1
- package/Misc/tools.pure.js +1 -1
- package/Misc/tools.pure.js.map +1 -1
- package/Rendering/IBLShadows/iblShadowsVoxelRenderer.pure.d.ts +1 -0
- package/Rendering/IBLShadows/iblShadowsVoxelRenderer.pure.js +34 -0
- package/Rendering/IBLShadows/iblShadowsVoxelRenderer.pure.js.map +1 -1
- package/Shaders/ShadersInclude/gaussianSplatting.js +1 -0
- package/Shaders/ShadersInclude/gaussianSplatting.js.map +1 -1
- package/Shaders/gaussianSplatting.fragment.js +17 -1
- package/Shaders/gaussianSplatting.fragment.js.map +1 -1
- package/Shaders/gaussianSplatting.vertex.js +1 -1
- package/Shaders/gaussianSplatting.vertex.js.map +1 -1
- package/Shaders/gaussianSplattingDepth.vertex.js +1 -1
- package/Shaders/gaussianSplattingDepth.vertex.js.map +1 -1
- package/Shaders/picking.fragment.js +39 -3
- package/Shaders/picking.fragment.js.map +1 -1
- package/ShadersWGSL/ShadersInclude/gaussianSplatting.js +3 -1
- package/ShadersWGSL/ShadersInclude/gaussianSplatting.js.map +1 -1
- package/ShadersWGSL/ShadersInclude/openpbrIblFunctions.js +4 -3
- package/ShadersWGSL/ShadersInclude/openpbrIblFunctions.js.map +1 -1
- package/ShadersWGSL/gaussianSplatting.fragment.js +14 -1
- package/ShadersWGSL/gaussianSplatting.fragment.js.map +1 -1
- package/ShadersWGSL/gaussianSplatting.vertex.js +2 -2
- package/ShadersWGSL/gaussianSplatting.vertex.js.map +1 -1
- package/ShadersWGSL/gaussianSplattingDepth.vertex.js +2 -2
- package/ShadersWGSL/gaussianSplattingDepth.vertex.js.map +1 -1
- package/ShadersWGSL/picking.fragment.js +22 -1
- package/ShadersWGSL/picking.fragment.js.map +1 -1
- package/package.json +1 -1
package/Loading/sceneLoader.js
CHANGED
|
@@ -101,11 +101,91 @@ function formatErrorMessage(fileInfo, message, exception) {
|
|
|
101
101
|
}
|
|
102
102
|
return errorMessage;
|
|
103
103
|
}
|
|
104
|
-
|
|
104
|
+
function createLoadError(fileInfo, message, exception) {
|
|
105
|
+
const errorMessage = formatErrorMessage(fileInfo, message, exception);
|
|
106
|
+
return new RuntimeError(errorMessage, ErrorCodes.SceneLoaderError, exception);
|
|
107
|
+
}
|
|
108
|
+
function getErrorMessage(error) {
|
|
109
|
+
return error instanceof Error ? error.message : String(error);
|
|
110
|
+
}
|
|
111
|
+
// Converts an error into a SceneLoader RuntimeError, leaving an already-wrapped SceneLoader error untouched
|
|
112
|
+
// so that it is not double-wrapped (which would duplicate the "Unable to load from ..." prefix).
|
|
113
|
+
function toLoadError(fileInfo, error) {
|
|
114
|
+
return error instanceof RuntimeError && error.errorCode === ErrorCodes.SceneLoaderError ? error : createLoadError(fileInfo, getErrorMessage(error), error);
|
|
115
|
+
}
|
|
116
|
+
const loadAssetContainerNotSupportedMessage = "LoadAssetContainer is not supported by this plugin. Plugin did not provide a loadAssetContainer or loadAssetContainerAsync method.";
|
|
117
|
+
// A synchronous plugin exposes the synchronous import/load methods; an asynchronous plugin exposes the *Async methods.
|
|
118
|
+
function isSyncPlugin(plugin) {
|
|
119
|
+
const candidate = plugin;
|
|
120
|
+
return !!candidate.importMesh || !!candidate.load || !!candidate.loadAssetContainer;
|
|
121
|
+
}
|
|
122
|
+
// Adapts a synchronous ISceneLoaderPlugin into an ISceneLoaderPluginAsync so that callers can use a single
|
|
123
|
+
// promise-based code path regardless of whether the underlying plugin is synchronous or asynchronous.
|
|
124
|
+
// Asynchronous plugins are returned unchanged. The synchronous plugin reports failure via an onError callback
|
|
125
|
+
// and/or a falsy return value; both are translated into a rejected promise.
|
|
126
|
+
function toAsyncPlugin(plugin, fileInfo) {
|
|
127
|
+
if (!isSyncPlugin(plugin)) {
|
|
128
|
+
return plugin;
|
|
129
|
+
}
|
|
130
|
+
const runSync = (invoke) => {
|
|
131
|
+
let pluginError;
|
|
132
|
+
const result = invoke((message, exception) => {
|
|
133
|
+
pluginError = { message, exception };
|
|
134
|
+
});
|
|
135
|
+
if (!result) {
|
|
136
|
+
throw createLoadError(fileInfo, pluginError?.message, pluginError?.exception);
|
|
137
|
+
}
|
|
138
|
+
return result;
|
|
139
|
+
};
|
|
140
|
+
return {
|
|
141
|
+
name: plugin.name,
|
|
142
|
+
extensions: plugin.extensions,
|
|
143
|
+
importMeshAsync: async (meshesNames, scene, data, rootUrl) => {
|
|
144
|
+
const meshes = [];
|
|
145
|
+
const particleSystems = [];
|
|
146
|
+
const skeletons = [];
|
|
147
|
+
runSync((onError) => plugin.importMesh(meshesNames, scene, data, rootUrl, meshes, particleSystems, skeletons, onError));
|
|
148
|
+
return { meshes, particleSystems, skeletons, animationGroups: [], transformNodes: [], geometries: [], lights: [], spriteManagers: [] };
|
|
149
|
+
},
|
|
150
|
+
loadAsync: async (scene, data, rootUrl) => {
|
|
151
|
+
runSync((onError) => plugin.load(scene, data, rootUrl, onError));
|
|
152
|
+
},
|
|
153
|
+
loadAssetContainerAsync: async (scene, data, rootUrl) => {
|
|
154
|
+
return runSync((onError) => plugin.loadAssetContainer(scene, data, rootUrl, onError));
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
// Reports a load failure to the legacy onError callback. The onError signature requires a Scene, but a scene
|
|
159
|
+
// may not be available (e.g. the error occurred before any scene was created). In that case, fall back to
|
|
160
|
+
// logging so the error handler does not throw a secondary error and mask the original failure.
|
|
161
|
+
function reportLegacyLoadError(onError, reportScene, error) {
|
|
162
|
+
const message = getErrorMessage(error);
|
|
163
|
+
if (onError && reportScene) {
|
|
164
|
+
onError(reportScene, message, error);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
Logger.Error(message);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// Wraps a user supplied progress callback so that an exception thrown by it is logged rather than
|
|
171
|
+
// aborting the entire loading operation.
|
|
172
|
+
function wrapProgress(onProgress) {
|
|
173
|
+
if (!onProgress) {
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
return (event) => {
|
|
177
|
+
try {
|
|
178
|
+
onProgress(event);
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
Logger.Warn("Error in onProgress callback: " + getErrorMessage(error));
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
async function loadDataAsync(fileInfo, scene, onProgress, pluginExtension, name, pluginOptions) {
|
|
105
186
|
const directLoad = getDirectLoad(fileInfo.url);
|
|
106
187
|
if (fileInfo.rawData && !pluginExtension) {
|
|
107
|
-
|
|
108
|
-
throw "When using ArrayBufferView to load data the file extension must be provided.";
|
|
188
|
+
throw new Error("When using ArrayBufferView to load data the file extension must be provided.");
|
|
109
189
|
}
|
|
110
190
|
const fileExtension = !directLoad && !pluginExtension ? getFilenameExtension(fileInfo.url) : "";
|
|
111
191
|
let registeredPlugin = pluginExtension
|
|
@@ -119,7 +199,6 @@ async function loadDataAsync(fileInfo, scene, onSuccess, onProgress, onError, on
|
|
|
119
199
|
const response = await _FetchAsync(fileInfo.url, { method: "HEAD", responseHeaders: ["Content-Type"] });
|
|
120
200
|
const mimeType = response.headerValues ? response.headerValues["Content-Type"] : "";
|
|
121
201
|
if (mimeType) {
|
|
122
|
-
// eslint-disable-next-line require-atomic-updates
|
|
123
202
|
registeredPlugin = getPluginForMimeType(mimeType);
|
|
124
203
|
}
|
|
125
204
|
}
|
|
@@ -134,101 +213,103 @@ async function loadDataAsync(fileInfo, scene, onSuccess, onProgress, onError, on
|
|
|
134
213
|
throw new Error(`The '${registeredPlugin.plugin.name}' plugin is disabled via the loader options passed to the loading operation.`);
|
|
135
214
|
}
|
|
136
215
|
if (fileInfo.rawData && !registeredPlugin.isBinary) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
onError("Error instantiating plugin.", error);
|
|
151
|
-
});
|
|
152
|
-
// When async factories are used, the plugin instance cannot be returned synchronously.
|
|
153
|
-
// In this case, the legacy loader functions will return null.
|
|
154
|
-
return null;
|
|
155
|
-
}
|
|
156
|
-
else {
|
|
157
|
-
callback(partialPlugin);
|
|
158
|
-
return partialPlugin;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
callback(registeredPlugin.plugin);
|
|
163
|
-
return registeredPlugin.plugin;
|
|
216
|
+
throw new Error("Loading from ArrayBufferView can not be used with plugins that don't support binary loading.");
|
|
217
|
+
}
|
|
218
|
+
// For plugin factories, the plugin is instantiated on each SceneLoader operation. This makes options handling
|
|
219
|
+
// much simpler as we can just pass the options to the factory, rather than passing options through to every possible
|
|
220
|
+
// plugin call. Given this, options are only supported for plugins that provide a factory function.
|
|
221
|
+
let plugin;
|
|
222
|
+
if (IsFactory(registeredPlugin.plugin)) {
|
|
223
|
+
const pluginFactory = registeredPlugin.plugin;
|
|
224
|
+
try {
|
|
225
|
+
// Only await when the factory is actually asynchronous, so that for synchronous factories the plugin is
|
|
226
|
+
// instantiated (and onPluginActivatedObservable is notified) synchronously within the calling load operation.
|
|
227
|
+
const createdPlugin = pluginFactory.createPlugin((pluginOptions ?? {}));
|
|
228
|
+
plugin = createdPlugin instanceof Promise ? await createdPlugin : createdPlugin;
|
|
164
229
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
if (!plugin) {
|
|
168
|
-
// eslint-disable-next-line no-throw-literal
|
|
169
|
-
throw `The loader plugin corresponding to the '${pluginExtension}' file type has not been found. If using es6, please import the plugin you wish to use before.`;
|
|
230
|
+
catch (error) {
|
|
231
|
+
throw createLoadError(fileInfo, "Error instantiating plugin.", error);
|
|
170
232
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
else {
|
|
189
|
-
onSuccess(plugin, result);
|
|
190
|
-
}
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
plugin = registeredPlugin.plugin;
|
|
236
|
+
}
|
|
237
|
+
if (!plugin) {
|
|
238
|
+
throw new Error(`The loader plugin corresponding to the '${pluginExtension}' file type has not been found. If using es6, please import the plugin you wish to use before.`);
|
|
239
|
+
}
|
|
240
|
+
onPluginActivatedObservable.notifyObservers(plugin);
|
|
241
|
+
// Check if we have a direct load url. If the plugin is registered to handle
|
|
242
|
+
// it or it's not a base64 data url, then pass it through the direct load path.
|
|
243
|
+
if (directLoad && ((plugin.canDirectLoad && plugin.canDirectLoad(fileInfo.url)) || !IsBase64DataUrl(fileInfo.url))) {
|
|
244
|
+
if (plugin.directLoad) {
|
|
245
|
+
let data;
|
|
246
|
+
try {
|
|
247
|
+
data = await plugin.directLoad(scene, directLoad);
|
|
191
248
|
}
|
|
192
|
-
|
|
193
|
-
|
|
249
|
+
catch (error) {
|
|
250
|
+
throw createLoadError(fileInfo, "Error in directLoad of _loadData: " + error, error);
|
|
194
251
|
}
|
|
195
|
-
return;
|
|
252
|
+
return { plugin, data };
|
|
196
253
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
onSuccess(plugin, data, responseURL);
|
|
204
|
-
};
|
|
254
|
+
return { plugin, data: directLoad };
|
|
255
|
+
}
|
|
256
|
+
const useArrayBuffer = registeredPlugin.isBinary;
|
|
257
|
+
return await new Promise((resolve, reject) => {
|
|
205
258
|
let request = null;
|
|
206
259
|
let pluginDisposed = false;
|
|
207
|
-
plugin.onDisposeObservable?.add(() => {
|
|
260
|
+
const onDisposeObserver = plugin.onDisposeObservable?.add(() => {
|
|
208
261
|
pluginDisposed = true;
|
|
209
262
|
if (request) {
|
|
210
263
|
request.abort();
|
|
211
264
|
request = null;
|
|
212
265
|
}
|
|
213
|
-
|
|
266
|
+
rejectAndCleanup(createLoadError(fileInfo, "Loading was aborted because the plugin was disposed."));
|
|
214
267
|
});
|
|
268
|
+
// Ensure the onDispose observer is removed once the promise settles, so observers do not accumulate across loads.
|
|
269
|
+
const cleanup = () => {
|
|
270
|
+
if (onDisposeObserver) {
|
|
271
|
+
plugin.onDisposeObservable?.remove(onDisposeObserver);
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
const resolveAndCleanup = (value) => {
|
|
275
|
+
cleanup();
|
|
276
|
+
resolve(value);
|
|
277
|
+
};
|
|
278
|
+
const rejectAndCleanup = (error) => {
|
|
279
|
+
cleanup();
|
|
280
|
+
reject(error);
|
|
281
|
+
};
|
|
282
|
+
const dataCallback = (data, responseURL) => {
|
|
283
|
+
if (scene.isDisposed) {
|
|
284
|
+
rejectAndCleanup(createLoadError(fileInfo, "Scene has been disposed"));
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
resolveAndCleanup({ plugin, data, responseURL });
|
|
288
|
+
};
|
|
215
289
|
const manifestChecked = () => {
|
|
216
290
|
if (pluginDisposed) {
|
|
217
291
|
return;
|
|
218
292
|
}
|
|
219
293
|
const errorCallback = (request, exception) => {
|
|
220
|
-
|
|
294
|
+
rejectAndCleanup(createLoadError(fileInfo, request?.statusText, exception));
|
|
221
295
|
};
|
|
222
296
|
if (!plugin.loadFile && fileInfo.rawData) {
|
|
223
|
-
|
|
224
|
-
|
|
297
|
+
rejectAndCleanup(createLoadError(fileInfo, "Plugin does not support loading ArrayBufferView."));
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
try {
|
|
301
|
+
request = plugin.loadFile
|
|
302
|
+
? plugin.loadFile(scene, fileInfo.rawData || fileInfo.file || fileInfo.url, fileInfo.rootUrl, dataCallback, onProgress, useArrayBuffer, errorCallback, name)
|
|
303
|
+
: scene._loadFile(fileInfo.file || fileInfo.url, dataCallback, onProgress, true, useArrayBuffer, errorCallback);
|
|
304
|
+
}
|
|
305
|
+
catch (error) {
|
|
306
|
+
rejectAndCleanup(createLoadError(fileInfo, undefined, error));
|
|
225
307
|
}
|
|
226
|
-
request = plugin.loadFile
|
|
227
|
-
? plugin.loadFile(scene, fileInfo.rawData || fileInfo.file || fileInfo.url, fileInfo.rootUrl, dataCallback, onProgress, useArrayBuffer, errorCallback, name)
|
|
228
|
-
: scene._loadFile(fileInfo.file || fileInfo.url, dataCallback, onProgress, true, useArrayBuffer, errorCallback);
|
|
229
308
|
};
|
|
230
309
|
const engine = scene.getEngine();
|
|
231
|
-
|
|
310
|
+
// File objects and raw data buffers are already in-memory and are not URL-backed requests, so they must
|
|
311
|
+
// not be routed through the offline (manifest/cache) provider.
|
|
312
|
+
let canUseOfflineSupport = !fileInfo.file && !fileInfo.rawData && engine.enableOfflineSupport;
|
|
232
313
|
if (canUseOfflineSupport) {
|
|
233
314
|
// Also check for exceptions
|
|
234
315
|
let exceptionFound = false;
|
|
@@ -242,7 +323,12 @@ async function loadDataAsync(fileInfo, scene, onSuccess, onProgress, onError, on
|
|
|
242
323
|
}
|
|
243
324
|
if (canUseOfflineSupport && AbstractEngine.OfflineProviderFactory) {
|
|
244
325
|
// Checking if a manifest file has been set for this scene and if offline mode has been requested
|
|
245
|
-
|
|
326
|
+
try {
|
|
327
|
+
scene.offlineProvider = AbstractEngine.OfflineProviderFactory(fileInfo.url, manifestChecked, engine.disableManifestCheck);
|
|
328
|
+
}
|
|
329
|
+
catch (error) {
|
|
330
|
+
rejectAndCleanup(createLoadError(fileInfo, undefined, error));
|
|
331
|
+
}
|
|
246
332
|
}
|
|
247
333
|
else {
|
|
248
334
|
manifestChecked();
|
|
@@ -350,120 +436,55 @@ export function GetRegisteredSceneLoaderPluginMetadata() {
|
|
|
350
436
|
*/
|
|
351
437
|
export async function ImportMeshAsync(source, scene, options) {
|
|
352
438
|
const { meshNames, rootUrl = "", onProgress, pluginExtension, name, pluginOptions } = options ?? {};
|
|
353
|
-
return await
|
|
439
|
+
return await importMeshCoreAsync(meshNames, rootUrl, source, scene, onProgress, pluginExtension, name, pluginOptions);
|
|
354
440
|
}
|
|
355
|
-
async function
|
|
441
|
+
async function importMeshCoreAsync(meshNames, rootUrl, sceneFilename = "", scene = EngineStore.LastCreatedScene, onProgress, pluginExtension, name = "", pluginOptions = {}) {
|
|
356
442
|
if (!scene) {
|
|
357
|
-
|
|
358
|
-
return null;
|
|
443
|
+
throw new Error("No scene available to import mesh to");
|
|
359
444
|
}
|
|
360
445
|
const fileInfo = GetFileInfo(rootUrl, sceneFilename);
|
|
361
446
|
if (!fileInfo) {
|
|
362
|
-
|
|
447
|
+
throw new Error("Cannot load file: a valid scene filename or root url was not provided.");
|
|
363
448
|
}
|
|
364
449
|
const loadingToken = {};
|
|
365
450
|
scene.addPendingData(loadingToken);
|
|
366
|
-
const
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
const errorHandler = (message, exception) => {
|
|
370
|
-
const errorMessage = formatErrorMessage(fileInfo, message, exception);
|
|
371
|
-
if (onError) {
|
|
372
|
-
onError(scene, errorMessage, new RuntimeError(errorMessage, ErrorCodes.SceneLoaderError, exception));
|
|
373
|
-
}
|
|
374
|
-
else {
|
|
375
|
-
Logger.Error(errorMessage);
|
|
376
|
-
// should the exception be thrown?
|
|
377
|
-
}
|
|
378
|
-
disposeHandler();
|
|
379
|
-
};
|
|
380
|
-
const progressHandler = onProgress
|
|
381
|
-
? (event) => {
|
|
382
|
-
try {
|
|
383
|
-
onProgress(event);
|
|
384
|
-
}
|
|
385
|
-
catch (e) {
|
|
386
|
-
errorHandler("Error in onProgress callback: " + e, e);
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
: undefined;
|
|
390
|
-
const successHandler = (meshes, particleSystems, skeletons, animationGroups, transformNodes, geometries, lights, spriteManagers) => {
|
|
391
|
-
scene.importedMeshesFiles.push(fileInfo.url);
|
|
392
|
-
if (onSuccess) {
|
|
393
|
-
try {
|
|
394
|
-
onSuccess(meshes, particleSystems, skeletons, animationGroups, transformNodes, geometries, lights, spriteManagers);
|
|
395
|
-
}
|
|
396
|
-
catch (e) {
|
|
397
|
-
errorHandler("Error in onSuccess callback: " + e, e);
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
scene.removePendingData(loadingToken);
|
|
401
|
-
};
|
|
402
|
-
return await loadDataAsync(fileInfo, scene, (plugin, data, responseURL) => {
|
|
451
|
+
const progressHandler = wrapProgress(onProgress);
|
|
452
|
+
try {
|
|
453
|
+
const { plugin, data, responseURL } = await loadDataAsync(fileInfo, scene, progressHandler, pluginExtension ?? null, name, pluginOptions);
|
|
403
454
|
if (plugin.rewriteRootURL) {
|
|
404
455
|
fileInfo.rootUrl = plugin.rewriteRootURL(fileInfo.rootUrl, responseURL);
|
|
405
456
|
}
|
|
406
|
-
|
|
407
|
-
const syncedPlugin = plugin;
|
|
408
|
-
const meshes = [];
|
|
409
|
-
const particleSystems = [];
|
|
410
|
-
const skeletons = [];
|
|
411
|
-
if (!syncedPlugin.importMesh(meshNames, scene, data, fileInfo.rootUrl, meshes, particleSystems, skeletons, errorHandler)) {
|
|
412
|
-
return;
|
|
413
|
-
}
|
|
414
|
-
scene.loadingPluginName = plugin.name;
|
|
415
|
-
successHandler(meshes, particleSystems, skeletons, [], [], [], [], []);
|
|
416
|
-
}
|
|
417
|
-
else {
|
|
418
|
-
const asyncedPlugin = plugin;
|
|
419
|
-
asyncedPlugin
|
|
420
|
-
.importMeshAsync(meshNames, scene, data, fileInfo.rootUrl, progressHandler, fileInfo.name)
|
|
421
|
-
// eslint-disable-next-line github/no-then
|
|
422
|
-
.then((result) => {
|
|
423
|
-
scene.loadingPluginName = plugin.name;
|
|
424
|
-
successHandler(result.meshes, result.particleSystems, result.skeletons, result.animationGroups, result.transformNodes, result.geometries, result.lights, result.spriteManagers);
|
|
425
|
-
})
|
|
426
|
-
// eslint-disable-next-line github/no-then
|
|
427
|
-
.catch((error) => {
|
|
428
|
-
errorHandler(error.message, error);
|
|
429
|
-
});
|
|
430
|
-
}
|
|
431
|
-
}, progressHandler, errorHandler, disposeHandler, pluginExtension, name, pluginOptions);
|
|
432
|
-
}
|
|
433
|
-
async function importMeshAsyncCoreAsync(meshNames, rootUrl, sceneFilename, scene, onProgress, pluginExtension, name, pluginOptions) {
|
|
434
|
-
return await new Promise((resolve, reject) => {
|
|
457
|
+
let result;
|
|
435
458
|
try {
|
|
436
|
-
|
|
437
|
-
resolve({
|
|
438
|
-
meshes: meshes,
|
|
439
|
-
particleSystems: particleSystems,
|
|
440
|
-
skeletons: skeletons,
|
|
441
|
-
animationGroups: animationGroups,
|
|
442
|
-
transformNodes: transformNodes,
|
|
443
|
-
geometries: geometries,
|
|
444
|
-
lights: lights,
|
|
445
|
-
spriteManagers: spriteManagers,
|
|
446
|
-
});
|
|
447
|
-
}, onProgress, (scene, message, exception) => {
|
|
448
|
-
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
|
|
449
|
-
reject(exception || new Error(message));
|
|
450
|
-
}, pluginExtension, name, pluginOptions
|
|
451
|
-
// eslint-disable-next-line github/no-then
|
|
452
|
-
).catch(reject);
|
|
459
|
+
result = await toAsyncPlugin(plugin, fileInfo).importMeshAsync(meshNames, scene, data, fileInfo.rootUrl, progressHandler, fileInfo.name);
|
|
453
460
|
}
|
|
454
461
|
catch (error) {
|
|
455
|
-
|
|
456
|
-
reject(error);
|
|
462
|
+
throw toLoadError(fileInfo, error);
|
|
457
463
|
}
|
|
458
|
-
|
|
464
|
+
// eslint-disable-next-line require-atomic-updates
|
|
465
|
+
scene.loadingPluginName = plugin.name;
|
|
466
|
+
scene.importedMeshesFiles.push(fileInfo.url);
|
|
467
|
+
return result;
|
|
468
|
+
}
|
|
469
|
+
finally {
|
|
470
|
+
scene.removePendingData(loadingToken);
|
|
471
|
+
}
|
|
459
472
|
}
|
|
460
473
|
// This is the core implementation of load scene
|
|
461
|
-
async function
|
|
474
|
+
async function loadSceneCoreAsync(rootUrl, sceneFilename = "", engine = EngineStore.LastCreatedEngine, onProgress, pluginExtension, name = "", pluginOptions = {}) {
|
|
462
475
|
if (!engine) {
|
|
463
|
-
|
|
464
|
-
|
|
476
|
+
throw new Error("No engine available");
|
|
477
|
+
}
|
|
478
|
+
const scene = new Scene(engine);
|
|
479
|
+
try {
|
|
480
|
+
await appendSceneCoreAsync(rootUrl, sceneFilename, scene, onProgress, pluginExtension, name, pluginOptions);
|
|
465
481
|
}
|
|
466
|
-
|
|
482
|
+
catch (error) {
|
|
483
|
+
// The scene was created here, so dispose it on failure to avoid leaking the partially loaded scene.
|
|
484
|
+
scene.dispose();
|
|
485
|
+
throw error;
|
|
486
|
+
}
|
|
487
|
+
return scene;
|
|
467
488
|
}
|
|
468
489
|
/**
|
|
469
490
|
* Load a scene
|
|
@@ -474,7 +495,7 @@ async function loadSceneImplAsync(rootUrl, sceneFilename = "", engine = EngineSt
|
|
|
474
495
|
*/
|
|
475
496
|
export async function LoadSceneAsync(source, engine, options) {
|
|
476
497
|
const { rootUrl = "", onProgress, pluginExtension, name, pluginOptions } = options ?? {};
|
|
477
|
-
return await
|
|
498
|
+
return await loadSceneCoreAsync(rootUrl, source, engine, onProgress, pluginExtension, name, pluginOptions);
|
|
478
499
|
}
|
|
479
500
|
/**
|
|
480
501
|
* Load a scene
|
|
@@ -487,33 +508,17 @@ export async function LoadSceneAsync(source, engine, options) {
|
|
|
487
508
|
export async function loadSceneAsync(source, engine, options) {
|
|
488
509
|
return await LoadSceneAsync(source, engine, options);
|
|
489
510
|
}
|
|
490
|
-
// This function is shared between the new module level loadSceneAsync and the legacy SceneLoader.LoadAsync
|
|
491
|
-
async function loadSceneSharedAsync(rootUrl, sceneFilename, engine, onProgress, pluginExtension, name, pluginOptions) {
|
|
492
|
-
return await new Promise((resolve, reject) => {
|
|
493
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
494
|
-
loadSceneImplAsync(rootUrl, sceneFilename, engine, (scene) => {
|
|
495
|
-
resolve(scene);
|
|
496
|
-
}, onProgress, (scene, message, exception) => {
|
|
497
|
-
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
|
|
498
|
-
reject(exception || new Error(message));
|
|
499
|
-
}, pluginExtension, name, pluginOptions);
|
|
500
|
-
});
|
|
501
|
-
}
|
|
502
511
|
// This is the core implementation of append scene
|
|
503
|
-
async function
|
|
512
|
+
async function appendSceneCoreAsync(rootUrl, sceneFilename = "", scene = EngineStore.LastCreatedScene, onProgress, pluginExtension, name = "", pluginOptions = {}) {
|
|
504
513
|
if (!scene) {
|
|
505
|
-
|
|
506
|
-
return null;
|
|
514
|
+
throw new Error("No scene available to append to");
|
|
507
515
|
}
|
|
508
516
|
const fileInfo = GetFileInfo(rootUrl, sceneFilename);
|
|
509
517
|
if (!fileInfo) {
|
|
510
|
-
|
|
518
|
+
throw new Error("Cannot load file: a valid scene filename or root url was not provided.");
|
|
511
519
|
}
|
|
512
520
|
const loadingToken = {};
|
|
513
521
|
scene.addPendingData(loadingToken);
|
|
514
|
-
const disposeHandler = () => {
|
|
515
|
-
scene.removePendingData(loadingToken);
|
|
516
|
-
};
|
|
517
522
|
if (SceneLoaderFlags.ShowLoadingScreen && !showingLoadingScreen) {
|
|
518
523
|
showingLoadingScreen = true;
|
|
519
524
|
scene.getEngine().displayLoadingUI();
|
|
@@ -522,62 +527,22 @@ async function appendSceneImplAsync(rootUrl, sceneFilename = "", scene = EngineS
|
|
|
522
527
|
showingLoadingScreen = false;
|
|
523
528
|
});
|
|
524
529
|
}
|
|
525
|
-
const
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
else {
|
|
531
|
-
Logger.Error(errorMessage);
|
|
532
|
-
// should the exception be thrown?
|
|
533
|
-
}
|
|
534
|
-
disposeHandler();
|
|
535
|
-
};
|
|
536
|
-
const progressHandler = onProgress
|
|
537
|
-
? (event) => {
|
|
538
|
-
try {
|
|
539
|
-
onProgress(event);
|
|
540
|
-
}
|
|
541
|
-
catch (e) {
|
|
542
|
-
errorHandler("Error in onProgress callback", e);
|
|
543
|
-
}
|
|
530
|
+
const progressHandler = wrapProgress(onProgress);
|
|
531
|
+
try {
|
|
532
|
+
const { plugin, data } = await loadDataAsync(fileInfo, scene, progressHandler, pluginExtension ?? null, name, pluginOptions);
|
|
533
|
+
try {
|
|
534
|
+
await toAsyncPlugin(plugin, fileInfo).loadAsync(scene, data, fileInfo.rootUrl, progressHandler, fileInfo.name);
|
|
544
535
|
}
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
if (onSuccess) {
|
|
548
|
-
try {
|
|
549
|
-
onSuccess(scene);
|
|
550
|
-
}
|
|
551
|
-
catch (e) {
|
|
552
|
-
errorHandler("Error in onSuccess callback", e);
|
|
553
|
-
}
|
|
536
|
+
catch (error) {
|
|
537
|
+
throw toLoadError(fileInfo, error);
|
|
554
538
|
}
|
|
539
|
+
// eslint-disable-next-line require-atomic-updates
|
|
540
|
+
scene.loadingPluginName = plugin.name;
|
|
541
|
+
return scene;
|
|
542
|
+
}
|
|
543
|
+
finally {
|
|
555
544
|
scene.removePendingData(loadingToken);
|
|
556
|
-
}
|
|
557
|
-
return await loadDataAsync(fileInfo, scene, (plugin, data) => {
|
|
558
|
-
if (plugin.load) {
|
|
559
|
-
const syncedPlugin = plugin;
|
|
560
|
-
if (!syncedPlugin.load(scene, data, fileInfo.rootUrl, errorHandler)) {
|
|
561
|
-
return;
|
|
562
|
-
}
|
|
563
|
-
scene.loadingPluginName = plugin.name;
|
|
564
|
-
successHandler();
|
|
565
|
-
}
|
|
566
|
-
else {
|
|
567
|
-
const asyncedPlugin = plugin;
|
|
568
|
-
asyncedPlugin
|
|
569
|
-
.loadAsync(scene, data, fileInfo.rootUrl, progressHandler, fileInfo.name)
|
|
570
|
-
// eslint-disable-next-line github/no-then
|
|
571
|
-
.then(() => {
|
|
572
|
-
scene.loadingPluginName = plugin.name;
|
|
573
|
-
successHandler();
|
|
574
|
-
})
|
|
575
|
-
// eslint-disable-next-line github/no-then
|
|
576
|
-
.catch((error) => {
|
|
577
|
-
errorHandler(error.message, error);
|
|
578
|
-
});
|
|
579
|
-
}
|
|
580
|
-
}, progressHandler, errorHandler, disposeHandler, pluginExtension, name, pluginOptions);
|
|
545
|
+
}
|
|
581
546
|
}
|
|
582
547
|
/**
|
|
583
548
|
* Append a scene
|
|
@@ -588,7 +553,7 @@ async function appendSceneImplAsync(rootUrl, sceneFilename = "", scene = EngineS
|
|
|
588
553
|
*/
|
|
589
554
|
export async function AppendSceneAsync(source, scene, options) {
|
|
590
555
|
const { rootUrl = "", onProgress, pluginExtension, name, pluginOptions } = options ?? {};
|
|
591
|
-
await
|
|
556
|
+
await appendSceneCoreAsync(rootUrl, source, scene, onProgress, pluginExtension, name, pluginOptions);
|
|
592
557
|
}
|
|
593
558
|
/**
|
|
594
559
|
* Append a scene
|
|
@@ -601,102 +566,39 @@ export async function AppendSceneAsync(source, scene, options) {
|
|
|
601
566
|
export async function appendSceneAsync(source, scene, options) {
|
|
602
567
|
return await AppendSceneAsync(source, scene, options);
|
|
603
568
|
}
|
|
604
|
-
// This function is shared between the new module level appendSceneAsync and the legacy SceneLoader.AppendAsync
|
|
605
|
-
async function appendSceneSharedAsync(rootUrl, sceneFilename, scene, onProgress, pluginExtension, name, pluginOptions) {
|
|
606
|
-
return await new Promise((resolve, reject) => {
|
|
607
|
-
try {
|
|
608
|
-
appendSceneImplAsync(rootUrl, sceneFilename, scene, (scene) => {
|
|
609
|
-
resolve(scene);
|
|
610
|
-
}, onProgress, (scene, message, exception) => {
|
|
611
|
-
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
|
|
612
|
-
reject(exception || new Error(message));
|
|
613
|
-
}, pluginExtension, name, pluginOptions
|
|
614
|
-
// eslint-disable-next-line github/no-then
|
|
615
|
-
).catch(reject);
|
|
616
|
-
}
|
|
617
|
-
catch (error) {
|
|
618
|
-
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
|
|
619
|
-
reject(error);
|
|
620
|
-
}
|
|
621
|
-
});
|
|
622
|
-
}
|
|
623
569
|
// This is the core implementation of load asset container
|
|
624
|
-
async function
|
|
570
|
+
async function loadAssetContainerCoreAsync(rootUrl, sceneFilename = "", scene = EngineStore.LastCreatedScene, onProgress, pluginExtension, name = "", pluginOptions = {}) {
|
|
625
571
|
if (!scene) {
|
|
626
|
-
|
|
627
|
-
return null;
|
|
572
|
+
throw new Error("No scene available to load asset container to");
|
|
628
573
|
}
|
|
629
574
|
const fileInfo = GetFileInfo(rootUrl, sceneFilename);
|
|
630
575
|
if (!fileInfo) {
|
|
631
|
-
|
|
576
|
+
throw new Error("Cannot load file: a valid scene filename or root url was not provided.");
|
|
632
577
|
}
|
|
633
578
|
const loadingToken = {};
|
|
634
579
|
scene.addPendingData(loadingToken);
|
|
635
|
-
const
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
// should the exception be thrown?
|
|
646
|
-
}
|
|
647
|
-
disposeHandler();
|
|
648
|
-
};
|
|
649
|
-
const progressHandler = onProgress
|
|
650
|
-
? (event) => {
|
|
651
|
-
try {
|
|
652
|
-
onProgress(event);
|
|
653
|
-
}
|
|
654
|
-
catch (e) {
|
|
655
|
-
errorHandler("Error in onProgress callback", e);
|
|
656
|
-
}
|
|
580
|
+
const progressHandler = wrapProgress(onProgress);
|
|
581
|
+
try {
|
|
582
|
+
const { plugin, data } = await loadDataAsync(fileInfo, scene, progressHandler, pluginExtension ?? null, name, pluginOptions);
|
|
583
|
+
const asyncPlugin = toAsyncPlugin(plugin, fileInfo);
|
|
584
|
+
if (!asyncPlugin.loadAssetContainerAsync) {
|
|
585
|
+
throw createLoadError(fileInfo, loadAssetContainerNotSupportedMessage);
|
|
586
|
+
}
|
|
587
|
+
let assetContainer;
|
|
588
|
+
try {
|
|
589
|
+
assetContainer = await asyncPlugin.loadAssetContainerAsync(scene, data, fileInfo.rootUrl, progressHandler, fileInfo.name);
|
|
657
590
|
}
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
if (onSuccess) {
|
|
661
|
-
try {
|
|
662
|
-
onSuccess(assets);
|
|
663
|
-
}
|
|
664
|
-
catch (e) {
|
|
665
|
-
errorHandler("Error in onSuccess callback", e);
|
|
666
|
-
}
|
|
591
|
+
catch (error) {
|
|
592
|
+
throw toLoadError(fileInfo, error);
|
|
667
593
|
}
|
|
594
|
+
assetContainer.populateRootNodes();
|
|
595
|
+
// eslint-disable-next-line require-atomic-updates
|
|
596
|
+
scene.loadingPluginName = plugin.name;
|
|
597
|
+
return assetContainer;
|
|
598
|
+
}
|
|
599
|
+
finally {
|
|
668
600
|
scene.removePendingData(loadingToken);
|
|
669
|
-
}
|
|
670
|
-
return await loadDataAsync(fileInfo, scene, (plugin, data) => {
|
|
671
|
-
if (plugin.loadAssetContainer) {
|
|
672
|
-
const syncedPlugin = plugin;
|
|
673
|
-
const assetContainer = syncedPlugin.loadAssetContainer(scene, data, fileInfo.rootUrl, errorHandler);
|
|
674
|
-
if (!assetContainer) {
|
|
675
|
-
return;
|
|
676
|
-
}
|
|
677
|
-
assetContainer.populateRootNodes();
|
|
678
|
-
scene.loadingPluginName = plugin.name;
|
|
679
|
-
successHandler(assetContainer);
|
|
680
|
-
}
|
|
681
|
-
else if (plugin.loadAssetContainerAsync) {
|
|
682
|
-
const asyncedPlugin = plugin;
|
|
683
|
-
asyncedPlugin
|
|
684
|
-
.loadAssetContainerAsync(scene, data, fileInfo.rootUrl, progressHandler, fileInfo.name)
|
|
685
|
-
// eslint-disable-next-line github/no-then
|
|
686
|
-
.then((assetContainer) => {
|
|
687
|
-
assetContainer.populateRootNodes();
|
|
688
|
-
scene.loadingPluginName = plugin.name;
|
|
689
|
-
successHandler(assetContainer);
|
|
690
|
-
})
|
|
691
|
-
// eslint-disable-next-line github/no-then
|
|
692
|
-
.catch((error) => {
|
|
693
|
-
errorHandler(error.message, error);
|
|
694
|
-
});
|
|
695
|
-
}
|
|
696
|
-
else {
|
|
697
|
-
errorHandler("LoadAssetContainer is not supported by this plugin. Plugin did not provide a loadAssetContainer or loadAssetContainerAsync method.");
|
|
698
|
-
}
|
|
699
|
-
}, progressHandler, errorHandler, disposeHandler, pluginExtension, name, pluginOptions);
|
|
601
|
+
}
|
|
700
602
|
}
|
|
701
603
|
/**
|
|
702
604
|
* Load a scene into an asset container
|
|
@@ -707,7 +609,7 @@ async function loadAssetContainerImplAsync(rootUrl, sceneFilename = "", scene =
|
|
|
707
609
|
*/
|
|
708
610
|
export async function LoadAssetContainerAsync(source, scene, options) {
|
|
709
611
|
const { rootUrl = "", onProgress, pluginExtension, name, pluginOptions } = options ?? {};
|
|
710
|
-
return await
|
|
612
|
+
return await loadAssetContainerCoreAsync(rootUrl, source, scene, onProgress, pluginExtension, name, pluginOptions);
|
|
711
613
|
}
|
|
712
614
|
/**
|
|
713
615
|
* Load a scene into an asset container
|
|
@@ -720,30 +622,10 @@ export async function LoadAssetContainerAsync(source, scene, options) {
|
|
|
720
622
|
export async function loadAssetContainerAsync(source, scene, options) {
|
|
721
623
|
return await LoadAssetContainerAsync(source, scene, options);
|
|
722
624
|
}
|
|
723
|
-
// This function is shared between the new module level loadAssetContainerAsync and the legacy SceneLoader.LoadAssetContainerAsync
|
|
724
|
-
async function loadAssetContainerSharedAsync(rootUrl, sceneFilename, scene, onProgress, pluginExtension, name, pluginOptions) {
|
|
725
|
-
return await new Promise((resolve, reject) => {
|
|
726
|
-
try {
|
|
727
|
-
loadAssetContainerImplAsync(rootUrl, sceneFilename, scene, (assets) => {
|
|
728
|
-
resolve(assets);
|
|
729
|
-
}, onProgress, (scene, message, exception) => {
|
|
730
|
-
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
|
|
731
|
-
reject(exception || new Error(message));
|
|
732
|
-
}, pluginExtension, name, pluginOptions
|
|
733
|
-
// eslint-disable-next-line github/no-then
|
|
734
|
-
).catch(reject);
|
|
735
|
-
}
|
|
736
|
-
catch (error) {
|
|
737
|
-
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
|
|
738
|
-
reject(error);
|
|
739
|
-
}
|
|
740
|
-
});
|
|
741
|
-
}
|
|
742
625
|
// This is the core implementation of import animations
|
|
743
|
-
async function
|
|
626
|
+
async function importAnimationsCoreAsync(rootUrl, sceneFilename = "", scene = EngineStore.LastCreatedScene, overwriteAnimations = true, animationGroupLoadingMode = 0 /* SceneLoaderAnimationGroupLoadingMode.Clean */, targetConverter = null, onProgress, pluginExtension, name = "", pluginOptions = {}) {
|
|
744
627
|
if (!scene) {
|
|
745
|
-
|
|
746
|
-
return;
|
|
628
|
+
throw new Error("No scene available to load animations to");
|
|
747
629
|
}
|
|
748
630
|
if (overwriteAnimations) {
|
|
749
631
|
// Reset, stop and dispose all animations before loading new ones
|
|
@@ -785,20 +667,14 @@ async function importAnimationsImplAsync(rootUrl, sceneFilename = "", scene = En
|
|
|
785
667
|
// nothing to do
|
|
786
668
|
break;
|
|
787
669
|
default:
|
|
788
|
-
|
|
789
|
-
return;
|
|
670
|
+
throw new Error("Unknown animation group loading mode value '" + animationGroupLoadingMode + "'");
|
|
790
671
|
}
|
|
791
672
|
}
|
|
792
673
|
const startingIndexForNewAnimatables = scene.animatables.length;
|
|
793
|
-
const
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
if (onSuccess) {
|
|
798
|
-
onSuccess(scene);
|
|
799
|
-
}
|
|
800
|
-
};
|
|
801
|
-
await loadAssetContainerImplAsync(rootUrl, sceneFilename, scene, onAssetContainerLoaded, onProgress, onError, pluginExtension, name, pluginOptions);
|
|
674
|
+
const container = await loadAssetContainerCoreAsync(rootUrl, sceneFilename, scene, onProgress, pluginExtension, name, pluginOptions);
|
|
675
|
+
container.mergeAnimationsTo(scene, scene.animatables.slice(startingIndexForNewAnimatables), targetConverter);
|
|
676
|
+
container.dispose();
|
|
677
|
+
scene.onAnimationFileImportedObservable.notifyObservers(scene);
|
|
802
678
|
}
|
|
803
679
|
/**
|
|
804
680
|
* Import animations from a file into a scene
|
|
@@ -809,7 +685,7 @@ async function importAnimationsImplAsync(rootUrl, sceneFilename = "", scene = En
|
|
|
809
685
|
*/
|
|
810
686
|
export async function ImportAnimationsAsync(source, scene, options) {
|
|
811
687
|
const { rootUrl = "", overwriteAnimations, animationGroupLoadingMode, targetConverter, onProgress, pluginExtension, name, pluginOptions } = options ?? {};
|
|
812
|
-
await
|
|
688
|
+
await importAnimationsCoreAsync(rootUrl, source, scene, overwriteAnimations, animationGroupLoadingMode, targetConverter, onProgress, pluginExtension, name, pluginOptions);
|
|
813
689
|
}
|
|
814
690
|
/**
|
|
815
691
|
* Import animations from a file into a scene
|
|
@@ -822,25 +698,6 @@ export async function ImportAnimationsAsync(source, scene, options) {
|
|
|
822
698
|
export async function importAnimationsAsync(source, scene, options) {
|
|
823
699
|
return await ImportAnimationsAsync(source, scene, options);
|
|
824
700
|
}
|
|
825
|
-
// This function is shared between the new module level importAnimationsAsync and the legacy SceneLoader.ImportAnimationsAsync
|
|
826
|
-
async function importAnimationsSharedAsync(rootUrl, sceneFilename, scene, overwriteAnimations, animationGroupLoadingMode, targetConverter, onProgress, pluginExtension, name, pluginOptions) {
|
|
827
|
-
return await new Promise((resolve, reject) => {
|
|
828
|
-
try {
|
|
829
|
-
importAnimationsImplAsync(rootUrl, sceneFilename, scene, overwriteAnimations, animationGroupLoadingMode, targetConverter, (scene) => {
|
|
830
|
-
resolve(scene);
|
|
831
|
-
}, onProgress, (scene, message, exception) => {
|
|
832
|
-
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
|
|
833
|
-
reject(exception || new Error(message));
|
|
834
|
-
}, pluginExtension, name, pluginOptions
|
|
835
|
-
// eslint-disable-next-line github/no-then
|
|
836
|
-
).catch(reject);
|
|
837
|
-
}
|
|
838
|
-
catch (error) {
|
|
839
|
-
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
|
|
840
|
-
reject(error);
|
|
841
|
-
}
|
|
842
|
-
});
|
|
843
|
-
}
|
|
844
701
|
/**
|
|
845
702
|
* Class used to load scene from various file formats using registered plugins
|
|
846
703
|
* @see https://doc.babylonjs.com/features/featuresDeepDive/importers/loadingFileTypes
|
|
@@ -933,8 +790,16 @@ export class SceneLoader {
|
|
|
933
790
|
* @deprecated Please use the module level {@link ImportMeshAsync} instead
|
|
934
791
|
*/
|
|
935
792
|
static ImportMesh(meshNames, rootUrl, sceneFilename, scene, onSuccess, onProgress, onError, pluginExtension, name, pluginOptions) {
|
|
936
|
-
|
|
937
|
-
|
|
793
|
+
const reportScene = scene ?? EngineStore.LastCreatedScene;
|
|
794
|
+
void (async () => {
|
|
795
|
+
try {
|
|
796
|
+
const result = await importMeshCoreAsync(meshNames, rootUrl, sceneFilename, scene, onProgress, pluginExtension, name, pluginOptions);
|
|
797
|
+
onSuccess?.(result.meshes, result.particleSystems, result.skeletons, result.animationGroups, result.transformNodes, result.geometries, result.lights, result.spriteManagers);
|
|
798
|
+
}
|
|
799
|
+
catch (error) {
|
|
800
|
+
reportLegacyLoadError(onError, reportScene, error);
|
|
801
|
+
}
|
|
802
|
+
})();
|
|
938
803
|
}
|
|
939
804
|
/**
|
|
940
805
|
* Import meshes into a scene
|
|
@@ -949,7 +814,7 @@ export class SceneLoader {
|
|
|
949
814
|
* @deprecated Please use the module level {@link ImportMeshAsync} instead
|
|
950
815
|
*/
|
|
951
816
|
static async ImportMeshAsync(meshNames, rootUrl, sceneFilename, scene, onProgress, pluginExtension, name) {
|
|
952
|
-
return await
|
|
817
|
+
return await importMeshCoreAsync(meshNames, rootUrl, sceneFilename, scene, onProgress, pluginExtension, name);
|
|
953
818
|
}
|
|
954
819
|
/**
|
|
955
820
|
* Load a scene
|
|
@@ -964,8 +829,15 @@ export class SceneLoader {
|
|
|
964
829
|
* @deprecated Please use the module level {@link LoadSceneAsync} instead
|
|
965
830
|
*/
|
|
966
831
|
static Load(rootUrl, sceneFilename, engine, onSuccess, onProgress, onError, pluginExtension, name) {
|
|
967
|
-
|
|
968
|
-
|
|
832
|
+
void (async () => {
|
|
833
|
+
try {
|
|
834
|
+
const scene = await loadSceneCoreAsync(rootUrl, sceneFilename, engine, onProgress, pluginExtension, name);
|
|
835
|
+
onSuccess?.(scene);
|
|
836
|
+
}
|
|
837
|
+
catch (error) {
|
|
838
|
+
reportLegacyLoadError(onError, EngineStore.LastCreatedScene, error);
|
|
839
|
+
}
|
|
840
|
+
})();
|
|
969
841
|
}
|
|
970
842
|
/**
|
|
971
843
|
* Load a scene
|
|
@@ -979,7 +851,7 @@ export class SceneLoader {
|
|
|
979
851
|
* @deprecated Please use the module level {@link LoadSceneAsync} instead
|
|
980
852
|
*/
|
|
981
853
|
static async LoadAsync(rootUrl, sceneFilename, engine, onProgress, pluginExtension, name) {
|
|
982
|
-
return await
|
|
854
|
+
return await loadSceneCoreAsync(rootUrl, sceneFilename, engine, onProgress, pluginExtension, name);
|
|
983
855
|
}
|
|
984
856
|
/**
|
|
985
857
|
* Append a scene
|
|
@@ -994,8 +866,16 @@ export class SceneLoader {
|
|
|
994
866
|
* @deprecated Please use the module level {@link AppendSceneAsync} instead
|
|
995
867
|
*/
|
|
996
868
|
static Append(rootUrl, sceneFilename, scene, onSuccess, onProgress, onError, pluginExtension, name) {
|
|
997
|
-
|
|
998
|
-
|
|
869
|
+
const reportScene = scene ?? EngineStore.LastCreatedScene;
|
|
870
|
+
void (async () => {
|
|
871
|
+
try {
|
|
872
|
+
const appendedScene = await appendSceneCoreAsync(rootUrl, sceneFilename, scene, onProgress, pluginExtension, name);
|
|
873
|
+
onSuccess?.(appendedScene);
|
|
874
|
+
}
|
|
875
|
+
catch (error) {
|
|
876
|
+
reportLegacyLoadError(onError, reportScene, error);
|
|
877
|
+
}
|
|
878
|
+
})();
|
|
999
879
|
}
|
|
1000
880
|
/**
|
|
1001
881
|
* Append a scene
|
|
@@ -1009,7 +889,7 @@ export class SceneLoader {
|
|
|
1009
889
|
* @deprecated Please use the module level {@link AppendSceneAsync} instead
|
|
1010
890
|
*/
|
|
1011
891
|
static async AppendAsync(rootUrl, sceneFilename, scene, onProgress, pluginExtension, name) {
|
|
1012
|
-
return await
|
|
892
|
+
return await appendSceneCoreAsync(rootUrl, sceneFilename, scene, onProgress, pluginExtension, name);
|
|
1013
893
|
}
|
|
1014
894
|
/**
|
|
1015
895
|
* Load a scene into an asset container
|
|
@@ -1024,8 +904,16 @@ export class SceneLoader {
|
|
|
1024
904
|
* @deprecated Please use the module level {@link LoadAssetContainerAsync} instead
|
|
1025
905
|
*/
|
|
1026
906
|
static LoadAssetContainer(rootUrl, sceneFilename, scene, onSuccess, onProgress, onError, pluginExtension, name) {
|
|
1027
|
-
|
|
1028
|
-
|
|
907
|
+
const reportScene = scene ?? EngineStore.LastCreatedScene;
|
|
908
|
+
void (async () => {
|
|
909
|
+
try {
|
|
910
|
+
const assets = await loadAssetContainerCoreAsync(rootUrl, sceneFilename, scene, onProgress, pluginExtension, name);
|
|
911
|
+
onSuccess?.(assets);
|
|
912
|
+
}
|
|
913
|
+
catch (error) {
|
|
914
|
+
reportLegacyLoadError(onError, reportScene, error);
|
|
915
|
+
}
|
|
916
|
+
})();
|
|
1029
917
|
}
|
|
1030
918
|
/**
|
|
1031
919
|
* Load a scene into an asset container
|
|
@@ -1039,7 +927,7 @@ export class SceneLoader {
|
|
|
1039
927
|
* @deprecated Please use the module level {@link LoadAssetContainerAsync} instead
|
|
1040
928
|
*/
|
|
1041
929
|
static async LoadAssetContainerAsync(rootUrl, sceneFilename, scene, onProgress, pluginExtension, name) {
|
|
1042
|
-
return await
|
|
930
|
+
return await loadAssetContainerCoreAsync(rootUrl, sceneFilename, scene, onProgress, pluginExtension, name);
|
|
1043
931
|
}
|
|
1044
932
|
/**
|
|
1045
933
|
* Import animations from a file into a scene
|
|
@@ -1057,9 +945,16 @@ export class SceneLoader {
|
|
|
1057
945
|
* @deprecated Please use the module level {@link ImportAnimationsAsync} instead
|
|
1058
946
|
*/
|
|
1059
947
|
static ImportAnimations(rootUrl, sceneFilename, scene, overwriteAnimations, animationGroupLoadingMode, targetConverter, onSuccess, onProgress, onError, pluginExtension, name) {
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
948
|
+
const reportScene = scene ?? EngineStore.LastCreatedScene;
|
|
949
|
+
void (async () => {
|
|
950
|
+
try {
|
|
951
|
+
await importAnimationsCoreAsync(rootUrl, sceneFilename, scene, overwriteAnimations, animationGroupLoadingMode, targetConverter, onProgress, pluginExtension, name);
|
|
952
|
+
onSuccess?.(reportScene);
|
|
953
|
+
}
|
|
954
|
+
catch (error) {
|
|
955
|
+
reportLegacyLoadError(onError, reportScene, error);
|
|
956
|
+
}
|
|
957
|
+
})();
|
|
1063
958
|
}
|
|
1064
959
|
/**
|
|
1065
960
|
* Import animations from a file into a scene
|
|
@@ -1082,7 +977,9 @@ export class SceneLoader {
|
|
|
1082
977
|
onSuccess, onProgress,
|
|
1083
978
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1084
979
|
onError, pluginExtension, name) {
|
|
1085
|
-
|
|
980
|
+
const targetScene = scene ?? EngineStore.LastCreatedScene;
|
|
981
|
+
await importAnimationsCoreAsync(rootUrl, sceneFilename, targetScene, overwriteAnimations, animationGroupLoadingMode, targetConverter, onProgress, pluginExtension, name);
|
|
982
|
+
return targetScene;
|
|
1086
983
|
}
|
|
1087
984
|
}
|
|
1088
985
|
/**
|