فهرست منبع

Unified load and parse behaviour of OBJLoader2 and OBJLoader2Parallel: Separate onParseComplete is gone. onLoad serves the same purpose in both sync an parallel use cases
Started to fix documentation of OBJLoader2 and added OBJLoader2Parallel

Kai Salmen 5 سال پیش
والد
کامیت
19a9f57e84

+ 7 - 8
docs/examples/en/loaders/OBJLoader2.html

@@ -22,30 +22,29 @@
 
 
 		<code>
 		<code>
 		// instantiate the loader
 		// instantiate the loader
-		var loader = new THREE.OBJLoader2();
+		let loader = new THREE.OBJLoader2();
 
 
 		// function called on successful load
 		// function called on successful load
-		var callbackOnLoad = function ( object3d ) {
+		function callbackOnLoad ( object3d ) {
 			scene.add( object3d );
 			scene.add( object3d );
-		};
+		}
 
 
 		// load a resource from provided URL synchronously
 		// load a resource from provided URL synchronously
-		loader.load( 'obj/female02/female02.obj', callbackOnLoad, null, null, null, false );
+		loader.load( 'obj/female02/female02.obj', callbackOnLoad, null, null, null );
 		</code>
 		</code>
 
 
 		[example:webgl_loader_obj2] - Simple example <br>
 		[example:webgl_loader_obj2] - Simple example <br>
-		[example:webgl_loader_obj2_options] - Example for multiple use-cases (parse, load and run with instructions (sync and async)<br>
+		[example:webgl_loader_obj2_options] - Example for multiple use-cases (parse and load, sync or in parallel to main (see [page:OBJLoader2Parallel]))<br>
 
 
 
 
 		<h2>Constructor</h2>
 		<h2>Constructor</h2>
 
 
-		<h3>[name]( [param:LoadingManager manager], [param:LoaderSupport.ConsoleLogger logger] )</h3>
+		<h3>[name]( [param:LoadingManager manager] )</h3>
 		<p>
 		<p>
 			[page:LoadingManager manager] - The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager].<br>
 			[page:LoadingManager manager] - The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager].<br>
-			[page:LoaderSupport.ConsoleLogger logger] - logger to be used
 		</p>
 		</p>
 		<p>
 		<p>
-			Use [name] to load OBJ data from files or to parse OBJ data from arraybuffer or text.
+			Creates a new [name]. Use it to load OBJ data from files or to parse OBJ data from arraybuffer or text.
 		</p>
 		</p>
 
 
 
 

+ 84 - 0
docs/examples/en/loaders/OBJLoader2Parallel.html

