浏览代码

Updates OBJLoader2 to V2.4.1 which fixes the following bugs:
- #14010: `TRHEE.OBJLoader2.loadMtl` transforms an ArrayBuffer to String `THREE.LoaderUtils.decodeText` if content is provided as ArrayBuffer
- #14032: Vertex Color value was not correctly initialized. Vertex colors are now correctly used
- Original repo issue 40: Added function `TRHEE.OBJLoader2.setUseOAsMesh` to enforce mesh creation on occurrence of "o". The default is false (spec compliant).
- Original repo issue 39: Ensure name of `THREE.LoaderSupport.ResourceDescriptor` always has a default name
- Original repo issue 38: Fixed onMeshAlter and onLoadMaterials callback usage in `THREE.LoaderSupport.WorkerDirector` and fixed handling of returned objects in `THREE.LoaderSupport.MeshBuilder`

Kai Salmen 7 年之前
父节点
当前提交
ea49123258

+ 22 - 9
examples/js/loaders/LoaderSupport.js

@@ -166,11 +166,12 @@ THREE.LoaderSupport.ResourceDescriptor = (function () {
 		} else {
 
 			this.path = Validator.verifyInput( urlParts.slice( 0, urlParts.length - 1).join( '/' ) + '/', null );
-			this.name = Validator.verifyInput( urlParts[ urlParts.length - 1 ], null );
+			this.name = urlParts[ urlParts.length - 1 ];
 			this.url = url;
 
 		}
-		this.extension = Validator.verifyInput( extension, "default" );
+		this.name = Validator.verifyInput( this.name, 'Unnamed_Resource' );
+		this.extension = Validator.verifyInput( extension, 'default' );
 		this.extension = this.extension.trim();
 		this.content = null;
 	}
