Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bug with MSFT_lod extension in glTF loader #4499

Merged
merged 1 commit into from
Jun 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,12 @@ module BABYLON.GLTF2.Extensions {
export class KHR_materials_pbrSpecularGlossiness extends GLTFLoaderExtension {
public readonly name = NAME;

protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>> {
protected _loadMaterialPropertiesAsync(context: string, material: _ILoaderMaterial, babylonMaterial: Material): Nullable<Promise<void>> {
return this._loadExtensionAsync<IKHRMaterialsPbrSpecularGlossiness>(context, material, (extensionContext, extension) => {
material._babylonData = material._babylonData || {};
let babylonData = material._babylonData[babylonDrawMode];
if (!babylonData) {
const promises = new Array<Promise<void>>();

const name = material.name || `materialSG_${material._index}`;
const babylonMaterial = this._loader._createMaterial(name, babylonDrawMode);

promises.push(this._loader._loadMaterialBasePropertiesAsync(context, material, babylonMaterial));
promises.push(this._loadSpecularGlossinessPropertiesAsync(extensionContext, material, extension, babylonMaterial));

this._loader._parent.onMaterialLoadedObservable.notifyObservers(babylonMaterial);

babylonData = {
material: babylonMaterial,
meshes: [],
loaded: Promise.all(promises).then(() => {})
};

material._babylonData[babylonDrawMode] = babylonData;
}

babylonData.meshes.push(babylonMesh);

assign(babylonData.material);
return babylonData.loaded;
const promises = new Array<Promise<void>>();
promises.push(this._loader._loadMaterialBasePropertiesAsync(context, material, babylonMaterial as PBRMaterial));
promises.push(this._loadSpecularGlossinessPropertiesAsync(extensionContext, material, extension, babylonMaterial as PBRMaterial));
return Promise.all(promises).then(() => {});
});
}

Expand Down
29 changes: 4 additions & 25 deletions loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,17 @@ module BABYLON.GLTF2.Extensions {
export class KHR_materials_unlit extends GLTFLoaderExtension {
public readonly name = NAME;

protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>> {
protected _loadMaterialPropertiesAsync(context: string, material: _ILoaderMaterial, babylonMaterial: Material): Nullable<Promise<void>> {
return this._loadExtensionAsync<{}>(context, material, () => {
material._babylonData = material._babylonData || {};
let babylonData = material._babylonData[babylonDrawMode];
if (!babylonData) {
const name = material.name || `materialUnlit_${material._index}`;
const babylonMaterial = this._loader._createMaterial(name, babylonDrawMode);
babylonMaterial.unlit = true;

const promise = this._loadUnlitPropertiesAsync(context, material, babylonMaterial);

this._loader._parent.onMaterialLoadedObservable.notifyObservers(babylonMaterial);

babylonData = {
material: babylonMaterial,
meshes: [],
loaded: promise
};

material._babylonData[babylonDrawMode] = babylonData;
}

babylonData.meshes.push(babylonMesh);

assign(babylonData.material);
return babylonData.loaded;
return this._loadUnlitPropertiesAsync(context, material, babylonMaterial as PBRMaterial);
});
}

private _loadUnlitPropertiesAsync(context: string, material: _ILoaderMaterial, babylonMaterial: PBRMaterial): Promise<void> {
const promises = new Array<Promise<void>>();

babylonMaterial.unlit = true;

// Ensure metallic workflow
babylonMaterial.metallic = 1;
babylonMaterial.roughness = 1;
Expand Down
20 changes: 19 additions & 1 deletion loaders/src/glTF/2.0/Extensions/MSFT_lod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,9 @@ module BABYLON.GLTF2.Extensions {
if (indexLOD !== 0) {
const previousNodeLOD = nodeLODs[indexLOD - 1];
if (previousNodeLOD._babylonMesh) {
previousNodeLOD._babylonMesh.dispose(false, true);
previousNodeLOD._babylonMesh.dispose();
delete previousNodeLOD._babylonMesh;
this._disposeUnusedMaterials();
}
}
});
Expand Down Expand Up @@ -228,6 +229,23 @@ module BABYLON.GLTF2.Extensions {
properties.push(property);
return properties;
}

private _disposeUnusedMaterials(): void {
const materials = this._loader._gltf.materials;
if (materials) {
for (const material of materials) {
if (material._babylonData) {
for (const drawMode in material._babylonData) {
const babylonData = material._babylonData[drawMode];
if (babylonData.meshes.length === 0) {
babylonData.material.dispose(false, true);
delete material._babylonData[drawMode];
}
}
}
}
}
}
}

GLTFLoader._Register(NAME, loader => new MSFT_lod(loader));
Expand Down
31 changes: 22 additions & 9 deletions loaders/src/glTF/2.0/babylon.glTFLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1286,35 +1286,48 @@ module BABYLON.GLTF2 {
material._babylonData = material._babylonData || {};
let babylonData = material._babylonData[babylonDrawMode];
if (!babylonData) {
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);

promises.push(this._loadMaterialBasePropertiesAsync(context, material, babylonMaterial));
promises.push(this._loadMaterialMetallicRoughnessPropertiesAsync(context, material, babylonMaterial));

this._parent.onMaterialLoadedObservable.notifyObservers(babylonMaterial);

babylonData = {
material: babylonMaterial,
meshes: [],
loaded: Promise.all(promises).then(() => {})
loaded: this._loadMaterialPropertiesAsync(context, material, babylonMaterial)
};

material._babylonData[babylonDrawMode] = babylonData;

this._parent.onMaterialLoadedObservable.notifyObservers(babylonMaterial);

this._parent._logClose();
}

babylonData.meshes.push(babylonMesh);
babylonMesh.onDisposeObservable.addOnce(() => {
const index = babylonData.meshes.indexOf(babylonMesh);
if (index !== -1) {
babylonData.meshes.splice(index, 1);
}
});

assign(babylonData.material);
return babylonData.loaded;
}

public _loadMaterialPropertiesAsync(context: string, material: _ILoaderMaterial, babylonMaterial: Material): Promise<void> {
const promise = GLTFLoaderExtension._LoadMaterialPropertiesAsync(this, context, material, babylonMaterial);
if (promise) {
return promise;
}

const promises = new Array<Promise<void>>();
promises.push(this._loadMaterialBasePropertiesAsync(context, material, babylonMaterial as PBRMaterial));
promises.push(this._loadMaterialMetallicRoughnessPropertiesAsync(context, material, babylonMaterial as PBRMaterial));
return Promise.all(promises).then(() => {});
}

public _createMaterial(name: string, drawMode: number): PBRMaterial {
const babylonMaterial = new PBRMaterial(name, this._babylonScene);
babylonMaterial.sideOrientation = this._babylonScene.useRightHandedSystem ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation;
Expand Down
14 changes: 14 additions & 0 deletions loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ module BABYLON.GLTF2 {
*/
protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>> { return null; }

/**
* Override this method to modify the default behavior for loading material properties.
* @hidden
*/
protected _loadMaterialPropertiesAsync(context: string, material: _ILoaderMaterial, babylonMaterial: Material): Nullable<Promise<void>> { return null; }

/**
* Override this method to modify the default behavior for loading textures.
* @hidden
Expand Down Expand Up @@ -160,6 +166,14 @@ module BABYLON.GLTF2 {
return loader._applyExtensions(extension => extension._loadMaterialAsync(context, material, mesh, babylonMesh, babylonDrawMode, assign));
}

/**
* Helper method called by the loader to allow extensions to override loading material properties.
* @hidden
*/
public static _LoadMaterialPropertiesAsync(loader: GLTFLoader, context: string, material: _ILoaderMaterial, babylonMaterial: Material): Nullable<Promise<void>> {
return loader._applyExtensions(extension => extension._loadMaterialPropertiesAsync(context, material, babylonMaterial));
}

/**
* Helper method called by the loader to allow extensions to override loading textures.
* @hidden
Expand Down