@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+
+		<h1>[name]</h1>
+
+		<p class="desc">A loader for loading a <em>.obj</em> resource.<br />
+			The <a href="https://en.wikipedia.org/wiki/Wavefront_.obj_file">OBJ file format</a> is a simple data-format
+			that represents 3D geometry in a human readable format as, the position of each vertex, the UV position of
+			each texture coordinate vertex, vertex normals, and the faces that make each polygon defined as a list of
+			vertices, and texture vertices.
+		</p>
+
+		<h2>Examples</h2>
+
+		<code>
+		// instantiate the loader
+		let objLoader2Parallel = new OBJLoader2Parallel();
+
+		// define where to attach the data
+		let local = new THREE.Object3D();
+
+		// function called on successful completion of parsing
+		function callbackOnLoad( object3d, message ) {
+			local.add( object3d );
+		}
+
+		// load a resource from provided URL in parallel to Main
+		objLoader2Parallel.load( 'models/obj/walt/WaltHead.obj', callbackOnLoad, null, null, null );
+		</code>
+
+		[example:webgl_loader_obj2_options] - Example for multiple use-cases (parse and load, sync (see [page:OBJLoader2]) or in parallel to main)<br>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [param:LoadingManager manager] )</h3>
+		<p>
+			[page:LoadingManager manager] - The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager].<br>
+		</p>
+		<p>
+			Creates a new [name]. Use it to load OBJ data from files or to parse OBJ data from arraybuffer or text.
+		</p>
+
+
+		<h2>Methods</h2>
+
+		<h3>[method:Object3D parse]( [param:arraybuffer content]|[param:String content] )</h3>
+		<p>
+			[[page:arraybuffer content]|[page:String content]] OBJ data as Uint8Array or String
+		</p>
+		<p>
+			Parses OBJ data synchronously from arraybuffer or string and returns the [page:Object3D loaderRoorNode].
+		</p>
+
+
+		<h3>[method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError], [param:Function onMeshAlter], [param:boolean useAsync] )</h3>
+		<p>
+			[page:String url] - A string containing the path/URL of the file to be loaded.<br>
+			[page:Function onLoad] - A function to be called after loading is successfully completed. The function receives loaded [page:Object3D] as an argument.<br>
+			[page:Function onProgress] - (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains [page:Integer total] and [page:Integer loaded] bytes.<br>
+			[page:Function onError] - (optional) A function to be called if an error occurs during loading. The function receives the error as an argument.<br>
+			[page:Function onMeshAlter] - (optional) A function to be called after a new mesh raw data becomes available for alteration.<br>
+			[page:boolean useAsync] - (optional) If true, uses async loading with worker, if false loads data synchronously.
+		</p>
+		<p>
+			Use this convenient method to load a file at the given URL. By default the fileLoader uses an ArrayBuffer.
+		</p>
+
+
+		<h2>Source</h2>
+
+		<p>
+			[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/OBJLoader2Parallel.js examples/jsm/loaders/OBJLoader2.js]
+		</p>
+	</body>
+</html>

+ 1 - 0
docs/list.js

@@ -372,6 +372,7 @@ var list = {
 				"MTLLoader": "examples/en/loaders/MTLLoader",
 				"MTLLoader": "examples/en/loaders/MTLLoader",
 				"OBJLoader": "examples/en/loaders/OBJLoader",
 				"OBJLoader": "examples/en/loaders/OBJLoader",
 				"OBJLoader2": "examples/en/loaders/OBJLoader2",
 				"OBJLoader2": "examples/en/loaders/OBJLoader2",
+				"OBJLoader2Parallel": "examples/en/loaders/OBJLoader2Parallel",
 				"PCDLoader": "examples/en/loaders/PCDLoader",
 				"PCDLoader": "examples/en/loaders/PCDLoader",
 				"PDBLoader": "examples/en/loaders/PDBLoader",
 				"PDBLoader": "examples/en/loaders/PDBLoader",
 				"PRWMLoader": "examples/en/loaders/PRWMLoader",
 				"PRWMLoader": "examples/en/loaders/PRWMLoader",

+ 1 - 0
examples/jsm/loaders/OBJLoader2.d.ts

@@ -34,6 +34,7 @@ export class OBJLoader2 extends Loader {
   setCallbackOnAssetAvailable(onAssetAvailable: Function): this;
   setCallbackOnAssetAvailable(onAssetAvailable: Function): this;
   setCallbackOnProgress(onProgress: Function): this;
   setCallbackOnProgress(onProgress: Function): this;
   setCallbackOnError(onError: Function): this;
   setCallbackOnError(onError: Function): this;
+  setCallbackOnLoad(onLoad: Function): this;
   setCallbackOnMeshAlter(onMeshAlter: Function): this;
   setCallbackOnMeshAlter(onMeshAlter: Function): this;
   setCallbackOnLoadMaterials(onLoadMaterials: Function): this;
   setCallbackOnLoadMaterials(onLoadMaterials: Function): this;
 
 

+ 17 - 1
examples/jsm/loaders/OBJLoader2.js

@@ -181,6 +181,17 @@ OBJLoader2.prototype = Object.assign( Object.create( Loader.prototype ), {
 
 
 	},
 	},
 
 
+	/**
+	 * See {@link OBJLoader2Parser.setCallbackOnLoad}
+	 * @return {OBJLoader2}
+	 */
+	setCallbackOnLoad: function ( onLoad ) {
+
+		this.parser.setCallbackOnLoad( onLoad );
+		return this;
+
+	},
+
 	/**
 	/**
 	 * Register a function that is called once a single mesh is available and it could be altered by the supplied function.
 	 * Register a function that is called once a single mesh is available and it could be altered by the supplied function.
 	 *
 	 *
@@ -225,6 +236,11 @@ OBJLoader2.prototype = Object.assign( Object.create( Loader.prototype ), {
 			scope.parser.callbacks.onError( errorMessage );
 			scope.parser.callbacks.onError( errorMessage );
 			throw errorMessage
 			throw errorMessage
 
 
+		}
+		else {
+
+			this.parser.setCallbackOnLoad( onLoad );
+
 		}
 		}
 		if ( onError === null || onError === undefined || !(onError instanceof Function) ) {
 		if ( onError === null || onError === undefined || !(onError instanceof Function) ) {
 
 
@@ -280,7 +296,7 @@ OBJLoader2.prototype = Object.assign( Object.create( Loader.prototype ), {
 		this.setCallbackOnMeshAlter( onMeshAlter );
 		this.setCallbackOnMeshAlter( onMeshAlter );
 		let fileLoaderOnLoad = function ( content ) {
 		let fileLoaderOnLoad = function ( content ) {
 
 
-			onLoad( scope.parse( content ) );
+			scope.parser.callbacks.onLoad( scope.parse( content ), "OBJLoader2#load: Parsing completed" );
 
 
 		};
 		};
 		let fileLoader = new FileLoader( this.manager );
 		let fileLoader = new FileLoader( this.manager );

+ 2 - 3
examples/jsm/loaders/OBJLoader2Parallel.d.ts

@@ -8,11 +8,10 @@ import { WorkerExecutionSupport} from './obj2/worker/main/WorkerExecutionSupport
 export class OBJLoader2Parallel extends OBJLoader2 {
 export class OBJLoader2Parallel extends OBJLoader2 {
   constructor(manager?: LoadingManager);
   constructor(manager?: LoadingManager);
   preferJsmWorker: boolean;
   preferJsmWorker: boolean;
-	executeParallel: boolean;
-	workerExecutionSupport: WorkerExecutionSupport;
+  executeParallel: boolean;
+  workerExecutionSupport: WorkerExecutionSupport;
 
 
   setPreferJsmWorker(preferJsmWorker: boolean): this;
   setPreferJsmWorker(preferJsmWorker: boolean): this;
-  setCallbackOnParseComplete(onParseComplete: Function): this;
   setExecuteParallel(executeParallel: boolean): this;
   setExecuteParallel(executeParallel: boolean): this;
   getWorkerExecutionSupport(): object;
   getWorkerExecutionSupport(): object;
   buildWorkerCode(): object;
   buildWorkerCode(): object;

+ 34 - 26
examples/jsm/loaders/OBJLoader2Parallel.js

@@ -4,6 +4,9 @@
  */
  */
 
 
 // Imports only related to wrapper
 // Imports only related to wrapper
+import {
+	Object3D
+} from "../../../build/three.module.js";
 import {
 import {
 	CodeBuilderInstructions,
 	CodeBuilderInstructions,
 	WorkerExecutionSupport
 	WorkerExecutionSupport
@@ -19,6 +22,7 @@ import {
 	DefaultWorkerPayloadHandler
 	DefaultWorkerPayloadHandler
 } from "./obj2/worker/parallel/WorkerRunner.js";
 } from "./obj2/worker/parallel/WorkerRunner.js";
 
 
+
 /**
 /**
  * Extends {OBJLoader2} with the capability to run the parser {OBJLoader2Parser} in web worker
  * Extends {OBJLoader2} with the capability to run the parser {OBJLoader2Parser} in web worker
  * with help of {WorkerExecutionSupport}.
  * with help of {WorkerExecutionSupport}.
@@ -31,7 +35,6 @@ const OBJLoader2Parallel = function ( manager ) {
 	OBJLoader2.call( this, manager );
 	OBJLoader2.call( this, manager );
 	this.preferJsmWorker = false;
 	this.preferJsmWorker = false;
 
 
-	this.parser.callbacks.onParseComplete = null;
 	this.executeParallel = true;
 	this.executeParallel = true;
 	this.workerExecutionSupport = new WorkerExecutionSupport();
 	this.workerExecutionSupport = new WorkerExecutionSupport();
 
 
@@ -52,23 +55,6 @@ OBJLoader2Parallel.prototype = Object.assign( Object.create( OBJLoader2.prototyp
 
 
 	},
 	},
 
 
-	/**
-	 * If this call back is not set, then the completion message from worker will not be received.
-	 *
-	 * @param {function} onParseComplete
-	 * @return {OBJLoader2Parallel}
-	 */
-	setCallbackOnParseComplete: function ( onParseComplete ) {
-
-		if ( onParseComplete !== undefined && onParseComplete !== null ) {
-
-			this.parser.callbacks.onParseComplete = onParseComplete;
-
-		}
-		return this;
-
-	},
-
 	/**
 	/**
 	 * Execution of parse in parallel via Worker is default, but normal {OBJLoader2} parsing can be enforced via false here.
 	 * Execution of parse in parallel via Worker is default, but normal {OBJLoader2} parsing can be enforced via false here.
 	 *
 	 *
@@ -130,9 +116,9 @@ OBJLoader2Parallel.prototype = Object.assign( Object.create( OBJLoader2.prototyp
 	 */
 	 */
 	_configure: function () {
 	_configure: function () {
 
 
-		if ( this.parser.callbacks.onParseComplete === null ) {
+		if ( this.parser.callbacks.onLoad === this.parser._onLoad ) {
 
 
-			throw "No callbackOnLoad was provided! Aborting!";
+			throw "No callback other than the default callback was provided! Aborting!";
 
 
 		}
 		}
 		// check if worker is already available and if so, then fast-fail
 		// check if worker is already available and if so, then fast-fail
@@ -147,7 +133,10 @@ OBJLoader2Parallel.prototype = Object.assign( Object.create( OBJLoader2.prototyp
 
 
 		};
 		};
 
 
-		this.workerExecutionSupport.updateCallbacks( scopedOnAssetAvailable, this.parser.callbacks.onParseComplete );
+		function scopedOnLoad ( message ) {
+			scope.parser.callbacks.onLoad( scope.baseObject3d, message );
+		}
+		this.workerExecutionSupport.updateCallbacks( scopedOnAssetAvailable, scopedOnLoad );
 
 
 	},
 	},
 
 
@@ -163,10 +152,27 @@ OBJLoader2Parallel.prototype = Object.assign( Object.create( OBJLoader2.prototyp
 	 */
 	 */
 	load: function ( content, onLoad, onFileLoadProgress, onError, onMeshAlter ) {
 	load: function ( content, onLoad, onFileLoadProgress, onError, onMeshAlter ) {
 
 
-		this.setCallbackOnParseComplete( onLoad );
+ 		let scope = this;
+		function interceptOnLoad ( object3d, message ) {
+
+			if ( object3d instanceof Object3D ) {
+
+				onLoad( object3d, message );
+
+			}
+			else {
+
+				if ( object3d == 'OBJLoader2Parallel' && scope.parser.logging.enabled && scope.parser.logging.debug ) {
 
 
-		OBJLoader2.prototype.load.call( this, content, function () {
-		}, onFileLoadProgress, onError, onMeshAlter );
+					console.debug( 'Received dummy answer from OBJLoader2Parallel#parse' );
+
+				}
+
+			}
+
+		}
+
+		OBJLoader2.prototype.load.call( this, content, interceptOnLoad, onFileLoadProgress, onError, onMeshAlter );
 
 
 	},
 	},
 
 
@@ -202,9 +208,11 @@ OBJLoader2Parallel.prototype = Object.assign( Object.create( OBJLoader2.prototyp
 					}
 					}
 				} );
 				} );
 
 
-		} else {
+			return 'OBJLoader2Parallel';
+		}
+		else {
 
 
-			this.parser.callbacks.onParseComplete( OBJLoader2.prototype.parse.call( this, content ) );
+			return OBJLoader2.prototype.parse.call( this, content );
 
 
 		}
 		}
 
 

