Browse Source

Transformed webgl_loader_obj2_options.html to jsm and aligned version information

Kai Salmen 6 years ago
parent
commit
f42bb736ef

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

@@ -44,7 +44,7 @@ const OBJLoader2 = function ( manager ) {
 	this.materialHandler = new MaterialHandler();
 	this.materialHandler = new MaterialHandler();
 	this.meshReceiver = new MeshReceiver( this.materialHandler );
 	this.meshReceiver = new MeshReceiver( this.materialHandler );
 };
 };
-OBJLoader2.OBJLOADER2_VERSION = '3.0.0-beta';
+OBJLoader2.OBJLOADER2_VERSION = '3.0.0-beta2';
 console.info( 'Using OBJLoader2 version: ' + OBJLoader2.OBJLOADER2_VERSION );
 console.info( 'Using OBJLoader2 version: ' + OBJLoader2.OBJLOADER2_VERSION );
 
 
 OBJLoader2.prototype = {
 OBJLoader2.prototype = {

+ 7 - 1
examples/jsm/loaders/OBJLoader2Parallel.js

@@ -8,7 +8,7 @@ import {
 	CodeBuilderInstructions,
 	CodeBuilderInstructions,
 	WorkerExecutionSupport
 	WorkerExecutionSupport
 } from "./obj2/worker/main/WorkerExecutionSupport.js";
 } from "./obj2/worker/main/WorkerExecutionSupport.js";
-import { CodeSerializer } from "./obj2/worker/main/CodeSerializer.js";
+import { CodeSerializer } from "./obj2/utils/CodeSerializer.js";
 import { OBJLoader2 } from "./OBJLoader2.js";
 import { OBJLoader2 } from "./OBJLoader2.js";
 
 
 // Imports only related to worker (when standard workers (modules aren't supported) are used)
 // Imports only related to worker (when standard workers (modules aren't supported) are used)
@@ -33,6 +33,8 @@ const OBJLoader2Parallel = function ( manager ) {
 	this.executeParallel = true;
 	this.executeParallel = true;
 	this.workerExecutionSupport = new WorkerExecutionSupport();
 	this.workerExecutionSupport = new WorkerExecutionSupport();
 };
 };
+OBJLoader2.OBJLOADER2_PARALLEL_VERSION = '3.0.0-beta2';
+console.info( 'Using OBJLoader2Parallel version: ' + OBJLoader2.OBJLOADER2PARALLEL_VERSION );
 
 
 OBJLoader2Parallel.prototype = Object.create( OBJLoader2.prototype );
 OBJLoader2Parallel.prototype = Object.create( OBJLoader2.prototype );
 OBJLoader2Parallel.prototype.constructor = OBJLoader2Parallel;
 OBJLoader2Parallel.prototype.constructor = OBJLoader2Parallel;
@@ -59,6 +61,10 @@ OBJLoader2Parallel.prototype.setExecuteParallel = function ( executeParallel ) {
 	return this;
 	return this;
 };
 };
 
 
