Bladeren bron

Merge branch 'dev' into textureoffset

Mr.doob 8 jaren geleden
bovenliggende
commit
c261aad8aa
100 gewijzigde bestanden met toevoegingen van 6005 en 5014 verwijderingen
  1. 2 2
      README.md
  2. 94 42
      build/three.js
  3. 279 280
      build/three.min.js
  4. 94 42
      build/three.module.js
  5. 0 8
      docs/api/cameras/Camera.html
  6. 5 1
      docs/api/cameras/OrthographicCamera.html
  7. 5 4
      docs/api/cameras/PerspectiveCamera.html
  8. 9 3
      docs/api/core/Object3D.html
  9. 3 3
      docs/api/loaders/managers/LoadingManager.html
  10. 274 0
      docs/examples/controls/OrbitControls.html
  11. 91 0
      docs/examples/exporters/GLTFExporter.html
  12. 9 1
      docs/list.js
  13. 2 2
      docs/manual/buildTools/Testing-with-NPM.html
  14. 7 3
      docs/manual/introduction/Creating-a-scene.html
  15. 2 2
      docs/manual/introduction/Import-via-modules.html
  16. 1 2
      editor/js/Sidebar.Material.js
  17. 5 4
      examples/files.js
  18. 21 8
      examples/js/Mirror.js
  19. 1 1
      examples/js/exporters/GLTFExporter.js
  20. 102 56
      examples/js/libs/msgpack-js.js
  21. 34 30
      examples/js/loaders/3MFLoader.js
  22. 4 4
      examples/js/loaders/AMFLoader.js
  23. 200 204
      examples/js/loaders/AWDLoader.js
  24. 3 3
      examples/js/loaders/AssimpJSONLoader.js
  25. 49 30
      examples/js/loaders/AssimpLoader.js
  26. 25 25
      examples/js/loaders/BVHLoader.js
  27. 1 0
      examples/js/loaders/BabylonLoader.js
  28. 37 37
      examples/js/loaders/BinaryLoader.js
  29. 42 34
      examples/js/loaders/ColladaLoader2.js
  30. 3 2
      examples/js/loaders/DDSLoader.js
  31. 12 9
      examples/js/loaders/FBXLoader.js
  32. 80 88
      examples/js/loaders/GLTFLoader.js
  33. 61 46
      examples/js/loaders/ImageBitmapLoader.js
  34. 1 1
      examples/js/loaders/KMZLoader.js
  35. 1155 0
      examples/js/loaders/LoaderSupport.js
  36. 104 104
      examples/js/loaders/MMDLoader.js
  37. 2 2
      examples/js/loaders/MTLLoader.js
  38. 15 13
      examples/js/loaders/NRRDLoader.js
  39. 634 250
      examples/js/loaders/OBJLoader2.js
  40. 0 0
      examples/js/loaders/PDBLoader.js
  41. 17 17
      examples/js/loaders/PLYLoader.js
  42. 1 3
      examples/js/loaders/PRWMLoader.js
  43. 54 77
      examples/js/loaders/PVRLoader.js
  44. 1 1
      examples/js/loaders/PlayCanvasLoader.js
  45. 32 35
      examples/js/loaders/RGBELoader.js
  46. 1 1
      examples/js/loaders/STLLoader.js
  47. 1 1
      examples/js/loaders/SVGLoader.js
  48. 60 65
      examples/js/loaders/TDSLoader.js
  49. 63 56
      examples/js/loaders/TGALoader.js
  50. 96 96
      examples/js/loaders/UTF8Loader.js
  51. 93 78
      examples/js/loaders/VRMLLoader.js
  52. 185 124
      examples/js/loaders/VTKLoader.js
  53. 0 1455
      examples/js/loaders/WWOBJLoader2.js
  54. 157 0
      examples/js/postprocessing/SSAOPass.js
  55. 30 8
      examples/js/postprocessing/UnrealBloomPass.js
  56. 1 1
      examples/js/renderers/SVGRenderer.js
  57. 4 4
      examples/js/shaders/LuminosityShader.js
  58. 6 6
      examples/js/shaders/ToneMapShader.js
  59. 2 2
      examples/js/vr/ViveController.js
  60. 4 56
      examples/js/vr/WebVR.js
  61. 5 2
      examples/misc_animation_keys.html
  62. 34 35
      examples/misc_controls_pointerlock.html
  63. 4 4
      examples/misc_exporter_gltf.html
  64. 146 0
      examples/models/collada/abb_irb52_7_120.dae
  65. 0 317
      examples/models/collada/multimaterial.dae
  66. 0 0
      examples/models/collada/skin_and_morph.dae
  67. BIN
      examples/models/skinned/simple/simple.blend
  68. 2 2
      examples/webaudio_sandbox.html
  69. 3 3
      examples/webaudio_visualizer.html
  70. 1 1
      examples/webgl_geometry_shapes.html
  71. 29 12
      examples/webgl_loader_collada_kinematics.html
  72. 27 178
      examples/webgl_loader_obj2.html
  73. 471 0
      examples/webgl_loader_obj2_meshspray.html
  74. 490 0
      examples/webgl_loader_obj2_options.html
  75. 93 109
      examples/webgl_loader_obj2_run_director.html
  76. 0 502
      examples/webgl_loader_obj2_ww.html
  77. 1 1
      examples/webgl_loader_prwm.html
  78. 4 2
      examples/webgl_mirror.html
  79. 1 1
      examples/webgl_postprocessing_sao.html
  80. 1 1
      examples/webgl_postprocessing_sobel.html
  81. 16 38
      examples/webgl_postprocessing_ssao.html
  82. 48 32
      examples/webgl_postprocessing_unreal_bloom.html
  83. 36 46
      examples/webgl_shader.html
  84. 36 49
      examples/webgl_shader2.html
  85. 19 39
      examples/webgl_shader_lava.html
  86. 20 2
      examples/webvr_cubes.html
  87. 2 2
      examples/webvr_daydream.html
  88. 2 2
      examples/webvr_panorama.html
  89. 2 2
      examples/webvr_rollercoaster.html
  90. 2 2
      examples/webvr_sandbox.html
  91. 2 2
      examples/webvr_video.html
  92. 22 15
      src/Three.Legacy.js
  93. 52 49
      src/animation/AnimationAction.js
  94. 19 19
      src/animation/AnimationClip.js
  95. 38 14
      src/animation/AnimationMixer.js
  96. 22 14
      src/animation/AnimationObjectGroup.js
  97. 32 33
      src/animation/KeyframeTrack.js
  98. 3 3
      src/animation/KeyframeTrackConstructor.js
  99. 10 14
      src/animation/KeyframeTrackPrototype.js
  100. 34 35
      src/animation/PropertyBinding.js

+ 2 - 2
README.md

@@ -19,14 +19,14 @@ The aim of the project is to create an easy to use, lightweight, 3D library. The
 
 ### Usage ###
 
-Download the [minified library](http://threejs.org/build/three.min.js) and include it in your html, or install and import it as a [module](http://threejs.org/docs/#manual/introduction/Import-via-modules),
+Download the [minified library](http://threejs.org/build/three.min.js) and include it in your HTML, or install and import it as a [module](http://threejs.org/docs/#manual/introduction/Import-via-modules),
 Alternatively see [how to build the library yourself](https://github.com/mrdoob/three.js/wiki/Build-instructions).
 
 ```html
 <script src="js/three.min.js"></script>
 ```
 
-This code creates a scene, a camera, and a geometric cube, and it adds the cube to the scene. It then creates a `WebGL` renderer for the scene and camera, and it adds that viewport to the document.body element. Finally it animates the cube within the scene for the camera.
+This code creates a scene, a camera, and a geometric cube, and it adds the cube to the scene. It then creates a `WebGL` renderer for the scene and camera, and it adds that viewport to the document.body element. Finally, it animates the cube within the scene for the camera.
 
 ```javascript
 var scene, camera, renderer;

File diff suppressed because it is too large
+ 94 - 42
build/three.js


File diff suppressed because it is too large
+ 279 - 280
build/three.min.js


File diff suppressed because it is too large
+ 94 - 42
build/three.module.js


+ 0 - 8
docs/api/cameras/Camera.html

@@ -80,14 +80,6 @@
 		(which can be reused in this way), otherwise a new vector will be created.
 		</div>
 
-		<h3>[method:null lookAt]( [page:Vector3 target] )</h3>
-		<div>
-		target — position in 3D space for the camera to point towards<br /><br />
-
-		This makes the camera look at the vector position in the global space as long as
-		the parent of this camera is the scene or at position (0,0,0).
-		</div>
-
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 5 - 1
docs/api/cameras/OrthographicCamera.html

@@ -58,7 +58,11 @@ scene.add( camera );</code>
 
 
 		<h2>Properties</h2>
-		<div>See the base [page:Camera] class for common properties.</div>
+		<div>
+			See the base [page:Camera] class for common properties.<br>
+ 			Note that after making changes to most of these poperties you will have to call 
+ 			[page:OrthographicCamera.updateProjectionMatrix .updateProjectionMatrix] for the changes to take effect.
+		</div>
 
 		<h3>[property:Float bottom]</h3>
 		<div>Camera frustum bottom plane.</div>

+ 5 - 4
docs/api/cameras/PerspectiveCamera.html

@@ -48,7 +48,11 @@ scene.add( camera );</code>
 
 
 		<h2>Properties</h2>
-		<div>See the base [page:Camera] class for common properties.</div>
+		<div>
+			See the base [page:Camera] class for common properties.<br>
+			Note that after making changes to most of these poperties you will have to call 
+			[page:PerspectiveCamera.updateProjectionMatrix .updateProjectionMatrix] for the changes to take effect. 
+		</div>
 
 		<h3>[property:Float aspect]</h3>
 		<div>Camera frustum aspect ratio, usually the canvas width / canvas height. Default is *1* (square canvas).</div>
@@ -103,9 +107,6 @@ scene.add( camera );</code>
 		<div>Gets or sets the zoom factor of the camera. Default is *1*.</div>
 
 
-
-
-
 		<h2>Methods</h2>
 		<div>See the base [page:Camera] class for common methods.</div>
 

+ 9 - 3
docs/api/core/Object3D.html

@@ -112,7 +112,7 @@
 		<div>Object's parent in the [link:https://en.wikipedia.org/wiki/Scene_graph scene graph].</div>
 
 		<h3>[property:Vector3 position]</h3>
-		<div>The object's local position.</div>
+		<div>A [page:Vector3] representing the object's local position. Default is (0, 0, 0).</div>
 
 		<h3>[property:Quaternion quaternion]</h3>
 		<div>Object's local rotation as a [page:Quaternion Quaternion].</div>
@@ -287,11 +287,17 @@
 		Converts the vector from local space to world space.
 		</div>
 
-		<h3>[method:null lookAt]( [page:Vector3 vector] )</h3>
+		<h3>[method:null lookAt]( [page:Vector3 vector] )</br>
+		[method:null lookAt]( [page:Float x], [page:Float y], [page:Float z] )</h3>
 		<div>
 		vector - A vector representing a position in world space.<br /><br />
+		Optionally, the [page:.x x], [page:.y y] and [page:.z z] components of the world space position.<br /><br />
+
+		Rotates the object to face a point in world space.<br /><br />
+
+		This method does not support objects with rotated and/or translated parent(s).
+		</div>
 
-		Rotates the object to face a point in world space.
 		</div>
 
 		<h3>[method:Array raycast]( [page:Raycaster raycaster], [page:Array intersects] )</h3>

+ 3 - 3
docs/api/loaders/managers/LoadingManager.html

@@ -130,14 +130,14 @@
 		<div>
 		[page:String url] — the url to load<br /><br />
 
-		This should be called by any loader used by the manager when the loader starts loading an url.
+		This should be called by any loader using the manager when the loader starts loading an url.
 		</div>
 
 		<h3>[method:null itemEnd]( [page:String url] )</h3>
 		<div>
 		[page:String url] — the loaded url<br /><br />
 
-		This should be called by any loader used by the manager when the loader ended loading an url.
+		This should be called by any loader using the manager when the loader ended loading an url.
 		</div>
 
 
@@ -145,7 +145,7 @@
 		<div>
 		[page:String url] — the loaded url<br /><br />
 
-		This should be called by any loader used by the manager when the loader errors loading an url.
+		This should be called by any loader using the manager when the loader errors loading an url.
 		</div>
 
 		<h2>Source</h2>

+ 274 - 0
docs/examples/controls/OrbitControls.html

@@ -0,0 +1,274 @@
+<!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>
+
+		<div class="desc">
+      Orbit controls allow the camera to orbit around a target.<br>
+
+      To use this, as with all files in the /examples directory, you will have to
+      include the file seperately in your HTML.
+
+		</div>
+
+
+		<h2>Example</h2>
+
+		<div>[example:misc_controls_orbit misc / controls / orbit ]</div>
+
+		<code>
+var renderer = new THREE.WebGLRenderer();
+renderer.setSize( window.innerWidth, window.innerHeight );
+document.body.appendChild( renderer.domElement );
+
+var scene = new THREE.Scene();
+
+var  camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
+
+var controls = new THREE.OrbitControls( camera );
+
+//controls.update() must be called after any manual changes to the camera's transform
+camera.position.set( 0, 20, 100 );
+controls.update();
+
+function animate() {
+
+  requestAnimationFrame( animate );
+
+  // required if controls.enableDamping or controls.autoRotate are set to true
+  controls.update();
+
+  renderer.render( scene, camera );
+
+}
+		</code>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [page:Camera object], [page:HTMLDOMElement domElement] )</h3>
+		<div>
+      [page:Camera object]: (required) The camera to be controlled.<br><br>
+
+      [page:HTMLDOMElement domElement]: (optional) The HTML element used for event listeners. By default this is the whole document,
+      however if you only want to the controls to work over a specific element (e.g. the canvas) you can specify that here.
+		</div>
+
+
+    <h2>Properties</h2>
+
+    <h3>[property:Boolean autoRotate]</h3>
+    <div>
+      Set to true to automatically rotate around the target.<br> Note that if this is enabled, you must call [page:.update]
+      () in your animation loop.
+    </div>
+
+    <h3>[property:Float autoRotateSpeed]</h3>
+    <div>
+      How fast to rotate around the target if [property:Boolean autoRotate] is true. Default is 2.0, which equates to 30 seconds
+      per rotation at 60fps.<br> Note that if [property:Boolean autoRotate] is enabled, you must call [page:.update]
+      () in your animation loop.
+    </div>
+
+    <h3>
+      [property:Float dampingFactor]</h3>
+    <div>
+      The damping inertia used if [property:Boolean enableDamping] is set to true.<br> Note that for this to work, you must
+      call [page:.update] () in your animation loop.
+    </div>
+
+    <h3>[property:HTMLDOMElement domElement]</h3>
+    <div>
+      The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will
+      not set up new event listeners. Default is the whole document.
+    </div>
+
+    <h3>[property:Boolean enabled]</h3>
+    <div>
+      Whether or not the controls are enabled.
+    </div>
+
+    <h3>[property:Boolean enableDamping]</h3>
+    <div>
+      Set to true to enable damping (inertia), which can be used to give a sense of weight to the controls. Default is false.<br>          Note that if this is enabled, you must call [page:.update] () in your animation loop.
+    </div>
+
+    <h3>[property:Boolean enableKeys]</h3>
+    <div>
+      Enable or disable the use of keyboard controls.
+    </div>
+
+    <h3>[property:Boolean enablePan]</h3>
+    <div>
+      Enable or disable camera panning. Default is true.
+    </div>
+
+    <h3>[property:Boolean enableRotate]</h3>
+    <div>
+      Enable or disable horizontal and vertical rotation of the camera. Default is true.<br>
+      Note that it is possible to disable a single axis by setting the min and max of the
+      [page:.minPolarAngle polar angle] or [page:.minAzimuthAngle azimuth angle] to the same value,
+      which will cause the vertical or horizontal rotation to be fixed at that value.
+    </div>
+
+    <h3>[property:Boolean enableZoom]</h3>
+    <div>
+      Enable or disable zooming (dollying) of the camera.
+    </div>
+
+    <h3>[property:Float keyPanSpeed]</h3>
+    <div>
+      How fast to pan the camera when the keyboard is used. Default is 7.0 pixels per keypress.
+    </div>
+
+    <h3>[property:Object keys]</h3>
+    <div>
+      This object contains references to the keycodes for controlling camera panning. Default is the 4 arrow keys.
+      <code>
+controls.keys = {
+  LEFT: 37, //left arrow
+  UP: 38, // up arrow
+  RIGHT: 39, // right arrow
+  BOTTOM: 40 // down arrow
+}
+       </code> See [link:https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode this page] for a full
+      list of keycodes.
+    </div>
+
+    <h3>[property:Float maxAzimuthAngle]</h3>
+    <div>
+      How far you can orbit horizontally, upper limit. Range is - Math.PI to Math.PI ( or Infinity for no limit ) and default is
+      Infinity;
+    </div>
+
+    <h3>[property:Float maxDistance]</h3>
+    <div>
+      How far you can dolly out ( [page:PerspectiveCamera] only ). Default is Infinity.
+    </div>
+
+    <h3>[property:Float maxPolarAngle]</h3>
+    <div>
+      How far you can orbit vertically, upper limit. Range is 0 to Math.PI radians, and default is Math.PI.
+    </div>
+
+    <h3>[property:Float maxZoom]</h3>
+    <div>
+      How far you can zoom out ( [page:OrthographicCamera] only ). Default is Infinity.
+    </div>
+
+    <h3>[property:Float minAzimuthAngle]</h3>
+    <div>
+      How far you can orbit horizontally, lower limit. Range is - Math.PI to Math.PI ( or - Infinity for no limit ) and default
+      is - Infinity;
+    </div>
+
+    <h3>[property:Float minDistance]</h3>
+    <div>
+       How far you can dolly in ( [page:PerspectiveCamera] only ). Default is 0.
+    </div>
+
+    <h3>[property:Float minPolarAngle]</h3>
+    <div>
+      How far you can orbit vertically, lower limit. Range is 0 to Math.PI radians, and default is 0.
+    </div>
+
+    <h3>[property:Float minZoom]</h3>
+    <div>
+      How far you can zoom in ( [page:OrthographicCamera] only ). Default is 0.
+    </div>
+
+    <h3>
+      [property:Object mouseButtons]</h3>
+    <div>
+      This object contains references to the mouse buttons used for the controls.
+      <code>
+controls.mouseButtons = {
+  ORBIT: THREE.MOUSE.LEFT,
+  ZOOM: THREE.MOUSE.MIDDLE,
+  PAN: THREE.MOUSE.RIGHT
+}
+      </code>
+    </div>
+
+    <h3>[property:Camera object]</h3>
+    <div>
+      The camera ( or other object ) that is being controlled.
+    </div>
+
+    <h3>[property:Vector3 position0]</h3>
+    <div>
+      Used internally by the [method:saveState] and [method:reset] methods.
+    </div>
+
+    <h3>[property:Float rotateSpeed]</h3>
+    <div>
+      Speed of rotation. Default is 1.
+    </div>
+
+    <h3>[property:Vector3 target0]</h3>
+    <div>
+      Used internally by the [method:saveState] and [method:reset] methods.
+    </div>
+
+    <h3>[property:Vector3 target]</h3>
+    <div>
+      The focus point of the controls, the [page:.object] orbits around this. It can be updated manually at any point to change
+      the focus of the controls.
+    </div>
+
+    <h3>[property:Float zoom0]</h3>
+    <div>
+      Used internally by the [method:saveState] and [method:reset] methods.
+    </div>
+
+    <h3>[property:Float zoomSpeed]</h3>
+    <div>
+      Speed of zooming / dollying. Default is 1.
+    </div>
+
+
+
+		<h2>Methods</h2>
+
+    <h3>[method:null dispose] ()</h3>
+    <div>
+      Remove all the event listeners.
+    </div>
+
+    <h3>[method:radians getAzimuthalAngle] ()</h3>
+    <div>
+      Get the current horizontal rotation, in radians.
+    </div>
+
+		<h3>[method:radians getPolarAngle] ()</h3>
+		<div>
+      Get the current vertical rotation, in radians.
+    </div>
+
+    <h3>[method:null reset] ()</h3>
+    <div>
+      Reset the controls to their state from either the last time the [page:.saveState] was called, or the initial state.
+    </div>
+
+    <h3>[method:null saveState] ()</h3>
+    <div>
+      Save the current state of the controls. This can later be recovered with [page:.reset].
+    </div>
+
+    <h3>[method:false update] ()</h3>
+    <div>
+      Update the controls. Must be called after any manual changes to the camera's transform,
+      or in the update loop if [page:.autoRotate] or [page:.enableDamping] are set.
+    </div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/[path].js examples/js/[path].js]
+	</body>
+</html>

+ 91 - 0
docs/examples/exporters/GLTFExporter.html

@@ -0,0 +1,91 @@
+<!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>
+
+		<div class="desc">
+		An exporter for *glTF* 2.0.
+		<br /><br />
+		<a href="https://www.khronos.org/gltf">glTF</a> (GL Transmission Format) is an
+		<a href="https://github.com/KhronosGroup/glTF/tree/master/specification/2.0">open format specification</a>
+		for efficient delivery and loading of 3D content. Assets may be provided either in JSON (.gltf)
+		or binary (.glb) format. External files store textures (.jpg, .png, ...) and additional binary
+		data (.bin). A glTF asset may deliver one or more scenes, including meshes, materials,
+		textures, skins, skeletons, morph targets, animations, lights, and/or cameras.
+		</div>
+
+		<h2>Example</h2>
+
+		<code>
+		// Instantiate a exporter
+		var exporter = new THREE.GLTFExporter( defaultOptions );
+
+		// Parse the input and generate the glTF output
+		exporter.parse( scene, function ( gltf ) {
+			console.log( gltf );
+			downloadJSON( gltf );
+		}, options );
+		</code>
+
+		[example:misc_exporter_gltf]
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( )</h3>
+		<div>
+		</div>
+		<div>
+		Creates a new [name].
+		</div>
+
+		<h2>Methods</h2>
+
+		<h3>[method:null parse]( [page:Object input], [page:Function onCompleted], [page:Object options] )</h3>
+		<div>
+		[page:Object input] — Scenes or objects to export. Valid options:<br />
+		<ul>
+			<li>
+				Export scenes
+				<code>
+					exporter.parse( scene1, ...)
+exporter.parse( [ scene1, scene2 ], ...)
+				</code>
+			</li>
+			<li>
+			Export objects (It will create a new Scene to hold all the objects)
+			<code>
+				exporter.parse( object1, ...)
+exporter.parse( [ object1, object2 ], ...)
+			</code>
+			</li>
+			<li>
+			Mix scenes and objects (It will export the scenes as usual but it will create a new scene to hold all the single objects).
+			<code>
+exporter.parse( [ scene1, object1, object2, scene2 ], ...)
+			</code>
+		</ul>
+
+		[page:Function onCompleted] — Will be called when the export completes. The argument will be the generated glTF JSON.<br />
+		[page:Options options] - Export options<br />
+		<ul>
+			<li>trs - bool. Export position, rotation and scale instead of matrix per node. Default is false</li>
+			<li>onlyVisible - bool. Export only visible objects. Default is true.</li>
+			<li>truncateDrawRange - bool. Export just the attributes within the drawRange, if defined, instead of exporting the whole array. Default is true.</li>
+		</ul>
+		</div>
+		<div>
+		Generates a glTF output (JSON) with from the input (Scene or Objects)
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/exporters/GLTFExporter.js examples/js/exporters/GLTFExporter.js]
+	</body>
+</html>

+ 9 - 1
docs/list.js

@@ -333,6 +333,10 @@ var list = {
 
 	"Examples": {
 
+		"Controls": {
+			"OrbitControls": "examples/controls/OrbitControls"
+		},
+
 		"Geometries": {
 			"ConvexBufferGeometry": "examples/geometries/ConvexBufferGeometry",
 			"ConvexGeometry": "examples/geometries/ConvexGeometry",
@@ -353,6 +357,10 @@ var list = {
 			"TGALoader": "examples/loaders/TGALoader"
 		},
 
+		"Exporters": {
+			"GLTFExporter": "examples/exporters/GLTFExporter"
+		},
+
 		"Plugins": {
 			"CombinedCamera": "examples/cameras/CombinedCamera",
 			"LookupTable": "examples/Lut",
@@ -392,4 +400,4 @@ var list = {
 
 	}
 
-}
+};

+ 2 - 2
docs/manual/buildTools/Testing-with-NPM.html

@@ -106,7 +106,7 @@ $ npm install mocha --save-dev
 				<li>
 					Rerun the test with
 					<code>
-						$ npm test.
+						$ npm test
 					</code>
 
 					This should now succeed, reporting 0 passing (1ms)
@@ -144,7 +144,7 @@ $ npm install three --save-dev
 				<li>
 					Mocha will look for tests in test/, so let's
 					<code>
-					$ mkdir test.
+					$ mkdir test
 					</code>
 				</li>
 

+ 7 - 3
docs/manual/introduction/Creating-a-scene.html

@@ -40,7 +40,7 @@
 
 		<h2>Creating the scene</h2>
 
-		<div>To actually be able to display anything with three.js, we need three things: A scene, a camera, and a renderer so we can render the scene with the camera.</div>
+		<div>To actually be able to display anything with three.js, we need three things: scene, camera and renderer, so that we can render the scene with camera.</div>
 
 		<code>
 		var scene = new THREE.Scene();
@@ -51,7 +51,11 @@
 		document.body.appendChild( renderer.domElement );
 		</code>
 
-		<div>Let's take a moment to explain what's going on here. We have now set up the scene, our camera and the renderer. There are a few different cameras in three.js. For now, let's use a PerspectiveCamera. The first attribute is the <strong>field of view</strong>.</div>
+		<div>Let's take a moment to explain what's going on here. We have now set up the scene, our camera and the renderer.</div>
+
+		<div>There are a few different cameras in three.js. For now, let's use a <strong>PerspectiveCamera</strong>.</div>
+
+		<div>The first attribute is the <strong>field of view</strong>. FOV is the extent of the scene that is seen on the display at any given moment. The value is in degrees.</div>
 
 		<div>The second one is the <strong>aspect ratio</strong>. You almost always want to use the width of the element divided by the height, or you'll get the same result as when you play old movies on a widescreen TV - the image looks squished.</div>
 
@@ -96,7 +100,7 @@
 		animate();
 		</code>
 
-		<div>This will create a loop that causes the renderer to draw the scene 60 times per second. If you're new to writing games in the browser, you might say "why don't we just  create a <strong>setInterval</strong>? The thing is - we could, but <strong>requestAnimationFrame</strong> has a number of advantages. Perhaps the most important one is that it pauses when the user navigates to another browser tab, hence not wasting their precious processing power and battery life.</div>
+		<div>This will create a loop that causes the renderer to draw the scene 60 times per second. If you're new to writing games in the browser, you might say <em>"why don't we just create a setInterval ?"</em> The thing is - we could, but <strong>requestAnimationFrame</strong> has a number of advantages. Perhaps the most important one is that it pauses when the user navigates to another browser tab, hence not wasting their precious processing power and battery life.</div>
 
 		<h2>Animating the cube</h2>
 

+ 2 - 2
docs/manual/introduction/Import-via-modules.html

@@ -19,7 +19,7 @@
 			</ul>
 		</div>
 
-		<div>Using a dependency manager like npm avoids these caveats by allowing you to simply download and import your desired version of the libarary onto your machine.</div>
+		<div>Using a dependency manager like npm avoids these caveats by allowing you to simply download and import your desired version of the library onto your machine.</div>
 
 		<h2>Installation via npm</h2>
 
@@ -65,7 +65,7 @@
 		<h2>Caveats</h2>
 
 		<div>
-			Currently it's not possible to import the files within the "examples/js" directroy in this way.
+			Currently it's not possible to import the files within the "examples/js" directory in this way.
 			This is due to some of the files relying on global namespace pollution of THREE. For more information see <a href="https://github.com/mrdoob/three.js/issues/9562" target="_blank">Transform `examples/js` to support modules #9562</a>.
 		</div>
 	</body>

+ 1 - 2
editor/js/Sidebar.Material.js

@@ -510,7 +510,6 @@ Sidebar.Material = function ( editor ) {
 		var object = currentObject;
 
 		var geometry = object.geometry;
-		var material = object.material;
 
 		var previousSelectedSlot = currentMaterialSlot;
 
@@ -518,7 +517,7 @@ Sidebar.Material = function ( editor ) {
 
 		if ( currentMaterialSlot !== previousSelectedSlot ) refreshUI( true );
 
-		material = editor.getObjectMaterial( currentObject, currentMaterialSlot )
+		var material = editor.getObjectMaterial( currentObject, currentMaterialSlot )
 
 		var textureWarning = false;
 		var objectHasUvs = false;

+ 5 - 4
examples/files.js

@@ -104,8 +104,9 @@ var files = {
 		"webgl_loader_obj",
 		"webgl_loader_obj_mtl",
 		"webgl_loader_obj2",
-		"webgl_loader_obj2_ww",
-		"webgl_loader_obj2_ww_parallels",
+		"webgl_loader_obj2_meshspray",
+		"webgl_loader_obj2_options",
+		"webgl_loader_obj2_run_director",
 		"webgl_loader_nrrd",
 		"webgl_loader_pcd",
 		"webgl_loader_pdb",
@@ -292,8 +293,8 @@ var files = {
 	],
 	*/
 	"webaudio": [
-		"misc_sound",
-		"misc_sound_visualizer"
+		"webaudio_sandbox",
+		"webaudio_visualizer"
 	],
 	"webvr": [
 		"webvr_cubes",

+ 21 - 8
examples/js/Mirror.js

@@ -21,6 +21,10 @@ THREE.Mirror = function ( width, height, options ) {
 	var clipBias = options.clipBias !== undefined ? options.clipBias : 0.0;
 	var mirrorColor = options.color !== undefined ? new THREE.Color( options.color ) : new THREE.Color( 0x7F7F7F );
 
+	var recursion = options.recursion !== undefined ? options.recursion : 0;
+
+	//
+
 	var mirrorPlane = new THREE.Plane();
 	var normal = new THREE.Vector3();
 	var mirrorWorldPosition = new THREE.Vector3();
@@ -109,9 +113,15 @@ THREE.Mirror = function ( width, height, options ) {
 
 	scope.material = material;
 
-	function updateTextureMatrix( camera ) {
-
-		scope.updateMatrixWorld();
+	scope.onBeforeRender = function ( renderer, scene, camera ) {
+
+		if ( 'recursion' in camera.userData ) {
+
+			if ( camera.userData.recursion === recursion ) return;
+
+			camera.userData.recursion ++;
+
+		}
 
 		mirrorWorldPosition.setFromMatrixPosition( scope.matrixWorld );
 		cameraWorldPosition.setFromMatrixPosition( camera.matrixWorld );
@@ -122,6 +132,11 @@ THREE.Mirror = function ( width, height, options ) {
 		normal.applyMatrix4( rotationMatrix );
 
 		view.subVectors( mirrorWorldPosition, cameraWorldPosition );
+
+		// Avoid rendering when mirror is facing away
+
+		if ( view.dot( normal ) > 0 ) return;
+
 		view.reflect( normal ).negate();
 		view.add( mirrorWorldPosition );
 
@@ -148,6 +163,8 @@ THREE.Mirror = function ( width, height, options ) {
 		mirrorCamera.updateMatrixWorld();
 		mirrorCamera.updateProjectionMatrix();
 
+		mirrorCamera.userData.recursion = 0;
+
 		// Update the texture matrix
 		textureMatrix.set(
 			0.5, 0.0, 0.0, 0.5,
@@ -181,11 +198,7 @@ THREE.Mirror = function ( width, height, options ) {
 		projectionMatrix.elements[ 10 ] = clipPlane.z + 1.0 - clipBias;
 		projectionMatrix.elements[ 14 ] = clipPlane.w;
 
-	}
-
-	scope.onBeforeRender = function ( renderer, scene, camera ) {
-
-		updateTextureMatrix( camera );
+		// Render
 
 		scope.visible = false;
 

+ 1 - 1
examples/js/exporters/GLTFExporter.js

@@ -997,7 +997,7 @@ THREE.GLTFExporter.prototype = {
 		if ( outputJSON.buffers && outputJSON.buffers.length > 0 ) {
 
 			outputJSON.buffers[ 0 ].byteLength = blob.size;
-			objectURL = URL.createObjectURL( blob );
+			var objectURL = URL.createObjectURL( blob );
 
 			var reader = new window.FileReader();
 			reader.readAsDataURL( blob );

+ 102 - 56
examples/js/libs/msgpack-js.js

@@ -1,3 +1,5 @@
+/* jshint browser: true */
+/* global define, module */
 ( // Module boilerplate to support browser globals and browserify and AMD.
   typeof define === "function" ? function (m) { define("msgpack-js", m); } :
   typeof exports === "object" ? function (m) { module.exports = m(); } :
@@ -54,7 +56,7 @@ function utf8Write(view, offset, string) {
       continue;
     }
 
-    // Three bytes of UTF-8.  
+    // Three bytes of UTF-8.
     if (codePoint < 0x10000) {
       view.setUint8(offset++, codePoint >>> 12 & 0x0f | 0xe0);
       view.setUint8(offset++, codePoint >>> 6  & 0x3f | 0x80);
@@ -87,7 +89,7 @@ function utf8Read(view, offset, length) {
     // Two byte character
     if ((byte & 0xe0) === 0xc0) {
       string += String.fromCharCode(
-        ((byte & 0x0f) << 6) | 
+        ((byte & 0x1f) << 6) |
         (view.getUint8(++i) & 0x3f)
       );
       continue;
@@ -143,7 +145,7 @@ function utf8ByteCount(string) {
 }
 
 exports.encode = function (value) {
-  var buffer = new ArrayBuffer(sizeof(value));
+  var buffer = new ArrayBuffer(encodedSize(value));
   var view = new DataView(buffer);
   encode(value, view, 0);
   return buffer;
@@ -151,14 +153,8 @@ exports.encode = function (value) {
 
 exports.decode = decode;
 
-// http://wiki.msgpack.org/display/MSGPACK/Format+specification
-// I've extended the protocol to have two new types that were previously reserved.
-//   buffer 16  11011000  0xd8
-//   buffer 32  11011001  0xd9
-// These work just like raw16 and raw32 except they are node buffers instead of strings.
-//
-// Also I've added a type for `undefined`
-//   undefined  11000100  0xc4
+// https://github.com/msgpack/msgpack/blob/master/spec.md
+// we reserve extension type 0x00 to encode javascript 'undefined'
 
 function Decoder(view, offset) {
   this.offset = offset || 0;
@@ -172,13 +168,13 @@ Decoder.prototype.map = function (length) {
   }
   return value;
 };
-Decoder.prototype.buf = function (length) {
+Decoder.prototype.bin = function (length) {
   var value = new ArrayBuffer(length);
   (new Uint8Array(value)).set(new Uint8Array(this.view.buffer, this.offset, length), 0);
   this.offset += length;
   return value;
 };
-Decoder.prototype.raw = function (length) {
+Decoder.prototype.str = function (length) {
   var value = utf8Read(this.view, this.offset, length);
   this.offset += length;
   return value;
@@ -193,11 +189,11 @@ Decoder.prototype.array = function (length) {
 Decoder.prototype.parse = function () {
   var type = this.view.getUint8(this.offset);
   var value, length;
-  // FixRaw
+  // FixStr
   if ((type & 0xe0) === 0xa0) {
     length = type & 0x1f;
     this.offset++;
-    return this.raw(length);
+    return this.str(length);
   }
   // FixMap
   if ((type & 0xf0) === 0x80) {
@@ -222,17 +218,42 @@ Decoder.prototype.parse = function () {
     this.offset++;
     return value;
   }
+  // Undefined as FixExt1
+  if (type === 0xd4 && this.view.getUint8(this.offset + 1) === 0x00) {
+    this.offset += 3;
+    return undefined;
+  }
   switch (type) {
-  // raw 16
+  // str 8
+  case 0xd9:
+    length = this.view.getUint8(this.offset + 1);
+    this.offset += 2;
+    return this.str(length);
+  // str 16
   case 0xda:
     length = this.view.getUint16(this.offset + 1);
     this.offset += 3;
-    return this.raw(length);
-  // raw 32
+    return this.str(length);
+  // str 32
   case 0xdb:
     length = this.view.getUint32(this.offset + 1);
     this.offset += 5;
-    return this.raw(length);
+    return this.str(length);
+  // bin 8
+  case 0xc4:
+    length = this.view.getUint8(this.offset + 1);
+    this.offset += 2;
+    return this.bin(length);
+  // bin 16
+  case 0xc5:
+    length = this.view.getUint16(this.offset + 1);
+    this.offset += 3;
+    return this.bin(length);
+  // bin 32
+  case 0xc6:
+    length = this.view.getUint32(this.offset + 1);
+    this.offset += 5;
+    return this.bin(length);
   // nil
   case 0xc0:
     this.offset++;
@@ -245,10 +266,6 @@ Decoder.prototype.parse = function () {
   case 0xc3:
     this.offset++;
     return true;
-  // undefined
-  case 0xc4:
-    this.offset++;
-    return undefined;
   // uint8
   case 0xcc:
     value = this.view.getUint8(this.offset + 1);
@@ -264,6 +281,13 @@ Decoder.prototype.parse = function () {
     value = this.view.getUint32(this.offset + 1);
     this.offset += 5;
     return value;
+  // uint 64
+  case 0xcf:
+    var high = this.view.getUint32(this.offset + 1);
+    var low = this.view.getUint32(this.offset + 5);
+    value = high*0x100000000 + low;
+    this.offset += 9;
+    return value;
   // int 8
   case 0xd0:
     value = this.view.getInt8(this.offset + 1);
@@ -279,6 +303,13 @@ Decoder.prototype.parse = function () {
     value = this.view.getInt32(this.offset + 1);
     this.offset += 5;
     return value;
+  // int 64
+  case 0xd3:
+    var high = this.view.getInt32(this.offset + 1);
+    var low = this.view.getUint32(this.offset + 5);
+    value = high*0x100000000 + low;
+    this.offset += 9;
+    return value;
   // map 16
   case 0xde:
     length = this.view.getUint16(this.offset + 1);
@@ -299,16 +330,6 @@ Decoder.prototype.parse = function () {
     length = this.view.getUint32(this.offset + 1);
     this.offset += 5;
     return this.array(length);
-  // buffer 16
-  case 0xd8:
-    length = this.view.getUint16(this.offset + 1);
-    this.offset += 3;
-    return this.buf(length);
-  // buffer 32
-  case 0xd9:
-    length = this.view.getUint32(this.offset + 1);
-    this.offset += 5;
-    return this.buf(length);
   // float
   case 0xca:
     value = this.view.getFloat32(this.offset + 1);
@@ -336,20 +357,27 @@ function encode(value, view, offset) {
   // Strings Bytes
   if (type === "string") {
     var length = utf8ByteCount(value);
-    // fix raw
+    // fix str
     if (length < 0x20) {
       view.setUint8(offset, length | 0xa0);
       utf8Write(view, offset + 1, value);
       return 1 + length;
     }
-    // raw 16
+    // str 8
+    if (length < 0x100) {
+      view.setUint8(offset, 0xd9);
+      view.setUint8(offset + 1, length);
+      utf8Write(view, offset + 2, value);
+      return 2 + length;
+    }
+    // str 16
     if (length < 0x10000) {
       view.setUint8(offset, 0xda);
       view.setUint16(offset + 1, length);
       utf8Write(view, offset + 3, value);
       return 3 + length;
     }
-    // raw 32
+    // str 32
     if (length < 0x100000000) {
       view.setUint8(offset, 0xdb);
       view.setUint32(offset + 1, length);
@@ -360,22 +388,29 @@ function encode(value, view, offset) {
 
   if (value instanceof ArrayBuffer) {
     var length = value.byteLength;
-    // buffer 16
+    // bin 8
+    if (length < 0x100) {
+      view.setUint8(offset, 0xc4);
+      view.setUint8(offset + 1, length);
+      (new Uint8Array(view.buffer)).set(new Uint8Array(value), offset + 2);
+      return 2 + length;
+    }
+    // bin 16
     if (length < 0x10000) {
-      view.setUint8(offset, 0xd8);
+      view.setUint8(offset, 0xc5);
       view.setUint16(offset + 1, length);
       (new Uint8Array(view.buffer)).set(new Uint8Array(value), offset + 3);
       return 3 + length;
     }
-    // buffer 32
+    // bin 32
     if (length < 0x100000000) {
-      view.setUint8(offset, 0xd9);
+      view.setUint8(offset, 0xc6);
       view.setUint32(offset + 1, length);
       (new Uint8Array(view.buffer)).set(new Uint8Array(value), offset + 5);
       return 5 + length;
     }
   }
-  
+
   if (type === "number") {
     // Floating Point
     if ((value << 0) !== value) {
@@ -436,13 +471,15 @@ function encode(value, view, offset) {
     }
     throw new Error("Number too small -0x" + (-value).toString(16).substr(1));
   }
-  
+
   // undefined
   if (type === "undefined") {
-    view.setUint8(offset, 0xc4);
-    return 1;
+    view.setUint8(offset, 0xd4);  // fixext 1
+    view.setUint8(offset + 1, 0); // type (undefined)
+    view.setUint8(offset + 2, 0); // data (ignored)
+    return 3;
   }
-  
+
   // null
   if (value === null) {
     view.setUint8(offset, 0xc0);
@@ -454,7 +491,7 @@ function encode(value, view, offset) {
     view.setUint8(offset, value ? 0xc3 : 0xc2);
     return 1;
   }
-  
+
   // Container Types
   if (type === "object") {
     var length, size = 0;
@@ -496,13 +533,13 @@ function encode(value, view, offset) {
         size += encode(value[key], view, offset + size);
       }
     }
-    
+
     return size;
   }
   throw new Error("Unknown type " + type);
 }
 
-function sizeof(value) {
+function encodedSize(value) {
   var type = typeof value;
 
   // Raw Bytes
@@ -511,6 +548,9 @@ function sizeof(value) {
     if (length < 0x20) {
       return 1 + length;
     }
+    if (length < 0x100) {
+      return 2 + length;
+    }
     if (length < 0x10000) {
       return 3 + length;
     }
@@ -518,9 +558,12 @@ function sizeof(value) {
       return 5 + length;
     }
   }
-  
+
   if (value instanceof ArrayBuffer) {
     var length = value.byteLength;
+    if (length < 0x100) {
+      return 2 + length;
+    }
     if (length < 0x10000) {
       return 3 + length;
     }
@@ -528,7 +571,7 @@ function sizeof(value) {
       return 5 + length;
     }
   }
-  
+
   if (type === "number") {
     // Floating Point
     // double
@@ -560,17 +603,20 @@ function sizeof(value) {
     if (value >= -0x8000000000000000) return 9;
     throw new Error("Number too small -0x" + value.toString(16).substr(1));
   }
-  
-  // Boolean, null, undefined
-  if (type === "boolean" || type === "undefined" || value === null) return 1;
-  
+
+  // undefined
+  if (type === "undefined") return 3;
+
+  // Boolean, null
+  if (type === "boolean" || value === null) return 1;
+
   // Container Types
   if (type === "object") {
     var length, size = 0;
     if (Array.isArray(value)) {
       length = value.length;
       for (var i = 0; i < length; i++) {
-        size += sizeof(value[i]);
+        size += encodedSize(value[i]);
       }
     }
     else {
@@ -578,7 +624,7 @@ function sizeof(value) {
       length = keys.length;
       for (var i = 0; i < length; i++) {
         var key = keys[i];
-        size += sizeof(key) + sizeof(value[key]);
+        size += encodedSize(key) + encodedSize(value[key]);
       }
     }
     if (length < 0x10) {

+ 34 - 30
examples/js/loaders/3MFLoader.js

@@ -18,7 +18,7 @@ THREE.ThreeMFLoader.prototype = {
 		var scope = this;
 		var loader = new THREE.FileLoader( scope.manager );
 		loader.setResponseType( 'arraybuffer' );
-		loader.load( url, function( buffer ) {
+		loader.load( url, function ( buffer ) {
 
 			onLoad( scope.parse( buffer ) );
 
@@ -49,7 +49,7 @@ THREE.ThreeMFLoader.prototype = {
 
 			try {
 
-				zip = new JSZip( data );
+				zip = new JSZip( data ); // eslint-disable-line no-undef
 
 			} catch ( e ) {
 
@@ -68,19 +68,19 @@ THREE.ThreeMFLoader.prototype = {
 
 					relsName = file;
 
-				} else if ( file.match(/^3D\/.*\.model$/) ) {
+				} else if ( file.match( /^3D\/.*\.model$/ ) ) {
 
 					modelPartNames.push( file );
 
-				} else if ( file.match(/^3D\/Metadata\/.*\.xml$/) ) {
+				} else if ( file.match( /^3D\/Metadata\/.*\.xml$/ ) ) {
 
 					printTicketPartNames.push( file );
 
-				} else if ( file.match(/^3D\/Textures\/.*/) ) {
+				} else if ( file.match( /^3D\/Textures\/.*/ ) ) {
 
 					texturesPartNames.push( file );
 
-				} else if ( file.match(/^3D\/Other\/.*/) ) {
+				} else if ( file.match( /^3D\/Other\/.*/ ) ) {
 
 					otherPartNames.push( file );
 
@@ -99,7 +99,7 @@ THREE.ThreeMFLoader.prototype = {
 			var relsFileText = new TextDecoder( 'utf-8' ).decode( relsView );
 			rels = parseRelsXml( relsFileText );
 
-			for ( var i = 0; i < modelPartNames.length; i++ ) {
+			for ( var i = 0; i < modelPartNames.length; i ++ ) {
 
 				var modelPart = modelPartNames[ i ];
 				var view = new DataView( zip.file( modelPart ).asArrayBuffer() );
@@ -116,7 +116,7 @@ THREE.ThreeMFLoader.prototype = {
 				var modelNode = xmlData.querySelector( 'model' );
 				var extensions = {};
 
-				for ( var i = 0; i < modelNode.attributes.length; i++ ) {
+				for ( var i = 0; i < modelNode.attributes.length; i ++ ) {
 
 					var attr = modelNode.attributes[ i ];
 					if ( attr.name.match( /^xmlns:(.+)$/ ) ) {
@@ -140,7 +140,7 @@ THREE.ThreeMFLoader.prototype = {
 
 			}
 
-			for ( var i = 0; i < texturesPartNames.length; i++ ) {
+			for ( var i = 0; i < texturesPartNames.length; i ++ ) {
 
 				var texturesPartName = texturesPartNames[ i ];
 				texturesParts[ texturesPartName ] = zip.file( texturesPartName ).asBinary();
@@ -154,6 +154,7 @@ THREE.ThreeMFLoader.prototype = {
 				texture: texturesParts,
 				other: otherParts
 			};
+
 		}
 
 		function parseRelsXml( relsFileText ) {
@@ -176,10 +177,10 @@ THREE.ThreeMFLoader.prototype = {
 
 			var metadataData = {};
 
-			for ( var i = 0; i < metadataNodes.length; i++ ) {
+			for ( var i = 0; i < metadataNodes.length; i ++ ) {
 
 				var metadataNode = metadataNodes[ i ];
-				var name = metadataNode.getAttribute('name');
+				var name = metadataNode.getAttribute( 'name' );
 				var validNames = [
 					'Title',
 					'Designer',
@@ -213,7 +214,7 @@ THREE.ThreeMFLoader.prototype = {
 			var vertices = [];
 			var vertexNodes = meshNode.querySelectorAll( 'vertices vertex' );
 
-			for ( var i = 0; i < vertexNodes.length; i++ ) {
+			for ( var i = 0; i < vertexNodes.length; i ++ ) {
 
 				var vertexNode = vertexNodes[ i ];
 				var x = vertexNode.getAttribute( 'x' );
@@ -226,7 +227,7 @@ THREE.ThreeMFLoader.prototype = {
 
 			meshData[ 'vertices' ] = new Float32Array( vertices.length );
 
-			for ( var i = 0; i < vertices.length; i++ ) {
+			for ( var i = 0; i < vertices.length; i ++ ) {
 
 				meshData[ 'vertices' ][ i ] = vertices[ i ];
 
@@ -236,7 +237,7 @@ THREE.ThreeMFLoader.prototype = {
 			var triangles = [];
 			var triangleNodes = meshNode.querySelectorAll( 'triangles triangle' );
 
-			for ( var i = 0; i < triangleNodes.length; i++ ) {
+			for ( var i = 0; i < triangleNodes.length; i ++ ) {
 
 				var triangleNode = triangleNodes[ i ];
 				var v1 = triangleNode.getAttribute( 'v1' );
@@ -280,12 +281,13 @@ THREE.ThreeMFLoader.prototype = {
 					triangleProperties.push( triangleProperty );
 
 				}
+
 			}
 
 			meshData[ 'triangleProperties' ] = triangleProperties;
 			meshData[ 'triangles' ] = new Uint32Array( triangles.length );
 
-			for ( var i = 0; i < triangles.length; i++ ) {
+			for ( var i = 0; i < triangles.length; i ++ ) {
 
 				meshData[ 'triangles' ][ i ] = triangles[ i ];
 
@@ -387,7 +389,7 @@ THREE.ThreeMFLoader.prototype = {
 			resourcesData[ 'object' ] = {};
 			var objectNodes = resourcesNode.querySelectorAll( 'object' );
 
-			for ( var i = 0; i < objectNodes.length; i++ ) {
+			for ( var i = 0; i < objectNodes.length; i ++ ) {
 
 				var objectNode = objectNodes[ i ];
 				var objectData = parseObjectNode( objectNode );
@@ -404,10 +406,10 @@ THREE.ThreeMFLoader.prototype = {
 			var buildData = [];
 			var itemNodes = buildNode.querySelectorAll( 'item' );
 
-			for ( var i = 0; i < itemNodes.length; i++ ) {
+			for ( var i = 0; i < itemNodes.length; i ++ ) {
 
 				var itemNode = itemNodes[ i ];
-				var buildItem =  {
+				var buildItem = {
 					objectid: itemNode.getAttribute( 'objectid' )
 				};
 				var transform = itemNode.getAttribute( 'transform' );
@@ -415,15 +417,17 @@ THREE.ThreeMFLoader.prototype = {
 				if ( transform ) {
 
 					var t = [];
-					transform.split( ' ' ).forEach( function( s ) {
+					transform.split( ' ' ).forEach( function ( s ) {
+
 						t.push( parseFloat( s ) );
+
 					} );
 					var mat4 = new THREE.Matrix4();
 					buildItem[ 'transform' ] = mat4.set(
-						t[ 0 ], t[  3 ], t[  6 ], t[  9 ],
-						t[ 1 ], t[  4 ], t[  7 ], t[ 10 ],
-						t[ 2 ], t[  5 ], t[  8 ], t[ 11 ],
-						   0.0,     0.0,     0.0,     1.0
+						t[ 0 ], t[ 3 ], t[ 6 ], t[ 9 ],
+						t[ 1 ], t[ 4 ], t[ 7 ], t[ 10 ],
+						t[ 2 ], t[ 5 ], t[ 8 ], t[ 11 ],
+						 0.0, 0.0, 0.0, 1.0
 					);
 
 				}
@@ -511,11 +515,11 @@ THREE.ThreeMFLoader.prototype = {
 			var availableExtensions = [];
 			var keys = Object.keys( extensions );
 
-			for ( var i = 0; i < keys.length; i++ ) {
+			for ( var i = 0; i < keys.length; i ++ ) {
 
 				var ns = keys[ i ];
 
-				for ( var j = 0; j < scope.availableExtensions.length; j++ ) {
+				for ( var j = 0; j < scope.availableExtensions.length; j ++ ) {
 
 					var extension = scope.availableExtensions[ j ];
 
@@ -529,7 +533,7 @@ THREE.ThreeMFLoader.prototype = {
 
 			}
 
-			for ( var i = 0; i < availableExtensions.length; i++ ) {
+			for ( var i = 0; i < availableExtensions.length; i ++ ) {
 
 				var extension = availableExtensions[ i ];
 				extension.apply( modelXml, extensions[ extension[ 'ns' ] ], meshData );
@@ -544,7 +548,7 @@ THREE.ThreeMFLoader.prototype = {
 			var meshes = {};
 			var modelsKeys = Object.keys( modelsData );
 
-			for ( var i = 0; i < modelsKeys.length; i++ ) {
+			for ( var i = 0; i < modelsKeys.length; i ++ ) {
 
 				var modelsKey = modelsKeys[ i ];
 				var modelData = modelsData[ modelsKey ];
@@ -553,7 +557,7 @@ THREE.ThreeMFLoader.prototype = {
 
 				var objectIds = Object.keys( modelData[ 'resources' ][ 'object' ] );
 
-				for ( var j = 0; j < objectIds.length; j++ ) {
+				for ( var j = 0; j < objectIds.length; j ++ ) {
 
 					var objectId = objectIds[ j ];
 					var objectData = modelData[ 'resources' ][ 'object' ][ objectId ];
@@ -574,7 +578,7 @@ THREE.ThreeMFLoader.prototype = {
 			var group = new THREE.Group();
 			var buildData = data3mf.model[ refs[ 'target' ].substring( 1 ) ][ 'build' ];
 
-			for ( var i = 0; i < buildData.length; i++ ) {
+			for ( var i = 0; i < buildData.length; i ++ ) {
 
 				var buildItem = buildData[ i ];
 				var mesh = meshes[ buildItem[ 'objectid' ] ];
@@ -600,7 +604,7 @@ THREE.ThreeMFLoader.prototype = {
 
 	},
 
-	addExtension: function( extension ) {
+	addExtension: function ( extension ) {
 
 		this.availableExtensions.push( extension );
 

+ 4 - 4
examples/js/loaders/AMFLoader.js

@@ -35,7 +35,7 @@ THREE.AMFLoader.prototype = {
 
 		var loader = new THREE.FileLoader( scope.manager );
 		loader.setResponseType( 'arraybuffer' );
-		loader.load( url, function( text ) {
+		loader.load( url, function ( text ) {
 
 			onLoad( scope.parse( text ) );
 
@@ -59,7 +59,7 @@ THREE.AMFLoader.prototype = {
 
 				try {
 
-					zip = new JSZip( data );
+					zip = new JSZip( data ); // eslint-disable-line no-undef
 
 				} catch ( e ) {
 
@@ -154,7 +154,7 @@ THREE.AMFLoader.prototype = {
 
 					if ( matChildEl.attributes.type.value === 'name' ) {
 
-						matname = matChildEl.textContent;
+						matName = matChildEl.textContent;
 
 					}
 
@@ -465,7 +465,7 @@ THREE.AMFLoader.prototype = {
 					newGeometry.setIndex( volume.triangles );
 					newGeometry.addAttribute( 'position', vertices.clone() );
 
-					if( normals ) {
+					if ( normals ) {
 
 						newGeometry.addAttribute( 'normal', normals.clone() );
 

+ 200 - 204
examples/js/loaders/AWDLoader.js

@@ -5,43 +5,43 @@
 
 ( function () {
 
-	var UNCOMPRESSED  = 0,
-			DEFLATE       = 1,
-			LZMA          = 2,
-
-			AWD_FIELD_INT8      = 1,
-			AWD_FIELD_INT16     = 2,
-			AWD_FIELD_INT32     = 3,
-			AWD_FIELD_UINT8     = 4,
-			AWD_FIELD_UINT16    = 5,
-			AWD_FIELD_UINT32    = 6,
-			AWD_FIELD_FLOAT32   = 7,
-			AWD_FIELD_FLOAT64   = 8,
-			AWD_FIELD_BOOL      = 21,
-			AWD_FIELD_COLOR     = 22,
-			AWD_FIELD_BADDR     = 23,
-			AWD_FIELD_STRING    = 31,
-			AWD_FIELD_BYTEARRAY = 32,
-			AWD_FIELD_VECTOR2x1 = 41,
-			AWD_FIELD_VECTOR3x1 = 42,
-			AWD_FIELD_VECTOR4x1 = 43,
-			AWD_FIELD_MTX3x2    = 44,
-			AWD_FIELD_MTX3x3    = 45,
-			AWD_FIELD_MTX4x3    = 46,
-			AWD_FIELD_MTX4x4    = 47,
-
-			BOOL       = 21,
-			COLOR      = 22,
-			BADDR      = 23,
-
-			INT8    = 1,
-			INT16   = 2,
-			INT32   = 3,
-			UINT8   = 4,
-			UINT16  = 5,
-			UINT32  = 6,
-			FLOAT32 = 7,
-			FLOAT64 = 8;
+	var UNCOMPRESSED = 0,
+		DEFLATE = 1,
+		LZMA = 2,
+
+		AWD_FIELD_INT8 = 1,
+		AWD_FIELD_INT16 = 2,
+		AWD_FIELD_INT32 = 3,
+		AWD_FIELD_UINT8 = 4,
+		AWD_FIELD_UINT16 = 5,
+		AWD_FIELD_UINT32 = 6,
+		AWD_FIELD_FLOAT32 = 7,
+		AWD_FIELD_FLOAT64 = 8,
+		AWD_FIELD_BOOL = 21,
+		AWD_FIELD_COLOR = 22,
+		AWD_FIELD_BADDR = 23,
+		AWD_FIELD_STRING = 31,
+		AWD_FIELD_BYTEARRAY = 32,
+		AWD_FIELD_VECTOR2x1 = 41,
+		AWD_FIELD_VECTOR3x1 = 42,
+		AWD_FIELD_VECTOR4x1 = 43,
+		AWD_FIELD_MTX3x2 = 44,
+		AWD_FIELD_MTX3x3 = 45,
+		AWD_FIELD_MTX4x3 = 46,
+		AWD_FIELD_MTX4x4 = 47,
+
+		BOOL = 21,
+		COLOR = 22,
+		BADDR = 23,
+
+		INT8 = 1,
+		INT16 = 2,
+		INT32 = 3,
+		UINT8 = 4,
+		UINT16 = 5,
+		UINT32 = 6,
+		FLOAT32 = 7,
+		FLOAT64 = 8;
 
 	var littleEndian = true;
 
@@ -55,17 +55,23 @@
 	function AWDProperties() {}
 
 	AWDProperties.prototype = {
-		set: function( key, value ) {
+		set: function ( key, value ) {
 
 			this[ key ] = value;
 
 		},
 
-		get: function( key, fallback ) {
+		get: function ( key, fallback ) {
+
+			if ( this.hasOwnProperty( key ) ) {
 
-			if ( this.hasOwnProperty( key ) )
 				return this[ key ];
-			else return fallback;
+
+			} else {
+
+				return fallback;
+
+			}
 
 		}
 	};
@@ -78,13 +84,13 @@
 
 		this.materialFactory = undefined;
 
-		this._url     = '';
+		this._url = '';
 		this._baseDir = '';
 
 		this._data = undefined;
 		this._ptr = 0;
 
-		this._version =  [];
+		this._version = [];
 		this._streaming = false;
 		this._optimized_for_accuracy = false;
 		this._compression = 0;
@@ -92,9 +98,9 @@
 
 		this._blocks = [ new Block() ];
 
-		this._accuracyMatrix  = false;
-		this._accuracyGeo     = false;
-		this._accuracyProps   = false;
+		this._accuracyMatrix = false;
+		this._accuracyGeo = false;
+		this._accuracyProps = false;
 
 	};
 
@@ -128,7 +134,7 @@
 
 			this._parseHeader( );
 
-			if ( this._compression != 0  ) {
+			if ( this._compression != 0 ) {
 
 				console.error( 'compressed AWD not supported' );
 
@@ -136,7 +142,7 @@
 
 			if ( ! this._streaming && this._bodylen != data.byteLength - this._ptr ) {
 
-				console.error( 'AWDLoader: body len does not match file length', this._bodylen,  blen - this._ptr );
+				console.error( 'AWDLoader: body len does not match file length', this._bodylen, blen - this._ptr );
 
 			}
 
@@ -150,62 +156,76 @@
 
 		},
 
-		parseNextBlock: function() {
+		parseNextBlock: function () {
 
 			var assetData,
-					ns, type, len, block,
-					blockId = this.readU32(),
-					ns      = this.readU8(),
-					type    = this.readU8(),
-					flags   = this.readU8(),
-					len     = this.readU32();
+				ns, type, len, block,
+				blockId = this.readU32(),
+				ns = this.readU8(),
+				type = this.readU8(),
+				flags = this.readU8(),
+				len = this.readU32();
 
 
 			switch ( type ) {
+
 				case 1:
 					assetData = this.parseMeshData( len );
 					break;
+
 				case 22:
 					assetData = this.parseContainer( len );
 					break;
+
 				case 23:
 					assetData = this.parseMeshInstance( len );
 					break;
+
 				case 81:
 					assetData = this.parseMaterial( len );
 					break;
+
 				case 82:
 					assetData = this.parseTexture( len );
 					break;
+
 				case 101:
 					assetData = this.parseSkeleton( len );
 					break;
 
-	//      case 111:
-	//        assetData = this.parseMeshPoseAnimation(len, true);
-	//        break;
+	    //  case 111:
+	    //    assetData = this.parseMeshPoseAnimation(len, true);
+	    //    break;
+
 				case 112:
 					assetData = this.parseMeshPoseAnimation( len, false );
 					break;
+
 				case 113:
 					assetData = this.parseVertexAnimationSet( len );
 					break;
+
 				case 102:
 					assetData = this.parseSkeletonPose( len );
 					break;
+
 				case 103:
 					assetData = this.parseSkeletonAnimation( len );
 					break;
+
 				case 122:
 					assetData = this.parseAnimatorSet( len );
 					break;
+
 				// case 121:
 				//  assetData = parseUVAnimation(len);
 				//  break;
+
 				default:
 					//debug('Ignoring block!',type, len);
 					this._ptr += len;
 					break;
+
 			}
 
 
@@ -220,10 +240,7 @@
 		_parseHeader: function () {
 
 			var version = this._version,
-					awdmagic =
-							( this.readU8() << 16 )
-					|   ( this.readU8() << 8 )
-					|     this.readU8();
+				awdmagic = ( this.readU8() << 16 ) | ( this.readU8() << 8 ) | this.readU8();
 
 			if ( awdmagic != 4282180 )
 				throw new Error( "AWDLoader - bad magic" );
@@ -237,17 +254,17 @@
 
 			if ( ( version[ 0 ] === 2 ) && ( version[ 1 ] === 1 ) ) {
 
-				this._accuracyMatrix =  ( flags & 0x2 ) === 0x2;
-				this._accuracyGeo =     ( flags & 0x4 ) === 0x4;
-				this._accuracyProps =   ( flags & 0x8 ) === 0x8;
+				this._accuracyMatrix = ( flags & 0x2 ) === 0x2;
+				this._accuracyGeo = ( flags & 0x4 ) === 0x4;
+				this._accuracyProps = ( flags & 0x8 ) === 0x8;
 
 			}
 
-			this._geoNrType     = this._accuracyGeo     ? FLOAT64 : FLOAT32;
-			this._matrixNrType  = this._accuracyMatrix  ? FLOAT64 : FLOAT32;
-			this._propsNrType   = this._accuracyProps   ? FLOAT64 : FLOAT32;
+			this._geoNrType = this._accuracyGeo ? FLOAT64 : FLOAT32;
+			this._matrixNrType = this._accuracyMatrix ? FLOAT64 : FLOAT32;
+			this._propsNrType = this._accuracyProps ? FLOAT64 : FLOAT32;
 
-			this._optimized_for_accuracy  = ( flags & 0x2 ) === 0x2;
+			this._optimized_for_accuracy = ( flags & 0x2 ) === 0x2;
 
 			this._compression = this.readU8();
 			this._bodylen = this.readU32();
@@ -257,9 +274,9 @@
 		parseContainer: function ( len ) {
 
 			var parent,
-					ctr     = new THREE.Object3D(),
-					par_id  = this.readU32(),
-					mtx     = this.parseMatrix4();
+				ctr = new THREE.Object3D(),
+				par_id = this.readU32(),
+				mtx = this.parseMatrix4();
 
 			ctr.name = this.readUTF();
 			ctr.applyMatrix( mtx );
@@ -283,18 +300,18 @@
 		parseMeshInstance: function ( len ) {
 
 			var name,
-					mesh, geometries, meshLen, meshes,
-					par_id, data_id,
-					mtx,
-					materials, mat, mat_id,
-					num_materials,
-					parent,
-					i;
-
-			par_id        = this.readU32();
-			mtx           = this.parseMatrix4();
-			name          = this.readUTF();
-			data_id       = this.readU32();
+				mesh, geometries, meshLen, meshes,
+				par_id, data_id,
+				mtx,
+				materials, mat, mat_id,
+				num_materials,
+				parent,
+				i;
+
+			par_id = this.readU32();
+			mtx = this.parseMatrix4();
+			name = this.readUTF();
+			data_id = this.readU32();
 			num_materials = this.readU16();
 
 			geometries = this.getBlock( data_id );
@@ -314,7 +331,7 @@
 
 			// TODO : BufferGeometry don't support "geometryGroups" for now.
 			// so we create sub meshes for each groups
-			if ( meshLen  > 1 ) {
+			if ( meshLen > 1 ) {
 
 				mesh = new THREE.Object3D();
 				for ( i = 0; i < meshLen; i ++ ) {
@@ -357,16 +374,16 @@
 		parseMaterial: function ( len ) {
 
 			var name,
-					type,
-					props,
-					mat,
-					attributes,
-					finalize,
-					num_methods,
-					methods_parsed;
-
-			name        = this.readUTF();
-			type        = this.readU8();
+				type,
+				props,
+				mat,
+				attributes,
+				finalize,
+				num_methods,
+				methods_parsed;
+
+			name = this.readUTF();
+			type = this.readU8();
 			num_methods = this.readU8();
 
 			//log( "AWDLoader parseMaterial ",name )
@@ -374,8 +391,8 @@
 			// Read material numerical properties
 			// (1=color, 2=bitmap url, 11=alpha_blending, 12=alpha_threshold, 13=repeat)
 			props = this.parseProperties( {
-				1:  AWD_FIELD_INT32,
-				2:  AWD_FIELD_BADDR,
+				1: AWD_FIELD_INT32,
+				2: AWD_FIELD_BADDR,
 				11: AWD_FIELD_BOOL,
 				12: AWD_FIELD_FLOAT32,
 				13: AWD_FIELD_BOOL
@@ -424,12 +441,12 @@
 
 		},
 
-		parseTexture: function( len ) {
+		parseTexture: function ( len ) {
 
 			var name = this.readUTF(),
-					type = this.readU8(),
-					asset,
-					data_len;
+				type = this.readU8(),
+				asset,
+				data_len;
 
 			// External
 			if ( type === 0 ) {
@@ -451,13 +468,13 @@
 
 		},
 
-		loadTexture: function( url ) {
+		loadTexture: function ( url ) {
 
 			var tex = new THREE.Texture();
 
 			var loader = new THREE.ImageLoader( this.manager );
 
-			loader.load( this._baseDir + url, function( image ) {
+			loader.load( this._baseDir + url, function ( image ) {
 
 				tex.image = image;
 				tex.needsUpdate = true;
@@ -468,13 +485,13 @@
 
 		},
 
-		parseSkeleton: function( len ) {
+		parseSkeleton: function ( len ) {
 
 			// Array<Bone>
-			var name          = this.readUTF(),
-					num_joints    = this.readU16(),
-					skeleton      = [],
-					joints_parsed = 0;
+			var name = this.readUTF(),
+				num_joints = this.readU16(),
+				skeleton = [],
+				joints_parsed = 0;
 
 			this.parseProperties( null );
 
@@ -509,7 +526,7 @@
 
 		},
 
-		parseSkeletonPose: function( blockID ) {
+		parseSkeletonPose: function ( blockID ) {
 
 			var name = this.readUTF();
 
@@ -552,7 +569,7 @@
 
 		},
 
-		parseSkeletonAnimation: function( blockID ) {
+		parseSkeletonAnimation: function ( blockID ) {
 
 			var frame_dur;
 			var pose_addr;
@@ -578,8 +595,8 @@
 				pose = this._blocks[ pose_addr ].data;
 				// debug( 'pose address ',pose[2].elements[12],pose[2].elements[13],pose[2].elements[14] );
 				clip.push( {
-					pose : pose,
-					duration : frame_dur
+					pose: pose,
+					duration: frame_dur
 				} );
 
 				frames_parsed ++;
@@ -598,14 +615,14 @@
 
 		},
 
-		parseVertexAnimationSet: function( len ) {
+		parseVertexAnimationSet: function ( len ) {
 
 			var poseBlockAdress,
-					name           = this.readUTF(),
-					num_frames     = this.readU16(),
-					props          = this.parseProperties( { 1: UINT16 } ),
-					frames_parsed  = 0,
-					skeletonFrames = [];
+				name = this.readUTF(),
+				num_frames = this.readU16(),
+				props = this.parseProperties( { 1: UINT16 } ),
+				frames_parsed = 0,
+				skeletonFrames = [];
 
 			while ( frames_parsed < num_frames ) {
 
@@ -622,7 +639,7 @@
 
 		},
 
-		parseAnimatorSet: function( len ) {
+		parseAnimatorSet: function ( len ) {
 
 			var targetMesh;
 
@@ -655,7 +672,7 @@
 
 				//      returnedArray = getAssetByID(meshAdresses[i], [AssetType.MESH]);
 				//      if (returnedArray[0])
-				targetMeshes.push( this._blocks[ meshAdresses[ i ]].data );
+				targetMeshes.push( this._blocks[ meshAdresses[ i ] ].data );
 
 			}
 
@@ -666,8 +683,8 @@
 
 
 				thisAnimator = {
-					animationSet : targetAnimationSet,
-					skeleton : this._blocks[ props.get( 1, 0 ) ].data
+					animationSet: targetAnimationSet,
+					skeleton: this._blocks[ props.get( 1, 0 ) ].data
 				};
 
 			} else if ( type == 2 ) {
@@ -688,19 +705,16 @@
 
 		parseMeshData: function ( len ) {
 
-			var name      = this.readUTF(),
-				num_subs  = this.readU16(),
+			var name = this.readUTF(),
+				num_subs = this.readU16(),
 				geom,
 				subs_parsed = 0,
-				props,
 				buffer,
 				skinW, skinI,
 				geometries = [];
 
-			props = this.parseProperties( {
-				1: this._geoNrType,
-				2: this._geoNrType
-			} );
+			// Ignore for now
+			this.parseProperties( { 1: this._geoNrType, 2: this._geoNrType } );
 
 			// Loop through sub meshes
 			while ( subs_parsed < num_subs ) {
@@ -723,15 +737,15 @@
 				while ( this._ptr < sm_end ) {
 
 					var idx = 0,
-							str_type  = this.readU8(),
-							str_ftype = this.readU8(),
-							str_len   = this.readU32(),
-							str_end   = str_len + this._ptr;
+						str_type = this.readU8(),
+						str_ftype = this.readU8(),
+						str_len = this.readU32(),
+						str_end = str_len + this._ptr;
 
-					// VERTICES
-					// ------------------
 					if ( str_type === 1 ) {
 
+						// VERTICES
+
 						buffer = new Float32Array( ( str_len / 12 ) * 3 );
 						attrib = new THREE.BufferAttribute( buffer, 3 );
 
@@ -740,18 +754,16 @@
 
 						while ( this._ptr < str_end ) {
 
-							buffer[ idx ]   = - this.readF32();
+							buffer[ idx ] = - this.readF32();
 							buffer[ idx + 1 ] = this.readF32();
 							buffer[ idx + 2 ] = this.readF32();
 							idx += 3;
 
 						}
 
-					}
+					} else if ( str_type === 2 ) {
 
-					// INDICES
-					// -----------------
-					else if ( str_type === 2 ) {
+						// INDICES
 
 						buffer = new Uint16Array( str_len / 2 );
 						attrib = new THREE.BufferAttribute( buffer, 1 );
@@ -761,18 +773,16 @@
 
 						while ( this._ptr < str_end ) {
 
-							buffer[ idx + 1 ]   = this.readU16();
-							buffer[ idx ]     = this.readU16();
-							buffer[ idx + 2 ]   = this.readU16();
+							buffer[ idx + 1 ] = this.readU16();
+							buffer[ idx ] = this.readU16();
+							buffer[ idx + 2 ] = this.readU16();
 							idx += 3;
 
 						}
 
-					}
+					} else if ( str_type === 3 ) {
 
-					// UVS
-					// -------------------
-					else if ( str_type === 3 ) {
+						// UVS
 
 						buffer = new Float32Array( ( str_len / 8 ) * 2 );
 						attrib = new THREE.BufferAttribute( buffer, 2 );
@@ -782,16 +792,15 @@
 
 						while ( this._ptr < str_end ) {
 
-							buffer[ idx ]   = this.readF32();
+							buffer[ idx ] = this.readF32();
 							buffer[ idx + 1 ] = 1.0 - this.readF32();
 							idx += 2;
 
 						}
 
-					}
+					} else if ( str_type === 4 ) {
 
-					// NORMALS
-					else if ( str_type === 4 ) {
+						// NORMALS
 
 						buffer = new Float32Array( ( str_len / 12 ) * 3 );
 						attrib = new THREE.BufferAttribute( buffer, 3 );
@@ -800,35 +809,14 @@
 
 						while ( this._ptr < str_end ) {
 
-							buffer[ idx ]   = - this.readF32();
+							buffer[ idx ] = - this.readF32();
 							buffer[ idx + 1 ] = this.readF32();
 							buffer[ idx + 2 ] = this.readF32();
 							idx += 3;
 
 						}
 
-					}
-
-					// else if (str_type == 6) {
-					//   skinI = new Float32Array( str_len>>1 );
-					//   idx = 0
-
-					//   while (this._ptr < str_end) {
-					//     skinI[idx]   = this.readU16();
-					//     idx++;
-					//   }
-
-					// }
-					// else if (str_type == 7) {
-					//   skinW = new Float32Array( str_len>>2 );
-					//   idx = 0;
-
-					//   while (this._ptr < str_end) {
-					//     skinW[idx]   = this.readF32();
-					//     idx++;
-					//   }
-					// }
-					else {
+					} else {
 
 						this._ptr = str_end;
 
@@ -852,31 +840,31 @@
 
 		},
 
-		parseMeshPoseAnimation: function( len, poseOnly ) {
+		parseMeshPoseAnimation: function ( len, poseOnly ) {
 
 			var num_frames = 1,
-					num_submeshes,
-					frames_parsed,
-					subMeshParsed,
-					frame_dur,
-					x, y, z,
-
-					str_len,
-					str_end,
-					geom,
-					subGeom,
-					idx = 0,
-					clip = {},
-					indices,
-					verts,
-					num_Streams,
-					streamsParsed,
-					streamtypes = [],
-
-					props,
-					thisGeo,
-					name = this.readUTF(),
-					geoAdress = this.readU32();
+				num_submeshes,
+				frames_parsed,
+				subMeshParsed,
+				frame_dur,
+				x, y, z,
+
+				str_len,
+				str_end,
+				geom,
+				subGeom,
+				idx = 0,
+				clip = {},
+				indices,
+				verts,
+				num_Streams,
+				streamsParsed,
+				streamtypes = [],
+
+				props,
+				thisGeo,
+				name = this.readUTF(),
+				geoAdress = this.readU32();
 
 			var mesh = this.getBlock( geoAdress );
 
@@ -932,7 +920,7 @@
 							//geom.addAttribute( 'morphTarget'+frames_parsed, Float32Array, str_len/12, 3 );
 							var buffer = new Float32Array( str_len / 4 );
 							geom.morphTargets.push( {
-								array : buffer
+								array: buffer
 							} );
 
 							//buffer = geom.attributes['morphTarget'+frames_parsed].array
@@ -940,9 +928,9 @@
 
 							while ( this._ptr < str_end ) {
 
-								buffer[ idx ]     = this.readF32();
-								buffer[ idx + 1 ]   = this.readF32();
-								buffer[ idx + 2 ]   = this.readF32();
+								buffer[ idx ] = this.readF32();
+								buffer[ idx + 1 ] = this.readF32();
+								buffer[ idx + 2 ] = this.readF32();
 								idx += 3;
 
 							}
@@ -1055,40 +1043,49 @@
 			var read_func;
 
 			switch ( type ) {
+
 				case AWD_FIELD_INT8:
 					elem_len = 1;
 					read_func = this.readI8;
 					break;
+
 				case AWD_FIELD_INT16:
 					elem_len = 2;
 					read_func = this.readI16;
 					break;
+
 				case AWD_FIELD_INT32:
 					elem_len = 4;
 					read_func = this.readI32;
 					break;
+
 				case AWD_FIELD_BOOL:
 				case AWD_FIELD_UINT8:
 					elem_len = 1;
 					read_func = this.readU8;
 					break;
+
 				case AWD_FIELD_UINT16:
 					elem_len = 2;
 					read_func = this.readU16;
 					break;
+
 				case AWD_FIELD_UINT32:
 				case AWD_FIELD_BADDR:
 					elem_len = 4;
 					read_func = this.readU32;
 					break;
+
 				case AWD_FIELD_FLOAT32:
 					elem_len = 4;
 					read_func = this.readF32;
 					break;
+
 				case AWD_FIELD_FLOAT64:
 					elem_len = 8;
 					read_func = this.readF64;
 					break;
+
 				case AWD_FIELD_VECTOR2x1:
 				case AWD_FIELD_VECTOR3x1:
 				case AWD_FIELD_VECTOR4x1:
@@ -1099,6 +1096,7 @@
 					elem_len = 8;
 					read_func = this.readF64;
 					break;
+
 			}
 
 			if ( elem_len < len ) {
@@ -1219,9 +1217,7 @@
 
 					var c2 = this._data.getUint8( this._ptr ++, littleEndian );
 					var c3 = this._data.getUint8( this._ptr ++, littleEndian );
-					out[ c ++ ] = String.fromCharCode(
-							( c1 & 15 ) << 12 | ( c2 & 63 ) << 6 | c3 & 63
-					);
+					out[ c ++ ] = String.fromCharCode( ( c1 & 15 ) << 12 | ( c2 & 63 ) << 6 | c3 & 63 );
 
 				}
 

+ 3 - 3
examples/js/loaders/AssimpJSONLoader.js

@@ -149,7 +149,7 @@ THREE.AssimpJSONLoader.prototype = {
 
 					case '$tex.file': {
 
-						var semantic =  property.semantic;
+						var semantic = property.semantic;
 
 						// prop.semantic gives the type of the texture
 						// 1: diffuse
@@ -255,8 +255,8 @@ THREE.AssimpJSONLoader.prototype = {
 		var textureLoader = new THREE.TextureLoader( this.manager );
 		textureLoader.setPath( path ).setCrossOrigin( this.crossOrigin );
 
-		var meshes = parseList ( json.meshes, parseMesh );
-		var materials = parseList ( json.materials, parseMaterial );
+		var meshes = parseList( json.meshes, parseMesh );
+		var materials = parseList( json.materials, parseMaterial );
 		return parseObject( json, json.rootnode, meshes, materials );
 
 	}

+ 49 - 30
examples/js/loaders/AssimpLoader.js

@@ -69,7 +69,7 @@ THREE.AssimpLoader.prototype = {
 				//      var keyscl =  key.parentspaceScl || key.scl;
 				var key2pos = nextKey.position;
 				var key2rot = nextKey.quaternion;
-					//  var key2scl =  key2.parentspaceScl || key2.scl;
+				//  var key2scl =  key2.parentspaceScl || key2.scl;
 				Virtulous.KeyFrame.tempAniPos.x = keypos.x * l2 + key2pos.x * l;
 				Virtulous.KeyFrame.tempAniPos.y = keypos.y * l2 + key2pos.y * l;
 				Virtulous.KeyFrame.tempAniPos.z = keypos.z * l2 + key2pos.z * l;
@@ -513,7 +513,7 @@ THREE.AssimpLoader.prototype = {
 			rootBone.position.copy( root.position );
 			rootBone.quaternion.copy( root.quaternion );
 			rootBone.scale.copy( root.scale );
-			scene.nodeCount++;
+			scene.nodeCount ++;
 			rootBone.name = "bone_" + root.name + scene.nodeCount.toString();
 
 			if ( ! scene.nodeToBoneMap[ root.name ] )
@@ -544,7 +544,11 @@ THREE.AssimpLoader.prototype = {
 
 			}
 
-			pairs.sort( function ( a, b ) { return b.w - a.w } );
+			pairs.sort( function ( a, b ) {
+
+				return b.w - a.w;
+
+			 } );
 
 			while ( pairs.length < 4 ) {
 
@@ -1202,9 +1206,21 @@ THREE.AssimpLoader.prototype = {
 			this.getLength = function () {
 
 				return Math.max(
-					Math.max.apply( null, this.mPositionKeys.map( function ( a ) { return a.mTime } ) ),
-					Math.max.apply( null, this.mRotationKeys.map( function ( a ) { return a.mTime } ) ),
-					Math.max.apply( null, this.mScalingKeys.map( function ( a ) { return a.mTime } ) )
+					Math.max.apply( null, this.mPositionKeys.map( function ( a ) {
+
+						return a.mTime;
+
+					} ) ),
+					Math.max.apply( null, this.mRotationKeys.map( function ( a ) {
+
+						return a.mTime;
+
+					} ) ),
+					Math.max.apply( null, this.mScalingKeys.map( function ( a ) {
+
+						return a.mTime;
+
+				 } ) )
 				);
 
 			};
@@ -1277,7 +1293,11 @@ THREE.AssimpLoader.prototype = {
 
 				}
 
-				animationHandle.length = Math.max.apply( null, animationHandle.tracks.map( function ( e ) { return e.length } ) );
+				animationHandle.length = Math.max.apply( null, animationHandle.tracks.map( function ( e ) {
+
+					return e.length;
+
+				} ) );
 				return animationHandle;
 
 			};
@@ -1397,9 +1417,9 @@ THREE.AssimpLoader.prototype = {
 
 				var m = new THREE.Matrix4();
 
-				for ( var i = 0; i < 4; ++i ) {
+				for ( var i = 0; i < 4; ++ i ) {
 
-					for ( var i2 = 0; i2 < 4; ++i2 ) {
+					for ( var i2 = 0; i2 < 4; ++ i2 ) {
 
 						m.elements[ i * 4 + i2 ] = this.elements[ i2 ][ i ];
 
@@ -1547,9 +1567,9 @@ THREE.AssimpLoader.prototype = {
 
 			var m = new aiMatrix4();
 
-			for ( var i = 0; i < 4; ++i ) {
+			for ( var i = 0; i < 4; ++ i ) {
 
-				for ( var i2 = 0; i2 < 4; ++i2 ) {
+				for ( var i2 = 0; i2 < 4; ++ i2 ) {
 
 					m.elements[ i ][ i2 ] = readFloat( stream );
 
@@ -1659,7 +1679,7 @@ THREE.AssimpLoader.prototype = {
 
 				node.mMeshes = [];
 
-				for ( var i = 0; i < node.mNumMeshes; ++i ) {
+				for ( var i = 0; i < node.mNumMeshes; ++ i ) {
 
 					node.mMeshes[ i ] = Read_unsigned_int( stream );
 
@@ -1671,7 +1691,7 @@ THREE.AssimpLoader.prototype = {
 
 				node.mChildren = [];
 
-				for ( var i = 0; i < node.mNumChildren; ++i ) {
+				for ( var i = 0; i < node.mNumChildren; ++ i ) {
 
 					var node2 = ReadBinaryNode( stream, node, depth ++ );
 					node.mChildren[ i ] = node2;
@@ -1787,7 +1807,7 @@ THREE.AssimpLoader.prototype = {
 
 			}
 
-			for ( var n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS; ++n ) {
+			for ( var n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS; ++ n ) {
 
 				if ( ! ( c & ASSBIN_MESH_HAS_COLOR( n ) ) ) break;
 
@@ -1809,7 +1829,7 @@ THREE.AssimpLoader.prototype = {
 
 			mesh.mTexCoordsBuffers = [];
 
-			for ( var n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++n ) {
+			for ( var n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++ n ) {
 
 				if ( ! ( c & ASSBIN_MESH_HAS_TEXCOORD( n ) ) ) break;
 
@@ -1857,14 +1877,14 @@ THREE.AssimpLoader.prototype = {
 				var indexCounter = 0;
 				mesh.mIndexArray = [];
 
-				for ( var i = 0; i < mesh.mNumFaces; ++i ) {
+				for ( var i = 0; i < mesh.mNumFaces; ++ i ) {
 
 					var f = mesh.mFaces[ i ] = new aiFace();
 					// BOOST_STATIC_ASSERT(AI_MAX_FACE_INDICES <= 0xffff);
 					f.mNumIndices = Read_uint16_t( stream );
 					f.mIndices = [];
 
-					for ( var a = 0; a < f.mNumIndices; ++a ) {
+					for ( var a = 0; a < f.mNumIndices; ++ a ) {
 
 						if ( mesh.mNumVertices < ( 1 << 16 ) ) {
 
@@ -1880,14 +1900,13 @@ THREE.AssimpLoader.prototype = {
 
 					}
 
-					if(f.mNumIndices === 3) {
+					if ( f.mNumIndices === 3 ) {
 
 						mesh.mIndexArray.push( f.mIndices[ 0 ] );
 						mesh.mIndexArray.push( f.mIndices[ 1 ] );
 						mesh.mIndexArray.push( f.mIndices[ 2 ] );
 
-					}
-					else if(f.mNumIndices === 4) {
+					} else if ( f.mNumIndices === 4 ) {
 
 						mesh.mIndexArray.push( f.mIndices[ 0 ] );
 						mesh.mIndexArray.push( f.mIndices[ 1 ] );
@@ -1898,7 +1917,7 @@ THREE.AssimpLoader.prototype = {
 
 					} else {
 
-						throw ( new Error( "Sorry, can't currently triangulate polys. Use the triangulate preprocessor in Assimp." ))
+						throw ( new Error( "Sorry, can't currently triangulate polys. Use the triangulate preprocessor in Assimp." ) );
 
 					}
 
@@ -1912,7 +1931,7 @@ THREE.AssimpLoader.prototype = {
 
 				mesh.mBones = [];
 
-				for ( var a = 0; a < mesh.mNumBones; ++a ) {
+				for ( var a = 0; a < mesh.mNumBones; ++ a ) {
 
 					mesh.mBones[ a ] = new aiBone();
 					ReadBinaryBone( stream, mesh.mBones[ a ] );
@@ -1959,7 +1978,7 @@ THREE.AssimpLoader.prototype = {
 
 				mat.mProperties = [];
 
-				for ( var i = 0; i < mat.mNumProperties; ++i ) {
+				for ( var i = 0; i < mat.mNumProperties; ++ i ) {
 
 					mat.mProperties[ i ] = new aiMaterialProperty();
 					ReadBinaryMaterialProperty( stream, mat.mProperties[ i ] );
@@ -2051,7 +2070,7 @@ THREE.AssimpLoader.prototype = {
 
 				anim.mChannels = [];
 
-				for ( var a = 0; a < anim.mNumChannels; ++a ) {
+				for ( var a = 0; a < anim.mNumChannels; ++ a ) {
 
 					anim.mChannels[ a ] = new aiNodeAnim();
 					ReadBinaryNodeAnim( stream, anim.mChannels[ a ] );
@@ -2158,7 +2177,7 @@ THREE.AssimpLoader.prototype = {
 
 				scene.mMeshes = [];
 
-				for ( var i = 0; i < scene.mNumMeshes; ++i ) {
+				for ( var i = 0; i < scene.mNumMeshes; ++ i ) {
 
 					scene.mMeshes[ i ] = new aiMesh();
 					ReadBinaryMesh( stream, scene.mMeshes[ i ] );
@@ -2171,7 +2190,7 @@ THREE.AssimpLoader.prototype = {
 
 				scene.mMaterials = [];
 
-				for ( var i = 0; i < scene.mNumMaterials; ++i ) {
+				for ( var i = 0; i < scene.mNumMaterials; ++ i ) {
 
 					scene.mMaterials[ i ] = new aiMaterial();
 					ReadBinaryMaterial( stream, scene.mMaterials[ i ] );
@@ -2184,7 +2203,7 @@ THREE.AssimpLoader.prototype = {
 
 				scene.mAnimations = [];
 
-				for ( var i = 0; i < scene.mNumAnimations; ++i ) {
+				for ( var i = 0; i < scene.mNumAnimations; ++ i ) {
 
 					scene.mAnimations[ i ] = new aiAnimation();
 					ReadBinaryAnim( stream, scene.mAnimations[ i ] );
@@ -2197,7 +2216,7 @@ THREE.AssimpLoader.prototype = {
 
 				scene.mTextures = [];
 
-				for ( var i = 0; i < scene.mNumTextures; ++i ) {
+				for ( var i = 0; i < scene.mNumTextures; ++ i ) {
 
 					scene.mTextures[ i ] = new aiTexture();
 					ReadBinaryTexture( stream, scene.mTextures[ i ] );
@@ -2210,7 +2229,7 @@ THREE.AssimpLoader.prototype = {
 
 				scene.mLights = [];
 
-				for ( var i = 0; i < scene.mNumLights; ++i ) {
+				for ( var i = 0; i < scene.mNumLights; ++ i ) {
 
 					scene.mLights[ i ] = new aiLight();
 					ReadBinaryLight( stream, scene.mLights[ i ] );
@@ -2223,7 +2242,7 @@ THREE.AssimpLoader.prototype = {
 
 				scene.mCameras = [];
 
-				for ( var i = 0; i < scene.mNumCameras; ++i ) {
+				for ( var i = 0; i < scene.mNumCameras; ++ i ) {
 
 					scene.mCameras[ i ] = new aiCamera();
 					ReadBinaryCamera( stream, scene.mCameras[ i ] );

+ 25 - 25
examples/js/loaders/BVHLoader.js

@@ -8,7 +8,7 @@
  *
  */
 
-THREE.BVHLoader = function( manager ) {
+THREE.BVHLoader = function ( manager ) {
 
 	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
 
@@ -26,7 +26,7 @@ THREE.BVHLoader.prototype = {
 		var scope = this;
 
 		var loader = new THREE.FileLoader( scope.manager );
-		loader.load( url, function( text ) {
+		loader.load( url, function ( text ) {
 
 			onLoad( scope.parse( text ) );
 
@@ -137,29 +137,29 @@ THREE.BVHLoader.prototype = {
 
 				switch ( bone.channels[ i ] ) {
 
-				case 'Xposition':
-					keyframe.position.x = parseFloat( data.shift().trim() );
-					break;
-				case 'Yposition':
-					keyframe.position.y = parseFloat( data.shift().trim() );
-					break;
-				case 'Zposition':
-					keyframe.position.z = parseFloat( data.shift().trim() );
-					break;
-				case 'Xrotation':
-					quat.setFromAxisAngle( vx, parseFloat( data.shift().trim() ) * Math.PI / 180 );
-					keyframe.rotation.multiply( quat );
-					break;
-				case 'Yrotation':
-					quat.setFromAxisAngle( vy, parseFloat( data.shift().trim() ) * Math.PI / 180 );
-					keyframe.rotation.multiply( quat );
-					break;
-				case 'Zrotation':
-					quat.setFromAxisAngle( vz, parseFloat( data.shift().trim() ) * Math.PI / 180 );
-					keyframe.rotation.multiply( quat );
-					break;
-				default:
-					console.warn( 'THREE.BVHLoader: Invalid channel type.' );
+					case 'Xposition':
+						keyframe.position.x = parseFloat( data.shift().trim() );
+						break;
+					case 'Yposition':
+						keyframe.position.y = parseFloat( data.shift().trim() );
+						break;
+					case 'Zposition':
+						keyframe.position.z = parseFloat( data.shift().trim() );
+						break;
+					case 'Xrotation':
+						quat.setFromAxisAngle( vx, parseFloat( data.shift().trim() ) * Math.PI / 180 );
+						keyframe.rotation.multiply( quat );
+						break;
+					case 'Yrotation':
+						quat.setFromAxisAngle( vy, parseFloat( data.shift().trim() ) * Math.PI / 180 );
+						keyframe.rotation.multiply( quat );
+						break;
+					case 'Zrotation':
+						quat.setFromAxisAngle( vz, parseFloat( data.shift().trim() ) * Math.PI / 180 );
+						keyframe.rotation.multiply( quat );
+						break;
+					default:
+						console.warn( 'THREE.BVHLoader: Invalid channel type.' );
 
 				}
 

+ 1 - 0
examples/js/loaders/BabylonLoader.js

@@ -177,6 +177,7 @@ THREE.BabylonLoader.prototype = {
 					case 3:
 						light = new THREE.HemisphereLight();
 						break;
+
 				}
 
 				light.name = data.name;

+ 37 - 37
examples/js/loaders/BinaryLoader.js

@@ -33,7 +33,7 @@ THREE.BinaryLoader.prototype = {
 		// todo: unify load API to for easier SceneLoader use
 
 		var texturePath = this.texturePath || THREE.Loader.prototype.extractUrlBase( url );
-		var binaryPath  = this.binaryPath || THREE.Loader.prototype.extractUrlBase( url );
+		var binaryPath = this.binaryPath || THREE.Loader.prototype.extractUrlBase( url );
 
 		// #1 load JS part via web worker
 
@@ -83,7 +83,7 @@ THREE.BinaryLoader.prototype = {
 
 	parse: function ( data, callback, texturePath, jsonMaterials ) {
 
-		var Model = function ( texturePath ) {
+		var Model = function () {
 
 			var scope = this,
 				currentOffset = 0,
@@ -110,17 +110,17 @@ THREE.BinaryLoader.prototype = {
 			*/
 			// buffers sizes
 
-			tri_size =  md.vertex_index_bytes * 3 + md.material_index_bytes;
+			tri_size = md.vertex_index_bytes * 3 + md.material_index_bytes;
 			quad_size = md.vertex_index_bytes * 4 + md.material_index_bytes;
 
-			len_tri_flat      = md.ntri_flat      * ( tri_size );
-			len_tri_smooth    = md.ntri_smooth    * ( tri_size + md.normal_index_bytes * 3 );
-			len_tri_flat_uv   = md.ntri_flat_uv   * ( tri_size + md.uv_index_bytes * 3 );
+			len_tri_flat = md.ntri_flat * ( tri_size );
+			len_tri_smooth = md.ntri_smooth * ( tri_size + md.normal_index_bytes * 3 );
+			len_tri_flat_uv = md.ntri_flat_uv * ( tri_size + md.uv_index_bytes * 3 );
 			len_tri_smooth_uv = md.ntri_smooth_uv * ( tri_size + md.normal_index_bytes * 3 + md.uv_index_bytes * 3 );
 
-			len_quad_flat      = md.nquad_flat      * ( quad_size );
-			len_quad_smooth    = md.nquad_smooth    * ( quad_size + md.normal_index_bytes * 4 );
-			len_quad_flat_uv   = md.nquad_flat_uv   * ( quad_size + md.uv_index_bytes * 4 );
+			len_quad_flat = md.nquad_flat * ( quad_size );
+			len_quad_smooth = md.nquad_smooth * ( quad_size + md.normal_index_bytes * 4 );
+			len_quad_flat_uv = md.nquad_flat_uv * ( quad_size + md.uv_index_bytes * 4 );
 
 			// read buffers
 
@@ -131,15 +131,15 @@ THREE.BinaryLoader.prototype = {
 
 			currentOffset += init_uvs( currentOffset );
 
-			start_tri_flat 		= currentOffset;
-			start_tri_smooth    = start_tri_flat    + len_tri_flat    + handlePadding( md.ntri_flat * 2 );
-			start_tri_flat_uv   = start_tri_smooth  + len_tri_smooth  + handlePadding( md.ntri_smooth * 2 );
+			start_tri_flat = currentOffset;
+			start_tri_smooth = start_tri_flat + len_tri_flat + handlePadding( md.ntri_flat * 2 );
+			start_tri_flat_uv = start_tri_smooth + len_tri_smooth + handlePadding( md.ntri_smooth * 2 );
 			start_tri_smooth_uv = start_tri_flat_uv + len_tri_flat_uv + handlePadding( md.ntri_flat_uv * 2 );
 
-			start_quad_flat     = start_tri_smooth_uv + len_tri_smooth_uv  + handlePadding( md.ntri_smooth_uv * 2 );
-			start_quad_smooth   = start_quad_flat     + len_quad_flat	   + handlePadding( md.nquad_flat * 2 );
-			start_quad_flat_uv  = start_quad_smooth   + len_quad_smooth    + handlePadding( md.nquad_smooth * 2 );
-			start_quad_smooth_uv = start_quad_flat_uv  + len_quad_flat_uv   + handlePadding( md.nquad_flat_uv * 2 );
+			start_quad_flat = start_tri_smooth_uv + len_tri_smooth_uv + handlePadding( md.ntri_smooth_uv * 2 );
+			start_quad_smooth = start_quad_flat + len_quad_flat	+ handlePadding( md.nquad_flat * 2 );
+			start_quad_flat_uv = start_quad_smooth + len_quad_smooth + handlePadding( md.nquad_smooth * 2 );
+			start_quad_smooth_uv = start_quad_flat_uv + len_quad_flat_uv + handlePadding( md.nquad_flat_uv * 2 );
 
 			// have to first process faces with uvs
 			// so that face and uv indices match
@@ -170,31 +170,31 @@ THREE.BinaryLoader.prototype = {
 
 				var metaData = {
 
-					'signature'               : parseString( data, offset,  12 ),
-					'header_bytes'            : parseUChar8( data, offset + 12 ),
+					'signature': parseString( data, offset, 12 ),
+					'header_bytes': parseUChar8( data, offset + 12 ),
 
-					'vertex_coordinate_bytes' : parseUChar8( data, offset + 13 ),
-					'normal_coordinate_bytes' : parseUChar8( data, offset + 14 ),
-					'uv_coordinate_bytes'     : parseUChar8( data, offset + 15 ),
+					'vertex_coordinate_bytes': parseUChar8( data, offset + 13 ),
+					'normal_coordinate_bytes': parseUChar8( data, offset + 14 ),
+					'uv_coordinate_bytes': parseUChar8( data, offset + 15 ),
 
-					'vertex_index_bytes'      : parseUChar8( data, offset + 16 ),
-					'normal_index_bytes'      : parseUChar8( data, offset + 17 ),
-					'uv_index_bytes'          : parseUChar8( data, offset + 18 ),
-					'material_index_bytes'    : parseUChar8( data, offset + 19 ),
+					'vertex_index_bytes': parseUChar8( data, offset + 16 ),
+					'normal_index_bytes': parseUChar8( data, offset + 17 ),
+					'uv_index_bytes': parseUChar8( data, offset + 18 ),
+					'material_index_bytes': parseUChar8( data, offset + 19 ),
 
-					'nvertices'    : parseUInt32( data, offset + 20 ),
-					'nnormals'     : parseUInt32( data, offset + 20 + 4 * 1 ),
-					'nuvs'         : parseUInt32( data, offset + 20 + 4 * 2 ),
+					'nvertices': parseUInt32( data, offset + 20 ),
+					'nnormals': parseUInt32( data, offset + 20 + 4 * 1 ),
+					'nuvs': parseUInt32( data, offset + 20 + 4 * 2 ),
 
-					'ntri_flat'      : parseUInt32( data, offset + 20 + 4 * 3 ),
-					'ntri_smooth'    : parseUInt32( data, offset + 20 + 4 * 4 ),
-					'ntri_flat_uv'   : parseUInt32( data, offset + 20 + 4 * 5 ),
-					'ntri_smooth_uv' : parseUInt32( data, offset + 20 + 4 * 6 ),
+					'ntri_flat': parseUInt32( data, offset + 20 + 4 * 3 ),
+					'ntri_smooth': parseUInt32( data, offset + 20 + 4 * 4 ),
+					'ntri_flat_uv': parseUInt32( data, offset + 20 + 4 * 5 ),
+					'ntri_smooth_uv': parseUInt32( data, offset + 20 + 4 * 6 ),
 
-					'nquad_flat'      : parseUInt32( data, offset + 20 + 4 * 7 ),
-					'nquad_smooth'    : parseUInt32( data, offset + 20 + 4 * 8 ),
-					'nquad_flat_uv'   : parseUInt32( data, offset + 20 + 4 * 9 ),
-					'nquad_smooth_uv' : parseUInt32( data, offset + 20 + 4 * 10 )
+					'nquad_flat': parseUInt32( data, offset + 20 + 4 * 7 ),
+					'nquad_smooth': parseUInt32( data, offset + 20 + 4 * 8 ),
+					'nquad_flat_uv': parseUInt32( data, offset + 20 + 4 * 9 ),
+					'nquad_smooth_uv': parseUInt32( data, offset + 20 + 4 * 10 )
 
 				};
 				/*
@@ -689,7 +689,7 @@ THREE.BinaryLoader.prototype = {
 		Model.prototype = Object.create( THREE.Geometry.prototype );
 		Model.prototype.constructor = Model;
 
-		var geometry = new Model( texturePath );
+		var geometry = new Model();
 		var materials = THREE.Loader.prototype.initMaterials( jsonMaterials, texturePath, this.crossOrigin );
 
 		callback( geometry, materials );

+ 42 - 34
examples/js/loaders/ColladaLoader2.js

@@ -130,7 +130,7 @@ THREE.ColladaLoader.prototype = {
 
 		function isEmpty( object ) {
 
-			return  Object.keys( object ).length === 0;
+			return Object.keys( object ).length === 0;
 
 		}
 
@@ -346,13 +346,11 @@ THREE.ColladaLoader.prototype = {
 
 					var inputId = sampler.inputs.INPUT;
 					var outputId = sampler.inputs.OUTPUT;
-					var interpolationId = sampler.inputs.INTERPOLATION;
 
 					var inputSource = sources[ inputId ];
 					var outputSource = sources[ outputId ];
-					var interpolationSource = sources[ interpolationId ];
 
-					var animation = buildAnimationChannel( channel, inputSource, outputSource, interpolationSource );
+					var animation = buildAnimationChannel( channel, inputSource, outputSource );
 
 					createKeyframeTracks( animation, tracks );
 
@@ -370,7 +368,7 @@ THREE.ColladaLoader.prototype = {
 
 		}
 
-		function buildAnimationChannel( channel, inputSource, outputSource, interpolationSource ) {
+		function buildAnimationChannel( channel, inputSource, outputSource ) {
 
 			var node = library.nodes[ channel.id ];
 			var object3D = getNode( node.id );
@@ -437,7 +435,7 @@ THREE.ColladaLoader.prototype = {
 			var animation = {
 				name: object3D.uuid,
 				keyframes: keyframes
-			}
+			};
 
 			return animation;
 
@@ -578,7 +576,7 @@ THREE.ColladaLoader.prototype = {
 					prev = getPrev( keyframes, i, property );
 					next = getNext( keyframes, i, property );
 
-					if ( prev === null )  {
+					if ( prev === null ) {
 
 						keyframe.value[ property ] = next.value[ property ];
 						continue;
@@ -726,6 +724,11 @@ THREE.ColladaLoader.prototype = {
 						data.skin = parseSkin( child );
 						break;
 
+					case 'morph':
+						data.id = parseId( child.getAttribute( 'source' ) );
+						console.warn( 'THREE.ColladaLoader: Morph target animation not supported yet.' );
+						break;
+
 				}
 
 			}
@@ -738,7 +741,7 @@ THREE.ColladaLoader.prototype = {
 
 			var data = {
 				sources: {}
-			}
+			};
 
 			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
 
@@ -777,7 +780,7 @@ THREE.ColladaLoader.prototype = {
 
 			var data = {
 				inputs: {}
-			}
+			};
 
 			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
 
@@ -805,7 +808,7 @@ THREE.ColladaLoader.prototype = {
 
 			var data = {
 				inputs: {}
-			}
+			};
 
 			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
 
@@ -840,16 +843,22 @@ THREE.ColladaLoader.prototype = {
 
 		function buildController( data ) {
 
-			var build = {};
+			var build = {
+				id: data.id
+			};
+
+			var geometry = library.geometries[ build.id ];
 
-			build.id = data.id;
-			build.skin = buildSkin( data.skin );
+			if ( data.skin !== undefined ) {
 
-			// we enhance the 'sources' property of the corresponding geometry with our skin data
+				build.skin = buildSkin( data.skin );
 
-			var geometry = library.geometries[ build.id ];
-			geometry.sources.skinIndices = build.skin.indices;
-			geometry.sources.skinWeights = build.skin.weights;
+				// we enhance the 'sources' property of the corresponding geometry with our skin data
+
+				geometry.sources.skinIndices = build.skin.indices;
+				geometry.sources.skinWeights = build.skin.weights;
+
+			}
 
 			return build;
 
@@ -1381,7 +1390,7 @@ THREE.ColladaLoader.prototype = {
 
 					var extra = textureObject.extra;
 
-					if ( extra !== undefined && extra.technique !== undefined  && isEmpty( extra.technique ) === false ) {
+					if ( extra !== undefined && extra.technique !== undefined && isEmpty( extra.technique ) === false ) {
 
 						var technique = extra.technique;
 
@@ -1850,7 +1859,7 @@ THREE.ColladaLoader.prototype = {
 			var primitive = {
 				type: xml.nodeName,
 				material: xml.getAttribute( 'material' ),
-				count:  parseInt( xml.getAttribute( 'count' ) ),
+				count: parseInt( xml.getAttribute( 'count' ) ),
 				inputs: {},
 				stride: 0
 			};
@@ -1949,7 +1958,6 @@ THREE.ColladaLoader.prototype = {
 			var materialKeys = [];
 
 			var start = 0, count = 0;
-			var array;
 
 			for ( var p = 0; p < primitives.length; p ++ ) {
 
@@ -1997,7 +2005,7 @@ THREE.ColladaLoader.prototype = {
 						case 'VERTEX':
 							for ( var key in vertices ) {
 
-								var id =  vertices[ key ];
+								var id = vertices[ key ];
 
 								switch ( key ) {
 
@@ -2165,7 +2173,7 @@ THREE.ColladaLoader.prototype = {
 
 			var data = {
 				name: xml.getAttribute( 'name' ) || '',
-				joints: [],
+				joints: {},
 				links: []
 			};
 
@@ -2187,7 +2195,7 @@ THREE.ColladaLoader.prototype = {
 
 			library.kinematicsModels[ xml.getAttribute( 'id' ) ] = data;
 
-		};
+		}
 
 		function buildKinematicsModel( data ) {
 
@@ -2214,7 +2222,7 @@ THREE.ColladaLoader.prototype = {
 				switch ( child.nodeName ) {
 
 					case 'joint':
-						data.joints.push( parseKinematicsJoint( child ) );
+						data.joints[ child.getAttribute( 'sid' ) ] = parseKinematicsJoint( child );
 						break;
 
 					case 'link':
@@ -2255,7 +2263,7 @@ THREE.ColladaLoader.prototype = {
 		function parseKinematicsJointParameter( xml, data ) {
 
 			var data = {
-				sid:  xml.getAttribute( 'sid' ),
+				sid: xml.getAttribute( 'sid' ),
 				name: xml.getAttribute( 'name' ) || '',
 				axis: new THREE.Vector3(),
 				limits: {
@@ -2452,7 +2460,8 @@ THREE.ColladaLoader.prototype = {
 					case 'axis':
 						var param = child.getElementsByTagName( 'param' )[ 0 ];
 						data.axis = param.textContent;
-						data.jointIndex = parseInt( data.axis.split( 'joint' ).pop().split( '.' )[ 0 ] );
+						var tmpJointIndex = data.axis.split( 'inst_' ).pop().split( 'axis' )[ 0 ];
+						data.jointIndex = tmpJointIndex.substr( 0, tmpJointIndex.length - 1 );
 						break;
 
 				}
@@ -2516,11 +2525,10 @@ THREE.ColladaLoader.prototype = {
 
 			function connect( jointIndex, visualElement ) {
 
-				var visualElementId = visualElement.getAttribute( 'id' );
 				var visualElementName = visualElement.getAttribute( 'name' );
 				var joint = kinematicsModel.joints[ jointIndex ];
 
-				visualScene.traverse( function( object ) {
+				visualScene.traverse( function ( object ) {
 
 					if ( object.name === visualElementName ) {
 
@@ -2535,7 +2543,7 @@ THREE.ColladaLoader.prototype = {
 
 				} );
 
-			};
+			}
 
 			var m0 = new THREE.Matrix4();
 
@@ -2543,7 +2551,7 @@ THREE.ColladaLoader.prototype = {
 
 				joints: kinematicsModel && kinematicsModel.joints,
 
-				getJointValue: function( jointIndex ) {
+				getJointValue: function ( jointIndex ) {
 
 					var jointData = jointMap[ jointIndex ];
 
@@ -2559,7 +2567,7 @@ THREE.ColladaLoader.prototype = {
 
 				},
 
-				setJointValue: function( jointIndex, value ) {
+				setJointValue: function ( jointIndex, value ) {
 
 					var jointData = jointMap[ jointIndex ];
 
@@ -2591,7 +2599,7 @@ THREE.ColladaLoader.prototype = {
 
 								// if there is a connection of the transform node with a joint, apply the joint value
 
-								if ( transform.sid && transform.sid.indexOf( 'joint' + jointIndex ) !== -1 ) {
+								if ( transform.sid && transform.sid.indexOf( jointIndex ) !== - 1 ) {
 
 									switch ( joint.type ) {
 
@@ -2693,7 +2701,7 @@ THREE.ColladaLoader.prototype = {
 						var array = parseFloats( child.textContent );
 						var vector = new THREE.Vector3().fromArray( array );
 						var angle = THREE.Math.degToRad( array[ 3 ] );
-						transforms.push({
+						transforms.push( {
 							sid: child.getAttribute( 'sid' ),
 							type: child.nodeName,
 							obj: vector,
@@ -2938,7 +2946,7 @@ THREE.ColladaLoader.prototype = {
 
 			// setup bone data from visual scene
 
-			root.traverse( function( object ) {
+			root.traverse( function ( object ) {
 
 				if ( object.isBone === true ) {
 

+ 3 - 2
examples/js/loaders/DDSLoader.js

@@ -186,7 +186,7 @@ THREE.DDSLoader.parse = function ( buffer, loadMipmaps ) {
 				&& header[ off_RBitMask ] & 0xff0000
 				&& header[ off_GBitMask ] & 0xff00
 				&& header[ off_BBitMask ] & 0xff
-				&& header[ off_ABitMask ] & 0xff000000  ) {
+				&& header[ off_ABitMask ] & 0xff000000 ) {
 
 				isRGBAUncompressed = true;
 				blockBytes = 64;
@@ -198,6 +198,7 @@ THREE.DDSLoader.parse = function ( buffer, loadMipmaps ) {
 				return dds;
 
 			}
+
 	}
 
 	dds.mipmapCount = 1;
@@ -217,7 +218,7 @@ THREE.DDSLoader.parse = function ( buffer, loadMipmaps ) {
 		! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY ) ||
 		! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ ) ||
 		! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ )
-		) ) {
+	) ) {
 
 		console.error( 'THREE.DDSLoader.parse: Incomplete cubemap faces' );
 		return dds;

+ 12 - 9
examples/js/loaders/FBXLoader.js

@@ -1426,7 +1426,7 @@
 						}
 						if ( 'color' in geometry.attributes ) {
 
-							for ( var materialIndex = 0, numMaterials = materials.length; materialIndex < numMaterials; ++materialIndex ) {
+							for ( var materialIndex = 0, numMaterials = materials.length; materialIndex < numMaterials; ++ materialIndex ) {
 
 								materials[ materialIndex ].vertexColors = THREE.VertexColors;
 
@@ -3659,7 +3659,9 @@
 					var nodeAttrs = match[ 2 ].split( ',' );
 
 					for ( var i = 0, l = nodeAttrs.length; i < l; i ++ ) {
+
 						nodeAttrs[ i ] = nodeAttrs[ i ].trim().replace( /^"/, '' ).replace( /"$/, '' );
+
 					}
 
 					this.parseNodeBegin( l, nodeName, nodeAttrs || null );
@@ -3925,7 +3927,9 @@
 			var props = propValue.split( '",' );
 
 			for ( var i = 0, l = props.length; i < l; i ++ ) {
+
 				props[ i ] = props[ i ].trim().replace( /^\"/, '' ).replace( /\s/, '_' );
+
 			}
 
 			var innerPropName = props[ 0 ];
@@ -4027,7 +4031,7 @@
 		 * @param {BinaryReader} reader
 		 * @returns {boolean}
 		 */
-		endOfContent: function( reader ) {
+		endOfContent: function ( reader ) {
 
 			// footer size: 160bytes + 16-byte alignment padding
 			// - 16bytes: magic
@@ -4039,7 +4043,7 @@
 			// - 16bytes: magic
 			if ( reader.size() % 16 === 0 ) {
 
-				return ( ( reader.getOffset() + 160 + 16 ) & ~0xf ) >= reader.size();
+				return ( ( reader.getOffset() + 160 + 16 ) & ~ 0xf ) >= reader.size();
 
 			} else {
 
@@ -4061,7 +4065,6 @@
 			// The first three data sizes depends on version.
 			var endOffset = ( version >= 7500 ) ? reader.getUint64() : reader.getUint32();
 			var numProperties = ( version >= 7500 ) ? reader.getUint64() : reader.getUint32();
-			var propertyListLen = ( version >= 7500 ) ? reader.getUint64() : reader.getUint32();
 			var nameLen = reader.getUint8();
 			var name = reader.getString( nameLen );
 
@@ -4355,7 +4358,7 @@
 
 					}
 
-					var inflate = new Zlib.Inflate( new Uint8Array( reader.getArrayBuffer( compressedLength ) ) );
+					var inflate = new Zlib.Inflate( new Uint8Array( reader.getArrayBuffer( compressedLength ) ) ); // eslint-disable-line no-undef
 					var reader2 = new BinaryReader( inflate.decompress().buffer );
 
 					switch ( type ) {
@@ -4602,8 +4605,8 @@
 			// calculate negative value
 			if ( high & 0x80000000 ) {
 
-				high = ~high & 0xFFFFFFFF;
-				low = ~low & 0xFFFFFFFF;
+				high = ~ high & 0xFFFFFFFF;
+				low = ~ low & 0xFFFFFFFF;
 
 				if ( low === 0xFFFFFFFF ) high = ( high + 1 ) & 0xFFFFFFFF;
 
@@ -4731,7 +4734,7 @@
 			while ( size > 0 ) {
 
 				var value = this.getUint8();
-				size--;
+				size --;
 
 				if ( value === 0 ) break;
 
@@ -5092,7 +5095,7 @@
 
 		}
 
-		return -1;
+		return - 1;
 
 	}
 

+ 80 - 88
examples/js/loaders/GLTFLoader.js

@@ -38,8 +38,12 @@ THREE.GLTFLoader = ( function () {
 
 				} catch ( e ) {
 
-					// For SyntaxError or TypeError, return a generic failure message.
-					onError( e.constructor === Error ? e : new Error( 'THREE.GLTFLoader: Unable to parse model.' ) );
+					if ( onError !== undefined ) {
+
+						// For SyntaxError or TypeError, return a generic failure message.
+						onError( e.constructor === Error ? e : new Error( 'THREE.GLTFLoader: Unable to parse model.' ) );
+
+					}
 
 				}
 
@@ -88,19 +92,19 @@ THREE.GLTFLoader = ( function () {
 
 			if ( json.extensionsUsed ) {
 
-				if( json.extensionsUsed.indexOf( EXTENSIONS.KHR_LIGHTS ) >= 0 ) {
+				if ( json.extensionsUsed.indexOf( EXTENSIONS.KHR_LIGHTS ) >= 0 ) {
 
 					extensions[ EXTENSIONS.KHR_LIGHTS ] = new GLTFLightsExtension( json );
 
 				}
 
-				if( json.extensionsUsed.indexOf( EXTENSIONS.KHR_MATERIALS_COMMON ) >= 0 ) {
+				if ( json.extensionsUsed.indexOf( EXTENSIONS.KHR_MATERIALS_COMMON ) >= 0 ) {
 
 					extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ] = new GLTFMaterialsCommonExtension( json );
 
 				}
 
-				if( json.extensionsUsed.indexOf( EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ) >= 0 ) {
+				if ( json.extensionsUsed.indexOf( EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ) >= 0 ) {
 
 					extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ] = new GLTFMaterialsPbrSpecularGlossinessExtension();
 
@@ -166,22 +170,6 @@ THREE.GLTFLoader = ( function () {
 
 				objects = {};
 
-			},
-
-			update: function ( scene, camera ) {
-
-				for ( var name in objects ) {
-
-					var object = objects[ name ];
-
-					if ( object.update ) {
-
-						object.update( scene, camera );
-
-					}
-
-				}
-
 			}
 
 		};
@@ -343,7 +331,7 @@ THREE.GLTFLoader = ( function () {
 
 		var materialValues = {};
 
-		keys.forEach( function( v ) {
+		keys.forEach( function ( v ) {
 
 			if ( khrMaterial[ v ] !== undefined ) materialValues[ v ] = khrMaterial[ v ];
 
@@ -515,14 +503,14 @@ THREE.GLTFLoader = ( function () {
 				].join( '\n' );
 
 				var fragmentShader = shader.fragmentShader
-							.replace( '#include <specularmap_fragment>', '' )
-							.replace( 'uniform float roughness;', 'uniform vec3 specular;' )
-							.replace( 'uniform float metalness;', 'uniform float glossiness;' )
-							.replace( '#include <roughnessmap_pars_fragment>', specularMapParsFragmentChunk )
-							.replace( '#include <metalnessmap_pars_fragment>', glossinessMapParsFragmentChunk )
-							.replace( '#include <roughnessmap_fragment>', specularMapFragmentChunk )
-							.replace( '#include <metalnessmap_fragment>', glossinessMapFragmentChunk )
-							.replace( '#include <lights_physical_fragment>', lightPhysicalFragmentChunk );
+					.replace( '#include <specularmap_fragment>', '' )
+					.replace( 'uniform float roughness;', 'uniform vec3 specular;' )
+					.replace( 'uniform float metalness;', 'uniform float glossiness;' )
+					.replace( '#include <roughnessmap_pars_fragment>', specularMapParsFragmentChunk )
+					.replace( '#include <metalnessmap_pars_fragment>', glossinessMapParsFragmentChunk )
+					.replace( '#include <roughnessmap_fragment>', specularMapFragmentChunk )
+					.replace( '#include <metalnessmap_fragment>', glossinessMapFragmentChunk )
+					.replace( '#include <lights_physical_fragment>', lightPhysicalFragmentChunk );
 
 				delete uniforms.roughness;
 				delete uniforms.metalness;
@@ -724,7 +712,7 @@ THREE.GLTFLoader = ( function () {
 
 				uniforms.envMap.value = material.envMap;
 				uniforms.envMapIntensity.value = material.envMapIntensity;
-				uniforms.flipEnvMap.value = ( material.envMap && material.envMap.isCubeTexture ) ? -1 : 1;
+				uniforms.flipEnvMap.value = ( material.envMap && material.envMap.isCubeTexture ) ? - 1 : 1;
 
 				uniforms.refractionRatio.value = material.refractionRatio;
 
@@ -841,8 +829,8 @@ THREE.GLTFLoader = ( function () {
 	};
 
 	var WEBGL_SIDES = {
-		1028: THREE.BackSide,  // Culling front
-		1029: THREE.FrontSide  // Culling back
+		1028: THREE.BackSide, // Culling front
+		1029: THREE.FrontSide // Culling back
 		//1032: THREE.NoSide   // Culling front and back, what to do?
 	};
 
@@ -925,8 +913,10 @@ THREE.GLTFLoader = ( function () {
 
 	function _each( object, callback, thisObj ) {
 
-		if ( !object ) {
+		if ( ! object ) {
+
 			return Promise.resolve();
+
 		}
 
 		var results;
@@ -948,11 +938,11 @@ THREE.GLTFLoader = ( function () {
 
 					if ( value instanceof Promise ) {
 
-						value.then( function( key, value ) {
+						value.then( function ( key, value ) {
 
 							results[ key ] = value;
 
-						}.bind( this, idx ));
+						}.bind( this, idx ) );
 
 					} else {
 
@@ -980,11 +970,11 @@ THREE.GLTFLoader = ( function () {
 
 						if ( value instanceof Promise ) {
 
-							value.then( function( key, value ) {
+							value.then( function ( key, value ) {
 
 								results[ key ] = value;
 
-							}.bind( this, key ));
+							}.bind( this, key ) );
 
 						} else {
 
@@ -1000,11 +990,11 @@ THREE.GLTFLoader = ( function () {
 
 		}
 
-		return Promise.all( fns ).then( function() {
+		return Promise.all( fns ).then( function () {
 
 			return results;
 
-		});
+		} );
 
 	}
 
@@ -1087,7 +1077,7 @@ THREE.GLTFLoader = ( function () {
 	 * @param {GLTF.Primitive} primitiveDef
 	 * @param {Object} dependencies
 	 */
-	function addMorphTargets ( mesh, meshDef, primitiveDef, dependencies ) {
+	function addMorphTargets( mesh, meshDef, primitiveDef, dependencies ) {
 
 		var geometry = mesh.geometry;
 		var material = mesh.material;
@@ -1264,9 +1254,9 @@ THREE.GLTFLoader = ( function () {
 
 			var scenes = [];
 
-			for ( var name in dependencies.scenes ) {
+			for ( var i = 0; i < dependencies.scenes.length; i ++ ) {
 
-				scenes.push( dependencies.scenes[ name ] );
+				scenes.push( dependencies.scenes[ i ] );
 
 			}
 
@@ -1274,18 +1264,22 @@ THREE.GLTFLoader = ( function () {
 
 			var cameras = [];
 
-			for ( var name in dependencies.cameras ) {
+			dependencies.cameras = dependencies.cameras || [];
+
+			for ( var i = 0; i < dependencies.cameras.length; i ++ ) {
 
-				var camera = dependencies.cameras[ name ];
+				var camera = dependencies.cameras[ i ];
 				cameras.push( camera );
 
 			}
 
 			var animations = [];
 
-			for ( var name in dependencies.animations ) {
+			dependencies.animations = dependencies.animations || [];
+
+			for ( var i = 0; i < dependencies.animations.length; i ++ ) {
 
-				animations.push( dependencies.animations[ name ] );
+				animations.push( dependencies.animations[ i ] );
 
 			}
 
@@ -1306,7 +1300,7 @@ THREE.GLTFLoader = ( function () {
 		var cacheKey = type + ':' + index;
 		var dependency = this.cache.get( cacheKey );
 
-		if ( !dependency ) {
+		if ( ! dependency ) {
 
 			var fnName = 'load' + type.charAt( 0 ).toUpperCase() + type.slice( 1 );
 			dependency = this[ fnName ]( index );
@@ -1346,7 +1340,7 @@ THREE.GLTFLoader = ( function () {
 
 			var loader = new THREE.FileLoader();
 			loader.setResponseType( 'arraybuffer' );
-			loader.load( resolveURL( bufferDef.uri, options.path ), resolve);
+			loader.load( resolveURL( bufferDef.uri, options.path ), resolve );
 
 		} );
 
@@ -1626,6 +1620,7 @@ THREE.GLTFLoader = ( function () {
 					materialParams.normalScale.set( material.normalTexture.scale, material.normalTexture.scale );
 
 				}
+
 			}
 
 			if ( material.occlusionTexture !== undefined ) {
@@ -1686,7 +1681,11 @@ THREE.GLTFLoader = ( function () {
 
 				// Normal map textures use OpenGL conventions:
 				// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#materialnormaltexture
-				_material.normalScale.x = -_material.normalScale.x;
+				if ( _material.normalScale ) {
+
+					_material.normalScale.x = - _material.normalScale.x;
+
+				}
 
 				if ( material.extras ) _material.userData = material.extras;
 
@@ -1807,10 +1806,10 @@ THREE.GLTFLoader = ( function () {
 
 				return scope.loadGeometries( primitives ).then( function ( geometries ) {
 
-					for ( var name in primitives ) {
+					for ( var i = 0; i < primitives.length; i ++ ) {
 
-						var primitive = primitives[ name ];
-						var geometry = geometries[ name ];
+						var primitive = primitives[ i ];
+						var geometry = geometries[ i ];
 
 						var material = primitive.material === undefined
 							? createDefaultMaterial()
@@ -1825,14 +1824,23 @@ THREE.GLTFLoader = ( function () {
 
 						}
 
-						if ( geometry.attributes.color !== undefined ) {
+						var useVertexColors = geometry.attributes.color !== undefined;
+						var useFlatShading = geometry.attributes.normal === undefined;
+
+						if ( useVertexColors || useFlatShading ) {
+
+							material = material.clone();
+
+						}
+
+						if ( useVertexColors ) {
 
 							material.vertexColors = THREE.VertexColors;
 							material.needsUpdate = true;
 
 						}
 
-						if ( geometry.attributes.normal === undefined ) {
+						if ( useFlatShading ) {
 
 							material.flatShading = true;
 
@@ -1876,7 +1884,7 @@ THREE.GLTFLoader = ( function () {
 
 						}
 
-						mesh.name = group.name + '_' + name;
+						mesh.name = group.name + '_' + i;
 
 						if ( primitive.targets !== undefined ) {
 
@@ -1913,7 +1921,7 @@ THREE.GLTFLoader = ( function () {
 
 			var params = camera[ camera.type ];
 
-			if ( !params ) {
+			if ( ! params ) {
 
 				console.warn( 'THREE.GLTFLoader: Missing camera parameters.' );
 				return;
@@ -1929,7 +1937,7 @@ THREE.GLTFLoader = ( function () {
 
 			} else if ( camera.type === 'orthographic' ) {
 
-				_camera = new THREE.OrthographicCamera( params.xmag / -2, params.xmag / 2, params.ymag / 2, params.ymag / -2, params.znear, params.zfar );
+				_camera = new THREE.OrthographicCamera( params.xmag / - 2, params.xmag / 2, params.ymag / 2, params.ymag / - 2, params.znear, params.zfar );
 
 			}
 
@@ -1982,9 +1990,9 @@ THREE.GLTFLoader = ( function () {
 
 				var tracks = [];
 
-				for ( var channelId in animation.channels ) {
+				for ( var i = 0; i < animation.channels.length; i ++ ) {
 
-					var channel = animation.channels[ channelId ];
+					var channel = animation.channels[ i ];
 					var sampler = animation.samplers[ channel.sampler ];
 
 					if ( sampler ) {
@@ -2065,10 +2073,10 @@ THREE.GLTFLoader = ( function () {
 							// KeyframeTrack.optimize() will modify given 'times' and 'values'
 							// buffers before creating a truncated copy to keep. Because buffers may
 							// be reused by other tracks, make copies here.
-							for ( var i = 0, il = targetNames.length; i < il; i ++ ) {
+							for ( var j = 0, jl = targetNames.length; j < jl; j ++ ) {
 
 								tracks.push( new TypedKeyframeTrack(
-									targetNames[ i ] + '.' + PATH_PROPERTIES[ target.path ],
+									targetNames[ j ] + '.' + PATH_PROPERTIES[ target.path ],
 									THREE.AnimationUtils.arraySlice( inputAccessor.array, 0 ),
 									THREE.AnimationUtils.arraySlice( outputAccessor.array, 0 ),
 									interpolation
@@ -2170,40 +2178,20 @@ THREE.GLTFLoader = ( function () {
 
 					var node = json.nodes[ nodeId ];
 
-					var meshes;
-
-					if ( node.mesh !== undefined) {
-
-						meshes = [ node.mesh ];
+					var mesh = node.mesh;
 
-					} else if ( node.meshes !== undefined ) {
+					if ( mesh !== undefined ) {
 
-						console.warn( 'THREE.GLTFLoader: Legacy glTF file detected. Nodes may have no more than one mesh.' );
+						var group = dependencies.meshes[ mesh ];
 
-						meshes = node.meshes;
-
-					}
-
-					if ( meshes !== undefined ) {
-
-						for ( var meshId in meshes ) {
-
-							var mesh = meshes[ meshId ];
-							var group = dependencies.meshes[ mesh ];
-
-							if ( group === undefined ) {
-
-								console.warn( 'THREE.GLTFLoader: Could not find node "' + mesh + '".' );
-								continue;
-
-							}
+						if ( group !== undefined ) {
 
 							// do not clone children as they will be replaced anyway
 							var clonedgroup = group.clone( false );
 
-							for ( var childrenId in group.children ) {
+							for ( var i = 0; i < group.children.length; i ++ ) {
 
-								var child = group.children[ childrenId ];
+								var child = group.children[ i ];
 								var originalChild = child;
 
 								// clone Mesh to add to _node
@@ -2299,6 +2287,10 @@ THREE.GLTFLoader = ( function () {
 
 							_node.add( clonedgroup );
 
+						} else {
+
+							console.warn( 'THREE.GLTFLoader: Could not find node "' + mesh + '".' );
+
 						}
 
 					}

+ 61 - 46
examples/js/loaders/ImageBitmapLoader.js

@@ -2,46 +2,59 @@
  * @author thespite / http://clicktorelease.com/
  */
 
- function detectCreateImageBitmap() {
+function detectCreateImageBitmap() {
 
 	var url = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==';
 
-	return new Promise(function (resolve, reject) {
+	return new Promise( function ( resolve, reject ) {
+
+		if ( ! ( 'createImageBitmap' in window ) ) {
 
-		if (!('createImageBitmap' in window)) {
 			reject();
 			return;
+
 		}
 
-		fetch(url).then(function (res) {
+		fetch( url ).then( function ( res ) {
+
 			return res.blob();
-		}).then(function (blob) {
-			Promise.all([
-				createImageBitmap(blob, { imageOrientation: "none", premultiplyAlpha: "none" }),
-				createImageBitmap(blob, { imageOrientation: "flipY", premultiplyAlpha: "none" }),
-				createImageBitmap(blob, { imageOrientation: "none", premultiplyAlpha: "premultiply" }),
-				createImageBitmap(blob, { imageOrientation: "flipY", premultiplyAlpha: "premultiply" })
-			]).then(function (res) {
+
+		} ).then( function ( blob ) {
+
+			Promise.all( [
+				createImageBitmap( blob, { imageOrientation: 'none', premultiplyAlpha: 'none' } ),
+				createImageBitmap( blob, { imageOrientation: 'flipY', premultiplyAlpha: 'none' } ),
+				createImageBitmap( blob, { imageOrientation: 'none', premultiplyAlpha: 'premultiply' } ),
+				createImageBitmap( blob, { imageOrientation: 'flipY', premultiplyAlpha: 'premultiply' } )
+			] ).then( function () {
+
 				resolve();
-			}).catch(function (e) {
+
+			} ).catch( function () {
+
 				reject();
-			});
-		});
-	});
+
+			} );
+
+		} );
+
+	} );
 
 }
 
 var canUseImageBitmap = detectCreateImageBitmap();
-canUseImageBitmap
-.then( function( res ) {
-	console.log( 'createImageBitmap supported' );
-})
-.catch( function( res ) {
-	console.log( 'createImageBitmap not supported' );
-});
+canUseImageBitmap.then( function () {
+
+	console.log( 'THREE.ImageBitmapLoader: createImageBitmap() supported.' );
+
+} ).catch( function () {
 
+	console.warn( 'THREE.ImageBitmapLoader: createImageBitmap() not supported.' );
 
-THREE.ImageBitmapLoader = function (manager) {
+} );
+
+
+THREE.ImageBitmapLoader = function ( manager ) {
 
 	this.manager = manager !== undefined ? manager : THREE.DefaultLoadingManager;
 	this.options = {};
@@ -52,62 +65,64 @@ THREE.ImageBitmapLoader.prototype = {
 
 	constructor: THREE.ImageBitmapLoader,
 
-	setOptions: function setOptions(options) {
+	setOptions: function setOptions( options ) {
 
 		this.options = options;
 		return this;
 
 	},
 
-	load: function load(url, onLoad, onProgress, onError) {
+	load: function load( url, onLoad, onProgress, onError ) {
 
-		if (url === undefined) url = '';
+		if ( url === undefined ) url = '';
 
-		if (this.path !== undefined) url = this.path + url;
+		if ( this.path !== undefined ) url = this.path + url;
 
 		var scope = this;
 
-		var cached = THREE.Cache.get(url);
+		var cached = THREE.Cache.get( url );
 
-		if (cached !== undefined) {
+		if ( cached !== undefined ) {
 
-			scope.manager.itemStart(url);
+			scope.manager.itemStart( url );
 
-			setTimeout(function () {
+			setTimeout( function () {
 
-				if (onLoad) onLoad(cached);
+				if ( onLoad ) onLoad( cached );
 
-				scope.manager.itemEnd(url);
+				scope.manager.itemEnd( url );
 
-			}, 0);
+			}, 0 );
 
 			return cached;
+
 		}
 
-		fetch(url).then(function (res) {
+		fetch( url ).then( function ( res ) {
 
 			return res.blob();
 
-		}).then(function (res) {
+		} ).then( function ( res ) {
+
+			return createImageBitmap( res, scope.options );
 
-			return createImageBitmap(res, scope.options);
+		} ).then( function ( res ) {
 
-		}).then(function (res) {
+			THREE.Cache.add( url, res );
 
-			THREE.Cache.add(url, res);
+			if ( onLoad ) onLoad( res );
 
-			if (onLoad) onLoad(res);
+			scope.manager.itemEnd( url );
 
-			scope.manager.itemEnd(url);
+		} ).catch( function ( e ) {
 
-		}).catch(function (e) {
+			if ( onError ) onError( e );
 
-			if (onError) onError(e);
+			scope.manager.itemEnd( url );
+			scope.manager.itemError( url );
 
-			scope.manager.itemEnd(url);
-			scope.manager.itemError(url);
+		} );
 
-		});
 	}
 
 };

+ 1 - 1
examples/js/loaders/KMZLoader.js

@@ -28,7 +28,7 @@ THREE.KMZLoader.prototype = {
 
 	parse: function ( data ) {
 
-		var zip = new JSZip( data );
+		var zip = new JSZip( data ); // eslint-disable-line no-undef
 
 		// console.log( zip );
 

+ 1155 - 0
examples/js/loaders/LoaderSupport.js

@@ -0,0 +1,1155 @@
+/**
+  * @author Kai Salmen / https://kaisalmen.de
+  * Development repository: https://github.com/kaisalmen/WWOBJLoader
+  */
+
+'use strict';
+
+if ( THREE.LoaderSupport === undefined ) { THREE.LoaderSupport = {} }
+
+/**
+ * Validation functions
+ * @class
+ */
+THREE.LoaderSupport.Validator = {
+	/**
+	 * If given input is null or undefined, false is returned otherwise true.
+	 *
+	 * @param input Anything
+	 * @returns {boolean}
+	 */
+	isValid: function( input ) {
+		return ( input !== null && input !== undefined );
+	},
+	/**
+	 * If given input is null or undefined, the defaultValue is returned otherwise the given input.
+	 *
+	 * @param input Anything
+	 * @param defaultValue Anything
+	 * @returns {*}
+	 */
+	verifyInput: function( input, defaultValue ) {
+		return ( input === null || input === undefined ) ? defaultValue : input;
+	}
+};
+
+
+/**
+ * Callbacks utilized by functions working with WWLoader implementations
+ * @class
+ */
+THREE.LoaderSupport.Callbacks = (function () {
+
+	var Validator = THREE.LoaderSupport.Validator;
+
+	function Callbacks() {
+		this.onProgress = null;
+		this.onMeshAlter = null;
+		this.onLoad = null;
+	}
+
+	/**
+	 * Register callback function that is invoked by internal function "announceProgress" to print feedback.
+	 * @memberOf THREE.LoaderSupport.Callbacks
+	 *
+	 * @param {callback} callbackOnProgress Callback function for described functionality
+	 */
+	Callbacks.prototype.setCallbackOnProgress = function ( callbackOnProgress ) {
+		this.onProgress = Validator.verifyInput( callbackOnProgress, this.onProgress );
+	};
+
+	/**
+	 * Register callback function that is called every time a mesh was loaded.
+	 * Use {@link THREE.LoaderSupport.LoadedMeshUserOverride} for alteration instructions (geometry, material or disregard mesh).
+	 * @memberOf THREE.LoaderSupport.Callbacks
+	 *
+	 * @param {callback} callbackOnMeshAlter Callback function for described functionality
+	 */
+	Callbacks.prototype.setCallbackOnMeshAlter = function ( callbackOnMeshAlter ) {
+		this.onMeshAlter = Validator.verifyInput( callbackOnMeshAlter, this.onMeshAlter );
+	};
+
+	/**
+	 * Register callback function that is called once loading of the complete model is completed.
+	 * @memberOf THREE.LoaderSupport.Callbacks
+	 *
+	 * @param {callback} callbackOnLoad Callback function for described functionality
+	 */
+	Callbacks.prototype.setCallbackOnLoad = function ( callbackOnLoad ) {
+		this.onLoad = Validator.verifyInput( callbackOnLoad, this.onLoad );
+	};
+
+	return Callbacks;
+})();
+
+
+/**
+ * Global callback definition
+ * @class
+ */
+THREE.LoaderSupport.Builder = (function () {
+
+	var Validator = THREE.LoaderSupport.Validator;
+
+	function Builder() {
+		this.callbacks = new THREE.LoaderSupport.Callbacks();
+		this.materials = [];
+		this.materialNames = [];
+		this._createDefaultMaterials();
+	}
+
+	Builder.prototype._createDefaultMaterials = function () {
+		var defaultMaterial = new THREE.MeshStandardMaterial( { color: 0xDCF1FF } );
+		defaultMaterial.name = 'defaultMaterial';
+		if ( ! Validator.isValid( this.materials[ defaultMaterial ] ) ) {
+			this.materials[ defaultMaterial.name ] = defaultMaterial;
+		}
+		this.materialNames.push( defaultMaterial.name );
+
+		var vertexColorMaterial = new THREE.MeshStandardMaterial( { color: 0xDCF1FF } );
+		vertexColorMaterial.name = 'vertexColorMaterial';
+		vertexColorMaterial.vertexColors = THREE.VertexColors;
+		if ( ! Validator.isValid( this.materials[ vertexColorMaterial.name ] ) ) {
+			this.materials[ vertexColorMaterial.name ] = vertexColorMaterial;
+		}
+		this.materialNames.push( vertexColorMaterial.name );
+	};
+
+	/**
+	 * Set materials loaded by any supplier of an Array of {@link THREE.Material}.
+	 * @memberOf THREE.LoaderSupport.Builder
+	 *
+	 * @param {THREE.Material[]} materials Array of {@link THREE.Material}
+	 */
+	Builder.prototype.setMaterials = function ( materials ) {
+		if ( Validator.isValid( materials ) && Object.keys( materials ).length > 0 ) {
+
+			var materialName;
+			for ( materialName in materials ) {
+
+				if ( materials.hasOwnProperty( materialName ) && ! this.materials.hasOwnProperty( materialName) ) {
+					this.materials[ materialName ] = materials[ materialName ];
+				}
+
+			}
+
+			// always reset list of names as they are an array
+			this.materialNames = [];
+			for ( materialName in materials ) this.materialNames.push( materialName );
+
+		}
+	};
+
+	Builder.prototype._setCallbacks = function ( callbackOnProgress, callbackOnMeshAlter, callbackOnLoad ) {
+		this.callbacks.setCallbackOnProgress( callbackOnProgress );
+		this.callbacks.setCallbackOnMeshAlter( callbackOnMeshAlter );
+		this.callbacks.setCallbackOnLoad( callbackOnLoad );
+	};
+
+	/**
+	 * Builds one or multiple meshes from the data described in the payload (buffers, params, material info,
+	 *
+	 * @param {Object} payload buffers, params, materials
+	 * @returns {THREE.Mesh[]} mesh Array of {@link THREE.Mesh}
+	 */
+	Builder.prototype.buildMeshes = function ( payload ) {
+		var meshName = payload.params.meshName;
+
+		var bufferGeometry = new THREE.BufferGeometry();
+		bufferGeometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( payload.buffers.vertices ), 3 ) );
+		if ( Validator.isValid( payload.buffers.indices ) ) {
+
+			bufferGeometry.setIndex( new THREE.BufferAttribute( new Uint32Array( payload.buffers.indices ), 1 ));
+
+		}
+		var haveVertexColors = Validator.isValid( payload.buffers.colors );
+		if ( haveVertexColors ) {
+
+			bufferGeometry.addAttribute( 'color', new THREE.BufferAttribute( new Float32Array( payload.buffers.colors ), 3 ) );
+
+		}
+		if ( Validator.isValid( payload.buffers.normals ) ) {
+
+			bufferGeometry.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( payload.buffers.normals ), 3 ) );
+
+		} else {
+
+			bufferGeometry.computeVertexNormals();
+
+		}
+		if ( Validator.isValid( payload.buffers.uvs ) ) {
+
+			bufferGeometry.addAttribute( 'uv', new THREE.BufferAttribute( new Float32Array( payload.buffers.uvs ), 2 ) );
+
+		}
+
+		var materialDescriptions = payload.materials.materialDescriptions;
+		var materialDescription;
+		var material;
+		var materialName;
+		var createMultiMaterial = payload.materials.multiMaterial;
+		var multiMaterials = [];
+
+		var key;
+		for ( key in materialDescriptions ) {
+
+			materialDescription = materialDescriptions[ key ];
+			material = this.materials[ materialDescription.name ];
+			material = Validator.verifyInput( material, this.materials[ 'defaultMaterial' ] );
+			if ( haveVertexColors ) {
+
+				if ( material.hasOwnProperty( 'vertexColors' ) ) {
+
+					materialName = material.name + '_vertexColor';
+					var materialClone = this.materials[ materialName ];
+					if ( ! Validator.isValid( materialClone ) ) {
+
+						materialClone = material.clone();
+						materialClone.name = materialName;
+						materialClone.vertexColors = THREE.VertexColors;
+						this.materials[ materialName ] = materialClone;
+
+					}
+					material = materialClone;
+
+				} else {
+
+					material = this.materials[ 'vertexColorMaterial' ];
+				}
+
+			}
+
+			if ( materialDescription.flat ) {
+
+				materialName = material.name + '_flat';
+				var materialClone = this.materials[ materialName ];
+				if ( ! Validator.isValid( materialClone ) ) {
+
+					materialClone = material.clone();
+					materialClone.name = materialName;
+					materialClone.flatShading = true;
+					this.materials[ materialName ] = materialClone;
+
+				}
+				material = materialClone;
+
+			}
+			if ( createMultiMaterial ) multiMaterials.push( material );
+
+		}
+		if ( createMultiMaterial ) {
+
+			material = multiMaterials;
+			var materialGroups = payload.materials.materialGroups;
+			var materialGroup;
+			for ( key in materialGroups ) {
+
+				materialGroup = materialGroups[ key ];
+				bufferGeometry.addGroup( materialGroup.start, materialGroup.count, materialGroup.index );
+
+			}
+
+		}
+
+		var meshes = [];
+		var mesh;
+		var callbackOnMeshAlter = this.callbacks.onMeshAlter;
+		var callbackOnMeshAlterResult;
+		var useOrgMesh = true;
+		if ( Validator.isValid( callbackOnMeshAlter ) ) {
+
+			callbackOnMeshAlterResult = callbackOnMeshAlter( meshName, bufferGeometry, material );
+			if ( Validator.isValid( callbackOnMeshAlterResult ) ) {
+
+				if ( ! callbackOnMeshAlterResult.isDisregardMesh() && callbackOnMeshAlterResult.providesAlteredMeshes() ) {
+
+					for ( var i in callbackOnMeshAlterResult.meshes ) {
+
+						meshes.push( callbackOnMeshAlterResult.meshes[ i ] );
+
+					}
+
+				}
+				useOrgMesh = false;
+
+			}
+
+		}
+		if ( useOrgMesh ) {
+
+			mesh = new THREE.Mesh( bufferGeometry, material );
+			mesh.name = meshName;
+			meshes.push( mesh );
+
+		}
+
+		var progressMessage;
+		if ( Validator.isValid( meshes ) && meshes.length > 0 ) {
+
+			var meshNames = [];
+			for ( var i in meshes ) {
+
+				mesh = meshes[ i ];
+				meshNames[ i ] = mesh.name;
+
+			}
+			progressMessage = 'Adding mesh(es) (' + meshNames.length + ': ' + meshNames + ') from input mesh: ' + meshName;
+
+		} else {
+
+			progressMessage = 'Not adding mesh: ' + meshName;
+
+		}
+		var callbackOnProgress = this.callbacks.onProgress;
+		if ( Validator.isValid( callbackOnProgress ) ) callbackOnProgress( progressMessage );
+
+		return meshes;
+	};
+
+	return Builder;
+})();
+
+
+/**
+ * Global callback definition
+ * @class
+ */
+THREE.LoaderSupport.Commons = (function () {
+
+	var Validator = THREE.LoaderSupport.Validator;
+
+	function Commons( manager ) {
+		this.manager = Validator.verifyInput( manager, THREE.DefaultLoadingManager );
+
+		this.modelName = '';
+		this.instanceNo = 0;
+		this.path = '';
+		this.debug = false;
+		this.useIndices = false;
+		this.disregardNormals = false;
+
+		this.loaderRootNode = new THREE.Group();
+		this.builder = new THREE.LoaderSupport.Builder();
+		this.callbacks = new THREE.LoaderSupport.Callbacks();
+	};
+
+	Commons.prototype._applyPrepData = function ( prepData ) {
+		if ( Validator.isValid( prepData ) ) {
+
+			this.setModelName( prepData.modelName );
+			this.setStreamMeshesTo( prepData.streamMeshesTo );
+			this.builder.setMaterials( prepData.materials );
+			this.setUseIndices( prepData.useIndices );
+			this.setDisregardNormals( prepData.disregardNormals );
+
+			this._setCallbacks( prepData.getCallbacks().onProgress, prepData.getCallbacks().onMeshAlter, prepData.getCallbacks().onLoad );
+		}
+	};
+
+	Commons.prototype._setCallbacks = function ( callbackOnProgress, callbackOnMeshAlter, callbackOnLoad ) {
+		this.callbacks.setCallbackOnProgress( callbackOnProgress );
+		this.callbacks.setCallbackOnMeshAlter( callbackOnMeshAlter );
+		this.callbacks.setCallbackOnLoad( callbackOnLoad );
+
+		this.builder._setCallbacks( callbackOnProgress, callbackOnMeshAlter, callbackOnLoad );
+	};
+
+	Commons.prototype.setModelName = function ( modelName ) {
+		this.modelName = Validator.verifyInput( modelName, this.modelName );
+	};
+
+	/**
+	 * The URL of the base path
+	 * @param {string} path
+	 */
+	Commons.prototype.setPath = function ( path ) {
+		this.path = Validator.verifyInput( path, this.path );
+	};
+
+	/**
+	 * Allows to set debug mode.
+	 * @memberOf THREE.LoaderSupport.Commons
+	 *
+	 * @param {boolean} enabled
+	 */
+	Commons.prototype.setDebug = function ( enabled ) {
+		this.debug = enabled;
+	};
+
+	/**
+	 * Set the node where the loaded objects will be attached directly.
+	 * @memberOf THREE.LoaderSupport.Commons
+	 *
+	 * @param {THREE.Object3D} streamMeshesTo Attached scenegraph object where meshes will be attached live
+	 */
+	Commons.prototype.setStreamMeshesTo = function ( streamMeshesTo ) {
+		this.loaderRootNode = Validator.verifyInput( streamMeshesTo, this.loaderRootNode );
+	};
+
+	/**
+	 * Set materials loaded by MTLLoader or any other supplier of an Array of {@link THREE.Material}.
+	 * @memberOf THREE.LoaderSupport.Commons
+	 *
+	 * @param {THREE.Material[]} materials Array of {@link THREE.Material}
+	 */
+	Commons.prototype.setMaterials = function ( materials ) {
+		this.builder.setMaterials( materials );
+	};
+
+	/**
+	 * Tells whether indices should be used
+	 * @memberOf THREE.LoaderSupport.Commons
+	 *
+	 * @param {boolean} useIndices=false Default is false
+	 */
+	Commons.prototype.setUseIndices = function ( useIndices ) {
+		this.useIndices = useIndices === true;
+	};
+
+	/**
+	 * Tells whether normals should be completely disregarded
+	 * @memberOf THREE.LoaderSupport.Commons
+	 *
+	 * @param {boolean} disregardNormals=false Default is false
+	 */
+	Commons.prototype.setDisregardNormals = function ( disregardNormals ) {
+		this.disregardNormals = disregardNormals === true;
+	};
+
+	/**
+	 * Announce feedback which is give to the registered callbacks and logged if debug is enabled
+	 * @memberOf THREE.LoaderSupport.Commons
+	 *
+	 * @param baseText
+	 * @param text
+	 */
+	Commons.prototype.onProgress = function ( baseText, text ) {
+		var content = Validator.isValid( baseText ) ? baseText: '';
+		content = Validator.isValid( text ) ? content + ' ' + text : content;
+
+		if ( Validator.isValid( this.callbacks.onProgress ) ) this.callbacks.onProgress( content, this.modelName, this.instanceNo );
+
+		if ( this.debug ) console.log( content );
+	};
+
+	return Commons;
+})();
+
+
+/**
+ * Object to return by {@link THREE.LoaderSupport.Commons}.callbacks.meshLoaded.
+ * Used to disregard a certain mesh or to return one to many created meshes.
+ * @class
+ *
+ * @param {boolean} disregardMesh=false Tell implementation to completely disregard this mesh
+ */
+THREE.LoaderSupport.LoadedMeshUserOverride = (function () {
+
+	function LoadedMeshUserOverride( disregardMesh, alteredMesh ) {
+		this.disregardMesh = disregardMesh === true;
+		this.alteredMesh = alteredMesh === true;
+		this.meshes = [];
+	}
+
+	/**
+	 * Add a mesh created within callback.
+	 *
+	 * @memberOf THREE.OBJLoader2.LoadedMeshUserOverride
+	 *
+	 * @param {THREE.Mesh} mesh
+	 */
+	LoadedMeshUserOverride.prototype.addMesh = function ( mesh ) {
+		this.meshes.push( mesh );
+	};
+
+	/**
+	 * Answers if mesh shall be disregarded completely.
+	 *
+	 * @returns {boolean}
+	 */
+	LoadedMeshUserOverride.prototype.isDisregardMesh = function () {
+		return this.disregardMesh;
+	};
+
+	/**
+	 * Answers if new mesh(es) were created.
+	 *
+	 * @returns {boolean}
+	 */
+	LoadedMeshUserOverride.prototype.providesAlteredMeshes = function () {
+		return this.alteredMesh;
+	};
+
+	return LoadedMeshUserOverride;
+})();
+
+
+/**
+ * A resource description used by {@link THREE.LoaderSupport.PrepData} and others.
+ * @class
+ *
+ * @param {string} url URL to the file
+ * @param {string} extension The file extension (type)
+ */
+THREE.LoaderSupport.ResourceDescriptor = (function () {
+
+	var Validator = THREE.LoaderSupport.Validator;
+
+	function ResourceDescriptor( url, extension ) {
+		var urlParts = url.split( '/' );
+
+		if ( urlParts.length < 2 ) {
+
+			this.path = null;
+			this.name = this.name = url;
+			this.url = url;
+
+		} else {
+
+			this.path = Validator.verifyInput( urlParts.slice( 0, urlParts.length - 1).join( '/' ) + '/', null );
+			this.name = Validator.verifyInput( urlParts[ urlParts.length - 1 ], null );
+			this.url = url;
+
+		}
+		this.extension = Validator.verifyInput( extension, "default" );
+		this.extension = this.extension.trim();
+		this.content = null;
+	}
+
+	/**
+	 * Set the content of this resource (String)
+	 * @memberOf THREE.LoaderSupport.ResourceDescriptor
+	 *
+	 * @param {Object} content The file content as arraybuffer or text
+	 */
+	ResourceDescriptor.prototype.setContent = function ( content ) {
+		this.content = Validator.verifyInput( content, null );
+	};
+
+	return ResourceDescriptor;
+})();
+
+
+/**
+ * Base class for configuration of prepareRun when using {@link THREE.LoaderSupport.WorkerSupport}.
+ * @class
+ */
+THREE.LoaderSupport.PrepData = (function () {
+
+	var Validator = THREE.LoaderSupport.Validator;
+
+	function PrepData( modelName ) {
+		this.modelName = Validator.verifyInput( modelName, '' );
+		this.resources = [];
+		this.streamMeshesTo = null;
+		this.materialPerSmoothingGroup = false;
+		this.useIndices = false;
+		this.disregardNormals = false;
+		this.callbacks = new THREE.LoaderSupport.Callbacks();
+		this.crossOrigin;
+		this.useAsync = false;
+	}
+
+	/**
+	 * {@link THREE.Object3D} where meshes will be attached.
+	 * @memberOf THREE.LoaderSupport.PrepData
+	 *
+	 * @param {THREE.Object3D} streamMeshesTo Scene graph object
+	 */
+	PrepData.prototype.setStreamMeshesTo = function ( streamMeshesTo ) {
+		this.streamMeshesTo = Validator.verifyInput( streamMeshesTo, null );
+	};
+
+	/**
+	 * Tells whether a material shall be created per smoothing group
+	 * @memberOf THREE.LoaderSupport.PrepData
+	 *
+	 * @param {boolean} materialPerSmoothingGroup
+	 */
+	PrepData.prototype.setMaterialPerSmoothingGroup = function ( materialPerSmoothingGroup ) {
+		this.materialPerSmoothingGroup = materialPerSmoothingGroup;
+	};
+
+	/**
+	 * Tells whether indices should be used
+	 * @memberOf THREE.LoaderSupport.PrepData
+	 *
+	 * @param {boolean} useIndices=false Default is false
+	 */
+	PrepData.prototype.setUseIndices = function ( useIndices ) {
+		this.useIndices = useIndices === true;
+	};
+
+
+	/**
+	 * Tells whether normals should be completely disregarded
+	 * @memberOf THREE.LoaderSupport.PrepData
+	 *
+	 * @param {boolean} disregardNormals=false Default is false
+	 */
+	PrepData.prototype.setDisregardNormals = function ( disregardNormals ) {
+		this.disregardNormals = disregardNormals === true;
+	};
+
+	/**
+	 * Returns all callbacks as {@link THREE.LoaderSupport.Callbacks}
+	 * @memberOf THREE.LoaderSupport.PrepData
+	 *
+	 * @returns {THREE.LoaderSupport.Callbacks}
+	 */
+	PrepData.prototype.getCallbacks = function () {
+		return this.callbacks;
+	};
+
+	/**
+	 * Sets the CORS string to be used.
+	 * @memberOf THREE.LoaderSupport.PrepData
+	 *
+	 * @param {string} crossOrigin CORS value
+	 */
+	PrepData.prototype.setCrossOrigin = function ( crossOrigin ) {
+		this.crossOrigin = crossOrigin;
+	};
+
+	/**
+	 * Add a resource description
+	 * @memberOf THREE.LoaderSupport.PrepData
+	 *
+	 * @param {THREE.LoaderSupport.ResourceDescriptor} The resource description
+	 */
+	PrepData.prototype.addResource = function ( resource ) {
+		this.resources.push( resource );
+	};
+
+	/**
+	 *
+	 * @param {boolean} useAsync
+	 */
+	PrepData.prototype.setUseAsync = function ( useAsync ) {
+		this.useAsync = useAsync === true;
+	};
+
+	/**
+	 * Clones this object and returns it afterwards.
+	 *
+	 * @returns {@link THREE.LoaderSupport.PrepData}
+	 */
+	PrepData.prototype.clone = function () {
+		var clone = new THREE.LoaderSupport.PrepData( this.modelName );
+		clone.resources = this.resources;
+		clone.streamMeshesTo = this.streamMeshesTo;
+		clone.materialPerSmoothingGroup = this.materialPerSmoothingGroup;
+		clone.useIndices = this.useIndices;
+		clone.disregardNormals = this.disregardNormals;
+		clone.callbacks = this.callbacks;
+		clone.crossOrigin = this.crossOrigin;
+		clone.useAsync = this.useAsync;
+		return clone;
+	};
+
+	return PrepData;
+})();
+
+THREE.LoaderSupport.WorkerRunnerRefImpl = (function () {
+
+	function WorkerRunnerRefImpl() {
+		var scope = this;
+		var scopedRunner = function( event ) {
+			scope.run( event.data );
+		};
+		self.addEventListener( 'message', scopedRunner, false );
+	}
+
+	WorkerRunnerRefImpl.prototype.applyProperties = function ( parser, params ) {
+		var property, funcName, values;
+		for ( property in params ) {
+			funcName = 'set' + property.substring( 0, 1 ).toLocaleUpperCase() + property.substring( 1 );
+			values = params[ property ];
+			if ( parser.hasOwnProperty( property ) ) {
+
+				if ( typeof parser[ funcName ] === 'function' ) {
+
+					parser[ funcName ]( values );
+
+				} else {
+
+					parser[ property ] = values;
+
+				}
+			}
+		}
+	};
+
+	WorkerRunnerRefImpl.prototype.run = function ( payload ) {
+		if ( payload.cmd === 'run' ) {
+
+			console.log( 'WorkerRunner: Starting Run...' );
+
+			var callbacks = {
+				callbackBuilder: function ( payload ) {
+					self.postMessage( payload );
+				},
+				callbackProgress: function ( message ) {
+					console.log( 'WorkerRunner: progress: ' + message );
+				}
+			};
+
+			// Parser is expected to be named as such
+			var parser = new Parser();
+			this.applyProperties( parser, payload.params );
+			this.applyProperties( parser, payload.materials );
+			this.applyProperties( parser, callbacks );
+			parser.parse( payload.buffers.input );
+
+			console.log( 'WorkerRunner: Run complete!' );
+
+			callbacks.callbackBuilder( {
+				cmd: 'complete',
+				msg: 'WorkerRunner completed run.'
+			} );
+
+		} else {
+
+			console.error( 'WorkerRunner: Received unknown command: ' + payload.cmd );
+
+		}
+	};
+
+	return WorkerRunnerRefImpl;
+})();
+
+THREE.LoaderSupport.WorkerSupport = (function () {
+
+	var WORKER_SUPPORT_VERSION = '1.0.0-dev';
+
+	var Validator = THREE.LoaderSupport.Validator;
+
+	function WorkerSupport() {
+		console.log( "Using THREE.LoaderSupport.WorkerSupport version: " + WORKER_SUPPORT_VERSION );
+
+		// check worker support first
+		if ( window.Worker === undefined ) throw "This browser does not support web workers!";
+		if ( window.Blob === undefined  ) throw "This browser does not support Blob!";
+		if ( typeof window.URL.createObjectURL !== 'function'  ) throw "This browser does not support Object creation from URL!";
+
+		this.worker = null;
+		this.workerCode = null;
+		this.running = false;
+		this.terminateRequested = false;
+
+		this.callbacks = {
+			builder: null,
+			onLoad: null
+		};
+	}
+
+	WorkerSupport.prototype.validate = function ( functionCodeBuilder, forceWorkerReload, runnerImpl ) {
+		this.running = false;
+		if ( forceWorkerReload ) {
+
+			this.worker = null;
+			this.workerCode = null;
+			this.callbacks.builder = null;
+			this.callbacks.onLoad = null;
+
+		}
+
+		if ( ! Validator.isValid( this.worker ) ) {
+
+			console.log( 'WorkerSupport: Building worker code...' );
+			console.time( 'buildWebWorkerCode' );
+
+			var workerRunner;
+			if ( Validator.isValid( runnerImpl ) ) {
+
+				console.log( 'WorkerSupport: Using "' + runnerImpl.name + '" as Runncer class for worker.');
+				workerRunner = runnerImpl;
+
+			} else {
+
+				console.log( 'WorkerSupport: Using DEFAULT "THREE.LoaderSupport.WorkerRunnerRefImpl" as Runncer class for worker.');
+				workerRunner = THREE.LoaderSupport.WorkerRunnerRefImpl;
+
+			}
+			this.workerCode = functionCodeBuilder( buildObject, buildSingelton );
+			this.workerCode += buildSingelton( workerRunner.name, workerRunner.name, workerRunner );
+			this.workerCode += 'new ' + workerRunner.name + '();\n\n';
+
+			var blob = new Blob( [ this.workerCode ], { type: 'text/plain' } );
+			this.worker = new Worker( window.URL.createObjectURL( blob ) );
+			console.timeEnd( 'buildWebWorkerCode' );
+
+			var scope = this;
+			var receiveWorkerMessage = function ( e ) {
+				var payload = e.data;
+
+				switch ( payload.cmd ) {
+					case 'meshData':
+						scope.callbacks.builder( payload );
+						break;
+
+					case 'complete':
+						scope.callbacks.onLoad( payload.msg );
+						scope.running = false;
+
+						if ( scope.terminateRequested ) {
+
+							console.log( 'WorkerSupport: Run is complete. Terminating application on request!' );
+							scope.terminateWorker();
+
+						}
+						break;
+
+					default:
+						console.error( 'WorkerSupport: Received unknown command: ' + payload.cmd );
+						break;
+
+				}
+			};
+			this.worker.addEventListener( 'message', receiveWorkerMessage, false );
+
+		}
+	};
+
+	WorkerSupport.prototype.terminateWorker = function () {
+		if ( Validator.isValid( this.worker ) ) {
+			this.worker.terminate();
+		}
+		this.worker = null;
+		this.workerCode = null;
+	};
+
+	WorkerSupport.prototype.setCallbacks = function ( builder, onLoad ) {
+		this.callbacks = {
+			builder: builder,
+			onLoad: onLoad
+		};
+	};
+
+	var buildObject = function ( fullName, object ) {
+		var objectString = fullName + ' = {\n';
+		var part;
+		for ( var name in object ) {
+
+			part = object[ name ];
+			if ( typeof( part ) === 'string' || part instanceof String ) {
+
+				part = part.replace( '\n', '\\n' );
+				part = part.replace( '\r', '\\r' );
+				objectString += '\t' + name + ': "' + part + '",\n';
+
+			} else if ( part instanceof Array ) {
+
+				objectString += '\t' + name + ': [' + part + '],\n';
+
+			} else if ( Number.isInteger( part ) ) {
+
+				objectString += '\t' + name + ': ' + part + ',\n';
+
+			} else if ( typeof part === 'function' ) {
+
+				objectString += '\t' + name + ': ' + part + ',\n';
+
+			}
+
+		}
+		objectString += '}\n\n';
+
+		return objectString;
+	};
+
+	var buildSingelton = function ( fullName, internalName, object ) {
+		var objectString = fullName + ' = (function () {\n\n';
+		objectString += '\t' + object.prototype.constructor.toString() + '\n\n';
+
+		var funcString;
+		var objectPart;
+		for ( var name in object.prototype ) {
+
+			objectPart = object.prototype[ name ];
+			if ( typeof objectPart === 'function' ) {
+
+				funcString = objectPart.toString();
+				objectString += '\t' + internalName + '.prototype.' + name + ' = ' + funcString + ';\n\n';
+
+			}
+
+		}
+		objectString += '\treturn ' + internalName + ';\n';
+		objectString += '})();\n\n';
+
+		return objectString;
+	};
+
+	WorkerSupport.prototype.setTerminateRequested = function ( terminateRequested ) {
+		this.terminateRequested = terminateRequested === true;
+	};
+
+	WorkerSupport.prototype.run = function ( messageObject ) {
+		if ( ! Validator.isValid( this.callbacks.builder ) ) throw 'Unable to run as no "builder" callback is set.';
+		if ( ! Validator.isValid( this.callbacks.onLoad ) ) throw 'Unable to run as no "onLoad" callback is set.';
+		if ( Validator.isValid( this.worker ) ) {
+			this.running = true;
+			this.worker.postMessage( messageObject );
+		}
+	};
+
+	return WorkerSupport;
+})();
+
+/**
+ * Orchestrate loading of multiple OBJ files/data from an instruction queue with a configurable amount of workers (1-16).
+ * Workflow:
+ *   prepareWorkers
+ *   enqueueForRun
+ *   processQueue
+ *   deregister
+ *
+ * @class
+ */
+THREE.LoaderSupport.WorkerDirector = (function () {
+
+	var LOADER_WORKER_DIRECTOR_VERSION = '1.0.0-dev';
+
+	var Validator = THREE.LoaderSupport.Validator;
+
+	var MAX_WEB_WORKER = 16;
+	var MAX_QUEUE_SIZE = 8192;
+
+	function WorkerDirector( classDef ) {
+		console.log( "Using THREE.LoaderSupport.WorkerDirector version: " + LOADER_WORKER_DIRECTOR_VERSION );
+
+		this.maxQueueSize = MAX_QUEUE_SIZE ;
+		this.maxWebWorkers = MAX_WEB_WORKER;
+		this.crossOrigin = null;
+
+		if ( ! Validator.isValid( classDef ) ) throw 'Provided invalid classDef: ' + classDef;
+
+		this.workerDescription = {
+			classDef: classDef,
+			globalCallbacks: {},
+			workerSupports: []
+		};
+		this.objectsCompleted = 0;
+		this.instructionQueue = [];
+	}
+
+	/**
+	 * Returns the maximum length of the instruction queue.
+	 * @memberOf THREE.LoaderSupport.WorkerDirector
+	 *
+	 * @returns {number}
+	 */
+	WorkerDirector.prototype.getMaxQueueSize = function () {
+		return this.maxQueueSize;
+	};
+
+	/**
+	 * Returns the maximum number of workers.
+	 * @memberOf THREE.LoaderSupport.WorkerDirector
+	 *
+	 * @returns {number}
+	 */
+	WorkerDirector.prototype.getMaxWebWorkers = function () {
+		return this.maxWebWorkers;
+	};
+
+	/**
+	 * Sets the CORS string to be used.
+	 * @memberOf THREE.LoaderSupport.WorkerDirector
+	 *
+	 * @param {string} crossOrigin CORS value
+	 */
+	WorkerDirector.prototype.setCrossOrigin = function ( crossOrigin ) {
+		this.crossOrigin = crossOrigin;
+	};
+
+	/**
+	 * Create or destroy workers according limits. Set the name and register callbacks for dynamically created web workers.
+	 * @memberOf THREE.LoaderSupport.WorkerDirector
+	 *
+	 * @param {THREE.OBJLoader2.WWOBJLoader2.PrepDataCallbacks} globalCallbacks  Register global callbacks used by all web workers
+	 * @param {number} maxQueueSize Set the maximum size of the instruction queue (1-1024)
+	 * @param {number} maxWebWorkers Set the maximum amount of workers (1-16)
+	 */
+	WorkerDirector.prototype.prepareWorkers = function ( globalCallbacks, maxQueueSize, maxWebWorkers ) {
+		if ( Validator.isValid( globalCallbacks ) ) this.workerDescription.globalCallbacks = globalCallbacks;
+		this.maxQueueSize = Math.min( maxQueueSize, MAX_QUEUE_SIZE );
+		this.maxWebWorkers = Math.min( maxWebWorkers, MAX_WEB_WORKER );
+		this.objectsCompleted = 0;
+		this.instructionQueue = [];
+
+		var start = this.workerDescription.workerSupports.length;
+		var i;
+		if ( start < this.maxWebWorkers ) {
+
+			for ( i = start; i < this.maxWebWorkers; i++ ) {
+
+				this.workerDescription.workerSupports[ i ] = {
+					workerSupport: new THREE.LoaderSupport.WorkerSupport(),
+					loader: null
+				};
+
+			}
+
+		} else {
+
+			for ( i = start - 1; i >= this.maxWebWorkers; i-- ) {
+
+				this.workerDescription.workerSupports[ i ].workerSupport.setRequestTerminate( true );
+				this.workerDescription.workerSupports.pop();
+
+			}
+		}
+	};
+
+	/**
+	 * Store run instructions in internal instructionQueue.
+	 * @memberOf THREE.LoaderSupport.WorkerDirector
+	 *
+	 * @param {Object} prepData Either {@link THREE.LoaderSupport.PrepData}
+	 */
+	WorkerDirector.prototype.enqueueForRun = function ( prepData ) {
+		if ( this.instructionQueue.length < this.maxQueueSize ) {
+			this.instructionQueue.push( prepData );
+		}
+	};
+
+	/**
+	 * Process the instructionQueue until it is depleted.
+	 * @memberOf THREE.LoaderSupport.WorkerDirector
+	 */
+	WorkerDirector.prototype.processQueue = function () {
+		if ( this.instructionQueue.length === 0 ) return;
+
+		var length = Math.min( this.maxWebWorkers, this.instructionQueue.length );
+		for ( var i = 0; i < length; i++ ) {
+
+			this._kickWorkerRun( this.instructionQueue[ 0 ], i );
+			this.instructionQueue.shift();
+
+		}
+	};
+
+	WorkerDirector.prototype._kickWorkerRun = function( prepData, workerInstanceNo ) {
+		var scope = this;
+		var directorOnLoad = function ( sceneGraphBaseNode, modelName, instanceNo ) {
+			scope.objectsCompleted++;
+
+			var nextPrepData = scope.instructionQueue[ 0 ];
+			if ( Validator.isValid( nextPrepData ) ) {
+
+				scope.instructionQueue.shift();
+				console.log( '\nAssigning next item from queue to worker (queue length: ' + scope.instructionQueue.length + ')\n\n' );
+				scope._kickWorkerRun( nextPrepData, instanceNo );
+
+			} else if ( scope.instructionQueue.length === 0 ) {
+
+				scope.deregister();
+
+			}
+		};
+
+		var prepDataCallbacks = prepData.getCallbacks();
+		var globalCallbacks = this.workerDescription.globalCallbacks;
+		var wrapperOnLoad = function ( sceneGraphBaseNode, modelName, instanceNo ) {
+			if ( Validator.isValid( globalCallbacks.onLoad ) ) {
+
+				globalCallbacks.onLoad( sceneGraphBaseNode, modelName, instanceNo );
+
+			}
+
+			if ( Validator.isValid( prepDataCallbacks.onLoad ) ) {
+
+				prepDataCallbacks.onLoad( sceneGraphBaseNode, modelName, instanceNo );
+
+			}
+			directorOnLoad( sceneGraphBaseNode, modelName, instanceNo );
+		};
+
+		var wrapperOnProgress = function ( content, modelName, instanceNo ) {
+			if ( Validator.isValid( globalCallbacks.onProgress ) ) {
+
+				globalCallbacks.onProgress( content, modelName, instanceNo );
+			}
+
+			if ( Validator.isValid( prepDataCallbacks.onProgress ) ) {
+
+				prepDataCallbacks.onProgress( content, modelName, instanceNo );
+
+			}
+		};
+
+		var wrapperOnMeshAlter = function ( meshName, bufferGeometry, material ) {
+			if ( Validator.isValid( globalCallbacks.onMeshAlter ) ) {
+
+				globalCallbacks.onMeshAlter( meshName, bufferGeometry, material );
+			}
+
+			if ( Validator.isValid( prepDataCallbacks.onMeshAlter ) ) {
+
+				prepDataCallbacks.onMeshAlter( meshName, bufferGeometry, material );
+
+			}
+		};
+
+		var supportTuple = this.workerDescription.workerSupports[ workerInstanceNo ];
+		supportTuple.loader = this._buildLoader( workerInstanceNo );
+
+		var updatedCallbacks = new THREE.LoaderSupport.Callbacks();
+		updatedCallbacks.setCallbackOnLoad( wrapperOnLoad );
+		updatedCallbacks.setCallbackOnProgress( wrapperOnProgress );
+		updatedCallbacks.setCallbackOnMeshAlter( wrapperOnMeshAlter );
+		prepData.callbacks = updatedCallbacks;
+
+		supportTuple.loader.run( prepData, supportTuple.workerSupport );
+	};
+
+	WorkerDirector.prototype._buildLoader = function ( instanceNo ) {
+		var classDef = this.workerDescription.classDef;
+		var loader = Object.create( classDef.prototype );
+		this.workerDescription.classDef.call( loader );
+
+		// verify that all required functions are implemented
+		if ( ! loader.hasOwnProperty( 'instanceNo' ) ) throw classDef.name + ' has no property "instanceNo".';
+		loader.instanceNo = instanceNo;
+
+		if ( ! loader.hasOwnProperty( 'workerSupport' ) ) {
+
+			throw classDef.name + ' has no property "workerSupport".';
+
+		} else if ( ! classDef.workerSupport instanceof THREE.LoaderSupport.WorkerSupport ) {
+
+			throw classDef.name + '.workerSupport is not of type "THREE.LoaderSupport.WorkerSupport".';
+
+		}
+		if ( typeof loader.run !== 'function'  ) throw classDef.name + ' has no function "run".';
+
+		return loader;
+	};
+
+	/**
+	 * Terminate all workers.
+	 * @memberOf THREE.LoaderSupport.WorkerDirector
+	 */
+	WorkerDirector.prototype.deregister = function () {
+		console.log( 'WorkerDirector received the deregister call. Terminating all workers!' );
+
+		for ( var i = 0, length = this.workerDescription.workerSupports.length; i < length; i++ ) {
+
+			var supportTuple = this.workerDescription.workerSupports[ i ];
+			supportTuple.workerSupport.setTerminateRequested( true );
+			console.log( 'Requested termination of worker.' );
+
+			var loaderCallbacks = supportTuple.loader.callbacks;
+			if ( Validator.isValid( loaderCallbacks.onProgress ) ) loaderCallbacks.onProgress( '' );
+
+		}
+
+		this.workerDescription.workerSupports = [];
+		this.instructionQueue = [];
+	};
+
+	return WorkerDirector;
+
+})();

+ 104 - 104
examples/js/loaders/MMDLoader.js

@@ -137,7 +137,7 @@ THREE.MMDLoader.prototype.loadVmds = function ( urls, callback, onProgress, onEr
 	var vmds = [];
 	urls = urls.slice();
 
-	function run () {
+	function run() {
 
 		var url = urls.shift();
 
@@ -195,7 +195,7 @@ THREE.MMDLoader.prototype.loadVpd = function ( url, callback, onProgress, onErro
 THREE.MMDLoader.prototype.parseModel = function ( buffer, modelExtension ) {
 
 	// Should I judge from model data header?
-	switch( modelExtension.toLowerCase() ) {
+	switch ( modelExtension.toLowerCase() ) {
 
 		case 'pmd':
 			return this.parsePmd( buffer );
@@ -310,7 +310,7 @@ THREE.MMDLoader.prototype.pourVmdIntoCamera = function ( camera, vmd, name ) {
 				interpolations = interpolations.slice();
 
 				var stride = values.length / times.length;
-				var interpolateStride = ( stride === 3 ) ? 12 : 4;  // 3: Vector3, others: Quaternion or Number
+				var interpolateStride = ( stride === 3 ) ? 12 : 4; // 3: Vector3, others: Quaternion or Number
 
 				var index = 1;
 
@@ -358,7 +358,7 @@ THREE.MMDLoader.prototype.pourVmdIntoCamera = function ( camera, vmd, name ) {
 
 		};
 
-		for ( var i = 0; i < orderedMotions.length; i++ ) {
+		for ( var i = 0; i < orderedMotions.length; i ++ ) {
 
 			var m = orderedMotions[ i ];
 
@@ -369,10 +369,10 @@ THREE.MMDLoader.prototype.pourVmdIntoCamera = function ( camera, vmd, name ) {
 			var fov = m.fov;
 			var interpolation = m.interpolation;
 
-			position.set( 0, 0, -distance );
+			position.set( 0, 0, - distance );
 			center.set( pos[ 0 ], pos[ 1 ], pos[ 2 ] );
 
-			euler.set( -rot[ 0 ], -rot[ 1 ], -rot[ 2 ] );
+			euler.set( - rot[ 0 ], - rot[ 1 ], - rot[ 2 ] );
 			quaternion.setFromEuler( euler );
 
 			position.add( center );
@@ -424,7 +424,7 @@ THREE.MMDLoader.prototype.pourVmdIntoCamera = function ( camera, vmd, name ) {
 		tracks.push( createTrack( '.position', 'VectorKeyframeTrackEx', times, positions, pInterpolations ) );
 		tracks.push( createTrack( '.fov', 'NumberKeyframeTrackEx', times, fovs, fInterpolations ) );
 
-		var clip = new THREE.AnimationClip( name === undefined ? THREE.Math.generateUUID() : name, -1, tracks );
+		var clip = new THREE.AnimationClip( name === undefined ? THREE.Math.generateUUID() : name, - 1, tracks );
 
 		if ( camera.center === undefined ) camera.center = new THREE.Vector3( 0, 0, 0 );
 		if ( camera.animations === undefined ) camera.animations = [];
@@ -491,7 +491,6 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 	var scope = this;
 	var geometry = new THREE.BufferGeometry();
 	var materials = [];
-	var helper = new THREE.MMDLoader.DataCreationHelper();
 
 	var buffer = {};
 
@@ -504,7 +503,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 	var initVartices = function () {
 
-		for ( var i = 0; i < model.metadata.vertexCount; i++ ) {
+		for ( var i = 0; i < model.metadata.vertexCount; i ++ ) {
 
 			var v = model.vertices[ i ];
 
@@ -544,7 +543,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 	var initFaces = function () {
 
-		for ( var i = 0; i < model.metadata.faceCount; i++ ) {
+		for ( var i = 0; i < model.metadata.faceCount; i ++ ) {
 
 			var f = model.faces[ i ];
 
@@ -577,7 +576,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 		}
 
-		for ( var i = 0; i < model.metadata.boneCount; i++ ) {
+		for ( var i = 0; i < model.metadata.boneCount; i ++ ) {
 
 			var bone = {};
 			var b = model.bones[ i ];
@@ -588,7 +587,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 			bone.rotq = [ 0, 0, 0, 1 ];
 			bone.scl = [ 1, 1, 1 ];
 
-			if ( bone.parent !== -1 ) {
+			if ( bone.parent !== - 1 ) {
 
 				bone.pos[ 0 ] -= model.bones[ bone.parent ].position[ 0 ];
 				bone.pos[ 1 ] -= model.bones[ bone.parent ].position[ 1 ];
@@ -596,7 +595,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 			}
 
-			bone.rigidBodyType = dictionary[ i ] !== undefined ? dictionary[ i ] : -1;
+			bone.rigidBodyType = dictionary[ i ] !== undefined ? dictionary[ i ] : - 1;
 
 			bones.push( bone );
 
@@ -613,9 +612,9 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 		// TODO: remove duplicated codes between PMD and PMX
 		if ( model.metadata.format === 'pmd' ) {
 
-			for ( var i = 0; i < model.metadata.ikCount; i++ ) {
+			for ( var i = 0; i < model.metadata.ikCount; i ++ ) {
 
-				var ik = model.iks[i];
+				var ik = model.iks[ i ];
 				var param = {};
 
 				param.target = ik.target;
@@ -624,7 +623,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 				param.maxAngle = ik.maxAngle * 4;
 				param.links = [];
 
-				for ( var j = 0; j < ik.links.length; j++ ) {
+				for ( var j = 0; j < ik.links.length; j ++ ) {
 
 					var link = {};
 					link.index = ik.links[ j ].index;
@@ -645,7 +644,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 		} else {
 
-			for ( var i = 0; i < model.metadata.boneCount; i++ ) {
+			for ( var i = 0; i < model.metadata.boneCount; i ++ ) {
 
 				var b = model.bones[ i ];
 				var ik = b.ik;
@@ -664,7 +663,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 				param.maxAngle = ik.maxAngle;
 				param.links = [];
 
-				for ( var j = 0; j < ik.links.length; j++ ) {
+				for ( var j = 0; j < ik.links.length; j ++ ) {
 
 					var link = {};
 					link.index = ik.links[ j ].index;
@@ -703,7 +702,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 		var grants = [];
 
-		for ( var i = 0; i < model.metadata.boneCount; i++ ) {
+		for ( var i = 0; i < model.metadata.boneCount; i ++ ) {
 
 			var b = model.bones[ i ];
 			var grant = b.grant;
@@ -750,7 +749,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 		function updateVertices( attribute, m, ratio ) {
 
-			for ( var i = 0; i < m.elementCount; i++ ) {
+			for ( var i = 0; i < m.elementCount; i ++ ) {
 
 				var v = m.elements[ i ];
 
@@ -775,7 +774,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 		var morphTargets = [];
 		var attributes = [];
 
-		for ( var i = 0; i < model.metadata.morphCount; i++ ) {
+		for ( var i = 0; i < model.metadata.morphCount; i ++ ) {
 
 			var m = model.morphs[ i ];
 			var params = { name: m.name };
@@ -783,7 +782,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 			var attribute = new THREE.Float32BufferAttribute( model.metadata.vertexCount * 3, 3 );
 			attribute.name = m.name;
 
-			for ( var j = 0; j < model.metadata.vertexCount * 3; j++ ) {
+			for ( var j = 0; j < model.metadata.vertexCount * 3; j ++ ) {
 
 				attribute.array[ j ] = buffer.vertices[ j ];
 
@@ -799,9 +798,9 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 			} else {
 
-				if ( m.type === 0 ) {    // group
+				if ( m.type === 0 ) { // group
 
-					for ( var j = 0; j < m.elementCount; j++ ) {
+					for ( var j = 0; j < m.elementCount; j ++ ) {
 
 						var m2 = model.morphs[ m.elements[ j ].index ];
 						var ratio = m.elements[ j ].ratio;
@@ -818,35 +817,35 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 					}
 
-				} else if ( m.type === 1 ) {    // vertex
+				} else if ( m.type === 1 ) { // vertex
 
 					updateVertices( attribute, m, 1.0 );
 
-				} else if ( m.type === 2 ) {    // bone
+				} else if ( m.type === 2 ) { // bone
 
 					// TODO: implement
 
-				} else if ( m.type === 3 ) {    // uv
+				} else if ( m.type === 3 ) { // uv
 
 					// TODO: implement
 
-				} else if ( m.type === 4 ) {    // additional uv1
+				} else if ( m.type === 4 ) { // additional uv1
 
 					// TODO: implement
 
-				} else if ( m.type === 5 ) {    // additional uv2
+				} else if ( m.type === 5 ) { // additional uv2
 
 					// TODO: implement
 
-				} else if ( m.type === 6 ) {    // additional uv3
+				} else if ( m.type === 6 ) { // additional uv3
 
 					// TODO: implement
 
-				} else if ( m.type === 7 ) {    // additional uv4
+				} else if ( m.type === 7 ) { // additional uv4
 
 					// TODO: implement
 
-				} else if ( m.type === 8 ) {    // material
+				} else if ( m.type === 8 ) { // material
 
 					// TODO: implement
 
@@ -876,7 +875,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 		if ( scope.textureCrossOrigin !== null ) textureLoader.setCrossOrigin( scope.textureCrossOrigin );
 
-		function loadTexture ( filePath, params ) {
+		function loadTexture( filePath, params ) {
 
 			if ( params === undefined ) {
 
@@ -931,8 +930,8 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 					context.clearRect( 0, 0, width, height );
 					context.translate( width / 2.0, height / 2.0 );
-					context.rotate( 0.5 * Math.PI );  // 90.0 * Math.PI / 180.0
-					context.translate( -width / 2.0, -height / 2.0 );
+					context.rotate( 0.5 * Math.PI ); // 90.0 * Math.PI / 180.0
+					context.translate( - width / 2.0, - height / 2.0 );
 					context.drawImage( image, 0, 0 );
 
 					t.image = context.getImageData( 0, 0, width, height );
@@ -943,7 +942,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 				t.wrapS = THREE.RepeatWrapping;
 				t.wrapT = THREE.RepeatWrapping;
 
-				for ( var i = 0; i < texture.readyCallbacks.length; i++ ) {
+				for ( var i = 0; i < texture.readyCallbacks.length; i ++ ) {
 
 					texture.readyCallbacks[ i ]( texture );
 
@@ -979,7 +978,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 		}
 
-		for ( var i = 0; i < model.metadata.materialCount; i++ ) {
+		for ( var i = 0; i < model.metadata.materialCount; i ++ ) {
 
 			var m = model.materials[ i ];
 			var params = {};
@@ -1040,7 +1039,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 					}
 
-					for ( var j = 0; j < fileNames.length; j++ ) {
+					for ( var j = 0; j < fileNames.length; j ++ ) {
 
 						var n = fileNames[ j ];
 
@@ -1070,7 +1069,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 			} else {
 
-				if ( m.textureIndex !== -1 ) {
+				if ( m.textureIndex !== - 1 ) {
 
 					var n = model.textures[ m.textureIndex ];
 					params.map = loadTexture( n );
@@ -1078,7 +1077,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 				}
 
 				// TODO: support m.envFlag === 3
-				if ( m.envTextureIndex !== -1 && ( m.envFlag === 1 || m.envFlag == 2 ) ) {
+				if ( m.envTextureIndex !== - 1 && ( m.envFlag === 1 || m.envFlag == 2 ) ) {
 
 					var n = model.textures[ m.envTextureIndex ];
 					params.envMap = loadTexture( n, { sphericalReflectionMapping: true } );
@@ -1104,7 +1103,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 		}
 
-		for ( var i = 0; i < materialParams.length; i++ ) {
+		for ( var i = 0; i < materialParams.length; i ++ ) {
 
 			var p = materialParams[ i ];
 			var p2 = model.materials[ i ];
@@ -1133,12 +1132,12 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 				m.faceNum = p.faceNum;
 
 				// Check if this part of the texture image the material uses requires transparency
-				function checkTextureTransparency ( m ) {
+				function checkTextureTransparency( m ) {
 
 					m.map.readyCallbacks.push( function ( t ) {
 
 						// Is there any efficient ways?
-						function createImageData ( image ) {
+						function createImageData( image ) {
 
 							var c = document.createElement( 'canvas' );
 							c.width = image.width;
@@ -1168,7 +1167,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 								var centerUV = { x: 0.0, y: 0.0 };
 
-								for ( var j = 0; j < 3; j++ ) {
+								for ( var j = 0; j < 3; j ++ ) {
 
 									var index = indices[ i * 3 + j ];
 									var uv = { x: uvs[ index * 2 + 0 ], y: uvs[ index * 2 + 1 ] };
@@ -1206,7 +1205,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 						 *   t.wrapT = THREE.RepeatWrapping
 						 * TODO: more precise
 						 */
-						function getAlphaByUv ( image, uv ) {
+						function getAlphaByUv( image, uv ) {
 
 							var width = image.width;
 							var height = image.height;
@@ -1270,7 +1269,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 			if ( model.metadata.format === 'pmd' ) {
 
-				function isDefaultToonTexture ( n ) {
+				function isDefaultToonTexture( n ) {
 
 					if ( n.length !== 10 ) {
 
@@ -1291,7 +1290,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 				if ( m.outlineParameters.thickness === 0.0 ) m.outlineParameters.visible = false;
 
-				var toonFileName = ( p2.toonIndex === -1 ) ? 'toon00.bmp' : model.toonTextures[ p2.toonIndex ].fileName;
+				var toonFileName = ( p2.toonIndex === - 1 ) ? 'toon00.bmp' : model.toonTextures[ p2.toonIndex ].fileName;
 				var uuid = loadTexture( toonFileName, { isToonTexture: true, defaultTexturePath: isDefaultToonTexture( toonFileName ) } );
 				m.gradientMap = getTexture( uuid, textures );
 
@@ -1308,7 +1307,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 				var toonFileName, isDefaultToon;
 
-				if ( p2.toonIndex === -1 || p2.toonFlag !== 0 ) {
+				if ( p2.toonIndex === - 1 || p2.toonFlag !== 0 ) {
 
 					var num = p2.toonIndex + 1;
 					toonFileName = 'toon' + ( num < 10 ? '0' + num : num ) + '.bmp';
@@ -1332,7 +1331,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 		if ( model.metadata.format === 'pmx' ) {
 
-			function checkAlphaMorph ( morph, elements ) {
+			function checkAlphaMorph( morph, elements ) {
 
 				if ( morph.type !== 8 ) {
 
@@ -1340,11 +1339,11 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 				}
 
-				for ( var i = 0; i < elements.length; i++ ) {
+				for ( var i = 0; i < elements.length; i ++ ) {
 
 					var e = elements[ i ];
 
-					if ( e.index === -1 ) {
+					if ( e.index === - 1 ) {
 
 						continue;
 
@@ -1362,14 +1361,14 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 			}
 
-			for ( var i = 0; i < model.morphs.length; i++ ) {
+			for ( var i = 0; i < model.morphs.length; i ++ ) {
 
 				var morph = model.morphs[ i ];
 				var elements = morph.elements;
 
 				if ( morph.type === 0 ) {
 
-					for ( var j = 0; j < elements.length; j++ ) {
+					for ( var j = 0; j < elements.length; j ++ ) {
 
 						var morph2 = model.morphs[ elements[ j ].index ];
 						var elements2 = morph2.elements;
@@ -1395,14 +1394,14 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 		var rigidBodies = [];
 		var constraints = [];
 
-		for ( var i = 0; i < model.metadata.rigidBodyCount; i++ ) {
+		for ( var i = 0; i < model.metadata.rigidBodyCount; i ++ ) {
 
 			var b = model.rigidBodies[ i ];
 			var keys = Object.keys( b );
 
 			var p = {};
 
-			for ( var j = 0; j < keys.length; j++ ) {
+			for ( var j = 0; j < keys.length; j ++ ) {
 
 				var key = keys[ j ];
 				p[ key ] = b[ key ];
@@ -1416,7 +1415,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 			 */
 			if ( model.metadata.format === 'pmx' ) {
 
-				if ( p.boneIndex !== -1 ) {
+				if ( p.boneIndex !== - 1 ) {
 
 					var bone = model.bones[ p.boneIndex ];
 					p.position[ 0 ] -= bone.position[ 0 ];
@@ -1431,14 +1430,14 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 		}
 
-		for ( var i = 0; i < model.metadata.constraintCount; i++ ) {
+		for ( var i = 0; i < model.metadata.constraintCount; i ++ ) {
 
 			var c = model.constraints[ i ];
 			var keys = Object.keys( c );
 
 			var p = {};
 
-			for ( var j = 0; j < keys.length; j++ ) {
+			for ( var j = 0; j < keys.length; j ++ ) {
 
 				var key = keys[ j ];
 				p[ key ] = c[ key ];
@@ -1453,7 +1452,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 			 */
 			if ( bodyA.type !== 0 && bodyB.type === 2 ) {
 
-				if ( bodyA.boneIndex !== -1 && bodyB.boneIndex !== -1 &&
+				if ( bodyA.boneIndex !== - 1 && bodyB.boneIndex !== - 1 &&
 				     model.bones[ bodyB.boneIndex ].parentIndex === bodyA.boneIndex ) {
 
 					bodyB.type = 1;
@@ -1522,14 +1521,14 @@ THREE.MMDLoader.prototype.createAnimation = function ( mesh, vmd, name ) {
 
 		var pushInterpolation = function ( array, interpolation, index ) {
 
-			array.push( interpolation[ index + 0 ] / 127 );  // x1
-			array.push( interpolation[ index + 8 ] / 127 );  // x2
-			array.push( interpolation[ index + 4 ] / 127 );  // y1
+			array.push( interpolation[ index + 0 ] / 127 ); // x1
+			array.push( interpolation[ index + 8 ] / 127 ); // x2
+			array.push( interpolation[ index + 4 ] / 127 ); // y1
 			array.push( interpolation[ index + 12 ] / 127 ); // y2
 
 		};
 
-		for ( var i = 0; i < orderedMotions.length; i++ ) {
+		for ( var i = 0; i < orderedMotions.length; i ++ ) {
 
 			var times = [];
 			var positions = [];
@@ -1540,7 +1539,7 @@ THREE.MMDLoader.prototype.createAnimation = function ( mesh, vmd, name ) {
 			var bone = bones[ i ];
 			var array = orderedMotions[ i ];
 
-			for ( var j = 0; j < array.length; j++ ) {
+			for ( var j = 0; j < array.length; j ++ ) {
 
 				var time = array[ j ].frameNum / 30;
 				var pos = array[ j ].position;
@@ -1580,7 +1579,7 @@ THREE.MMDLoader.prototype.createAnimation = function ( mesh, vmd, name ) {
 
 		}
 
-		var clip = new THREE.AnimationClip( name === undefined ? THREE.Math.generateUUID() : name, -1, tracks );
+		var clip = new THREE.AnimationClip( name === undefined ? THREE.Math.generateUUID() : name, - 1, tracks );
 
 		if ( mesh.geometry.animations === undefined ) mesh.geometry.animations = [];
 		mesh.geometry.animations.push( clip );
@@ -1599,13 +1598,13 @@ THREE.MMDLoader.prototype.createAnimation = function ( mesh, vmd, name ) {
 
 		var tracks = [];
 
-		for ( var i = 0; i < orderedMorphs.length; i++ ) {
+		for ( var i = 0; i < orderedMorphs.length; i ++ ) {
 
 			var times = [];
 			var values = [];
 			var array = orderedMorphs[ i ];
 
-			for ( var j = 0; j < array.length; j++ ) {
+			for ( var j = 0; j < array.length; j ++ ) {
 
 				times.push( array[ j ].frameNum / 30 );
 				values.push( array[ j ].weight );
@@ -1618,7 +1617,7 @@ THREE.MMDLoader.prototype.createAnimation = function ( mesh, vmd, name ) {
 
 		}
 
-		var clip = new THREE.AnimationClip( name === undefined ? THREE.Math.generateUUID() : name + 'Morph', -1, tracks );
+		var clip = new THREE.AnimationClip( name === undefined ? THREE.Math.generateUUID() : name + 'Morph', - 1, tracks );
 
 		if ( mesh.geometry.animations === undefined ) mesh.geometry.animations = [];
 		mesh.geometry.animations.push( clip );
@@ -1648,9 +1647,9 @@ THREE.MMDLoader.DataCreationHelper.prototype = {
 
 		var str = '';
 
-		for ( var i = 0; i < s.length; i++ ) {
+		for ( var i = 0; i < s.length; i ++ ) {
 
-			str += '0x' + ( '0000' + s[ i ].charCodeAt().toString( 16 ) ).substr( -4 );
+			str += '0x' + ( '0000' + s[ i ].charCodeAt().toString( 16 ) ).substr( - 4 );
 
 		}
 
@@ -1662,7 +1661,7 @@ THREE.MMDLoader.DataCreationHelper.prototype = {
 
 		var dict = {};
 
-		for ( var i = 0; i < array.length; i++ ) {
+		for ( var i = 0; i < array.length; i ++ ) {
 
 			dict[ array[ i ].name ] = i;
 
@@ -1676,7 +1675,7 @@ THREE.MMDLoader.DataCreationHelper.prototype = {
 
 		var result = [];
 
-		for ( var i = 0; i < array.length; i++ ) {
+		for ( var i = 0; i < array.length; i ++ ) {
 
 			result[ i ] = [];
 
@@ -1692,13 +1691,13 @@ THREE.MMDLoader.DataCreationHelper.prototype = {
 
 			return a.frameNum - b.frameNum;
 
-		} ) ;
+		} );
 
 	},
 
 	sortMotionArrays: function ( arrays ) {
 
-		for ( var i = 0; i < arrays.length; i++ ) {
+		for ( var i = 0; i < arrays.length; i ++ ) {
 
 			this.sortMotionArray( arrays[ i ] );
 
@@ -1710,7 +1709,7 @@ THREE.MMDLoader.DataCreationHelper.prototype = {
 
 		var result = [];
 
-		for ( var i = 0; i < array.length; i++ ) {
+		for ( var i = 0; i < array.length; i ++ ) {
 
 			result.push( array[ i ] );
 
@@ -1722,7 +1721,7 @@ THREE.MMDLoader.DataCreationHelper.prototype = {
 
 	createMotionArrays: function ( array, result, dict, key ) {
 
-		for ( var i = 0; i < array.length; i++ ) {
+		for ( var i = 0; i < array.length; i ++ ) {
 
 			var a = array[ i ];
 			var num = dict[ a[ key ] ];
@@ -1777,13 +1776,13 @@ THREE.MMDLoader.VectorKeyframeTrackEx.prototype = Object.create( THREE.VectorKey
 THREE.MMDLoader.VectorKeyframeTrackEx.prototype.constructor = THREE.MMDLoader.VectorKeyframeTrackEx;
 THREE.MMDLoader.VectorKeyframeTrackEx.prototype.TimeBufferType = Float64Array;
 
-THREE.MMDLoader.VectorKeyframeTrackEx.prototype.InterpolantFactoryMethodCubicBezier = function( result ) {
+THREE.MMDLoader.VectorKeyframeTrackEx.prototype.InterpolantFactoryMethodCubicBezier = function ( result ) {
 
 	return new THREE.MMDLoader.CubicBezierInterpolation( this.times, this.values, this.getValueSize(), result, this.interpolationParameters );
 
 };
 
-THREE.MMDLoader.VectorKeyframeTrackEx.prototype.setInterpolation = function( interpolation ) {
+THREE.MMDLoader.VectorKeyframeTrackEx.prototype.setInterpolation = function ( interpolation ) {
 
 	this.createInterpolant = this.InterpolantFactoryMethodCubicBezier;
 
@@ -1801,13 +1800,13 @@ THREE.MMDLoader.QuaternionKeyframeTrackEx.prototype = Object.create( THREE.Quate
 THREE.MMDLoader.QuaternionKeyframeTrackEx.prototype.constructor = THREE.MMDLoader.QuaternionKeyframeTrackEx;
 THREE.MMDLoader.QuaternionKeyframeTrackEx.prototype.TimeBufferType = Float64Array;
 
-THREE.MMDLoader.QuaternionKeyframeTrackEx.prototype.InterpolantFactoryMethodCubicBezier = function( result ) {
+THREE.MMDLoader.QuaternionKeyframeTrackEx.prototype.InterpolantFactoryMethodCubicBezier = function ( result ) {
 
 	return new THREE.MMDLoader.CubicBezierInterpolation( this.times, this.values, this.getValueSize(), result, this.interpolationParameters );
 
 };
 
-THREE.MMDLoader.QuaternionKeyframeTrackEx.prototype.setInterpolation = function( interpolation ) {
+THREE.MMDLoader.QuaternionKeyframeTrackEx.prototype.setInterpolation = function ( interpolation ) {
 
 	this.createInterpolant = this.InterpolantFactoryMethodCubicBezier;
 
@@ -1825,13 +1824,13 @@ THREE.MMDLoader.NumberKeyframeTrackEx.prototype = Object.create( THREE.NumberKey
 THREE.MMDLoader.NumberKeyframeTrackEx.prototype.constructor = THREE.MMDLoader.NumberKeyframeTrackEx;
 THREE.MMDLoader.NumberKeyframeTrackEx.prototype.TimeBufferType = Float64Array;
 
-THREE.MMDLoader.NumberKeyframeTrackEx.prototype.InterpolantFactoryMethodCubicBezier = function( result ) {
+THREE.MMDLoader.NumberKeyframeTrackEx.prototype.InterpolantFactoryMethodCubicBezier = function ( result ) {
 
 	return new THREE.MMDLoader.CubicBezierInterpolation( this.times, this.values, this.getValueSize(), result, this.interpolationParameters );
 
 };
 
-THREE.MMDLoader.NumberKeyframeTrackEx.prototype.setInterpolation = function( interpolation ) {
+THREE.MMDLoader.NumberKeyframeTrackEx.prototype.setInterpolation = function ( interpolation ) {
 
 	this.createInterpolant = this.InterpolantFactoryMethodCubicBezier;
 
@@ -1843,12 +1842,12 @@ THREE.MMDLoader.CubicBezierInterpolation = function ( parameterPositions, sample
 
 	this.params = params;
 
-}
+};
 
 THREE.MMDLoader.CubicBezierInterpolation.prototype = Object.create( THREE.LinearInterpolant.prototype );
 THREE.MMDLoader.CubicBezierInterpolation.prototype.constructor = THREE.MMDLoader.CubicBezierInterpolation;
 
-THREE.MMDLoader.CubicBezierInterpolation.prototype.interpolate_ = function( i1, t0, t, t1 ) {
+THREE.MMDLoader.CubicBezierInterpolation.prototype.interpolate_ = function ( i1, t0, t, t1 ) {
 
 	var result = this.resultBuffer;
 	var values = this.sampleValues;
@@ -1859,7 +1858,7 @@ THREE.MMDLoader.CubicBezierInterpolation.prototype.interpolate_ = function( i1,
 
 	var weight1 = ( t - t0 ) / ( t1 - t0 );
 
-	if ( stride === 4 ) {  // Quaternion
+	if ( stride === 4 ) { // Quaternion
 
 		var x1 = this.params[ i1 * 4 + 0 ];
 		var x2 = this.params[ i1 * 4 + 1 ];
@@ -1870,7 +1869,7 @@ THREE.MMDLoader.CubicBezierInterpolation.prototype.interpolate_ = function( i1,
 
 		THREE.Quaternion.slerpFlat( result, 0, values, offset0, values, offset1, ratio );
 
-	} else if ( stride === 3 ) {  // Vector3
+	} else if ( stride === 3 ) { // Vector3
 
 		for ( var i = 0; i !== stride; ++ i ) {
 
@@ -1885,7 +1884,7 @@ THREE.MMDLoader.CubicBezierInterpolation.prototype.interpolate_ = function( i1,
 
 		}
 
-	} else {  // Number
+	} else { // Number
 
 		var x1 = this.params[ i1 * 4 + 0 ];
 		var x2 = this.params[ i1 * 4 + 1 ];
@@ -1902,7 +1901,7 @@ THREE.MMDLoader.CubicBezierInterpolation.prototype.interpolate_ = function( i1,
 
 };
 
-THREE.MMDLoader.CubicBezierInterpolation.prototype._calculate = function( x1, x2, y1, y2, x ) {
+THREE.MMDLoader.CubicBezierInterpolation.prototype._calculate = function ( x1, x2, y1, y2, x ) {
 
 	/*
 	 * Cubic Bezier curves
@@ -1962,7 +1961,7 @@ THREE.MMDLoader.CubicBezierInterpolation.prototype._calculate = function( x1, x2
 
 		c /= 2.0;
 
-		t += ( ft < 0 ) ? c : -c;
+		t += ( ft < 0 ) ? c : - c;
 		s = 1.0 - t;
 
 	}
@@ -2173,7 +2172,7 @@ THREE.MMDHelper.prototype = {
 
 	setPhysicses: function ( params ) {
 
-		for ( var i = 0; i < this.meshes.length; i++ ) {
+		for ( var i = 0; i < this.meshes.length; i ++ ) {
 
 			this.setPhysics( this.meshes[ i ], params );
 
@@ -2226,6 +2225,7 @@ THREE.MMDHelper.prototype = {
 				return this.masterPhysics;
 
 			}
+
 		}
 
 		return null;
@@ -2286,7 +2286,7 @@ THREE.MMDHelper.prototype = {
 
 	setAnimations: function () {
 
-		for ( var i = 0; i < this.meshes.length; i++ ) {
+		for ( var i = 0; i < this.meshes.length; i ++ ) {
 
 			this.setAnimation( this.meshes[ i ] );
 
@@ -2315,7 +2315,7 @@ THREE.MMDHelper.prototype = {
 			var foundAnimation = false;
 			var foundMorphAnimation = false;
 
-			for ( var i = 0; i < mesh.geometry.animations.length; i++ ) {
+			for ( var i = 0; i < mesh.geometry.animations.length; i ++ ) {
 
 				var clip = mesh.geometry.animations[ i ];
 
@@ -2386,7 +2386,7 @@ THREE.MMDHelper.prototype = {
 		var audioManager = this.audioManager;
 
 		// check the longest duration
-		for ( var i = 0; i < this.meshes.length; i++ ) {
+		for ( var i = 0; i < this.meshes.length; i ++ ) {
 
 			var mesh = this.meshes[ i ];
 			var mixer = mesh.mixer;
@@ -2397,7 +2397,7 @@ THREE.MMDHelper.prototype = {
 
 			}
 
-			for ( var j = 0; j < mixer._actions.length; j++ ) {
+			for ( var j = 0; j < mixer._actions.length; j ++ ) {
 
 				var action = mixer._actions[ j ];
 				max = Math.max( max, action._clip.duration );
@@ -2410,7 +2410,7 @@ THREE.MMDHelper.prototype = {
 
 			var mixer = camera.mixer;
 
-			for ( var i = 0; i < mixer._actions.length; i++ ) {
+			for ( var i = 0; i < mixer._actions.length; i ++ ) {
 
 				var action = mixer._actions[ i ];
 				max = Math.max( max, action._clip.duration );
@@ -2432,7 +2432,7 @@ THREE.MMDHelper.prototype = {
 		}
 
 		// set the duration
-		for ( var i = 0; i < this.meshes.length; i++ ) {
+		for ( var i = 0; i < this.meshes.length; i ++ ) {
 
 			var mesh = this.meshes[ i ];
 			var mixer = mesh.mixer;
@@ -2443,7 +2443,7 @@ THREE.MMDHelper.prototype = {
 
 			}
 
-			for ( var j = 0; j < mixer._actions.length; j++ ) {
+			for ( var j = 0; j < mixer._actions.length; j ++ ) {
 
 				var action = mixer._actions[ j ];
 				action._clip.duration = max;
@@ -2456,7 +2456,7 @@ THREE.MMDHelper.prototype = {
 
 			var mixer = camera.mixer;
 
-			for ( var i = 0; i < mixer._actions.length; i++ ) {
+			for ( var i = 0; i < mixer._actions.length; i ++ ) {
 
 				var action = mixer._actions[ i ];
 				action._clip.duration = max;
@@ -2489,7 +2489,7 @@ THREE.MMDHelper.prototype = {
 
 		this.controlAudio( delta );
 
-		for ( var i = 0; i < this.meshes.length; i++ ) {
+		for ( var i = 0; i < this.meshes.length; i ++ ) {
 
 			this.animateOneMesh( delta, this.meshes[ i ] );
 
@@ -2620,7 +2620,7 @@ THREE.MMDHelper.prototype = {
 
 		var table = {};
 
-		for ( var i = 0; i < bones.length; i++ ) {
+		for ( var i = 0; i < bones.length; i ++ ) {
 
 			table[ bones[ i ].name ] = i;
 
@@ -2629,7 +2629,7 @@ THREE.MMDHelper.prototype = {
 		var thV = new THREE.Vector3();
 		var thQ = new THREE.Quaternion();
 
-		for ( var i = 0; i < bones2.length; i++ ) {
+		for ( var i = 0; i < bones2.length; i ++ ) {
 
 			var b = bones2[ i ];
 			var index = table[ b.name ];
@@ -2680,7 +2680,7 @@ THREE.MMDHelper.prototype = {
 
 		mesh.skeleton.backupBones = [];
 
-		for ( var i = 0; i < mesh.skeleton.bones.length; i++ ) {
+		for ( var i = 0; i < mesh.skeleton.bones.length; i ++ ) {
 
 			mesh.skeleton.backupBones.push( mesh.skeleton.bones[ i ].clone() );
 
@@ -2692,7 +2692,7 @@ THREE.MMDHelper.prototype = {
 
 		mesh.skeleton.backupBoneIsSaved = true;
 
-		for ( var i = 0; i < mesh.skeleton.bones.length; i++ ) {
+		for ( var i = 0; i < mesh.skeleton.bones.length; i ++ ) {
 
 			var b = mesh.skeleton.backupBones[ i ];
 			var b2 = mesh.skeleton.bones[ i ];
@@ -2713,7 +2713,7 @@ THREE.MMDHelper.prototype = {
 
 		mesh.skeleton.backupBoneIsSaved = false;
 
-		for ( var i = 0; i < mesh.skeleton.bones.length; i++ ) {
+		for ( var i = 0; i < mesh.skeleton.bones.length; i ++ ) {
 
 			var b = mesh.skeleton.bones[ i ];
 			var b2 = mesh.skeleton.backupBones[ i ];

+ 2 - 2
examples/js/loaders/MTLLoader.js

@@ -448,7 +448,7 @@ THREE.MTLLoader.MaterialCreator.prototype = {
 					break;
 
 				case 'd':
-					n = parseFloat(value);
+					n = parseFloat( value );
 
 					if ( n < 1 ) {
 
@@ -460,7 +460,7 @@ THREE.MTLLoader.MaterialCreator.prototype = {
 					break;
 
 				case 'tr':
-					n = parseFloat(value);
+					n = parseFloat( value );
 
 					if ( n > 0 ) {
 

+ 15 - 13
examples/js/loaders/NRRDLoader.js

@@ -91,7 +91,7 @@ THREE.NRRDLoader.prototype = {
 
 			// increase the data pointer in-place
 			var _bytes = new _array_type( _data.slice( _dataPointer,
-			_dataPointer += chunks * _chunkSize ) );
+				_dataPointer += chunks * _chunkSize ) );
 
 			// if required, flip the endianness of the bytes
 			if ( _nativeLittleEndian != _littleEndian ) {
@@ -285,7 +285,7 @@ THREE.NRRDLoader.prototype = {
 
 			// we need to decompress the datastream
 			// here we start the unzipping and get a typed Uint8Array back
-			var inflate = new Zlib.Gunzip( new Uint8Array( _data ) );
+			var inflate = new Zlib.Gunzip( new Uint8Array( _data ) ); // eslint-disable-line no-undef
 			_data = inflate.decompress();
 
 		} else if ( headerObject.encoding === 'ascii' || headerObject.encoding === 'text' || headerObject.encoding === 'txt' || headerObject.encoding === 'hex' ) {
@@ -330,11 +330,11 @@ THREE.NRRDLoader.prototype = {
 		volume.zLength = volume.dimensions[ 2 ];
 		// spacing
 		var spacingX = ( new THREE.Vector3( headerObject.vectors[ 0 ][ 0 ], headerObject.vectors[ 0 ][ 1 ],
-		headerObject.vectors[ 0 ][ 2 ] ) ).length();
+			headerObject.vectors[ 0 ][ 2 ] ) ).length();
 		var spacingY = ( new THREE.Vector3( headerObject.vectors[ 1 ][ 0 ], headerObject.vectors[ 1 ][ 1 ],
-		headerObject.vectors[ 1 ][ 2 ] ) ).length();
+			headerObject.vectors[ 1 ][ 2 ] ) ).length();
 		var spacingZ = ( new THREE.Vector3( headerObject.vectors[ 2 ][ 0 ], headerObject.vectors[ 2 ][ 1 ],
-		headerObject.vectors[ 2 ][ 2 ] ) ).length();
+			headerObject.vectors[ 2 ][ 2 ] ) ).length();
 		volume.spacing = [ spacingX, spacingY, spacingZ ];
 
 
@@ -359,19 +359,21 @@ THREE.NRRDLoader.prototype = {
 
 		if ( ! headerObject.vectors ) {
 
-			volume.matrix.set( _spaceX, 0, 0, 0,
-			0, _spaceY, 0, 0,
-			0, 0, _spaceZ, 0,
-			0, 0, 0, 1 );
+			volume.matrix.set(
+				_spaceX, 0, 0, 0,
+				0, _spaceY, 0, 0,
+				0, 0, _spaceZ, 0,
+				0, 0, 0, 1 );
 
 		} else {
 
 			var v = headerObject.vectors;
 
-			volume.matrix.set( _spaceX * v[ 0 ][ 0 ], _spaceX * v[ 1 ][ 0 ], _spaceX * v[ 2 ][ 0 ], 0,
-			_spaceY * v[ 0 ][ 1 ], _spaceY * v[ 1 ][ 1 ], _spaceY * v[ 2 ][ 1 ], 0,
-			_spaceZ * v[ 0 ][ 2 ], _spaceZ * v[ 1 ][ 2 ], _spaceZ * v[ 2 ][ 2 ], 0,
-			0, 0, 0, 1 );
+			volume.matrix.set(
+				_spaceX * v[ 0 ][ 0 ], _spaceX * v[ 1 ][ 0 ], _spaceX * v[ 2 ][ 0 ], 0,
+				_spaceY * v[ 0 ][ 1 ], _spaceY * v[ 1 ][ 1 ], _spaceY * v[ 2 ][ 1 ], 0,
+				_spaceZ * v[ 0 ][ 2 ], _spaceZ * v[ 1 ][ 2 ], _spaceZ * v[ 2 ][ 2 ], 0,
+				0, 0, 0, 1 );
 
 		}
 

File diff suppressed because it is too large
+ 634 - 250
examples/js/loaders/OBJLoader2.js


File diff suppressed because it is too large
+ 0 - 0
examples/js/loaders/PDBLoader.js


+ 17 - 17
examples/js/loaders/PLYLoader.js

@@ -92,7 +92,7 @@ THREE.PLYLoader.prototype = {
 
 			if ( result !== null ) {
 
-				headerText = result [ 1 ];
+				headerText = result[ 1 ];
 				headerLength = result[ 0 ].length;
 
 			}
@@ -203,14 +203,14 @@ THREE.PLYLoader.prototype = {
 
 			switch ( type ) {
 
-			case 'char': case 'uchar': case 'short': case 'ushort': case 'int': case 'uint':
-			case 'int8': case 'uint8': case 'int16': case 'uint16': case 'int32': case 'uint32':
+				case 'char': case 'uchar': case 'short': case 'ushort': case 'int': case 'uint':
+				case 'int8': case 'uint8': case 'int16': case 'uint16': case 'int32': case 'uint32':
 
-				return parseInt( n );
+					return parseInt( n );
 
-			case 'float': case 'double': case 'float32': case 'float64':
+				case 'float': case 'double': case 'float32': case 'float64':
 
-				return parseFloat( n );
+					return parseFloat( n );
 
 			}
 
@@ -254,11 +254,11 @@ THREE.PLYLoader.prototype = {
 			// PLY ascii format specification, as per http://en.wikipedia.org/wiki/PLY_(file_format)
 
 			var buffer = {
-				indices : [],
-				vertices : [],
-				normals : [],
-				uvs : [],
-				colors : []
+				indices: [],
+				vertices: [],
+				normals: [],
+				uvs: [],
+				colors: []
 			};
 
 			var result;
@@ -267,7 +267,7 @@ THREE.PLYLoader.prototype = {
 			var body = '';
 			if ( ( result = patternBody.exec( data ) ) !== null ) {
 
-				body = result [ 1 ];
+				body = result[ 1 ];
 
 			}
 
@@ -447,11 +447,11 @@ THREE.PLYLoader.prototype = {
 		function parseBinary( data, header ) {
 
 			var buffer = {
-				indices : [],
-				vertices : [],
-				normals : [],
-				uvs : [],
-				colors : []
+				indices: [],
+				vertices: [],
+				normals: [],
+				uvs: [],
+				colors: []
 			};
 
 			var little_endian = ( header.format === 'binary_little_endian' );

+ 1 - 3
examples/js/loaders/PRWMLoader.js

@@ -5,7 +5,7 @@
 
 ( function ( THREE ) {
 
-	"use strict";
+	'use strict';
 
 	var bigEndianPlatform = null;
 
@@ -146,7 +146,6 @@
 			attributeName,
 			char,
 			attributeType,
-			attributeNormalized,
 			cardinality,
 			encodingType,
 			arrayType,
@@ -178,7 +177,6 @@
 			flags = array[ pos ];
 
 			attributeType = flags >> 7 & 0x01;
-			attributeNormalized = !! ( flags >> 6 & 0x01 );
 			cardinality = ( flags >> 4 & 0x03 ) + 1;
 			encodingType = flags & 0x0F;
 			arrayType = InvertedEncodingTypes[ encodingType ];

+ 54 - 77
examples/js/loaders/PVRLoader.js

@@ -27,24 +27,25 @@ THREE.PVRLoader.parse = function ( buffer, loadMipmaps ) {
 
 	var pvrDatas = {
 		buffer: buffer,
-		header : header,
-		loadMipmaps : loadMipmaps
+		header: header,
+		loadMipmaps: loadMipmaps
 	};
 
-	// PVR v3
 	if ( header[ 0 ] === 0x03525650 ) {
 
+		// PVR v3
+
 		return THREE.PVRLoader._parseV3( pvrDatas );
 
-	}
-	// PVR v2
-	else if ( header[ 11 ] === 0x21525650 ) {
+	} else if ( header[ 11 ] === 0x21525650 ) {
+
+		// PVR v2
 
 		return THREE.PVRLoader._parseV2( pvrDatas );
 
 	} else {
 
-		throw new Error( "[THREE.PVRLoader] Unknown PVR format" );
+		console.error( 'THREE.PVRLoader: Unknown PVR format.' );
 
 	}
 
@@ -56,43 +57,48 @@ THREE.PVRLoader._parseV3 = function ( pvrDatas ) {
 	var bpp, format;
 
 
-	var metaLen 	  = header[ 12 ],
-		pixelFormat   =  header[ 2 ],
-		height        =  header[ 6 ],
-		width         =  header[ 7 ],
-		numSurfs      =  header[ 9 ],
-		numFaces      =  header[ 10 ],
-		numMipmaps    =  header[ 11 ];
+	var metaLen = header[ 12 ],
+		pixelFormat = header[ 2 ],
+		height = header[ 6 ],
+		width = header[ 7 ],
+		// numSurfs = header[ 9 ],
+		numFaces = header[ 10 ],
+		numMipmaps = header[ 11 ];
 
 	switch ( pixelFormat ) {
+
 		case 0 : // PVRTC 2bpp RGB
 			bpp = 2;
 			format = THREE.RGB_PVRTC_2BPPV1_Format;
 			break;
+
 		case 1 : // PVRTC 2bpp RGBA
 			bpp = 2;
 			format = THREE.RGBA_PVRTC_2BPPV1_Format;
 			break;
+
 		case 2 : // PVRTC 4bpp RGB
 			bpp = 4;
 			format = THREE.RGB_PVRTC_4BPPV1_Format;
 			break;
+
 		case 3 : // PVRTC 4bpp RGBA
 			bpp = 4;
 			format = THREE.RGBA_PVRTC_4BPPV1_Format;
 			break;
+
 		default :
-			throw new Error( "pvrtc - unsupported PVR format " + pixelFormat );
+			console.error( 'THREE.PVRLoader: Unsupported PVR format:', pixelFormat );
+
 	}
 
-	pvrDatas.dataPtr 	 = 52 + metaLen;
-	pvrDatas.bpp 		 = bpp;
-	pvrDatas.format 	 = format;
-	pvrDatas.width 		 = width;
-	pvrDatas.height 	 = height;
+	pvrDatas.dataPtr = 52 + metaLen;
+	pvrDatas.bpp = bpp;
+	pvrDatas.format = format;
+	pvrDatas.width = width;
+	pvrDatas.height = height;
 	pvrDatas.numSurfaces = numFaces;
-	pvrDatas.numMipmaps  = numMipmaps;
-
+	pvrDatas.numMipmaps = numMipmaps;
 	pvrDatas.isCubemap 	= ( numFaces === 6 );
 
 	return THREE.PVRLoader._extract( pvrDatas );
@@ -103,19 +109,19 @@ THREE.PVRLoader._parseV2 = function ( pvrDatas ) {
 
 	var header = pvrDatas.header;
 
-	var headerLength  =  header[ 0 ],
-		height        =  header[ 1 ],
-		width         =  header[ 2 ],
-		numMipmaps    =  header[ 3 ],
-		flags         =  header[ 4 ],
-		dataLength    =  header[ 5 ],
-		// bpp           =  header[ 6 ],
-		bitmaskRed    =  header[ 7 ],
-		bitmaskGreen  =  header[ 8 ],
-		bitmaskBlue   =  header[ 9 ],
-		bitmaskAlpha  =  header[ 10 ],
-		pvrTag        =  header[ 11 ],
-		numSurfs      =  header[ 12 ];
+	var headerLength = header[ 0 ],
+		height = header[ 1 ],
+		width = header[ 2 ],
+		numMipmaps = header[ 3 ],
+		flags = header[ 4 ],
+		// dataLength = header[ 5 ],
+		// bpp =  header[ 6 ],
+		// bitmaskRed = header[ 7 ],
+		// bitmaskGreen = header[ 8 ],
+		// bitmaskBlue = header[ 9 ],
+		bitmaskAlpha = header[ 10 ],
+		// pvrTag = header[ 11 ],
+		numSurfs = header[ 12 ];
 
 
 	var TYPE_MASK = 0xff;
@@ -124,8 +130,6 @@ THREE.PVRLoader._parseV2 = function ( pvrDatas ) {
 
 	var formatFlags = flags & TYPE_MASK;
 
-
-
 	var bpp, format;
 	var _hasAlpha = bitmaskAlpha > 0;
 
@@ -139,18 +143,19 @@ THREE.PVRLoader._parseV2 = function ( pvrDatas ) {
 		format = _hasAlpha ? THREE.RGBA_PVRTC_2BPPV1_Format : THREE.RGB_PVRTC_2BPPV1_Format;
 		bpp = 2;
 
-	} else
-		throw new Error( "pvrtc - unknown format " + formatFlags );
+	} else {
 
+		console.error( 'THREE.PVRLoader: Unknown PVR format:', formatFlags );
 
+	}
 
-	pvrDatas.dataPtr 	 = headerLength;
-	pvrDatas.bpp 		 = bpp;
-	pvrDatas.format 	 = format;
-	pvrDatas.width 		 = width;
-	pvrDatas.height 	 = height;
+	pvrDatas.dataPtr = headerLength;
+	pvrDatas.bpp = bpp;
+	pvrDatas.format = format;
+	pvrDatas.width = width;
+	pvrDatas.height = height;
 	pvrDatas.numSurfaces = numSurfs;
-	pvrDatas.numMipmaps  = numMipmaps + 1;
+	pvrDatas.numMipmaps = numMipmaps + 1;
 
 	// guess cubemap type seems tricky in v2
 	// it juste a pvr containing 6 surface (no explicit cubemap type)
@@ -169,32 +174,11 @@ THREE.PVRLoader._extract = function ( pvrDatas ) {
 		height: pvrDatas.height,
 		format: pvrDatas.format,
 		mipmapCount: pvrDatas.numMipmaps,
-		isCubemap : pvrDatas.isCubemap
+		isCubemap: pvrDatas.isCubemap
 	};
 
 	var buffer = pvrDatas.buffer;
 
-
-
-	// console.log( "--------------------------" );
-
-	// console.log( "headerLength ", headerLength);
-	// console.log( "height       ", height      );
-	// console.log( "width        ", width       );
-	// console.log( "numMipmaps   ", numMipmaps  );
-	// console.log( "flags        ", flags       );
-	// console.log( "dataLength   ", dataLength  );
-	// console.log( "bpp          ", bpp         );
-	// console.log( "bitmaskRed   ", bitmaskRed  );
-	// console.log( "bitmaskGreen ", bitmaskGreen);
-	// console.log( "bitmaskBlue  ", bitmaskBlue );
-	// console.log( "bitmaskAlpha ", bitmaskAlpha);
-	// console.log( "pvrTag       ", pvrTag      );
-	// console.log( "numSurfs     ", numSurfs    );
-
-
-
-
 	var dataOffset = pvrDatas.dataPtr,
 		bpp = pvrDatas.bpp,
 		numSurfs = pvrDatas.numSurfaces,
@@ -205,8 +189,6 @@ THREE.PVRLoader._extract = function ( pvrDatas ) {
 		widthBlocks = 0,
 		heightBlocks = 0;
 
-
-
 	if ( bpp === 2 ) {
 
 		blockWidth = 8;
@@ -228,20 +210,17 @@ THREE.PVRLoader._extract = function ( pvrDatas ) {
 	while ( mipLevel < pvrDatas.numMipmaps ) {
 
 		var sWidth = pvrDatas.width >> mipLevel,
-		sHeight = pvrDatas.height >> mipLevel;
+			sHeight = pvrDatas.height >> mipLevel;
 
 		widthBlocks = sWidth / blockWidth;
 		heightBlocks = sHeight / blockHeight;
 
 		// Clamp to minimum number of blocks
-		if ( widthBlocks < 2 )
-			widthBlocks = 2;
-		if ( heightBlocks < 2 )
-			heightBlocks = 2;
+		if ( widthBlocks < 2 ) widthBlocks = 2;
+		if ( heightBlocks < 2 ) heightBlocks = 2;
 
 		dataSize = widthBlocks * heightBlocks * blockSize;
 
-
 		for ( var surfIndex = 0; surfIndex < numSurfs; surfIndex ++ ) {
 
 			var byteArray = new Uint8Array( buffer, dataOffset, dataSize );
@@ -256,14 +235,12 @@ THREE.PVRLoader._extract = function ( pvrDatas ) {
 
 			dataOffset += dataSize;
 
-
 		}
 
 		mipLevel ++;
 
 	}
 
-
 	return pvr;
 
 };

+ 1 - 1
examples/js/loaders/PlayCanvasLoader.js

@@ -181,7 +181,7 @@ THREE.PlayCanvasLoader.prototype = {
 
 			var parent = model.parents[ i ];
 
-			if ( parent === -1 ) continue;
+			if ( parent === - 1 ) continue;
 
 			model.nodes[ parent ]._object.add( model.nodes[ i ]._object );
 

+ 32 - 35
examples/js/loaders/RGBELoader.js

@@ -15,50 +15,52 @@ THREE.HDRLoader = THREE.RGBELoader = function ( manager ) {
 THREE.RGBELoader.prototype = Object.create( THREE.DataTextureLoader.prototype );
 
 // adapted from http://www.graphics.cornell.edu/~bjw/rgbe.html
-THREE.RGBELoader.prototype._parser = function( buffer ) {
+THREE.RGBELoader.prototype._parser = function ( buffer ) {
 
 	var
 		/* return codes for rgbe routines */
-		RGBE_RETURN_SUCCESS =  0,
+		RGBE_RETURN_SUCCESS = 0,
 		RGBE_RETURN_FAILURE = - 1,
 
 		/* default error routine.  change this to change error handling */
-		rgbe_read_error     = 1,
-		rgbe_write_error    = 2,
-		rgbe_format_error   = 3,
-		rgbe_memory_error   = 4,
-		rgbe_error = function( rgbe_error_code, msg ) {
+		rgbe_read_error = 1,
+		rgbe_write_error = 2,
+		rgbe_format_error = 3,
+		rgbe_memory_error = 4,
+		rgbe_error = function ( rgbe_error_code, msg ) {
 
 			switch ( rgbe_error_code ) {
+
 				case rgbe_read_error: console.error( "THREE.RGBELoader Read Error: " + ( msg || '' ) );
 					break;
 				case rgbe_write_error: console.error( "THREE.RGBELoader Write Error: " + ( msg || '' ) );
 					break;
-				case rgbe_format_error:  console.error( "THREE.RGBELoader Bad File Format: " + ( msg || '' ) );
+				case rgbe_format_error: console.error( "THREE.RGBELoader Bad File Format: " + ( msg || '' ) );
 					break;
 				default:
-				case rgbe_memory_error:  console.error( "THREE.RGBELoader: Error: " + ( msg || '' ) );
+				case rgbe_memory_error: console.error( "THREE.RGBELoader: Error: " + ( msg || '' ) );
+
 			}
 			return RGBE_RETURN_FAILURE;
 
 		},
 
 		/* offsets to red, green, and blue components in a data (float) pixel */
-		RGBE_DATA_RED      = 0,
-		RGBE_DATA_GREEN    = 1,
-		RGBE_DATA_BLUE     = 2,
+		RGBE_DATA_RED = 0,
+		RGBE_DATA_GREEN = 1,
+		RGBE_DATA_BLUE = 2,
 
 		/* number of floats per pixel, use 4 since stored in rgba image format */
-		RGBE_DATA_SIZE     = 4,
+		RGBE_DATA_SIZE = 4,
 
 		/* flags indicating which fields in an rgbe_header_info are valid */
-		RGBE_VALID_PROGRAMTYPE      = 1,
-		RGBE_VALID_FORMAT           = 2,
-		RGBE_VALID_DIMENSIONS       = 4,
+		RGBE_VALID_PROGRAMTYPE = 1,
+		RGBE_VALID_FORMAT = 2,
+		RGBE_VALID_DIMENSIONS = 4,
 
 		NEWLINE = "\n",
 
-		fgets = function( buffer, lineLimit, consume ) {
+		fgets = function ( buffer, lineLimit, consume ) {
 
 			lineLimit = ! lineLimit ? 1024 : lineLimit;
 			var p = buffer.pos,
@@ -90,7 +92,7 @@ THREE.RGBELoader.prototype._parser = function( buffer ) {
 		},
 
 		/* minimal header reading.  modify if you want to parse more information */
-		RGBE_ReadHeader = function( buffer ) {
+		RGBE_ReadHeader = function ( buffer ) {
 
 			var line, match,
 
@@ -104,28 +106,23 @@ THREE.RGBELoader.prototype._parser = function( buffer ) {
 				// RGBE format header struct
 				header = {
 
-					valid: 0,                         /* indicate which fields are valid */
+					valid: 0, /* indicate which fields are valid */
 
-					string: '',                       /* the actual header string */
+					string: '', /* the actual header string */
 
-					comments: '',                     /* comments found in header */
+					comments: '', /* comments found in header */
 
-					programtype: 'RGBE',              /* listed at beginning of file to identify it
-													* after "#?".  defaults to "RGBE" */
+					programtype: 'RGBE', /* listed at beginning of file to identify it after "#?". defaults to "RGBE" */
 
-					format: '',                       /* RGBE format, default 32-bit_rle_rgbe */
+					format: '', /* RGBE format, default 32-bit_rle_rgbe */
 
-					gamma: 1.0,                       /* image has already been gamma corrected with
-													* given gamma.  defaults to 1.0 (no correction) */
+					gamma: 1.0, /* image has already been gamma corrected with given gamma. defaults to 1.0 (no correction) */
 
-					exposure: 1.0,                    /* a value of 1.0 in an image corresponds to
-													* <exposure> watts/steradian/m^2.
-													* defaults to 1.0 */
+					exposure: 1.0, /* a value of 1.0 in an image corresponds to <exposure> watts/steradian/m^2. defaults to 1.0 */
 
-					width: 0, height: 0               /* image dimensions, width/height */
+					width: 0, height: 0 /* image dimensions, width/height */
 
-				}
-			;
+				};
 
 			if ( buffer.pos >= buffer.byteLength || ! ( line = fgets( buffer ) ) ) {
 
@@ -198,7 +195,7 @@ THREE.RGBELoader.prototype._parser = function( buffer ) {
 
 		},
 
-		RGBE_ReadPixels_RLE = function( buffer, w, h ) {
+		RGBE_ReadPixels_RLE = function ( buffer, w, h ) {
 
 			var data_rgba, offset, pos, count, byteValue,
 				scanline_buffer, ptr, ptr_end, i, l, off, isEncodedRun,
@@ -326,8 +323,8 @@ THREE.RGBELoader.prototype._parser = function( buffer ) {
 	if ( RGBE_RETURN_FAILURE !== rgbe_header_info ) {
 
 		var w = rgbe_header_info.width,
-			h = rgbe_header_info.height
-			, image_rgba_data = RGBE_ReadPixels_RLE( byteArray.subarray( byteArray.pos ), w, h )
+			h = rgbe_header_info.height,
+			image_rgba_data = RGBE_ReadPixels_RLE( byteArray.subarray( byteArray.pos ), w, h )
 		;
 		if ( RGBE_RETURN_FAILURE !== image_rgba_data ) {
 

+ 1 - 1
examples/js/loaders/STLLoader.js

@@ -88,7 +88,7 @@ THREE.STLLoader.prototype = {
  			}
 
 			// First 5 bytes read "solid"; declare it to be an ASCII STL
-			
+
 			return false;
 
 		}

+ 1 - 1
examples/js/loaders/SVGLoader.js

@@ -22,7 +22,7 @@ THREE.SVGLoader.prototype = {
 		var loader = new THREE.FileLoader( scope.manager );
 		loader.load( url, function ( svgString ) {
 
-			var doc = parser.parseFromString( svgString, 'image/svg+xml' );  // application/xml
+			var doc = parser.parseFromString( svgString, 'image/svg+xml' ); // application/xml
 
 			onLoad( doc.documentElement );
 

+ 60 - 65
examples/js/loaders/TDSLoader.js

@@ -29,7 +29,7 @@ THREE.TDSLoader = function ( manager ) {
 THREE.TDSLoader.prototype = {
 
 	constructor: THREE.TDSLoader,
-	
+
 	/**
 	 * Load 3ds file from url.
 	 *
@@ -39,7 +39,7 @@ THREE.TDSLoader.prototype = {
 	 * @param {Function} onProgress onProgress callback.
 	 * @param {Function} onError onError callback.
 	 */
-	load : function ( url, onLoad, onProgress, onError ) {
+	load: function ( url, onLoad, onProgress, onError ) {
 
 		var scope = this;
 
@@ -63,7 +63,7 @@ THREE.TDSLoader.prototype = {
 	 * @param {String} path Path for external resources.
 	 * @return {Object3D} Group loaded from 3ds file.
 	 */
-	parse : function ( arraybuffer ) {
+	parse: function ( arraybuffer ) {
 
 		this.group = new THREE.Group();
 		this.position = 0;
@@ -88,7 +88,7 @@ THREE.TDSLoader.prototype = {
 	 * @method readFile
 	 * @param {ArrayBuffer} arraybuffer Arraybuffer data to be loaded.
 	 */
-	readFile : function ( arraybuffer ) {
+	readFile: function ( arraybuffer ) {
 
 		var data = new DataView( arraybuffer );
 		var chunk = this.readChunk( data );
@@ -131,7 +131,7 @@ THREE.TDSLoader.prototype = {
 	 * @method readMeshData
 	 * @param {Dataview} data Dataview in use.
 	 */
-	readMeshData : function ( data ) {
+	readMeshData: function ( data ) {
 
 		var chunk = this.readChunk( data );
 		var next = this.nextChunk( data, chunk );
@@ -179,7 +179,7 @@ THREE.TDSLoader.prototype = {
 	 * @method readNamedObject
 	 * @param {Dataview} data Dataview in use.
 	 */
-	readNamedObject : function ( data ) {
+	readNamedObject: function ( data ) {
 
 		var chunk = this.readChunk( data );
 		var name = this.readString( data, 64 );
@@ -215,7 +215,7 @@ THREE.TDSLoader.prototype = {
 	 * @method readMaterialEntry
 	 * @param {Dataview} data Dataview in use.
 	 */
-	readMaterialEntry : function ( data ) {
+	readMaterialEntry: function ( data ) {
 
 		var chunk = this.readChunk( data );
 		var next = this.nextChunk( data, chunk );
@@ -270,25 +270,25 @@ THREE.TDSLoader.prototype = {
 				material.shininess = shininess;
 				this.debugMessage( '   Shininess : ' + shininess );
 
-			} else if( next === MAT_TEXMAP ) {
+			} else if ( next === MAT_TEXMAP ) {
 
 				this.debugMessage( '   ColorMap' );
 				this.resetPosition( data );
 				material.map = this.readMap( data );
 
-			} else if( next === MAT_BUMPMAP ) {
+			} else if ( next === MAT_BUMPMAP ) {
 
 				this.debugMessage( '   BumpMap' );
 				this.resetPosition( data );
 				material.bumpMap = this.readMap( data );
 
-			} else if( next == MAT_OPACMAP ) {
+			} else if ( next === MAT_OPACMAP ) {
 
 				this.debugMessage( '   OpacityMap' );
 				this.resetPosition( data );
 				material.alphaMap = this.readMap( data );
 
-			} else if( next == MAT_SPECMAP ) {
+			} else if ( next === MAT_SPECMAP ) {
 
 				this.debugMessage( '   SpecularMap' );
 				this.resetPosition( data );
@@ -316,7 +316,7 @@ THREE.TDSLoader.prototype = {
 	 * @method readMesh
 	 * @param {Dataview} data Dataview in use.
 	 */
-	readMesh : function ( data ) {
+	readMesh: function ( data ) {
 
 		var chunk = this.readChunk( data );
 		var next = this.nextChunk( data, chunk );
@@ -412,44 +412,44 @@ THREE.TDSLoader.prototype = {
 				this.debugMessage( '   Tranformation Matrix (TODO)' );
 
 				var values = [];
-				for( var i = 0; i < 12; i++ ) {
+				for ( var i = 0; i < 12; i ++ ) {
 
 					values[ i ] = this.readFloat( data );
-				
+
 				}
 
 				var matrix = new THREE.Matrix4();
 
 				//X Line
-				matrix.elements[0] = values[0];
-				matrix.elements[1] = values[6];
-				matrix.elements[2] = values[3];
-				matrix.elements[3] = values[9];
+				matrix.elements[ 0 ] = values[ 0 ];
+				matrix.elements[ 1 ] = values[ 6 ];
+				matrix.elements[ 2 ] = values[ 3 ];
+				matrix.elements[ 3 ] = values[ 9 ];
 
 				//Y Line
-				matrix.elements[4] = values[2];
-				matrix.elements[5] = values[8];
-				matrix.elements[6] = values[5];
-				matrix.elements[7] = values[11];
+				matrix.elements[ 4 ] = values[ 2 ];
+				matrix.elements[ 5 ] = values[ 8 ];
+				matrix.elements[ 6 ] = values[ 5 ];
+				matrix.elements[ 7 ] = values[ 11 ];
 
 				//Z Line
-				matrix.elements[8] = values[1];
-				matrix.elements[9] = values[7];
-				matrix.elements[10] = values[4];
-				matrix.elements[11] = values[10];
+				matrix.elements[ 8 ] = values[ 1 ];
+				matrix.elements[ 9 ] = values[ 7 ];
+				matrix.elements[ 10 ] = values[ 4 ];
+				matrix.elements[ 11 ] = values[ 10 ];
 
 				//W Line
-				matrix.elements[12] = 0;
-				matrix.elements[13] = 0;
-				matrix.elements[14] = 0;
-				matrix.elements[15] = 1;
+				matrix.elements[ 12 ] = 0;
+				matrix.elements[ 13 ] = 0;
+				matrix.elements[ 14 ] = 0;
+				matrix.elements[ 15 ] = 1;
 
 				matrix.transpose();
 
 				var inverse = new THREE.Matrix4();
 				inverse.getInverse( matrix, true );
 				geometry.applyMatrix( inverse );
-				
+
 				matrix.decompose( mesh.position, mesh.quaternion, mesh.scale );
 
 			} else {
@@ -479,8 +479,8 @@ THREE.TDSLoader.prototype = {
 				}
 
 				geometry.faceVertexUvs[ 0 ] = faceUV;
-	
-			}		
+
+			}
 
 			geometry.computeVertexNormals();
 
@@ -497,7 +497,7 @@ THREE.TDSLoader.prototype = {
 	 * @param {Dataview} data Dataview in use.
 	 * @param {Mesh} mesh Mesh to be filled with the data read.
 	 */
-	readFaceArray : function ( data, mesh ) {
+	readFaceArray: function ( data, mesh ) {
 
 		var chunk = this.readChunk( data );
 		var faces = this.readWord( data );
@@ -561,7 +561,7 @@ THREE.TDSLoader.prototype = {
 	 * @param {Dataview} data Dataview in use.
 	 * @return {Texture} Texture read from this data chunk.
 	 */
-	readMap : function( data ) {
+	readMap: function ( data ) {
 
 		var chunk = this.readChunk( data );
 		var next = this.nextChunk( data, chunk );
@@ -570,7 +570,7 @@ THREE.TDSLoader.prototype = {
 		var loader = new THREE.TextureLoader();
 		loader.setPath( this.path );
 
-		while( next !== 0 ) {
+		while ( next !== 0 ) {
 
 			if ( next === MAT_MAPNAME ) {
 
@@ -579,32 +579,27 @@ THREE.TDSLoader.prototype = {
 
 				this.debugMessage( '      File: ' + this.path + name );
 
-			}
-			else if ( next === MAT_MAP_UOFFSET) {
+			} else if ( next === MAT_MAP_UOFFSET ) {
 
 				texture.offset.x = this.readFloat( data );
 				this.debugMessage( '      OffsetX: ' + texture.offset.x );
 
-			}
-			else if ( next === MAT_MAP_VOFFSET) {
+			} else if ( next === MAT_MAP_VOFFSET ) {
 
 				texture.offset.y = this.readFloat( data );
 				this.debugMessage( '      OffsetY: ' + texture.offset.y );
 
-			}
-			else if ( next === MAT_MAP_USCALE) {
+			} else if ( next === MAT_MAP_USCALE ) {
 
 				texture.repeat.x = this.readFloat( data );
 				this.debugMessage( '      RepeatX: ' + texture.repeat.x );
 
-			}
-			else if ( next === MAT_MAP_VSCALE) {
+			} else if ( next === MAT_MAP_VSCALE ) {
 
 				texture.repeat.y = this.readFloat( data );
 				this.debugMessage( '      RepeatY: ' + texture.repeat.y );
 
-			}
-			else {
+			} else {
 
 				this.debugMessage( '      Unknown map chunk: ' + next.toString( 16 ) );
 
@@ -627,7 +622,7 @@ THREE.TDSLoader.prototype = {
 	 * @param {Dataview} data Dataview in use.
 	 * @return {Object} Object with name and index of the object.
 	 */
-	readMaterialGroup : function ( data ) {
+	readMaterialGroup: function ( data ) {
 
 		var chunk = this.readChunk( data );
 		var name = this.readString( data, 64 );
@@ -654,7 +649,7 @@ THREE.TDSLoader.prototype = {
 	 * @param {DataView} data Dataview.
 	 * @return {Color} Color value read..
 	 */
-	readColor : function ( data ) {
+	readColor: function ( data ) {
 
 		var chunk = this.readChunk( data );
 		var color = new THREE.Color();
@@ -681,7 +676,7 @@ THREE.TDSLoader.prototype = {
 
 		}	else {
 
-			this.debugMessage( '      Unknown color chunk: ' + c.toString( 16 ) );
+			this.debugMessage( '      Unknown color chunk: ' + chunk.toString( 16 ) );
 
 		}
 
@@ -697,7 +692,7 @@ THREE.TDSLoader.prototype = {
 	 * @param {DataView} data Dataview.
 	 * @return {Object} Chunk of data read.
 	 */
-	readChunk : function ( data ) {
+	readChunk: function ( data ) {
 
 		var chunk = {};
 
@@ -717,7 +712,7 @@ THREE.TDSLoader.prototype = {
 	 * @method endChunk
 	 * @param {Object} chunk Data chunk.
 	 */
-	endChunk : function ( chunk ) {
+	endChunk: function ( chunk ) {
 
 		this.position = chunk.end;
 
@@ -730,7 +725,7 @@ THREE.TDSLoader.prototype = {
 	 * @param {DataView} data Dataview.
 	 * @param {Object} chunk Data chunk.
 	 */
-	nextChunk : function ( data, chunk ) {
+	nextChunk: function ( data, chunk ) {
 
 		if ( chunk.cur >= chunk.end ) {
 
@@ -761,7 +756,7 @@ THREE.TDSLoader.prototype = {
 	 * @method resetPosition
 	 * @param {DataView} data Dataview.
 	 */
-	resetPosition : function ( data, chunk ) {
+	resetPosition: function () {
 
 		this.position -= 6;
 
@@ -774,7 +769,7 @@ THREE.TDSLoader.prototype = {
 	 * @param {DataView} data Dataview to read data from.
 	 * @return {Number} Data read from the dataview.
 	 */
-	readByte : function ( data ) {
+	readByte: function ( data ) {
 
 		var v = data.getUint8( this.position, true );
 		this.position += 1;
@@ -789,7 +784,7 @@ THREE.TDSLoader.prototype = {
 	 * @param {DataView} data Dataview to read data from.
 	 * @return {Number} Data read from the dataview.
 	 */
-	readFloat : function ( data ) {
+	readFloat: function ( data ) {
 
 		try {
 
@@ -812,7 +807,7 @@ THREE.TDSLoader.prototype = {
 	 * @param {DataView} data Dataview to read data from.
 	 * @return {Number} Data read from the dataview.
 	 */
-	readInt : function ( data ) {
+	readInt: function ( data ) {
 
 		var v = data.getInt32( this.position, true );
 		this.position += 4;
@@ -827,7 +822,7 @@ THREE.TDSLoader.prototype = {
 	 * @param {DataView} data Dataview to read data from.
 	 * @return {Number} Data read from the dataview.
 	 */
-	readShort : function ( data ) {
+	readShort: function ( data ) {
 
 		var v = data.getInt16( this.position, true );
 		this.position += 2;
@@ -842,7 +837,7 @@ THREE.TDSLoader.prototype = {
 	 * @param {DataView} data Dataview to read data from.
 	 * @return {Number} Data read from the dataview.
 	 */
-	readDWord : function ( data ) {
+	readDWord: function ( data ) {
 
 		var v = data.getUint32( this.position, true );
 		this.position += 4;
@@ -857,7 +852,7 @@ THREE.TDSLoader.prototype = {
 	 * @param {DataView} data Dataview to read data from.
 	 * @return {Number} Data read from the dataview.
 	 */
-	readWord : function ( data ) {
+	readWord: function ( data ) {
 
 		var v = data.getUint16( this.position, true );
 		this.position += 2;
@@ -873,7 +868,7 @@ THREE.TDSLoader.prototype = {
 	 * @param {Number} maxLength Max size of the string to be read.
 	 * @return {String} Data read from the dataview.
 	 */
-	readString : function ( data, maxLength ) {
+	readString: function ( data, maxLength ) {
 
 		var s = '';
 
@@ -901,11 +896,12 @@ THREE.TDSLoader.prototype = {
 	 * @param {String} path Path to resources.
 	 * @return Self for chaining.
 	 */
-	setPath : function ( path ) {
+	setPath: function ( path ) {
+
+		if ( path !== undefined ) {
 
-		if(path !== undefined)
-		{
 			this.path = path;
+
 		}
 
 		return this;
@@ -920,7 +916,7 @@ THREE.TDSLoader.prototype = {
 	 * @method debugMessage
 	 * @param {Object} message Debug message to print to the console.
 	 */
-	debugMessage : function ( message ) {
+	debugMessage: function ( message ) {
 
 		if ( this.debug ) {
 
@@ -1148,4 +1144,3 @@ var VIEWPORT_DATA = 0x7011;
 var VIEWPORT_DATA_3 = 0x7012;
 var VIEWPORT_SIZE = 0x7020;
 var NETWORK_VIEW = 0x7030;
-

+ 63 - 56
examples/js/loaders/TGALoader.js

@@ -80,7 +80,7 @@ THREE.TGALoader.prototype = {
 				// Invalid type ?
 
 				default:
-					console.error( 'THREE.TGALoader: Invalid type "%s".',  header.image_type );
+					console.error( 'THREE.TGALoader: Invalid type "%s".', header.image_type );
 
 			}
 
@@ -94,7 +94,7 @@ THREE.TGALoader.prototype = {
 
 			// check image pixel size
 
-			if ( header.pixel_size !== 8  && header.pixel_size !== 16 &&
+			if ( header.pixel_size !== 8 && header.pixel_size !== 16 &&
 				header.pixel_size !== 24 && header.pixel_size !== 32 ) {
 
 				console.error( 'THREE.TGALoader: Invalid pixel size "%s".', header.pixel_size );
@@ -339,6 +339,7 @@ THREE.TGALoader.prototype = {
 				y_end;
 
 			switch ( ( header.flags & TGA_ORIGIN_MASK ) >> TGA_ORIGIN_SHIFT ) {
+
 				default:
 				case TGA_ORIGIN_UL:
 					x_start = 0;
@@ -381,20 +382,25 @@ THREE.TGALoader.prototype = {
 			if ( use_grey ) {
 
 				switch ( header.pixel_size ) {
+
 					case 8:
 						tgaGetImageDataGrey8bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image );
 						break;
+
 					case 16:
 						tgaGetImageDataGrey16bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image );
 						break;
+
 					default:
 						console.error( 'THREE.TGALoader: Format not supported.' );
 						break;
+
 				}
 
 			} else {
 
 				switch ( header.pixel_size ) {
+
 					case 8:
 						tgaGetImageData8bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image, palette );
 						break;
@@ -414,6 +420,7 @@ THREE.TGALoader.prototype = {
 					default:
 						console.error( 'THREE.TGALoader: Format not supported.' );
 						break;
+
 				}
 
 			}
@@ -428,19 +435,19 @@ THREE.TGALoader.prototype = {
 		// TGA constants
 
 		var TGA_TYPE_NO_DATA = 0,
-		TGA_TYPE_INDEXED = 1,
-		TGA_TYPE_RGB = 2,
-		TGA_TYPE_GREY = 3,
-		TGA_TYPE_RLE_INDEXED = 9,
-		TGA_TYPE_RLE_RGB = 10,
-		TGA_TYPE_RLE_GREY = 11,
-
-		TGA_ORIGIN_MASK = 0x30,
-		TGA_ORIGIN_SHIFT = 0x04,
-		TGA_ORIGIN_BL = 0x00,
-		TGA_ORIGIN_BR = 0x01,
-		TGA_ORIGIN_UL = 0x02,
-		TGA_ORIGIN_UR = 0x03;
+			TGA_TYPE_INDEXED = 1,
+			TGA_TYPE_RGB = 2,
+			TGA_TYPE_GREY = 3,
+			TGA_TYPE_RLE_INDEXED = 9,
+			TGA_TYPE_RLE_RGB = 10,
+			TGA_TYPE_RLE_GREY = 11,
+
+			TGA_ORIGIN_MASK = 0x30,
+			TGA_ORIGIN_SHIFT = 0x04,
+			TGA_ORIGIN_BL = 0x00,
+			TGA_ORIGIN_BR = 0x01,
+			TGA_ORIGIN_UL = 0x02,
+			TGA_ORIGIN_UR = 0x03;
 
 		if ( buffer.length < 19 ) console.error( 'THREE.TGALoader: Not enough data to contain header.' );
 
@@ -465,68 +472,68 @@ THREE.TGALoader.prototype = {
 
 			// check tga if it is valid format
 
-			tgaCheckHeader( header );
+		tgaCheckHeader( header );
 
-			if ( header.id_length + offset > buffer.length ) {
+		if ( header.id_length + offset > buffer.length ) {
 
-				console.error( 'THREE.TGALoader: No data.' );
+			console.error( 'THREE.TGALoader: No data.' );
 
-			}
+		}
 
-			// skip the needn't data
+		// skip the needn't data
 
-			offset += header.id_length;
+		offset += header.id_length;
 
-			// get targa information about RLE compression and palette
+		// get targa information about RLE compression and palette
 
-			var use_rle = false,
-				use_pal = false,
-				use_grey = false;
+		var use_rle = false,
+			use_pal = false,
+			use_grey = false;
 
-			switch ( header.image_type ) {
+		switch ( header.image_type ) {
 
-				case TGA_TYPE_RLE_INDEXED:
-					use_rle = true;
-					use_pal = true;
-					break;
+			case TGA_TYPE_RLE_INDEXED:
+				use_rle = true;
+				use_pal = true;
+				break;
 
-				case TGA_TYPE_INDEXED:
-					use_pal = true;
-					break;
+			case TGA_TYPE_INDEXED:
+				use_pal = true;
+				break;
 
-				case TGA_TYPE_RLE_RGB:
-					use_rle = true;
-					break;
+			case TGA_TYPE_RLE_RGB:
+				use_rle = true;
+				break;
 
-				case TGA_TYPE_RGB:
-					break;
+			case TGA_TYPE_RGB:
+				break;
 
-				case TGA_TYPE_RLE_GREY:
-					use_rle = true;
-					use_grey = true;
-					break;
+			case TGA_TYPE_RLE_GREY:
+				use_rle = true;
+				use_grey = true;
+				break;
 
-				case TGA_TYPE_GREY:
-					use_grey = true;
-					break;
+			case TGA_TYPE_GREY:
+				use_grey = true;
+				break;
 
-			}
+		}
 
-			//
+		//
 
-			var canvas = document.createElement( 'canvas' );
-			canvas.width = header.width;
-			canvas.height = header.height;
+		var canvas = document.createElement( 'canvas' );
+		canvas.width = header.width;
+		canvas.height = header.height;
 
-			var context = canvas.getContext( '2d' );
-			var imageData = context.createImageData( header.width, header.height );
+		var context = canvas.getContext( '2d' );
+		var imageData = context.createImageData( header.width, header.height );
 
-			var result = tgaParse( use_rle, use_pal, header, offset, content );
-			var rgbaData = getTgaRGBA( imageData.data, header.width, header.height, result.pixel_data, result.palettes );
+		var result = tgaParse( use_rle, use_pal, header, offset, content );
+		var rgbaData = getTgaRGBA( imageData.data, header.width, header.height, result.pixel_data, result.palettes );
 
-			context.putImageData( imageData, 0, 0 );
+		context.putImageData( imageData, 0, 0 );
 
-			return canvas;
+		return canvas;
 
 	}
 

+ 96 - 96
examples/js/loaders/UTF8Loader.js

@@ -50,7 +50,7 @@ THREE.UTF8Loader.BufferGeometryCreator.prototype.create = function ( attribArray
 
 	for ( i = offset; i < end; i += stride ) {
 
-		positions[ j ++ ] = attribArray[ i     ];
+		positions[ j ++ ] = attribArray[ i ];
 		positions[ j ++ ] = attribArray[ i + 1 ];
 		positions[ j ++ ] = attribArray[ i + 2 ];
 
@@ -63,8 +63,9 @@ THREE.UTF8Loader.BufferGeometryCreator.prototype.create = function ( attribArray
 
 	for ( i = offset; i < end; i += stride ) {
 
-		uvs[ j ++ ] = attribArray[ i     ];
+		uvs[ j ++ ] = attribArray[ i ];
 		uvs[ j ++ ] = attribArray[ i + 1 ];
+
 	}
 
 	// extract normals
@@ -74,7 +75,7 @@ THREE.UTF8Loader.BufferGeometryCreator.prototype.create = function ( attribArray
 
 	for ( i = offset; i < end; i += stride ) {
 
-		normals[ j ++ ] = attribArray[ i     ];
+		normals[ j ++ ] = attribArray[ i ];
 		normals[ j ++ ] = attribArray[ i + 1 ];
 		normals[ j ++ ] = attribArray[ i + 2 ];
 
@@ -117,18 +118,18 @@ THREE.UTF8Loader.BufferGeometryCreator.prototype.create = function ( attribArray
 
 var DEFAULT_DECODE_PARAMS = {
 
-    decodeOffsets: [ -4095, -4095, -4095, 0, 0, -511, -511, -511 ],
-    decodeScales: [ 1 / 8191, 1 / 8191, 1 / 8191, 1 / 1023, 1 / 1023, 1 / 1023, 1 / 1023, 1 / 1023 ]
+	decodeOffsets: [ - 4095, - 4095, - 4095, 0, 0, - 511, - 511, - 511 ],
+	decodeScales: [ 1 / 8191, 1 / 8191, 1 / 8191, 1 / 1023, 1 / 1023, 1 / 1023, 1 / 1023, 1 / 1023 ]
 
-    // TODO: normal decoding? (see walt.js)
-    // needs to know: input, output (from vertex format!)
-    //
-    // Should split attrib/index.
-    // 1) Decode position and non-normal attributes.
-    // 2) Decode indices, computing normals
-    // 3) Maybe normalize normals? Only necessary for refinement, or fixed?
-    // 4) Maybe refine normals? Should this be part of regular refinement?
-    // 5) Morphing
+	// TODO: normal decoding? (see walt.js)
+	// needs to know: input, output (from vertex format!)
+	//
+	// Should split attrib/index.
+	// 1) Decode position and non-normal attributes.
+	// 2) Decode indices, computing normals
+	// 3) Maybe normalize normals? Only necessary for refinement, or fixed?
+	// 4) Maybe refine normals? Should this be part of regular refinement?
+	// 5) Morphing
 
 };
 
@@ -139,15 +140,14 @@ var DEFAULT_DECODE_PARAMS = {
 // decodeScale?
 
 THREE.UTF8Loader.prototype.decompressAttribsInner_ = function ( str, inputStart, inputEnd,
-                                                                  output, outputStart, stride,
-                                                                  decodeOffset, decodeScale ) {
+	output, outputStart, stride, decodeOffset, decodeScale ) {
 
 	var prev = 0;
 
 	for ( var j = inputStart; j < inputEnd; j ++ ) {
 
 		var code = str.charCodeAt( j );
-		prev += ( code >> 1 ) ^ ( -( code & 1 ) );
+		prev += ( code >> 1 ) ^ ( - ( code & 1 ) );
 
 		output[ outputStart ] = decodeScale * ( prev + decodeOffset );
 		outputStart += stride;
@@ -156,8 +156,7 @@ THREE.UTF8Loader.prototype.decompressAttribsInner_ = function ( str, inputStart,
 
 };
 
-THREE.UTF8Loader.prototype.decompressIndices_ = function( str, inputStart, numIndices,
-                                                            output, outputStart ) {
+THREE.UTF8Loader.prototype.decompressIndices_ = function ( str, inputStart, numIndices, output, outputStart ) {
 
 	var highest = 0;
 
@@ -177,8 +176,8 @@ THREE.UTF8Loader.prototype.decompressIndices_ = function( str, inputStart, numIn
 
 };
 
-THREE.UTF8Loader.prototype.decompressAABBs_ = function ( str, inputStart, numBBoxen,
-                                                           decodeOffsets, decodeScales ) {
+THREE.UTF8Loader.prototype.decompressAABBs_ = function ( str, inputStart, numBBoxen, decodeOffsets, decodeScales ) {
+
 	var numFloats = 6 * numBBoxen;
 
 	var inputEnd = inputStart + numFloats;
@@ -188,21 +187,21 @@ THREE.UTF8Loader.prototype.decompressAABBs_ = function ( str, inputStart, numBBo
 
 	for ( var i = inputStart; i < inputEnd; i += 6 ) {
 
-		var minX = str.charCodeAt(i + 0) + decodeOffsets[0];
-		var minY = str.charCodeAt(i + 1) + decodeOffsets[1];
-		var minZ = str.charCodeAt(i + 2) + decodeOffsets[2];
+		var minX = str.charCodeAt( i + 0 ) + decodeOffsets[ 0 ];
+		var minY = str.charCodeAt( i + 1 ) + decodeOffsets[ 1 ];
+		var minZ = str.charCodeAt( i + 2 ) + decodeOffsets[ 2 ];
 
-		var radiusX = (str.charCodeAt(i + 3) + 1) >> 1;
-		var radiusY = (str.charCodeAt(i + 4) + 1) >> 1;
-		var radiusZ = (str.charCodeAt(i + 5) + 1) >> 1;
+		var radiusX = ( str.charCodeAt( i + 3 ) + 1 ) >> 1;
+		var radiusY = ( str.charCodeAt( i + 4 ) + 1 ) >> 1;
+		var radiusZ = ( str.charCodeAt( i + 5 ) + 1 ) >> 1;
 
-		bboxen[ outputStart ++ ] = decodeScales[0] * (minX + radiusX);
-		bboxen[ outputStart ++ ] = decodeScales[1] * (minY + radiusY);
-		bboxen[ outputStart ++ ] = decodeScales[2] * (minZ + radiusZ);
+		bboxen[ outputStart ++ ] = decodeScales[ 0 ] * ( minX + radiusX );
+		bboxen[ outputStart ++ ] = decodeScales[ 1 ] * ( minY + radiusY );
+		bboxen[ outputStart ++ ] = decodeScales[ 2 ] * ( minZ + radiusZ );
 
-		bboxen[ outputStart ++ ] = decodeScales[0] * radiusX;
-		bboxen[ outputStart ++ ] = decodeScales[1] * radiusY;
-		bboxen[ outputStart ++ ] = decodeScales[2] * radiusZ;
+		bboxen[ outputStart ++ ] = decodeScales[ 0 ] * radiusX;
+		bboxen[ outputStart ++ ] = decodeScales[ 1 ] * radiusY;
+		bboxen[ outputStart ++ ] = decodeScales[ 2 ] * radiusZ;
 
 	}
 
@@ -210,51 +209,49 @@ THREE.UTF8Loader.prototype.decompressAABBs_ = function ( str, inputStart, numBBo
 
 };
 
-THREE.UTF8Loader.prototype.decompressMesh =  function ( str, meshParams, decodeParams, name, idx, callback ) {
+THREE.UTF8Loader.prototype.decompressMesh = function ( str, meshParams, decodeParams, name, idx, callback ) {
 
-    // Extract conversion parameters from attribArrays.
+	// Extract conversion parameters from attribArrays.
 
 	var stride = decodeParams.decodeScales.length;
 
 	var decodeOffsets = decodeParams.decodeOffsets;
 	var decodeScales = decodeParams.decodeScales;
 
-	var attribStart = meshParams.attribRange[0];
-	var numVerts = meshParams.attribRange[1];
+	var attribStart = meshParams.attribRange[ 0 ];
+	var numVerts = meshParams.attribRange[ 1 ];
 
-    // Decode attributes.
+	// Decode attributes.
 
 	var inputOffset = attribStart;
 	var attribsOut = new Float32Array( stride * numVerts );
 
-	for (var j = 0; j < stride; j ++ ) {
+	for ( var j = 0; j < stride; j ++ ) {
 
 		var end = inputOffset + numVerts;
 
-		var decodeScale = decodeScales[j];
+		var decodeScale = decodeScales[ j ];
 
 		if ( decodeScale ) {
 
-            // Assume if decodeScale is never set, simply ignore the
-            // attribute.
+			// Assume if decodeScale is never set, simply ignore the
+			// attribute.
+
+			this.decompressAttribsInner_( str, inputOffset, end, attribsOut, j, stride, decodeOffsets[ j ], decodeScale );
 
-			this.decompressAttribsInner_( str, inputOffset, end,
-                attribsOut, j, stride,
-                decodeOffsets[j], decodeScale );
 		}
 
 		inputOffset = end;
 
 	}
 
-	var indexStart = meshParams.indexRange[ 0 ];
 	var numIndices = 3 * meshParams.indexRange[ 1 ];
 
 	var indicesOut = new Uint16Array( numIndices );
 
 	this.decompressIndices_( str, inputOffset, numIndices, indicesOut, 0 );
 
-    // Decode bboxen.
+	// Decode bboxen.
 
 	var bboxen = undefined;
 	var bboxOffset = meshParams.bboxes;
@@ -262,6 +259,7 @@ THREE.UTF8Loader.prototype.decompressMesh =  function ( str, meshParams, decodeP
 	if ( bboxOffset ) {
 
 		bboxen = this.decompressAABBs_( str, bboxOffset, meshParams.names.length, decodeOffsets, decodeScales );
+
 	}
 
 	callback( name, idx, attribsOut, indicesOut, bboxen, meshParams );
@@ -279,17 +277,17 @@ THREE.UTF8Loader.prototype.copyAttrib = function ( stride, attribsOutFixed, last
 };
 
 THREE.UTF8Loader.prototype.decodeAttrib2 = function ( str, stride, decodeOffsets, decodeScales, deltaStart,
-                                                        numVerts, attribsOut, attribsOutFixed, lastAttrib,
-                                                        index ) {
+	numVerts, attribsOut, attribsOutFixed, lastAttrib, index ) {
 
 	for ( var j = 0; j < 5; j ++ ) {
 
 		var code = str.charCodeAt( deltaStart + numVerts * j + index );
-		var delta = ( code >> 1) ^ (-(code & 1));
+		var delta = ( code >> 1 ) ^ ( - ( code & 1 ) );
 
 		lastAttrib[ j ] += delta;
 		attribsOutFixed[ stride * index + j ] = lastAttrib[ j ];
 		attribsOut[ stride * index + j ] = decodeScales[ j ] * ( lastAttrib[ j ] + decodeOffsets[ j ] );
+
 	}
 
 };
@@ -320,25 +318,25 @@ THREE.UTF8Loader.prototype.accumulateNormal = function ( i0, i1, i2, attribsOutF
 	p0y = p1z * p2x - p1x * p2z;
 	p0z = p1x * p2y - p1y * p2x;
 
-	crosses[ 3 * i0 ]     += p0x;
+	crosses[ 3 * i0 ] += p0x;
 	crosses[ 3 * i0 + 1 ] += p0y;
 	crosses[ 3 * i0 + 2 ] += p0z;
 
-	crosses[ 3 * i1 ]     += p0x;
+	crosses[ 3 * i1 ] += p0x;
 	crosses[ 3 * i1 + 1 ] += p0y;
 	crosses[ 3 * i1 + 2 ] += p0z;
 
-	crosses[ 3 * i2 ]     += p0x;
+	crosses[ 3 * i2 ] += p0x;
 	crosses[ 3 * i2 + 1 ] += p0y;
 	crosses[ 3 * i2 + 2 ] += p0z;
 
 };
 
-THREE.UTF8Loader.prototype.decompressMesh2 = function( str, meshParams, decodeParams, name, idx, callback ) {
+THREE.UTF8Loader.prototype.decompressMesh2 = function ( str, meshParams, decodeParams, name, idx, callback ) {
 
 	var MAX_BACKREF = 96;
 
-    // Extract conversion parameters from attribArrays.
+	// Extract conversion parameters from attribArrays.
 
 	var stride = decodeParams.decodeScales.length;
 
@@ -349,7 +347,6 @@ THREE.UTF8Loader.prototype.decompressMesh2 = function( str, meshParams, decodePa
 	var numVerts = meshParams.attribRange[ 1 ];
 
 	var codeStart = meshParams.codeRange[ 0 ];
-	var codeLength = meshParams.codeRange[ 1 ];
 
 	var numIndices = 3 * meshParams.codeRange[ 2 ];
 
@@ -373,7 +370,7 @@ THREE.UTF8Loader.prototype.decompressMesh2 = function( str, meshParams, decodePa
 
 		if ( code < max_backref ) {
 
-            // Parallelogram
+  		// Parallelogram
 
 			var winding = code % 3;
 			var backref = i - ( code - winding );
@@ -414,16 +411,16 @@ THREE.UTF8Loader.prototype.decompressMesh2 = function( str, meshParams, decodePa
 
 			if ( code === 0 ) {
 
-				for (var j = 0; j < 5; j ++ ) {
+				for ( var j = 0; j < 5; j ++ ) {
 
 					var deltaCode = str.charCodeAt( deltaStart + numVerts * j + highest );
 
-					var prediction = ((deltaCode >> 1) ^ (-(deltaCode & 1))) +
-                        attribsOutFixed[stride * i0 + j] +
-                        attribsOutFixed[stride * i1 + j] -
-                        attribsOutFixed[stride * i2 + j];
+					var prediction = ( ( deltaCode >> 1 ) ^ ( - ( deltaCode & 1 ) ) ) +
+						attribsOutFixed[ stride * i0 + j ] +
+						attribsOutFixed[ stride * i1 + j ] -
+						attribsOutFixed[ stride * i2 + j ];
 
-					lastAttrib[j] = prediction;
+					lastAttrib[ j ] = prediction;
 
 					attribsOutFixed[ stride * highest + j ] = prediction;
 					attribsOut[ stride * highest + j ] = decodeScales[ j ] * ( prediction + decodeOffsets[ j ] );
@@ -442,7 +439,7 @@ THREE.UTF8Loader.prototype.decompressMesh2 = function( str, meshParams, decodePa
 
 		} else {
 
-            // Simple
+			// Simple
 
 			var index0 = highest - ( code - max_backref );
 
@@ -451,12 +448,11 @@ THREE.UTF8Loader.prototype.decompressMesh2 = function( str, meshParams, decodePa
 			if ( code === max_backref ) {
 
 				this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart,
-                    numVerts, attribsOut, attribsOutFixed, lastAttrib,
-                    highest ++ );
+					numVerts, attribsOut, attribsOutFixed, lastAttrib, highest ++ );
 
 			} else {
 
-				this.copyAttrib(stride, attribsOutFixed, lastAttrib, index0);
+				this.copyAttrib( stride, attribsOutFixed, lastAttrib, index0 );
 
 			}
 
@@ -468,8 +464,7 @@ THREE.UTF8Loader.prototype.decompressMesh2 = function( str, meshParams, decodePa
 			if ( code === 0 ) {
 
 				this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart,
-                    numVerts, attribsOut, attribsOutFixed, lastAttrib,
-                    highest ++ );
+					numVerts, attribsOut, attribsOutFixed, lastAttrib, highest ++ );
 
 			} else {
 
@@ -491,8 +486,7 @@ THREE.UTF8Loader.prototype.decompressMesh2 = function( str, meshParams, decodePa
 				}
 
 				this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart,
-                    numVerts, attribsOut, attribsOutFixed, lastAttrib,
-                    highest ++ );
+					numVerts, attribsOut, attribsOutFixed, lastAttrib, highest ++ );
 
 			} else {
 
@@ -518,9 +512,10 @@ THREE.UTF8Loader.prototype.decompressMesh2 = function( str, meshParams, decodePa
 		var cy = str.charCodeAt( deltaStart + 6 * numVerts + i );
 		var cz = str.charCodeAt( deltaStart + 7 * numVerts + i );
 
-		attribsOut[ stride * i + 5 ] = norm * nx + ((cx >> 1) ^ (-(cx & 1)));
-		attribsOut[ stride * i + 6 ] = norm * ny + ((cy >> 1) ^ (-(cy & 1)));
-		attribsOut[ stride * i + 7 ] = norm * nz + ((cz >> 1) ^ (-(cz & 1)));
+		attribsOut[ stride * i + 5 ] = norm * nx + ( ( cx >> 1 ) ^ ( - ( cx & 1 ) ) );
+		attribsOut[ stride * i + 6 ] = norm * ny + ( ( cy >> 1 ) ^ ( - ( cy & 1 ) ) );
+		attribsOut[ stride * i + 7 ] = norm * nz + ( ( cz >> 1 ) ^ ( - ( cz & 1 ) ) );
+
 	}
 
 	callback( name, idx, attribsOut, indicesOut, undefined, meshParams );
@@ -555,6 +550,7 @@ THREE.UTF8Loader.prototype.downloadMesh = function ( path, name, meshEntry, deco
 				if ( data.length < meshEnd ) break;
 
 				loader.decompressMesh2( data, meshParams, decodeParams, name, idx, callback );
+
 			}
 
 			++ idx;
@@ -563,13 +559,13 @@ THREE.UTF8Loader.prototype.downloadMesh = function ( path, name, meshEntry, deco
 
 	}
 
-	getHttpRequest( path, function( data ) {
+	getHttpRequest( path, function ( data ) {
 
 		onprogress( data );
 
-        // TODO: handle errors.
+		// TODO: handle errors.
 
-	});
+	} );
 
 };
 
@@ -577,14 +573,14 @@ THREE.UTF8Loader.prototype.downloadMeshes = function ( path, meshUrlMap, decodeP
 
 	for ( var url in meshUrlMap ) {
 
-		var meshEntry = meshUrlMap[url];
+		var meshEntry = meshUrlMap[ url ];
 		this.downloadMesh( path + url, url, meshEntry, decodeParams, callback );
 
 	}
 
 };
 
-THREE.UTF8Loader.prototype.createMeshCallback = function( materialBaseUrl, loadModelInfo, allDoneCallback ) {
+THREE.UTF8Loader.prototype.createMeshCallback = function ( materialBaseUrl, loadModelInfo, allDoneCallback ) {
 
 	var nCompletedUrls = 0;
 	var nExpectedUrls = 0;
@@ -609,7 +605,7 @@ THREE.UTF8Loader.prototype.createMeshCallback = function( materialBaseUrl, loadM
 
 	var model = new THREE.Object3D();
 
-    // Prepare materials first...
+	// Prepare materials first...
 
 	var materialCreator = new THREE.MTLLoader.MaterialCreator( materialBaseUrl, loadModelInfo.options );
 	materialCreator.setMaterials( loadModelInfo.materials );
@@ -620,16 +616,16 @@ THREE.UTF8Loader.prototype.createMeshCallback = function( materialBaseUrl, loadM
 
 	var bufferGeometryCreator = new THREE.UTF8Loader.BufferGeometryCreator();
 
-	var meshCallback = function( name, idx, attribArray, indexArray, bboxen, meshParams ) {
+	var meshCallback = function ( name, idx, attribArray, indexArray, bboxen, meshParams ) {
 
-        // Got ourselves a new mesh
+		// Got ourselves a new mesh
 
-        // name identifies this part of the model (url)
-        // idx is the mesh index of this mesh of the part
-        // attribArray defines the vertices
-        // indexArray defines the faces
-        // bboxen defines the bounding box
-        // meshParams contains the material info
+		// name identifies this part of the model (url)
+		// idx is the mesh index of this mesh of the part
+		// attribArray defines the vertices
+		// indexArray defines the faces
+		// bboxen defines the bounding box
+		// meshParams contains the material info
 
 		var geometry = bufferGeometryCreator.create( attribArray, indexArray );
 		var material = materialCreator.create( meshParams.material );
@@ -637,7 +633,7 @@ THREE.UTF8Loader.prototype.createMeshCallback = function( materialBaseUrl, loadM
 		var mesh = new THREE.Mesh( geometry, material );
 		modelParts[ name ].add( mesh );
 
-        //model.add(new THREE.Mesh(geometry, material));
+		//model.add(new THREE.Mesh(geometry, material));
 
 		decodedMeshesPerUrl[ name ] ++;
 
@@ -649,7 +645,7 @@ THREE.UTF8Loader.prototype.createMeshCallback = function( materialBaseUrl, loadM
 
 			if ( nCompletedUrls === nExpectedUrls ) {
 
-                // ALL DONE!!!
+				// ALL DONE!!!
 
 				allDoneCallback( model );
 
@@ -672,7 +668,7 @@ THREE.UTF8Loader.prototype.downloadModel = function ( geometryBase, materialBase
 
 THREE.UTF8Loader.prototype.downloadModelJson = function ( jsonUrl, callback, options ) {
 
-	getJsonRequest( jsonUrl, function( loaded ) {
+	getJsonRequest( jsonUrl, function ( loaded ) {
 
 		if ( ! loaded.decodeParams ) {
 
@@ -711,7 +707,7 @@ THREE.UTF8Loader.prototype.downloadModelJson = function ( jsonUrl, callback, opt
 
 			if ( materialBase.charAt( materialBase.length - 1 ) !== "/" ) {
 
-				materialBase = materialBase  + "/";
+				materialBase = materialBase + "/";
 
 			}
 
@@ -734,19 +730,23 @@ function getHttpRequest( url, onload, opt_onprogress ) {
 
 function getJsonRequest( url, onjson ) {
 
-	getHttpRequest( url,
-        function( e ) { onjson( JSON.parse( e ) ); },
-        function() {} );
+	getHttpRequest( url, function ( e ) {
+
+		onjson( JSON.parse( e ) );
+
+	},
+	function () {} );
 
 }
 
 function addListeners( dom, listeners ) {
 
-    // TODO: handle event capture, object binding.
+	// TODO: handle event capture, object binding.
 
 	for ( var key in listeners ) {
 
 		dom.addEventListener( key, listeners[ key ] );
 
 	}
+
 }

+ 93 - 78
examples/js/loaders/VRMLLoader.js

@@ -16,7 +16,7 @@ THREE.VRMLLoader.prototype = {
 	isRecordingPoints: false,
 	isRecordingFaces: false,
 	points: [],
-	indexes : [],
+	indexes: [],
 
 	// for Background support
 	isRecordingAngles: false,
@@ -54,11 +54,11 @@ THREE.VRMLLoader.prototype = {
 		var textureLoader = new THREE.TextureLoader( this.manager );
 		textureLoader.setCrossOrigin( this.crossOrigin );
 
-		function parseV1( lines, scene ) {
+		function parseV1() {
 
 			console.warn( 'THREE.VRMLLoader: V1.0 not supported yet.' );
 
-		};
+		}
 
 		function parseV2( lines, scene ) {
 
@@ -179,7 +179,7 @@ THREE.VRMLLoader.prototype = {
 
 				geometry.addAttribute( 'color', colorAttribute );
 
-			};
+			}
 
 			var index = [];
 
@@ -193,7 +193,7 @@ THREE.VRMLLoader.prototype = {
 				 */
 				var regex = /[^\s,\[\]]+/g;
 
-				var point, angles, colors;
+				var point;
 
 				while ( null !== ( part = regex.exec( line ) ) ) {
 
@@ -206,6 +206,7 @@ THREE.VRMLLoader.prototype = {
 
 				// trigger several recorders
 				switch ( fieldName ) {
+
 					case 'skyAngle':
 					case 'groundAngle':
 						this.recordingFieldname = fieldName;
@@ -232,6 +233,7 @@ THREE.VRMLLoader.prototype = {
 						this.isRecordingFaces = true;
 						this.indexes = [];
 						break;
+
 				}
 
 				if ( this.isRecordingFaces ) {
@@ -283,36 +285,40 @@ THREE.VRMLLoader.prototype = {
 						index = [];
 
 						this.isRecordingFaces = false;
-						node[this.recordingFieldname] = this.indexes;
+						node[ this.recordingFieldname ] = this.indexes;
 
 					}
 
 				} else if ( this.isRecordingPoints ) {
 
-					if ( node.nodeType == 'Coordinate' )
+					if ( node.nodeType == 'Coordinate' ) {
 
-					while ( null !== ( parts = float3_pattern.exec( line ) ) ) {
+						while ( null !== ( parts = float3_pattern.exec( line ) ) ) {
 
-						point = {
-							x: parseFloat( parts[ 1 ] ),
-							y: parseFloat( parts[ 2 ] ),
-							z: parseFloat( parts[ 3 ] )
-						};
+							point = {
+								x: parseFloat( parts[ 1 ] ),
+								y: parseFloat( parts[ 2 ] ),
+								z: parseFloat( parts[ 3 ] )
+							};
+
+							this.points.push( point );
 
-						this.points.push( point );
+						}
 
 					}
 
-					if ( node.nodeType == 'TextureCoordinate' )
+					if ( node.nodeType == 'TextureCoordinate' ) {
 
-					while ( null !== ( parts = float2_pattern.exec( line ) ) ) {
+						while ( null !== ( parts = float2_pattern.exec( line ) ) ) {
 
-						point = {
-							x: parseFloat( parts[ 1 ] ),
-							y: parseFloat( parts[ 2 ] )
-						};
+							point = {
+								x: parseFloat( parts[ 1 ] ),
+								y: parseFloat( parts[ 2 ] )
+							};
+
+							this.points.push( point );
 
-						this.points.push( point );
+						}
 
 					}
 
@@ -470,6 +476,7 @@ THREE.VRMLLoader.prototype = {
 							property = parts[ 1 ] === 'TRUE' ? true : false;
 
 							break;
+
 					}
 
 					node[ fieldName ] = property;
@@ -478,7 +485,7 @@ THREE.VRMLLoader.prototype = {
 
 				return property;
 
-			};
+			}
 
 			function getTree( lines ) {
 
@@ -494,7 +501,7 @@ THREE.VRMLLoader.prototype = {
 					var line = lines[ i ];
 
 					// omit whitespace only lines
-					if ( null !== ( result = /^\s+?$/g.exec( line ) ) ) {
+					if ( null !== ( /^\s+?$/g.exec( line ) ) ) {
 
 						continue;
 
@@ -525,7 +532,7 @@ THREE.VRMLLoader.prototype = {
 
 						// first subpattern should match the Node name
 
-						var block = { 'nodeType' : matches[ 1 ], 'string': line, 'parent': current, 'children': [], 'comment' : comment };
+						var block = { 'nodeType': matches[ 1 ], 'string': line, 'parent': current, 'children': [], 'comment': comment };
 						current.children.push( block );
 						current = block;
 
@@ -559,7 +566,7 @@ THREE.VRMLLoader.prototype = {
 
 				return tree;
 
-			};
+			}
 
 			function parseNode( data, parent ) {
 
@@ -610,7 +617,7 @@ THREE.VRMLLoader.prototype = {
 
 				object = parent;
 
-				if ( data.string.indexOf( 'AmbientLight') > - 1 && data.nodeType === 'PointLight' ) {
+				if ( data.string.indexOf( 'AmbientLight' ) > - 1 && data.nodeType === 'PointLight' ) {
 
 					data.nodeType = 'AmbientLight';
 
@@ -626,7 +633,7 @@ THREE.VRMLLoader.prototype = {
 
 				}
 
-				if ( 'AmbientLight' === data.nodeType){
+				if ( 'AmbientLight' === data.nodeType ) {
 
 					object = new THREE.AmbientLight( l_color, l_intensity );
 					object.visible = l_visible;
@@ -635,43 +642,43 @@ THREE.VRMLLoader.prototype = {
 
 				} else if ( 'PointLight' === data.nodeType ) {
 
-						var l_distance = 0;
+					var l_distance = 0;
 
-						if ( data.radius !== undefined && data.radius < 1000 ){
+					if ( data.radius !== undefined && data.radius < 1000 ) {
 
-							l_distance = data.radius;
+						l_distance = data.radius;
 
-						}
+					}
 
-						object=new THREE.PointLight( l_color, l_intensity, l_distance );
-						object.visible = l_visible;
+					object = new THREE.PointLight( l_color, l_intensity, l_distance );
+					object.visible = l_visible;
 
-						parent.add( object );
+					parent.add( object );
 
 				} else if ( 'SpotLight' === data.nodeType ) {
 
-						var l_intensity = 1;
-						var l_distance = 0;
-						var l_angle = Math.PI/3;
-						var l_penumbra = 0;
-						var l_visible = true;
+					var l_intensity = 1;
+					var l_distance = 0;
+					var l_angle = Math.PI / 3;
+					var l_penumbra = 0;
+					var l_visible = true;
 
-						if ( data.radius !== undefined && data.radius < 1000 ) {
+					if ( data.radius !== undefined && data.radius < 1000 ) {
 
-							l_distance = data.radius;
+						l_distance = data.radius;
 
-						}
+					}
 
-						if ( data.cutOffAngle !== undefined ) {
+					if ( data.cutOffAngle !== undefined ) {
 
-							l_angle = data.cutOffAngle;
+						l_angle = data.cutOffAngle;
 
-						}
+					}
 
-						object = new THREE.SpotLight( l_color, l_intensity, l_distance, l_angle, l_penumbra );
-						object.visible = l_visible;
+					object = new THREE.SpotLight( l_color, l_intensity, l_distance, l_angle, l_penumbra );
+					object.visible = l_visible;
 
-						parent.add( object );
+					parent.add( object );
 
 				} else if ( 'Transform' === data.nodeType || 'Group' === data.nodeType ) {
 
@@ -739,7 +746,7 @@ THREE.VRMLLoader.prototype = {
 
 						paintFaces( skyGeometry, radius, data.skyAngle, data.skyColor, true );
 
-						skyMaterial.vertexColors = THREE.VertexColors
+						skyMaterial.vertexColors = THREE.VertexColors;
 
 					} else {
 
@@ -789,7 +796,6 @@ THREE.VRMLLoader.prototype = {
 
 						var geometry = new THREE.BufferGeometry();
 
-						var index = [];
 						var positions = [];
 						var uvs = [];
 
@@ -833,7 +839,7 @@ THREE.VRMLLoader.prototype = {
 
 								}
 
-								if ( child.string.indexOf ( 'DEF' ) > - 1 ) {
+								if ( child.string.indexOf( 'DEF' ) > - 1 ) {
 
 									var name = /DEF\s+([^\s]+)/.exec( child.string )[ 1 ];
 
@@ -841,7 +847,7 @@ THREE.VRMLLoader.prototype = {
 
 								}
 
-								if ( child.string.indexOf ( 'USE' ) > - 1 ) {
+								if ( child.string.indexOf( 'USE' ) > - 1 ) {
 
 									var defineKey = /USE\s+([^\s]+)/.exec( child.string )[ 1 ];
 
@@ -1006,9 +1012,9 @@ THREE.VRMLLoader.prototype = {
 
 						if ( 'ImageTexture' === child.nodeType ) {
 
-							var textureName = /"([^"]+)"/.exec(child.children[ 0 ]);
+							var textureName = /"([^"]+)"/.exec( child.children[ 0 ] );
 
-							if (textureName) {
+							if ( textureName ) {
 
 								parent.material.name = textureName[ 1 ];
 
@@ -1030,48 +1036,57 @@ THREE.VRMLLoader.prototype = {
 
 				}
 
-			};
+			}
 
 			parseNode( getTree( lines ), scene );
 
-		};
+		}
 
 		var scene = new THREE.Scene();
 
 		var lines = data.split( '\n' );
 
 		// some lines do not have breaks
-		for (var i = lines.length -1; i > -1; i--) {
+		for ( var i = lines.length - 1; i > - 1; i -- ) {
 
 			// split lines with {..{ or {..[ - some have both
-			if (/{.*[{\[]/.test (lines[i])) {
-				var parts = lines[i].split ('{').join ('{\n').split ('\n');
-				parts.unshift(1);
-				parts.unshift(i);
-				lines.splice.apply(lines, parts);
-			} else
-
-			// split lines with ]..}
-			if (/\].*}/.test (lines[i])) {
-				var parts = lines[i].split (']').join (']\n').split ('\n');
-				parts.unshift(1);
-				parts.unshift(i);
-				lines.splice.apply(lines, parts);
+			if ( /{.*[{\[]/.test( lines[ i ] ) ) {
+
+				var parts = lines[ i ].split( '{' ).join( '{\n' ).split( '\n' );
+				parts.unshift( 1 );
+				parts.unshift( i );
+				lines.splice.apply( lines, parts );
+
+			} else if ( /\].*}/.test( lines[ i ] ) ) {
+
+				// split lines with ]..}
+				var parts = lines[ i ].split( ']' ).join( ']\n' ).split( '\n' );
+				parts.unshift( 1 );
+				parts.unshift( i );
+				lines.splice.apply( lines, parts );
+
 			}
 
-			// split lines with }..}
-			if (/}.*}/.test (lines[i])) {
-				var parts = lines[i].split ('}').join ('}\n').split ('\n');
-				parts.unshift(1);
-				parts.unshift(i);
-				lines.splice.apply(lines, parts);
+			if ( /}.*}/.test( lines[ i ] ) ) {
+
+				// split lines with }..}
+
+				var parts = lines[ i ].split( '}' ).join( '}\n' ).split( '\n' );
+				parts.unshift( 1 );
+				parts.unshift( i );
+				lines.splice.apply( lines, parts );
+
 			}
 
 			// force the parser to create Coordinate node for empty coords
 			// coord USE something -> coord USE something Coordinate {}
-			if((lines[i].indexOf ('coord') > -1) && (lines[i].indexOf ('[') < 0) && (lines[i].indexOf ('{') < 0)) {
-				lines[i] += ' Coordinate {}';
+
+			if ( ( lines[ i ].indexOf( 'coord' ) > - 1 ) && ( lines[ i ].indexOf( '[' ) < 0 ) && ( lines[ i ].indexOf( '{' ) < 0 ) ) {
+
+				lines[ i ] += ' Coordinate {}';
+
 			}
+
 		}
 
 		var header = lines.shift();

+ 185 - 124
examples/js/loaders/VTKLoader.js

@@ -1,7 +1,7 @@
 /**
  * @author mrdoob / http://mrdoob.com/
  * @author Alex Pletzer
- * 
+ *
  * Updated on 22.03.2017
  * VTK header is now parsed and used to extract all the compressed data
  * @author Andrii Iudin https://github.com/andreyyudin
@@ -9,7 +9,7 @@
  * @author Sriram Somasundharam https://github.com/raamssundar
  */
 
-THREE.VTKLoader = function( manager ) {
+THREE.VTKLoader = function ( manager ) {
 
 	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
 
@@ -23,7 +23,7 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 
 		var loader = new THREE.FileLoader( scope.manager );
 		loader.setResponseType( 'arraybuffer' );
-		loader.load( url, function( text ) {
+		loader.load( url, function ( text ) {
 
 			onLoad( scope.parse( text ) );
 
@@ -286,7 +286,6 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 
 				var numTriangles = indices.length / 3;
 				var numPoints = positions.length / 3;
-				var va, vb, vc;
 				var face;
 				var ia, ib, ic;
 				var x, y, z;
@@ -332,9 +331,9 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 
 		function parseBinary( data ) {
 
-			var count, pointIndex, i, numberOfPoints, pt, s;
-			var buffer = new Uint8Array ( data );
-			var dataView = new DataView ( data );
+			var count, pointIndex, i, numberOfPoints, s;
+			var buffer = new Uint8Array( data );
+			var dataView = new DataView( data );
 
 			// Points and normals, by default, are empty
 			var points = [];
@@ -352,16 +351,16 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 				var s = [];
 				while ( c != 10 ) {
 
-					s.push ( String.fromCharCode ( c ) );
+					s.push( String.fromCharCode( c ) );
 					index ++;
 					c = buffer[ index ];
 
 				}
 
 				return { start: start,
-						end: index,
-						next: index + 1,
-						parsedString: s.join( '' ) };
+					end: index,
+					next: index + 1,
+					parsedString: s.join( '' ) };
 
 			}
 
@@ -370,14 +369,14 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 			while ( true ) {
 
 				// Get a string
-				state = findString ( buffer, index );
+				state = findString( buffer, index );
 				line = state.parsedString;
 
-				if ( line.indexOf ( 'POINTS' ) === 0 ) {
+				if ( line.indexOf( 'POINTS' ) === 0 ) {
 
-					vtk.push ( line );
+					vtk.push( line );
 					// Add the points
-					numberOfPoints = parseInt ( line.split( ' ' )[ 1 ], 10 );
+					numberOfPoints = parseInt( line.split( ' ' )[ 1 ], 10 );
 
 					// Each point is 3 4-byte floats
 					count = numberOfPoints * 4 * 3;
@@ -396,10 +395,10 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 					// increment our next pointer
 					state.next = state.next + count + 1;
 
-				} else if ( line.indexOf ( 'TRIANGLE_STRIPS' ) === 0 ) {
+				} else if ( line.indexOf( 'TRIANGLE_STRIPS' ) === 0 ) {
 
-					var numberOfStrips = parseInt ( line.split( ' ' )[ 1 ], 10 );
-					var size = parseInt ( line.split ( ' ' )[ 2 ], 10 );
+					var numberOfStrips = parseInt( line.split( ' ' )[ 1 ], 10 );
+					var size = parseInt( line.split( ' ' )[ 2 ], 10 );
 					// 4 byte integers
 					count = size * 4;
 
@@ -415,7 +414,7 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 						pointIndex += 4;
 						for ( s = 0; s < indexCount; s ++ ) {
 
-							strip.push ( dataView.getInt32( pointIndex, false ) );
+							strip.push( dataView.getInt32( pointIndex, false ) );
 							pointIndex += 4;
 
 						}
@@ -444,10 +443,10 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 					// increment our next pointer
 					state.next = state.next + count + 1;
 
-				} else if ( line.indexOf ( 'POLYGONS' ) === 0 ) {
+				} else if ( line.indexOf( 'POLYGONS' ) === 0 ) {
 
-					var numberOfStrips = parseInt ( line.split( ' ' )[ 1 ], 10 );
-					var size = parseInt ( line.split ( ' ' )[ 2 ], 10 );
+					var numberOfStrips = parseInt( line.split( ' ' )[ 1 ], 10 );
+					var size = parseInt( line.split( ' ' )[ 2 ], 10 );
 					// 4 byte integers
 					count = size * 4;
 
@@ -463,11 +462,11 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 						pointIndex += 4;
 						for ( s = 0; s < indexCount; s ++ ) {
 
-							strip.push ( dataView.getInt32( pointIndex, false ) );
+							strip.push( dataView.getInt32( pointIndex, false ) );
 							pointIndex += 4;
 
 						}
-						var i0 = strip[ 0 ];
+
 						// divide the polygon in n-2 triangle
 						for ( var j = 1; j < indexCount - 1; j ++ ) {
 
@@ -481,12 +480,12 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 					// increment our next pointer
 					state.next = state.next + count + 1;
 
-				} else if ( line.indexOf ( 'POINT_DATA' ) === 0 ) {
+				} else if ( line.indexOf( 'POINT_DATA' ) === 0 ) {
 
-					numberOfPoints = parseInt ( line.split( ' ' )[ 1 ], 10 );
+					numberOfPoints = parseInt( line.split( ' ' )[ 1 ], 10 );
 
 					// Grab the next line
-					state = findString ( buffer, state.next );
+					state = findString( buffer, state.next );
 
 					// Now grab the binary data
 					count = numberOfPoints * 4 * 3;
@@ -532,24 +531,26 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 
 		}
 
-		function Float32Concat(first, second) {
-		    var firstLength = first.length,
-		        result = new Float32Array(firstLength + second.length);
+		function Float32Concat( first, second ) {
+
+		    var firstLength = first.length, result = new Float32Array( firstLength + second.length );
 
-		    result.set(first);
-		    result.set(second, firstLength);
+		    result.set( first );
+		    result.set( second, firstLength );
 
 		    return result;
+
 		}
 
-		function Int32Concat(first, second) {
-		    var firstLength = first.length,
-		        result = new Int32Array(firstLength + second.length);
+		function Int32Concat( first, second ) {
+
+		    var firstLength = first.length, result = new Int32Array( firstLength + second.length );
 
-		    result.set(first);
-		    result.set(second, firstLength);
+		    result.set( first );
+		    result.set( second, firstLength );
 
 		    return result;
+
 		}
 
 		function parseXML( stringFile ) {
@@ -596,7 +597,7 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 						var item = xml.childNodes.item( i );
 						var nodeName = item.nodeName;
 
-						if ( typeof( obj[ nodeName ] ) === 'undefined' ) {
+						if ( typeof obj[ nodeName ] === 'undefined' ) {
 
 							var tmp = xmlToJson( item );
 
@@ -604,7 +605,7 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 
 						} else {
 
-							if ( typeof( obj[ nodeName ].push ) === 'undefined' ) {
+							if ( typeof obj[ nodeName ].push === 'undefined' ) {
 
 								var old = obj[ nodeName ];
 								obj[ nodeName ] = [ old ];
@@ -692,106 +693,151 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 			}
 
 			function parseDataArray( ele, compressed ) {
+
 				var numBytes = 0;
-				if ( json.attributes.header_type == 'UInt64' )
+
+				if ( json.attributes.header_type == 'UInt64' ) {
+
 					numBytes = 8;
-				else if( json.attributes.header_type == 'UInt32' )
+
+				}	else if ( json.attributes.header_type == 'UInt32' ) {
+
 					numBytes = 4;
 
+				}
+
+
 				// Check the format
 				if ( ele.attributes.format == 'binary' && compressed ) {
-						var rawData, content, byteData, blocks, cSizeStart, headerSize, padding, dataOffsets, currentOffset;
 
-						if ( ele.attributes.type == 'Float32' ) {
-							var txt = new Float32Array( );
-						} else if ( ele.attributes.type === 'Int64' ) {
-							var txt = new Int32Array( );
-						}
+					var rawData, content, byteData, blocks, cSizeStart, headerSize, padding, dataOffsets, currentOffset;
+
+					if ( ele.attributes.type == 'Float32' ) {
+
+						var txt = new Float32Array( );
+
+					} else if ( ele.attributes.type === 'Int64' ) {
+
+						var txt = new Int32Array( );
+
+					}
+
+					// VTP data with the header has the following structure:
+					// [#blocks][#u-size][#p-size][#c-size-1][#c-size-2]...[#c-size-#blocks][DATA]
+					//
+					// Each token is an integer value whose type is specified by "header_type" at the top of the file (UInt32 if no type specified). The token meanings are:
+					// [#blocks] = Number of blocks
+					// [#u-size] = Block size before compression
+					// [#p-size] = Size of last partial block (zero if it not needed)
+					// [#c-size-i] = Size in bytes of block i after compression
+					//
+					// The [DATA] portion stores contiguously every block appended together. The offset from the beginning of the data section to the beginning of a block is
+					// computed by summing the compressed block sizes from preceding blocks according to the header.
+
+					rawData = ele[ '#text' ];
+
+					byteData = Base64toByteArray( rawData );
+
+					blocks = byteData[ 0 ];
+					for ( var i = 1; i < numBytes - 1; i ++ ) {
+
+						blocks = blocks | ( byteData[ i ] << ( i * numBytes ) );
+
+					}
+
+					headerSize = ( blocks + 3 ) * numBytes;
+					padding = ( ( headerSize % 3 ) > 0 ) ? 3 - ( headerSize % 3 ) : 0;
+					headerSize = headerSize + padding;
+
+					dataOffsets = [];
+					currentOffset = headerSize;
+					dataOffsets.push( currentOffset );
+
+					// Get the blocks sizes after the compression.
+					// There are three blocks before c-size-i, so we skip 3*numBytes
+					cSizeStart = 3 * numBytes;
+
+					for ( var i = 0; i < blocks; i ++ ) {
+
+						var currentBlockSize = byteData[ i * numBytes + cSizeStart ];
+
+						for ( var j = 1; j < numBytes - 1; j ++ ) {
+
+							// Each data point consists of 8 bytes regardless of the header type
+							currentBlockSize = currentBlockSize | ( byteData[ i * numBytes + cSizeStart + j ] << ( j * 8 ) );
 
-						// VTP data with the header has the following structure:
-						// [#blocks][#u-size][#p-size][#c-size-1][#c-size-2]...[#c-size-#blocks][DATA]
-						//
-						// Each token is an integer value whose type is specified by "header_type" at the top of the file (UInt32 if no type specified). The token meanings are:
-						// [#blocks] = Number of blocks
-						// [#u-size] = Block size before compression
-						// [#p-size] = Size of last partial block (zero if it not needed)
-						// [#c-size-i] = Size in bytes of block i after compression
-						//
-						// The [DATA] portion stores contiguously every block appended together. The offset from the beginning of the data section to the beginning of a block is 
-						// computed by summing the compressed block sizes from preceding blocks according to the header. 
-
-						rawData = ele[ '#text' ];
-
-						byteData = Base64toByteArray( rawData );
-
-						blocks = byteData[0]
-						for ( var i = 1; i<numBytes-1; i++ ) {
-							blocks = blocks | ( byteData[i] << (i*numBytes) );
 						}
 
-						headerSize = (blocks + 3) * numBytes;
-						padding = ( (headerSize % 3) > 0 ) ? 3 - (headerSize % 3) : 0;
-						headerSize = headerSize + padding;
-						
-						dataOffsets = [];
-						currentOffset = headerSize;
+						currentOffset = currentOffset + currentBlockSize;
 						dataOffsets.push( currentOffset );
 
-						// Get the blocks sizes after the compression.
-						// There are three blocks before c-size-i, so we skip 3*numBytes
-						cSizeStart = 3*numBytes;
-						for ( var i = 0; i<blocks; i++ ) {
-							var currentBlockSize = byteData[i*numBytes + cSizeStart];
-							for ( var j = 1; j<numBytes-1; j++ ) {
-								// Each data point consists of 8 bytes regardless of the header type
-								currentBlockSize = currentBlockSize | ( byteData[i*numBytes + cSizeStart + j] << (j*8) );
-							}
-							
-							currentOffset = currentOffset + currentBlockSize;
-							dataOffsets.push( currentOffset );
+					}
+
+					for ( var i = 0; i < dataOffsets.length - 1; i ++ ) {
+
+						var inflate = new Zlib.Inflate( byteData.slice( dataOffsets[ i ], dataOffsets[ i + 1 ] ), { resize: true, verify: true } ); // eslint-disable-line no-undef
+						content = inflate.decompress();
+						content = content.buffer;
+
+						if ( ele.attributes.type == 'Float32' ) {
+
+							content = new Float32Array( content );
+							txt = Float32Concat( txt, content );
+
+						} else if ( ele.attributes.type === 'Int64' ) {
+
+							content = new Int32Array( content );
+							txt = Int32Concat( txt, content );
+
 						}
 
-						for ( var i=0; i<dataOffsets.length-1; i++ ) {
-							var inflate = new Zlib.Inflate( byteData.slice( dataOffsets[i], dataOffsets[i+1] ), { resize: true, verify: true } );
-							content = inflate.decompress();
-							content = content.buffer;
-
-							if ( ele.attributes.type == 'Float32' ) {
-								content = new Float32Array( content );
-								txt = Float32Concat(txt, content);
-							} else if ( ele.attributes.type === 'Int64' ) {
-								content = new Int32Array( content );
-								txt = Int32Concat(txt, content);
+					}
+
+					delete ele[ '#text' ];
+
+					// Get the content and optimize it
+					if ( ele.attributes.type == 'Float32' ) {
+
+						if ( ele.attributes.format == 'binary' ) {
+
+							if ( ! compressed ) {
+
+								txt = txt.filter( function ( el, idx ) {
+
+									if ( idx !== 0 ) return true;
+
+								} );
+
 							}
+
 						}
 
-						delete ele[ '#text' ];
+					} else if ( ele.attributes.type === 'Int64' ) {
 
-						// Get the content and optimize it
-						if ( ele.attributes.type == 'Float32' ) {
-							if ( ele.attributes.format == 'binary' ) {
-								if ( ! compressed ) {
-									txt = txt.filter( function( el, idx, arr ) {
-										if ( idx !== 0 ) return true;
-									} );
-								}
-							}
+						if ( ele.attributes.format == 'binary' ) {
 
-						} else if ( ele.attributes.type === 'Int64' ) {
-							if ( ele.attributes.format == 'binary' ) {
-								if ( ! compressed ) {
-									txt = txt.filter( function ( el, idx, arr ) {
-										if ( idx !== 0 ) return true;
-									} );
-								}
+							if ( ! compressed ) {
+
+								txt = txt.filter( function ( el, idx ) {
+
+									if ( idx !== 0 ) return true;
 
-								txt = txt.filter( function ( el, idx, arr ) {
-									if ( idx % 2 !== 1 ) return true;
 								} );
+
 							}
+
+							txt = txt.filter( function ( el, idx ) {
+
+								if ( idx % 2 !== 1 ) return true;
+
+							} );
+
 						}
 
+					}
+
 				} else {
+
 					if ( ele.attributes.format == 'binary' && ! compressed ) {
 
 						var content = Base64toByteArray( ele[ '#text' ] );
@@ -799,16 +845,22 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 						//  VTP data for the uncompressed case has the following structure:
 						// [#bytes][DATA]
 						// where "[#bytes]" is an integer value specifying the number of bytes in the block of data following it.
-						content = content.slice(numBytes).buffer;
+						content = content.slice( numBytes ).buffer;
 
 					} else {
 
 						if ( ele[ '#text' ] ) {
-							var content = ele[ '#text' ].replace( /\n/g, ' ' ).split( ' ' ).filter( function ( el, idx, arr ) {
+
+							var content = ele[ '#text' ].replace( /\n/g, ' ' ).split( ' ' ).filter( function ( el ) {
+
 								if ( el !== '' ) return el;
+
 							} );
+
 						} else {
+
 							var content = new Int32Array( 0 ).buffer;
+
 						}
 
 					}
@@ -821,13 +873,19 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 						var txt = new Float32Array( content );
 
 					} else if ( ele.attributes.type === 'Int64' ) {
+
 						var txt = new Int32Array( content );
 
 						if ( ele.attributes.format == 'binary' ) {
-							txt = txt.filter( function ( el, idx, arr ) {
+
+							txt = txt.filter( function ( el, idx ) {
+
 								if ( idx % 2 !== 1 ) return true;
+
 							} );
+
 						}
+
 					}
 
 				} // endif ( ele.attributes.format == 'binary' && compressed )
@@ -856,10 +914,10 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 
 				try {
 
-					dom = new ActiveXObject( 'Microsoft.XMLDOM' );
+					dom = new ActiveXObject( 'Microsoft.XMLDOM' ); // eslint-disable-line no-undef
 					dom.async = false;
 
-					if ( ! dom.loadXML( xml ) ) {
+					if ( ! dom.loadXML( /* xml */ ) ) {
 
 						throw new Error( dom.parseError.reason + dom.parseError.srcText );
 
@@ -920,10 +978,13 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 						while ( dataArrayIndex < numberOfDataArrays ) {
 
 							// Parse the DataArray
-							if ( ('#text' in arr[ dataArrayIndex ]) && (arr[ dataArrayIndex ][ '#text' ].length > 0) ) {
+							if ( ( '#text' in arr[ dataArrayIndex ] ) && ( arr[ dataArrayIndex ][ '#text' ].length > 0 ) ) {
+
 								arr[ dataArrayIndex ].text = parseDataArray( arr[ dataArrayIndex ], compressed );
+
 							}
-								dataArrayIndex ++;
+
+							dataArrayIndex ++;
 
 						}
 
@@ -985,13 +1046,13 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 
 									var indicesIndex = 0;
 
-									for ( var i = 0,len = numberOfStrips; i < len; i ++ ) {
+									for ( var i = 0, len = numberOfStrips; i < len; i ++ ) {
 
 										var strip = [];
 
 										for ( var s = 0, len1 = offset[ i ], len0 = 0; s < len1 - len0; s ++ ) {
 
-											strip.push ( connectivity[ s ] );
+											strip.push( connectivity[ s ] );
 
 											if ( i > 0 ) len0 = offset[ i - 1 ];
 
@@ -1038,7 +1099,7 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 									var size = numberOfPolys + connectivity.length;
 									indices = new Uint32Array( 3 * size - 9 * numberOfPolys );
 									var indicesIndex = 0, connectivityIndex = 0;
-									var i = 0,len = numberOfPolys, len0 = 0;
+									var i = 0, len = numberOfPolys, len0 = 0;
 
 									while ( i < len ) {
 

+ 0 - 1455
examples/js/loaders/WWOBJLoader2.js

@@ -1,1455 +0,0 @@
-/**
-  * @author Kai Salmen / https://kaisalmen.de
-  * Development repository: https://github.com/kaisalmen/WWOBJLoader
-  */
-
-'use strict';
-
-if ( THREE.OBJLoader2 === undefined ) { THREE.OBJLoader2 = {} }
-
-/**
- * OBJ data will be loaded by dynamically created web worker.
- * First feed instructions with: prepareRun
- * Then: Execute with: run
- * @class
- */
-THREE.OBJLoader2.WWOBJLoader2 = (function () {
-
-	var WWOBJLOADER2_VERSION = '1.4.1';
-
-	var Validator = THREE.OBJLoader2.prototype._getValidator();
-
-	function WWOBJLoader2() {
-		this._init();
-	}
-
-	WWOBJLoader2.prototype._init = function () {
-		console.log( "Using THREE.OBJLoader2.WWOBJLoader2 version: " + WWOBJLOADER2_VERSION );
-
-		// check worker support first
-		if ( window.Worker === undefined ) throw "This browser does not support web workers!";
-		if ( window.Blob === undefined  ) throw "This browser does not support Blob!";
-		if ( typeof window.URL.createObjectURL !== 'function'  ) throw "This browser does not support Object creation from URL!";
-
-		this.instanceNo = 0;
-		this.worker = null;
-		this.workerCode = null;
-		this.debug = false;
-
-		this.sceneGraphBaseNode = null;
-		this.streamMeshes = true;
-		this.meshStore = null;
-		this.modelName = '';
-		this.validated = false;
-		this.running = false;
-		this.requestTerminate = false;
-
-		this.clearAllCallbacks();
-
-		this.manager = THREE.DefaultLoadingManager;
-		this.fileLoader = new THREE.FileLoader( this.manager );
-		this.mtlLoader = null;
-		this.crossOrigin = null;
-
-		this.dataAvailable = false;
-		this.objAsArrayBuffer = null;
-		this.fileObj = null;
-		this.pathObj = null;
-
-		this.fileMtl = null;
-		this.mtlAsString = null;
-		this.texturePath = null;
-
-		this.materials = [];
-		this.counter = 0;
-	};
-
-	/**
-	 * Enable or disable debug logging.
-	 * @memberOf THREE.OBJLoader2.WWOBJLoader2
-	 *
-	 * @param {boolean} enabled True or false
-	 */
-	WWOBJLoader2.prototype.setDebug = function ( enabled ) {
-		this.debug = enabled;
-	};
-
-	/**
-	 * Sets the CORS string to be used.
-	 * @memberOf THREE.OBJLoader2.WWOBJLoader2
-	 *
-	 * @param {string} crossOrigin CORS value
-	 */
-	WWOBJLoader2.prototype.setCrossOrigin = function ( crossOrigin ) {
-		this.crossOrigin = crossOrigin;
-	};
-
-	/**
-	 * Register callback function that is invoked by internal function "_announceProgress" to print feedback.
-	 * @memberOf THREE.OBJLoader2.WWOBJLoader2
-	 *
-	 * @param {callback} callbackProgress Callback function for described functionality
-	 */
-	WWOBJLoader2.prototype.registerCallbackProgress = function ( callbackProgress ) {
-		if ( Validator.isValid( callbackProgress ) ) this.callbacks.progress.push( callbackProgress );
-	};
-
-	/**
-	 * Register callback function that is called once loading of the complete model is completed.
-	 * @memberOf THREE.OBJLoader2.WWOBJLoader2
-	 *
-	 * @param {callback} callbackCompletedLoading Callback function for described functionality
-	 */
-	WWOBJLoader2.prototype.registerCallbackCompletedLoading = function ( callbackCompletedLoading ) {
-		if ( Validator.isValid( callbackCompletedLoading ) ) this.callbacks.completedLoading.push( callbackCompletedLoading );
-	};
-
-	/**
-	 * Register callback function that is called once materials have been loaded. It allows to alter and return materials.
-	 * @memberOf THREE.OBJLoader2.WWOBJLoader2
-	 *
-	 * @param {callback} callbackMaterialsLoaded Callback function for described functionality
-	 */
-	WWOBJLoader2.prototype.registerCallbackMaterialsLoaded = function ( callbackMaterialsLoaded ) {
-		if ( Validator.isValid( callbackMaterialsLoaded ) ) this.callbacks.materialsLoaded.push( callbackMaterialsLoaded );
-	};
-
-	/**
-	 * Register callback function that is called every time a mesh was loaded.
-	 * Use {@link THREE.OBJLoader2.WWOBJLoader2.LoadedMeshUserOverride} for alteration instructions (geometry, material or disregard mesh).
-	 * @memberOf THREE.OBJLoader2.WWOBJLoader2
-	 *
-	 * @param {callback} callbackMeshLoaded Callback function for described functionality
-	 */
-	WWOBJLoader2.prototype.registerCallbackMeshLoaded = function ( callbackMeshLoaded ) {
-		if ( Validator.isValid( callbackMeshLoaded ) ) this.callbacks.meshLoaded.push( callbackMeshLoaded );
-	};
-
-	/**
-	 * Register callback function that is called to report an error that prevented loading.
-	 * @memberOf THREE.OBJLoader2.WWOBJLoader2
-	 *
-	 * @param {callback} callbackErrorWhileLoading Callback function for described functionality
-	 */
-	WWOBJLoader2.prototype.registerCallbackErrorWhileLoading = function ( callbackErrorWhileLoading ) {
-		if ( Validator.isValid( callbackErrorWhileLoading ) ) this.callbacks.errorWhileLoading.push( callbackErrorWhileLoading );
-	};
-
-	/**
-	 * Clears all registered callbacks.
-	 * @memberOf THREE.OBJLoader2.WWOBJLoader2
-	 */
-	WWOBJLoader2.prototype.clearAllCallbacks = function () {
-		this.callbacks = {
-			progress: [],
-			completedLoading: [],
-			errorWhileLoading: [],
-			materialsLoaded: [],
-			meshLoaded: []
-		};
-	};
-
-	/**
-	 * Call requestTerminate to terminate the web worker and free local resource after execution.
-	 * @memberOf THREE.OBJLoader2.WWOBJLoader2
-	 *
-	 * @param {boolean} requestTerminate True or false
-	 */
-	WWOBJLoader2.prototype.setRequestTerminate = function ( requestTerminate ) {
-		this.requestTerminate = requestTerminate === true;
-	};
-
-	WWOBJLoader2.prototype._validate = function () {
-		if ( this.validated ) return;
-		if ( ! Validator.isValid( this.worker ) ) {
-
-			this._buildWebWorkerCode();
-			var blob = new Blob( [ this.workerCode ], { type: 'text/plain' } );
-			this.worker = new Worker( window.URL.createObjectURL( blob ) );
-
-			var scope = this;
-			var scopeFunction = function ( e ) {
-				scope._receiveWorkerMessage( e );
-			};
-			this.worker.addEventListener( 'message', scopeFunction, false );
-
-		}
-
-		this.sceneGraphBaseNode = null;
-		this.streamMeshes = true;
-		this.meshStore = [];
-		this.modelName = '';
-		this.validated = true;
-		this.running = true;
-		this.requestTerminate = false;
-
-		this.fileLoader = Validator.verifyInput( this.fileLoader, new THREE.FileLoader( this.manager ) );
-		this.mtlLoader = Validator.verifyInput( this.mtlLoader, new THREE.MTLLoader() );
-		if ( Validator.isValid( this.crossOrigin ) ) this.mtlLoader.setCrossOrigin( this.crossOrigin );
-
-		this.dataAvailable = false;
-		this.fileObj = null;
-		this.pathObj = null;
-		this.fileMtl = null;
-		this.texturePath = null;
-
-		this.objAsArrayBuffer = null;
-		this.mtlAsString = null;
-
-		this.materials = [];
-		var defaultMaterial = new THREE.MeshStandardMaterial( { color: 0xDCF1FF } );
-		defaultMaterial.name = 'defaultMaterial';
-		this.materials[ defaultMaterial.name ] = defaultMaterial;
-
-		var vertexColorMaterial = new THREE.MeshBasicMaterial( { color: 0xDCF1FF } );
-		vertexColorMaterial.name = 'vertexColorMaterial';
-		vertexColorMaterial.vertexColors = THREE.VertexColors;
-		this.materials[ 'vertexColorMaterial' ] = vertexColorMaterial;
-
-		this.counter = 0;
-	};
-
-	/**
-	 * Set all parameters for required for execution of "run".
-	 * @memberOf THREE.OBJLoader2.WWOBJLoader2
-	 *
-	 * @param {Object} params Either {@link THREE.OBJLoader2.WWOBJLoader2.PrepDataArrayBuffer} or {@link THREE.OBJLoader2.WWOBJLoader2.PrepDataFile}
-	 */
-	WWOBJLoader2.prototype.prepareRun = function ( params ) {
-		this._validate();
-		this.dataAvailable = params.dataAvailable;
-		this.modelName = params.modelName;
-		console.time( 'WWOBJLoader2' );
-		if ( this.dataAvailable ) {
-
-			// fast-fail on bad type
-			if ( ! ( params.objAsArrayBuffer instanceof Uint8Array ) ) {
-				throw 'Provided input is not of type arraybuffer! Aborting...';
-			}
-
-			this.worker.postMessage( {
-				cmd: 'init',
-				debug: this.debug
-			} );
-
-			this.objAsArrayBuffer = params.objAsArrayBuffer;
-			this.mtlAsString = params.mtlAsString;
-
-		} else {
-
-			// fast-fail on bad type
-			if ( ! ( typeof( params.fileObj ) === 'string' || params.fileObj instanceof String ) ) {
-				throw 'Provided file is not properly defined! Aborting...';
-			}
-
-			this.worker.postMessage( {
-				cmd: 'init',
-				debug: this.debug
-			} );
-
-			this.fileObj = params.fileObj;
-			this.pathObj = params.pathObj;
-			this.fileMtl = params.fileMtl;
-
-		}
-		this.setRequestTerminate( params.requestTerminate );
-		this.pathTexture = params.pathTexture;
-		this.sceneGraphBaseNode = params.sceneGraphBaseNode;
-		this.streamMeshes = params.streamMeshes;
-		if ( ! this.streamMeshes ) this.meshStore = [];
-	};
-
-	/**
-	 * Run the loader according the preparation instruction provided in "prepareRun".
-	 * @memberOf THREE.OBJLoader2.WWOBJLoader2
-	 */
-	WWOBJLoader2.prototype.run = function () {
-		var scope = this;
-		var processLoadedMaterials = function ( materialCreator ) {
-			var materialCreatorMaterials = [];
-			var materialNames = [];
-			if ( Validator.isValid( materialCreator ) ) {
-
-				materialCreator.preload();
-				materialCreatorMaterials = materialCreator.materials;
-				for ( var materialName in materialCreatorMaterials ) {
-
-					if ( materialCreatorMaterials.hasOwnProperty( materialName ) ) {
-
-						materialNames.push( materialName );
-						scope.materials[ materialName ] = materialCreatorMaterials[ materialName ];
-
-					}
-
-				}
-
-			}
-			scope.worker.postMessage( {
-				cmd: 'setMaterials',
-				materialNames: materialNames
-			} );
-
-			var materialsFromCallback;
-			var callbackMaterialsLoaded;
-			for ( var index in scope.callbacks.materialsLoaded ) {
-
-				callbackMaterialsLoaded = scope.callbacks.materialsLoaded[ index ];
-				materialsFromCallback = callbackMaterialsLoaded( scope.materials );
-				if ( Validator.isValid( materialsFromCallback ) ) scope.materials = materialsFromCallback;
-
-			}
-			if ( scope.dataAvailable && scope.objAsArrayBuffer ) {
-
-				scope.worker.postMessage({
-					cmd: 'run',
-					objAsArrayBuffer: scope.objAsArrayBuffer
-				}, [ scope.objAsArrayBuffer.buffer ] );
-
-			} else {
-
-				var refPercentComplete = 0;
-				var percentComplete = 0;
-				var onLoad = function ( objAsArrayBuffer ) {
-
-					scope._announceProgress( 'Running web worker!' );
-					scope.objAsArrayBuffer = new Uint8Array( objAsArrayBuffer );
-					scope.worker.postMessage( {
-						cmd: 'run',
-						objAsArrayBuffer: scope.objAsArrayBuffer
-					}, [ scope.objAsArrayBuffer.buffer ] );
-
-				};
-
-				var onProgress = function ( event ) {
-					if ( ! event.lengthComputable ) return;
-
-					percentComplete = Math.round( event.loaded / event.total * 100 );
-					if ( percentComplete > refPercentComplete ) {
-
-						refPercentComplete = percentComplete;
-						var output = 'Download of "' + scope.fileObj + '": ' + percentComplete + '%';
-						console.log( output );
-						scope._announceProgress( output );
-
-					}
-				};
-
-				var onError = function ( event ) {
-					var output = 'Error occurred while downloading "' + scope.fileObj + '"';
-					console.error( output + ': ' + event );
-					scope._announceProgress( output );
-					scope._finalize( 'error' );
-
-				};
-
-				scope.fileLoader.setPath( scope.pathObj );
-				scope.fileLoader.setResponseType( 'arraybuffer' );
-				scope.fileLoader.load( scope.fileObj, onLoad, onProgress, onError );
-			}
-			console.timeEnd( 'Loading MTL textures' );
-		};
-
-
-		this.mtlLoader.setPath( this.pathTexture );
-		if ( this.dataAvailable ) {
-
-			processLoadedMaterials( Validator.isValid( this.mtlAsString ) ? this.mtlLoader.parse( this.mtlAsString ) : null );
-
-		} else {
-
-			if ( Validator.isValid( this.fileMtl ) ) {
-
-				var onError = function ( event ) {
-					var output = 'Error occurred while downloading "' + scope.fileMtl + '"';
-					console.error( output + ': ' + event );
-					scope._announceProgress( output );
-					scope._finalize( 'error' );
-				};
-
-				this.mtlLoader.load( this.fileMtl, processLoadedMaterials, undefined, onError );
-
-			} else {
-
-				processLoadedMaterials();
-
-			}
-
-		}
-	};
-
-	WWOBJLoader2.prototype._receiveWorkerMessage = function ( event ) {
-		var payload = event.data;
-
-		switch ( payload.cmd ) {
-			case 'objData':
-
-				this.counter++;
-				var meshName = payload.meshName;
-
-				var bufferGeometry = new THREE.BufferGeometry();
-				bufferGeometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( payload.vertices ), 3 ) );
-				var haveVertexColors = Validator.isValid( payload.colors );
-				if ( haveVertexColors ) {
-
-					bufferGeometry.addAttribute( 'color', new THREE.BufferAttribute( new Float32Array( payload.colors ), 3 ) );
-
-				}
-				if ( Validator.isValid( payload.normals ) ) {
-
-					bufferGeometry.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( payload.normals ), 3 ) );
-
-				} else {
-
-					bufferGeometry.computeVertexNormals();
-
-				}
-				if ( Validator.isValid( payload.uvs ) ) {
-
-					bufferGeometry.addAttribute( 'uv', new THREE.BufferAttribute( new Float32Array( payload.uvs ), 2 ) );
-
-				}
-
-				var materialDescriptions = payload.materialDescriptions;
-				var materialDescription;
-				var material;
-				var materialName;
-				var createMultiMaterial = payload.multiMaterial;
-				var multiMaterials = [];
-
-				var key;
-				for ( key in materialDescriptions ) {
-
-					materialDescription = materialDescriptions[ key ];
-					material = haveVertexColors ? this.materials[ 'vertexColorMaterial' ] : this.materials[ materialDescription.name ];
-					if ( ! material ) material = this.materials[ 'defaultMaterial' ];
-
-					if ( materialDescription.default ) {
-
-						material = this.materials[ 'defaultMaterial' ];
-
-					} else if ( materialDescription.flat ) {
-
-						materialName = material.name + '_flat';
-						var materialClone = this.materials[ materialName ];
-						if ( ! materialClone ) {
-
-							materialClone = material.clone();
-							materialClone.name = materialName;
-							materialClone.flatShading = true;
-							this.materials[ materialName ] = name;
-
-						}
-
-					}
-
-					if ( materialDescription.vertexColors ) material.vertexColors = THREE.VertexColors;
-					if ( createMultiMaterial ) multiMaterials.push( material );
-
-				}
-				if ( createMultiMaterial ) {
-
-					material = multiMaterials;
-					var materialGroups = payload.materialGroups;
-					var materialGroup;
-					for ( key in materialGroups ) {
-
-						materialGroup = materialGroups[ key ];
-						bufferGeometry.addGroup( materialGroup.start, materialGroup.count, materialGroup.index );
-
-					}
-
-				}
-
-				var callbackMeshLoaded;
-				var callbackMeshLoadedResult;
-				var disregardMesh = false;
-				for ( var index in this.callbacks.meshLoaded ) {
-
-					callbackMeshLoaded = this.callbacks.meshLoaded[ index ];
-					callbackMeshLoadedResult = callbackMeshLoaded( meshName, bufferGeometry, material );
-
-					if ( Validator.isValid( callbackMeshLoadedResult ) ) {
-
-						if ( callbackMeshLoadedResult.disregardMesh ) {
-
-							// if one callback disregards the mesh, then processing stops
-							disregardMesh = true;
-							break;
-
-						}
-						if ( callbackMeshLoadedResult.replaceBufferGeometry ) bufferGeometry = callbackMeshLoadedResult.bufferGeometry;
-						if ( callbackMeshLoadedResult.replaceMaterial ) material = callbackMeshLoadedResult.material;
-
-					}
-
-				}
-
-				if ( !disregardMesh ) {
-
-					var mesh = new THREE.Mesh( bufferGeometry, material );
-					mesh.name = meshName;
-
-					if ( this.streamMeshes ) {
-
-						this.sceneGraphBaseNode.add( mesh );
-
-					} else {
-
-						this.meshStore.push( mesh );
-
-					}
-					this._announceProgress( 'Adding mesh (' + this.counter + '):', meshName );
-
-				} else {
-
-					this._announceProgress( 'Removing mesh:', meshName );
-
-				}
-				break;
-
-			case 'complete':
-
-				if ( ! this.streamMeshes ) {
-
-					for ( var meshStoreKey in this.meshStore ) {
-
-						if ( this.meshStore.hasOwnProperty( meshStoreKey ) ) this.sceneGraphBaseNode.add( this.meshStore[ meshStoreKey ] );
-
-					}
-
-				}
-
-				console.timeEnd( 'WWOBJLoader2' );
-				if ( Validator.isValid( payload.msg ) ) {
-
-					this._announceProgress( payload.msg );
-
-				} else {
-
-					this._announceProgress( '' );
-
-				}
-
-				this._finalize( 'complete' );
-				break;
-
-			case 'report_progress':
-				this._announceProgress( '', payload.output );
-				break;
-
-			default:
-				console.error( 'Received unknown command: ' + payload.cmd );
-				break;
-
-		}
-	};
-
-	WWOBJLoader2.prototype._terminate = function () {
-		if ( Validator.isValid( this.worker ) ) {
-
-			if ( this.running ) throw 'Unable to gracefully terminate worker as it is currently running!';
-
-			this.worker.terminate();
-			this.worker = null;
-			this.workerCode = null;
-			this._finalize( 'terminate' );
-
-		}
-		this.fileLoader = null;
-		this.mtlLoader = null;
-	};
-
-	WWOBJLoader2.prototype._finalize = function ( reason, requestTerminate ) {
-		this.running = false;
-		var index;
-		var callback;
-
-		if ( reason === 'complete' ) {
-
-			for ( index in this.callbacks.completedLoading ) {
-
-				callback = this.callbacks.completedLoading[ index ];
-				callback( this.modelName, this.instanceNo, this.requestTerminate );
-
-			}
-
-		} else if ( reason === 'error' ) {
-
-			for ( index in this.callbacks.errorWhileLoading ) {
-
-				callback = this.callbacks.errorWhileLoading[ index ];
-				callback( this.modelName, this.instanceNo, this.requestTerminate );
-
-			}
-
-		}
-		this.validated = false;
-
-		this.setRequestTerminate( requestTerminate );
-
-		if ( this.requestTerminate ) {
-			this._terminate();
-		}
-	};
-
-	WWOBJLoader2.prototype._announceProgress = function ( baseText, text ) {
-		var output = Validator.isValid( baseText ) ? baseText: "";
-		output = Validator.isValid( text ) ? output + " " + text : output;
-
-		var callbackProgress;
-		for ( var index in this.callbacks.progress ) {
-
-			callbackProgress = this.callbacks.progress[ index ];
-			callbackProgress( output, this.instanceNo );
-
-		}
-
-		if ( this.debug ) console.log( output );
-	};
-
-	WWOBJLoader2.prototype._buildWebWorkerCode = function ( existingWorkerCode ) {
-		if ( Validator.isValid( existingWorkerCode ) ) this.workerCode = existingWorkerCode;
-		if ( ! Validator.isValid( this.workerCode ) ) {
-
-			console.time( 'buildWebWorkerCode' );
-			var wwDef = (function () {
-
-				function WWOBJLoader() {
-					this.wwMeshCreator = new WWMeshCreator();
-					this.parser = new Parser( this.wwMeshCreator );
-					this.validated = false;
-					this.cmdState = 'created';
-
-					this.debug = false;
-				}
-
-				/**
-				 * Allows to set debug mode for the parser and the meshCreatorDebug
-				 *
-				 * @param parserDebug
-				 * @param meshCreatorDebug
-				 */
-				WWOBJLoader.prototype.setDebug = function ( parserDebug, meshCreatorDebug ) {
-					this.parser.setDebug( parserDebug );
-					this.wwMeshCreator.setDebug( meshCreatorDebug );
-				};
-
-				/**
-				 * Validate status, then parse arrayBuffer, finalize and return objGroup
-				 *
-				 * @param arrayBuffer
-				 */
-				WWOBJLoader.prototype.parse = function ( arrayBuffer ) {
-					console.log( 'Parsing arrayBuffer...' );
-					console.time( 'parseArrayBuffer' );
-
-					this.validate();
-					this.parser.parseArrayBuffer( arrayBuffer );
-					var objGroup = this._finalize();
-
-					console.timeEnd( 'parseArrayBuffer' );
-
-					return objGroup;
-				};
-
-				WWOBJLoader.prototype.validate = function () {
-					if ( this.validated ) return;
-
-					this.parser.validate();
-					this.wwMeshCreator.validate();
-
-					this.validated = true;
-				};
-
-				WWOBJLoader.prototype._finalize = function () {
-					console.log( 'Global output object count: ' + this.wwMeshCreator.globalObjectCount );
-					this.parser.finalize();
-					this.wwMeshCreator.finalize();
-					this.validated = false;
-				};
-
-				WWOBJLoader.prototype.init = function ( payload ) {
-					this.cmdState = 'init';
-					this.setDebug( payload.debug, payload.debug );
-				};
-
-				WWOBJLoader.prototype.setMaterials = function ( payload ) {
-					this.cmdState = 'setMaterials';
-					this.wwMeshCreator.setMaterials( payload.materialNames );
-				};
-
-				WWOBJLoader.prototype.run = function ( payload ) {
-					this.cmdState = 'run';
-
-					this.parse( payload.objAsArrayBuffer );
-					console.log( 'OBJ loading complete!' );
-
-					this.cmdState = 'complete';
-					self.postMessage( {
-						cmd: this.cmdState,
-						msg: null
-					} );
-				};
-
-				return WWOBJLoader;
-			})();
-
-			var wwMeshCreatorDef = (function () {
-
-				function WWMeshCreator() {
-					this.materials = null;
-					this.debug = false;
-					this.globalObjectCount = 1;
-					this.validated = false;
-				}
-
-				WWMeshCreator.prototype.setMaterials = function ( materials ) {
-					this.materials = Validator.verifyInput( materials, this.materials );
-					this.materials = Validator.verifyInput( this.materials, { materials: [] } );
-				};
-
-				WWMeshCreator.prototype.setDebug = function ( debug ) {
-					if ( debug === true || debug === false ) this.debug = debug;
-				};
-
-				WWMeshCreator.prototype.validate = function () {
-					if ( this.validated ) return;
-
-					this.setMaterials( null );
-					this.setDebug( null );
-					this.globalObjectCount = 1;
-				};
-
-				WWMeshCreator.prototype.finalize = function () {
-					this.materials = null;
-					this.validated = false;
-				};
-
-				/**
-				 * RawObjectDescriptions are transformed to THREE.Mesh.
-				 * It is ensured that rawObjectDescriptions only contain objects with vertices (no need to check).
-				 *
-				 * @param rawObjectDescriptions
-				 * @param inputObjectCount
-				 * @param absoluteVertexCount
-				 * @param absoluteNormalCount
-				 * @param absoluteUvCount
-				 */
-				WWMeshCreator.prototype.buildMesh = function ( rawObjectDescriptions, inputObjectCount, absoluteVertexCount,
-															   absoluteColorCount, absoluteNormalCount, absoluteUvCount ) {
-					if ( this.debug ) console.log( 'OBJLoader.buildMesh:\nInput object no.: ' + inputObjectCount );
-
-					var vertexFA = new Float32Array( absoluteVertexCount );
-					var colorFA = ( absoluteColorCount > 0 ) ? new Float32Array( absoluteColorCount ) : null;
-					var normalFA = ( absoluteNormalCount > 0 ) ? new Float32Array( absoluteNormalCount ) : null;
-					var uvFA = ( absoluteUvCount > 0 ) ? new Float32Array( absoluteUvCount ) : null;
-
-					var rawObjectDescription;
-					var materialDescription;
-					var materialDescriptions = [];
-
-					var createMultiMaterial = ( rawObjectDescriptions.length > 1 );
-					var materialIndex = 0;
-					var materialIndexMapping = [];
-					var selectedMaterialIndex;
-					var materialGroup;
-					var materialGroups = [];
-
-					var vertexFAOffset = 0;
-					var vertexGroupOffset = 0;
-					var vertexLength;
-					var colorFAOffset = 0;
-					var normalFAOffset = 0;
-					var uvFAOffset = 0;
-
-					for ( var oodIndex in rawObjectDescriptions ) {
-						if ( ! rawObjectDescriptions.hasOwnProperty( oodIndex ) ) continue;
-						rawObjectDescription = rawObjectDescriptions[ oodIndex ];
-
-						materialDescription = {
-							name: rawObjectDescription.materialName,
-							flat: false,
-							vertexColors: false,
-							default: false
-						};
-						if ( this.materials[ materialDescription.name ] === null ) {
-
-							materialDescription.default = true;
-							console.warn( 'object_group "' + rawObjectDescription.objectName + '_' + rawObjectDescription.groupName + '" was defined without material! Assigning "defaultMaterial".' );
-
-						}
-						// Attach '_flat' to materialName in case flat shading is needed due to smoothingGroup 0
-						if ( rawObjectDescription.smoothingGroup === 0 ) materialDescription.flat = true;
-
-						vertexLength = rawObjectDescription.vertices.length;
-						if ( createMultiMaterial ) {
-
-							// re-use material if already used before. Reduces materials array size and eliminates duplicates
-
-							selectedMaterialIndex = materialIndexMapping[ materialDescription.name ];
-							if ( ! selectedMaterialIndex ) {
-
-								selectedMaterialIndex = materialIndex;
-								materialIndexMapping[ materialDescription.name ] = materialIndex;
-								materialDescriptions.push( materialDescription );
-								materialIndex++;
-
-							}
-							materialGroup = {
-								start: vertexGroupOffset,
-								count: vertexLength / 3,
-								index: selectedMaterialIndex
-							};
-							materialGroups.push( materialGroup );
-							vertexGroupOffset += vertexLength / 3;
-
-						} else {
-
-							materialDescriptions.push( materialDescription );
-
-						}
-
-						vertexFA.set( rawObjectDescription.vertices, vertexFAOffset );
-						vertexFAOffset += vertexLength;
-
-						if ( colorFA ) {
-
-							colorFA.set( rawObjectDescription.colors, colorFAOffset );
-							colorFAOffset += rawObjectDescription.colors.length;
-							materialDescription.vertexColors = true;
-
-						}
-
-						if ( normalFA ) {
-
-							normalFA.set( rawObjectDescription.normals, normalFAOffset );
-							normalFAOffset += rawObjectDescription.normals.length;
-
-						}
-						if ( uvFA ) {
-
-							uvFA.set( rawObjectDescription.uvs, uvFAOffset );
-							uvFAOffset += rawObjectDescription.uvs.length;
-
-						}
-						if ( this.debug ) this.printReport( rawObjectDescription, selectedMaterialIndex );
-
-					}
-
-					self.postMessage(
-						{
-							cmd: 'objData',
-							meshName: rawObjectDescription.groupName !== '' ? rawObjectDescription.groupName : rawObjectDescription.objectName,
-							multiMaterial: createMultiMaterial,
-							materialDescriptions: materialDescriptions,
-							materialGroups: materialGroups,
-							vertices: vertexFA,
-							colors: colorFA,
-							normals: normalFA,
-							uvs: uvFA
-						},
-						[ vertexFA.buffer ],
-						colorFA !== null ? [ colorFA.buffer ] : null,
-						normalFA !== null ? [ normalFA.buffer ] : null,
-						uvFA !== null ? [ uvFA.buffer ] : null
-					);
-
-					this.globalObjectCount++;
-				};
-
-				WWMeshCreator.prototype.printReport = function ( rawObjectDescription, selectedMaterialIndex ) {
-					var materialIndexLine = Validator.isValid( selectedMaterialIndex ) ? '\n materialIndex: ' + selectedMaterialIndex : '';
-					console.log(
-						' Output Object no.: ' + this.globalObjectCount +
-						'\n objectName: ' + rawObjectDescription.objectName +
-						'\n groupName: ' + rawObjectDescription.groupName +
-						'\n materialName: ' + rawObjectDescription.materialName +
-						materialIndexLine +
-						'\n smoothingGroup: ' + rawObjectDescription.smoothingGroup +
-						'\n #vertices: ' + rawObjectDescription.vertices.length / 3 +
-						'\n #colors: ' + rawObjectDescription.colors.length / 3 +
-						'\n #uvs: ' + rawObjectDescription.uvs.length / 2 +
-						'\n #normals: ' + rawObjectDescription.normals.length / 3
-					);
-				};
-
-				return WWMeshCreator;
-			})();
-
-			var wwObjLoaderRunnerDef = (function () {
-
-				function WWOBJLoaderRunner() {
-					self.addEventListener( 'message', this.runner, false );
-				}
-
-				WWOBJLoaderRunner.prototype.runner = function ( event ) {
-					var payload = event.data;
-
-					console.log( 'Command state before: ' + WWOBJLoaderRef.cmdState );
-
-					switch ( payload.cmd ) {
-						case 'init':
-
-							WWOBJLoaderRef.init( payload );
-							break;
-
-						case 'setMaterials':
-
-							WWOBJLoaderRef.setMaterials( payload );
-							break;
-
-						case 'run':
-
-							WWOBJLoaderRef.run( payload );
-							break;
-
-						default:
-
-							console.error( 'OBJLoader: Received unknown command: ' + payload.cmd );
-							break;
-
-					}
-
-					console.log( 'Command state after: ' + WWOBJLoaderRef.cmdState );
-				};
-
-				return WWOBJLoaderRunner;
-			})();
-
-			var buildObject = function ( fullName, object ) {
-				var objectString = fullName + ' = {\n';
-				var part;
-				for ( var name in object ) {
-
-					part = object[ name ];
-					if ( typeof( part ) === 'string' || part instanceof String ) {
-
-						part = part.replace( '\n', '\\n' );
-						part = part.replace( '\r', '\\r' );
-						objectString += '\t' + name + ': "' + part + '",\n';
-
-					} else if ( part instanceof Array ) {
-
-						objectString += '\t' + name + ': [' + part + '],\n';
-
-					} else if ( Number.isInteger( part ) ) {
-
-						objectString += '\t' + name + ': ' + part + ',\n';
-
-					} else if ( typeof part === 'function' ) {
-
-						objectString += '\t' + name + ': ' + part + ',\n';
-
-					}
-
-				}
-				objectString += '}\n\n';
-
-				return objectString;
-			};
-
-			var buildSingelton = function ( fullName, internalName, object ) {
-				var objectString = fullName + ' = (function () {\n\n';
-				objectString += '\t' + object.prototype.constructor.toString() + '\n\n';
-
-				var funcString;
-				var objectPart;
-				for ( var name in object.prototype ) {
-
-					objectPart = object.prototype[ name ];
-					if ( typeof objectPart === 'function' ) {
-
-						funcString = objectPart.toString();
-						objectString += '\t' + internalName + '.prototype.' + name + ' = ' + funcString + ';\n\n';
-
-					}
-
-				}
-				objectString += '\treturn ' + internalName + ';\n';
-				objectString += '})();\n\n';
-
-				return objectString;
-			};
-
-			this.workerCode = '';
-			this.workerCode += '/**\n';
-			this.workerCode += '  * This code was constructed by WWOBJLoader2._buildWebWorkerCode\n';
-			this.workerCode += '  */\n\n';
-
-			// parser re-construction
-			this.workerCode += THREE.OBJLoader2.prototype._buildWebWorkerCode( buildObject, buildSingelton );
-
-			// web worker construction
-			this.workerCode += buildSingelton( 'WWOBJLoader', 'WWOBJLoader', wwDef );
-			this.workerCode += buildSingelton( 'WWMeshCreator', 'WWMeshCreator', wwMeshCreatorDef );
-			this.workerCode += 'WWOBJLoaderRef = new WWOBJLoader();\n\n';
-			this.workerCode += buildSingelton( 'WWOBJLoaderRunner', 'WWOBJLoaderRunner', wwObjLoaderRunnerDef );
-			this.workerCode += 'new WWOBJLoaderRunner();\n\n';
-
-			console.timeEnd( 'buildWebWorkerCode' );
-		}
-
-		return this.workerCode;
-	};
-
-	return WWOBJLoader2;
-
-})();
-
-/**
- * Instruction to configure {@link THREE.OBJLoader2.WWOBJLoader2}.prepareRun to load OBJ from given ArrayBuffer and MTL from given String.
- *
- * @param {string} modelName Overall name of the model
- * @param {Uint8Array} objAsArrayBuffer OBJ file content as ArrayBuffer
- * @param {string} pathTexture Path to texture files
- * @param {string} mtlAsString MTL file content as string
- *
- * @returns {{modelName: string, dataAvailable: boolean, objAsArrayBuffer: null, pathTexture: null, mtlAsString: null, sceneGraphBaseNode: null, streamMeshes: boolean, requestTerminate: boolean}}
- * @constructor
- */
-THREE.OBJLoader2.WWOBJLoader2.PrepDataArrayBuffer = function ( modelName, objAsArrayBuffer, pathTexture, mtlAsString ) {
-
-	var Validator = THREE.OBJLoader2.prototype._getValidator();
-
-	return {
-
-		/**
-		 * {@link THREE.Object3D} where meshes will be attached.
-		 * @memberOf THREE.OBJLoader2.WWOBJLoader2.PrepDataArrayBuffer
-		 *
-		 * @param {THREE.Object3D} sceneGraphBaseNode Scene graph object
-		 */
-		setSceneGraphBaseNode: function ( sceneGraphBaseNode ) {
-			this.sceneGraphBaseNode = Validator.verifyInput( sceneGraphBaseNode, null );
-		},
-
-		/**
-		 * Singles meshes are directly integrated into scene when loaded or later.
-		 * @memberOf THREE.OBJLoader2.WWOBJLoader2.PrepDataArrayBuffer
-		 *
-		 * @param {boolean} streamMeshes=true Default is true
-		 */
-		setStreamMeshes: function ( streamMeshes ) {
-			this.streamMeshes = streamMeshes !== false;
-		},
-
-		/**
-		 * Request termination of web worker and free local resources after execution.
-		 * @memberOf THREE.OBJLoader2.WWOBJLoader2.PrepDataArrayBuffer
-		 *
-		 * @param {boolean} requestTerminate=false Default is false
-		 */
-		setRequestTerminate: function ( requestTerminate ) {
-			this.requestTerminate = requestTerminate === true;
-		},
-
-		/**
-		 * Returns all callbacks as {@link THREE.OBJLoader2.WWOBJLoader2.PrepDataCallbacks}
-		 * @memberOf THREE.OBJLoader2.WWOBJLoader2.PrepDataArrayBuffer
-		 *
-		 * @returns {THREE.OBJLoader2.WWOBJLoader2.PrepDataCallbacks}
-		 */
-		getCallbacks: function () {
-			return this.callbacks;
-		},
-		modelName: Validator.verifyInput( modelName, '' ),
-		dataAvailable: true,
-		objAsArrayBuffer: Validator.verifyInput( objAsArrayBuffer, null ),
-		pathTexture: Validator.verifyInput( pathTexture, null ),
-		mtlAsString: Validator.verifyInput( mtlAsString, null ),
-		sceneGraphBaseNode: null,
-		streamMeshes: true,
-		requestTerminate: false,
-		callbacks: new THREE.OBJLoader2.WWOBJLoader2.PrepDataCallbacks()
-	};
-};
-
-/**
- * Instruction to configure {@link THREE.OBJLoader2.WWOBJLoader2}.prepareRun to load OBJ and MTL from files.
- *
- * @param {string} modelName Overall name of the model
- * @param {string} pathObj Path to OBJ file
- * @param {string} fileObj OBJ file name
- * @param {string} pathTexture Path to texture files
- * @param {string} fileMtl MTL file name
- *
- * @returns {{modelName: string, dataAvailable: boolean, pathObj: null, fileObj: null, pathTexture: null, fileMtl: null, sceneGraphBaseNode: null, streamMeshes: boolean,  requestTerminate: boolean}}
- * @constructor
- */
-THREE.OBJLoader2.WWOBJLoader2.PrepDataFile = function ( modelName, pathObj, fileObj, pathTexture, fileMtl ) {
-
-	var Validator = THREE.OBJLoader2.prototype._getValidator();
-
-	return {
-
-		/**
-		 * {@link THREE.Object3D} where meshes will be attached.
-		 * @memberOf THREE.OBJLoader2.WWOBJLoader2.PrepDataFile
-		 *
-		 * @param {THREE.Object3D} sceneGraphBaseNode Scene graph object
-		 */
-		setSceneGraphBaseNode: function ( sceneGraphBaseNode ) {
-			this.sceneGraphBaseNode = Validator.verifyInput( sceneGraphBaseNode, null );
-		},
-
-		/**
-		 * Singles meshes are directly integrated into scene when loaded or later.
-		 * @memberOf THREE.OBJLoader2.WWOBJLoader2.PrepDataFile
-		 *
-		 * @param {boolean} streamMeshes=true Default is true
-		 */
-		setStreamMeshes: function ( streamMeshes ) {
-			this.streamMeshes = streamMeshes !== false;
-		},
-
-		/**
-		 * Request termination of web worker and free local resources after execution.
-		 * @memberOf THREE.OBJLoader2.WWOBJLoader2.PrepDataFile
-		 *
-		 * @param {boolean} requestTerminate=false Default is false
-		 */
-		setRequestTerminate: function ( requestTerminate ) {
-			this.requestTerminate = requestTerminate === true;
-		},
-
-		/**
-		 * Returns all callbacks as {@link THREE.OBJLoader2.WWOBJLoader2.PrepDataCallbacks}
-		 * @memberOf THREE.OBJLoader2.WWOBJLoader2.PrepDataFile
-		 *
-		 * @returns {THREE.OBJLoader2.WWOBJLoader2.PrepDataCallbacks}
-		 */
-		getCallbacks: function () {
-			return this.callbacks;
-		},
-		modelName: Validator.verifyInput( modelName, '' ),
-		dataAvailable: false,
-		pathObj: Validator.verifyInput( pathObj, null ),
-		fileObj: Validator.verifyInput( fileObj, null ),
-		pathTexture: Validator.verifyInput( pathTexture, null ),
-		fileMtl: Validator.verifyInput( fileMtl, null ),
-		sceneGraphBaseNode: null,
-		streamMeshes: true,
-		requestTerminate: false,
-		callbacks: new THREE.OBJLoader2.WWOBJLoader2.PrepDataCallbacks()
-	};
-};
-
-/**
- * Callbacks utilized by functions working with {@link THREE.OBJLoader2.WWOBJLoader2.PrepDataArrayBuffer} or {@link THREE.OBJLoader2.WWOBJLoader2.PrepDataFile}
- *
- * @returns {{registerCallbackProgress: THREE.OBJLoader2.WWOBJLoader2.PrepDataCallbacks.registerCallbackProgress, registerCallbackCompletedLoading: THREE.OBJLoader2.WWOBJLoader2.PrepDataCallbacks.registerCallbackCompletedLoading, registerCallbackMaterialsLoaded: THREE.OBJLoader2.WWOBJLoader2.PrepDataCallbacks.registerCallbackMaterialsLoaded, registerCallbackMeshLoaded: THREE.OBJLoader2.WWOBJLoader2.PrepDataCallbacks.registerCallbackMeshLoaded, registerCallbackErrorWhileLoading: THREE.OBJLoader2.WWOBJLoader2.PrepDataCallbacks.registerCallbackErrorWhileLoading, progress: null, completedLoading: null, errorWhileLoading: null, materialsLoaded: null, meshLoaded: null}}
- * @constructor
- */
-THREE.OBJLoader2.WWOBJLoader2.PrepDataCallbacks = function () {
-
-	var Validator = THREE.OBJLoader2.prototype._getValidator();
-
-	return {
-		/**
-		 * Register callback function that is invoked by internal function "_announceProgress" to print feedback.
-		 * @memberOf THREE.OBJLoader2.WWOBJLoader2.PrepDataCallbacks
-		 *
-		 * @param {callback} callbackProgress Callback function for described functionality
-		 */
-		registerCallbackProgress: function ( callbackProgress ) {
-			if ( Validator.isValid( callbackProgress ) ) this.progress = callbackProgress;
-		},
-
-		/**
-		 * Register callback function that is called once loading of the complete model is completed.
-		 * @memberOf THREE.OBJLoader2.WWOBJLoader2.PrepDataCallbacks
-		 *
-		 * @param {callback} callbackCompletedLoading Callback function for described functionality
-		 */
-		registerCallbackCompletedLoading: function ( callbackCompletedLoading ) {
-			if ( Validator.isValid( callbackCompletedLoading ) ) this.completedLoading = callbackCompletedLoading;
-		},
-
-		/**
-		 * Register callback function that is called once materials have been loaded. It allows to alter and return materials.
-		 * @memberOf THREE.OBJLoader2.WWOBJLoader2.PrepDataCallbacks
-		 *
-		 * @param {callback} callbackMaterialsLoaded Callback function for described functionality
-		 */
-		registerCallbackMaterialsLoaded: function ( callbackMaterialsLoaded ) {
-			if ( Validator.isValid( callbackMaterialsLoaded ) ) this.materialsLoaded = callbackMaterialsLoaded;
-		},
-
-		/**
-		 * Register callback function that is called every time a mesh was loaded.
-		 * Use {@link THREE.OBJLoader2.WWOBJLoader2.LoadedMeshUserOverride} for alteration instructions (geometry, material or disregard mesh).
-		 * @memberOf THREE.OBJLoader2.WWOBJLoader2.PrepDataCallbacks
-		 *
-		 * @param {callback} callbackMeshLoaded Callback function for described functionality
-		 */
-		registerCallbackMeshLoaded: function ( callbackMeshLoaded ) {
-			if ( Validator.isValid( callbackMeshLoaded ) ) this.meshLoaded = callbackMeshLoaded;
-		},
-
-		/**
-		 * Report if an error prevented loading.
-		 * @memberOf THREE.OBJLoader2.WWOBJLoader2.PrepDataCallbacks
-		 *
-		 * @param {callback} callbackErrorWhileLoading Callback function for described functionality
-		 */
-		registerCallbackErrorWhileLoading: function ( callbackErrorWhileLoading ) {
-			if ( Validator.isValid( callbackErrorWhileLoading ) ) this.errorWhileLoading = callbackErrorWhileLoading;
-		},
-
-		progress: null,
-		completedLoading: null,
-		errorWhileLoading: null,
-		materialsLoaded: null,
-		meshLoaded: null
-	};
-};
-
-
-/**
- * Object to return by {@link THREE.OBJLoader2.WWOBJLoader2}.callbacks.meshLoaded. Used to adjust bufferGeometry or material or prevent complete loading of mesh
- *
- * @param {boolean} disregardMesh=false Tell WWOBJLoader2 to completely disregard this mesh
- * @param {THREE.BufferGeometry} bufferGeometry The {@link THREE.BufferGeometry} to be used
- * @param {THREE.Material} material The {@link THREE.Material} to be used
- *
- * @returns {{ disregardMesh: boolean, replaceBufferGeometry: boolean, bufferGeometry: THREE.BufferGeometry, replaceMaterial: boolean, material: THREE.Material}}
- * @constructor
- */
-THREE.OBJLoader2.WWOBJLoader2.LoadedMeshUserOverride = function ( disregardMesh, bufferGeometry, material ) {
-
-	var Validator = THREE.OBJLoader2.prototype._getValidator();
-
-	return {
-		disregardMesh: disregardMesh === true,
-		replaceBufferGeometry: Validator.isValid( bufferGeometry ),
-		bufferGeometry: Validator.verifyInput( bufferGeometry, null ),
-		replaceMaterial: Validator.isValid( material ),
-		material: Validator.verifyInput( material, null )
-	};
-};
-
-/**
- * Orchestrate loading of multiple OBJ files/data from an instruction queue with a configurable amount of workers (1-16).
- * Workflow:
- *   prepareWorkers
- *   enqueueForRun
- *   processQueue
- *   deregister
- *
- * @class
- */
-THREE.OBJLoader2.WWOBJLoader2Director = (function () {
-
-	var Validator = THREE.OBJLoader2.prototype._getValidator();
-
-	var MAX_WEB_WORKER = 16;
-	var MAX_QUEUE_SIZE = 1024;
-
-	function WWOBJLoader2Director() {
-		this.maxQueueSize = MAX_QUEUE_SIZE ;
-		this.maxWebWorkers = MAX_WEB_WORKER;
-		this.crossOrigin = null;
-
-		this.workerDescription = {
-			prototypeDef: THREE.OBJLoader2.WWOBJLoader2.prototype,
-			globalCallbacks: {},
-			webWorkers: [],
-			codeBuffer: null
-		};
-		this.objectsCompleted = 0;
-		this.instructionQueue = [];
-	}
-
-	/**
-	 * Returns the maximum length of the instruction queue.
-	 * @memberOf THREE.OBJLoader2.WWOBJLoader2Director
-	 *
-	 * @returns {number}
-	 */
-	WWOBJLoader2Director.prototype.getMaxQueueSize = function () {
-		return this.maxQueueSize;
-	};
-
-	/**
-	 * Returns the maximum number of workers.
-	 * @memberOf THREE.OBJLoader2.WWOBJLoader2Director
-	 *
-	 * @returns {number}
-	 */
-	WWOBJLoader2Director.prototype.getMaxWebWorkers = function () {
-		return this.maxWebWorkers;
-	};
-
-	/**
-	 * Sets the CORS string to be used.
-	 * @memberOf THREE.OBJLoader2.WWOBJLoader2Director
-	 *
-	 * @param {string} crossOrigin CORS value
-	 */
-	WWOBJLoader2Director.prototype.setCrossOrigin = function ( crossOrigin ) {
-		this.crossOrigin = crossOrigin;
-	};
-
-	/**
-	 * Create or destroy workers according limits. Set the name and register callbacks for dynamically created web workers.
-	 * @memberOf THREE.OBJLoader2.WWOBJLoader2Director
-	 *
-	 * @param {THREE.OBJLoader2.WWOBJLoader2.PrepDataCallbacks} globalCallbacks  Register global callbacks used by all web workers
-	 * @param {number} maxQueueSize Set the maximum size of the instruction queue (1-1024)
-	 * @param {number} maxWebWorkers Set the maximum amount of workers (1-16)
-	 */
-	WWOBJLoader2Director.prototype.prepareWorkers = function ( globalCallbacks, maxQueueSize, maxWebWorkers ) {
-		if ( Validator.isValid( globalCallbacks ) ) this.workerDescription.globalCallbacks = globalCallbacks;
-		this.maxQueueSize = Math.min( maxQueueSize, MAX_QUEUE_SIZE );
-		this.maxWebWorkers = Math.min( maxWebWorkers, MAX_WEB_WORKER );
-		this.objectsCompleted = 0;
-		this.instructionQueue = [];
-
-		var start = this.workerDescription.webWorkers.length;
-		if ( start < this.maxWebWorkers ) {
-
-			for ( i = start; i < this.maxWebWorkers; i ++ ) {
-
-				webWorker = this._buildWebWorker();
-				this.workerDescription.webWorkers[ i ] = webWorker;
-
-			}
-
-		} else {
-
-			for ( var webWorker, i = start - 1; i >= this.maxWebWorkers; i-- ) {
-
-				webWorker = this.workerDescription.webWorkers[ i ];
-				webWorker.setRequestTerminate( true );
-
-				this.workerDescription.webWorkers.pop();
-
-			}
-
-		}
-	};
-
-	/**
-	 * Store run instructions in internal instructionQueue.
-	 * @memberOf THREE.OBJLoader2.WWOBJLoader2Director
-	 *
-	 * @param {Object} runParams Either {@link THREE.OBJLoader2.WWOBJLoader2.PrepDataArrayBuffer} or {@link THREE.OBJLoader2.WWOBJLoader2.PrepDataFile}
-	 */
-	WWOBJLoader2Director.prototype.enqueueForRun = function ( runParams ) {
-		if ( this.instructionQueue.length < this.maxQueueSize ) {
-			this.instructionQueue.push( runParams );
-		}
-	};
-
-	/**
-	 * Process the instructionQueue until it is depleted.
-	 * @memberOf THREE.OBJLoader2.WWOBJLoader2Director
-	 */
-	WWOBJLoader2Director.prototype.processQueue = function () {
-		if ( this.instructionQueue.length === 0 ) return;
-
-		var length = Math.min( this.maxWebWorkers, this.instructionQueue.length );
-		for ( var i = 0; i < length; i++ ) {
-
-			this._kickWebWorkerRun( this.workerDescription.webWorkers[ i ], this.instructionQueue[ 0 ] );
-			this.instructionQueue.shift();
-
-		}
-	};
-
-	WWOBJLoader2Director.prototype._kickWebWorkerRun = function( worker, runParams ) {
-		worker.clearAllCallbacks();
-		var key;
-		var globalCallbacks = this.workerDescription.globalCallbacks;
-		var workerCallbacks = worker.callbacks;
-		var selectedGlobalCallback;
-		for ( key in globalCallbacks ) {
-
-			if ( workerCallbacks.hasOwnProperty( key ) && globalCallbacks.hasOwnProperty( key ) ) {
-
-				selectedGlobalCallback = globalCallbacks[ key ];
-				if ( Validator.isValid( selectedGlobalCallback ) ) workerCallbacks[ key ].push( selectedGlobalCallback );
-
-			}
-
-		}
-		// register per object callbacks
-		var runCallbacks = runParams.callbacks;
-		if ( Validator.isValid( runCallbacks ) ) {
-
-			for ( key in runCallbacks ) {
-
-				if ( workerCallbacks.hasOwnProperty( key ) && runCallbacks.hasOwnProperty( key ) && Validator.isValid( runCallbacks[ key ] ) ) {
-
-					workerCallbacks[ key ].push( runCallbacks[ key ] );
-
-				}
-
-			}
-
-		}
-
-		var scope = this;
-		var directorCompletedLoading = function ( modelName, instanceNo, requestTerminate ) {
-			scope.objectsCompleted++;
-			if ( ! requestTerminate ) {
-
-				var worker = scope.workerDescription.webWorkers[ instanceNo ];
-				var runParams = scope.instructionQueue[ 0 ];
-				if ( Validator.isValid( runParams ) ) {
-
-					console.log( '\nAssigning next item from queue to worker (queue length: ' + scope.instructionQueue.length + ')\n\n' );
-					scope._kickWebWorkerRun( worker, runParams );
-					scope.instructionQueue.shift();
-
-				}
-
-			}
-		};
-		worker.registerCallbackCompletedLoading( directorCompletedLoading );
-
-		worker.prepareRun( runParams );
-		worker.run();
-	};
-
-	WWOBJLoader2Director.prototype._buildWebWorker = function () {
-		var webWorker = Object.create( this.workerDescription.prototypeDef );
-		webWorker._init();
-		if ( Validator.isValid( this.crossOrigin ) ) webWorker.setCrossOrigin( this.crossOrigin );
-
-		// Ensure code string is built once and then it is just passed on to every new instance
-		if ( Validator.isValid( this.workerDescription.codeBuffer ) ) {
-
-			webWorker._buildWebWorkerCode( this.workerDescription.codeBuffer );
-
-		} else {
-
-			this.workerDescription.codeBuffer = webWorker._buildWebWorkerCode();
-
-		}
-
-		webWorker.instanceNo = this.workerDescription.webWorkers.length;
-		this.workerDescription.webWorkers.push( webWorker );
-		return webWorker;
-	};
-
-	/**
-	 * Terminate all workers.
-	 * @memberOf THREE.OBJLoader2.WWOBJLoader2Director
-	 */
-	WWOBJLoader2Director.prototype.deregister = function () {
-		console.log( 'WWOBJLoader2Director received the unregister call. Terminating all workers!' );
-		for ( var i = 0, webWorker, length = this.workerDescription.webWorkers.length; i < length; i++ ) {
-
-			webWorker = this.workerDescription.webWorkers[ i ];
-			webWorker.setRequestTerminate( true );
-
-		}
-		this.workerDescription.globalCallbacks = {};
-		this.workerDescription.webWorkers = [];
-		this.workerDescription.codeBuffer = null;
-	};
-
-	return WWOBJLoader2Director;
-
-})();

+ 157 - 0
examples/js/postprocessing/SSAOPass.js

@@ -0,0 +1,157 @@
+'use strict';
+
+/**
+ * Screen-space ambient occlusion pass.
+ *
+ * Has the following parameters
+ *  - radius
+ *  	- Ambient occlusion shadow radius (numeric value).
+ *  - onlyAO
+ *  	- Display only ambient occlusion result (boolean value).
+ *  - aoClamp
+ *  	- Ambient occlusion clamp (numeric value).
+ *  - lumInfluence
+ *  	- Pixel luminosity influence in AO calculation (numeric value).
+ * 
+ * To output to screen set renderToScreens true
+ *
+ * @author alteredq / http://alteredqualia.com/
+ * @author tentone
+ * @class SSAOPass
+ */
+THREE.SSAOPass = function ( scene, camera, width, height ) {
+
+	if ( THREE.SSAOShader === undefined) {
+
+		console.warn( 'THREE.SSAOPass depends on THREE.SSAOShader' );
+		return new THREE.ShaderPass();
+
+	}
+
+	THREE.ShaderPass.call( this, THREE.SSAOShader );
+
+	this.width = ( width !== undefined ) ? width : 512;
+	this.height = ( height !== undefined ) ? height : 256;
+
+	this.renderToScreen = false;
+
+	this.camera2 = camera;
+	this.scene2 = scene;
+
+	//Depth material
+	this.depthMaterial = new THREE.MeshDepthMaterial();
+	this.depthMaterial.depthPacking = THREE.RGBADepthPacking;
+	this.depthMaterial.blending = THREE.NoBlending;
+
+	//Depth render target
+	this.depthRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter } );
+	//this.depthRenderTarget.texture.name = 'SSAOShader.rt';
+	
+	//Shader uniforms
+	this.uniforms[ 'tDepth' ].value = this.depthRenderTarget.texture;
+	this.uniforms[ 'size' ].value.set( this.width, this.height );
+	this.uniforms[ 'cameraNear' ].value = this.camera2.near;
+	this.uniforms[ 'cameraFar' ].value = this.camera2.far;
+
+	this.uniforms[ 'radius' ].value = 4;
+	this.uniforms[ 'onlyAO' ].value = false;
+	this.uniforms[ 'aoClamp' ].value = 0.25;
+	this.uniforms[ 'lumInfluence' ].value = 0.7;
+
+	//Setters and getters for uniforms
+	var self = this;
+	Object.defineProperties(this, {
+
+		radius: {
+			get: function() { return this.uniforms[ 'radius' ].value; },
+			set: function( value ) { this.uniforms[ 'radius' ].value = value; }
+		},
+
+		onlyAO: {
+			get: function() { return this.uniforms[ 'onlyAO' ].value; },
+			set: function( value ) { this.uniforms[ 'onlyAO' ].value = value; }
+		},
+
+		aoClamp: {
+			get: function() { return this.uniforms[ 'aoClamp' ].value; },
+			set: function( value ) { this.uniforms[ 'aoClamp' ].value = value; }
+		},
+
+		lumInfluence: {
+			get: function() { return this.uniforms[ 'lumInfluence' ].value; },
+			set: function( value ) { this.uniforms[ 'lumInfluence' ].value = value; }
+		},
+
+	});
+}
+
+THREE.SSAOPass.prototype = Object.create( THREE.ShaderPass.prototype );
+
+/**
+ * Render using this pass.
+ * 
+ * @method render
+ * @param {WebGLRenderer} renderer
+ * @param {WebGLRenderTarget} writeBuffer Buffer to write output.
+ * @param {WebGLRenderTarget} readBuffer Input buffer.
+ * @param {Number} delta Delta time in milliseconds.
+ * @param {Boolean} maskActive Not used in this pass.
+ */
+THREE.SSAOPass.prototype.render = function( renderer, writeBuffer, readBuffer, delta, maskActive ) {
+
+	//Render depth into depthRenderTarget
+	this.scene2.overrideMaterial = this.depthMaterial;
+	
+	renderer.render( this.scene2, this.camera2, this.depthRenderTarget, true );
+	
+	this.scene2.overrideMaterial = null;
+
+
+	//SSAO shaderPass
+	THREE.ShaderPass.prototype.render.call( this, renderer, writeBuffer, readBuffer, delta, maskActive );
+
+};
+
+/**
+ * Change scene to be renderer by this render pass.
+ *
+ * @method setScene
+ * @param {Scene} scene
+ */
+THREE.SSAOPass.prototype.setScene = function(scene) {
+	
+	this.scene2 = scene;
+
+};
+
+/**
+ * Set camera used by this render pass.
+ *
+ * @method setCamera
+ * @param {Camera} camera
+ */
+THREE.SSAOPass.prototype.setCamera = function( camera ) {
+
+	this.camera2 = camera;
+
+	this.uniforms[ 'cameraNear' ].value = this.camera2.near;
+	this.uniforms[ 'cameraFar' ].value = this.camera2.far;
+
+};
+
+/**
+ * Set resolution of this render pass.
+ * 
+ * @method setSize
+ * @param {Number} width
+ * @param {Number} height
+ */
+THREE.SSAOPass.prototype.setSize = function( width, height ) {
+
+	this.width = width;
+	this.height = height;
+
+	this.uniforms[ 'size' ].value.set( this.width, this.height );
+	this.depthRenderTarget.setSize( this.width, this.height );
+
+};

+ 30 - 8
examples/js/postprocessing/UnrealBloomPass.js

@@ -1,9 +1,9 @@
 /**
  * @author spidersharma / http://eduperiment.com/
- Inspired from Unreal Engine::
- https://docs.unrealengine.com/latest/INT/Engine/Rendering/PostProcessEffects/Bloom/
+ * 
+ * Inspired from Unreal Engine
+ * https://docs.unrealengine.com/latest/INT/Engine/Rendering/PostProcessEffects/Bloom/
  */
-
 THREE.UnrealBloomPass = function ( resolution, strength, radius, threshold ) {
 
 	THREE.Pass.call( this );
@@ -131,6 +131,8 @@ THREE.UnrealBloomPass = function ( resolution, strength, radius, threshold ) {
 	this.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
 	this.scene = new THREE.Scene();
 
+	this.basic = new THREE.MeshBasicMaterial();
+
 	this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null );
 	this.quad.frustumCulled = false; // Avoid getting clipped
 	this.scene.add( this.quad );
@@ -191,11 +193,23 @@ THREE.UnrealBloomPass.prototype = Object.assign( Object.create( THREE.Pass.proto
 
 		if ( maskActive ) renderer.context.disable( renderer.context.STENCIL_TEST );
 
+		// Render input to screen
+
+		if ( this.renderToScreen ) {
+
+			this.quad.material = this.basic;
+			this.basic.map = readBuffer.texture;
+
+			renderer.render( this.scene, this.camera, undefined, true );
+
+		}
+
 		// 1. Extract Bright Areas
 
 		this.highPassUniforms[ "tDiffuse" ].value = readBuffer.texture;
 		this.highPassUniforms[ "luminosityThreshold" ].value = this.threshold;
 		this.quad.material = this.materialHighPassFilter;
+
 		renderer.render( this.scene, this.camera, this.renderTargetBright, true );
 
 		// 2. Blur All the mips progressively
@@ -207,15 +221,11 @@ THREE.UnrealBloomPass.prototype = Object.assign( Object.create( THREE.Pass.proto
 			this.quad.material = this.separableBlurMaterials[ i ];
 
 			this.separableBlurMaterials[ i ].uniforms[ "colorTexture" ].value = inputRenderTarget.texture;
-
 			this.separableBlurMaterials[ i ].uniforms[ "direction" ].value = THREE.UnrealBloomPass.BlurDirectionX;
-
 			renderer.render( this.scene, this.camera, this.renderTargetsHorizontal[ i ], true );
 
 			this.separableBlurMaterials[ i ].uniforms[ "colorTexture" ].value = this.renderTargetsHorizontal[ i ].texture;
-
 			this.separableBlurMaterials[ i ].uniforms[ "direction" ].value = THREE.UnrealBloomPass.BlurDirectionY;
-
 			renderer.render( this.scene, this.camera, this.renderTargetsVertical[ i ], true );
 
 			inputRenderTarget = this.renderTargetsVertical[ i ];
@@ -228,6 +238,7 @@ THREE.UnrealBloomPass.prototype = Object.assign( Object.create( THREE.Pass.proto
 		this.compositeMaterial.uniforms[ "bloomStrength" ].value = this.strength;
 		this.compositeMaterial.uniforms[ "bloomRadius" ].value = this.radius;
 		this.compositeMaterial.uniforms[ "bloomTintColors" ].value = this.bloomTintColors;
+
 		renderer.render( this.scene, this.camera, this.renderTargetsHorizontal[ 0 ], true );
 
 		// Blend it additively over the input texture
@@ -237,7 +248,18 @@ THREE.UnrealBloomPass.prototype = Object.assign( Object.create( THREE.Pass.proto
 
 		if ( maskActive ) renderer.context.enable( renderer.context.STENCIL_TEST );
 
-		renderer.render( this.scene, this.camera, readBuffer, false );
+
+		if ( this.renderToScreen ) {
+
+			renderer.render( this.scene, this.camera, undefined, false );
+
+		} else {
+
+			renderer.render( this.scene, this.camera, readBuffer, false );
+
+		}
+
+		// Restore renderer settings
 
 		renderer.setClearColor( this.oldClearColor, this.oldClearAlpha );
 		renderer.autoClear = oldAutoClear;

+ 1 - 1
examples/js/renderers/SVGRenderer.js

@@ -131,7 +131,7 @@ THREE.SVGRenderer = function () {
 
 		if ( opacity === undefined || opacity === 1 ) return 'rgb(' + arg + ')';
 
-		return 'rgba(' + arg + ',' + opacity + ')';
+		return 'rgb(' + arg + '); fill-opacity: ' + opacity;
 
 	}
 

+ 4 - 4
examples/js/shaders/LuminosityShader.js

@@ -29,6 +29,8 @@ THREE.LuminosityShader = {
 
 	fragmentShader: [
 
+		"#include <common>",
+
 		"uniform sampler2D tDiffuse;",
 
 		"varying vec2 vUv;",
@@ -37,11 +39,9 @@ THREE.LuminosityShader = {
 
 			"vec4 texel = texture2D( tDiffuse, vUv );",
 
-			"vec3 luma = vec3( 0.299, 0.587, 0.114 );",
-
-			"float v = dot( texel.xyz, luma );",
+			"float l = linearToRelativeLuminance( texel.rgb );",
 
-			"gl_FragColor = vec4( v, v, v, texel.w );",
+			"gl_FragColor = vec4( l, l, l, texel.w );",
 
 		"}"
 

+ 6 - 6
examples/js/shaders/ToneMapShader.js

@@ -31,6 +31,8 @@ THREE.ToneMapShader = {
 
 	fragmentShader: [
 
+		"#include <common>",
+
 		"uniform sampler2D tDiffuse;",
 
 		"varying vec2 vUv;",
@@ -43,19 +45,17 @@ THREE.ToneMapShader = {
 		"#else",
 			"uniform float averageLuminance;",
 		"#endif",
-		
-		"const vec3 LUM_CONVERT = vec3(0.299, 0.587, 0.114);",
 
 		"vec3 ToneMap( vec3 vColor ) {",
 			"#ifdef ADAPTED_LUMINANCE",
-				// Get the calculated average luminance 
+				// Get the calculated average luminance
 				"float fLumAvg = texture2D(luminanceMap, vec2(0.5, 0.5)).r;",
 			"#else",
 				"float fLumAvg = averageLuminance;",
 			"#endif",
-			
+
 			// Calculate the luminance of the current pixel
-			"float fLumPixel = dot(vColor, LUM_CONVERT);",
+			"float fLumPixel = linearToRelativeLuminance( vColor );",
 
 			// Apply the modified operator (Eq. 4)
 			"float fLumScaled = (fLumPixel * middleGrey) / max( minLuminance, fLumAvg );",
@@ -67,7 +67,7 @@ THREE.ToneMapShader = {
 		"void main() {",
 
 			"vec4 texel = texture2D( tDiffuse, vUv );",
-			
+
 			"gl_FragColor = vec4( ToneMap( texel.xyz ), texel.w );",
 
 		"}"

+ 2 - 2
examples/js/vr/ViveController.js

@@ -23,11 +23,11 @@ THREE.ViveController = function ( id ) {
 
 		var gamepads = navigator.getGamepads && navigator.getGamepads();
 
-		for ( var i = 0, j = 0; i < 4; i ++ ) {
+		for ( var i = 0, j = 0; i < gamepads.length; i ++ ) {
 
 			var gamepad = gamepads[ i ];
 
-			if ( gamepad && ( gamepad.id === 'OpenVR Gamepad' || gamepad.id === 'Oculus Touch (Left)' || gamepad.id === 'Oculus Touch (Right)' ) ) {
+			if ( gamepad && ( gamepad.id === 'OpenVR Gamepad' || gamepad.id.startsWith( 'Oculus Touch' ) || gamepad.id.startsWith( 'Spatial Controller' ) ) ) {
 
 				if ( j === id ) return gamepad;
 

+ 4 - 56
examples/js/vr/WebVR.js

@@ -7,13 +7,6 @@
 
 var WEBVR = {
 
-	isAvailable: function () {
-
-		console.warn( 'WEBVR: isAvailable() is being deprecated. Use .checkAvailability() instead.' );
-		return navigator.getVRDisplays !== undefined;
-
-	},
-
 	checkAvailability: function () {
 
 		return new Promise( function( resolve, reject ) {
@@ -32,6 +25,10 @@ var WEBVR = {
 
 					}
 
+				}, function () {
+
+					reject( 'Your browser does not support WebVR. See <a href="https://webvr.info">webvr.info</a> for assistance.' );
+				
 				} );
 
 			} else {
@@ -57,55 +54,6 @@ var WEBVR = {
 
 	},
 
-	getMessage: function () {
-
-		console.warn( 'WEBVR: getMessage() is being deprecated. Use .getMessageContainer( message ) instead.' );
-
-		var message;
-
-		if ( navigator.getVRDisplays ) {
-
-			navigator.getVRDisplays().then( function ( displays ) {
-
-				if ( displays.length === 0 ) message = 'WebVR supported, but no VRDisplays found.';
-
-			} );
-
-		} else {
-
-			message = 'Your browser does not support WebVR. See <a href="http://webvr.info">webvr.info</a> for assistance.';
-
-		}
-
-		if ( message !== undefined ) {
-
-			var container = document.createElement( 'div' );
-			container.style.position = 'absolute';
-			container.style.left = '0';
-			container.style.top = '0';
-			container.style.right = '0';
-			container.style.zIndex = '999';
-			container.align = 'center';
-
-			var error = document.createElement( 'div' );
-			error.style.fontFamily = 'sans-serif';
-			error.style.fontSize = '16px';
-			error.style.fontStyle = 'normal';
-			error.style.lineHeight = '26px';
-			error.style.backgroundColor = '#fff';
-			error.style.color = '#000';
-			error.style.padding = '10px 20px';
-			error.style.margin = '50px';
-			error.style.display = 'inline-block';
-			error.innerHTML = message;
-			container.appendChild( error );
-
-			return container;
-
-		}
-
-	},
-
 	getMessageContainer: function ( message ) {
 
 		var container = document.createElement( 'div' );

+ 5 - 2
examples/misc_animation_keys.html

@@ -70,7 +70,7 @@
 				//
 
 				var geometry = new THREE.BoxBufferGeometry( 5, 5, 5 );
-				var material = new THREE.MeshBasicMaterial( { color: 0xffffff } );
+				var material = new THREE.MeshBasicMaterial( { color: 0xffffff, transparent: true } );
 				var mesh = new THREE.Mesh( geometry, material );
 				scene.add( mesh );
 
@@ -97,9 +97,12 @@
 				// COLOR
 				var colorKF = new THREE.ColorKeyframeTrack( '.material.color', [ 0, 1, 2 ], [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ], THREE.InterpolateDiscrete );
 
+				// OPACITY
+				var opacityKF = new THREE.NumberKeyframeTrack( '.material.opacity', [ 0, 1, 2 ], [ 1, 0, 1 ] );
+
 				// create an animation sequence with the tracks
 				// If a negative time value is passed, the duration will be calculated from the times of the passed tracks array
-				var clip = new THREE.AnimationClip( 'Action', 3, [ scaleKF, positionKF, quaternionKF, colorKF ] );
+				var clip = new THREE.AnimationClip( 'Action', 3, [ scaleKF, positionKF, quaternionKF, colorKF, opacityKF ] );
 
 				// setup the AnimationMixer
 				mixer = new THREE.AnimationMixer( mesh );

+ 34 - 35
examples/misc_controls_pointerlock.html

@@ -74,9 +74,7 @@
 
 		<script>
 
-			var camera, scene, renderer;
-			var geometry, material, mesh;
-			var controls;
+			var camera, scene, renderer, controls;
 
 			var objects = [];
 
@@ -106,9 +104,7 @@
 
 						controls.enabled = false;
 
-						blocker.style.display = '-webkit-box';
-						blocker.style.display = '-moz-box';
-						blocker.style.display = 'box';
+						blocker.style.display = 'block';
 
 						instructions.style.display = '';
 
@@ -160,6 +156,7 @@
 
 			var prevTime = performance.now();
 			var velocity = new THREE.Vector3();
+			var direction = new THREE.Vector3();
 
 			function init() {
 
@@ -243,39 +240,39 @@
 
 				// floor
 
-				geometry = new THREE.PlaneGeometry( 2000, 2000, 100, 100 );
-				geometry.rotateX( - Math.PI / 2 );
+				var floorGeometry = new THREE.PlaneGeometry( 2000, 2000, 100, 100 );
+				floorGeometry.rotateX( - Math.PI / 2 );
 
-				for ( var i = 0, l = geometry.vertices.length; i < l; i ++ ) {
+				for ( var i = 0, l = floorGeometry.vertices.length; i < l; i ++ ) {
 
-					var vertex = geometry.vertices[ i ];
+					var vertex = floorGeometry.vertices[ i ];
 					vertex.x += Math.random() * 20 - 10;
 					vertex.y += Math.random() * 2;
 					vertex.z += Math.random() * 20 - 10;
 
 				}
 
-				for ( var i = 0, l = geometry.faces.length; i < l; i ++ ) {
+				for ( var i = 0, l = floorGeometry.faces.length; i < l; i ++ ) {
 
-					var face = geometry.faces[ i ];
+					var face = floorGeometry.faces[ i ];
 					face.vertexColors[ 0 ] = new THREE.Color().setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );
 					face.vertexColors[ 1 ] = new THREE.Color().setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );
 					face.vertexColors[ 2 ] = new THREE.Color().setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );
 
 				}
 
-				material = new THREE.MeshBasicMaterial( { vertexColors: THREE.VertexColors } );
+				var floorMaterial = new THREE.MeshBasicMaterial( { vertexColors: THREE.VertexColors } );
 
-				mesh = new THREE.Mesh( geometry, material );
-				scene.add( mesh );
+				var floor = new THREE.Mesh( floorGeometry, floorMaterial );
+				scene.add( floor );
 
 				// objects
 
-				geometry = new THREE.BoxGeometry( 20, 20, 20 );
+				var boxGeometry = new THREE.BoxGeometry( 20, 20, 20 );
 
-				for ( var i = 0, l = geometry.faces.length; i < l; i ++ ) {
+				for ( var i = 0, l = boxGeometry.faces.length; i < l; i ++ ) {
 
-					var face = geometry.faces[ i ];
+					var face = boxGeometry.faces[ i ];
 					face.vertexColors[ 0 ] = new THREE.Color().setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );
 					face.vertexColors[ 1 ] = new THREE.Color().setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );
 					face.vertexColors[ 2 ] = new THREE.Color().setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );
@@ -284,17 +281,16 @@
 
 				for ( var i = 0; i < 500; i ++ ) {
 
-					material = new THREE.MeshPhongMaterial( { specular: 0xffffff, flatShading: true, vertexColors: THREE.VertexColors } );
+					var boxMaterial = new THREE.MeshPhongMaterial( { specular: 0xffffff, flatShading: true, vertexColors: THREE.VertexColors } );
+					boxMaterial.color.setHSL( Math.random() * 0.2 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );
 
-					var mesh = new THREE.Mesh( geometry, material );
-					mesh.position.x = Math.floor( Math.random() * 20 - 10 ) * 20;
-					mesh.position.y = Math.floor( Math.random() * 20 ) * 20 + 10;
-					mesh.position.z = Math.floor( Math.random() * 20 - 10 ) * 20;
-					scene.add( mesh );
+					var box = new THREE.Mesh( boxGeometry, boxMaterial );
+					box.position.x = Math.floor( Math.random() * 20 - 10 ) * 20;
+					box.position.y = Math.floor( Math.random() * 20 ) * 20 + 10;
+					box.position.z = Math.floor( Math.random() * 20 - 10 ) * 20;
 
-					material.color.setHSL( Math.random() * 0.2 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );
-
-					objects.push( mesh );
+					scene.add( box );
+					objects.push( box );
 
 				}
 
@@ -324,13 +320,14 @@
 
 				requestAnimationFrame( animate );
 
-				if ( controlsEnabled ) {
+				if ( controlsEnabled === true ) {
+
 					raycaster.ray.origin.copy( controls.getObject().position );
 					raycaster.ray.origin.y -= 10;
 
 					var intersections = raycaster.intersectObjects( objects );
 
-					var isOnObject = intersections.length > 0;
+					var onObject = intersections.length > 0;
 
 					var time = performance.now();
 					var delta = ( time - prevTime ) / 1000;
@@ -340,16 +337,18 @@
 
 					velocity.y -= 9.8 * 100.0 * delta; // 100.0 = mass
 
-					if ( moveForward ) velocity.z -= 400.0 * delta;
-					if ( moveBackward ) velocity.z += 400.0 * delta;
+					direction.z = Number( moveForward ) - Number( moveBackward );
+					direction.x = Number( moveLeft ) - Number( moveRight );
+					direction.normalize(); // this ensures consistent movements in all directions
 
-					if ( moveLeft ) velocity.x -= 400.0 * delta;
-					if ( moveRight ) velocity.x += 400.0 * delta;
+					if ( moveForward || moveBackward ) velocity.z -= direction.z * 400.0 * delta;
+					if ( moveLeft || moveRight ) velocity.x -= direction.x * 400.0 * delta;
 
-					if ( isOnObject === true ) {
-						velocity.y = Math.max( 0, velocity.y );
+					if ( onObject === true ) {
 
+						velocity.y = Math.max( 0, velocity.y );
 						canJump = true;
+
 					}
 
 					controls.getObject().translateX( velocity.x * delta );

+ 4 - 4
examples/misc_exporter_gltf.html

@@ -263,16 +263,16 @@
 				// ---------------------------------------------------------------------
 				// Groups
 				// ---------------------------------------------------------------------
-				group1 = new THREE.Group();
+				var group1 = new THREE.Group();
 				group1.name = "Group";
 				scene1.add( group1 );
 
-				group2 = new THREE.Group();
+				var group2 = new THREE.Group();
 				group2.name = "subGroup";
 				group2.position.set( 0, 50, 0);
 				group1.add( group2 );
 
-				object2 = new THREE.Mesh( new THREE.BoxBufferGeometry( 30, 30, 30 ), material );
+				var object2 = new THREE.Mesh( new THREE.BoxBufferGeometry( 30, 30, 30 ), material );
 				object2.name = "Cube in group";
 				object2.position.set( 0, 0, 400 );
 				group2.add( object2 );
@@ -399,7 +399,7 @@
 					pointsArray[ 3 * i + 2 ] = -50 + Math.random() * 100;
 				}
 
-				pointsGeo = new THREE.BufferGeometry();
+				var pointsGeo = new THREE.BufferGeometry();
 				pointsGeo.addAttribute( 'position', new THREE.BufferAttribute( pointsArray, 3 ) );
 
 				var pointsMaterial = new THREE.PointsMaterial( { color: 0xffff00, size: 5 } );

File diff suppressed because it is too large
+ 146 - 0
examples/models/collada/abb_irb52_7_120.dae


+ 0 - 317
examples/models/collada/multimaterial.dae

@@ -1,317 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
-  <asset>
-    <contributor>
-      <author>Igor Campbell</author>
-      <authoring_tool>Blender 2.66.1 r55078</authoring_tool>
-    </contributor>
-    <created>2013-04-17T12:27:39</created>
-    <modified>2013-04-17T12:27:39</modified>
-    <unit name="meter" meter="1"/>
-    <up_axis>Z_UP</up_axis>
-  </asset>
-  <library_images/>
-  <library_effects>
-    <effect id="Material_001-effect">
-      <profile_COMMON>
-        <technique sid="common">
-          <phong>
-            <emission>
-              <color sid="emission">0 0 0 1</color>
-            </emission>
-            <ambient>
-              <color sid="ambient">0 0 0 1</color>
-            </ambient>
-            <diffuse>
-              <color sid="diffuse">0.64 0 0 1</color>
-            </diffuse>
-            <specular>
-              <color sid="specular">0.25 0.25 0.25 1</color>
-            </specular>
-            <shininess>
-              <float sid="shininess">50</float>
-            </shininess>
-            <index_of_refraction>
-              <float sid="index_of_refraction">1</float>
-            </index_of_refraction>
-          </phong>
-        </technique>
-        <extra>
-          <technique profile="GOOGLEEARTH">
-            <double_sided>1</double_sided>
-          </technique>
-        </extra>
-      </profile_COMMON>
-      <extra><technique profile="MAX3D"><double_sided>1</double_sided></technique></extra>
-    </effect>
-    <effect id="Material2-effect">
-      <profile_COMMON>
-        <technique sid="common">
-          <phong>
-            <emission>
-              <color sid="emission">0 0 0 1</color>
-            </emission>
-            <ambient>
-              <color sid="ambient">0 0 0 1</color>
-            </ambient>
-            <diffuse>
-              <color sid="diffuse">0 0 0.64 1</color>
-            </diffuse>
-            <specular>
-              <color sid="specular">0.25 0.25 0.25 1</color>
-            </specular>
-            <shininess>
-              <float sid="shininess">50</float>
-            </shininess>
-            <index_of_refraction>
-              <float sid="index_of_refraction">1</float>
-            </index_of_refraction>
-          </phong>
-        </technique>
-        <extra>
-          <technique profile="GOOGLEEARTH">
-            <double_sided>1</double_sided>
-          </technique>
-        </extra>
-      </profile_COMMON>
-      <extra><technique profile="MAX3D"><double_sided>1</double_sided></technique></extra>
-    </effect>
-    <effect id="Material3-effect">
-      <profile_COMMON>
-        <technique sid="common">
-          <phong>
-            <emission>
-              <color sid="emission">0 0 0 1</color>
-            </emission>
-            <ambient>
-              <color sid="ambient">0 0 0 1</color>
-            </ambient>
-            <diffuse>
-              <color sid="diffuse">0 0.64 0 1</color>
-            </diffuse>
-            <specular>
-              <color sid="specular">0.25 0.25 0.25 1</color>
-            </specular>
-            <shininess>
-              <float sid="shininess">50</float>
-            </shininess>
-            <index_of_refraction>
-              <float sid="index_of_refraction">1</float>
-            </index_of_refraction>
-          </phong>
-        </technique>
-        <extra>
-          <technique profile="GOOGLEEARTH">
-            <double_sided>1</double_sided>
-          </technique>
-        </extra>
-      </profile_COMMON>
-      <extra><technique profile="MAX3D"><double_sided>1</double_sided></technique></extra>
-    </effect>
-    <effect id="Material4-effect">
-      <profile_COMMON>
-        <technique sid="common">
-          <phong>
-            <emission>
-              <color sid="emission">0 0 0 1</color>
-            </emission>
-            <ambient>
-              <color sid="ambient">0 0 0 1</color>
-            </ambient>
-            <diffuse>
-              <color sid="diffuse">0.64 0.64 0 1</color>
-            </diffuse>
-            <specular>
-              <color sid="specular">0.25 0.25 0.25 1</color>
-            </specular>
-            <shininess>
-              <float sid="shininess">50</float>
-            </shininess>
-            <index_of_refraction>
-              <float sid="index_of_refraction">1</float>
-            </index_of_refraction>
-          </phong>
-        </technique>
-        <extra>
-          <technique profile="GOOGLEEARTH">
-            <double_sided>1</double_sided>
-          </technique>
-        </extra>
-      </profile_COMMON>
-      <extra><technique profile="MAX3D"><double_sided>1</double_sided></technique></extra>
-    </effect>
-    <effect id="Material5-effect">
-      <profile_COMMON>
-        <technique sid="common">
-          <phong>
-            <emission>
-              <color sid="emission">0 0 0 1</color>
-            </emission>
-            <ambient>
-              <color sid="ambient">0 0 0 1</color>
-            </ambient>
-            <diffuse>
-              <color sid="diffuse">0.64 0 0.64 1</color>
-            </diffuse>
-            <specular>
-              <color sid="specular">0.25 0.25 0.25 1</color>
-            </specular>
-            <shininess>
-              <float sid="shininess">50</float>
-            </shininess>
-            <index_of_refraction>
-              <float sid="index_of_refraction">1</float>
-            </index_of_refraction>
-          </phong>
-        </technique>
-        <extra>
-          <technique profile="GOOGLEEARTH">
-            <double_sided>1</double_sided>
-          </technique>
-        </extra>
-      </profile_COMMON>
-      <extra><technique profile="MAX3D"><double_sided>1</double_sided></technique></extra>
-    </effect>
-    <effect id="Material6-effect">
-      <profile_COMMON>
-        <technique sid="common">
-          <phong>
-            <emission>
-              <color sid="emission">0 0 0 1</color>
-            </emission>
-            <ambient>
-              <color sid="ambient">0 0 0 1</color>
-            </ambient>
-            <diffuse>
-              <color sid="diffuse">0 0.64 0.64 1</color>
-            </diffuse>
-            <specular>
-              <color sid="specular">0.25 0.25 0.25 1</color>
-            </specular>
-            <shininess>
-              <float sid="shininess">50</float>
-            </shininess>
-            <index_of_refraction>
-              <float sid="index_of_refraction">1</float>
-            </index_of_refraction>
-          </phong>
-        </technique>
-        <extra>
-          <technique profile="GOOGLEEARTH">
-            <double_sided>1</double_sided>
-          </technique>
-        </extra>
-      </profile_COMMON>
-      <extra><technique profile="MAX3D"><double_sided>1</double_sided></technique></extra>
-    </effect>
-  </library_effects>
-  <library_materials>
-    <material id="Material_001-material" name="Material_001">
-      <instance_effect url="#Material_001-effect"/>
-    </material>
-    <material id="Material2-material" name="Material2">
-      <instance_effect url="#Material2-effect"/>
-    </material>
-    <material id="Material3-material" name="Material3">
-      <instance_effect url="#Material3-effect"/>
-    </material>
-    <material id="Material4-material" name="Material4">
-      <instance_effect url="#Material4-effect"/>
-    </material>
-    <material id="Material5-material" name="Material5">
-      <instance_effect url="#Material5-effect"/>
-    </material>
-    <material id="Material6-material" name="Material6">
-      <instance_effect url="#Material6-effect"/>
-    </material>
-  </library_materials>
-  <library_geometries>
-    <geometry id="Cube_001-mesh" name="Cube.001">
-      <mesh>
-        <source id="Cube_001-mesh-positions">
-          <float_array id="Cube_001-mesh-positions-array" count="24">1 1 -1 1 -1 -1 -1 -0.9999998 -1 -0.9999997 1 -1 1 0.9999995 1 0.9999994 -1.000001 1 -1 -0.9999997 1 -1 1 1</float_array>
-          <technique_common>
-            <accessor source="#Cube_001-mesh-positions-array" count="8" stride="3">
-              <param name="X" type="float"/>
-              <param name="Y" type="float"/>
-              <param name="Z" type="float"/>
-            </accessor>
-          </technique_common>
-        </source>
-        <source id="Cube_001-mesh-normals">
-          <float_array id="Cube_001-mesh-normals-array" count="18">1 -1.49012e-7 1.49012e-7 0 0 1 -3.57628e-7 -1 -2.08616e-7 0 0 -1 1.19209e-7 1 1.19209e-7 -1 0 0</float_array>
-          <technique_common>
-            <accessor source="#Cube_001-mesh-normals-array" count="6" stride="3">
-              <param name="X" type="float"/>
-              <param name="Y" type="float"/>
-              <param name="Z" type="float"/>
-            </accessor>
-          </technique_common>
-        </source>
-        <vertices id="Cube_001-mesh-vertices">
-          <input semantic="POSITION" source="#Cube_001-mesh-positions"/>
-        </vertices>
-        <polylist material="Material_001-material" count="1">
-          <input semantic="VERTEX" source="#Cube_001-mesh-vertices" offset="0"/>
-          <input semantic="NORMAL" source="#Cube_001-mesh-normals" offset="1"/>
-          <vcount>4 </vcount>
-          <p>0 0 4 0 5 0 1 0</p>
-        </polylist>
-        <polylist material="Material2-material" count="1">
-          <input semantic="VERTEX" source="#Cube_001-mesh-vertices" offset="0"/>
-          <input semantic="NORMAL" source="#Cube_001-mesh-normals" offset="1"/>
-          <vcount>4 </vcount>
-          <p>4 1 7 1 6 1 5 1</p>
-        </polylist>
-        <polylist material="Material3-material" count="1">
-          <input semantic="VERTEX" source="#Cube_001-mesh-vertices" offset="0"/>
-          <input semantic="NORMAL" source="#Cube_001-mesh-normals" offset="1"/>
-          <vcount>4 </vcount>
-          <p>1 2 5 2 6 2 2 2</p>
-        </polylist>
-        <polylist material="Material4-material" count="1">
-          <input semantic="VERTEX" source="#Cube_001-mesh-vertices" offset="0"/>
-          <input semantic="NORMAL" source="#Cube_001-mesh-normals" offset="1"/>
-          <vcount>4 </vcount>
-          <p>0 3 1 3 2 3 3 3</p>
-        </polylist>
-        <polylist material="Material5-material" count="1">
-          <input semantic="VERTEX" source="#Cube_001-mesh-vertices" offset="0"/>
-          <input semantic="NORMAL" source="#Cube_001-mesh-normals" offset="1"/>
-          <vcount>4 </vcount>
-          <p>4 4 0 4 3 4 7 4</p>
-        </polylist>
-        <polylist material="Material6-material" count="1">
-          <input semantic="VERTEX" source="#Cube_001-mesh-vertices" offset="0"/>
-          <input semantic="NORMAL" source="#Cube_001-mesh-normals" offset="1"/>
-          <vcount>4 </vcount>
-          <p>2 5 6 5 7 5 3 5</p>
-        </polylist>
-      </mesh>
-      <extra><technique profile="MAYA"><double_sided>1</double_sided></technique></extra>
-    </geometry>
-  </library_geometries>
-  <library_controllers/>
-  <library_visual_scenes>
-    <visual_scene id="Scene" name="Scene">
-      <node id="Cube_001" name="Cube_001" type="NODE">
-        <matrix sid="transform">1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</matrix>
-        <instance_geometry url="#Cube_001-mesh">
-          <bind_material>
-            <technique_common>
-              <instance_material symbol="Material_001-material" target="#Material_001-material"/>
-              <instance_material symbol="Material2-material" target="#Material2-material"/>
-              <instance_material symbol="Material3-material" target="#Material3-material"/>
-              <instance_material symbol="Material4-material" target="#Material4-material"/>
-              <instance_material symbol="Material5-material" target="#Material5-material"/>
-              <instance_material symbol="Material6-material" target="#Material6-material"/>
-            </technique_common>
-          </bind_material>
-        </instance_geometry>
-      </node>
-    </visual_scene>
-  </library_visual_scenes>
-  <scene>
-    <instance_visual_scene url="#Scene"/>
-  </scene>
-</COLLADA>

+ 0 - 0
examples/models/skin_and_morph.dae → examples/models/collada/skin_and_morph.dae


BIN
examples/models/skinned/simple/simple.blend


+ 2 - 2
examples/misc_sound.html → examples/webaudio_sandbox.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en">
 	<head>
-		<title>three.js misc - sound</title>
+		<title>three.js webaudio - sandbox</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<style>
@@ -32,7 +32,7 @@
 	<body>
 
 		<div id="info">
-			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - webgl 3d sounds -
+			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> webaudio - sandbox<br/>
 			music by <a href="http://www.newgrounds.com/audio/listen/358232" target="_blank" rel="noopener">larrylarrybb</a>,
 			<a href="http://www.newgrounds.com/audio/listen/376737" target="_blank" rel="noopener">skullbeatz</a> and
 			<a href="http://opengameart.org/content/project-utopia-seamless-loop" target="_blank" rel="noopener">congusbongus</a><br/><br/>

+ 3 - 3
examples/misc_sound_visualizer.html → examples/webaudio_visualizer.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en">
 	<head>
-		<title>three.js misc - sound visualizer</title>
+		<title>three.js webaudio - visualizer</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<style>
@@ -70,8 +70,8 @@
 
 	<div id="container"></div>
 	<div id="info">
-		<a href="https://threejs.org" target="_blank">three.js</a> - misc - sound visualizer -
-		music by <a href="http://www.newgrounds.com/audio/listen/358232" target="_blank">larrylarrybb</a>
+		<a href="https://threejs.org" target="_blank" rel="noopener noreferrer">three.js</a> webaudio - visualizer<br/>
+		music by <a href="http://www.newgrounds.com/audio/listen/358232" target="_blank" rel="noopener noreferrer">larrylarrybb</a>
 	</div>
 
 	<script>

+ 1 - 1
examples/webgl_geometry_shapes.html

@@ -75,7 +75,7 @@
 				function addShape( shape, extrudeSettings, color, x, y, z, rx, ry, rz, s ) {
 
 					// flat shape with texture
-					// note: default UVs generated by ShapeBufferGemoetry are simply the x- and y-coordinates of the vertices
+					// note: default UVs generated by ShapeBufferGeometry are simply the x- and y-coordinates of the vertices
 
 					var geometry = new THREE.ShapeBufferGeometry( shape );
 

+ 29 - 12
examples/webgl_loader_collada_kinematics.html

@@ -58,7 +58,8 @@
 
 			var loader = new THREE.ColladaLoader();
 			loader.options.convertUpAxis = true;
-			loader.load( './models/collada/kawada-hironx.dae', function ( collada ) {
+			// loader.load( './models/collada/kawada-hironx.dae', function ( collada ) {
+			loader.load( './models/collada/abb_irb52_7_120.dae', function ( collada ) {
 
 				dae = collada.scene;
 
@@ -135,17 +136,25 @@
 
 				var target = {};
 
-				for ( var i = 0; i < kinematics.joints.length; i ++ ) {
+				for ( var prop in kinematics.joints ) {
 
-					var joint = kinematics.joints[ i ];
+					if ( kinematics.joints.hasOwnProperty( prop ) ) {
 
-					var old = tweenParameters[ i ];
+						if ( ! kinematics.joints[ prop ].static ) {
 
-					var position = old ? old : joint.zeroPosition;
+							var joint = kinematics.joints[ prop ];
 
-					tweenParameters[ i ] = position;
+							var old = tweenParameters[ prop ];
 
-					target[ i ] = THREE.Math.randInt( joint.limits.min, joint.limits.max )
+							var position = old ? old : joint.zeroPosition;
+
+							tweenParameters[ prop ] = position;
+
+							target[ prop ] = THREE.Math.randInt( joint.limits.min, joint.limits.max )
+
+						}
+
+					}
 
 				}
 
@@ -153,9 +162,17 @@
 
 				kinematicsTween.onUpdate( function() {
 
-					for ( var i = 0; i < kinematics.joints.length; i ++ ) {
+					for ( var prop in kinematics.joints ) {
+
+						if ( kinematics.joints.hasOwnProperty( prop ) ) {
+
+							if ( ! kinematics.joints[ prop ].static ) {
+
+								kinematics.setJointValue( prop, this[ prop ] );
+
+							}
 
-						kinematics.setJointValue( i, this[ i ] );
+						}
 
 					}
 
@@ -192,11 +209,11 @@
 
 				var timer = Date.now() * 0.0001;
 
-				camera.position.x = Math.cos( timer ) * 17;
+				camera.position.x = Math.cos( timer ) * 20;
 				camera.position.y = 10;
-				camera.position.z = Math.sin( timer ) * 17;
+				camera.position.z = Math.sin( timer ) * 20;
 
-				camera.lookAt( scene.position );
+				camera.lookAt( new THREE.Vector3( 0, 5, 0 ) );
 
 				particleLight.position.x = Math.sin( timer * 4 ) * 3009;
 				particleLight.position.y = Math.cos( timer * 5 ) * 4000;

+ 27 - 178
examples/webgl_loader_obj2.html

@@ -78,6 +78,7 @@
 		<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>
 
@@ -85,7 +86,7 @@
 
 			var OBJLoader2Example = (function () {
 
-				var Validator = THREE.OBJLoader2.prototype._getValidator();
+				var Validator = THREE.LoaderSupport.Validator;
 
 				function OBJLoader2Example( elementToBindTo ) {
 					this.renderer = null;
@@ -105,24 +106,17 @@
 					this.cameraTarget = this.cameraDefaults.posCameraTarget;
 
 					this.controls = null;
-
-					this.flatShading = false;
-					this.doubleSide = false;
-
-					this.cube = null;
-					this.pivot = null;
-
-					this.feedbackArray = [];
 				}
 
 				OBJLoader2Example.prototype.initGL = function () {
 					this.renderer = new THREE.WebGLRenderer( {
 						canvas: this.canvas,
-						antialias: true
+						antialias: true,
+						autoClear: true
 					} );
+					this.renderer.setClearColor( 0x050505 );
 
 					this.scene = new THREE.Scene();
-					this.scene.background = new THREE.Color( 0x050505 );
 
 					this.camera = new THREE.PerspectiveCamera( this.cameraDefaults.fov, this.aspectRatio, this.cameraDefaults.near, this.cameraDefaults.far );
 					this.resetCamera();
@@ -141,70 +135,34 @@
 
 					var helper = new THREE.GridHelper( 1200, 60, 0xFF4444, 0x404040 );
 					this.scene.add( helper );
-
-					var geometry = new THREE.BoxGeometry( 10, 10, 10 );
-					var material = new THREE.MeshNormalMaterial();
-					this.cube = new THREE.Mesh( geometry, material );
-					this.cube.position.set( 0, 0, 0 );
-					this.scene.add( this.cube );
-
-					this.pivot = new THREE.Object3D();
-					this.pivot.name = 'Pivot';
-					this.scene.add( this.pivot );
 				};
 
-				OBJLoader2Example.prototype.initPostGL = function () {
-					return true;
-				};
+				OBJLoader2Example.prototype.initContent = function () {
+					var modelName = 'female02';
+					this._reportProgress( 'Loading: ' + modelName );
 
-				OBJLoader2Example.prototype.loadObj = function ( objDef ) {
-					this.scene.add( objDef.pivot );
 					var scope = this;
-					scope._reportProgress( 'Loading: ' + objDef.fileObj, objDef.instanceNo );
-
-					var mtlLoader = new THREE.MTLLoader();
-					mtlLoader.setPath( objDef.texturePath );
-					mtlLoader.setCrossOrigin( 'anonymous' );
-					mtlLoader.load( objDef.fileMtl, function( materials ) {
-
-						materials.preload();
-
-						scope.pivot.add( objDef.pivot );
-						var objLoader = new THREE.OBJLoader2();
-						objLoader.setSceneGraphBaseNode( objDef.pivot );
-						objLoader.setMaterials( materials.materials );
-						objLoader.setPath( objDef.path );
-						objLoader.setDebug( false, false );
-
-						var onSuccess = function ( object3d ) {
-							console.log( 'Loading complete. Meshes were attached to: ' + object3d.name );
-							scope._reportProgress( '', objDef.instanceNo );
-						};
-
-						var onProgress = function ( event ) {
-							if ( event.lengthComputable ) {
-
-								var percentComplete = event.loaded / event.total * 100;
-								var output = 'Download of "' + objDef.fileObj + '": ' + Math.round( percentComplete ) + '%';
-								scope._reportProgress( output, objDef.instanceNo );
-							}
-						};
-
-						var onError = function ( event ) {
-							var output = 'Error of type "' + event.type + '" occurred when trying to load: ' + event.src;
-							scope._reportProgress( output, objDef.instanceNo );
-						};
-
-						objLoader.load( objDef.fileObj, onSuccess, onProgress, onError );
+					var objLoader = new THREE.OBJLoader2();
+					var callbackOnLoad = function ( loaderRootNode, modelName, instanceNo ) {
+						scope.scene.add( loaderRootNode );
+						console.log( 'Loading complete: ' + modelName );
+						scope._reportProgress( '' );
+					};
 
-					});
+					var onLoadMtl = function ( materials ) {
+						objLoader.setModelName( modelName );
+						objLoader.setMaterials( materials );
+						objLoader.setUseIndices( true );
+						objLoader.setDisregardNormals( false );
+						objLoader.setDebug( false );
+						objLoader.load( 'obj/female02/female02.obj', callbackOnLoad, null, null, null, false );
+					};
+					objLoader.loadMtl( 'obj/female02/female02.mtl', 'female02.mtl', null, onLoadMtl );
 				};
 
-				OBJLoader2Example.prototype._reportProgress = function( text, instanceNo ) {
-					this.feedbackArray[ instanceNo ] = text;
-					console.log( 'Progress: ' + text );
-
-					document.getElementById( 'feedback' ).innerHTML = Validator.isValid( this.feedbackArray ) && this.feedbackArray.length > 0 ? this.feedbackArray.join( '\<br\>' ) : '';
+				OBJLoader2Example.prototype._reportProgress = function( content ) {
+					console.log( 'Progress: ' + content );
+					document.getElementById( 'feedback' ).innerHTML = Validator.isValid( content ) ? content : '';
 				};
 
 				OBJLoader2Example.prototype.resizeDisplayGL = function () {
@@ -235,103 +193,16 @@
 
 				OBJLoader2Example.prototype.render = function () {
 					if ( ! this.renderer.autoClear ) this.renderer.clear();
-
 					this.controls.update();
-
-					this.cube.rotation.x += 0.05;
-					this.cube.rotation.y += 0.05;
-
 					this.renderer.render( this.scene, this.camera );
 				};
 
-				OBJLoader2Example.prototype.alterShading = function () {
-
-					var scope = this;
-					scope.flatShading = ! scope.flatShading;
-					console.log( scope.flatShading ? 'Enabling flat shading' : 'Enabling smooth shading');
-
-					scope.traversalFunction = function ( material ) {
-						material.flatShading = scope.flatShading;
-						material.needsUpdate = true;
-					};
-					var scopeTraverse = function ( object3d ) {
-						scope.traverseScene( object3d );
-					};
-					scope.pivot.traverse( scopeTraverse );
-				};
-
-				OBJLoader2Example.prototype.alterDouble = function () {
-
-					var scope = this;
-					scope.doubleSide = ! scope.doubleSide;
-					console.log( scope.doubleSide ? 'Enabling DoubleSide materials' : 'Enabling FrontSide materials');
-
-					scope.traversalFunction  = function ( material ) {
-						material.side = scope.doubleSide ? THREE.DoubleSide : THREE.FrontSide;
-					};
-
-					var scopeTraverse = function ( object3d ) {
-						scope.traverseScene( object3d );
-					};
-					scope.pivot.traverse( scopeTraverse );
-				};
-
-				OBJLoader2Example.prototype.traverseScene = function ( object3d ) {
-
-					if ( object3d.material instanceof THREE.MultiMaterial ) {
-
-						var materials = object3d.material.materials;
-						for ( var name in materials ) {
-
-							if ( materials.hasOwnProperty( name ) )	this.traversalFunction( materials[ name ] );
-
-						}
-
-					} else if ( object3d.material ) {
-
-						this.traversalFunction( object3d.material );
-
-					}
-
-				};
-
 				return OBJLoader2Example;
 
 			})();
 
 			var app = new OBJLoader2Example( document.getElementById( 'example' ) );
 
-			// Init dat.gui and controls
-			var OBJLoader2Control = function() {
-				this.flatShading = app.flatShading;
-				this.doubleSide = app.doubleSide;
-			};
-			var objLoader2Control = new OBJLoader2Control();
-
-			var gui = new dat.GUI( {
-				autoPlace: false,
-				width: 320
-			} );
-
-			var menuDiv = document.getElementById( 'dat' );
-			menuDiv.appendChild(gui.domElement);
-			var folderQueue = gui.addFolder( 'OBJLoader2 Options' );
-			var controlSmooth = folderQueue.add( objLoader2Control, 'flatShading' ).name( 'Flat Shading' );
-			controlSmooth.onChange( function( value ) {
-				console.log( 'Setting flatShading to: ' + value );
-				app.alterShading();
-			});
-
-			var controlDouble = folderQueue.add( objLoader2Control, 'doubleSide' ).name( 'Double Side Materials' );
-			controlDouble.onChange( function( value ) {
-				console.log( 'Setting doubleSide to: ' + value );
-				app.alterDouble();
-			});
-			folderQueue.open();
-
-
-
-			// init three.js example application
 			var resizeWindow = function () {
 				app.resizeDisplayGL();
 			};
@@ -346,29 +217,7 @@
 			console.log( 'Starting initialisation phase...' );
 			app.initGL();
 			app.resizeDisplayGL();
-			app.initPostGL();
-
-			var pivotA = new THREE.Object3D();
-			pivotA.name = 'PivotA';
-			pivotA.position.set( -50, 0, 0 );
-			app.loadObj( {
-				path: 'obj/female02/',
-				fileObj: 'female02_vertex_colors.obj',
-				pivot: pivotA,
-				instanceNo: 0
-			} );
-
-			var pivotB = new THREE.Object3D();
-			pivotB.name = 'PivotB';
-			pivotB.position.set( 50, 0, 0 );
-			app.loadObj( {
-				path: 'obj/female02/',
-				fileObj: 'female02.obj',
-				texturePath: 'obj/female02/',
-				fileMtl: 'female02.mtl',
-				pivot: pivotB,
-				instanceNo: 1
-			} );
+			app.initContent();
 
 			render();
 

+ 471 - 0
examples/webgl_loader_obj2_meshspray.html

@@ -0,0 +1,471 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>Mesh Spray - Worker based mesh spray</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+
+		<style>
+			body {
+				font-family: Monospace;
+				background-color: #000;
+				color: #fff;
+				margin: 0 0 0 0;
+				padding: 0 0 0 0;
+				border: none;
+				cursor: default;
+			}
+			#info {
+				color: #fff;
+				position: absolute;
+				top: 10px;
+				width: 100%;
+				text-align: center;
+				z-index: 100;
+				display:block;
+			}
+			#info a {
+				color: #f00;
+				font-weight: bold;
+				text-decoration: underline;
+				cursor: pointer
+			}
+			#glFullscreen {
+				width: 100%;
+				height: 100vh;
+				min-width: 640px;
+				min-height: 360px;
+				position: relative;
+				overflow: hidden;
+				z-index: 0;
+			}
+			#example {
+				width: 100%;
+				height: 100%;
+				top: 0;
+				left: 0;
+				background-color: #000000;
+			}
+			#feedback {
+				color: darkorange;
+			}
+			#dat {
+				user-select: none;
+				position: absolute;
+				left: 0;
+				top: 0;
+				z-Index: 200;
+			}
+		</style>
+
+	</head>
+
+	<body>
+	<div id="glFullscreen">
+		<canvas id="example"></canvas>
+	</div>
+	<div id="dat">
+
+	</div>
+	<div id="info">
+		<a href="http://threejs.org" target="_blank">three.js</a> - Mesh Spray
+		<div id="feedback"></div>
+	</div>
+
+		<script src="js/Detector.js"></script>
+		<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>
+			/**
+			 * @author Kai Salmen / www.kaisalmen.de
+			 */
+
+			'use strict';
+
+			var MeshSpray = (function () {
+
+				var Validator = THREE.LoaderSupport.Validator;
+
+				MeshSpray.prototype = Object.create( THREE.LoaderSupport.Commons.prototype );
+				MeshSpray.prototype.constructor = MeshSpray;
+
+				function MeshSpray( manager ) {
+					THREE.LoaderSupport.Commons.call( this, manager );
+					this.workerSupport = null;
+				};
+
+				MeshSpray.prototype.run = function ( prepData, workerSupportExternal ) {
+					console.time( 'MeshSpray' );
+
+					this._applyPrepData( prepData );
+
+					var scope = this;
+					var scopeBuilderFunc = function ( payload ) {
+						var meshes = scope.builder.buildMeshes( payload );
+						var mesh;
+						for ( var i in meshes ) {
+							mesh = meshes[ i ];
+							scope.loaderRootNode.add( mesh );
+						}
+					};
+					var scopeFuncComplete = function ( message ) {
+						var callback = scope.callbacks.onLoad;
+						if ( Validator.isValid( callback ) ) callback( scope.loaderRootNode, scope.modelName, scope.instanceNo, message );
+						console.timeEnd( 'MeshSpray' );
+					};
+
+			        this.workerSupport = Validator.verifyInput( workerSupportExternal, this.workerSupport );
+					this.workerSupport = Validator.verifyInput( this.workerSupport, new THREE.LoaderSupport.WorkerSupport() );
+					var buildCode = function ( funcBuildObject, funcBuildSingelton ) {
+						var workerCode = '';
+						workerCode += '/**\n';
+						workerCode += '  * This code was constructed by MeshSpray buildWorkerCode.\n';
+						workerCode += '  */\n\n';
+						workerCode += funcBuildObject( 'Validator', Validator );
+						workerCode += funcBuildSingelton( 'Parser', 'Parser', Parser );
+
+						return workerCode;
+					};
+					this.workerSupport.validate( buildCode, false );
+					this.workerSupport.setCallbacks( scopeBuilderFunc, scopeFuncComplete );
+					this.workerSupport.run(
+						{
+							cmd: 'run',
+							params: {
+								debug: this.debug,
+								dimension: prepData.dimension,
+								quantity: prepData.quantity,
+								globalObjectCount: prepData.globalObjectCount
+							},
+							materials: {
+								materialNames: this.builder.materialNames
+							},
+							buffers: {
+								input: null
+							}
+						}
+					);
+				};
+
+				var Parser  = ( function () {
+
+					function Parser() {
+						this.sizeFactor = 0.5;
+						this.localOffsetFactor = 1.0;
+						this.globalObjectCount = 0;
+						this.debug = false;
+						this.dimension = 200;
+						this.quantity = 1;
+						this.callbackBuilder = null;
+					};
+
+					Parser.prototype.parse = function () {
+						var materialDescription;
+						var materialDescriptions = [];
+						var materialGroups = [];
+
+						materialDescription = {
+							name: 'Gen',
+							flat: false,
+							vertexColors: true,
+							default: true
+						};
+						materialDescriptions.push( materialDescription );
+
+						var baseTriangle = [ 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 0.0, -1.0, 1.0 ];
+						var vertices = [];
+						var colors = [];
+						var normals = [];
+						var uvs = [];
+
+						var dimensionHalf = this.dimension / 2;
+						var fixedOffsetX;
+						var fixedOffsetY;
+						var fixedOffsetZ;
+						var s, t;
+						// complete triagle
+						var sizeVaring = this.sizeFactor * Math.random();
+						// local coords offset
+						var localOffsetFactor = this.localOffsetFactor;
+
+						for ( var i = 0; i < this.quantity; i++ ) {
+							sizeVaring = this.sizeFactor * Math.random();
+
+							s = 2 * Math.PI * Math.random();
+							t = Math.PI * Math.random();
+
+							fixedOffsetX = dimensionHalf * Math.random() * Math.cos( s ) * Math.sin( t );
+							fixedOffsetY = dimensionHalf * Math.random() * Math.sin( s ) * Math.sin( t );
+							fixedOffsetZ = dimensionHalf * Math.random() * Math.cos( t );
+							for ( var j = 0; j < baseTriangle.length; j += 3 ) {
+								vertices.push( baseTriangle[ j ] * sizeVaring + localOffsetFactor * Math.random() + fixedOffsetX );
+								vertices.push( baseTriangle[ j + 1 ] * sizeVaring + localOffsetFactor * Math.random() + fixedOffsetY );
+								vertices.push( baseTriangle[ j + 2 ] * sizeVaring + localOffsetFactor * Math.random() + fixedOffsetZ );
+								colors.push( Math.random() );
+								colors.push( Math.random() );
+								colors.push( Math.random() );
+							}
+						}
+
+						var absoluteVertexCount = vertices.length;
+						var absoluteColorCount = colors.length;
+						var absoluteNormalCount = 0;
+						var absoluteUvCount = 0;
+
+						var vertexFA = new Float32Array( absoluteVertexCount );
+						var colorFA = ( absoluteColorCount > 0 ) ? new Float32Array( absoluteColorCount ) : null;
+						var normalFA = ( absoluteNormalCount > 0 ) ? new Float32Array( absoluteNormalCount ) : null;
+						var uvFA = ( absoluteUvCount > 0 ) ? new Float32Array( absoluteUvCount ) : null;
+
+						vertexFA.set( vertices, 0 );
+						if ( colorFA ) {
+
+							colorFA.set( colors, 0 );
+
+						}
+
+						if ( normalFA ) {
+
+							normalFA.set( normals, 0 );
+
+						}
+						if ( uvFA ) {
+
+							uvFA.set( uvs, 0 );
+
+						}
+
+						this.globalObjectCount++;
+						this.callbackBuilder(
+							{
+								cmd: 'meshData',
+								params: {
+									meshName: 'Gen' + this.globalObjectCount
+								},
+								materials: {
+									multiMaterial: false,
+									materialDescriptions: materialDescriptions,
+									materialGroups: materialGroups
+								},
+								buffers: {
+									vertices: vertexFA,
+									colors: colorFA,
+									normals: normalFA,
+									uvs: uvFA
+								}
+							},
+							[ vertexFA.buffer ],
+							colorFA !== null ? [ colorFA.buffer ] : null,
+							normalFA !== null ? [ normalFA.buffer ] : null,
+							uvFA !== null ? [ uvFA.buffer ] : null
+						);
+
+						console.log( 'Global output object count: ' + this.globalObjectCount );
+					};
+
+					return Parser;
+				})();
+
+				return MeshSpray;
+
+			})();
+
+			var MeshSprayApp = (function () {
+
+				function MeshSprayApp( elementToBindTo ) {
+					this.renderer = null;
+					this.canvas = elementToBindTo;
+					this.aspectRatio = 1;
+					this.recalcAspectRatio();
+
+					this.scene = null;
+					this.cameraDefaults = {
+						posCamera: new THREE.Vector3( 500.0, 500.0, 1000.0 ),
+						posCameraTarget: new THREE.Vector3( 0, 0, 0 ),
+						near: 0.1,
+						far: 10000,
+						fov: 45
+					};
+					this.camera = null;
+					this.cameraTarget = this.cameraDefaults.posCameraTarget;
+
+					this.controls = null;
+
+					this.cube = null;
+					this.pivot = null;
+				}
+
+				MeshSprayApp.prototype.initGL = function () {
+					this.renderer = new THREE.WebGLRenderer( {
+						canvas: this.canvas,
+						antialias: true,
+						autoClear: true
+					} );
+					this.renderer.setClearColor( 0x050505 );
+
+					this.scene = new THREE.Scene();
+
+					this.camera = new THREE.PerspectiveCamera( this.cameraDefaults.fov, this.aspectRatio, this.cameraDefaults.near, this.cameraDefaults.far );
+					this.resetCamera();
+					this.controls = new THREE.TrackballControls( this.camera, this.renderer.domElement );
+
+					var ambientLight = new THREE.AmbientLight( 0x404040 );
+					var directionalLight1 = new THREE.DirectionalLight( 0xC0C090 );
+					var directionalLight2 = new THREE.DirectionalLight( 0xC0C090 );
+
+					directionalLight1.position.set( -100, -50, 100 );
+					directionalLight2.position.set( 100, 50, -100 );
+
+					this.scene.add( directionalLight1 );
+					this.scene.add( directionalLight2 );
+					this.scene.add( ambientLight );
+
+					var helper = new THREE.GridHelper( 1200, 60, 0xFF4444, 0x404040 );
+					this.scene.add( helper );
+
+					var geometry = new THREE.BoxGeometry( 10, 10, 10 );
+					var material = new THREE.MeshNormalMaterial();
+					this.cube = new THREE.Mesh( geometry, material );
+					this.cube.position.set( 0, 0, 0 );
+					this.scene.add( this.cube );
+
+					this.pivot = new THREE.Object3D();
+					this.pivot.name = 'Pivot';
+					this.scene.add( this.pivot );
+				};
+
+				MeshSprayApp.prototype.initContent = function () {
+					var maxQueueSize = 1024;
+					var maxWebWorkers = 4;
+					var radius = 640;
+					this.workerDirector = new THREE.LoaderSupport.WorkerDirector( MeshSpray );
+					this.workerDirector.setCrossOrigin( 'anonymous' );
+
+					var scope = this;
+					var callbackOnLoad = function ( sceneGraphBaseNode, modelName, instanceNo ) {
+						var msg = 'Worker #' + instanceNo + ': Completed loading. (#' + scope.workerDirector.objectsCompleted + ')';
+						console.log( msg );
+					};
+					var reportProgress = function( content, modelName, instanceNo ) {
+						if ( THREE.LoaderSupport.Validator.isValid( content ) && content.length > 0 ) {
+
+							document.getElementById( 'feedback' ).innerHTML = content;
+							console.log( content );
+
+						}
+					};
+					var callbackMeshAlter = function ( name, bufferGeometry, material ) {
+						var override = new THREE.LoaderSupport.LoadedMeshUserOverride( false, true );
+
+						var mesh = new THREE.Mesh( bufferGeometry, material );
+						material.side = THREE.DoubleSide;
+						mesh.name = name;
+						override.addMesh( mesh );
+
+						return override;
+					};
+
+
+					var callbacks = new THREE.LoaderSupport.Callbacks();
+					callbacks.setCallbackOnMeshAlter( callbackMeshAlter );
+					callbacks.setCallbackOnLoad( callbackOnLoad );
+					callbacks.setCallbackOnProgress( reportProgress );
+					this.workerDirector.prepareWorkers( callbacks, maxQueueSize, maxWebWorkers );
+
+					var prepData;
+					var pivot;
+					var s, t, r, x, y, z;
+					var globalObjectCount = 0;
+					for ( var i = 0; i < maxQueueSize; i++ ) {
+						prepData = new THREE.LoaderSupport.PrepData( 'Triangles_' + i );
+
+						pivot = new THREE.Object3D();
+						s = 2 * Math.PI * Math.random();
+						t = Math.PI * Math.random();
+						r = radius * Math.random();
+						x = r * Math.cos( s ) * Math.sin( t );
+						y = r * Math.sin( s ) * Math.sin( t );
+						z = r * Math.cos( t );
+						pivot.position.set( x, y, z );
+						this.scene.add( pivot );
+						prepData.setStreamMeshesTo( pivot );
+
+						prepData.quantity = 8192;
+						prepData.dimension = Math.max( Math.random() * 500, 100 );
+						prepData.globalObjectCount = globalObjectCount++;
+
+						this.workerDirector.enqueueForRun( prepData );
+					}
+					this.workerDirector.processQueue();
+				};
+
+				MeshSprayApp.prototype.resizeDisplayGL = function () {
+					this.controls.handleResize();
+
+					this.recalcAspectRatio();
+					this.renderer.setSize( this.canvas.offsetWidth, this.canvas.offsetHeight, false );
+
+					this.updateCamera();
+				};
+
+				MeshSprayApp.prototype.recalcAspectRatio = function () {
+					this.aspectRatio = ( this.canvas.offsetHeight === 0 ) ? 1 : this.canvas.offsetWidth / this.canvas.offsetHeight;
+				};
+
+				MeshSprayApp.prototype.resetCamera = function () {
+					this.camera.position.copy( this.cameraDefaults.posCamera );
+					this.cameraTarget.copy( this.cameraDefaults.posCameraTarget );
+
+					this.updateCamera();
+				};
+
+				MeshSprayApp.prototype.updateCamera = function () {
+					this.camera.aspect = this.aspectRatio;
+					this.camera.lookAt( this.cameraTarget );
+					this.camera.updateProjectionMatrix();
+				};
+
+				MeshSprayApp.prototype.render = function () {
+					if ( ! this.renderer.autoClear ) this.renderer.clear();
+
+					this.controls.update();
+
+					this.cube.rotation.x += 0.05;
+					this.cube.rotation.y += 0.05;
+
+					this.renderer.render( this.scene, this.camera );
+				};
+
+				return MeshSprayApp;
+
+			})();
+
+			var app = new MeshSprayApp( document.getElementById( 'example' ) );
+
+			// init three.js example application
+			var resizeWindow = function () {
+				app.resizeDisplayGL();
+			};
+
+			var render = function () {
+				requestAnimationFrame( render );
+				app.render();
+			};
+
+			window.addEventListener( 'resize', resizeWindow, false );
+
+			console.log( 'Starting initialisation phase...' );
+			app.initGL();
+			app.resizeDisplayGL();
+			app.initContent();
+
+			render();
+
+		</script>
+	</body>
+</html>

+ 490 - 0
examples/webgl_loader_obj2_options.html

@@ -0,0 +1,490 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - WWOBJLoader2</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+
+		<style>
+			body {
+				font-family: Monospace;
+				background-color: #000;
+				color: #fff;
+				margin: 0 0 0 0;
+				padding: 0 0 0 0;
+				border: none;
+				cursor: default;
+			}
+			#info {
+				color: #fff;
+				position: absolute;
+				top: 10px;
+				width: 100%;
+				text-align: center;
+				z-index: 100;
+				display:block;
+			}
+			#info a {
+				color: #f00;
+				font-weight: bold;
+				text-decoration: underline;
+				cursor: pointer
+			}
+			#glFullscreen {
+				width: 100%;
+				height: 100vh;
+				min-width: 640px;
+				min-height: 360px;
+				position: relative;
+				overflow: hidden;
+				z-index: 0;
+			}
+			#example {
+				width: 100%;
+				height: 100%;
+				top: 0;
+				left: 0;
+				background-color: #000000;
+			}
+			#feedback {
+				color: darkorange;
+			}
+			#dat {
+				user-select: none;
+				position: absolute;
+				left: 0;
+				top: 0;
+				z-Index: 200;
+			}
+		</style>
+
+	</head>
+
+	<body>
+		<div id="glFullscreen">
+			<canvas id="example"></canvas>
+		</div>
+		<div id="dat">
+
+		</div>
+		<div id="info">
+			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - OBJLoader2 usage options
+			<div id="feedback"></div>
+		</div>
+
+		<script src="js/Detector.js"></script>
+		<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>
+
+			'use strict';
+
+			var WWOBJLoader2Example = (function () {
+
+				var Validator = THREE.LoaderSupport.Validator;
+
+				function WWOBJLoader2Example( elementToBindTo ) {
+					this.renderer = null;
+					this.canvas = elementToBindTo;
+					this.aspectRatio = 1;
+					this.recalcAspectRatio();
+
+					this.scene = null;
+					this.cameraDefaults = {
+						posCamera: new THREE.Vector3( 0.0, 175.0, 500.0 ),
+						posCameraTarget: new THREE.Vector3( 0, 0, 0 ),
+						near: 0.1,
+						far: 10000,
+						fov: 45
+					};
+					this.camera = null;
+					this.cameraTarget = this.cameraDefaults.posCameraTarget;
+
+					this.controls = null;
+
+					this.flatShading = false;
+					this.doubleSide = false;
+
+					this.cube = null;
+					this.pivot = null;
+				}
+
+				WWOBJLoader2Example.prototype.initGL = function () {
+					this.renderer = new THREE.WebGLRenderer( {
+						canvas: this.canvas,
+						antialias: true,
+						autoClear: true
+					} );
+					this.renderer.setClearColor( 0x050505 );
+
+					this.scene = new THREE.Scene();
+
+					this.camera = new THREE.PerspectiveCamera( this.cameraDefaults.fov, this.aspectRatio, this.cameraDefaults.near, this.cameraDefaults.far );
+					this.resetCamera();
+					this.controls = new THREE.TrackballControls( this.camera, this.renderer.domElement );
+
+					var ambientLight = new THREE.AmbientLight( 0x404040 );
+					var directionalLight1 = new THREE.DirectionalLight( 0xC0C090 );
+					var directionalLight2 = new THREE.DirectionalLight( 0xC0C090 );
+
+					directionalLight1.position.set( -100, -50, 100 );
+					directionalLight2.position.set( 100, 50, -100 );
+
+					this.scene.add( directionalLight1 );
+					this.scene.add( directionalLight2 );
+					this.scene.add( ambientLight );
+
+					var helper = new THREE.GridHelper( 1200, 60, 0xFF4444, 0x404040 );
+					this.scene.add( helper );
+
+					var geometry = new THREE.BoxGeometry( 10, 10, 10 );
+					var material = new THREE.MeshNormalMaterial();
+					this.cube = new THREE.Mesh( geometry, material );
+					this.cube.position.set( 0, 0, 0 );
+					this.scene.add( this.cube );
+
+					this.pivot = new THREE.Object3D();
+					this.pivot.name = 'Pivot';
+					this.scene.add( this.pivot );
+				};
+
+				WWOBJLoader2Example.prototype.useParseSync = function () {
+					var modelName = 'female02';
+					this._reportProgress( 'Loading: ' + modelName );
+
+					var scope = this;
+					var objLoader = new THREE.OBJLoader2();
+					var onLoadMtl = function ( materials ) {
+						objLoader.setModelName( modelName );
+						objLoader.setMaterials( materials );
+
+						var fileLoader = new THREE.FileLoader();
+						fileLoader.setPath( '' );
+						fileLoader.setResponseType( 'arraybuffer' );
+						fileLoader.load( 'obj/female02/female02.obj',
+							function ( content ) {
+								var local = new THREE.Object3D();
+								local.name = 'Pivot_female02';
+								local.position.set( 75, 0, 0 );
+								scope.pivot.add( local );
+								local.add( objLoader.parse( content ) );
+
+								scope._reportProgress( 'Loading complete: ' + modelName );
+							}
+						);
+					};
+					objLoader.loadMtl( 'obj/female02/female02.mtl', 'female02.mtl', null, onLoadMtl );
+				};
+
+
+				WWOBJLoader2Example.prototype.useParseAsync = function () {
+					var modelName = 'female02_vertex' ;
+					this._reportProgress( 'Loading: ' + modelName );
+
+					var callbackOnLoad = function ( loaderRootNode, modelName, instanceNo ) {
+						var local = new THREE.Object3D();
+						local.name = 'Pivot_female02_vertex';
+						local.position.set( -75, 0, 0 );
+						scope.pivot.add( local );
+						local.add( loaderRootNode );
+
+						scope._reportProgress( 'Loading complete: ' + modelName );
+					};
+
+					var scope = this;
+					var objLoader = new THREE.OBJLoader2();
+					objLoader.setModelName( modelName );
+
+					var fileLoader = new THREE.FileLoader();
+					fileLoader.setPath( '' );
+					fileLoader.setResponseType( 'arraybuffer' );
+					fileLoader.load( 'obj/female02/female02_vertex_colors.obj',
+						function ( content ) {
+							objLoader.parseAsync( content, callbackOnLoad );
+							scope._reportProgress( 'Loading complete: ' + modelName );
+						}
+					);
+				};
+
+				WWOBJLoader2Example.prototype.useLoadSync = function () {
+					var modelName = 'male02';
+					this._reportProgress( 'Loading: ' + modelName );
+
+					var scope = this;
+					var objLoader = new THREE.OBJLoader2();
+					var callbackOnLoad = function ( loaderRootNode, modelName, instanceNo ) {
+						var local = new THREE.Object3D();
+						local.name = 'Pivot_male02';
+						local.position.set( 0, 0, -75 );
+						scope.pivot.add( local );
+						local.add( loaderRootNode );
+
+						scope._reportProgress( 'Loading complete: ' + modelName );
+					};
+
+					var onLoadMtl = function ( materials ) {
+						objLoader.setModelName( modelName );
+						objLoader.setMaterials( materials );
+						objLoader.load( 'obj/male02/male02.obj', callbackOnLoad, null, null, null, false );
+					};
+					objLoader.loadMtl( 'obj/male02/male02.mtl', 'female02.mtl', null, onLoadMtl );
+				};
+
+				WWOBJLoader2Example.prototype.useLoadAsync = function () {
+					var modelName = 'WaltHead';
+					this._reportProgress( 'Loading: ' + modelName );
+
+					var scope = this;
+					var objLoader = new THREE.OBJLoader2();
+					var callbackOnLoad = function ( loaderRootNode, modelName, instanceNo ) {
+						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( loaderRootNode );
+
+						scope._reportProgress( 'Loading complete: ' + modelName );
+					};
+
+					var onLoadMtl = function ( materials ) {
+						objLoader.setModelName( modelName );
+						objLoader.setMaterials( materials );
+						objLoader.load( 'obj/walt/WaltHead.obj', callbackOnLoad, null, null, null, true );
+					};
+					objLoader.loadMtl( 'obj/walt//WaltHead.mtl', 'WaltHead.mtl', null, onLoadMtl );
+				};
+
+				WWOBJLoader2Example.prototype.useRunSync = function () {
+					var scope = this;
+					var callbackOnLoad = function ( loaderRootNode, modelName, instanceNo ) {
+						scope._reportProgress( 'Loading complete: ' + modelName );
+					};
+
+					var prepData = new THREE.LoaderSupport.PrepData( 'cerberus' );
+					var local = new THREE.Object3D();
+					local.position.set( 0, 0, 100 );
+					local.scale.set( 50.0, 50.0, 50.0 );
+					this.pivot.add( local );
+					prepData.setStreamMeshesTo( 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 );
+				};
+
+				WWOBJLoader2Example.prototype.useRunAsyncMeshAlter = function () {
+					var scope = this;
+					var callbackOnLoad = function ( loaderRootNode, modelName, instanceNo ) {
+						scope._reportProgress( 'Loading complete: ' + modelName );
+					};
+
+					var prepData = new THREE.LoaderSupport.PrepData( 'vive-controller' );
+					var local = new THREE.Object3D();
+					local.position.set( 125, 50, 0 );
+					local.name = 'Pivot_vive-controller';
+					this.pivot.add( local );
+					prepData.setStreamMeshesTo( local );
+					prepData.addResource( new THREE.LoaderSupport.ResourceDescriptor( 'models/obj/vive-controller/vr_controller_vive_1_5.obj', 'OBJ' ) );
+					prepData.setUseAsync( true );
+					var callbacks = prepData.getCallbacks();
+					var callbackMeshAlter = function ( name, bufferGeometry, material ) {
+						var override = new THREE.LoaderSupport.LoadedMeshUserOverride( false, true );
+
+						var mesh = new THREE.Mesh( bufferGeometry, material );
+						var scale = 200.0;
+						mesh.scale.set( scale, scale, scale );
+						mesh.name = name;
+						var helper = new THREE.VertexNormalsHelper( mesh, 2, 0x00ff00, 1 );
+						helper.name = 'VertexNormalsHelper';
+
+						override.addMesh( mesh );
+						override.addMesh( helper );
+
+						return override;
+					};
+					callbacks.setCallbackOnMeshAlter( callbackMeshAlter );
+					callbacks.setCallbackOnProgress( this._reportProgress );
+					callbacks.setCallbackOnLoad( callbackOnLoad );
+
+					var objLoader = new THREE.OBJLoader2();
+					objLoader.run( prepData );
+				};
+
+				WWOBJLoader2Example.prototype.finalize = function () {
+					this._reportProgress( '' );
+				};
+
+				WWOBJLoader2Example.prototype._reportProgress = function( content, modelName, instanceNo ) {
+					console.log( 'Progress: ' + content );
+					document.getElementById( 'feedback' ).innerHTML = Validator.isValid( content ) ? content : '';
+				};
+
+				WWOBJLoader2Example.prototype.resizeDisplayGL = function () {
+					this.controls.handleResize();
+
+					this.recalcAspectRatio();
+					this.renderer.setSize( this.canvas.offsetWidth, this.canvas.offsetHeight, false );
+
+					this.updateCamera();
+				};
+
+				WWOBJLoader2Example.prototype.recalcAspectRatio = function () {
+					this.aspectRatio = ( this.canvas.offsetHeight === 0 ) ? 1 : this.canvas.offsetWidth / this.canvas.offsetHeight;
+				};
+
+				WWOBJLoader2Example.prototype.resetCamera = function () {
+					this.camera.position.copy( this.cameraDefaults.posCamera );
+					this.cameraTarget.copy( this.cameraDefaults.posCameraTarget );
+
+					this.updateCamera();
+				};
+
+				WWOBJLoader2Example.prototype.updateCamera = function () {
+					this.camera.aspect = this.aspectRatio;
+					this.camera.lookAt( this.cameraTarget );
+					this.camera.updateProjectionMatrix();
+				};
+
+				WWOBJLoader2Example.prototype.render = function () {
+					if ( ! this.renderer.autoClear ) this.renderer.clear();
+
+					this.controls.update();
+
+					this.cube.rotation.x += 0.05;
+					this.cube.rotation.y += 0.05;
+
+					this.renderer.render( this.scene, this.camera );
+				};
+
+				WWOBJLoader2Example.prototype.alterShading = function () {
+					var scope = this;
+					scope.flatShading = ! scope.flatShading;
+					console.log( scope.flatShading ? 'Enabling flat shading' : 'Enabling smooth shading');
+
+					scope.traversalFunction = function ( material ) {
+						material.flatShading = scope.flatShading;
+						material.needsUpdate = true;
+					};
+					var scopeTraverse = function ( object3d ) {
+						scope.traverseScene( object3d );
+					};
+					scope.pivot.traverse( scopeTraverse );
+				};
+
+				WWOBJLoader2Example.prototype.alterDouble = function () {
+					var scope = this;
+					scope.doubleSide = ! scope.doubleSide;
+					console.log( scope.doubleSide ? 'Enabling DoubleSide materials' : 'Enabling FrontSide materials');
+
+					scope.traversalFunction  = function ( material ) {
+						material.side = scope.doubleSide ? THREE.DoubleSide : THREE.FrontSide;
+					};
+
+					var scopeTraverse = function ( object3d ) {
+						scope.traverseScene( object3d );
+					};
+					scope.pivot.traverse( scopeTraverse );
+				};
+
+				WWOBJLoader2Example.prototype.traverseScene = function ( object3d ) {
+					if ( object3d.material instanceof THREE.MultiMaterial ) {
+
+						var materials = object3d.material.materials;
+						for ( var name in materials ) {
+
+							if ( materials.hasOwnProperty( name ) )	this.traversalFunction( materials[ name ] );
+
+						}
+
+					} else if ( object3d.material ) {
+
+						this.traversalFunction( object3d.material );
+
+					}
+				};
+
+				return WWOBJLoader2Example;
+
+			})();
+
+			var app = new WWOBJLoader2Example( document.getElementById( 'example' ) );
+
+			var wwObjLoader2Control = {
+				flatShading: app.flatShading,
+				doubleSide: app.doubleSide
+			};
+
+			var menuDiv = document.getElementById( 'dat' );
+			var gui = new dat.GUI( {
+				autoPlace: false,
+				width: 320
+			} );
+			menuDiv.appendChild( gui.domElement );
+
+			var folderOptions = gui.addFolder( 'WWOBJLoader2 Options' );
+			var controlFlat = folderOptions.add( wwObjLoader2Control, 'flatShading' ).name( 'Flat Shading' );
+			controlFlat.onChange( function( value ) {
+				console.log( 'Setting flatShading to: ' + value );
+				app.alterShading();
+			});
+
+			var controlDouble = folderOptions.add( wwObjLoader2Control, 'doubleSide' ).name( 'Double Side Materials' );
+			controlDouble.onChange( function( value ) {
+				console.log( 'Setting doubleSide to: ' + value );
+				app.alterDouble();
+			});
+			folderOptions.open();
+
+
+			// init three.js example application
+			var resizeWindow = function () {
+				app.resizeDisplayGL();
+			};
+
+			var render = function () {
+				requestAnimationFrame( render );
+				app.render();
+			};
+			window.addEventListener( 'resize', resizeWindow, false );
+
+			console.log( 'Starting initialisation phase...' );
+			app.initGL();
+			app.resizeDisplayGL();
+
+			// kick render loop
+			render();
+
+
+			// 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 OBJLoader.load asynchronously
+			app.useLoadAsync();
+
+			// Load a file with OBJLoader.run synchronously
+			app.useRunSync();
+
+			// Load a file with OBJLoader.run asynchronously and add normals during onMeshAlter
+			app.useRunAsyncMeshAlter();
+
+			app.finalize();
+
+		</script>
+	</body>
+</html>

+ 93 - 109
examples/webgl_loader_obj2_ww_parallels.html → examples/webgl_loader_obj2_run_director.html

@@ -73,7 +73,7 @@
 
 		</div>
 		<div id="info">
-			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - WWOBJLoader2Director Parallels Demo
+			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - Web Worker LoaderDirector Parallels Demo
 		</div>
 		<div id="feedback">
 		</div>
@@ -84,15 +84,15 @@
 		<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 src="js/loaders/WWOBJLoader2.js"></script>
 		<script>
 
 			'use strict';
 
 			var WWParallels = (function () {
 
-				var Validator = THREE.OBJLoader2.prototype._getValidator();
+				var Validator = THREE.LoaderSupport.Validator;
 
 				function WWParallels( elementToBindTo ) {
 					this.renderer = null;
@@ -111,8 +111,8 @@
 					this.camera = null;
 					this.cameraTarget = this.cameraDefaults.posCameraTarget;
 
-					this.wwDirector = new THREE.OBJLoader2.WWOBJLoader2Director();
-					this.wwDirector.setCrossOrigin( 'anonymous' );
+					this.workerDirector = new THREE.LoaderSupport.WorkerDirector( THREE.OBJLoader2 );
+					this.workerDirector.setCrossOrigin( 'anonymous' );
 
 					this.controls = null;
 					this.cube = null;
@@ -126,11 +126,12 @@
 				WWParallels.prototype.initGL = function () {
 					this.renderer = new THREE.WebGLRenderer( {
 						canvas: this.canvas,
-						antialias: true
+						antialias: true,
+						autoClear: true
 					} );
+					this.renderer.setClearColor( 0x050505 );
 
 					this.scene = new THREE.Scene();
-					this.scene.background = new THREE.Color( 0x050505 );
 
 					this.camera = new THREE.PerspectiveCamera( this.cameraDefaults.fov, this.aspectRatio, this.cameraDefaults.near, this.cameraDefaults.far );
 					this.resetCamera();
@@ -204,8 +205,9 @@
 						this.running = true;
 
 					}
+
 					var scope = this;
-					scope.wwDirector.objectsCompleted = 0;
+					scope.workerDirector.objectsCompleted = 0;
 					scope.feedbackArray = [];
 					scope.reportDonwload = [];
 
@@ -218,18 +220,19 @@
 					}
 					scope.reportProgress( scope.feedbackArray.join( '\<br\>' ) );
 
-					var callbackCompletedLoading = function ( modelName, instanceNo ) {
+					var callbackOnLoad = function ( loaderRootNode, modelName, instanceNo ) {
 						scope.reportDonwload[ instanceNo ] = false;
+						scope.allAssets.push( loaderRootNode );
 
-						var msg = 'Worker #' + instanceNo + ': Completed loading: ' + modelName + ' (#' + scope.wwDirector.objectsCompleted + ')';
+						var msg = 'Worker #' + instanceNo + ': Completed loading: ' + modelName + ' (#' + scope.workerDirector.objectsCompleted + ')';
 						console.log( msg );
 						scope.feedbackArray[ instanceNo ] = msg;
 						scope.reportProgress( scope.feedbackArray.join( '\<br\>' ) );
 
-						if ( scope.wwDirector.objectsCompleted + 1 === maxQueueSize ) scope.running = false;
+						if ( scope.workerDirector.objectsCompleted + 1 === maxQueueSize ) scope.running = false;
 					};
 
-					var callbackReportProgress = function ( content, instanceNo ) {
+					var callbackReportProgress = function ( content, modelName, instanceNo ) {
 						if ( scope.reportDonwload[ instanceNo ] ) {
 							var msg = 'Worker #' + instanceNo + ': ' + content;
 							console.log( msg );
@@ -239,83 +242,71 @@
 						}
 					};
 
-					var callbackMeshLoaded = function ( name, bufferGeometry, material ) {
-						var materialOverride;
+					var callbackMeshAlter = function ( name, bufferGeometry, material ) {
+						var override = new THREE.LoaderSupport.LoadedMeshUserOverride( false, false );
 
-						if ( Validator.isValid( material ) && material.name === 'defaultMaterial' || name === 'Mesh_Mesh_head_geo.001' ) {
+						if ( Validator.isValid( material ) && material.name === 'defaultMaterial' || name === 'Mesh_Mesh_head_geo.001_lambert2SG.001' ) {
 
-							materialOverride = material;
+							var materialOverride = material;
 							materialOverride.color = new THREE.Color( Math.random(), Math.random(), Math.random() );
+							var mesh = new THREE.Mesh( bufferGeometry, material );
+							mesh.name = name;
 
-						}
+							override.addMesh( mesh );
+							override.alteredMesh = true;
 
-						return new THREE.OBJLoader2.WWOBJLoader2.LoadedMeshUserOverride( false, undefined, materialOverride );
+						}
+						return override;
 					};
 
-					var globalCallbacks = new THREE.OBJLoader2.WWOBJLoader2.PrepDataCallbacks();
-					globalCallbacks.registerCallbackProgress( callbackReportProgress );
-					globalCallbacks.registerCallbackCompletedLoading( callbackCompletedLoading );
-					globalCallbacks.registerCallbackMeshLoaded( callbackMeshLoaded );
-					this.wwDirector.prepareWorkers( globalCallbacks, maxQueueSize, maxWebWorkers );
-					console.log( 'Configuring WWManager with queue size ' + this.wwDirector.getMaxQueueSize() + ' and ' + this.wwDirector.getMaxWebWorkers() + ' workers.' );
+					var callbacks = new THREE.LoaderSupport.Callbacks();
+					callbacks.setCallbackOnProgress( callbackReportProgress );
+					callbacks.setCallbackOnLoad( callbackOnLoad );
+					callbacks.setCallbackOnMeshAlter( callbackMeshAlter );
 
-					var callbackCompletedLoadingWalt = function () {
-						console.log( 'Callback check: WALT was loaded (#' + scope.wwDirector.objectsCompleted + ')' );
-					};
+					this.workerDirector.prepareWorkers( callbacks, maxQueueSize, maxWebWorkers );
+					console.log( 'Configuring WWManager with queue size ' + this.workerDirector.getMaxQueueSize() + ' and ' + this.workerDirector.getMaxWebWorkers() + ' workers.' );
 
-					var models = [];
-					models.push( {
-						modelName: 'male02',
-						dataAvailable: false,
-						pathObj: 'obj/male02/',
-						fileObj: 'male02.obj',
-						pathTexture: 'obj/male02/',
-						fileMtl: 'male02.mtl'
-					} );
+					var modelPrepDatas = [];
+					prepData = new THREE.LoaderSupport.PrepData( 'male02' );
+					prepData.addResource( new THREE.LoaderSupport.ResourceDescriptor( 'obj/male02/male02.obj', 'OBJ ') );
+					prepData.addResource( new THREE.LoaderSupport.ResourceDescriptor( 'obj/male02/male02.mtl', 'MTL' ) );
+					modelPrepDatas.push( prepData );
 
-					models.push( {
-						modelName: 'female02',
-						dataAvailable: false,
-						pathObj: 'obj/female02/',
-						fileObj: 'female02.obj',
-						pathTexture: 'obj/female02/',
-						fileMtl: 'female02.mtl'
-					} );
+					prepData = new THREE.LoaderSupport.PrepData( 'female02' );
+					prepData.addResource( new THREE.LoaderSupport.ResourceDescriptor( 'obj/female02/female02.obj', 'OBJ' ) );
+					prepData.addResource( new THREE.LoaderSupport.ResourceDescriptor( 'obj/female02/female02.mtl', 'MTL' ) );
+					modelPrepDatas.push( prepData );
 
-					models.push( {
-						modelName: 'viveController',
-						dataAvailable: false,
-						pathObj: 'models/obj/vive-controller/',
-						fileObj: 'vr_controller_vive_1_5.obj',
-						scale: 400.0
-					} );
+					prepData = new THREE.LoaderSupport.PrepData( 'viveController' );
+					prepData.addResource( new THREE.LoaderSupport.ResourceDescriptor( 'models/obj/vive-controller/vr_controller_vive_1_5.obj', 'OBJ' ) );
+					prepData.scale = 400.0;
+					modelPrepDatas.push( prepData );
 
-					models.push( {
-						modelName: 'cerberus',
-						dataAvailable: false,
-						pathObj: 'models/obj/cerberus/',
-						fileObj: 'Cerberus.obj',
-						scale: 50.0
-					} );
-					models.push( {
-						modelName: 'WaltHead',
-						dataAvailable: false,
-						pathObj: 'obj/walt/',
-						fileObj: 'WaltHead.obj',
-						pathTexture: 'obj/walt/',
-						fileMtl: 'WaltHead.mtl'
-					} );
+					prepData = new THREE.LoaderSupport.PrepData( 'cerberus' );
+					prepData.addResource( new THREE.LoaderSupport.ResourceDescriptor( 'models/obj/cerberus/Cerberus.obj', 'OBJ' ) );
+					prepData.scale = 50.0;
+					modelPrepDatas.push( prepData );
+
+					prepData = new THREE.LoaderSupport.PrepData( 'WaltHead' );
+					prepData.addResource( new THREE.LoaderSupport.ResourceDescriptor( 'obj/walt/WaltHead.obj', 'OBJ' ) );
+					prepData.addResource( new THREE.LoaderSupport.ResourceDescriptor( 'obj/walt/WaltHead.mtl', 'MTL' ) );
+					modelPrepDatas.push( prepData );
 
 					var pivot;
 					var distributionBase = -500;
 					var distributionMax = 1000;
-					var modelIndex = 0;
-					var model;
-					var runParams;
+					var modelPrepDataIndex = 0;
+					var modelPrepData;
+					var prepData;
+					var scale;
 					for ( i = 0; i < maxQueueSize; i++ ) {
 
-						modelIndex = Math.floor( Math.random() * models.length );
-						model = models[ modelIndex ];
+						modelPrepDataIndex = Math.floor( Math.random() * modelPrepDatas.length );
+
+						modelPrepData = modelPrepDatas[ modelPrepDataIndex ];
+						scale = Validator.verifyInput( modelPrepData.scale, 0 );
+						modelPrepData = modelPrepData.clone();
 
 						pivot = new THREE.Object3D();
 						pivot.position.set(
@@ -323,38 +314,27 @@
 							distributionBase + distributionMax * Math.random(),
 							distributionBase + distributionMax * Math.random()
 						);
-						if ( Validator.isValid( model.scale ) ) pivot.scale.set( model.scale, model.scale, model.scale );
-
+						if ( scale > 0 ) pivot.scale.set( scale, scale, scale );
 						this.scene.add( pivot );
+						modelPrepData.setStreamMeshesTo( pivot );
+						modelPrepData.setUseAsync( true );
 
-						model.sceneGraphBaseNode = pivot;
-
-						runParams = new THREE.OBJLoader2.WWOBJLoader2.PrepDataFile(
-							model.modelName, model.pathObj, model.fileObj, model.pathTexture, model.fileMtl
-						);
-						runParams.setSceneGraphBaseNode( model.sceneGraphBaseNode );
-						runParams.setStreamMeshes( streamMeshes );
-						if ( model.modelName === 'WaltHead' ) {
-							runParams.getCallbacks().registerCallbackCompletedLoading( callbackCompletedLoadingWalt );
-						}
-
-						this.wwDirector.enqueueForRun( runParams );
-						this.allAssets.push( runParams );
+						this.workerDirector.enqueueForRun( modelPrepData );
 					}
 
-					this.wwDirector.processQueue();
+					this.workerDirector.processQueue();
 				};
 
 				WWParallels.prototype.clearAllAssests = function () {
-					var ref;
-					var scope = this;
-
+					var storedObject3d;
 					for ( var asset in this.allAssets ) {
-						ref = this.allAssets[ asset ];
 
+						storedObject3d = this.allAssets[ asset ];
+						var scope = this;
 						var remover = function ( object3d ) {
 
-							if ( object3d === ref.sceneGraphBaseNode ) return;
+							if ( storedObject3d === object3d ) return;
+
 							console.log( 'Removing ' + object3d.name );
 							scope.scene.remove( object3d );
 
@@ -372,42 +352,46 @@
 									}
 								}
 							}
-							if ( object3d.hasOwnProperty( 'texture' ) ) object3d.texture.dispose();
+							if ( object3d.hasOwnProperty( 'texture' ) )	object3d.texture.dispose();
 						};
-						scope.scene.remove( ref.sceneGraphBaseNode );
-						ref.sceneGraphBaseNode.traverse( remover );
-						ref.sceneGraphBaseNode = null;
+						if ( Validator.isValid( storedObject3d ) ) {
+
+							if ( this.pivot !== storedObject3d ) scope.scene.remove( storedObject3d );
+							storedObject3d.traverse( remover );
+							storedObject3d = null;
+
+						}
 					}
 					this.allAssets = [];
 				};
 
 				WWParallels.prototype.terminateManager = function () {
-					this.wwDirector.deregister();
+					this.workerDirector.deregister();
+					this.running = false;
 				};
 
 				return WWParallels;
 
 			})();
 
+
 			var app = new WWParallels( document.getElementById( 'example' ) );
 
-			var WWParallelsControl = function() {
-				this.queueLength = 128;
-				this.workerCount = 4;
-				this.streamMeshes = true;
-				this.run = function () {
+			var wwParallelsControl = {
+				queueLength: 128,
+				workerCount: 4,
+				streamMeshes: true,
+				run: function () {
 					app.enqueueAllAssests( this.queueLength, this.workerCount, this.streamMeshes );
-				};
-				this.terminate = function () {
+				},
+				terminate: function () {
 					app.terminateManager();
-				};
-				this.clearAllAssests = function () {
+				},
+				clearAllAssests: function () {
 					app.terminateManager();
 					app.clearAllAssests();
-				};
+				}
 			};
-			var wwParallelsControl = new WWParallelsControl();
-
 			var gui = new dat.GUI( {
 				autoPlace: false,
 				width: 320

+ 0 - 502
examples/webgl_loader_obj2_ww.html

@@ -1,502 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<title>three.js webgl - WWOBJLoader2</title>
-		<meta charset="utf-8">
-		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-
-		<style>
-			body {
-				font-family: Monospace;
-				background-color: #000;
-				color: #fff;
-				margin: 0 0 0 0;
-				padding: 0 0 0 0;
-				border: none;
-				cursor: default;
-			}
-			#info {
-				color: #fff;
-				position: absolute;
-				top: 10px;
-				width: 100%;
-				text-align: center;
-				z-index: 100;
-				display:block;
-			}
-			#info a {
-				color: #f00;
-				font-weight: bold;
-				text-decoration: underline;
-				cursor: pointer
-			}
-			#glFullscreen {
-				width: 100%;
-				height: 100vh;
-				min-width: 640px;
-				min-height: 360px;
-				position: relative;
-				overflow: hidden;
-				z-index: 0;
-			}
-			#example {
-				width: 100%;
-				height: 100%;
-				top: 0;
-				left: 0;
-				background-color: #000000;
-			}
-			#feedback {
-				color: darkorange;
-			}
-			#dat {
-				user-select: none;
-				position: absolute;
-				left: 0;
-				top: 0;
-				z-Index: 200;
-			}
-			#fileUploadInput {
-				display: none;
-			}
-		</style>
-
-	</head>
-
-	<body>
-		<div id="glFullscreen">
-			<canvas id="example"></canvas>
-		</div>
-		<div id="dat">
-
-		</div>
-		<div id="info">
-			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - OBJLoader2 direct loader test
-			<div id="feedback"></div>
-		</div>
-		<input id="fileUploadInput" type="file" name="files[]" multiple accept=".obj,.mtl" />
-
-		<script src="js/Detector.js"></script>
-		<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/OBJLoader2.js"></script>
-		<script src="js/loaders/WWOBJLoader2.js"></script>
-		<script>
-
-			'use strict';
-
-			var WWOBJLoader2Example = (function () {
-
-				var Validator = THREE.OBJLoader2.prototype._getValidator();
-
-				function WWOBJLoader2Example( elementToBindTo ) {
-					this.renderer = null;
-					this.canvas = elementToBindTo;
-					this.aspectRatio = 1;
-					this.recalcAspectRatio();
-
-					this.scene = null;
-					this.cameraDefaults = {
-						posCamera: new THREE.Vector3( 0.0, 175.0, 500.0 ),
-						posCameraTarget: new THREE.Vector3( 0, 0, 0 ),
-						near: 0.1,
-						far: 10000,
-						fov: 45
-					};
-					this.camera = null;
-					this.cameraTarget = this.cameraDefaults.posCameraTarget;
-
-					this.controls = null;
-
-					this.flatShading = false;
-					this.doubleSide = false;
-					this.streamMeshes = true;
-
-					this.cube = null;
-					this.pivot = null;
-
-					this.wwObjLoader2 = new THREE.OBJLoader2.WWOBJLoader2();
-					this.wwObjLoader2.setCrossOrigin( 'anonymous' );
-
-					// Check for the various File API support.
-					this.fileApiAvailable = true;
-					if ( window.File && window.FileReader && window.FileList && window.Blob ) {
-
-						console.log( 'File API is supported! Enabling all features.' );
-
-					} else {
-
-						this.fileApiAvailable = false;
-						console.warn( 'File API is not supported! Disabling file loading.' );
-
-					}
-				}
-
-				WWOBJLoader2Example.prototype.initGL = function () {
-					this.renderer = new THREE.WebGLRenderer( {
-						canvas: this.canvas,
-						antialias: true
-					} );
-
-					this.scene = new THREE.Scene();
-					this.scene.background = new THREE.Color( 0x050505 );
-
-					this.camera = new THREE.PerspectiveCamera( this.cameraDefaults.fov, this.aspectRatio, this.cameraDefaults.near, this.cameraDefaults.far );
-					this.resetCamera();
-					this.controls = new THREE.TrackballControls( this.camera, this.renderer.domElement );
-
-					var ambientLight = new THREE.AmbientLight( 0x404040 );
-					var directionalLight1 = new THREE.DirectionalLight( 0xC0C090 );
-					var directionalLight2 = new THREE.DirectionalLight( 0xC0C090 );
-
-					directionalLight1.position.set( -100, -50, 100 );
-					directionalLight2.position.set( 100, 50, -100 );
-
-					this.scene.add( directionalLight1 );
-					this.scene.add( directionalLight2 );
-					this.scene.add( ambientLight );
-
-					var helper = new THREE.GridHelper( 1200, 60, 0xFF4444, 0x404040 );
-					this.scene.add( helper );
-
-					var geometry = new THREE.BoxGeometry( 10, 10, 10 );
-					var material = new THREE.MeshNormalMaterial();
-					this.cube = new THREE.Mesh( geometry, material );
-					this.cube.position.set( 0, 0, 0 );
-					this.scene.add( this.cube );
-
-					this.createPivot();
-				};
-
-				WWOBJLoader2Example.prototype.createPivot = function () {
-					this.pivot = new THREE.Object3D();
-					this.pivot.name = 'Pivot';
-					this.scene.add( this.pivot );
-				};
-
-				WWOBJLoader2Example.prototype.initPostGL = function () {
-					var scope = this;
-					var materialsLoaded = function ( materials ) {
-						var count = Validator.isValid( materials ) ? materials.length : 0;
-						console.log( 'Loaded #' + count + ' materials.' );
-					};
-					var meshLoaded = function ( name, bufferGeometry, material ) {
-						console.log( 'Loaded mesh: ' + name + ' Material name: ' + material.name );
-					};
-					var completedLoading = function () {
-						console.log( 'Loading complete!' );
-						scope._reportProgress( '' );
-					};
-					this.wwObjLoader2.registerCallbackProgress( this._reportProgress );
-					this.wwObjLoader2.registerCallbackCompletedLoading( completedLoading );
-					this.wwObjLoader2.registerCallbackMaterialsLoaded( materialsLoaded );
-					this.wwObjLoader2.registerCallbackMeshLoaded( meshLoaded );
-
-					return true;
-				};
-
-				WWOBJLoader2Example.prototype._reportProgress = function( text ) {
-					console.log( 'Progress: ' + text );
-					document.getElementById( 'feedback' ).innerHTML = Validator.isValid( text ) ? text : '';
-				};
-
-				WWOBJLoader2Example.prototype.loadFiles = function ( prepData ) {
-					prepData.setSceneGraphBaseNode( this.pivot );
-					prepData.setStreamMeshes( this.streamMeshes );
-					this.wwObjLoader2.prepareRun( prepData );
-					this.wwObjLoader2.run();
-				};
-
-				WWOBJLoader2Example.prototype._handleFileSelect = function ( event, pathTexture ) {
-					var fileObj = null;
-					var fileMtl = null;
-					var files = event.target.files;
-
-					for ( var i = 0, file; file = files[ i ]; i++) {
-
-						if ( file.name.indexOf( '\.obj' ) > 0 && fileObj === null ) {
-							fileObj = file;
-						}
-
-						if ( file.name.indexOf( '\.mtl' ) > 0 && fileMtl === null ) {
-							fileMtl = file;
-						}
-
-					}
-
-					if ( ! Validator.isValid( fileObj ) ) {
-						alert( 'Unable to load OBJ file from given files.' );
-					}
-
-					var fileReader = new FileReader();
-					fileReader.onload = function( fileDataObj ) {
-
-						var uint8Array = new Uint8Array( fileDataObj.target.result );
-						if ( fileMtl === null ) {
-
-							app.loadFilesUser({
-								name: 'userObj',
-								objAsArrayBuffer: uint8Array,
-								pathTexture: pathTexture,
-								mtlAsString: null
-							})
-
-						} else {
-
-							fileReader.onload = function( fileDataMtl ) {
-
-								app.loadFilesUser({
-									name: 'userObj',
-									objAsArrayBuffer: uint8Array,
-									pathTexture: pathTexture,
-									mtlAsString: fileDataMtl.target.result
-								})
-							};
-							fileReader.readAsText( fileMtl );
-
-						}
-
-					};
-					fileReader.readAsArrayBuffer( fileObj );
-
-				};
-
-				WWOBJLoader2Example.prototype.loadFilesUser = function ( objDef ) {
-					var prepData = new THREE.OBJLoader2.WWOBJLoader2.PrepDataArrayBuffer(
-						objDef.name, objDef.objAsArrayBuffer, objDef.pathTexture, objDef.mtlAsString
-					);
-					prepData.setSceneGraphBaseNode( this.pivot );
-					prepData.setStreamMeshes( this.streamMeshes );
-					this.wwObjLoader2.prepareRun( prepData );
-					this.wwObjLoader2.run();
-				};
-
-				WWOBJLoader2Example.prototype.resizeDisplayGL = function () {
-					this.controls.handleResize();
-
-					this.recalcAspectRatio();
-					this.renderer.setSize( this.canvas.offsetWidth, this.canvas.offsetHeight, false );
-
-					this.updateCamera();
-				};
-
-				WWOBJLoader2Example.prototype.recalcAspectRatio = function () {
-					this.aspectRatio = ( this.canvas.offsetHeight === 0 ) ? 1 : this.canvas.offsetWidth / this.canvas.offsetHeight;
-				};
-
-				WWOBJLoader2Example.prototype.resetCamera = function () {
-					this.camera.position.copy( this.cameraDefaults.posCamera );
-					this.cameraTarget.copy( this.cameraDefaults.posCameraTarget );
-
-					this.updateCamera();
-				};
-
-				WWOBJLoader2Example.prototype.updateCamera = function () {
-					this.camera.aspect = this.aspectRatio;
-					this.camera.lookAt( this.cameraTarget );
-					this.camera.updateProjectionMatrix();
-				};
-
-				WWOBJLoader2Example.prototype.render = function () {
-					if ( ! this.renderer.autoClear ) this.renderer.clear();
-
-					this.controls.update();
-
-					this.cube.rotation.x += 0.05;
-					this.cube.rotation.y += 0.05;
-
-					this.renderer.render( this.scene, this.camera );
-				};
-
-				WWOBJLoader2Example.prototype.alterShading = function () {
-
-					var scope = this;
-					scope.flatShading = ! scope.flatShading;
-					console.log( scope.flatShading ? 'Enabling flat shading' : 'Enabling smooth shading');
-
-					scope.traversalFunction = function ( material ) {
-						material.flatShading = scope.flatShading;
-						material.needsUpdate = true;
-					};
-					var scopeTraverse = function ( object3d ) {
-						scope.traverseScene( object3d );
-					};
-					scope.pivot.traverse( scopeTraverse );
-				};
-
-				WWOBJLoader2Example.prototype.alterDouble = function () {
-
-					var scope = this;
-					scope.doubleSide = ! scope.doubleSide;
-					console.log( scope.doubleSide ? 'Enabling DoubleSide materials' : 'Enabling FrontSide materials');
-
-					scope.traversalFunction  = function ( material ) {
-						material.side = scope.doubleSide ? THREE.DoubleSide : THREE.FrontSide;
-					};
-
-					var scopeTraverse = function ( object3d ) {
-						scope.traverseScene( object3d );
-					};
-					scope.pivot.traverse( scopeTraverse );
-				};
-
-				WWOBJLoader2Example.prototype.traverseScene = function ( object3d ) {
-
-					if ( object3d.material instanceof THREE.MultiMaterial ) {
-
-						var materials = object3d.material.materials;
-						for ( var name in materials ) {
-
-							if ( materials.hasOwnProperty( name ) )	this.traversalFunction( materials[ name ] );
-
-						}
-
-					} else if ( object3d.material ) {
-
-						this.traversalFunction( object3d.material );
-
-					}
-
-				};
-
-				WWOBJLoader2Example.prototype.clearAllAssests = function () {
-					var scope = this;
-					var remover = function ( object3d ) {
-
-						if ( object3d === scope.pivot ) {
-							return;
-						}
-						console.log( 'Removing: ' + object3d.name );
-						scope.scene.remove( object3d );
-
-						if ( object3d.hasOwnProperty( 'geometry' ) ) {
-							object3d.geometry.dispose();
-						}
-						if ( object3d.hasOwnProperty( 'material' ) ) {
-
-							var mat = object3d.material;
-							if ( mat.hasOwnProperty( 'materials' ) ) {
-
-								var materials = mat.materials;
-								for ( var name in materials ) {
-
-									if ( materials.hasOwnProperty( name ) ) materials[ name ].dispose();
-
-								}
-							}
-						}
-						if ( object3d.hasOwnProperty( 'texture' ) ) {
-							object3d.texture.dispose();
-						}
-					};
-
-					scope.scene.remove( scope.pivot );
-					scope.pivot.traverse( remover );
-					scope.createPivot();
-				};
-
-				return WWOBJLoader2Example;
-
-			})();
-
-			var app = new WWOBJLoader2Example( document.getElementById( 'example' ) );
-
-			// Init dat.gui and controls
-			var elemFileInput = document.getElementById( 'fileUploadInput' );
-			var WWOBJLoader2Control = function() {
-				this.flatShading = app.flatShading;
-				this.doubleSide = app.doubleSide;
-				this.streamMeshes = app.streamMeshes;
-			};
-			var wwObjLoader2Control = new WWOBJLoader2Control();
-
-			var gui = new dat.GUI( {
-				autoPlace: false,
-				width: 320
-			} );
-
-			var menuDiv = document.getElementById( 'dat' );
-			menuDiv.appendChild(gui.domElement);
-			var folderOptions = gui.addFolder( 'WWOBJLoader2 Options' );
-			var controlSmooth = folderOptions.add( wwObjLoader2Control, 'flatShading' ).name( 'Flat Shading' );
-			controlSmooth.onChange( function( value ) {
-				console.log( 'Setting flatShading to: ' + value );
-				app.alterShading();
-			});
-
-			var controlDouble = folderOptions.add( wwObjLoader2Control, 'doubleSide' ).name( 'Double Side Materials' );
-			controlDouble.onChange( function( value ) {
-				console.log( 'Setting doubleSide to: ' + value );
-				app.alterDouble();
-			});
-
-			var controlStreamMeshes = folderOptions.add( wwObjLoader2Control, 'streamMeshes' ).name( 'Stream Meshes' );
-			controlStreamMeshes.onChange( function( value ) {
-				console.log( 'Setting streamMeshes to: ' + value );
-				app.streamMeshes = value;
-			});
-
-			if ( app.fileApiAvailable ) {
-
-				wwObjLoader2Control.pathTexture = 'obj/female02/';
-				var controlPathTexture = folderOptions.add( wwObjLoader2Control, 'pathTexture' ).name( 'Relative path to textures' );
-				controlPathTexture.onChange( function( value ) {
-					console.log( 'Setting pathTexture to: ' + value );
-					app.pathTexture = value + '/';
-				});
-
-				wwObjLoader2Control.loadObjFile = function () {
-					elemFileInput.click();
-				};
-				folderOptions.add( wwObjLoader2Control, 'loadObjFile' ).name( 'Load OBJ/MTL Files' );
-
-				var handleFileSelect = function ( object3d ) {
-					app._handleFileSelect( object3d, wwObjLoader2Control.pathTexture );
-				};
-				elemFileInput.addEventListener( 'change' , handleFileSelect, false );
-
-				wwObjLoader2Control.clearAllAssests = function () {
-					app.clearAllAssests();
-				};
-				folderOptions.add( wwObjLoader2Control, 'clearAllAssests' ).name( 'Clear Scene' );
-
-			}
-			folderOptions.open();
-
-
-
-			// init three.js example application
-			var resizeWindow = function () {
-				app.resizeDisplayGL();
-			};
-
-			var render = function () {
-				requestAnimationFrame( render );
-				app.render();
-			};
-
-			window.addEventListener( 'resize', resizeWindow, false );
-
-			console.log( 'Starting initialisation phase...' );
-			app.initGL();
-			app.resizeDisplayGL();
-			app.initPostGL();
-
-			var prepData = new THREE.OBJLoader2.WWOBJLoader2.PrepDataFile(
-				'male02',
-				'obj/male02/',
-				'male02.obj',
-				'obj/male02/',
-				'male02.mtl'
-			);
-			app.loadFiles( prepData );
-
-			// kick render loop
-			render();
-
-		</script>
-	</body>
-</html>

+ 1 - 1
examples/webgl_loader_prwm.html

@@ -69,7 +69,7 @@
 			download the most appropriate file.<br><br>
 			This platform endianness is <strong id="endianness"></strong>.<br><br>
 			See your console for stats.<br><br>
-			<a href="https://github.com/kchapelier/PRWM" target="_blank">Specifications and implementations</a>
+			<a href="https://github.com/kchapelier/PRWM" target="_blank" rel="noopener noreferrer">Specifications and implementations</a>
 		</div>
 
 		<script src="../build/three.js"></script>

+ 4 - 2
examples/webgl_mirror.html

@@ -92,7 +92,8 @@
 					clipBias: 0.003,
 					textureWidth: WIDTH * window.devicePixelRatio,
 					textureHeight: HEIGHT * window.devicePixelRatio,
-					color: 0x777777
+					color: 0x777777,
+					recursion: 1
 				} );
 				groundMirror.rotateX( - Math.PI / 2 );
 				scene.add( groundMirror );
@@ -101,7 +102,8 @@
 					clipBias: 0.003,
 					textureWidth: WIDTH * window.devicePixelRatio,
 					textureHeight: HEIGHT * window.devicePixelRatio,
-					color: 0x889999
+					color: 0x889999,
+					recursion: 1
 				} );
 				verticalMirror.position.y = 35;
 				verticalMirror.position.z = -45;

+ 1 - 1
examples/webgl_postprocessing_sao.html

@@ -50,7 +50,7 @@
 		<script src='js/libs/dat.gui.min.js'></script>
 
 		<div id="info">
-			<a href="http://threejs.org" target="_blank">three.js</a> - Scalable Ambient Occlusion (SAO) shader by <a href="http://clara.io">Ben Houston</a> / Post-processing pass by <a href="http://ludobaka.github.io">Ludobaka</a>
+			<a href="http://threejs.org" target="_blank" rel="noopener noreferrer">three.js</a> - Scalable Ambient Occlusion (SAO) shader by <a href="http://clara.io">Ben Houston</a> / Post-processing pass by <a href="http://ludobaka.github.io">Ludobaka</a>
 		</div>
 
 		<script>

+ 1 - 1
examples/webgl_postprocessing_sobel.html

@@ -45,7 +45,7 @@
 		<script src="js/postprocessing/ShaderPass.js"></script>
 
 		<div id="info">
-			<a href="https://threejs.org" target="_blank">three.js</a> - webgl - postprocessing - sobel (edge detection)
+			<a href="https://threejs.org" target="_blank" rel="noopener noreferrer">three.js</a> - webgl - postprocessing - sobel (edge detection)
 		</div>
 
 		<script>

+ 16 - 38
examples/webgl_postprocessing_ssao.html

@@ -48,6 +48,7 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info
 		<script src="js/postprocessing/RenderPass.js"></script>
 		<script src="js/postprocessing/ShaderPass.js"></script>
 		<script src="js/postprocessing/MaskPass.js"></script>
+		<script src="js/postprocessing/SSAOPass.js"></script>
 
 		<script src="js/Detector.js"></script>
 		<script src="js/libs/stats.min.js"></script>
@@ -64,10 +65,11 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info
 
 			var container, stats;
 			var camera, scene, renderer;
-			var depthMaterial, effectComposer, depthRenderTarget;
+			var effectComposer;
 			var ssaoPass;
 			var group;
-			var postprocessing = { enabled: true, ao_only: false, radius: 32 };
+
+			var postprocessing = { enabled: true, onlyAO: false, radius: 32, aoClamp: 0.25, lumInfluence: 0.7 };
 
 			init();
 			animate();
@@ -119,25 +121,23 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info
 
 				// Init gui
 				var gui = new dat.GUI();
-				gui.add( postprocessing, "enabled" );
-				gui.add( postprocessing, "ao_only", false ).onChange( renderModeChange );
-				gui.add( postprocessing, "radius" ).min( 0 ).max( 64 ).onChange( radiusChange );
+				gui.add( postprocessing, 'enabled' );
 
-				window.addEventListener( 'resize', onWindowResize, false );
+				gui.add( postprocessing, 'onlyAO', false ).onChange( function( value ) { ssaoPass.onlyAO = value; } );
 
-			}
+				gui.add( postprocessing, 'radius' ).min( 0 ).max( 64 ).onChange( function( value ) { ssaoPass.radius = value; } );
+				
+				gui.add( postprocessing, 'aoClamp' ).min( 0 ).max( 1 ).onChange( function( value ) { ssaoPass.aoClamp = value; } );
+				
+				gui.add( postprocessing, 'lumInfluence' ).min( 0 ).max( 1 ).onChange( function( value ) { ssaoPass.lumInfluence = value; } );
+				
 
-			function radiusChange( value ) {
+				window.addEventListener( 'resize', onWindowResize, false );
 
-				ssaoPass.uniforms[ 'radius' ].value = value;
+				onWindowResize();
 
 			}
 
-			function renderModeChange( value ) {
-
-				ssaoPass.uniforms[ 'onlyAO' ].value = value;
-
-			}
 
 			function onWindowResize() {
 
@@ -149,14 +149,12 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info
 				renderer.setSize( width, height );
 
 				// Resize renderTargets
-				ssaoPass.uniforms[ 'size' ].value.set( width, height );
+				ssaoPass.setSize( width, height );
 
 				var pixelRatio = renderer.getPixelRatio();
 				var newWidth  = Math.floor( width / pixelRatio ) || 1;
 				var newHeight = Math.floor( height / pixelRatio ) || 1;
-				depthRenderTarget.setSize( newWidth, newHeight );
 				effectComposer.setSize( newWidth, newHeight );
-
 			}
 
 			function initPostprocessing() {
@@ -164,23 +162,9 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info
 				// Setup render pass
 				var renderPass = new THREE.RenderPass( scene, camera );
 
-				// Setup depth pass
-				depthMaterial = new THREE.MeshDepthMaterial();
-				depthMaterial.depthPacking = THREE.RGBADepthPacking;
-				depthMaterial.blending = THREE.NoBlending;
-
-				var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter };
-				depthRenderTarget = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, pars );
-				depthRenderTarget.texture.name = "SSAOShader.rt";
-
 				// Setup SSAO pass
-				ssaoPass = new THREE.ShaderPass( THREE.SSAOShader );
+				ssaoPass = new THREE.SSAOPass( scene, camera );
 				ssaoPass.renderToScreen = true;
-				//ssaoPass.uniforms[ "tDiffuse" ].value will be set by ShaderPass
-				ssaoPass.uniforms[ "tDepth" ].value = depthRenderTarget.texture;
-				ssaoPass.uniforms[ 'size' ].value.set( window.innerWidth, window.innerHeight );
-				ssaoPass.uniforms[ 'cameraNear' ].value = camera.near;
-				ssaoPass.uniforms[ 'cameraFar' ].value = camera.far;
 
 				// Add pass to effect composer
 				effectComposer = new THREE.EffectComposer( renderer );
@@ -207,12 +191,6 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info
 
 				if ( postprocessing.enabled ) {
 
-					// Render depth into depthRenderTarget
-					scene.overrideMaterial = depthMaterial;
-					renderer.render( scene, camera, depthRenderTarget, true );
-
-					// Render renderPass and SSAO shaderPass
-					scene.overrideMaterial = null;
 					effectComposer.render();
 
 				} else {

+ 48 - 32
examples/webgl_postprocessing_unreal_bloom.html

@@ -70,7 +70,7 @@
 			var params = {
 				projection: 'normal',
 				background: false,
-				exposure: 1.0,
+				exposure: 0.9,
 				bloomStrength: 1.5,
 				bloomThreshold: 0.85,
 				bloomRadius: 0.4
@@ -114,7 +114,8 @@
 				objects.push( torusMesh1 );
 
 				var textureLoader = new THREE.TextureLoader();
-				textureLoader.load( "./textures/roughness_map.jpg", function( map ) {
+				textureLoader.load( './textures/roughness_map.jpg', function ( map ) {
+
 					map.wrapS = THREE.RepeatWrapping;
 					map.wrapT = THREE.RepeatWrapping;
 					map.anisotropy = 4;
@@ -122,17 +123,20 @@
 					standardMaterial.roughnessMap = map;
 					standardMaterial.bumpMap = map;
 					standardMaterial.needsUpdate = true;
+
 				} );
 
-				var genCubeUrls = function( prefix, postfix ) {
+				var genCubeUrls = function ( prefix, postfix ) {
+
 					return [
 						prefix + 'px' + postfix, prefix + 'nx' + postfix,
 						prefix + 'py' + postfix, prefix + 'ny' + postfix,
 						prefix + 'pz' + postfix, prefix + 'nz' + postfix
 					];
+
 				};
 
-				var hdrUrls = genCubeUrls( "./textures/cube/pisaHDR/", ".hdr" );
+				var hdrUrls = genCubeUrls( './textures/cube/pisaHDR/', '.hdr' );
 				new THREE.HDRCubeTextureLoader().load( THREE.UnsignedByteType, hdrUrls, function ( hdrCubeMap ) {
 
 					var pmremGenerator = new THREE.PMREMGenerator( hdrCubeMap );
@@ -144,11 +148,12 @@
 					hdrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
 
 				} );
+
 				// Lights
 
-				scene.add( new THREE.AmbientLight( 0x222222 ) );
+				scene.add( new THREE.AmbientLight( 0xffffff, 0.1 ) );
 
-				var spotLight = new THREE.SpotLight( 0xffffff );
+				var spotLight = new THREE.SpotLight( 0xffffff, 1 );
 				spotLight.position.set( 50, 100, 50 );
 				spotLight.angle = Math.PI / 7;
 				spotLight.penumbra = 0.8;
@@ -160,23 +165,20 @@
 				renderer.shadowMap.enabled = true;
 				container.appendChild( renderer.domElement );
 
-				renderScene = new THREE.RenderPass(scene, camera);
+				renderScene = new THREE.RenderPass( scene, camera );
+
+				effectFXAA = new THREE.ShaderPass( THREE.FXAAShader );
+				effectFXAA.uniforms[ 'resolution' ].value.set( 1 / window.innerWidth, 1 / window.innerHeight );
 
-		    // renderScene.clear = true;
-		    effectFXAA = new THREE.ShaderPass(THREE.FXAAShader);
-		    effectFXAA.uniforms['resolution'].value.set(1 / window.innerWidth, 1 / window.innerHeight );
+				bloomPass = new THREE.UnrealBloomPass( new THREE.Vector2( window.innerWidth, window.innerHeight ), 1.5, 0.4, 0.85 ); //1.0, 9, 0.5, 512);
+				bloomPass.renderToScreen = true;
 
-				var copyShader = new THREE.ShaderPass(THREE.CopyShader);
-				copyShader.renderToScreen = true;
+				composer = new THREE.EffectComposer( renderer );
+				composer.setSize( window.innerWidth, window.innerHeight );
+				composer.addPass( renderScene );
+				composer.addPass( effectFXAA );
+				composer.addPass( bloomPass );
 
-		    bloomPass = new THREE.UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight), 1.5, 0.4, 0.85);//1.0, 9, 0.5, 512);
-				composer = new THREE.EffectComposer(renderer);
-		    composer.setSize(window.innerWidth, window.innerHeight);
-		    composer.addPass(renderScene);
-				composer.addPass(effectFXAA);
-		    composer.addPass(bloomPass);
-				composer.addPass(copyShader);
-				//renderer.toneMapping = THREE.ReinhardToneMapping;
 				renderer.gammaInput = true;
 				renderer.gammaOutput = true;
 
@@ -184,21 +186,33 @@
 				container.appendChild( stats.dom );
 
 				controls = new THREE.OrbitControls( camera, renderer.domElement );
+				controls.minDistance = 50;
+				controls.maxDistance = 200;
 
 				window.addEventListener( 'resize', onWindowResize, false );
 
 				var gui = new dat.GUI();
 
 				gui.add( params, 'exposure', 0.1, 2 );
-				gui.add( params, 'bloomThreshold', 0.0, 1.0 ).onChange( function(value) {
-		        bloomPass.threshold = Number(value);
-		    });
-				gui.add( params, 'bloomStrength', 0.0, 3.0 ).onChange( function(value) {
-		        bloomPass.strength = Number(value);
-		    });
-				gui.add( params, 'bloomRadius', 0.0, 1.0 ).onChange( function(value) {
-		        bloomPass.radius = Number(value);
-		    });
+
+				gui.add( params, 'bloomThreshold', 0.0, 1.0 ).onChange( function ( value ) {
+
+					bloomPass.threshold = Number( value );
+
+				} );
+
+				gui.add( params, 'bloomStrength', 0.0, 3.0 ).onChange( function ( value ) {
+
+					bloomPass.strength = Number( value );
+
+				} );
+
+				gui.add( params, 'bloomRadius', 0.0, 1.0 ).onChange( function ( value ) {
+
+					bloomPass.radius = Number( value );
+
+				} );
+
 				gui.open();
 
 			}
@@ -213,7 +227,8 @@
 
 				renderer.setSize( width, height );
 				composer.setSize( width, height );
-				effectFXAA.uniforms['resolution'].value.set(1 / window.innerWidth, 1 / window.innerHeight );
+				effectFXAA.uniforms[ 'resolution' ].value.set( 1 / window.innerWidth, 1 / window.innerHeight );
+
 			}
 
 			//
@@ -233,7 +248,7 @@
 				if ( standardMaterial !== undefined ) {
 
 					standardMaterial.roughness = 1.0;
-					standardMaterial.bumpScale = - 0.05;
+					standardMaterial.bumpScale = 0.25;
 
 					var newEnvMap = standardMaterial.envMap;
 
@@ -242,6 +257,7 @@
 					if ( newEnvMap !== standardMaterial.envMap ) {
 
 						standardMaterial.envMap = newEnvMap;
+						standardMaterial.envMapIntensity = 1;
 						standardMaterial.needsUpdate = true;
 
 					}
@@ -261,8 +277,8 @@
 
 				}
 
-				// renderer.render( scene, camera );
 				composer.render();
+
 			}
 
 		</script>

+ 36 - 46
examples/webgl_shader.html

@@ -28,7 +28,6 @@
 				color: #ffffff;
 			}
 
-			#oldie a { color:#da0 }
 		</style>
 	</head>
 	<body>
@@ -39,12 +38,15 @@
 		<script src="../build/three.js"></script>
 
 		<script src="js/Detector.js"></script>
-		<script src="js/libs/stats.min.js"></script>
 
 		<script id="vertexShader" type="x-shader/x-vertex">
 
+			varying vec2 vUv;
+
 			void main()	{
 
+				vUv = uv;
+
 				gl_Position = vec4( position, 1.0 );
 
 			}
@@ -53,34 +55,37 @@
 
 		<script id="fragmentShader" type="x-shader/x-fragment">
 
-			uniform vec2 resolution;
+			varying vec2 vUv;
+
 			uniform float time;
 
 			void main()	{
 
-				vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
-				float a = time*40.0;
-				float d,e,f,g=1.0/40.0,h,i,r,q;
-				e=400.0*(p.x*0.5+0.5);
-				f=400.0*(p.y*0.5+0.5);
-				i=200.0+sin(e*g+a/150.0)*20.0;
-				d=200.0+cos(f*g/2.0)*18.0+cos(e*g)*7.0;
-				r=sqrt(pow(abs(i-e),2.0)+pow(abs(d-f),2.0));
-				q=f/r;
-				e=(r*cos(q))-a/2.0;f=(r*sin(q))-a/2.0;
-				d=sin(e*g)*176.0+sin(e*g)*164.0+r;
-				h=((f+d)+a/2.0)*g;
-				i=cos(h+r*p.x/1.3)*(e+e+a)+cos(q*g*6.0)*(r+h/3.0);
-				h=sin(f*g)*144.0-sin(e*g)*212.0*p.x;
-				h=(h+(f-e)*q+sin(r-(a+h)/7.0)*10.0+i/4.0)*g;
-				i+=cos(h*2.3*sin(a/350.0-q))*184.0*sin(q-(r*4.3+a/12.0)*g)+tan(r*g+h)*184.0*cos(r*g+h);
-				i=mod(i/5.6,256.0)/64.0;
-				if(i<0.0) i+=4.0;
-				if(i>=2.0) i=4.0-i;
-				d=r/350.0;
-				d+=sin(d*d*8.0)*0.52;
-				f=(sin(a*g)+1.0)/2.0;
-				gl_FragColor=vec4(vec3(f*i/1.6,i/2.0+d/13.0,i)*d*p.x+vec3(i/1.3+d/8.0,i/2.0+d/18.0,i)*d*(1.0-p.x),1.0);
+				vec2 p = - 1.0 + 2.0 * vUv;
+				float a = time * 40.0;
+				float d, e, f, g = 1.0 / 40.0 ,h ,i ,r ,q;
+
+				e = 400.0 * ( p.x * 0.5 + 0.5 );
+				f = 400.0 * ( p.y * 0.5 + 0.5 );
+				i = 200.0 + sin( e * g + a / 150.0 ) * 20.0;
+				d = 200.0 + cos( f * g / 2.0 ) * 18.0 + cos( e * g ) * 7.0;
+				r = sqrt( pow( abs( i - e ), 2.0 ) + pow( abs( d - f ), 2.0 ) );
+				q = f / r;
+				e = ( r * cos( q ) ) - a / 2.0;
+				f = ( r * sin( q ) ) - a / 2.0;
+				d = sin( e * g ) * 176.0 + sin( e * g ) * 164.0 + r;
+				h = ( ( f + d ) + a / 2.0 ) * g;
+				i = cos( h + r * p.x / 1.3 ) * ( e + e + a ) + cos( q * g * 6.0 ) * ( r + h / 3.0 );
+				h = sin( f * g ) * 144.0 - sin( e * g ) * 212.0 * p.x;
+				h = ( h + ( f - e ) * q + sin( r - ( a + h ) / 7.0 ) * 10.0 + i / 4.0 ) * g;
+				i += cos( h * 2.3 * sin( a / 350.0 - q ) ) * 184.0 * sin( q - ( r * 4.3 + a / 12.0 ) * g ) + tan( r * g + h ) * 184.0 * cos( r * g + h );
+				i = mod( i / 5.6, 256.0 ) / 64.0;
+				if ( i < 0.0 ) i += 4.0;
+				if ( i >= 2.0 ) i = 4.0 - i;
+				d = r / 350.0;
+				d += sin( d * d * 8.0 ) * 0.52;
+				f = ( sin( a * g ) + 1.0 ) / 2.0;
+				gl_FragColor = vec4( vec3( f * i / 1.6, i / 2.0 + d / 13.0, i ) * d * p.x + vec3( i / 1.3 + d / 8.0, i / 2.0 + d / 18.0, i ) * d * ( 1.0 - p.x ), 1.0 );
 
 			}
 
@@ -90,7 +95,7 @@
 
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 
-			var container, stats;
+			var container;
 
 			var camera, scene, renderer;
 
@@ -103,16 +108,14 @@
 
 				container = document.getElementById( 'container' );
 
-				camera = new THREE.Camera();
-				camera.position.z = 1;
+				camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
 
 				scene = new THREE.Scene();
 
 				var geometry = new THREE.PlaneBufferGeometry( 2, 2 );
 
 				uniforms = {
-					time:       { value: 1.0 },
-					resolution: { value: new THREE.Vector2() }
+					time: { value: 1.0 }
 				};
 
 				var material = new THREE.ShaderMaterial( {
@@ -130,9 +133,6 @@
 				renderer.setPixelRatio( window.devicePixelRatio );
 				container.appendChild( renderer.domElement );
 
-				stats = new Stats();
-				container.appendChild( stats.dom );
-
 				onWindowResize();
 
 				window.addEventListener( 'resize', onWindowResize, false );
@@ -143,25 +143,15 @@
 
 				renderer.setSize( window.innerWidth, window.innerHeight );
 
-				uniforms.resolution.value.x = renderer.domElement.width;
-				uniforms.resolution.value.y = renderer.domElement.height;
-
 			}
 
 			//
 
-			function animate() {
+			function animate( timestamp ) {
 
 				requestAnimationFrame( animate );
 
-				render();
-				stats.update();
-
-			}
-
-			function render() {
-
-				uniforms.time.value += 0.05;
+				uniforms.time.value = timestamp / 1000;
 
 				renderer.render( scene, camera );
 

+ 36 - 49
examples/webgl_shader2.html

@@ -28,7 +28,6 @@
 				color: #ffffff;
 			}
 
-			#oldie a { color:#da0 }
 		</style>
 	</head>
 	<body>
@@ -44,13 +43,12 @@
 		<script id="fragment_shader4" type="x-shader/x-fragment">
 
 			uniform float time;
-			uniform vec2 resolution;
 
 			varying vec2 vUv;
 
 			void main( void ) {
 
-				vec2 position = -1.0 + 2.0 * vUv;
+				vec2 position = - 1.0 + 2.0 * vUv;
 
 				float red = abs( sin( position.x * position.y + time / 5.0 ) );
 				float green = abs( sin( position.x * position.y + time / 4.0 ) );
@@ -64,7 +62,6 @@
 		<script id="fragment_shader3" type="x-shader/x-fragment">
 
 			uniform float time;
-			uniform vec2 resolution;
 
 			varying vec2 vUv;
 
@@ -87,7 +84,6 @@
 		<script id="fragment_shader2" type="x-shader/x-fragment">
 
 			uniform float time;
-			uniform vec2 resolution;
 
 			uniform sampler2D texture;
 
@@ -95,7 +91,7 @@
 
 			void main( void ) {
 
-				vec2 position = -1.0 + 2.0 * vUv;
+				vec2 position = - 1.0 + 2.0 * vUv;
 
 				float a = atan( position.y, position.x );
 				float r = sqrt( dot( position, position ) );
@@ -115,38 +111,37 @@
 
 		<script id="fragment_shader1" type="x-shader/x-fragment">
 
-			uniform vec2 resolution;
 			uniform float time;
 
 			varying vec2 vUv;
 
-			void main(void)
-			{
-
-				vec2 p = -1.0 + 2.0 * vUv;
-				float a = time*40.0;
-				float d,e,f,g=1.0/40.0,h,i,r,q;
-
-				e=400.0*(p.x*0.5+0.5);
-				f=400.0*(p.y*0.5+0.5);
-				i=200.0+sin(e*g+a/150.0)*20.0;
-				d=200.0+cos(f*g/2.0)*18.0+cos(e*g)*7.0;
-				r=sqrt(pow(i-e,2.0)+pow(d-f,2.0));
-				q=f/r;
-				e=(r*cos(q))-a/2.0;f=(r*sin(q))-a/2.0;
-				d=sin(e*g)*176.0+sin(e*g)*164.0+r;
-				h=((f+d)+a/2.0)*g;
-				i=cos(h+r*p.x/1.3)*(e+e+a)+cos(q*g*6.0)*(r+h/3.0);
-				h=sin(f*g)*144.0-sin(e*g)*212.0*p.x;
-				h=(h+(f-e)*q+sin(r-(a+h)/7.0)*10.0+i/4.0)*g;
-				i+=cos(h*2.3*sin(a/350.0-q))*184.0*sin(q-(r*4.3+a/12.0)*g)+tan(r*g+h)*184.0*cos(r*g+h);
-				i=mod(i/5.6,256.0)/64.0;
-				if(i<0.0) i+=4.0;
-				if(i>=2.0) i=4.0-i;
-				d=r/350.0;
-				d+=sin(d*d*8.0)*0.52;
-				f=(sin(a*g)+1.0)/2.0;
-				gl_FragColor=vec4(vec3(f*i/1.6,i/2.0+d/13.0,i)*d*p.x+vec3(i/1.3+d/8.0,i/2.0+d/18.0,i)*d*(1.0-p.x),1.0);
+			void main(void) {
+
+				vec2 p = - 1.0 + 2.0 * vUv;
+				float a = time * 40.0;
+				float d, e, f, g = 1.0 / 40.0 ,h ,i ,r ,q;
+
+				e = 400.0 * ( p.x * 0.5 + 0.5 );
+				f = 400.0 * ( p.y * 0.5 + 0.5 );
+				i = 200.0 + sin( e * g + a / 150.0 ) * 20.0;
+				d = 200.0 + cos( f * g / 2.0 ) * 18.0 + cos( e * g ) * 7.0;
+				r = sqrt( pow( abs( i - e ), 2.0 ) + pow( abs( d - f ), 2.0 ) );
+				q = f / r;
+				e = ( r * cos( q ) ) - a / 2.0;
+				f = ( r * sin( q ) ) - a / 2.0;
+				d = sin( e * g ) * 176.0 + sin( e * g ) * 164.0 + r;
+				h = ( ( f + d ) + a / 2.0 ) * g;
+				i = cos( h + r * p.x / 1.3 ) * ( e + e + a ) + cos( q * g * 6.0 ) * ( r + h / 3.0 );
+				h = sin( f * g ) * 144.0 - sin( e * g ) * 212.0 * p.x;
+				h = ( h + ( f - e ) * q + sin( r - ( a + h ) / 7.0 ) * 10.0 + i / 4.0 ) * g;
+				i += cos( h * 2.3 * sin( a / 350.0 - q ) ) * 184.0 * sin( q - ( r * 4.3 + a / 12.0 ) * g ) + tan( r * g + h ) * 184.0 * cos( r * g + h );
+				i = mod( i / 5.6, 256.0 ) / 64.0;
+				if ( i < 0.0 ) i += 4.0;
+				if ( i >= 2.0 ) i = 4.0 - i;
+				d = r / 350.0;
+				d += sin( d * d * 8.0 ) * 0.52;
+				f = ( sin( a * g ) + 1.0 ) / 2.0;
+				gl_FragColor = vec4( vec3( f * i / 1.6, i / 2.0 + d / 13.0, i ) * d * p.x + vec3( i / 1.3 + d / 8.0, i / 2.0 + d / 18.0, i ) * d * ( 1.0 - p.x ), 1.0 );
 
 			}
 
@@ -171,12 +166,10 @@
 
 			var container, stats;
 
-			var camera, scene, renderer;
+			var camera, scene, renderer, clock;
 
 			var uniforms1, uniforms2;
 
-			var clock = new THREE.Clock();
-
 			init();
 			animate();
 
@@ -189,17 +182,17 @@
 
 				scene = new THREE.Scene();
 
-				var geometry = new THREE.BoxGeometry( 0.75, 0.75, 0.75 );
+				clock = new THREE.Clock();
+
+				var geometry = new THREE.BoxBufferGeometry( 0.75, 0.75, 0.75 );
 
 				uniforms1 = {
-					time:       { value: 1.0 },
-					resolution: { value: new THREE.Vector2() }
+					time: { value: 1.0 }
 				};
 
 				uniforms2 = {
-					time:       { value: 1.0 },
-					resolution: { value: new THREE.Vector2() },
-					texture:    { value: new THREE.TextureLoader().load( "textures/disturb.jpg" ) }
+					time: { value: 1.0 },
+					texture: { value: new THREE.TextureLoader().load( 'textures/disturb.jpg' ) }
 				};
 
 				uniforms2.texture.value.wrapS = uniforms2.texture.value.wrapT = THREE.RepeatWrapping;
@@ -243,12 +236,6 @@
 
 			function onWindowResize( event ) {
 
-				uniforms1.resolution.value.x = window.innerWidth;
-				uniforms1.resolution.value.y = window.innerHeight;
-
-				uniforms2.resolution.value.x = window.innerWidth;
-				uniforms2.resolution.value.y = window.innerHeight;
-
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.updateProjectionMatrix();
 

+ 19 - 39
examples/webgl_shader_lava.html

@@ -50,12 +50,10 @@
 		<script src="js/postprocessing/FilmPass.js"></script>
 
 		<script src="js/Detector.js"></script>
-		<script src="js/libs/stats.min.js"></script>
 
 		<script id="fragmentShader" type="x-shader/x-fragment">
 
 			uniform float time;
-			uniform vec2 resolution;
 
 			uniform float fogDensity;
 			uniform vec3 fogColor;
@@ -67,11 +65,11 @@
 
 			void main( void ) {
 
-				vec2 position = -1.0 + 2.0 * vUv;
+				vec2 position = - 1.0 + 2.0 * vUv;
 
 				vec4 noise = texture2D( texture1, vUv );
-				vec2 T1 = vUv + vec2( 1.5, -1.5 ) * time  *0.02;
-				vec2 T2 = vUv + vec2( -0.5, 2.0 ) * time * 0.01;
+				vec2 T1 = vUv + vec2( 1.5, - 1.5 ) * time * 0.02;
+				vec2 T2 = vUv + vec2( - 0.5, 2.0 ) * time * 0.01;
 
 				T1.x += noise.x * 2.0;
 				T1.y += noise.y * 2.0;
@@ -83,9 +81,9 @@
 				vec4 color = texture2D( texture2, T2 * 2.0 );
 				vec4 temp = color * ( vec4( p, p, p, p ) * 2.0 ) + ( color * color - 0.1 );
 
-				if( temp.r > 1.0 ){ temp.bg += clamp( temp.r - 2.0, 0.0, 100.0 ); }
-				if( temp.g > 1.0 ){ temp.rb += temp.g - 1.0; }
-				if( temp.b > 1.0 ){ temp.rg += temp.b - 1.0; }
+				if( temp.r > 1.0 ) { temp.bg += clamp( temp.r - 2.0, 0.0, 100.0 ); }
+				if( temp.g > 1.0 ) { temp.rb += temp.g - 1.0; }
+				if( temp.b > 1.0 ) { temp.rg += temp.b - 1.0; }
 
 				gl_FragColor = temp;
 
@@ -120,22 +118,11 @@
 
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 
-			var container, stats;
+			var container;
 
-			var clock = new THREE.Clock();
+			var camera, scene, renderer, composer, clock;
 
-			var camera, scene, renderer, composer;
-
-			var uniforms, material, mesh;
-
-			var mouseX = 0, mouseY = 0,
-			lat = 0, lon = 0, phy = 0, theta = 0;
-
-			var width = window.innerWidth || 2;
-			var height = window.innerHeight || 2;
-
-			var windowHalfX = width / 2;
-			var windowHalfY = height / 2;
+			var uniforms, mesh;
 
 			init();
 			animate();
@@ -144,22 +131,23 @@
 
 				container = document.getElementById( 'container' );
 
-				camera = new THREE.PerspectiveCamera( 35, windowHalfX / windowHalfY, 1, 3000 );
+				camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 3000 );
 				camera.position.z = 4;
 
 				scene = new THREE.Scene();
 
+				clock = new THREE.Clock();
+
 				var textureLoader = new THREE.TextureLoader();
 
 				uniforms = {
 
 					fogDensity: { value: 0.45 },
-					fogColor:   { value: new THREE.Vector3( 0, 0, 0 ) },
-					time:       { value: 1.0 },
-					resolution: { value: new THREE.Vector2() },
-					uvScale:    { value: new THREE.Vector2( 3.0, 1.0 ) },
-					texture1:   { value: textureLoader.load( "textures/lava/cloud.png" ) },
-					texture2:   { value: textureLoader.load( "textures/lava/lavatile.jpg" ) }
+					fogColor: { value: new THREE.Vector3( 0, 0, 0 ) },
+					time: { value: 1.0 },
+					uvScale: { value: new THREE.Vector2( 3.0, 1.0 ) },
+					texture1: { value: textureLoader.load( 'textures/lava/cloud.png' ) },
+					texture2: { value: textureLoader.load( 'textures/lava/lavatile.jpg' ) }
 
 				};
 
@@ -168,7 +156,7 @@
 
 				var size = 0.65;
 
-				material = new THREE.ShaderMaterial( {
+				var material = new THREE.ShaderMaterial( {
 
 					uniforms: uniforms,
 					vertexShader: document.getElementById( 'vertexShader' ).textContent,
@@ -176,7 +164,7 @@
 
 				} );
 
-				mesh = new THREE.Mesh( new THREE.TorusGeometry( size, 0.3, 30, 30 ), material );
+				mesh = new THREE.Mesh( new THREE.TorusBufferGeometry( size, 0.3, 30, 30 ), material );
 				mesh.rotation.x = 0.3;
 				scene.add( mesh );
 
@@ -187,10 +175,6 @@
 				container.appendChild( renderer.domElement );
 				renderer.autoClear = false;
 
-				//
-
-				stats = new Stats();
-				//container.appendChild( stats.dom );
 
 				//
 
@@ -216,9 +200,6 @@
 
 			function onWindowResize( event ) {
 
-				uniforms.resolution.value.x = window.innerWidth;
-				uniforms.resolution.value.y = window.innerHeight;
-
 				renderer.setSize( window.innerWidth, window.innerHeight );
 
 				camera.aspect = window.innerWidth / window.innerHeight;
@@ -235,7 +216,6 @@
 				requestAnimationFrame( animate );
 
 				render();
-				stats.update();
 
 			}
 

+ 20 - 2
examples/webvr_cubes.html

@@ -4,8 +4,8 @@
 		<title>three.js webvr - cubes</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-09-03 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-09-03" content="Aqj+6XPnxHoSxQj/CDjGXhzrVFeP12/Pgvj7rfqFqVzodYX0ZXJNHTJIvCVExQfvip+Zq9GES+SOQ/zJlpceZgcAAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwNDQ2NDIwNn0=">
+		<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-10-09 -->
+		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-10-09" content="AjrMPp+ZdEH97MOiKUzcpxLvh+B6I0CL55bPSbvQxL5ggVHl7X2dyEwTfXUgaMV7YLPOev4VZ4Uz+jMTsx3MPQEAAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwNzU3MTAwOH0=">
 		<style>
 			body {
 				font-family: Monospace;
@@ -142,6 +142,8 @@
 
 				//
 
+				window.addEventListener( 'vrdisplaypointerrestricted', onPointerRestricted, false );
+				window.addEventListener( 'vrdisplaypointerunrestricted', onPointerUnrestricted, false );
 				window.addEventListener( 'resize', onWindowResize, false );
 
 			}
@@ -158,6 +160,22 @@
 
 			}
 
+			function onPointerRestricted() {
+				var pointerLockElement = renderer.domElement;
+				if ( pointerLockElement && typeof(pointerLockElement.requestPointerLock) === 'function' ) {
+					pointerLockElement.requestPointerLock();
+
+				}
+			}
+
+			function onPointerUnrestricted() {
+				var currentPointerLockElement = document.pointerLockElement;
+				var expectedPointerLockElement = renderer.domElement;
+				if ( currentPointerLockElement && currentPointerLockElement === expectedPointerLockElement && typeof(document.exitPointerLock) === 'function' ) {
+					document.exitPointerLock();
+				}
+			}
+
 			function onWindowResize() {
 
 				camera.aspect = window.innerWidth / window.innerHeight;

+ 2 - 2
examples/webvr_daydream.html

@@ -4,8 +4,8 @@
 		<title>three.js webvr - daydream</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-09-03 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-09-03" content="Aqj+6XPnxHoSxQj/CDjGXhzrVFeP12/Pgvj7rfqFqVzodYX0ZXJNHTJIvCVExQfvip+Zq9GES+SOQ/zJlpceZgcAAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwNDQ2NDIwNn0=">
+		<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-10-09 -->
+		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-10-09" content="AjrMPp+ZdEH97MOiKUzcpxLvh+B6I0CL55bPSbvQxL5ggVHl7X2dyEwTfXUgaMV7YLPOev4VZ4Uz+jMTsx3MPQEAAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwNzU3MTAwOH0=">
 		<style>
 			body {
 				font-family: Monospace;

+ 2 - 2
examples/webvr_panorama.html

@@ -4,8 +4,8 @@
 		<title>three.js webvr - panorama</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-09-03 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-09-03" content="Aqj+6XPnxHoSxQj/CDjGXhzrVFeP12/Pgvj7rfqFqVzodYX0ZXJNHTJIvCVExQfvip+Zq9GES+SOQ/zJlpceZgcAAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwNDQ2NDIwNn0=">
+		<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-10-09 -->
+		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-10-09" content="AjrMPp+ZdEH97MOiKUzcpxLvh+B6I0CL55bPSbvQxL5ggVHl7X2dyEwTfXUgaMV7YLPOev4VZ4Uz+jMTsx3MPQEAAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwNzU3MTAwOH0=">
 		<style>
 			html, body {
 				background-color: #000;

+ 2 - 2
examples/webvr_rollercoaster.html

@@ -4,8 +4,8 @@
 		<title>three.js webvr - roller coaster</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-09-03 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-09-03" content="Aqj+6XPnxHoSxQj/CDjGXhzrVFeP12/Pgvj7rfqFqVzodYX0ZXJNHTJIvCVExQfvip+Zq9GES+SOQ/zJlpceZgcAAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwNDQ2NDIwNn0=">
+		<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-10-09 -->
+		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-10-09" content="AjrMPp+ZdEH97MOiKUzcpxLvh+B6I0CL55bPSbvQxL5ggVHl7X2dyEwTfXUgaMV7YLPOev4VZ4Uz+jMTsx3MPQEAAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwNzU3MTAwOH0=">
 		<style>
 			body {
 				margin: 0px;

+ 2 - 2
examples/webvr_sandbox.html

@@ -4,8 +4,8 @@
 		<title>three.js webvr - sandbox</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-09-03 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-09-03" content="Aqj+6XPnxHoSxQj/CDjGXhzrVFeP12/Pgvj7rfqFqVzodYX0ZXJNHTJIvCVExQfvip+Zq9GES+SOQ/zJlpceZgcAAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwNDQ2NDIwNn0=">
+		<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-10-09 -->
+		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-10-09" content="AjrMPp+ZdEH97MOiKUzcpxLvh+B6I0CL55bPSbvQxL5ggVHl7X2dyEwTfXUgaMV7YLPOev4VZ4Uz+jMTsx3MPQEAAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwNzU3MTAwOH0=">
 		<style>
 			body {
 				margin: 0px;

+ 2 - 2
examples/webvr_video.html

@@ -4,8 +4,8 @@
 		<title>three.js webvr - video</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-09-03 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-09-03" content="Aqj+6XPnxHoSxQj/CDjGXhzrVFeP12/Pgvj7rfqFqVzodYX0ZXJNHTJIvCVExQfvip+Zq9GES+SOQ/zJlpceZgcAAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwNDQ2NDIwNn0=">
+		<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-10-09 -->
+		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-10-09" content="AjrMPp+ZdEH97MOiKUzcpxLvh+B6I0CL55bPSbvQxL5ggVHl7X2dyEwTfXUgaMV7YLPOev4VZ4Uz+jMTsx3MPQEAAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwNzU3MTAwOH0=">
 		<style>
 			body {
 				font-family: Monospace;

+ 22 - 15
src/Three.Legacy.js

@@ -20,12 +20,12 @@ import {
 } from './core/BufferAttribute.js';
 import { BufferGeometry } from './core/BufferGeometry.js';
 import { Face3 } from './core/Face3.js';
-import { Geometry } from './core/Geometry';
+import { Geometry } from './core/Geometry.js';
 import { Object3D } from './core/Object3D.js';
-import { Uniform } from './core/Uniform';
+import { Uniform } from './core/Uniform.js';
 import { Curve } from './extras/core/Curve.js';
 import { CatmullRomCurve3 } from './extras/curves/CatmullRomCurve3.js';
-import { BoxHelper } from './helpers/BoxHelper';
+import { BoxHelper } from './helpers/BoxHelper.js';
 import { GridHelper } from './helpers/GridHelper.js';
 import { SkeletonHelper } from './helpers/SkeletonHelper.js';
 import { BoxGeometry } from './geometries/BoxGeometry.js';
@@ -281,17 +281,17 @@ Spline.prototype = Object.create( CatmullRomCurve3.prototype );
 
 Object.assign( Spline.prototype, {
 
-	initFromArray: function ( a ) {
+	initFromArray: function ( /* a */ ) {
 
 		console.error( 'THREE.Spline: .initFromArray() has been removed.' );
 
 	},
-	getControlPointsArray: function ( optionalTarget ) {
+	getControlPointsArray: function ( /* optionalTarget */ ) {
 
 		console.error( 'THREE.Spline: .getControlPointsArray() has been removed.' );
 
 	},
-	reparametrizeByArcLength: function ( samplingCoef ) {
+	reparametrizeByArcLength: function ( /* samplingCoef */ ) {
 
 		console.error( 'THREE.Spline: .reparametrizeByArcLength() has been removed.' );
 
@@ -441,18 +441,18 @@ Object.assign( Matrix3.prototype, {
 		return vector.applyMatrix3( this );
 
 	},
-	multiplyVector3Array: function ( a ) {
+	multiplyVector3Array: function ( /* a */ ) {
 
-		console.error( 'THREE.Matrix3: .multiplyVector3Array() has been removed.'  );
+		console.error( 'THREE.Matrix3: .multiplyVector3Array() has been removed.' );
 
 	},
-	applyToBuffer: function( buffer, offset, length ) {
+	applyToBuffer: function ( buffer /*, offset, length */ ) {
 
 		console.warn( 'THREE.Matrix3: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );
 		return this.applyToBufferAttribute( buffer );
 
 	},
-	applyToVector3Array: function( array, offset, length ) {
+	applyToVector3Array: function ( /* array, offset, length */ ) {
 
 		console.error( 'THREE.Matrix3: .applyToVector3Array() has been removed.' );
 
@@ -510,9 +510,9 @@ Object.assign( Matrix4.prototype, {
 		return vector.applyMatrix4( this );
 
 	},
-	multiplyVector3Array: function ( a ) {
+	multiplyVector3Array: function ( /* a */ ) {
 
-		console.error( 'THREE.Matrix4: .multiplyVector3Array() has been removed.'  );
+		console.error( 'THREE.Matrix4: .multiplyVector3Array() has been removed.' );
 
 	},
 	rotateAxis: function ( v ) {
@@ -552,18 +552,18 @@ Object.assign( Matrix4.prototype, {
 		console.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' );
 
 	},
-	applyToBuffer: function( buffer, offset, length ) {
+	applyToBuffer: function ( buffer /*, offset, length */ ) {
 
 		console.warn( 'THREE.Matrix4: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );
 		return this.applyToBufferAttribute( buffer );
 
 	},
-	applyToVector3Array: function( array, offset, length ) {
+	applyToVector3Array: function ( /* array, offset, length */ ) {
 
 		console.error( 'THREE.Matrix4: .applyToVector3Array() has been removed.' );
 
 	},
-	makeFrustum: function( left, right, bottom, top, near, far ) {
+	makeFrustum: function ( left, right, bottom, top, near, far ) {
 
 		console.warn( 'THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.' );
 		return this.makePerspective( left, right, top, bottom, near, far );
@@ -1116,6 +1116,13 @@ Object.assign( WebGLRenderer.prototype, {
 
 	},
 
+	resetGLState: function () {
+
+		console.warn( 'THREE.WebGLRenderer: .resetGLState() is now .state.reset().' );
+		return this.state.reset();
+
+	},
+
 	supportsFloatTextures: function () {
 
 		console.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \'OES_texture_float\' ).' );

+ 52 - 49
src/animation/AnimationAction.js

@@ -1,4 +1,4 @@
-import { WrapAroundEnding, ZeroCurvatureEnding, ZeroSlopeEnding, LoopPingPong, LoopOnce, LoopRepeat } from '../constants';
+import { WrapAroundEnding, ZeroCurvatureEnding, ZeroSlopeEnding, LoopPingPong, LoopOnce, LoopRepeat } from '../constants.js';
 
 /**
  *
@@ -22,8 +22,8 @@ function AnimationAction( mixer, clip, localRoot ) {
 		interpolants = new Array( nTracks );
 
 	var interpolantSettings = {
-			endingStart: 	ZeroCurvatureEnding,
-			endingEnd:		ZeroCurvatureEnding
+		endingStart: ZeroCurvatureEnding,
+		endingEnd: ZeroCurvatureEnding
 	};
 
 	for ( var i = 0; i !== nTracks; ++ i ) {
@@ -48,7 +48,7 @@ function AnimationAction( mixer, clip, localRoot ) {
 	this._weightInterpolant = null;
 
 	this.loop = LoopRepeat;
-	this._loopCount = -1;
+	this._loopCount = - 1;
 
 	// global mixer time when the action is to be started
 	// it's set back to 'null' upon start of the action
@@ -80,7 +80,7 @@ Object.assign( AnimationAction.prototype, {
 
 	// State & Scheduling
 
-	play: function() {
+	play: function () {
 
 		this._mixer._activateAction( this );
 
@@ -88,7 +88,7 @@ Object.assign( AnimationAction.prototype, {
 
 	},
 
-	stop: function() {
+	stop: function () {
 
 		this._mixer._deactivateAction( this );
 
@@ -96,20 +96,20 @@ Object.assign( AnimationAction.prototype, {
 
 	},
 
-	reset: function() {
+	reset: function () {
 
 		this.paused = false;
 		this.enabled = true;
 
 		this.time = 0;			// restart clip
-		this._loopCount = -1;	// forget previous loops
+		this._loopCount = - 1;	// forget previous loops
 		this._startTime = null;	// forget scheduling
 
 		return this.stopFading().stopWarping();
 
 	},
 
-	isRunning: function() {
+	isRunning: function () {
 
 		return this.enabled && ! this.paused && this.timeScale !== 0 &&
 				this._startTime === null && this._mixer._isActiveAction( this );
@@ -117,13 +117,13 @@ Object.assign( AnimationAction.prototype, {
 	},
 
 	// return true when play has been called
-	isScheduled: function() {
+	isScheduled: function () {
 
 		return this._mixer._isActiveAction( this );
 
 	},
 
-	startAt: function( time ) {
+	startAt: function ( time ) {
 
 		this._startTime = time;
 
@@ -131,7 +131,7 @@ Object.assign( AnimationAction.prototype, {
 
 	},
 
-	setLoop: function( mode, repetitions ) {
+	setLoop: function ( mode, repetitions ) {
 
 		this.loop = mode;
 		this.repetitions = repetitions;
@@ -145,7 +145,7 @@ Object.assign( AnimationAction.prototype, {
 	// set the weight stopping any scheduled fading
 	// although .enabled = false yields an effective weight of zero, this
 	// method does *not* change .enabled, because it would be confusing
-	setEffectiveWeight: function( weight ) {
+	setEffectiveWeight: function ( weight ) {
 
 		this.weight = weight;
 
@@ -157,30 +157,30 @@ Object.assign( AnimationAction.prototype, {
 	},
 
 	// return the weight considering fading and .enabled
-	getEffectiveWeight: function() {
+	getEffectiveWeight: function () {
 
 		return this._effectiveWeight;
 
 	},
 
-	fadeIn: function( duration ) {
+	fadeIn: function ( duration ) {
 
 		return this._scheduleFading( duration, 0, 1 );
 
 	},
 
-	fadeOut: function( duration ) {
+	fadeOut: function ( duration ) {
 
 		return this._scheduleFading( duration, 1, 0 );
 
 	},
 
-	crossFadeFrom: function( fadeOutAction, duration, warp ) {
+	crossFadeFrom: function ( fadeOutAction, duration, warp ) {
 
 		fadeOutAction.fadeOut( duration );
 		this.fadeIn( duration );
 
-		if( warp ) {
+		if ( warp ) {
 
 			var fadeInDuration = this._clip.duration,
 				fadeOutDuration = fadeOutAction._clip.duration,
@@ -197,13 +197,13 @@ Object.assign( AnimationAction.prototype, {
 
 	},
 
-	crossFadeTo: function( fadeInAction, duration, warp ) {
+	crossFadeTo: function ( fadeInAction, duration, warp ) {
 
 		return fadeInAction.crossFadeFrom( this, duration, warp );
 
 	},
 
-	stopFading: function() {
+	stopFading: function () {
 
 		var weightInterpolant = this._weightInterpolant;
 
@@ -223,23 +223,23 @@ Object.assign( AnimationAction.prototype, {
 	// set the time scale stopping any scheduled warping
 	// although .paused = true yields an effective time scale of zero, this
 	// method does *not* change .paused, because it would be confusing
-	setEffectiveTimeScale: function( timeScale ) {
+	setEffectiveTimeScale: function ( timeScale ) {
 
 		this.timeScale = timeScale;
-		this._effectiveTimeScale = this.paused ? 0 :timeScale;
+		this._effectiveTimeScale = this.paused ? 0 : timeScale;
 
 		return this.stopWarping();
 
 	},
 
 	// return the time scale considering warping and .paused
-	getEffectiveTimeScale: function() {
+	getEffectiveTimeScale: function () {
 
 		return this._effectiveTimeScale;
 
 	},
 
-	setDuration: function( duration ) {
+	setDuration: function ( duration ) {
 
 		this.timeScale = this._clip.duration / duration;
 
@@ -247,7 +247,7 @@ Object.assign( AnimationAction.prototype, {
 
 	},
 
-	syncWith: function( action ) {
+	syncWith: function ( action ) {
 
 		this.time = action.time;
 		this.timeScale = action.timeScale;
@@ -256,13 +256,13 @@ Object.assign( AnimationAction.prototype, {
 
 	},
 
-	halt: function( duration ) {
+	halt: function ( duration ) {
 
 		return this.warp( this._effectiveTimeScale, 0, duration );
 
 	},
 
-	warp: function( startTimeScale, endTimeScale, duration ) {
+	warp: function ( startTimeScale, endTimeScale, duration ) {
 
 		var mixer = this._mixer, now = mixer.time,
 			interpolant = this._timeScaleInterpolant,
@@ -289,7 +289,7 @@ Object.assign( AnimationAction.prototype, {
 
 	},
 
-	stopWarping: function() {
+	stopWarping: function () {
 
 		var timeScaleInterpolant = this._timeScaleInterpolant;
 
@@ -306,19 +306,19 @@ Object.assign( AnimationAction.prototype, {
 
 	// Object Accessors
 
-	getMixer: function() {
+	getMixer: function () {
 
 		return this._mixer;
 
 	},
 
-	getClip: function() {
+	getClip: function () {
 
 		return this._clip;
 
 	},
 
-	getRoot: function() {
+	getRoot: function () {
 
 		return this._localRoot || this._mixer._root;
 
@@ -326,7 +326,7 @@ Object.assign( AnimationAction.prototype, {
 
 	// Interna
 
-	_update: function( time, deltaTime, timeDirection, accuIndex ) {
+	_update: function ( time, deltaTime, timeDirection, accuIndex ) {
 
 		// called by the mixer
 
@@ -385,7 +385,7 @@ Object.assign( AnimationAction.prototype, {
 
 	},
 
-	_updateWeight: function( time ) {
+	_updateWeight: function ( time ) {
 
 		var weight = 0;
 
@@ -422,7 +422,7 @@ Object.assign( AnimationAction.prototype, {
 
 	},
 
-	_updateTimeScale: function( time ) {
+	_updateTimeScale: function ( time ) {
 
 		var timeScale = 0;
 
@@ -465,7 +465,7 @@ Object.assign( AnimationAction.prototype, {
 
 	},
 
-	_updateTime: function( deltaTime ) {
+	_updateTime: function ( deltaTime ) {
 
 		var time = this.time + deltaTime;
 
@@ -478,7 +478,8 @@ Object.assign( AnimationAction.prototype, {
 
 		if ( loop === LoopOnce ) {
 
-			if ( loopCount === -1 ) {
+			if ( loopCount === - 1 ) {
+
 				// just started
 
 				this._loopCount = 0;
@@ -503,7 +504,7 @@ Object.assign( AnimationAction.prototype, {
 
 				this._mixer.dispatchEvent( {
 					type: 'finished', action: this,
-					direction: deltaTime < 0 ? -1 : 1
+					direction: deltaTime < 0 ? - 1 : 1
 				} );
 
 			}
@@ -512,15 +513,15 @@ Object.assign( AnimationAction.prototype, {
 
 			var pingPong = ( loop === LoopPingPong );
 
-			if ( loopCount === -1 ) {
+			if ( loopCount === - 1 ) {
+
 				// just started
 
 				if ( deltaTime >= 0 ) {
 
 					loopCount = 0;
 
-					this._setEndings(
-							true, this.repetitions === 0, pingPong );
+					this._setEndings( true, this.repetitions === 0, pingPong );
 
 				} else {
 
@@ -528,14 +529,14 @@ Object.assign( AnimationAction.prototype, {
 					// transition through zero counts as a repetition,
 					// so leave loopCount at -1
 
-					this._setEndings(
-							this.repetitions === 0, true, pingPong );
+					this._setEndings( this.repetitions === 0, true, pingPong );
 
 				}
 
 			}
 
 			if ( time >= duration || time < 0 ) {
+
 				// wrap around
 
 				var loopDelta = Math.floor( time / duration ); // signed
@@ -546,6 +547,7 @@ Object.assign( AnimationAction.prototype, {
 				var pending = this.repetitions - loopCount;
 
 				if ( pending < 0 ) {
+
 					// have to stop (switch state, clamp time, fire event)
 
 					if ( this.clampWhenFinished ) this.paused = true;
@@ -555,13 +557,15 @@ Object.assign( AnimationAction.prototype, {
 
 					this._mixer.dispatchEvent( {
 						type: 'finished', action: this,
-						direction: deltaTime > 0 ? 1 : -1
+						direction: deltaTime > 0 ? 1 : - 1
 					} );
 
 				} else {
+
 					// keep running
 
 					if ( pending === 0 ) {
+
 						// entering the last round
 
 						var atStart = deltaTime < 0;
@@ -584,6 +588,7 @@ Object.assign( AnimationAction.prototype, {
 			}
 
 			if ( pingPong && ( loopCount & 1 ) === 1 ) {
+
 				// invert time for the "pong round"
 
 				this.time = time;
@@ -598,7 +603,7 @@ Object.assign( AnimationAction.prototype, {
 
 	},
 
-	_setEndings: function( atStart, atEnd, pingPong ) {
+	_setEndings: function ( atStart, atEnd, pingPong ) {
 
 		var settings = this._interpolantSettings;
 
@@ -613,8 +618,7 @@ Object.assign( AnimationAction.prototype, {
 
 			if ( atStart ) {
 
-				settings.endingStart = this.zeroSlopeAtStart ?
-						ZeroSlopeEnding : ZeroCurvatureEnding;
+				settings.endingStart = this.zeroSlopeAtStart ? ZeroSlopeEnding : ZeroCurvatureEnding;
 
 			} else {
 
@@ -624,8 +628,7 @@ Object.assign( AnimationAction.prototype, {
 
 			if ( atEnd ) {
 
-				settings.endingEnd = this.zeroSlopeAtEnd ?
-						ZeroSlopeEnding : ZeroCurvatureEnding;
+				settings.endingEnd = this.zeroSlopeAtEnd ? ZeroSlopeEnding : ZeroCurvatureEnding;
 
 			} else {
 
@@ -637,7 +640,7 @@ Object.assign( AnimationAction.prototype, {
 
 	},
 
-	_scheduleFading: function( duration, weightNow, weightThen ) {
+	_scheduleFading: function ( duration, weightNow, weightThen ) {
 
 		var mixer = this._mixer, now = mixer.time,
 			interpolant = this._weightInterpolant;

+ 19 - 19
src/animation/AnimationClip.js

@@ -1,9 +1,9 @@
-import { VectorKeyframeTrack } from './tracks/VectorKeyframeTrack';
-import { QuaternionKeyframeTrack } from './tracks/QuaternionKeyframeTrack';
-import { NumberKeyframeTrack } from './tracks/NumberKeyframeTrack';
-import { AnimationUtils } from './AnimationUtils';
-import { KeyframeTrack } from './KeyframeTrack';
-import { _Math } from '../math/Math';
+import { VectorKeyframeTrack } from './tracks/VectorKeyframeTrack.js';
+import { QuaternionKeyframeTrack } from './tracks/QuaternionKeyframeTrack.js';
+import { NumberKeyframeTrack } from './tracks/NumberKeyframeTrack.js';
+import { AnimationUtils } from './AnimationUtils.js';
+import { KeyframeTrack } from './KeyframeTrack.js';
+import { _Math } from '../math/Math.js';
 
 /**
  *
@@ -84,9 +84,9 @@ Object.assign( AnimationClip, {
 			var values = [];
 
 			times.push(
-					( i + numMorphTargets - 1 ) % numMorphTargets,
-					i,
-					( i + 1 ) % numMorphTargets );
+				( i + numMorphTargets - 1 ) % numMorphTargets,
+				i,
+				( i + 1 ) % numMorphTargets );
 
 			values.push( 0, 1, 0 );
 
@@ -104,10 +104,10 @@ Object.assign( AnimationClip, {
 			}
 
 			tracks.push(
-					new NumberKeyframeTrack(
-						'.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',
-						times, values
-					).scale( 1.0 / fps ) );
+				new NumberKeyframeTrack(
+					'.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',
+					times, values
+				).scale( 1.0 / fps ) );
 
 		}
 
@@ -281,16 +281,16 @@ Object.assign( AnimationClip, {
 				var boneName = '.bones[' + bones[ h ].name + ']';
 
 				addNonemptyTrack(
-						VectorKeyframeTrack, boneName + '.position',
-						animationKeys, 'pos', tracks );
+					VectorKeyframeTrack, boneName + '.position',
+					animationKeys, 'pos', tracks );
 
 				addNonemptyTrack(
-						QuaternionKeyframeTrack, boneName + '.quaternion',
-						animationKeys, 'rot', tracks );
+					QuaternionKeyframeTrack, boneName + '.quaternion',
+					animationKeys, 'rot', tracks );
 
 				addNonemptyTrack(
-						VectorKeyframeTrack, boneName + '.scale',
-						animationKeys, 'scl', tracks );
+					VectorKeyframeTrack, boneName + '.scale',
+					animationKeys, 'scl', tracks );
 
 			}
 

+ 38 - 14
src/animation/AnimationMixer.js

@@ -1,9 +1,9 @@
-import { AnimationAction } from './AnimationAction';
-import { EventDispatcher } from '../core/EventDispatcher';
-import { LinearInterpolant } from '../math/interpolants/LinearInterpolant';
-import { PropertyBinding } from './PropertyBinding';
-import { PropertyMixer } from './PropertyMixer';
-import { AnimationClip } from './AnimationClip';
+import { AnimationAction } from './AnimationAction.js';
+import { EventDispatcher } from '../core/EventDispatcher.js';
+import { LinearInterpolant } from '../math/interpolants/LinearInterpolant.js';
+import { PropertyBinding } from './PropertyBinding.js';
+import { PropertyMixer } from './PropertyMixer.js';
+import { AnimationClip } from './AnimationClip.js';
 
 /**
  *
@@ -77,7 +77,7 @@ Object.assign( AnimationMixer.prototype, EventDispatcher.prototype, {
 				}
 
 				var path = prototypeAction && prototypeAction.
-						_propertyBindings[ i ].binding.parsedPath;
+					_propertyBindings[ i ].binding.parsedPath;
 
 				binding = new PropertyMixer(
 					PropertyBinding.create( root, trackName, path ),
@@ -193,16 +193,40 @@ Object.assign( AnimationMixer.prototype, EventDispatcher.prototype, {
 		this.stats = {
 
 			actions: {
-				get total() { return scope._actions.length; },
-				get inUse() { return scope._nActiveActions; }
+				get total() {
+
+					return scope._actions.length;
+
+				},
+				get inUse() {
+
+					return scope._nActiveActions;
+
+				}
 			},
 			bindings: {
-				get total() { return scope._bindings.length; },
-				get inUse() { return scope._nActiveBindings; }
+				get total() {
+
+					return scope._bindings.length;
+
+				},
+				get inUse() {
+
+					return scope._nActiveBindings;
+
+				}
 			},
 			controlInterpolants: {
-				get total() { return scope._controlInterpolants.length; },
-				get inUse() { return scope._nActiveControlInterpolants; }
+				get total() {
+
+					return scope._controlInterpolants.length;
+
+				},
+				get inUse() {
+
+					return scope._nActiveControlInterpolants;
+
+				}
 			}
 
 		};
@@ -404,7 +428,7 @@ Object.assign( AnimationMixer.prototype, EventDispatcher.prototype, {
 
 		remove_empty_map: {
 
-			for ( var _ in bindingByName ) break remove_empty_map;
+			for ( var _ in bindingByName ) break remove_empty_map; // eslint-disable-line no-unused-vars
 
 			delete bindingsByRoot[ rootUuid ];
 

+ 22 - 14
src/animation/AnimationObjectGroup.js

@@ -1,5 +1,5 @@
-import { PropertyBinding } from './PropertyBinding';
-import { _Math } from '../math/Math';
+import { PropertyBinding } from './PropertyBinding.js';
+import { _Math } from '../math/Math.js';
 
 /**
  *
@@ -32,7 +32,7 @@ import { _Math } from '../math/Math';
  * @author tschw
  */
 
-function AnimationObjectGroup( var_args ) {
+function AnimationObjectGroup() {
 
 	this.uuid = _Math.generateUUID();
 
@@ -61,11 +61,22 @@ function AnimationObjectGroup( var_args ) {
 	this.stats = {
 
 		objects: {
-			get total() { return scope._objects.length; },
-			get inUse() { return this.total - scope.nCachedObjects_; }
+			get total() {
+
+				return scope._objects.length;
+
+			},
+			get inUse() {
+
+				return this.total - scope.nCachedObjects_;
+
+			}
 		},
+		get bindingsPerObject() {
+
+			return scope._bindings.length;
 
-		get bindingsPerObject() { return scope._bindings.length; }
+		}
 
 	};
 
@@ -75,7 +86,7 @@ Object.assign( AnimationObjectGroup.prototype, {
 
 	isAnimationObjectGroup: true,
 
-	add: function( var_args ) {
+	add: function () {
 
 		var objects = this._objects,
 			nObjects = objects.length,
@@ -105,9 +116,7 @@ Object.assign( AnimationObjectGroup.prototype, {
 
 				for ( var j = 0, m = nBindings; j !== m; ++ j ) {
 
-					bindings[ j ].push(
-							new PropertyBinding(
-								object, paths[ j ], parsedPaths[ j ] ) );
+					bindings[ j ].push( new PropertyBinding( object, paths[ j ], parsedPaths[ j ] ) );
 
 				}
 
@@ -142,8 +151,7 @@ Object.assign( AnimationObjectGroup.prototype, {
 						// for objects that are cached, the binding may
 						// or may not exist
 
-						binding = new PropertyBinding(
-								object, paths[ j ], parsedPaths[ j ] );
+						binding = new PropertyBinding( object, paths[ j ], parsedPaths[ j ] );
 
 					}
 
@@ -164,7 +172,7 @@ Object.assign( AnimationObjectGroup.prototype, {
 
 	},
 
-	remove: function( var_args ) {
+	remove: function () {
 
 		var objects = this._objects,
 			nCachedObjects = this.nCachedObjects_,
@@ -213,7 +221,7 @@ Object.assign( AnimationObjectGroup.prototype, {
 	},
 
 	// remove & forget
-	uncache: function( var_args ) {
+	uncache: function () {
 
 		var objects = this._objects,
 			nObjects = objects.length,

+ 32 - 33
src/animation/KeyframeTrack.js

@@ -1,12 +1,12 @@
-import { KeyframeTrackPrototype } from './KeyframeTrackPrototype';
-import { StringKeyframeTrack } from './tracks/StringKeyframeTrack';
-import { BooleanKeyframeTrack } from './tracks/BooleanKeyframeTrack';
-import { QuaternionKeyframeTrack } from './tracks/QuaternionKeyframeTrack';
-import { ColorKeyframeTrack } from './tracks/ColorKeyframeTrack';
-import { VectorKeyframeTrack } from './tracks/VectorKeyframeTrack';
-import { NumberKeyframeTrack } from './tracks/NumberKeyframeTrack';
-import { AnimationUtils } from './AnimationUtils';
-import { KeyframeTrackConstructor } from './KeyframeTrackConstructor';
+import { KeyframeTrackPrototype } from './KeyframeTrackPrototype.js';
+import { StringKeyframeTrack } from './tracks/StringKeyframeTrack.js';
+import { BooleanKeyframeTrack } from './tracks/BooleanKeyframeTrack.js';
+import { QuaternionKeyframeTrack } from './tracks/QuaternionKeyframeTrack.js';
+import { ColorKeyframeTrack } from './tracks/ColorKeyframeTrack.js';
+import { VectorKeyframeTrack } from './tracks/VectorKeyframeTrack.js';
+import { NumberKeyframeTrack } from './tracks/NumberKeyframeTrack.js';
+import { AnimationUtils } from './AnimationUtils.js';
+import { KeyframeTrackConstructor } from './KeyframeTrackConstructor.js';
 
 /**
  *
@@ -20,7 +20,7 @@ import { KeyframeTrackConstructor } from './KeyframeTrackConstructor';
 
 function KeyframeTrack( name, times, values, interpolation ) {
 
-	KeyframeTrackConstructor.apply( this, arguments );
+	KeyframeTrackConstructor.apply( this, name, times, values, interpolation );
 
 }
 
@@ -34,11 +34,11 @@ Object.assign( KeyframeTrack, {
 	// Serialization (in static context, because of constructor invocation
 	// and automatic invocation of .toJSON):
 
-	parse: function( json ) {
+	parse: function ( json ) {
 
-		if( json.type === undefined ) {
+		if ( json.type === undefined ) {
 
-			throw new Error( "track type undefined, can not parse" );
+			throw new Error( 'track type undefined, can not parse' );
 
 		}
 
@@ -63,14 +63,13 @@ Object.assign( KeyframeTrack, {
 		} else {
 
 			// by default, we assume a constructor compatible with the base
-			return new trackType(
-					json.name, json.times, json.values, json.interpolation );
+			return new trackType( json.name, json.times, json.values, json.interpolation );
 
 		}
 
 	},
 
-	toJSON: function( track ) {
+	toJSON: function ( track ) {
 
 		var trackType = track.constructor;
 
@@ -108,45 +107,45 @@ Object.assign( KeyframeTrack, {
 
 	},
 
-	_getTrackTypeForValueTypeName: function( typeName ) {
+	_getTrackTypeForValueTypeName: function ( typeName ) {
 
-		switch( typeName.toLowerCase() ) {
+		switch ( typeName.toLowerCase() ) {
 
-			case "scalar":
-			case "double":
-			case "float":
-			case "number":
-			case "integer":
+			case 'scalar':
+			case 'double':
+			case 'float':
+			case 'number':
+			case 'integer':
 
 				return NumberKeyframeTrack;
 
-			case "vector":
-			case "vector2":
-			case "vector3":
-			case "vector4":
+			case 'vector':
+			case 'vector2':
+			case 'vector3':
+			case 'vector4':
 
 				return VectorKeyframeTrack;
 
-			case "color":
+			case 'color':
 
 				return ColorKeyframeTrack;
 
-			case "quaternion":
+			case 'quaternion':
 
 				return QuaternionKeyframeTrack;
 
-			case "bool":
-			case "boolean":
+			case 'bool':
+			case 'boolean':
 
 				return BooleanKeyframeTrack;
 
-			case "string":
+			case 'string':
 
 				return StringKeyframeTrack;
 
 		}
 
-		throw new Error( "Unsupported typeName: " + typeName );
+		throw new Error( 'Unsupported typeName: ' + typeName );
 
 	}
 

+ 3 - 3
src/animation/KeyframeTrackConstructor.js

@@ -1,12 +1,12 @@
-import { AnimationUtils } from './AnimationUtils';
+import { AnimationUtils } from './AnimationUtils.js';
 
 function KeyframeTrackConstructor( name, times, values, interpolation ) {
 
-	if ( name === undefined ) throw new Error( "track name is undefined" );
+	if ( name === undefined ) throw new Error( 'track name is undefined' );
 
 	if ( times === undefined || times.length === 0 ) {
 
-		throw new Error( "no keyframes in track named " + name );
+		throw new Error( 'no keyframes in track named ' + name );
 
 	}
 

+ 10 - 14
src/animation/KeyframeTrackPrototype.js

@@ -1,9 +1,9 @@
-import { InterpolateLinear } from '../constants';
-import { AnimationUtils } from './AnimationUtils';
-import { InterpolateSmooth, InterpolateDiscrete } from '../constants';
-import { CubicInterpolant } from '../math/interpolants/CubicInterpolant';
-import { LinearInterpolant } from '../math/interpolants/LinearInterpolant';
-import { DiscreteInterpolant } from '../math/interpolants/DiscreteInterpolant';
+import { InterpolateLinear } from '../constants.js';
+import { AnimationUtils } from './AnimationUtils.js';
+import { InterpolateSmooth, InterpolateDiscrete } from '../constants.js';
+import { CubicInterpolant } from '../math/interpolants/CubicInterpolant.js';
+import { LinearInterpolant } from '../math/interpolants/LinearInterpolant.js';
+import { DiscreteInterpolant } from '../math/interpolants/DiscreteInterpolant.js';
 
 var KeyframeTrackPrototype;
 
@@ -16,22 +16,19 @@ KeyframeTrackPrototype = {
 
 	InterpolantFactoryMethodDiscrete: function ( result ) {
 
-		return new DiscreteInterpolant(
-				this.times, this.values, this.getValueSize(), result );
+		return new DiscreteInterpolant( this.times, this.values, this.getValueSize(), result );
 
 	},
 
 	InterpolantFactoryMethodLinear: function ( result ) {
 
-		return new LinearInterpolant(
-				this.times, this.values, this.getValueSize(), result );
+		return new LinearInterpolant( this.times, this.values, this.getValueSize(), result );
 
 	},
 
 	InterpolantFactoryMethodSmooth: function ( result ) {
 
-		return new CubicInterpolant(
-				this.times, this.values, this.getValueSize(), result );
+		return new CubicInterpolant( this.times, this.values, this.getValueSize(), result );
 
 	},
 
@@ -175,8 +172,7 @@ KeyframeTrackPrototype = {
 
 			var stride = this.getValueSize();
 			this.times = AnimationUtils.arraySlice( times, from, to );
-			this.values = AnimationUtils.
-					arraySlice( this.values, from * stride, to * stride );
+			this.values = AnimationUtils.arraySlice( this.values, from * stride, to * stride );
 
 		}
 

+ 34 - 35
src/animation/PropertyBinding.js

@@ -132,7 +132,7 @@ Object.assign( PropertyBinding, {
 		// contain any non-bracket characters.
 		var propertyRe = /\.([\w-]+)(?:\[(.+)\])?/;
 
-		var trackRe = new RegExp(''
+		var trackRe = new RegExp( ''
 			+ '^'
 			+ directoryRe.source
 			+ nodeRe.source
@@ -145,51 +145,51 @@ Object.assign( PropertyBinding, {
 
 		return function ( trackName ) {
 
-				var matches = trackRe.exec( trackName );
+			var matches = trackRe.exec( trackName );
 
-				if ( ! matches ) {
+			if ( ! matches ) {
 
-					throw new Error( 'PropertyBinding: Cannot parse trackName: ' + trackName );
+				throw new Error( 'PropertyBinding: Cannot parse trackName: ' + trackName );
 
-				}
-
-				var results = {
-					// directoryName: matches[ 1 ], // (tschw) currently unused
-					nodeName: matches[ 2 ],
-					objectName: matches[ 3 ],
-					objectIndex: matches[ 4 ],
-					propertyName: matches[ 5 ],     // required
-					propertyIndex: matches[ 6 ]
-				};
+			}
 
-				var lastDot = results.nodeName && results.nodeName.lastIndexOf( '.' );
+			var results = {
+				// directoryName: matches[ 1 ], // (tschw) currently unused
+				nodeName: matches[ 2 ],
+				objectName: matches[ 3 ],
+				objectIndex: matches[ 4 ],
+				propertyName: matches[ 5 ], // required
+				propertyIndex: matches[ 6 ]
+			};
 
-				if ( lastDot !== undefined && lastDot !== -1 ) {
+			var lastDot = results.nodeName && results.nodeName.lastIndexOf( '.' );
 
-					var objectName = results.nodeName.substring( lastDot + 1 );
+			if ( lastDot !== undefined && lastDot !== - 1 ) {
 
-					// Object names must be checked against a whitelist. Otherwise, there
-					// is no way to parse 'foo.bar.baz': 'baz' must be a property, but
-					// 'bar' could be the objectName, or part of a nodeName (which can
-					// include '.' characters).
-					if ( supportedObjectNames.indexOf( objectName ) !== -1 ) {
+				var objectName = results.nodeName.substring( lastDot + 1 );
 
-						results.nodeName = results.nodeName.substring( 0, lastDot );
-						results.objectName = objectName;
+				// Object names must be checked against a whitelist. Otherwise, there
+				// is no way to parse 'foo.bar.baz': 'baz' must be a property, but
+				// 'bar' could be the objectName, or part of a nodeName (which can
+				// include '.' characters).
+				if ( supportedObjectNames.indexOf( objectName ) !== - 1 ) {
 
-					}
+					results.nodeName = results.nodeName.substring( 0, lastDot );
+					results.objectName = objectName;
 
 				}
 
-				if ( results.propertyName === null || results.propertyName.length === 0 ) {
+			}
 
-					throw new Error( 'PropertyBinding: can not parse propertyName from trackName: ' + trackName );
+			if ( results.propertyName === null || results.propertyName.length === 0 ) {
 
-				}
+				throw new Error( 'PropertyBinding: can not parse propertyName from trackName: ' + trackName );
 
-				return results;
+			}
 
-			};
+			return results;
+
+		};
 
 	}(),
 
@@ -333,20 +333,20 @@ Object.assign( PropertyBinding.prototype, { // prototype, continued
 
 			function setValue_direct( buffer, offset ) {
 
-				this.node[ this.propertyName ] = buffer[ offset ];
+				this.targetObject[ this.propertyName ] = buffer[ offset ];
 
 			},
 
 			function setValue_direct_setNeedsUpdate( buffer, offset ) {
 
-				this.node[ this.propertyName ] = buffer[ offset ];
+				this.targetObject[ this.propertyName ] = buffer[ offset ];
 				this.targetObject.needsUpdate = true;
 
 			},
 
 			function setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) {
 
-				this.node[ this.propertyName ] = buffer[ offset ];
+				this.targetObject[ this.propertyName ] = buffer[ offset ];
 				this.targetObject.matrixWorldNeedsUpdate = true;
 
 			}
@@ -479,8 +479,7 @@ Object.assign( PropertyBinding.prototype, { // prototype, continued
 
 		if ( ! targetObject ) {
 
-			targetObject = PropertyBinding.findNode(
-					this.rootNode, parsedPath.nodeName ) || this.rootNode;
+			targetObject = PropertyBinding.findNode( this.rootNode, parsedPath.nodeName ) || this.rootNode;
 
 			this.node = targetObject;
 

Some files were not shown because too many files changed in this diff