+ 2 - 0
examples/jsm/loaders/obj2/worker/parallel/OBJLoader2Parser.d.ts

@@ -4,6 +4,7 @@ export class OBJLoader2Parser {
     onProgress: Function;
     onProgress: Function;
     onAssetAvailable: Function;
     onAssetAvailable: Function;
     onError: Function;
     onError: Function;
+    onLoad: Function;
   };
   };
   contentRef: Uint8Array;
   contentRef: Uint8Array;
   legacyMode: boolean;
   legacyMode: boolean;
@@ -63,6 +64,7 @@ export class OBJLoader2Parser {
   setCallbackOnAssetAvailable(onAssetAvailable: Function): this;
   setCallbackOnAssetAvailable(onAssetAvailable: Function): this;
   setCallbackOnProgress(onProgress: Function): this;
   setCallbackOnProgress(onProgress: Function): this;
   setCallbackOnError(onError: Function): this;
   setCallbackOnError(onError: Function): this;
+  setCallbackOnLoad(onLoad: Function): this;
   setLogging(enabled: boolean, debug: boolean): this;
   setLogging(enabled: boolean, debug: boolean): this;
   execute(arrayBuffer: Uint8Array): void;
   execute(arrayBuffer: Uint8Array): void;
   executeLegacy(text: string): void;
   executeLegacy(text: string): void;

+ 27 - 1
examples/jsm/loaders/obj2/worker/parallel/OBJLoader2Parser.js

@@ -18,7 +18,10 @@ const OBJLoader2Parser = function () {
 		},
 		},
 		onError: function ( errorMessage ) {
 		onError: function ( errorMessage ) {
 			scope._onError( errorMessage )
 			scope._onError( errorMessage )
-		}
+		},
+		onLoad: function ( object3d, message ) {
+			scope._onLoad( object3d, message )
+		},
 	};
 	};
 	this.contentRef = null;
 	this.contentRef = null;
 	this.legacyMode = false;
 	this.legacyMode = false;