+OBJLoader2Parallel.prototype.getWorkerExecutionSupport = function () {
+	return this.workerExecutionSupport;
+};
+
 OBJLoader2Parallel.prototype._configure = function () {
 OBJLoader2Parallel.prototype._configure = function () {
 	if ( this.callbackOnLoad === null ) {
 	if ( this.callbackOnLoad === null ) {
 		"No callbackOnLoad was provided! Aborting!"
 		"No callbackOnLoad was provided! Aborting!"

+ 0 - 4
examples/jsm/loaders/obj2/shared/MeshReceiver.js

@@ -20,8 +20,6 @@ import { MaterialHandler } from "./MaterialHandler.js";
  * @constructor
  * @constructor
  */
  */
 const MeshReceiver = function( materialHandler ) {
 const MeshReceiver = function( materialHandler ) {
-	console.info( 'Using MeshReceiver version: ' + MeshReceiver.MESH_RECEIVER_VERSION );
-
 	this.logging = {
 	this.logging = {
 		enabled: true,
 		enabled: true,
 		debug: false
 		debug: false
@@ -33,8 +31,6 @@ const MeshReceiver = function( materialHandler ) {
 	};
 	};
 	this.materialHandler = materialHandler;
 	this.materialHandler = materialHandler;
 };
 };
-MeshReceiver.MESH_RECEIVER_VERSION = '2.0.0-preview';
-
 
 
 MeshReceiver.prototype = {
 MeshReceiver.prototype = {
 
 

+ 1 - 1
examples/jsm/loaders/obj2/worker/main/WorkerExecutionSupport.js

@@ -68,7 +68,7 @@ const WorkerExecutionSupport = function () {
 
 
 	this._reset();
 	this._reset();
 };
 };
-WorkerExecutionSupport.WORKER_SUPPORT_VERSION = '3.0.0-preview';
+WorkerExecutionSupport.WORKER_SUPPORT_VERSION = '3.0.0-beta2';
 console.info( 'Using WorkerSupport version: ' + WorkerExecutionSupport.WORKER_SUPPORT_VERSION );
 console.info( 'Using WorkerSupport version: ' + WorkerExecutionSupport.WORKER_SUPPORT_VERSION );
 
 
 
 

+ 191 - 180
examples/webgl_loader_obj2_options.html

@@ -48,18 +48,38 @@
 			<div id="feedback"></div>
 			<div id="feedback"></div>
 		</div>
 		</div>
 
 
-		<script src="../build/three.js"></script>
-		<script src="js/controls/TrackballControls.js"></script>
-		<script src="js/loaders/MTLLoader.js"></script>
-		<script src="js/libs/dat.gui.min.js"></script>
-
-		<script src="js/loaders/LoaderSupport.js"></script>
-		<script src="js/loaders/OBJLoader2.js"></script>
-		<script>
+		<script type="module">
 
 
 			'use strict';
 			'use strict';
 
 
-			var WWOBJLoader2Example = function ( elementToBindTo ) {
+			import {
+				AmbientLight,
+				DirectionalLight,
+				GridHelper,
+				PerspectiveCamera,
+				Scene,
+				Vector3,
+				BoxBufferGeometry,
+				WebGLRenderer,
+				Object3D,
+				MeshNormalMaterial,
+				Mesh,
+				VertexNormalsHelper,
+				FileLoader,
+				DoubleSide,
+				FrontSide
+			} from "../build/three.module.js";
+			import { GUI } from './jsm/libs/dat.gui.module.js';
+
+			import { TrackballControls } from "./jsm/controls/TrackballControls.js";
+
+			import { MTLLoader } from "./jsm/loaders/MTLLoader.js";
+			import { MtlObjBridge } from "./jsm/loaders/obj2/bridge/MtlObjBridge.js";
+			import { OBJLoader2 } from "./jsm/loaders/OBJLoader2.js";
+			import { OBJLoader2Parallel } from "./jsm/loaders/OBJLoader2Parallel.js";
+			import { LoadedMeshUserOverride } from "./jsm/loaders/obj2/shared/MeshReceiver.js";
+
+			const WWOBJLoader2Example = function ( elementToBindTo ) {
 				this.renderer = null;
 				this.renderer = null;
 				this.canvas = elementToBindTo;
 				this.canvas = elementToBindTo;
 				this.aspectRatio = 1;
 				this.aspectRatio = 1;
@@ -67,8 +87,8 @@
 
 
 				this.scene = null;
 				this.scene = null;
 				this.cameraDefaults = {
 				this.cameraDefaults = {
-					posCamera: new THREE.Vector3( 0.0, 175.0, 500.0 ),
-					posCameraTarget: new THREE.Vector3( 0, 0, 0 ),
+					posCamera: new Vector3( 0.0, 175.0, 500.0 ),
+					posCameraTarget: new Vector3( 0, 0, 0 ),
 					near: 0.1,
 					near: 0.1,
 					far: 10000,
 					far: 10000,
 					fov: 45
 					fov: 45
@@ -90,22 +110,22 @@
 				constructor: WWOBJLoader2Example,
 				constructor: WWOBJLoader2Example,
 
 
 				initGL: function () {
 				initGL: function () {
-					this.renderer = new THREE.WebGLRenderer( {
+					this.renderer = new WebGLRenderer( {
 						canvas: this.canvas,
 						canvas: this.canvas,
 						antialias: true,
 						antialias: true,
 						autoClear: true
 						autoClear: true
 					} );
 					} );
 					this.renderer.setClearColor( 0x050505 );
 					this.renderer.setClearColor( 0x050505 );
 
 
-					this.scene = new THREE.Scene();
+					this.scene = new Scene();
 
 
-					this.camera = new THREE.PerspectiveCamera( this.cameraDefaults.fov, this.aspectRatio, this.cameraDefaults.near, this.cameraDefaults.far );
+					this.camera = new PerspectiveCamera( this.cameraDefaults.fov, this.aspectRatio, this.cameraDefaults.near, this.cameraDefaults.far );
 					this.resetCamera();
 					this.resetCamera();
-					this.controls = new THREE.TrackballControls( this.camera, this.renderer.domElement );
+					this.controls = new TrackballControls( this.camera, this.renderer.domElement );
 
 
-					var ambientLight = new THREE.AmbientLight( 0x404040 );
-					var directionalLight1 = new THREE.DirectionalLight( 0xC0C090 );
-					var directionalLight2 = new THREE.DirectionalLight( 0xC0C090 );
+					let ambientLight = new AmbientLight( 0x404040 );
+					let directionalLight1 = new DirectionalLight( 0xC0C090 );
+					let directionalLight2 = new DirectionalLight( 0xC0C090 );
 
 
 					directionalLight1.position.set( -100, -50, 100 );
 					directionalLight1.position.set( -100, -50, 100 );
 					directionalLight2.position.set( 100, 50, -100 );
 					directionalLight2.position.set( 100, 50, -100 );
@@ -114,193 +134,182 @@
 					this.scene.add( directionalLight2 );
 					this.scene.add( directionalLight2 );
 					this.scene.add( ambientLight );
 					this.scene.add( ambientLight );
 
 
-					var helper = new THREE.GridHelper( 1200, 60, 0xFF4444, 0x404040 );
+					let helper = new GridHelper( 1200, 60, 0xFF4444, 0x404040 );
 					this.scene.add( helper );
 					this.scene.add( helper );
 
 
-					var geometry = new THREE.BoxBufferGeometry( 10, 10, 10 );
-					var material = new THREE.MeshNormalMaterial();
-					this.cube = new THREE.Mesh( geometry, material );
+					let geometry = new BoxBufferGeometry( 10, 10, 10 );
+					let material = new MeshNormalMaterial();
+					this.cube = new Mesh( geometry, material );
 					this.cube.position.set( 0, 0, 0 );
 					this.cube.position.set( 0, 0, 0 );
 					this.scene.add( this.cube );
 					this.scene.add( this.cube );
 
 
-					this.pivot = new THREE.Object3D();
+					this.pivot = new Object3D();
 					this.pivot.name = 'Pivot';
 					this.pivot.name = 'Pivot';
 					this.scene.add( this.pivot );
 					this.scene.add( this.pivot );
 				},
 				},
 
 
-				useParseSync: function () {
-					var modelName = 'female02';
+				useParseMain: function () {
+					let modelName = 'female02';
 					this._reportProgress( { detail: { text: 'Loading: ' + modelName } } );
 					this._reportProgress( { detail: { text: 'Loading: ' + modelName } } );
 
 
-					var scope = this;
-					var objLoader = new THREE.OBJLoader2();
-					var onLoadMtl = function ( materials ) {
-						objLoader.setModelName( modelName );
-						objLoader.setMaterials( materials );
+					let objLoader2 = new OBJLoader2()
+						.setModelName( modelName );
+
+					let scope = this;
+					function onLoadMtl ( mtlParseResult ) {
+						objLoader2.addMaterials( MtlObjBridge.addMaterialsFromMtlLoader( mtlParseResult ) );
 
 
-						var fileLoader = new THREE.FileLoader();
+						let fileLoader = new FileLoader();
 						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 ) {
-								var local = new THREE.Object3D();
+								let local = new 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( objLoader.parse( content ) );
+								local.add( objLoader2.parse( content ) );
 
 
 								scope._reportProgress( { detail: { text: 'Loading complete: ' + modelName } } );
 								scope._reportProgress( { detail: { text: 'Loading complete: ' + modelName } } );
 							}
 							}
 						);
 						);
-					};
-					var onError = function ( event ) {
-						console.error( 'Error occurred: ' + event );
-					};
-					objLoader.loadMtl( 'models/obj/female02/female02.mtl', null, onLoadMtl, null, onError );
+					}
+
+					let mtlLoader = new MTLLoader();
+					mtlLoader.load( 'models/obj/female02/female02.mtl', onLoadMtl );
 				},
 				},
 
 
-				useParseAsync: function () {
-					var modelName = 'female02_vertex' ;
+				useParseParallel: function () {
+					let modelName = 'female02_vertex' ;
 					this._reportProgress( { detail: { text: 'Loading: ' + modelName } } );
 					this._reportProgress( { detail: { text: 'Loading: ' + modelName } } );
 
 
-					var callbackOnLoad = function ( event ) {
-						var local = new THREE.Object3D();
-						local.name = 'Pivot_female02_vertex';
-						local.position.set( -75, 0, 0 );
-						scope.pivot.add( local );
-						local.add( event.detail.loaderRootNode );
+					let scope = this;
 
 
-						scope._reportProgress( { detail: { text: 'Loading complete: ' + event.detail.modelName } } );
-					};
+					let objLoader2Parallel = new OBJLoader2Parallel();
+					objLoader2Parallel.setModelName( modelName );
 
 
-					var scope = this;
-					var objLoader = new THREE.OBJLoader2();
-					objLoader.setModelName( modelName );
-
-					var fileLoader = new THREE.FileLoader();
-					fileLoader.setPath( '' );
-					fileLoader.setResponseType( 'arraybuffer' );
-					var filename = 'models/obj/female02/female02_vertex_colors.obj';
-					fileLoader.load( filename,
-						function ( content ) {
-							objLoader.parseAsync( content, callbackOnLoad );
-							scope._reportProgress( { detail: { text: 'File loading complete: ' + filename } } );
-						}
-					);
+					function callbackOnLoad ( message ) {
+						scope.scene.add( objLoader2Parallel.baseObject3d  );
+						scope._reportProgress( { detail: { text: 'Loading complete: ' + message } } );
+					}
+
+					let filename = 'models/obj/female02/female02_vertex_colors.obj';
+					objLoader2Parallel.load( filename, callbackOnLoad );
 				},
 				},
 
 
-				useLoadSync: function () {
-					var modelName = 'male02';
+				useLoadMain: function () {
+					let modelName = 'male02';
 					this._reportProgress( { detail: { text: 'Loading: ' + modelName } } );
 					this._reportProgress( { detail: { text: 'Loading: ' + modelName } } );
 
 
-					var scope = this;
-					var objLoader = new THREE.OBJLoader2();
-					var callbackOnLoad = function ( event ) {
-						var local = new THREE.Object3D();
+					let objLoader2 = new OBJLoader2()
+					.setModelName( modelName )
+					.setUseIndices( true );
+
+					let scope = this;
+					function callbackOnLoad ( object3d ) {
+						let local = new 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( event.detail.loaderRootNode );
+						local.add( object3d );
 
 
-						scope._reportProgress( { detail: { text: 'Loading complete: ' + event.detail.modelName } } );
-					};
+						scope._reportProgress( { detail: { text: 'Loading complete: ' + objLoader2.modelName } } );
+					}
 
 
-					var onLoadMtl = function ( materials ) {
-						objLoader.setModelName( modelName );
-						objLoader.setMaterials( materials );
-						objLoader.setUseIndices( true );
-						objLoader.load( 'models/obj/male02/male02.obj', callbackOnLoad, null, null, null, false );
-					};
-					objLoader.loadMtl( 'models/obj/male02/male02.mtl', null, onLoadMtl );
+					function onLoadMtl ( mtlParseResult ) {
+						objLoader2.addMaterials( MtlObjBridge.addMaterialsFromMtlLoader( mtlParseResult ) );
+						objLoader2.load( 'models/obj/male02/male02.obj', callbackOnLoad, null, null, null );
+					}
+
+					let mtlLoader = new MTLLoader();
+					mtlLoader.load( 'models/obj/male02/male02.mtl', onLoadMtl );
 				},
 				},
 
 
-				useLoadAsync: function () {
-					var modelName = 'WaltHead';
+				useLoadParallel: function () {
+					let modelName = 'WaltHead';
 					this._reportProgress( { detail: { text: 'Loading: ' + modelName } } );
 					this._reportProgress( { detail: { text: 'Loading: ' + modelName } } );
 
 
-					var scope = this;
-					var objLoader = new THREE.OBJLoader2();
-					var callbackOnLoad = function ( event ) {
-						objLoader.workerSupport.setTerminateRequested( true );
-
-						var local = new THREE.Object3D();
-						local.name = 'Pivot_WaltHead';
-						local.position.set( -125, 50, 0 );
-						var scale = 0.5;
-						local.scale.set( scale, scale, scale );
-						scope.pivot.add( local );
-						local.add( event.detail.loaderRootNode );
+					let local = new Object3D();
+					local.name = 'Pivot_WaltHead';
+					local.position.set( -125, 50, 0 );
+					let scale = 0.5;
+					local.scale.set( scale, scale, scale );
+					this.pivot.add( local );
 
 
-						scope._reportProgress( { detail: { text: 'Loading complete: ' + event.detail.modelName } } );
-					};
+					let objLoader2Parallel = new OBJLoader2Parallel()
+					.setModelName( modelName )
+					.setBaseObject3d( local );
 
 
-					var onLoadMtl = function ( materials ) {
-						objLoader.setModelName( modelName );
-						objLoader.setMaterials( materials );
-						objLoader.terminateWorkerOnLoad = false;
-						objLoader.load( 'models/obj/walt/WaltHead.obj', callbackOnLoad, null, null, null, true );
+					let scope = this;
+					function callbackOnLoad ( message ) {
+						scope._reportProgress( { detail: { text: 'Loading complete: ' + message } } );
+					}
+					function onLoadMtl ( mtlParseResult ) {
+						objLoader2Parallel.addMaterials( MtlObjBridge.addMaterialsFromMtlLoader( mtlParseResult ) );
+						objLoader2Parallel.load( 'models/obj/walt/WaltHead.obj', callbackOnLoad );
+					}
 
 
-					};
-					objLoader.loadMtl( 'models/obj/walt/WaltHead.mtl', null, onLoadMtl );
+					let mtlLoader = new MTLLoader();
+					mtlLoader.load( 'models/obj/walt/WaltHead.mtl', onLoadMtl );
 				},
 				},
 
 
-				useRunSync: function () {
-					var scope = this;
-					var callbackOnLoad = function ( event ) {
-						scope._reportProgress( { detail: { text: 'Loading complete: ' + event.detail.modelName } } );
-					};
-
-					var prepData = new THREE.LoaderSupport.PrepData( 'cerberus' );
-					var local = new THREE.Object3D();
+				useLoadMainFallback: function () {
+					let local = new Object3D();
+					local.name = 'Pivot_Cerberus';
 					local.position.set( 0, 0, 100 );
 					local.position.set( 0, 0, 100 );
-					local.scale.set( 50.0, 50.0, 50.0 );
+					let scale = 50;
+					local.scale.set( scale, scale, scale );
 					this.pivot.add( local );
 					this.pivot.add( local );
-					prepData.streamMeshesTo = local;
-					prepData.addResource( new THREE.LoaderSupport.ResourceDescriptor( 'models/obj/cerberus/Cerberus.obj', 'OBJ' ) );
-					var callbacks = prepData.getCallbacks();
-					callbacks.setCallbackOnProgress( this._reportProgress );
-					callbacks.setCallbackOnLoad( callbackOnLoad );
-
-					var objLoader = new THREE.OBJLoader2();
-					objLoader.run( prepData );
-				},
 
 
-				useRunAsyncMeshAlter: function () {
-					var scope = this;
-					var callbackOnLoad = function ( event ) {
-						scope._reportProgress( { detail: { text: 'Loading complete: ' + event.detail.modelName } } );
-					};
+					let objLoader2Parallel = new OBJLoader2Parallel()
+					.setModelName( local.name )
+					.setExecuteParallel( false );
+
+					let scope = this;
+					function callbackOnLoad ( object3d ) {
+						local.add( object3d );
+						scope._reportProgress( { detail: { text: 'Loading complete: ' + local.name } } );
+					}
 
 
-					var prepData = new THREE.LoaderSupport.PrepData( 'vive-controller' );
-					var local = new THREE.Object3D();
+					objLoader2Parallel.load( 'models/obj/cerberus/Cerberus.obj', callbackOnLoad );
+				},
+
+				useLoadParallelMeshAlter: function () {
+					let local = new Object3D();
 					local.position.set( 125, 50, 0 );
 					local.position.set( 125, 50, 0 );
 					local.name = 'Pivot_vive-controller';
 					local.name = 'Pivot_vive-controller';
 					this.pivot.add( local );
 					this.pivot.add( local );
-					prepData.streamMeshesTo = local;
-					prepData.addResource( new THREE.LoaderSupport.ResourceDescriptor( 'models/obj/vive-controller/vr_controller_vive_1_5.obj', 'OBJ' ) );
-					prepData.useAsync = true;
-					var callbacks = prepData.getCallbacks();
-					var callbackMeshAlter = function ( event ) {
-						var override = new THREE.LoaderSupport.LoadedMeshUserOverride( false, true );
-
-						var mesh = new THREE.Mesh( event.detail.bufferGeometry, event.detail.material );
-						var scale = 200.0;
+
+					let objLoader2Parallel = new OBJLoader2Parallel()
+					.setModelName( local.name )
+					.setBaseObject3d( local );
+
+					// Configure WorkerExecutionSupport to disregard worker after execution
+					objLoader2Parallel.getWorkerExecutionSupport().setTerminateWorkerOnLoad( true );
+
+					function callbackMeshAlter ( event ) {
+						let override = new LoadedMeshUserOverride( false, true );
+
+						let mesh = new Mesh( event.detail.bufferGeometry, event.detail.material );
+						let scale = 200.0;
 						mesh.scale.set( scale, scale, scale );
 						mesh.scale.set( scale, scale, scale );
 						mesh.name = event.detail.meshName;
 						mesh.name = event.detail.meshName;
-						var helper = new THREE.VertexNormalsHelper( mesh, 2, 0x00ff00, 1 );
+						let helper = new VertexNormalsHelper( mesh, 2, 0x00ff00, 1 );
 						helper.name = 'VertexNormalsHelper';
 						helper.name = 'VertexNormalsHelper';
 
 
 						override.addMesh( mesh );
 						override.addMesh( mesh );
 						override.addMesh( helper );
 						override.addMesh( helper );
 
 
 						return override;
 						return override;
-					};
-					callbacks.setCallbackOnMeshAlter( callbackMeshAlter );
-					callbacks.setCallbackOnProgress( this._reportProgress );
-					callbacks.setCallbackOnLoad( callbackOnLoad );
+					}
+					objLoader2Parallel._setCallbacks( null, callbackMeshAlter );
 
 
-					var objLoader = new THREE.OBJLoader2();
-					objLoader.run( prepData );
+					let scope = this;
+					function callbackOnLoad ( message ) {
+						scope._reportProgress( { detail: { text: 'Loading complete: ' + message } } );
+					}
+
+					objLoader2Parallel.load( 'models/obj/vive-controller/vr_controller_vive_1_5.obj', callbackOnLoad );
 				},
 				},
 
 
 				finalize: function () {
 				finalize: function () {
@@ -308,7 +317,12 @@
 				},
 				},
 
 
 				_reportProgress: function( event ) {
 				_reportProgress: function( event ) {
-					var output = THREE.LoaderSupport.Validator.verifyInput( event.detail.text, '' );
+					let output = '';
+					if ( event.detail !== null && event.detail !== undefined && event.detail.text ) {
+
+						output = event.detail.text;
+
+					}
 					console.log( 'Progress: ' + output );
 					console.log( 'Progress: ' + output );
 					document.getElementById( 'feedback' ).innerHTML = output;
 					document.getElementById( 'feedback' ).innerHTML = output;
 				},
 				},
@@ -351,7 +365,7 @@
 				},
 				},
 
 
 				alterShading: function () {
 				alterShading: function () {
-					var scope = this;
+					let scope = this;
 					scope.flatShading = ! scope.flatShading;
 					scope.flatShading = ! scope.flatShading;
 					console.log( scope.flatShading ? 'Enabling flat shading' : 'Enabling smooth shading');
 					console.log( scope.flatShading ? 'Enabling flat shading' : 'Enabling smooth shading');
 
 
@@ -359,32 +373,32 @@
 						material.flatShading = scope.flatShading;
 						material.flatShading = scope.flatShading;
 						material.needsUpdate = true;
 						material.needsUpdate = true;
 					};
 					};
-					var scopeTraverse = function ( object3d ) {
+					function scopeTraverse ( object3d ) {
 						scope.traverseScene( object3d );
 						scope.traverseScene( object3d );
-					};
+					}
 					scope.pivot.traverse( scopeTraverse );
 					scope.pivot.traverse( scopeTraverse );
 				},
 				},
 
 
 				alterDouble: function () {
 				alterDouble: function () {
-					var scope = this;
+					let scope = this;
 					scope.doubleSide = ! scope.doubleSide;
 					scope.doubleSide = ! scope.doubleSide;
-					console.log( scope.doubleSide ? 'Enabling DoubleSide materials' : 'Enabling FrontSide materials' );
+					console.log( scope.doubleSide ? 'Enabling DoubleSide materials' : 'Enabling FrontSide materials');
 
 
 					scope.traversalFunction = function ( material ) {
 					scope.traversalFunction = function ( material ) {
-						material.side = scope.doubleSide ? THREE.DoubleSide : THREE.FrontSide;
+						material.side = scope.doubleSide ? DoubleSide : FrontSide;
 					};
 					};
 
 
-					var scopeTraverse = function ( object3d ) {
+					function scopeTraverse ( object3d ) {
 						scope.traverseScene( object3d );
 						scope.traverseScene( object3d );
-					};
+					}
 					scope.pivot.traverse( scopeTraverse );
 					scope.pivot.traverse( scopeTraverse );
 				},
 				},
 
 
 				traverseScene: function ( object3d ) {
 				traverseScene: function ( object3d ) {
-					if ( object3d.material instanceof THREE.MultiMaterial ) {
+					if ( Array.isArray( object3d.material ) ) {
 
 
-						var materials = object3d.material.materials;
-						for ( var name in materials ) {
+						let materials = object3d.material.materials;
+						for ( let name in materials ) {
 
 
 							if ( materials.hasOwnProperty( name ) )	this.traversalFunction( materials[ name ] );
 							if ( materials.hasOwnProperty( name ) )	this.traversalFunction( materials[ name ] );
 
 
@@ -399,29 +413,28 @@
 
 
 			};
 			};
 
 
+			let app = new WWOBJLoader2Example( document.getElementById( 'example' ) );
 
 
-			var app = new WWOBJLoader2Example( document.getElementById( 'example' ) );
-
-			var wwObjLoader2Control = {
+			let wwObjLoader2Control = {
 				flatShading: app.flatShading,
 				flatShading: app.flatShading,
 				doubleSide: app.doubleSide
 				doubleSide: app.doubleSide
 			};
 			};
 
 
-			var menuDiv = document.getElementById( 'dat' );
-			var gui = new dat.GUI( {
+			let menuDiv = document.getElementById( 'dat' );
+			let gui = new GUI( {
 				autoPlace: false,
 				autoPlace: false,
 				width: 320
 				width: 320
 			} );
 			} );
 			menuDiv.appendChild( gui.domElement );
 			menuDiv.appendChild( gui.domElement );
 
 
-			var folderOptions = gui.addFolder( 'WWOBJLoader2 Options' );
-			var controlFlat = folderOptions.add( wwObjLoader2Control, 'flatShading' ).name( 'Flat Shading' );
+			let folderOptions = gui.addFolder( 'WWOBJLoader2 Options' );
+			let controlFlat = folderOptions.add( wwObjLoader2Control, 'flatShading' ).name( 'Flat Shading' );
 			controlFlat.onChange( function( value ) {
 			controlFlat.onChange( function( value ) {
 				console.log( 'Setting flatShading to: ' + value );
 				console.log( 'Setting flatShading to: ' + value );
 				app.alterShading();
 				app.alterShading();
 			});
 			});
 
 
-			var controlDouble = folderOptions.add( wwObjLoader2Control, 'doubleSide' ).name( 'Double Side Materials' );
+			let controlDouble = folderOptions.add( wwObjLoader2Control, 'doubleSide' ).name( 'Double Side Materials' );
 			controlDouble.onChange( function( value ) {
 			controlDouble.onChange( function( value ) {
 				console.log( 'Setting doubleSide to: ' + value );
 				console.log( 'Setting doubleSide to: ' + value );
 				app.alterDouble();
 				app.alterDouble();
@@ -430,14 +443,14 @@
 
 
 
 
 			// init three.js example application
 			// init three.js example application
-			var resizeWindow = function () {
+			function resizeWindow () {
 				app.resizeDisplayGL();
 				app.resizeDisplayGL();
-			};
+			}
 
 
-			var render = function () {
+			function render () {
 				requestAnimationFrame( render );
 				requestAnimationFrame( render );
 				app.render();
 				app.render();
-			};
+			}
 			window.addEventListener( 'resize', resizeWindow, false );
 			window.addEventListener( 'resize', resizeWindow, false );
 
 
 			console.log( 'Starting initialisation phase...' );
 			console.log( 'Starting initialisation phase...' );
@@ -447,25 +460,23 @@
 			// kick render loop
 			// kick render loop
 			render();
 			render();
 
 
+			// Load a file with OBJLoader2.parse on main
+			app.useParseMain();
 
 
-			// Load a file with OBJLoader.parse synchronously
-			app.useParseSync();
-
-			// Load a file with OBJLoader.parseAsync asynchronously using a worker
-			app.useParseAsync();
-
-			// Load a file with OBJLoader.load synchronously
-			app.useLoadSync();
+			// Load a file with OBJLoader2Parallel.parse in parallel in worker
+			app.useParseParallel();
 
 
-			// Load a file with OBJLoader.load asynchronously
-			app.useLoadAsync();
+			// Load a file with OBJLoader.load on main
+			app.useLoadMain();
 
 
-			// Load a file with OBJLoader.run synchronously
-			app.useRunSync();
+			// Load a file with OBJLoader2Parallel.load in parallel in worker
+			app.useLoadParallel();
 
 
-			// Load a file with OBJLoader.run asynchronously and add normals during onMeshAlter
-			app.useRunAsyncMeshAlter();
+			// Load a file with OBJLoader2Parallel.load on main with fallback to OBJLoader2.parse
+			app.useLoadMainFallback();
 
 
+			// Load a file with OBJLoader2Parallel.load in parallel in worker and add normals during onMeshAlter
+			app.useLoadParallelMeshAlter();
 			app.finalize();
 			app.finalize();
 
 
 		</script>
 		</script>