Browse Source

GLTFLoader: Implement KHR_texture_basisu support

This change implements support for (draft) KHR_texture_basisu extension
as described in https://github.com/KhronosGroup/glTF/pull/1751; at this
point the expectation is that this extension will land with very few
changes if any.

To make this work, two general changes to GLTFLoader were necessary:

- The plugin extension framework now supports overriding loadTexture
- To simplify implementation, the bulk of the loading functionality was
extracted into loadTextureImage.

As with other dependent loaders, it's the caller's responsibility to
call setKTX2Loader on the GLTFLoader before loading files with this
extension.
Arseny Kapoulkine 5 năm trước cách đây
mục cha
commit
b993164e8e
1 tập tin đã thay đổi với 81 bổ sung6 xóa
  1. 81 6
      examples/jsm/loaders/GLTFLoader.js

+ 81 - 6
examples/jsm/loaders/GLTFLoader.js

@@ -4,6 +4,7 @@
  * @author Tony Parisi / http://www.tonyparisi.com/
  * @author Takahiro / https://github.com/takahirox
  * @author Don McCurdy / https://www.donmccurdy.com
+ * @author Arseny Kapoulkine / https://github.com/zeux
  */
 
 import {
@@ -80,6 +81,7 @@ var GLTFLoader = ( function () {
 
 		this.dracoLoader = null;
 		this.ddsLoader = null;
+		this.ktx2Loader = null;
 
 		this.pluginCallbacks = [];
 		this.register( function ( parser ) {
@@ -87,6 +89,11 @@ var GLTFLoader = ( function () {
 			return new GLTFMaterialsClearcoatExtension( parser );
 
 		} );
+		this.register( function ( parser ) {
+
+			return new GLTFTextureBasisU( parser );
+
+		} );
 
 	}
 
@@ -184,6 +191,13 @@ var GLTFLoader = ( function () {
 
 		},
 
+		setKTX2Loader: function ( ktx2Loader ) {
+
+			this.ktx2Loader = ktx2Loader;
+			return this;
+
+		},
+
 		register: function ( callback ) {
 
 			if ( this.pluginCallbacks.indexOf( callback ) === - 1 ) {
@@ -258,7 +272,8 @@ var GLTFLoader = ( function () {
 
 				path: path || this.resourcePath || '',
 				crossOrigin: this.crossOrigin,
-				manager: this.manager
+				manager: this.manager,
+				ktx2Loader: this.ktx2Loader
 
 			} );
 
@@ -600,6 +615,46 @@ var GLTFLoader = ( function () {
 
 	};
 
+	/**
+	 * BasisU Texture Extension
+	 *
+	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_basisu
+	 * (Link above TBD, currently in PR https://github.com/KhronosGroup/glTF/pull/1751)
+	 */
+	function GLTFTextureBasisU( parser ) {
+
+		this.parser = parser;
+		this.name = "KHR_texture_basisu";
+
+	}
+
+	GLTFTextureBasisU.prototype.loadTexture = function ( textureIndex ) {
+
+		var parser = this.parser;
+		var json = parser.json;
+
+		var textureDef = json.textures[ textureIndex ];
+
+		if ( ! textureDef.extensions || ! textureDef.extensions[ this.name ] ) {
+
+			return Promise.resolve();
+
+		}
+
+		var extension = textureDef.extensions[ this.name ];
+		var source = json.images[ extension.source ];
+		var loader = parser.options.ktx2Loader;
+
+		if ( !loader ) {
+
+			throw new Error( 'THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures' );
+
+		}
+
+		return parser.loadTextureImage( textureIndex, source, loader );
+
+	};
+
 	/* BINARY EXTENSION */
 	var BINARY_EXTENSION_HEADER_MAGIC = 'glTF';
 	var BINARY_EXTENSION_HEADER_LENGTH = 12;
@@ -1761,7 +1816,11 @@ var GLTFLoader = ( function () {
 					break;
 
 				case 'texture':
-					dependency = this.loadTexture( index );
+					dependency = this._invokeOne( function ( ext ) {
+
+						return ext.loadTexture && ext.loadTexture( index );
+
+					} );
 					break;
 
 				case 'skin':
@@ -2021,8 +2080,6 @@ var GLTFLoader = ( function () {
 		var options = this.options;
 		var textureLoader = this.textureLoader;
 
-		var URL = self.URL || self.webkitURL;
-
 		var textureDef = json.textures[ textureIndex ];
 
 		var textureExtensions = textureDef.extensions || {};
@@ -2039,6 +2096,19 @@ var GLTFLoader = ( function () {
 
 		}
 
+		return loadTextureImage( textureIndex, source );
+	};
+
+	GLTFParser.prototype.loadTextureImage = function ( textureIndex, source, loaderOverride ) {
+
+		var parser = this;
+		var json = this.json;
+		var options = this.options;
+
+		var textureDef = json.textures[ textureIndex ];
+
+		var URL = self.URL || self.webkitURL;
+
 		var sourceURI = source.uri;
 		var isObjectURL = false;
 
@@ -2059,9 +2129,13 @@ var GLTFLoader = ( function () {
 
 		return Promise.resolve( sourceURI ).then( function ( sourceURI ) {
 
-			// Load Texture resource.
+			var loader = loaderOverride;
+
+			if ( ! loader ) {
 
-			var loader = options.manager.getHandler( sourceURI );
+				loader = options.manager.getHandler( sourceURI );
+
+			}
 
 			if ( ! loader ) {
 
@@ -2129,6 +2203,7 @@ var GLTFLoader = ( function () {
 
 	};
 
+
 	/**
 	 * Asynchronously assigns a texture to the given material parameters.
 	 * @param {Object} materialParams