|
@@ -1,5 +1,8 @@
|
|
/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
|
|
/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+* Defines the GLTF2 module used to import/export GLTF 2.0 files
|
|
|
|
+*/
|
|
module BABYLON.GLTF2 {
|
|
module BABYLON.GLTF2 {
|
|
interface IFileRequestInfo extends IFileRequest {
|
|
interface IFileRequestInfo extends IFileRequest {
|
|
_lengthComputable?: boolean;
|
|
_lengthComputable?: boolean;
|
|
@@ -7,14 +10,37 @@ module BABYLON.GLTF2 {
|
|
_total?: number;
|
|
_total?: number;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Interface for a meterial with a constructor
|
|
|
|
+ */
|
|
export interface MaterialConstructor<T extends Material> {
|
|
export interface MaterialConstructor<T extends Material> {
|
|
|
|
+ /**
|
|
|
|
+ * The material class
|
|
|
|
+ */
|
|
readonly prototype: T;
|
|
readonly prototype: T;
|
|
|
|
+ /**
|
|
|
|
+ * Instatiates a material
|
|
|
|
+ * @param name name of the material
|
|
|
|
+ * @param scene the scene the material will be added to
|
|
|
|
+ */
|
|
new(name: string, scene: Scene): T;
|
|
new(name: string, scene: Scene): T;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Used to load from a GLTF2 file
|
|
|
|
+ */
|
|
export class GLTFLoader implements IGLTFLoader {
|
|
export class GLTFLoader implements IGLTFLoader {
|
|
|
|
+ /**
|
|
|
|
+ * Internal
|
|
|
|
+ */
|
|
public _gltf: ILoaderGLTF;
|
|
public _gltf: ILoaderGLTF;
|
|
|
|
+ /**
|
|
|
|
+ * Internal
|
|
|
|
+ */
|
|
public _babylonScene: Scene;
|
|
public _babylonScene: Scene;
|
|
|
|
+ /**
|
|
|
|
+ * Internal
|
|
|
|
+ */
|
|
public _completePromises = new Array<Promise<void>>();
|
|
public _completePromises = new Array<Promise<void>>();
|
|
|
|
|
|
private _disposed = false;
|
|
private _disposed = false;
|
|
@@ -29,6 +55,11 @@ module BABYLON.GLTF2 {
|
|
|
|
|
|
private static _Names = new Array<string>();
|
|
private static _Names = new Array<string>();
|
|
private static _Factories: { [name: string]: (loader: GLTFLoader) => GLTFLoaderExtension } = {};
|
|
private static _Factories: { [name: string]: (loader: GLTFLoader) => GLTFLoaderExtension } = {};
|
|
|
|
+ /**
|
|
|
|
+ * Internal, registers the loader
|
|
|
|
+ * @param name name of the loader
|
|
|
|
+ * @param factory function that converts a loader to a loader extension
|
|
|
|
+ */
|
|
public static _Register(name: string, factory: (loader: GLTFLoader) => GLTFLoaderExtension): void {
|
|
public static _Register(name: string, factory: (loader: GLTFLoader) => GLTFLoaderExtension): void {
|
|
if (GLTFLoader._Factories[name]) {
|
|
if (GLTFLoader._Factories[name]) {
|
|
Tools.Error(`Extension with the name '${name}' already exists`);
|
|
Tools.Error(`Extension with the name '${name}' already exists`);
|
|
@@ -41,23 +72,62 @@ module BABYLON.GLTF2 {
|
|
GLTFLoader._Names.push(name);
|
|
GLTFLoader._Names.push(name);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Coordinate system that will be used when loading from the gltf file
|
|
|
|
+ */
|
|
public coordinateSystemMode = GLTFLoaderCoordinateSystemMode.AUTO;
|
|
public coordinateSystemMode = GLTFLoaderCoordinateSystemMode.AUTO;
|
|
|
|
+ /**
|
|
|
|
+ * Animation mode that determines which animations should be started when a file is loaded
|
|
|
|
+ */
|
|
public animationStartMode = GLTFLoaderAnimationStartMode.FIRST;
|
|
public animationStartMode = GLTFLoaderAnimationStartMode.FIRST;
|
|
|
|
+ /**
|
|
|
|
+ * If the materials in the file should automatically be compiled
|
|
|
|
+ */
|
|
public compileMaterials = false;
|
|
public compileMaterials = false;
|
|
|
|
+ /**
|
|
|
|
+ * If a clip plane should be usede when loading meshes in the file
|
|
|
|
+ */
|
|
public useClipPlane = false;
|
|
public useClipPlane = false;
|
|
|
|
+ /**
|
|
|
|
+ * If shadow generators should automatically be compiled
|
|
|
|
+ */
|
|
public compileShadowGenerators = false;
|
|
public compileShadowGenerators = false;
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Observable that fires when the loader is disposed
|
|
|
|
+ */
|
|
public readonly onDisposeObservable = new Observable<IGLTFLoader>();
|
|
public readonly onDisposeObservable = new Observable<IGLTFLoader>();
|
|
|
|
+ /**
|
|
|
|
+ * Observable that fires each time a mesh is loaded
|
|
|
|
+ */
|
|
public readonly onMeshLoadedObservable = new Observable<AbstractMesh>();
|
|
public readonly onMeshLoadedObservable = new Observable<AbstractMesh>();
|
|
|
|
+ /**
|
|
|
|
+ * Observable that fires each time a texture is loaded
|
|
|
|
+ */
|
|
public readonly onTextureLoadedObservable = new Observable<BaseTexture>();
|
|
public readonly onTextureLoadedObservable = new Observable<BaseTexture>();
|
|
|
|
+ /**
|
|
|
|
+ * Observable that fires each time a material is loaded
|
|
|
|
+ */
|
|
public readonly onMaterialLoadedObservable = new Observable<Material>();
|
|
public readonly onMaterialLoadedObservable = new Observable<Material>();
|
|
|
|
+ /**
|
|
|
|
+ * Observable that fires each time an extension is loaded
|
|
|
|
+ */
|
|
public readonly onExtensionLoadedObservable = new Observable<IGLTFLoaderExtension>();
|
|
public readonly onExtensionLoadedObservable = new Observable<IGLTFLoaderExtension>();
|
|
|
|
+ /**
|
|
|
|
+ * Observable that fires when the load has completed
|
|
|
|
+ */
|
|
public readonly onCompleteObservable = new Observable<IGLTFLoader>();
|
|
public readonly onCompleteObservable = new Observable<IGLTFLoader>();
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * The current state of the loader
|
|
|
|
+ */
|
|
public get state(): Nullable<GLTFLoaderState> {
|
|
public get state(): Nullable<GLTFLoaderState> {
|
|
return this._state;
|
|
return this._state;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Disposes of the loader
|
|
|
|
+ */
|
|
public dispose(): void {
|
|
public dispose(): void {
|
|
if (this._disposed) {
|
|
if (this._disposed) {
|
|
return;
|
|
return;
|
|
@@ -71,6 +141,14 @@ module BABYLON.GLTF2 {
|
|
this._clear();
|
|
this._clear();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Imports one or more meshes from a loaded gltf file 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 gltf data containing information of the meshes in a loaded file
|
|
|
|
+ * @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(() => {
|
|
let nodes: Nullable<Array<ILoaderNode>> = null;
|
|
let nodes: Nullable<Array<ILoaderNode>> = null;
|
|
@@ -107,6 +185,13 @@ module BABYLON.GLTF2 {
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Imports all objects from a loaded gltf file and adds them to the scene
|
|
|
|
+ * @param scene the scene the objects should be added to
|
|
|
|
+ * @param data gltf data containing information of the meshes in a loaded file
|
|
|
|
+ * @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 this._loadAsync(null, scene, data, rootUrl, onProgress);
|
|
return this._loadAsync(null, scene, data, rootUrl, onProgress);
|
|
}
|
|
}
|
|
@@ -286,6 +371,9 @@ module BABYLON.GLTF2 {
|
|
return Promise.all(promises).then(() => {});
|
|
return Promise.all(promises).then(() => {});
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Internal
|
|
|
|
+ */
|
|
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) {
|
|
@@ -396,6 +484,9 @@ module BABYLON.GLTF2 {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Internal
|
|
|
|
+ */
|
|
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) {
|
|
@@ -1001,6 +1092,9 @@ module BABYLON.GLTF2 {
|
|
return buffer._data;
|
|
return buffer._data;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Internal
|
|
|
|
+ */
|
|
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;
|
|
@@ -1067,6 +1161,9 @@ module BABYLON.GLTF2 {
|
|
return accessor._data;
|
|
return accessor._data;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Internal
|
|
|
|
+ */
|
|
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;
|
|
@@ -1153,6 +1250,9 @@ module BABYLON.GLTF2 {
|
|
return Promise.all(promises).then(() => {});
|
|
return Promise.all(promises).then(() => {});
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Internal
|
|
|
|
+ */
|
|
public _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Promise<void> {
|
|
public _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Promise<void> {
|
|
const promise = GLTFLoaderExtension._LoadMaterialAsync(this, context, material, babylonMesh, babylonDrawMode, assign);
|
|
const promise = GLTFLoaderExtension._LoadMaterialAsync(this, context, material, babylonMesh, babylonDrawMode, assign);
|
|
if (promise) {
|
|
if (promise) {
|
|
@@ -1187,6 +1287,9 @@ module BABYLON.GLTF2 {
|
|
return babylonData.loaded;
|
|
return babylonData.loaded;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Internal
|
|
|
|
+ */
|
|
public _createMaterial<T extends Material>(type: MaterialConstructor<T>, name: string, drawMode: number): T {
|
|
public _createMaterial<T extends Material>(type: MaterialConstructor<T>, name: string, drawMode: number): T {
|
|
const babylonMaterial = new type(name, this._babylonScene);
|
|
const babylonMaterial = new type(name, this._babylonScene);
|
|
babylonMaterial.sideOrientation = this._babylonScene.useRightHandedSystem ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation;
|
|
babylonMaterial.sideOrientation = this._babylonScene.useRightHandedSystem ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation;
|
|
@@ -1194,6 +1297,9 @@ module BABYLON.GLTF2 {
|
|
return babylonMaterial;
|
|
return babylonMaterial;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Internal
|
|
|
|
+ */
|
|
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>>();
|
|
|
|
|
|
@@ -1235,6 +1341,9 @@ module BABYLON.GLTF2 {
|
|
return Promise.all(promises).then(() => {});
|
|
return Promise.all(promises).then(() => {});
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Internal
|
|
|
|
+ */
|
|
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) {
|
|
@@ -1264,6 +1373,9 @@ module BABYLON.GLTF2 {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Internal
|
|
|
|
+ */
|
|
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 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}`;
|
|
@@ -1335,6 +1447,9 @@ module BABYLON.GLTF2 {
|
|
return image._objectURL;
|
|
return image._objectURL;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Internal
|
|
|
|
+ */
|
|
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) {
|
|
@@ -1399,6 +1514,9 @@ module BABYLON.GLTF2 {
|
|
this._progressCallback(new SceneLoaderProgressEvent(lengthComputable, loaded, lengthComputable ? total : 0));
|
|
this._progressCallback(new SceneLoaderProgressEvent(lengthComputable, loaded, lengthComputable ? total : 0));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Internal
|
|
|
|
+ */
|
|
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})`);
|
|
@@ -1571,6 +1689,9 @@ module BABYLON.GLTF2 {
|
|
this.onMaterialLoadedObservable.clear();
|
|
this.onMaterialLoadedObservable.clear();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Internal
|
|
|
|
+ */
|
|
public _applyExtensions<T>(actionAsync: (extension: GLTFLoaderExtension) => Nullable<Promise<T>>) {
|
|
public _applyExtensions<T>(actionAsync: (extension: GLTFLoaderExtension) => Nullable<Promise<T>>) {
|
|
for (const name of GLTFLoader._Names) {
|
|
for (const name of GLTFLoader._Names) {
|
|
const extension = this._extensions[name];
|
|
const extension = this._extensions[name];
|