@@ -216,6 +219,23 @@ OBJLoader2Parser.prototype = {
 
 
 	},
 	},
 
 
+	/**
+	 * Register a function that is called when parsing was completed.
+	 *
+	 * @param {Function} onLoad
+	 * @return {OBJLoader2Parser}
+	 */
+	setCallbackOnLoad: function ( onLoad ) {
+
+		if ( onLoad !== null && onLoad !== undefined && onLoad instanceof Function ) {
+
+			this.callbacks.onLoad = onLoad;
+
+		}
+		return this;
+
+	},
+
 	/**
 	/**
 	 * Announce parse progress feedback which is logged to the console.
 	 * Announce parse progress feedback which is logged to the console.
 	 * @private
 	 * @private
@@ -257,6 +277,12 @@ OBJLoader2Parser.prototype = {
 
 
 	},
 	},
 
 
+	_onLoad: function ( object3d, message ) {
+
+		console.log( "You reached parser default onLoad callback: " + message );
+
+	},
+
 	/**
 	/**
 	 * Enable or disable logging in general (except warn and error), plus enable or disable debug logging.
 	 * Enable or disable logging in general (except warn and error), plus enable or disable debug logging.
 	 *
 	 *

+ 31 - 25
examples/webgl_loader_obj2_options.html

@@ -147,14 +147,14 @@
 						fileLoader.setPath( '' );
 						fileLoader.setPath( '' );
 						fileLoader.setResponseType( 'arraybuffer' );
 						fileLoader.setResponseType( 'arraybuffer' );
 						fileLoader.load( 'models/obj/female02/female02.obj',
 						fileLoader.load( 'models/obj/female02/female02.obj',
-							function ( content ) {
+							function ( content, message ) {
 								let local = new THREE.Object3D();
 								let local = new THREE.Object3D();
 								local.name = 'Pivot_female02';
 								local.name = 'Pivot_female02';
 								local.position.set( 75, 0, 0 );
 								local.position.set( 75, 0, 0 );
 								scope.pivot.add( local );
 								scope.pivot.add( local );
 								local.add( objLoader2.parse( content ) );
 								local.add( objLoader2.parse( content ) );
 
 
-								scope._reportProgress( { detail: { text: 'Loading complete: ' + modelName } } );
+								scope._reportProgress( { detail: { text: 'Loading of ' + modelName + 'completed: ' + message } } );
 							}
 							}
 						);
 						);
 					}
 					}
@@ -168,17 +168,23 @@
 					this._reportProgress( { detail: { text: 'Loading: ' + modelName } } );
 					this._reportProgress( { detail: { text: 'Loading: ' + modelName } } );
 
 
 					let scope = this;
 					let scope = this;
-
-					let objLoader2Parallel = new OBJLoader2Parallel();
-					objLoader2Parallel.setModelName( modelName );
-
-					function callbackOnLoad ( message ) {
-						scope.scene.add( objLoader2Parallel.baseObject3d  );
-						scope._reportProgress( { detail: { text: 'Loading complete: ' + message } } );
+					function callbackOnLoad( object3d, message ) {
+						scope.scene.add( object3d );
+						scope._reportProgress( { detail: { text: 'Loading of ' + modelName + 'completed: ' + message } } );
 					}
 					}
 
 
-					let filename = 'models/obj/female02/female02_vertex_colors.obj';
-					objLoader2Parallel.load( filename, callbackOnLoad );
+					let objLoader2Parallel = new OBJLoader2Parallel()
+						.setModelName( modelName )
+						.setCallbackOnLoad( callbackOnLoad );
+
+					let fileLoader = new THREE.FileLoader();
+					fileLoader.setPath( '' );
+					fileLoader.setResponseType( 'arraybuffer' );
+					fileLoader.load( 'models/obj/female02/female02_vertex_colors.obj',
+						function ( content ) {
+							objLoader2Parallel.parse( content );
+						}
+					);
 				},
 				},
 
 
 				useLoadMain: function () {
 				useLoadMain: function () {
@@ -190,14 +196,14 @@
 					.setUseIndices( true );
 					.setUseIndices( true );
 
 
 					let scope = this;
 					let scope = this;
-					function callbackOnLoad ( object3d ) {
+					function callbackOnLoad ( object3d, message ) {
 						let local = new THREE.Object3D();
 						let local = new THREE.Object3D();
 						local.name = 'Pivot_male02';
 						local.name = 'Pivot_male02';
 						local.position.set( 0, 0, -75 );
 						local.position.set( 0, 0, -75 );
 						scope.pivot.add( local );
 						scope.pivot.add( local );
 						local.add( object3d );
 						local.add( object3d );
 
 
-						scope._reportProgress( { detail: { text: 'Loading complete: ' + objLoader2.modelName } } );
+						scope._reportProgress( { detail: { text: 'Loading of ' + modelName + 'completed: ' + message } } );
 					}
 					}
 
 
 					function onLoadMtl ( mtlParseResult ) {
 					function onLoadMtl ( mtlParseResult ) {
@@ -221,12 +227,12 @@
 					this.pivot.add( local );
 					this.pivot.add( local );
 
 
 					let objLoader2Parallel = new OBJLoader2Parallel()
 					let objLoader2Parallel = new OBJLoader2Parallel()
-					.setModelName( modelName )
-					.setBaseObject3d( local );
+						.setModelName( modelName );
 
 
 					let scope = this;
 					let scope = this;
-					function callbackOnLoad ( message ) {
-						scope._reportProgress( { detail: { text: 'Loading complete: ' + message } } );
+					function callbackOnLoad ( object3d, message ) {
+						local.add( object3d );
+						scope._reportProgress( { detail: { text: 'Loading of ' + modelName + 'completed: ' + message } } );
 					}
 					}
 					function onLoadMtl ( mtlParseResult ) {
 					function onLoadMtl ( mtlParseResult ) {
 						objLoader2Parallel.addMaterials( MtlObjBridge.addMaterialsFromMtlLoader( mtlParseResult ) );
 						objLoader2Parallel.addMaterials( MtlObjBridge.addMaterialsFromMtlLoader( mtlParseResult ) );
@@ -246,13 +252,13 @@
 					this.pivot.add( local );
 					this.pivot.add( local );
 
 
 					let objLoader2Parallel = new OBJLoader2Parallel()
 					let objLoader2Parallel = new OBJLoader2Parallel()
-					.setModelName( local.name )
-					.setExecuteParallel( false );
+						.setModelName( local.name )
+						.setExecuteParallel( false );
 
 
 					let scope = this;
 					let scope = this;
-					function callbackOnLoad ( object3d ) {
+					function callbackOnLoad ( object3d, message ) {
 						local.add( object3d );
 						local.add( object3d );
-						scope._reportProgress( { detail: { text: 'Loading complete: ' + local.name } } );
+						scope._reportProgress( { detail: { text: 'Loading of ' + objLoader2Parallel.modelName + 'completed: ' + message } } );
 					}
 					}
 
 
 					objLoader2Parallel.load( 'models/obj/cerberus/Cerberus.obj', callbackOnLoad );
 					objLoader2Parallel.load( 'models/obj/cerberus/Cerberus.obj', callbackOnLoad );
@@ -265,8 +271,8 @@
 					this.pivot.add( local );
 					this.pivot.add( local );
 
 
 					let objLoader2Parallel = new OBJLoader2Parallel()
 					let objLoader2Parallel = new OBJLoader2Parallel()
-					.setModelName( local.name )
-					.setBaseObject3d( local );
+						.setModelName( local.name )
+						.setBaseObject3d( local );
 
 
 					// Configure WorkerExecutionSupport to not disregard worker after execution
 					// Configure WorkerExecutionSupport to not disregard worker after execution
 					objLoader2Parallel.getWorkerExecutionSupport().setTerminateWorkerOnLoad( false );
 					objLoader2Parallel.getWorkerExecutionSupport().setTerminateWorkerOnLoad( false );
@@ -289,8 +295,8 @@
 					objLoader2Parallel.setCallbackOnMeshAlter( callbackMeshAlter );
 					objLoader2Parallel.setCallbackOnMeshAlter( callbackMeshAlter );
 
 
 					let scope = this;
 					let scope = this;
-					function callbackOnLoad ( message ) {
-						scope._reportProgress( { detail: { text: 'Loading complete: ' + message } } );
+					function callbackOnLoad ( object3d, message ) {
+						scope._reportProgress( { detail: { text: 'Loading of ' + objLoader2Parallel.modelName + 'completed: ' + message } } );
 					}
 					}
 
 
 					objLoader2Parallel.load( 'models/obj/vive-controller/vr_controller_vive_1_5.obj', callbackOnLoad );
 					objLoader2Parallel.load( 'models/obj/vive-controller/vr_controller_vive_1_5.obj', callbackOnLoad );