|
@@ -16,6 +16,9 @@ THREE.GLTFLoader = ( function () {
|
|
|
this.dracoLoader = null;
|
|
|
this.ddsLoader = null;
|
|
|
|
|
|
+ this.pluginCallbacks = [];
|
|
|
+ this.register( function ( parser ) { return new GLTFMaterialsClearcoatExtension( parser ); } );
|
|
|
+
|
|
|
}
|
|
|
|
|
|
GLTFLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), {
|
|
@@ -112,10 +115,35 @@ THREE.GLTFLoader = ( function () {
|
|
|
|
|
|
},
|
|
|
|
|
|
+ register: function ( callback ) {
|
|
|
+
|
|
|
+ if ( this.pluginCallbacks.indexOf( callback ) === -1 ) {
|
|
|
+
|
|
|
+ this.pluginCallbacks.push( callback );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return this;
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
+ unregister: function ( callback ) {
|
|
|
+
|
|
|
+ if ( this.pluginCallbacks.indexOf( callback ) !== -1 ) {
|
|
|
+
|
|
|
+ this.pluginCallbacks.splice( this.pluginCallbacks.indexOf( callback ), 1 );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return this;
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
parse: function ( data, path, onLoad, onError ) {
|
|
|
|
|
|
var content;
|
|
|
var extensions = {};
|
|
|
+ var plugins = {};
|
|
|
|
|
|
if ( typeof data === 'string' ) {
|
|
|
|
|
@@ -157,6 +185,29 @@ THREE.GLTFLoader = ( function () {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ var parser = new GLTFParser( json, {
|
|
|
+
|
|
|
+ path: path || this.resourcePath || '',
|
|
|
+ crossOrigin: this.crossOrigin,
|
|
|
+ manager: this.manager
|
|
|
+
|
|
|
+ } );
|
|
|
+
|
|
|
+ parser.fileLoader.setRequestHeader( this.requestHeader );
|
|
|
+
|
|
|
+ for ( var i = 0; i < this.pluginCallbacks.length; i ++ ) {
|
|
|
+
|
|
|
+ var plugin = this.pluginCallbacks[ i ]( parser );
|
|
|
+ plugins[ plugin.name ] = plugin;
|
|
|
+
|
|
|
+ // Workaround to avoid determining as unknown extension
|
|
|
+ // in addUnknownExtensionsToUserData().
|
|
|
+ // Remove this workaround if we move all the existing
|
|
|
+ // extension handlers to plugin system
|
|
|
+ extensions[ plugin.name ] = true;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
if ( json.extensionsUsed ) {
|
|
|
|
|
|
for ( var i = 0; i < json.extensionsUsed.length; ++ i ) {
|
|
@@ -170,10 +221,6 @@ THREE.GLTFLoader = ( function () {
|
|
|
extensions[ extensionName ] = new GLTFLightsExtension( json );
|
|
|
break;
|
|
|
|
|
|
- case EXTENSIONS.KHR_MATERIALS_CLEARCOAT:
|
|
|
- extensions[ extensionName ] = new GLTFMaterialsClearcoatExtension();
|
|
|
- break;
|
|
|
-
|
|
|
case EXTENSIONS.KHR_MATERIALS_UNLIT:
|
|
|
extensions[ extensionName ] = new GLTFMaterialsUnlitExtension();
|
|
|
break;
|
|
@@ -200,7 +247,7 @@ THREE.GLTFLoader = ( function () {
|
|
|
|
|
|
default:
|
|
|
|
|
|
- if ( extensionsRequired.indexOf( extensionName ) >= 0 ) {
|
|
|
+ if ( extensionsRequired.indexOf( extensionName ) >= 0 && plugins[ extensionName ] === undefined ) {
|
|
|
|
|
|
console.warn( 'THREE.GLTFLoader: Unknown extension "' + extensionName + '".' );
|
|
|
|
|
@@ -212,15 +259,8 @@ THREE.GLTFLoader = ( function () {
|
|
|
|
|
|
}
|
|
|
|
|
|
- var parser = new GLTFParser( json, extensions, {
|
|
|
-
|
|
|
- path: path || this.resourcePath || '',
|
|
|
- crossOrigin: this.crossOrigin,
|
|
|
- manager: this.manager
|
|
|
-
|
|
|
- } );
|
|
|
-
|
|
|
- parser.fileLoader.setRequestHeader( this.requestHeader );
|
|
|
+ parser.setExtensions( extensions );
|
|
|
+ parser.setPlugins( plugins );
|
|
|
parser.parse( onLoad, onError );
|
|
|
|
|
|
}
|
|
@@ -421,19 +461,29 @@ THREE.GLTFLoader = ( function () {
|
|
|
*
|
|
|
* Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat
|
|
|
*/
|
|
|
- function GLTFMaterialsClearcoatExtension() {
|
|
|
+ function GLTFMaterialsClearcoatExtension( parser ) {
|
|
|
|
|
|
+ this.parser = parser;
|
|
|
this.name = EXTENSIONS.KHR_MATERIALS_CLEARCOAT;
|
|
|
|
|
|
}
|
|
|
|
|
|
- GLTFMaterialsClearcoatExtension.prototype.getMaterialType = function () {
|
|
|
+ GLTFMaterialsClearcoatExtension.prototype.getMaterialType = function ( materialIndex ) {
|
|
|
|
|
|
return THREE.MeshPhysicalMaterial;
|
|
|
|
|
|
};
|
|
|
|
|
|
- GLTFMaterialsClearcoatExtension.prototype.extendParams = function ( materialParams, materialDef, parser ) {
|
|
|
+ GLTFMaterialsClearcoatExtension.prototype.extendMaterialParams = function ( materialIndex, materialParams ) {
|
|
|
+
|
|
|
+ var parser = this.parser;
|
|
|
+ var materialDef = parser.json.materials[ materialIndex ];
|
|
|
+
|
|
|
+ if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
|
|
|
+
|
|
|
+ return Promise.resolve();
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
var pending = [];
|
|
|
|
|
@@ -1398,10 +1448,11 @@ THREE.GLTFLoader = ( function () {
|
|
|
|
|
|
/* GLTF PARSER */
|
|
|
|
|
|
- function GLTFParser( json, extensions, options ) {
|
|
|
+ function GLTFParser( json, options ) {
|
|
|
|
|
|
this.json = json || {};
|
|
|
- this.extensions = extensions || {};
|
|
|
+ this.extensions = {};
|
|
|
+ this.plugins = {};
|
|
|
this.options = options || {};
|
|
|
|
|
|
// loader object cache
|
|
@@ -1435,6 +1486,18 @@ THREE.GLTFLoader = ( function () {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ GLTFParser.prototype.setExtensions = function ( extensions ) {
|
|
|
+
|
|
|
+ this.extensions = extensions;
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
+ GLTFParser.prototype.setPlugins = function ( plugins ) {
|
|
|
+
|
|
|
+ this.plugins = plugins;
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
GLTFParser.prototype.parse = function ( onLoad, onError ) {
|
|
|
|
|
|
var parser = this;
|
|
@@ -1538,6 +1601,38 @@ THREE.GLTFLoader = ( function () {
|
|
|
|
|
|
};
|
|
|
|
|
|
+ GLTFParser.prototype._invokeOne = function ( func ) {
|
|
|
+
|
|
|
+ var extensions = Object.values( this.plugins );
|
|
|
+ extensions.push( this );
|
|
|
+
|
|
|
+ for ( var i = 0; i < extensions.length; i ++ ) {
|
|
|
+
|
|
|
+ var result = func( extensions[ i ] );
|
|
|
+
|
|
|
+ if ( result ) return result;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
+ GLTFParser.prototype._invokeAll = function ( func ) {
|
|
|
+
|
|
|
+ var extensions = Object.values( this.plugins );
|
|
|
+ extensions.unshift( this );
|
|
|
+
|
|
|
+ var pending = [];
|
|
|
+
|
|
|
+ for ( var i = 0; i < extensions.length; i ++ ) {
|
|
|
+
|
|
|
+ pending.push( func( extensions[ i ] ) );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return Promise.all( pending );
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
/**
|
|
|
* Requests the specified dependency asynchronously, with caching.
|
|
|
* @param {string} type
|
|
@@ -1562,7 +1657,11 @@ THREE.GLTFLoader = ( function () {
|
|
|
break;
|
|
|
|
|
|
case 'mesh':
|
|
|
- dependency = this.loadMesh( index );
|
|
|
+ dependency = this._invokeOne( function ( ext ) {
|
|
|
+
|
|
|
+ return ext.loadMesh && ext.loadMesh( index );
|
|
|
+
|
|
|
+ } );
|
|
|
break;
|
|
|
|
|
|
case 'accessor':
|
|
@@ -1570,7 +1669,11 @@ THREE.GLTFLoader = ( function () {
|
|
|
break;
|
|
|
|
|
|
case 'bufferView':
|
|
|
- dependency = this.loadBufferView( index );
|
|
|
+ dependency = this._invokeOne( function ( ext ) {
|
|
|
+
|
|
|
+ return ext.loadBufferView && ext.loadBufferView( index );
|
|
|
+
|
|
|
+ } );
|
|
|
break;
|
|
|
|
|
|
case 'buffer':
|
|
@@ -1578,7 +1681,11 @@ THREE.GLTFLoader = ( function () {
|
|
|
break;
|
|
|
|
|
|
case 'material':
|
|
|
- dependency = this.loadMaterial( index );
|
|
|
+ dependency = this._invokeOne( function ( ext ) {
|
|
|
+
|
|
|
+ return ext.loadMaterial && ext.loadMaterial( index );
|
|
|
+
|
|
|
+ } );
|
|
|
break;
|
|
|
|
|
|
case 'texture':
|
|
@@ -2129,6 +2236,12 @@ THREE.GLTFLoader = ( function () {
|
|
|
|
|
|
};
|
|
|
|
|
|
+ GLTFParser.prototype.getMaterialType = function ( materialIndex ) {
|
|
|
+
|
|
|
+ return THREE.MeshStandardMaterial;
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
/**
|
|
|
* Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#materials
|
|
|
* @param {number} materialIndex
|
|
@@ -2164,8 +2277,6 @@ THREE.GLTFLoader = ( function () {
|
|
|
// Specification:
|
|
|
// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#metallic-roughness-material
|
|
|
|
|
|
- materialType = THREE.MeshStandardMaterial;
|
|
|
-
|
|
|
var metallicRoughness = materialDef.pbrMetallicRoughness || {};
|
|
|
|
|
|
materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 );
|
|
@@ -2196,6 +2307,18 @@ THREE.GLTFLoader = ( function () {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ materialType = this._invokeOne( function ( ext ) {
|
|
|
+
|
|
|
+ return ext.getMaterialType && ext.getMaterialType( materialIndex );
|
|
|
+
|
|
|
+ } );
|
|
|
+
|
|
|
+ pending.push( this._invokeAll( function ( ext ) {
|
|
|
+
|
|
|
+ return ext.extendMaterialParams && ext.extendMaterialParams( materialIndex, materialParams );
|
|
|
+
|
|
|
+ } ) );
|
|
|
+
|
|
|
}
|
|
|
|
|
|
if ( materialDef.doubleSided === true ) {
|
|
@@ -2263,14 +2386,6 @@ THREE.GLTFLoader = ( function () {
|
|
|
|
|
|
}
|
|
|
|
|
|
- if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_CLEARCOAT ] ) {
|
|
|
-
|
|
|
- var clearcoatExtension = extensions[ EXTENSIONS.KHR_MATERIALS_CLEARCOAT ];
|
|
|
- materialType = clearcoatExtension.getMaterialType();
|
|
|
- pending.push( clearcoatExtension.extendParams( materialParams, { extensions: materialExtensions }, parser ) );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
return Promise.all( pending ).then( function () {
|
|
|
|
|
|
var material;
|