Skip to content
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
22 changes: 22 additions & 0 deletions docs/examples/loaders/GLTFLoader.html
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,28 @@ <h2>Browser compatibility</h2>
<a href="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/stefanpenner/es6-promise">include a polyfill</a>
providing a Promise replacement.</p>

<h2>Custom extensions</h2>

<p>
Metadata from unknown extensions is preserved as “.userData.gltfExtensions” on Object3D, Scene, and Material instances,
or attached to the response “gltf” object. Example:
</p>

<code>
loader.load('foo.gltf', function ( gltf ) {

var scene = gltf.scene;

var mesh = scene.children[ 3 ];

var fooExtension = mesh.userData.gltfExtensions.EXT_foo;

gltf.parser.getDependency( 'bufferView', fooExtension.bufferView )
.then( function ( fooBuffer ) { ... } );

} );
</code>

<br>
<hr>

Expand Down
73 changes: 54 additions & 19 deletions examples/js/loaders/GLTFLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,33 +123,42 @@ THREE.GLTFLoader = ( function () {

if ( json.extensionsUsed ) {

if ( json.extensionsUsed.indexOf( EXTENSIONS.KHR_LIGHTS ) >= 0 ) {
for ( var i = 0; i < json.extensionsUsed.length; ++ i ) {

extensions[ EXTENSIONS.KHR_LIGHTS ] = new GLTFLightsExtension( json );
var extensionName = json.extensionsUsed[ i ];
var extensionsRequired = json.extensionsRequired || [];

}

if ( json.extensionsUsed.indexOf( EXTENSIONS.KHR_MATERIALS_UNLIT ) >= 0 ) {
switch ( extensionName ) {

extensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ] = new GLTFMaterialsUnlitExtension( json );
case EXTENSIONS.KHR_LIGHTS:
extensions[ extensionName ] = new GLTFLightsExtension( json );
break;

}
case EXTENSIONS.KHR_MATERIALS_UNLIT:
extensions[ extensionName ] = new GLTFMaterialsUnlitExtension( json );
break;

if ( json.extensionsUsed.indexOf( EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ) >= 0 ) {
case EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS:
extensions[ extensionName ] = new GLTFMaterialsPbrSpecularGlossinessExtension();
break;

extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ] = new GLTFMaterialsPbrSpecularGlossinessExtension();
case EXTENSIONS.KHR_DRACO_MESH_COMPRESSION:
extensions[ extensionName ] = new GLTFDracoMeshCompressionExtension( this.dracoLoader );
break;

}
case EXTENSIONS.MSFT_TEXTURE_DDS:
extensions[ EXTENSIONS.MSFT_TEXTURE_DDS ] = new GLTFTextureDDSExtension();
break;

if ( json.extensionsUsed.indexOf( EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ) >= 0 ) {
default:

extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] = new GLTFDracoMeshCompressionExtension( this.dracoLoader );
if ( extensionsRequired.indexOf( extensionName ) >= 0 ) {

}
console.warn( 'THREE.GLTFLoader: Unknown extension "' + extensionName + '".' );

if ( json.extensionsUsed.indexOf( EXTENSIONS.MSFT_TEXTURE_DDS ) >= 0 ) {
}

extensions[ EXTENSIONS.MSFT_TEXTURE_DDS ] = new GLTFTextureDDSExtension();
}

}

Expand All @@ -165,7 +174,7 @@ THREE.GLTFLoader = ( function () {

} );

parser.parse( function ( scene, scenes, cameras, animations, asset ) {
parser.parse( function ( scene, scenes, cameras, animations, json ) {

console.timeEnd( 'GLTFLoader' );

Expand All @@ -174,9 +183,13 @@ THREE.GLTFLoader = ( function () {
scenes: scenes,
cameras: cameras,
animations: animations,
asset: asset
asset: json.asset,
parser: parser,
userData: {}
};

addUnknownExtensionsToUserData( extensions, glTF, json );

onLoad( glTF );

}, onError );
Expand Down Expand Up @@ -1155,6 +1168,23 @@ THREE.GLTFLoader = ( function () {

}

function addUnknownExtensionsToUserData( knownExtensions, object, objectDef ) {

// Add unknown glTF extensions to an object's userData.

for ( var name in objectDef.extensions ) {

if ( knownExtensions[ name ] === undefined ) {

object.userData.gltfExtensions = object.userData.gltfExtensions || {};
object.userData.gltfExtensions[ name ] = objectDef.extensions[ name ];

}

}

}

/**
* Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#morph-targets
*
Expand Down Expand Up @@ -1433,10 +1463,9 @@ THREE.GLTFLoader = ( function () {
var scenes = dependencies.scenes || [];
var scene = scenes[ json.scene || 0 ];
var animations = dependencies.animations || [];
var asset = json.asset;
var cameras = dependencies.cameras || [];

onLoad( scene, scenes, cameras, animations, asset );
onLoad( scene, scenes, cameras, animations, json );

} ).catch( onError );

Expand Down Expand Up @@ -2114,6 +2143,8 @@ THREE.GLTFLoader = ( function () {

if ( materialDef.extras ) material.userData = materialDef.extras;

if ( materialDef.extensions ) addUnknownExtensionsToUserData( extensions, material, materialDef );

return material;

} );
Expand Down Expand Up @@ -2734,6 +2765,8 @@ THREE.GLTFLoader = ( function () {

if ( nodeDef.extras ) node.userData = nodeDef.extras;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's true that any GLTF object can have extensions right? Material is most immediately useful for us, but just 'scene' would also be useful.

Copy link
Collaborator Author

@donmccurdy donmccurdy Apr 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With some exceptions in the spec, and other exceptions that don't map directly to loader output, but yes most objects can have extensions. Added scene as well. :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! 'mesh' may also be useful, but not immediate for me.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's wait on that one — a "mesh" does not map 1:1 with a THREE.Mesh (multiple primitives etc.) so it is a bit trickier.

if ( nodeDef.extensions ) addUnknownExtensionsToUserData( extensions, node, nodeDef );

if ( nodeDef.matrix !== undefined ) {

var matrix = new THREE.Matrix4();
Expand Down Expand Up @@ -2866,6 +2899,8 @@ THREE.GLTFLoader = ( function () {

if ( sceneDef.extras ) scene.userData = sceneDef.extras;

if ( sceneDef.extensions ) addUnknownExtensionsToUserData( extensions, scene, sceneDef );

var nodeIds = sceneDef.nodes || [];

for ( var i = 0, il = nodeIds.length; i < il; i ++ ) {
Expand Down