Skip to content

Commit

Permalink
Merge pull request #19144 from takahirox/GLTFLoaderPluginSystemNew
Browse files Browse the repository at this point in the history
GLTFLoader plugin system, first round
  • Loading branch information
mrdoob authored Jun 11, 2020
2 parents 65c6062 + 7208eb8 commit 7d976f3
Show file tree
Hide file tree
Showing 2 changed files with 294 additions and 64 deletions.
179 changes: 147 additions & 32 deletions examples/js/loaders/GLTFLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 ), {
Expand Down Expand Up @@ -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' ) {

Expand Down Expand Up @@ -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 ) {
Expand All @@ -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;
Expand All @@ -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 + '".' );

Expand All @@ -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 );

}
Expand Down Expand Up @@ -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 = [];

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -1562,23 +1657,35 @@ THREE.GLTFLoader = ( function () {
break;

case 'mesh':
dependency = this.loadMesh( index );
dependency = this._invokeOne( function ( ext ) {

return ext.loadMesh && ext.loadMesh( index );

} );
break;

case 'accessor':
dependency = this.loadAccessor( index );
break;

case 'bufferView':
dependency = this.loadBufferView( index );
dependency = this._invokeOne( function ( ext ) {

return ext.loadBufferView && ext.loadBufferView( index );

} );
break;

case 'buffer':
dependency = this.loadBuffer( index );
break;

case 'material':
dependency = this.loadMaterial( index );
dependency = this._invokeOne( function ( ext ) {

return ext.loadMaterial && ext.loadMaterial( index );

} );
break;

case 'texture':
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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 ) {
Expand Down Expand Up @@ -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;
Expand Down
Loading

0 comments on commit 7d976f3

Please sign in to comment.