|
@@ -20,20 +20,12 @@ module BABYLON.GLTF2 {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- /**
|
|
|
|
- * Loader for loading a glTF 2.0 asset
|
|
|
|
- */
|
|
|
|
|
|
+ /** @hidden */
|
|
export class GLTFLoader implements IGLTFLoader {
|
|
export class GLTFLoader implements IGLTFLoader {
|
|
- /** @hidden */
|
|
|
|
|
|
+ public _parent: GLTFFileLoader;
|
|
public _gltf: _ILoaderGLTF;
|
|
public _gltf: _ILoaderGLTF;
|
|
-
|
|
|
|
- /** @hidden */
|
|
|
|
public _babylonScene: Scene;
|
|
public _babylonScene: Scene;
|
|
-
|
|
|
|
- /** @hidden */
|
|
|
|
public _completePromises = new Array<Promise<void>>();
|
|
public _completePromises = new Array<Promise<void>>();
|
|
-
|
|
|
|
- /** @hidden */
|
|
|
|
public _onReadyObservable = new Observable<IGLTFLoader>();
|
|
public _onReadyObservable = new Observable<IGLTFLoader>();
|
|
|
|
|
|
private _disposed = false;
|
|
private _disposed = false;
|
|
@@ -49,7 +41,6 @@ module BABYLON.GLTF2 {
|
|
private static _ExtensionNames = new Array<string>();
|
|
private static _ExtensionNames = new Array<string>();
|
|
private static _ExtensionFactories: { [name: string]: (loader: GLTFLoader) => GLTFLoaderExtension } = {};
|
|
private static _ExtensionFactories: { [name: string]: (loader: GLTFLoader) => GLTFLoaderExtension } = {};
|
|
|
|
|
|
- /** @hidden */
|
|
|
|
public static _Register(name: string, factory: (loader: GLTFLoader) => GLTFLoaderExtension): void {
|
|
public static _Register(name: string, factory: (loader: GLTFLoader) => GLTFLoaderExtension): void {
|
|
if (GLTFLoader._ExtensionFactories[name]) {
|
|
if (GLTFLoader._ExtensionFactories[name]) {
|
|
Tools.Error(`Extension with the name '${name}' already exists`);
|
|
Tools.Error(`Extension with the name '${name}' already exists`);
|
|
@@ -63,93 +54,16 @@ module BABYLON.GLTF2 {
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * Mode that determines the coordinate system to use.
|
|
|
|
- */
|
|
|
|
- public coordinateSystemMode = GLTFLoaderCoordinateSystemMode.AUTO;
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Mode that determines what animations will start.
|
|
|
|
- */
|
|
|
|
- public animationStartMode = GLTFLoaderAnimationStartMode.FIRST;
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Defines if the loader should compile materials.
|
|
|
|
- */
|
|
|
|
- public compileMaterials = false;
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Defines if the loader should also compile materials with clip planes.
|
|
|
|
- */
|
|
|
|
- public useClipPlane = false;
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Defines if the loader should compile shadow generators.
|
|
|
|
- */
|
|
|
|
- public compileShadowGenerators = false;
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Defines if the Alpha blended materials are only applied as coverage.
|
|
|
|
- * If false, (default) The luminance of each pixel will reduce its opacity to simulate the behaviour of most physical materials.
|
|
|
|
- * If true, no extra effects are applied to transparent pixels.
|
|
|
|
- */
|
|
|
|
- public transparencyAsCoverage = false;
|
|
|
|
-
|
|
|
|
- /** @hidden */
|
|
|
|
- public _normalizeAnimationGroupsToBeginAtZero = true;
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Function called before loading a url referenced by the asset.
|
|
|
|
- */
|
|
|
|
- public preprocessUrlAsync = (url: string) => Promise.resolve(url);
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Observable raised when the loader creates a mesh after parsing the glTF properties of the mesh.
|
|
|
|
- */
|
|
|
|
- public readonly onMeshLoadedObservable = new Observable<AbstractMesh>();
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Observable raised when the loader creates a texture after parsing the glTF properties of the texture.
|
|
|
|
- */
|
|
|
|
- public readonly onTextureLoadedObservable = new Observable<BaseTexture>();
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Observable raised when the loader creates a material after parsing the glTF properties of the material.
|
|
|
|
- */
|
|
|
|
- public readonly onMaterialLoadedObservable = new Observable<Material>();
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Observable raised when the loader creates a camera after parsing the glTF properties of the camera.
|
|
|
|
- */
|
|
|
|
- public readonly onCameraLoadedObservable = new Observable<Camera>();
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Observable raised when the asset is completely loaded, immediately before the loader is disposed.
|
|
|
|
- * For assets with LODs, raised when all of the LODs are complete.
|
|
|
|
- * For assets without LODs, raised when the model is complete, immediately after the loader resolves the returned promise.
|
|
|
|
- */
|
|
|
|
- public readonly onCompleteObservable = new Observable<IGLTFLoader>();
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Observable raised after the loader is disposed.
|
|
|
|
- */
|
|
|
|
- public readonly onDisposeObservable = new Observable<IGLTFLoader>();
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Observable raised after a loader extension is created.
|
|
|
|
- * Set additional options for a loader extension in this event.
|
|
|
|
- */
|
|
|
|
- public readonly onExtensionLoadedObservable = new Observable<IGLTFLoaderExtension>();
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
* Loader state or null if the loader is not active.
|
|
* Loader state or null if the loader is not active.
|
|
*/
|
|
*/
|
|
public get state(): Nullable<GLTFLoaderState> {
|
|
public get state(): Nullable<GLTFLoaderState> {
|
|
return this._state;
|
|
return this._state;
|
|
}
|
|
}
|
|
|
|
|
|
- /**
|
|
|
|
- * Disposes the loader, releases resources during load, and cancels any outstanding requests.
|
|
|
|
- */
|
|
|
|
|
|
+ constructor(parent: GLTFFileLoader) {
|
|
|
|
+ this._parent = parent;
|
|
|
|
+ }
|
|
|
|
+
|
|
public dispose(): void {
|
|
public dispose(): void {
|
|
if (this._disposed) {
|
|
if (this._disposed) {
|
|
return;
|
|
return;
|
|
@@ -157,21 +71,29 @@ module BABYLON.GLTF2 {
|
|
|
|
|
|
this._disposed = true;
|
|
this._disposed = true;
|
|
|
|
|
|
- this.onDisposeObservable.notifyObservers(this);
|
|
|
|
- this.onDisposeObservable.clear();
|
|
|
|
|
|
+ for (const request of this._requests) {
|
|
|
|
+ request.abort();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this._requests.length = 0;
|
|
|
|
+
|
|
|
|
+ delete this._gltf;
|
|
|
|
+ delete this._babylonScene;
|
|
|
|
+ this._completePromises.length = 0;
|
|
|
|
+ this._onReadyObservable.clear();
|
|
|
|
+
|
|
|
|
+ for (const name in this._extensions) {
|
|
|
|
+ this._extensions[name].dispose();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this._extensions = {};
|
|
|
|
+
|
|
|
|
+ delete this._rootBabylonMesh;
|
|
|
|
+ delete this._progressCallback;
|
|
|
|
|
|
- this._clear();
|
|
|
|
|
|
+ this._parent._clear();
|
|
}
|
|
}
|
|
|
|
|
|
- /**
|
|
|
|
- * Imports one or more meshes from the loaded glTF data and adds them to the scene
|
|
|
|
- * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
|
|
|
|
- * @param scene the scene the meshes should be added to
|
|
|
|
- * @param data the glTF data to load
|
|
|
|
- * @param rootUrl root url to load from
|
|
|
|
- * @param onProgress event that fires when loading progress has occured
|
|
|
|
- * @returns a promise containg the loaded meshes, particles, skeletons and animations
|
|
|
|
- */
|
|
|
|
public importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{ meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[], animationGroups: AnimationGroup[] }> {
|
|
public importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{ meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[], animationGroups: AnimationGroup[] }> {
|
|
return Promise.resolve().then(() => {
|
|
return Promise.resolve().then(() => {
|
|
this._babylonScene = scene;
|
|
this._babylonScene = scene;
|
|
@@ -213,14 +135,6 @@ module BABYLON.GLTF2 {
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
- /**
|
|
|
|
- * Imports all objects from the loaded glTF data and adds them to the scene
|
|
|
|
- * @param scene the scene the objects should be added to
|
|
|
|
- * @param data the glTF data to load
|
|
|
|
- * @param rootUrl root url to load from
|
|
|
|
- * @param onProgress event that fires when loading progress has occured
|
|
|
|
- * @returns a promise which completes when objects have been loaded to the scene
|
|
|
|
- */
|
|
|
|
public loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<void> {
|
|
public loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<void> {
|
|
return Promise.resolve().then(() => {
|
|
return Promise.resolve().then(() => {
|
|
this._babylonScene = scene;
|
|
this._babylonScene = scene;
|
|
@@ -234,6 +148,7 @@ module BABYLON.GLTF2 {
|
|
private _loadAsync(nodes: Nullable<Array<_ILoaderNode>>): Promise<void> {
|
|
private _loadAsync(nodes: Nullable<Array<_ILoaderNode>>): Promise<void> {
|
|
return Promise.resolve().then(() => {
|
|
return Promise.resolve().then(() => {
|
|
this._state = GLTFLoaderState.LOADING;
|
|
this._state = GLTFLoaderState.LOADING;
|
|
|
|
+ this._parent._log(`Loading`);
|
|
|
|
|
|
this._loadExtensions();
|
|
this._loadExtensions();
|
|
this._checkExtensions();
|
|
this._checkExtensions();
|
|
@@ -248,16 +163,18 @@ module BABYLON.GLTF2 {
|
|
promises.push(this._loadSceneAsync(`#/scenes/${scene._index}`, scene));
|
|
promises.push(this._loadSceneAsync(`#/scenes/${scene._index}`, scene));
|
|
}
|
|
}
|
|
|
|
|
|
- if (this.compileMaterials) {
|
|
|
|
|
|
+ if (this._parent.compileMaterials) {
|
|
promises.push(this._compileMaterialsAsync());
|
|
promises.push(this._compileMaterialsAsync());
|
|
}
|
|
}
|
|
|
|
|
|
- if (this.compileShadowGenerators) {
|
|
|
|
|
|
+ if (this._parent.compileShadowGenerators) {
|
|
promises.push(this._compileShadowGeneratorsAsync());
|
|
promises.push(this._compileShadowGeneratorsAsync());
|
|
}
|
|
}
|
|
|
|
|
|
const resultPromise = Promise.all(promises).then(() => {
|
|
const resultPromise = Promise.all(promises).then(() => {
|
|
this._state = GLTFLoaderState.READY;
|
|
this._state = GLTFLoaderState.READY;
|
|
|
|
+ this._parent._log(`Ready`);
|
|
|
|
+
|
|
this._onReadyObservable.notifyObservers(this);
|
|
this._onReadyObservable.notifyObservers(this);
|
|
this._startAnimations();
|
|
this._startAnimations();
|
|
});
|
|
});
|
|
@@ -271,12 +188,14 @@ module BABYLON.GLTF2 {
|
|
if (!this._disposed) {
|
|
if (!this._disposed) {
|
|
Promise.all(this._completePromises).then(() => {
|
|
Promise.all(this._completePromises).then(() => {
|
|
this._state = GLTFLoaderState.COMPLETE;
|
|
this._state = GLTFLoaderState.COMPLETE;
|
|
- this.onCompleteObservable.notifyObservers(this);
|
|
|
|
- this.onCompleteObservable.clear();
|
|
|
|
- this._clear();
|
|
|
|
|
|
+ this._parent._log(`Complete`);
|
|
|
|
+
|
|
|
|
+ this._parent.onCompleteObservable.notifyObservers(undefined);
|
|
|
|
+ this._parent.onCompleteObservable.clear();
|
|
|
|
+ this.dispose();
|
|
}).catch(error => {
|
|
}).catch(error => {
|
|
Tools.Error(`glTF Loader: ${error.message}`);
|
|
Tools.Error(`glTF Loader: ${error.message}`);
|
|
- this._clear();
|
|
|
|
|
|
+ this.dispose();
|
|
});
|
|
});
|
|
}
|
|
}
|
|
});
|
|
});
|
|
@@ -286,7 +205,7 @@ module BABYLON.GLTF2 {
|
|
}).catch(error => {
|
|
}).catch(error => {
|
|
if (!this._disposed) {
|
|
if (!this._disposed) {
|
|
Tools.Error(`glTF Loader: ${error.message}`);
|
|
Tools.Error(`glTF Loader: ${error.message}`);
|
|
- this._clear();
|
|
|
|
|
|
+ this.dispose();
|
|
throw error;
|
|
throw error;
|
|
}
|
|
}
|
|
});
|
|
});
|
|
@@ -350,10 +269,10 @@ module BABYLON.GLTF2 {
|
|
const extension = GLTFLoader._ExtensionFactories[name](this);
|
|
const extension = GLTFLoader._ExtensionFactories[name](this);
|
|
this._extensions[name] = extension;
|
|
this._extensions[name] = extension;
|
|
|
|
|
|
- this.onExtensionLoadedObservable.notifyObservers(extension);
|
|
|
|
|
|
+ this._parent.onExtensionLoadedObservable.notifyObservers(extension);
|
|
}
|
|
}
|
|
|
|
|
|
- this.onExtensionLoadedObservable.clear();
|
|
|
|
|
|
+ this._parent.onExtensionLoadedObservable.clear();
|
|
}
|
|
}
|
|
|
|
|
|
private _checkExtensions(): void {
|
|
private _checkExtensions(): void {
|
|
@@ -372,7 +291,7 @@ module BABYLON.GLTF2 {
|
|
this._rootBabylonMesh.setEnabled(false);
|
|
this._rootBabylonMesh.setEnabled(false);
|
|
|
|
|
|
const rootNode = { _babylonMesh: this._rootBabylonMesh } as _ILoaderNode;
|
|
const rootNode = { _babylonMesh: this._rootBabylonMesh } as _ILoaderNode;
|
|
- switch (this.coordinateSystemMode) {
|
|
|
|
|
|
+ switch (this._parent.coordinateSystemMode) {
|
|
case GLTFLoaderCoordinateSystemMode.AUTO: {
|
|
case GLTFLoaderCoordinateSystemMode.AUTO: {
|
|
if (!this._babylonScene.useRightHandedSystem) {
|
|
if (!this._babylonScene.useRightHandedSystem) {
|
|
rootNode.rotation = [0, 1, 0, 0];
|
|
rootNode.rotation = [0, 1, 0, 0];
|
|
@@ -386,11 +305,11 @@ module BABYLON.GLTF2 {
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
default: {
|
|
default: {
|
|
- throw new Error(`Invalid coordinate system mode (${this.coordinateSystemMode})`);
|
|
|
|
|
|
+ throw new Error(`Invalid coordinate system mode (${this._parent.coordinateSystemMode})`);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- this.onMeshLoadedObservable.notifyObservers(this._rootBabylonMesh);
|
|
|
|
|
|
+ this._parent.onMeshLoadedObservable.notifyObservers(this._rootBabylonMesh);
|
|
return rootNode;
|
|
return rootNode;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -406,7 +325,6 @@ module BABYLON.GLTF2 {
|
|
return Promise.all(promises).then(() => {});
|
|
return Promise.all(promises).then(() => {});
|
|
}
|
|
}
|
|
|
|
|
|
- /** @hidden */
|
|
|
|
public _loadSceneAsync(context: string, scene: _ILoaderScene): Promise<void> {
|
|
public _loadSceneAsync(context: string, scene: _ILoaderScene): Promise<void> {
|
|
const promise = GLTFLoaderExtension._LoadSceneAsync(this, context, scene);
|
|
const promise = GLTFLoaderExtension._LoadSceneAsync(this, context, scene);
|
|
if (promise) {
|
|
if (promise) {
|
|
@@ -415,13 +333,19 @@ module BABYLON.GLTF2 {
|
|
|
|
|
|
const promises = new Array<Promise<void>>();
|
|
const promises = new Array<Promise<void>>();
|
|
|
|
|
|
- for (let index of scene.nodes) {
|
|
|
|
- const node = GLTFLoader._GetProperty(`${context}/nodes/${index}`, this._gltf.nodes, index);
|
|
|
|
- promises.push(this._loadNodeAsync(`#/nodes/${node._index}`, node));
|
|
|
|
|
|
+ this._parent._logOpen(`${context} ${scene.name || ""}`);
|
|
|
|
+
|
|
|
|
+ if (scene.nodes) {
|
|
|
|
+ for (let index of scene.nodes) {
|
|
|
|
+ const node = GLTFLoader._GetProperty(`${context}/nodes/${index}`, this._gltf.nodes, index);
|
|
|
|
+ promises.push(this._loadNodeAsync(`#/nodes/${node._index}`, node));
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
promises.push(this._loadAnimationsAsync());
|
|
promises.push(this._loadAnimationsAsync());
|
|
|
|
|
|
|
|
+ this._parent._logClose();
|
|
|
|
+
|
|
return Promise.all(promises).then(() => {});
|
|
return Promise.all(promises).then(() => {});
|
|
}
|
|
}
|
|
|
|
|
|
@@ -491,7 +415,7 @@ module BABYLON.GLTF2 {
|
|
}
|
|
}
|
|
|
|
|
|
private _startAnimations(): void {
|
|
private _startAnimations(): void {
|
|
- switch (this.animationStartMode) {
|
|
|
|
|
|
+ switch (this._parent.animationStartMode) {
|
|
case GLTFLoaderAnimationStartMode.NONE: {
|
|
case GLTFLoaderAnimationStartMode.NONE: {
|
|
// do nothing
|
|
// do nothing
|
|
break;
|
|
break;
|
|
@@ -511,13 +435,12 @@ module BABYLON.GLTF2 {
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
default: {
|
|
default: {
|
|
- Tools.Error(`Invalid animation start mode (${this.animationStartMode})`);
|
|
|
|
|
|
+ Tools.Error(`Invalid animation start mode (${this._parent.animationStartMode})`);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- /** @hidden */
|
|
|
|
public _loadNodeAsync(context: string, node: _ILoaderNode): Promise<void> {
|
|
public _loadNodeAsync(context: string, node: _ILoaderNode): Promise<void> {
|
|
const promise = GLTFLoaderExtension._LoadNodeAsync(this, context, node);
|
|
const promise = GLTFLoaderExtension._LoadNodeAsync(this, context, node);
|
|
if (promise) {
|
|
if (promise) {
|
|
@@ -530,6 +453,8 @@ module BABYLON.GLTF2 {
|
|
|
|
|
|
const promises = new Array<Promise<void>>();
|
|
const promises = new Array<Promise<void>>();
|
|
|
|
|
|
|
|
+ this._parent._logOpen(`${context} ${node.name || ""}`);
|
|
|
|
+
|
|
const babylonMesh = new Mesh(node.name || `node${node._index}`, this._babylonScene, node._parent ? node._parent._babylonMesh : null);
|
|
const babylonMesh = new Mesh(node.name || `node${node._index}`, this._babylonScene, node._parent ? node._parent._babylonMesh : null);
|
|
node._babylonMesh = babylonMesh;
|
|
node._babylonMesh = babylonMesh;
|
|
|
|
|
|
@@ -552,7 +477,9 @@ module BABYLON.GLTF2 {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- this.onMeshLoadedObservable.notifyObservers(babylonMesh);
|
|
|
|
|
|
+ this._parent.onMeshLoadedObservable.notifyObservers(babylonMesh);
|
|
|
|
+
|
|
|
|
+ this._parent._logClose();
|
|
|
|
|
|
return Promise.all(promises).then(() => {});
|
|
return Promise.all(promises).then(() => {});
|
|
}
|
|
}
|
|
@@ -560,6 +487,8 @@ module BABYLON.GLTF2 {
|
|
private _loadMeshAsync(context: string, node: _ILoaderNode, mesh: _ILoaderMesh, babylonMesh: Mesh): Promise<void> {
|
|
private _loadMeshAsync(context: string, node: _ILoaderNode, mesh: _ILoaderMesh, babylonMesh: Mesh): Promise<void> {
|
|
const promises = new Array<Promise<void>>();
|
|
const promises = new Array<Promise<void>>();
|
|
|
|
|
|
|
|
+ this._parent._logOpen(`${context} ${mesh.name || ""}`);
|
|
|
|
+
|
|
const primitives = mesh.primitives;
|
|
const primitives = mesh.primitives;
|
|
if (!primitives || primitives.length === 0) {
|
|
if (!primitives || primitives.length === 0) {
|
|
throw new Error(`${context}: Primitives are missing`);
|
|
throw new Error(`${context}: Primitives are missing`);
|
|
@@ -576,7 +505,7 @@ module BABYLON.GLTF2 {
|
|
const primitiveBabylonMesh = new Mesh(`${mesh.name || babylonMesh.name}_${primitive._index}`, this._babylonScene, babylonMesh);
|
|
const primitiveBabylonMesh = new Mesh(`${mesh.name || babylonMesh.name}_${primitive._index}`, this._babylonScene, babylonMesh);
|
|
node._primitiveBabylonMeshes.push(primitiveBabylonMesh);
|
|
node._primitiveBabylonMeshes.push(primitiveBabylonMesh);
|
|
promises.push(this._loadPrimitiveAsync(`${context}/primitives/${primitive._index}`, node, mesh, primitive, primitiveBabylonMesh));
|
|
promises.push(this._loadPrimitiveAsync(`${context}/primitives/${primitive._index}`, node, mesh, primitive, primitiveBabylonMesh));
|
|
- this.onMeshLoadedObservable.notifyObservers(babylonMesh);
|
|
|
|
|
|
+ this._parent.onMeshLoadedObservable.notifyObservers(babylonMesh);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -585,6 +514,8 @@ module BABYLON.GLTF2 {
|
|
promises.push(this._loadSkinAsync(`#/skins/${skin._index}`, node, mesh, skin));
|
|
promises.push(this._loadSkinAsync(`#/skins/${skin._index}`, node, mesh, skin));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ this._parent._logClose();
|
|
|
|
+
|
|
return Promise.all(promises).then(() => {
|
|
return Promise.all(promises).then(() => {
|
|
this._forEachPrimitive(node, babylonMesh => {
|
|
this._forEachPrimitive(node, babylonMesh => {
|
|
babylonMesh._refreshBoundingInfo(true);
|
|
babylonMesh._refreshBoundingInfo(true);
|
|
@@ -595,6 +526,8 @@ module BABYLON.GLTF2 {
|
|
private _loadPrimitiveAsync(context: string, node: _ILoaderNode, mesh: _ILoaderMesh, primitive: _ILoaderMeshPrimitive, babylonMesh: Mesh): Promise<void> {
|
|
private _loadPrimitiveAsync(context: string, node: _ILoaderNode, mesh: _ILoaderMesh, primitive: _ILoaderMeshPrimitive, babylonMesh: Mesh): Promise<void> {
|
|
const promises = new Array<Promise<void>>();
|
|
const promises = new Array<Promise<void>>();
|
|
|
|
|
|
|
|
+ this._parent._logOpen(`${context}`);
|
|
|
|
+
|
|
this._createMorphTargets(context, node, mesh, primitive, babylonMesh);
|
|
this._createMorphTargets(context, node, mesh, primitive, babylonMesh);
|
|
promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(babylonGeometry => {
|
|
promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(babylonGeometry => {
|
|
return this._loadMorphTargetsAsync(context, primitive, babylonMesh, babylonGeometry).then(() => {
|
|
return this._loadMorphTargetsAsync(context, primitive, babylonMesh, babylonGeometry).then(() => {
|
|
@@ -613,6 +546,8 @@ module BABYLON.GLTF2 {
|
|
}));
|
|
}));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ this._parent._logClose();
|
|
|
|
+
|
|
return Promise.all(promises).then(() => {});
|
|
return Promise.all(promises).then(() => {});
|
|
}
|
|
}
|
|
|
|
|
|
@@ -920,7 +855,7 @@ module BABYLON.GLTF2 {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- this.onCameraLoadedObservable.notifyObservers(babylonCamera);
|
|
|
|
|
|
+ this._parent.onCameraLoadedObservable.notifyObservers(babylonCamera);
|
|
}
|
|
}
|
|
|
|
|
|
private _loadAnimationsAsync(): Promise<void> {
|
|
private _loadAnimationsAsync(): Promise<void> {
|
|
@@ -953,7 +888,7 @@ module BABYLON.GLTF2 {
|
|
}
|
|
}
|
|
|
|
|
|
return Promise.all(promises).then(() => {
|
|
return Promise.all(promises).then(() => {
|
|
- babylonAnimationGroup.normalize(this._normalizeAnimationGroupsToBeginAtZero ? 0 : null);
|
|
|
|
|
|
+ babylonAnimationGroup.normalize(this._parent._normalizeAnimationGroupsToBeginAtZero ? 0 : null);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1161,7 +1096,6 @@ module BABYLON.GLTF2 {
|
|
return buffer._data;
|
|
return buffer._data;
|
|
}
|
|
}
|
|
|
|
|
|
- /** @hidden */
|
|
|
|
public _loadBufferViewAsync(context: string, bufferView: _ILoaderBufferView): Promise<ArrayBufferView> {
|
|
public _loadBufferViewAsync(context: string, bufferView: _ILoaderBufferView): Promise<ArrayBufferView> {
|
|
if (bufferView._data) {
|
|
if (bufferView._data) {
|
|
return bufferView._data;
|
|
return bufferView._data;
|
|
@@ -1255,7 +1189,6 @@ module BABYLON.GLTF2 {
|
|
return accessor._data as Promise<Float32Array>;
|
|
return accessor._data as Promise<Float32Array>;
|
|
}
|
|
}
|
|
|
|
|
|
- /** @hidden */
|
|
|
|
public _loadVertexBufferViewAsync(context: string, bufferView: _ILoaderBufferView, kind: string): Promise<Buffer> {
|
|
public _loadVertexBufferViewAsync(context: string, bufferView: _ILoaderBufferView, kind: string): Promise<Buffer> {
|
|
if (bufferView._babylonBuffer) {
|
|
if (bufferView._babylonBuffer) {
|
|
return bufferView._babylonBuffer;
|
|
return bufferView._babylonBuffer;
|
|
@@ -1297,7 +1230,7 @@ module BABYLON.GLTF2 {
|
|
babylonMaterial.transparencyMode = PBRMaterial.PBRMATERIAL_OPAQUE;
|
|
babylonMaterial.transparencyMode = PBRMaterial.PBRMATERIAL_OPAQUE;
|
|
babylonMaterial.metallic = 1;
|
|
babylonMaterial.metallic = 1;
|
|
babylonMaterial.roughness = 1;
|
|
babylonMaterial.roughness = 1;
|
|
- this.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
|
|
|
|
|
|
+ this._parent.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
|
|
}
|
|
}
|
|
|
|
|
|
return babylonMaterial;
|
|
return babylonMaterial;
|
|
@@ -1345,7 +1278,6 @@ module BABYLON.GLTF2 {
|
|
return Promise.all(promises).then(() => {});
|
|
return Promise.all(promises).then(() => {});
|
|
}
|
|
}
|
|
|
|
|
|
- /** @hidden */
|
|
|
|
public _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Promise<void> {
|
|
public _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Promise<void> {
|
|
const promise = GLTFLoaderExtension._LoadMaterialAsync(this, context, material, mesh, babylonMesh, babylonDrawMode, assign);
|
|
const promise = GLTFLoaderExtension._LoadMaterialAsync(this, context, material, mesh, babylonMesh, babylonDrawMode, assign);
|
|
if (promise) {
|
|
if (promise) {
|
|
@@ -1357,13 +1289,15 @@ module BABYLON.GLTF2 {
|
|
if (!babylonData) {
|
|
if (!babylonData) {
|
|
const promises = new Array<Promise<void>>();
|
|
const promises = new Array<Promise<void>>();
|
|
|
|
|
|
|
|
+ this._parent._logOpen(`${context} ${material.name || ""}`);
|
|
|
|
+
|
|
const name = material.name || `material_${material._index}`;
|
|
const name = material.name || `material_${material._index}`;
|
|
const babylonMaterial = this._createMaterial(name, babylonDrawMode);
|
|
const babylonMaterial = this._createMaterial(name, babylonDrawMode);
|
|
|
|
|
|
promises.push(this._loadMaterialBasePropertiesAsync(context, material, babylonMaterial));
|
|
promises.push(this._loadMaterialBasePropertiesAsync(context, material, babylonMaterial));
|
|
promises.push(this._loadMaterialMetallicRoughnessPropertiesAsync(context, material, babylonMaterial));
|
|
promises.push(this._loadMaterialMetallicRoughnessPropertiesAsync(context, material, babylonMaterial));
|
|
|
|
|
|
- this.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
|
|
|
|
|
|
+ this._parent.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
|
|
|
|
|
|
babylonData = {
|
|
babylonData = {
|
|
material: babylonMaterial,
|
|
material: babylonMaterial,
|
|
@@ -1372,6 +1306,8 @@ module BABYLON.GLTF2 {
|
|
};
|
|
};
|
|
|
|
|
|
material._babylonData[babylonDrawMode] = babylonData;
|
|
material._babylonData[babylonDrawMode] = babylonData;
|
|
|
|
+
|
|
|
|
+ this._parent._logClose();
|
|
}
|
|
}
|
|
|
|
|
|
babylonData.meshes.push(babylonMesh);
|
|
babylonData.meshes.push(babylonMesh);
|
|
@@ -1380,18 +1316,16 @@ module BABYLON.GLTF2 {
|
|
return babylonData.loaded;
|
|
return babylonData.loaded;
|
|
}
|
|
}
|
|
|
|
|
|
- /** @hidden */
|
|
|
|
public _createMaterial(name: string, drawMode: number): PBRMaterial {
|
|
public _createMaterial(name: string, drawMode: number): PBRMaterial {
|
|
const babylonMaterial = new PBRMaterial(name, this._babylonScene);
|
|
const babylonMaterial = new PBRMaterial(name, this._babylonScene);
|
|
babylonMaterial.sideOrientation = this._babylonScene.useRightHandedSystem ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation;
|
|
babylonMaterial.sideOrientation = this._babylonScene.useRightHandedSystem ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation;
|
|
babylonMaterial.fillMode = drawMode;
|
|
babylonMaterial.fillMode = drawMode;
|
|
babylonMaterial.enableSpecularAntiAliasing = true;
|
|
babylonMaterial.enableSpecularAntiAliasing = true;
|
|
- babylonMaterial.useRadianceOverAlpha = !this.transparencyAsCoverage;
|
|
|
|
- babylonMaterial.useSpecularOverAlpha = !this.transparencyAsCoverage;
|
|
|
|
|
|
+ babylonMaterial.useRadianceOverAlpha = !this._parent.transparencyAsCoverage;
|
|
|
|
+ babylonMaterial.useSpecularOverAlpha = !this._parent.transparencyAsCoverage;
|
|
return babylonMaterial;
|
|
return babylonMaterial;
|
|
}
|
|
}
|
|
|
|
|
|
- /** @hidden */
|
|
|
|
public _loadMaterialBasePropertiesAsync(context: string, material: _ILoaderMaterial, babylonMaterial: PBRMaterial): Promise<void> {
|
|
public _loadMaterialBasePropertiesAsync(context: string, material: _ILoaderMaterial, babylonMaterial: PBRMaterial): Promise<void> {
|
|
const promises = new Array<Promise<void>>();
|
|
const promises = new Array<Promise<void>>();
|
|
|
|
|
|
@@ -1433,7 +1367,6 @@ module BABYLON.GLTF2 {
|
|
return Promise.all(promises).then(() => {});
|
|
return Promise.all(promises).then(() => {});
|
|
}
|
|
}
|
|
|
|
|
|
- /** @hidden */
|
|
|
|
public _loadMaterialAlphaProperties(context: string, material: _ILoaderMaterial, babylonMaterial: PBRMaterial): void {
|
|
public _loadMaterialAlphaProperties(context: string, material: _ILoaderMaterial, babylonMaterial: PBRMaterial): void {
|
|
const alphaMode = material.alphaMode || MaterialAlphaMode.OPAQUE;
|
|
const alphaMode = material.alphaMode || MaterialAlphaMode.OPAQUE;
|
|
switch (alphaMode) {
|
|
switch (alphaMode) {
|
|
@@ -1463,18 +1396,21 @@ module BABYLON.GLTF2 {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- /** @hidden */
|
|
|
|
public _loadTextureAsync(context: string, textureInfo: ITextureInfo, assign: (texture: Texture) => void): Promise<void> {
|
|
public _loadTextureAsync(context: string, textureInfo: ITextureInfo, assign: (texture: Texture) => void): Promise<void> {
|
|
const promise = GLTFLoaderExtension._LoadTextureAsync(this, context, textureInfo, assign);
|
|
const promise = GLTFLoaderExtension._LoadTextureAsync(this, context, textureInfo, assign);
|
|
if (promise) {
|
|
if (promise) {
|
|
return promise;
|
|
return promise;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ this._parent._logOpen(`${context}`);
|
|
|
|
+
|
|
const texture = GLTFLoader._GetProperty(`${context}/index`, this._gltf.textures, textureInfo.index);
|
|
const texture = GLTFLoader._GetProperty(`${context}/index`, this._gltf.textures, textureInfo.index);
|
|
context = `#/textures/${textureInfo.index}`;
|
|
context = `#/textures/${textureInfo.index}`;
|
|
|
|
|
|
const promises = new Array<Promise<void>>();
|
|
const promises = new Array<Promise<void>>();
|
|
|
|
|
|
|
|
+ this._parent._logOpen(`${context} ${texture.name || ""}`);
|
|
|
|
+
|
|
const sampler = (texture.sampler == undefined ? this._defaultSampler : GLTFLoader._GetProperty(`${context}/sampler`, this._gltf.samplers, texture.sampler));
|
|
const sampler = (texture.sampler == undefined ? this._defaultSampler : GLTFLoader._GetProperty(`${context}/sampler`, this._gltf.samplers, texture.sampler));
|
|
const samplerData = this._loadSampler(`#/samplers/${sampler._index}`, sampler);
|
|
const samplerData = this._loadSampler(`#/samplers/${sampler._index}`, sampler);
|
|
|
|
|
|
@@ -1502,7 +1438,10 @@ module BABYLON.GLTF2 {
|
|
}));
|
|
}));
|
|
|
|
|
|
assign(babylonTexture);
|
|
assign(babylonTexture);
|
|
- this.onTextureLoadedObservable.notifyObservers(babylonTexture);
|
|
|
|
|
|
+ this._parent.onTextureLoadedObservable.notifyObservers(babylonTexture);
|
|
|
|
+
|
|
|
|
+ this._parent._logClose();
|
|
|
|
+ this._parent._logClose();
|
|
|
|
|
|
return Promise.all(promises).then(() => {});
|
|
return Promise.all(promises).then(() => {});
|
|
}
|
|
}
|
|
@@ -1521,27 +1460,28 @@ module BABYLON.GLTF2 {
|
|
}
|
|
}
|
|
|
|
|
|
private _loadImageAsync(context: string, image: _ILoaderImage): Promise<Blob> {
|
|
private _loadImageAsync(context: string, image: _ILoaderImage): Promise<Blob> {
|
|
- if (image._blob) {
|
|
|
|
- return image._blob;
|
|
|
|
- }
|
|
|
|
|
|
+ if (!image._blob) {
|
|
|
|
+ this._parent._logOpen(`${context} ${image.name || ""}`);
|
|
|
|
|
|
- let promise: Promise<ArrayBufferView>;
|
|
|
|
- if (image.uri) {
|
|
|
|
- promise = this._loadUriAsync(context, image.uri);
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- const bufferView = GLTFLoader._GetProperty(`${context}/bufferView`, this._gltf.bufferViews, image.bufferView);
|
|
|
|
- promise = this._loadBufferViewAsync(`#/bufferViews/${bufferView._index}`, bufferView);
|
|
|
|
- }
|
|
|
|
|
|
+ let promise: Promise<ArrayBufferView>;
|
|
|
|
+ if (image.uri) {
|
|
|
|
+ promise = this._loadUriAsync(context, image.uri);
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ const bufferView = GLTFLoader._GetProperty(`${context}/bufferView`, this._gltf.bufferViews, image.bufferView);
|
|
|
|
+ promise = this._loadBufferViewAsync(`#/bufferViews/${bufferView._index}`, bufferView);
|
|
|
|
+ }
|
|
|
|
|
|
- image._blob = promise.then(data => {
|
|
|
|
- return new Blob([data], { type: image.mimeType });
|
|
|
|
- });
|
|
|
|
|
|
+ image._blob = promise.then(data => {
|
|
|
|
+ return new Blob([data], { type: image.mimeType });
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ this._parent._logClose();
|
|
|
|
+ }
|
|
|
|
|
|
return image._blob;
|
|
return image._blob;
|
|
}
|
|
}
|
|
|
|
|
|
- /** @hidden */
|
|
|
|
public _loadUriAsync(context: string, uri: string): Promise<ArrayBufferView> {
|
|
public _loadUriAsync(context: string, uri: string): Promise<ArrayBufferView> {
|
|
const promise = GLTFLoaderExtension._LoadUriAsync(this, context, uri);
|
|
const promise = GLTFLoaderExtension._LoadUriAsync(this, context, uri);
|
|
if (promise) {
|
|
if (promise) {
|
|
@@ -1553,28 +1493,37 @@ module BABYLON.GLTF2 {
|
|
}
|
|
}
|
|
|
|
|
|
if (Tools.IsBase64(uri)) {
|
|
if (Tools.IsBase64(uri)) {
|
|
- return Promise.resolve(new Uint8Array(Tools.DecodeBase64(uri)));
|
|
|
|
|
|
+ const data = new Uint8Array(Tools.DecodeBase64(uri));
|
|
|
|
+ this._parent._log(`Decoded ${uri.substr(0, 64)}... (${data.length} bytes)`);
|
|
|
|
+ return Promise.resolve(data);
|
|
}
|
|
}
|
|
|
|
|
|
- return this.preprocessUrlAsync(this._rootUrl + uri).then(url => {
|
|
|
|
|
|
+ this._parent._log(`Loading ${uri}`);
|
|
|
|
+
|
|
|
|
+ return this._parent.preprocessUrlAsync(this._rootUrl + uri).then(url => {
|
|
return new Promise<ArrayBufferView>((resolve, reject) => {
|
|
return new Promise<ArrayBufferView>((resolve, reject) => {
|
|
if (!this._disposed) {
|
|
if (!this._disposed) {
|
|
- const request = Tools.LoadFile(url, data => {
|
|
|
|
|
|
+ const request = Tools.LoadFile(url, fileData => {
|
|
if (!this._disposed) {
|
|
if (!this._disposed) {
|
|
- resolve(new Uint8Array(data as ArrayBuffer));
|
|
|
|
|
|
+ const data = new Uint8Array(fileData as ArrayBuffer);
|
|
|
|
+ this._parent._log(`Loaded ${uri} (${data.length} bytes)`);
|
|
|
|
+ resolve(data);
|
|
}
|
|
}
|
|
}, event => {
|
|
}, event => {
|
|
if (!this._disposed) {
|
|
if (!this._disposed) {
|
|
- try {
|
|
|
|
- if (request && this._state === GLTFLoaderState.LOADING) {
|
|
|
|
- request._lengthComputable = event.lengthComputable;
|
|
|
|
- request._loaded = event.loaded;
|
|
|
|
- request._total = event.total;
|
|
|
|
|
|
+ if (request) {
|
|
|
|
+ request._lengthComputable = event.lengthComputable;
|
|
|
|
+ request._loaded = event.loaded;
|
|
|
|
+ request._total = event.total;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this._state === GLTFLoaderState.LOADING) {
|
|
|
|
+ try {
|
|
this._onProgress();
|
|
this._onProgress();
|
|
}
|
|
}
|
|
- }
|
|
|
|
- catch (e) {
|
|
|
|
- reject(e);
|
|
|
|
|
|
+ catch (e) {
|
|
|
|
+ reject(e);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}, this._babylonScene.database, true, (request, exception) => {
|
|
}, this._babylonScene.database, true, (request, exception) => {
|
|
@@ -1610,7 +1559,6 @@ module BABYLON.GLTF2 {
|
|
this._progressCallback(new SceneLoaderProgressEvent(lengthComputable, loaded, lengthComputable ? total : 0));
|
|
this._progressCallback(new SceneLoaderProgressEvent(lengthComputable, loaded, lengthComputable ? total : 0));
|
|
}
|
|
}
|
|
|
|
|
|
- /** @hidden */
|
|
|
|
public static _GetProperty<T>(context: string, array: ArrayLike<T> | undefined, index: number | undefined): T {
|
|
public static _GetProperty<T>(context: string, array: ArrayLike<T> | undefined, index: number | undefined): T {
|
|
if (!array || index == undefined || !array[index]) {
|
|
if (!array || index == undefined || !array[index]) {
|
|
throw new Error(`${context}: Failed to find index (${index})`);
|
|
throw new Error(`${context}: Failed to find index (${index})`);
|
|
@@ -1740,7 +1688,7 @@ module BABYLON.GLTF2 {
|
|
|
|
|
|
const babylonMaterial = babylonData.material;
|
|
const babylonMaterial = babylonData.material;
|
|
promises.push(babylonMaterial.forceCompilationAsync(babylonMesh));
|
|
promises.push(babylonMaterial.forceCompilationAsync(babylonMesh));
|
|
- if (this.useClipPlane) {
|
|
|
|
|
|
+ if (this._parent.useClipPlane) {
|
|
promises.push(babylonMaterial.forceCompilationAsync(babylonMesh, { clipPlane: true }));
|
|
promises.push(babylonMaterial.forceCompilationAsync(babylonMesh, { clipPlane: true }));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1766,35 +1714,7 @@ module BABYLON.GLTF2 {
|
|
return Promise.all(promises).then(() => {});
|
|
return Promise.all(promises).then(() => {});
|
|
}
|
|
}
|
|
|
|
|
|
- private _clear(): void {
|
|
|
|
- for (const request of this._requests) {
|
|
|
|
- request.abort();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- this._requests.length = 0;
|
|
|
|
-
|
|
|
|
- delete this._gltf;
|
|
|
|
- delete this._babylonScene;
|
|
|
|
- this._completePromises.length = 0;
|
|
|
|
- this._onReadyObservable.clear();
|
|
|
|
-
|
|
|
|
- for (const name in this._extensions) {
|
|
|
|
- this._extensions[name].dispose();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- this._extensions = {};
|
|
|
|
-
|
|
|
|
- delete this._rootBabylonMesh;
|
|
|
|
- delete this._progressCallback;
|
|
|
|
-
|
|
|
|
- this.onMeshLoadedObservable.clear();
|
|
|
|
- this.onTextureLoadedObservable.clear();
|
|
|
|
- this.onMaterialLoadedObservable.clear();
|
|
|
|
- this.onCameraLoadedObservable.clear();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /** @hidden */
|
|
|
|
- public _applyExtensions<T>(actionAsync: (extension: GLTFLoaderExtension) => Nullable<Promise<T>>) {
|
|
|
|
|
|
+ public _applyExtensions<T>(actionAsync: (extension: GLTFLoaderExtension) => Nullable<Promise<T>>): Nullable<Promise<T>> {
|
|
for (const name of GLTFLoader._ExtensionNames) {
|
|
for (const name of GLTFLoader._ExtensionNames) {
|
|
const extension = this._extensions[name];
|
|
const extension = this._extensions[name];
|
|
if (extension.enabled) {
|
|
if (extension.enabled) {
|
|
@@ -1809,5 +1729,5 @@ module BABYLON.GLTF2 {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- GLTFFileLoader._CreateGLTFLoaderV2 = () => new GLTFLoader();
|
|
|
|
|
|
+ GLTFFileLoader._CreateGLTFLoaderV2 = parent => new GLTFLoader(parent);
|
|
}
|
|
}
|