@@ -348,7 +349,7 @@ THREE.LoaderSupport.PrepData = (function () {
  */
 THREE.LoaderSupport.MeshBuilder = (function () {
 
-	var LOADER_MESH_BUILDER_VERSION = '1.2.0';
+	var LOADER_MESH_BUILDER_VERSION = '1.2.1';
 
 	var Validator = THREE.LoaderSupport.Validator;
 
@@ -540,16 +541,20 @@ THREE.LoaderSupport.MeshBuilder = (function () {
 			);
 			if ( Validator.isValid( callbackOnMeshAlterResult ) ) {
 
-				if ( ! callbackOnMeshAlterResult.isDisregardMesh() && callbackOnMeshAlterResult.providesAlteredMeshes() ) {
+				if ( callbackOnMeshAlterResult.isDisregardMesh() ) {
+
+					useOrgMesh = false;
+
+				} else if ( callbackOnMeshAlterResult.providesAlteredMeshes() ) {
 
 					for ( var i in callbackOnMeshAlterResult.meshes ) {
 
 						meshes.push( callbackOnMeshAlterResult.meshes[ i ] );
 
 					}
+					useOrgMesh = false;
 
 				}
-				useOrgMesh = false;
 
 			}
 
@@ -1219,7 +1224,7 @@ THREE.LoaderSupport.WorkerSupport = (function () {
  */
 THREE.LoaderSupport.WorkerDirector = (function () {
 
-	var LOADER_WORKER_DIRECTOR_VERSION = '2.2.0';
+	var LOADER_WORKER_DIRECTOR_VERSION = '2.2.1';
 
 	var Validator = THREE.LoaderSupport.Validator;
 
@@ -1418,9 +1423,16 @@ THREE.LoaderSupport.WorkerDirector = (function () {
 			if ( Validator.isValid( prepDataCallbacks.onProgress ) ) prepDataCallbacks.onProgress( event );
 		};
 
-		var wrapperOnMeshAlter = function ( event ) {
-			if ( Validator.isValid( globalCallbacks.onMeshAlter ) ) globalCallbacks.onMeshAlter( event );
-			if ( Validator.isValid( prepDataCallbacks.onMeshAlter ) ) prepDataCallbacks.onMeshAlter( event );
+		var wrapperOnMeshAlter = function ( event, override ) {
+			if ( Validator.isValid( globalCallbacks.onMeshAlter ) ) override = globalCallbacks.onMeshAlter( event, override );
+			if ( Validator.isValid( prepDataCallbacks.onMeshAlter ) ) override = globalCallbacks.onMeshAlter( event, override );
+			return override;
+		};
+
+		var wrapperOnLoadMaterials = function ( materials ) {
+			if ( Validator.isValid( globalCallbacks.onLoadMaterials ) ) materials = globalCallbacks.onLoadMaterials( materials );
+			if ( Validator.isValid( prepDataCallbacks.onLoadMaterials ) ) materials = prepDataCallbacks.onLoadMaterials( materials );
+			return materials;
 		};
 
 		supportDesc.loader = this._buildLoader( supportDesc.instanceNo );
@@ -1429,6 +1441,7 @@ THREE.LoaderSupport.WorkerDirector = (function () {
 		updatedCallbacks.setCallbackOnLoad( wrapperOnLoad );
 		updatedCallbacks.setCallbackOnProgress( wrapperOnProgress );
 		updatedCallbacks.setCallbackOnMeshAlter( wrapperOnMeshAlter );
+		updatedCallbacks.setCallbackOnLoadMaterials( wrapperOnLoadMaterials );
 		prepData.callbacks = updatedCallbacks;
 
 		supportDesc.loader.run( prepData, supportDesc.workerSupport );

+ 43 - 10
examples/js/loaders/OBJLoader2.js

@@ -17,7 +17,7 @@ if ( THREE.LoaderSupport === undefined ) console.error( '"THREE.LoaderSupport" i
  */
 THREE.OBJLoader2 = (function () {
 
-	var OBJLOADER2_VERSION = '2.4.0';
+	var OBJLOADER2_VERSION = '2.4.1';
 	var Validator = THREE.LoaderSupport.Validator;
 
 	function OBJLoader2( manager ) {
@@ -35,6 +35,7 @@ THREE.OBJLoader2 = (function () {
 		this.useIndices = false;
 		this.disregardNormals = false;
 		this.materialPerSmoothingGroup = false;
+		this.useOAsMesh = false;
 		this.loaderRootNode = new THREE.Group();
 
 		this.meshBuilder = new THREE.LoaderSupport.MeshBuilder();
@@ -126,6 +127,16 @@ THREE.OBJLoader2 = (function () {
 		this.materialPerSmoothingGroup = materialPerSmoothingGroup === true;
 	};
 
+	/**
+	 * Usually 'o' is meta-information and does not result in creation of new meshes, but mesh creation on occurrence of "o" can be enforced.
+	 * @memberOf THREE.OBJLoader2
+	 *
+	 * @param {boolean} useOAsMesh=false
+	 */
+	OBJLoader2.prototype.setUseOAsMesh = function ( useOAsMesh ) {
+		this.useOAsMesh = useOAsMesh === true;
+	};
+
 	OBJLoader2.prototype._setCallbacks = function ( callbacks ) {
 		if ( Validator.isValid( callbacks.onProgress ) ) this.callbacks.setCallbackOnProgress( callbacks.onProgress );
 		if ( Validator.isValid( callbacks.onMeshAlter ) ) this.callbacks.setCallbackOnMeshAlter( callbacks.onMeshAlter );
@@ -297,6 +308,7 @@ THREE.OBJLoader2 = (function () {
 			this.setUseIndices( prepData.useIndices );
 			this.setDisregardNormals( prepData.disregardNormals );
 			this.setMaterialPerSmoothingGroup( prepData.materialPerSmoothingGroup );
+			this.setUseOAsMesh( prepData.useOAsMesh );
 
 			this._setCallbacks( prepData.getCallbacks() );
 
@@ -323,6 +335,7 @@ THREE.OBJLoader2 = (function () {
 		var parser = new Parser();
 		parser.setLogging( this.logging.enabled, this.logging.debug );
 		parser.setMaterialPerSmoothingGroup( this.materialPerSmoothingGroup );
+		parser.setUseOAsMesh( this.useOAsMesh );
 		parser.setUseIndices( this.useIndices );
 		parser.setDisregardNormals( this.disregardNormals );
 		// sync code works directly on the material references
@@ -434,6 +447,7 @@ THREE.OBJLoader2 = (function () {
 				params: {
 					useAsync: true,
 					materialPerSmoothingGroup: this.materialPerSmoothingGroup,
+					useOAsMesh: this.useOAsMesh,
 					useIndices: this.useIndices,
 					disregardNormals: this.disregardNormals
 				},
@@ -469,6 +483,7 @@ THREE.OBJLoader2 = (function () {
 			this.materials = {};
 			this.useAsync = false;
 			this.materialPerSmoothingGroup = false;
+			this.useOAsMesh = false;
 			this.useIndices = false;
 			this.disregardNormals = false;
 
@@ -541,6 +556,10 @@ THREE.OBJLoader2 = (function () {
 			this.materialPerSmoothingGroup = materialPerSmoothingGroup;
 		};
 
+		Parser.prototype.setUseOAsMesh = function ( useOAsMesh ) {
+			this.useOAsMesh = useOAsMesh;
+		};
+
 		Parser.prototype.setUseIndices = function ( useIndices ) {
 			this.useIndices = useIndices;
 		};
@@ -579,6 +598,7 @@ THREE.OBJLoader2 = (function () {
 					+ matNames
 					+ '\n\tuseAsync: ' + this.useAsync
 					+ '\n\tmaterialPerSmoothingGroup: ' + this.materialPerSmoothingGroup
+					+ '\n\tuseOAsMesh: ' + this.useOAsMesh
 					+ '\n\tuseIndices: ' + this.useIndices
 					+ '\n\tdisregardNormals: ' + this.disregardNormals
 					+ '\n\tcallbackMeshBuilderName: ' + this.callbackMeshBuilder.name
@@ -826,7 +846,8 @@ THREE.OBJLoader2 = (function () {
 					break;
 
 				case 'o':
-					// 'o' is pure meta-information and does not result in creation of new meshes
+					// 'o' is meta-information and usually does not result in creation of new meshes, but can be enforced with "useOAsMesh"
+					if ( this.useOAsMesh ) this.processCompletedMesh();
 					this.rawMesh.objectName = reconstructString( this.contentRef, this.legacyMode, this.globalCounts.lineByte + 2, this.globalCounts.currentByte );
 					break;
 
@@ -926,7 +947,7 @@ THREE.OBJLoader2 = (function () {
 				vertices.push( scope.vertices[ indexPointerV++ ] );
 				vertices.push( scope.vertices[ indexPointerV ] );
 
-				var indexPointerC = scope.colors.length > 0 ? indexPointerV : null;
+				var indexPointerC = scope.colors.length > 0 ? indexPointerV + 1 : null;
 				if ( indexPointerC !== null ) {
 
 					var colors = scope.rawMesh.subGroupInUse.colors;
@@ -1356,19 +1377,31 @@ THREE.OBJLoader2 = (function () {
 			mtlLoader.setPath( resource.path );
 			if ( Validator.isValid( materialOptions ) ) mtlLoader.setMaterialOptions( materialOptions );
 
+			var parseTextWithMtlLoader = function ( content ) {
+				var contentAsText = content;
+				if ( typeof( content ) !== 'string' && ! ( content instanceof String ) ) {
+
+					if ( content.length > 0 || content.byteLength > 0 ) {
+
+						contentAsText = THREE.LoaderUtils.decodeText( content );
+
+					} else {
+
+						throw 'Unable to parse mtl as it it seems to be neither a String, an Array or an ArrayBuffer!';
+					}
+
+				}
+				processMaterials( mtlLoader.parse( contentAsText ) );
+			};
+
 			if ( Validator.isValid( resource.content ) ) {
 
-				processMaterials( Validator.isValid( resource.content ) ? mtlLoader.parse( resource.content ) : null );
+				parseTextWithMtlLoader( resource.content );
 
 			} else if ( Validator.isValid( resource.url ) ) {
 
 				var fileLoader = new THREE.FileLoader( this.manager );
-				fileLoader.load( resource.url, function ( text ) {
-
-					resource.content = text;
-					processMaterials( mtlLoader.parse( text ) );
-
-				}, this._onProgress, this._onError );
+				fileLoader.load( resource.url, parseTextWithMtlLoader, this._onProgress, this._onError );
 
 			}
 		}

+ 1 - 0
examples/models/obj/verify/verify.html

@@ -161,6 +161,7 @@
 						objLoader2.setModelName( modelName );
 						objLoader2.setMaterials( materials );
 						objLoader2.setLogging( true, false );
+						objLoader2.setUseOAsMesh( true );
 						objLoader2.load( './verify.obj', callbackOnLoad, null, null, null, false );
 					};
 					objLoader2.loadMtl( './verify.mtl', null, onLoadMtl );

+ 3 - 1
examples/models/obj/verify/verify.obj

@@ -3,6 +3,7 @@
 mtllib verify.mtl
 
 # Cube no materials. Translated x:-150
+o cube 1
 v -160 60 10
 v -160 40 10
 v -140 40 10
@@ -21,6 +22,7 @@ f 2 6 7 3
 
 
 # Cube with two materials. Translated x:-100
+o cube 2
 v -110 60 10
 v -110 40 10
 v -90 40 10
@@ -188,7 +190,7 @@ v 210 60 -10
 p -8 -7 -6 -5 -4 -3 -2 -1
 
 
-# Line. Translated x:250
+# Point/Line. Translated x:250
 v 240 60 10
 v 240 40 10
 v 260 40 10

+ 9 - 3
examples/webgl_loader_obj2_run_director.html

@@ -258,8 +258,8 @@
 						}
 					};
 
-					var callbackMeshAlter = function ( event ) {
-						var override = new THREE.LoaderSupport.LoadedMeshUserOverride( false, false );
+					var callbackMeshAlter = function ( event, override ) {
+						if ( ! Validator.isValid( override ) ) override = new THREE.LoaderSupport.LoadedMeshUserOverride( false, false );
 
 						var material = event.detail.material;
 						var meshName = event.detail.meshName;
@@ -277,16 +277,22 @@
 						return override;
 					};
 
+					var callbackOnLoadMaterials = function ( materials ) {
+						console.log( 'Materials loaded' );
+						return materials;
+					};
+
 					var callbacks = new THREE.LoaderSupport.Callbacks();
 					callbacks.setCallbackOnProgress( callbackReportProgress );
 					callbacks.setCallbackOnLoad( callbackOnLoad );
 					callbacks.setCallbackOnMeshAlter( callbackMeshAlter );
+					callbacks.setCallbackOnLoadMaterials( callbackOnLoadMaterials );
 
 					this.workerDirector.prepareWorkers( callbacks, maxQueueSize, maxWebWorkers );
 					if ( this.logging.enabled ) console.info( 'Configuring WWManager with queue size ' + this.workerDirector.getMaxQueueSize() + ' and ' + this.workerDirector.getMaxWebWorkers() + ' workers.' );
 
-					var prepData;
 					var modelPrepDatas = [];
+					var prepData;
 					prepData = new THREE.LoaderSupport.PrepData( 'male02' );
 					prepData.addResource( new THREE.LoaderSupport.ResourceDescriptor( 'models/obj/male02/male02.obj', 'OBJ ') );
 					prepData.addResource( new THREE.LoaderSupport.ResourceDescriptor( 'models/obj/male02/male02.mtl', 'MTL' ) );