Browse Source

Merge branch 'dev' into fbxloader_pivots_fix

Mr.doob 7 years ago
parent
commit
2435d08c5b
100 changed files with 4159 additions and 4588 deletions
  1. 1 1
      .github/ISSUE_TEMPLATE.md
  2. 10 11
      README.md
  3. 599 700
      build/three.js
  4. 374 367
      build/three.min.js
  5. 599 700
      build/three.module.js
  6. 6 3
      docs/api/audio/Audio.html
  7. 0 8
      docs/api/cameras/Camera.html
  8. 5 2
      docs/api/cameras/OrthographicCamera.html
  9. 5 4
      docs/api/cameras/PerspectiveCamera.html
  10. 0 3
      docs/api/core/BufferGeometry.html
  11. 1 1
      docs/api/core/Face3.html
  12. 12 12
      docs/api/core/Geometry.html
  13. 9 3
      docs/api/core/Object3D.html
  14. 0 63
      docs/api/extras/CurveUtils.html
  15. 47 0
      docs/api/extras/core/Interpolations.html
  16. 0 1
      docs/api/extras/core/Shape.html
  17. 1 1
      docs/api/extras/curves/SplineCurve.html
  18. 1 1
      docs/api/geometries/TextBufferGeometry.html
  19. 64 0
      docs/api/helpers/Box3Helper.html
  20. 65 0
      docs/api/helpers/PlaneHelper.html
  21. 0 2
      docs/api/lights/PointLight.html
  22. 0 1
      docs/api/lights/RectAreaLight.html
  23. 1 1
      docs/api/lights/SpotLight.html
  24. 3 3
      docs/api/loaders/AnimationLoader.html
  25. 8 0
      docs/api/loaders/FontLoader.html
  26. 17 7
      docs/api/loaders/TextureLoader.html
  27. 3 3
      docs/api/loaders/managers/LoadingManager.html
  28. 1 1
      docs/api/math/Box3.html
  29. 1 1
      docs/api/math/Frustum.html
  30. 4 4
      docs/api/math/Math.html
  31. 17 0
      docs/api/math/Matrix3.html
  32. 1 1
      docs/api/math/Matrix4.html
  33. 5 0
      docs/api/math/Vector2.html
  34. 2 2
      docs/api/math/Vector4.html
  35. 26 1
      docs/api/textures/Texture.html
  36. 0 234
      docs/examples/cameras/CombinedCamera.html
  37. 274 0
      docs/examples/controls/OrbitControls.html
  38. 91 0
      docs/examples/exporters/GLTFExporter.html
  39. 2 0
      docs/examples/geometries/ConvexBufferGeometry.html
  40. 2 0
      docs/examples/geometries/ConvexGeometry.html
  41. 57 0
      docs/examples/geometries/DecalGeometry.html
  42. 18 10
      docs/examples/loaders/BabylonLoader.html
  43. 0 103
      docs/examples/loaders/ColladaLoader.html
  44. 41 24
      docs/examples/loaders/GLTFLoader.html
  45. 622 0
      docs/examples/loaders/LoaderSupport.html
  46. 9 6
      docs/examples/loaders/MTLLoader.html
  47. 40 21
      docs/examples/loaders/OBJLoader.html
  48. 92 35
      docs/examples/loaders/OBJLoader2.html
  49. 24 8
      docs/examples/loaders/PCDLoader.html
  50. 23 25
      docs/examples/loaders/PDBLoader.html
  51. 43 5
      docs/examples/loaders/SVGLoader.html
  52. 19 12
      docs/examples/loaders/TGALoader.html
  53. 0 404
      docs/examples/loaders/WWOBJLoader2.html
  54. 16 7
      docs/list.js
  55. 2 2
      docs/manual/buildTools/Testing-with-NPM.html
  56. 1 1
      docs/manual/introduction/Animation-system.html
  57. 7 3
      docs/manual/introduction/Creating-a-scene.html
  58. 2 2
      docs/manual/introduction/Import-via-modules.html
  59. 1 1
      docs/manual/introduction/Useful-links.html
  60. 3 1
      editor/css/dark.css
  61. 3 1
      editor/css/light.css
  62. 2 49
      editor/index.html
  63. 0 7
      editor/js/Editor.js
  64. 1 1
      editor/js/Loader.js
  65. 7 15
      editor/js/Menubar.File.js
  66. 3 4
      editor/js/Sidebar.Material.js
  67. 3 62
      editor/js/Viewport.js
  68. 13 13
      editor/js/commands/SetMaterialColorCommand.js
  69. 6 13
      editor/js/commands/SetMaterialCommand.js
  70. 15 9
      editor/js/commands/SetMaterialMapCommand.js
  71. 13 13
      editor/js/commands/SetMaterialValueCommand.js
  72. 25 48
      editor/js/libs/app.js
  73. 0 108
      editor/js/libs/tern-threejs/threejs.js
  74. 0 214
      examples/canvas_camera_orthographic2.html
  75. 4 1
      examples/canvas_geometry_panorama.html
  76. 4 1
      examples/canvas_geometry_panorama_fisheye.html
  77. 8 24
      examples/css3d_molecules.html
  78. 4 1
      examples/css3d_panorama.html
  79. 4 4
      examples/css3d_periodictable.html
  80. 26 20
      examples/files.js
  81. 13 13
      examples/index.html
  82. 20 33
      examples/js/ParametricGeometries.js
  83. 8 9
      examples/js/QuickHull.js
  84. 0 322
      examples/js/WaterShader.js
  85. 0 285
      examples/js/cameras/CombinedCamera.js
  86. 5 5
      examples/js/controls/TrackballControls.js
  87. 271 123
      examples/js/exporters/GLTFExporter.js
  88. 5 6
      examples/js/exporters/MMDExporter.js
  89. 16 15
      examples/js/exporters/OBJExporter.js
  90. 1 1
      examples/js/exporters/STLExporter.js
  91. 2 2
      examples/js/exporters/TypedGeometryExporter.js
  92. 2 2
      examples/js/geometries/ConvexGeometry.js
  93. 23 23
      examples/js/geometries/DecalGeometry.js
  94. 7 7
      examples/js/geometries/hilbert2D.js
  95. 11 11
      examples/js/geometries/hilbert3D.js
  96. 102 56
      examples/js/libs/msgpack-js.js
  97. 41 37
      examples/js/loaders/3MFLoader.js
  98. 11 11
      examples/js/loaders/AMFLoader.js
  99. 200 204
      examples/js/loaders/AWDLoader.js
  100. 3 3
      examples/js/loaders/AssimpJSONLoader.js

+ 1 - 1
.github/ISSUE_TEMPLATE.md

@@ -14,7 +14,7 @@ http://jsfiddle.net/hw9rcLL8/ (dev)
 ##### Three.js version
 
 - [ ] Dev
-- [ ] r85
+- [ ] r87
 - [ ] ...
 
 ##### Browser

+ 10 - 11
README.md

@@ -19,17 +19,17 @@ 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;
+var camera, scene, renderer;
 var geometry, material, mesh;
 
 init();
@@ -37,20 +37,19 @@ animate();
 
 function init() {
 
-	scene = new THREE.Scene();
+	camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
+	camera.position.z = 1;
 
-	camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 );
-	camera.position.z = 1000;
+	scene = new THREE.Scene();
 
-	geometry = new THREE.BoxGeometry( 200, 200, 200 );
-	material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } );
+	geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
+	material = new THREE.MeshNormalMaterial();
 
 	mesh = new THREE.Mesh( geometry, material );
 	scene.add( mesh );
 
-	renderer = new THREE.WebGLRenderer();
+	renderer = new THREE.WebGLRenderer( { antialias: true } );
 	renderer.setSize( window.innerWidth, window.innerHeight );
-
 	document.body.appendChild( renderer.domElement );
 
 }
@@ -67,7 +66,7 @@ function animate() {
 }
 ```
 
-If everything went well you should see [this](https://jsfiddle.net/hfj7gm6t/).
+If everything went well you should see [this](https://jsfiddle.net/f2Lommf5/).
 
 ### Change log ###
 

File diff suppressed because it is too large
+ 599 - 700
build/three.js


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


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


+ 6 - 3
docs/api/audio/Audio.html

@@ -35,8 +35,8 @@
 		//Load a sound and set it as the Audio object's buffer
 		audioLoader.load( 'sounds/ambient.ogg', function( buffer ) {
 			sound.setBuffer( buffer );
-			sound.setLoop(true);
-			sound.setVolume(0.5);
+			sound.setLoop( true );
+			sound.setVolume( 0.5 );
 			sound.play();
 		});
 		</code>
@@ -77,7 +77,10 @@
 		<div>Whether the audio is currently playing.</div>
 
 		<h3>[property:Number startTime]</h3>
-		<div>Point at which to start playback. Default is *0*.</div>
+		<div>The time at which the sound should begin to play. Same as the *when* paramter of [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start AudioBufferSourceNode.start](). Default is *0*.</div>
+
+		<h3>[property:Number offset]</h3>
+		<div>An offset to the time within the audio buffer that playback should begin. Same as the *offset* paramter of [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start AudioBufferSourceNode.start](). Default is *0*.</div>
 
 		<h3>[property:String source]</h3>
 		<div>An [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode AudioBufferSourceNode] created

+ 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 - 2
docs/api/cameras/OrthographicCamera.html

@@ -25,7 +25,6 @@
 		<h2>Example</h2>
 
 		<div>[example:canvas_camera_orthographic camera / orthographic ]</div>
-		<div>[example:canvas_camera_orthographic2 camera / orthographic2 ]</div>
 		<div>[example:webgl_camera camera ]</div>
 		<div>[example:webgl_interactive_cubes_ortho interactive / cubes / ortho ]</div>
 		<div>[example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic ]</div>
@@ -58,7 +57,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>
 

+ 0 - 3
docs/api/core/BufferGeometry.html

@@ -176,9 +176,6 @@
 			You should not change this, as it used internally for optimisation.
 		</div>
 
-		<h3>[property:Integer MaxIndex]</h3>
-		<div>Maximum number of vertices allowed, set to *65535*.</div>
-
 		<h3>[property:Object morphAttributes]</h3>
 		<div>
 			Hashmap of [page:BufferAttribute]s holding details of the geometry's [page:Geometry.morphTargets morphTargets].

+ 1 - 1
docs/api/core/Face3.html

@@ -21,7 +21,7 @@
 
 		<div>[example:misc_ubiquity_test ubiquity / test ]</div>
 		<div>[example:svg_sandbox svg / sandbox ]</div>
-		<div>[example:webgl_exporter_obj WebGL / exporter / obj ]</div>
+		<div>[example:misc_exporter_obj exporter / obj ]</div>
 		<div>[example:webgl_shaders_vector WebGL / shaders / vector ]</div>
 
 

+ 12 - 12
docs/api/core/Geometry.html

@@ -274,7 +274,7 @@
 		<div>
 		vector - A world vector to look at.<br /><br />
 
-		Rotates the geometry to face point in space. This is typically done as a one time operation, and not during a loop
+		Rotates the geometry to face point in space. This is typically done as a one time operation but not during the render loop.<br>
 		Use [page:Object3D.lookAt] for typical real-time mesh usage.
 		</div>
 
@@ -299,31 +299,31 @@
 
 		<h3>[method:Geometry rotateX] ( [page:Float radians] )</h3>
 		<div>
-		Rotate the geometry about the X axis. This is typically done as a one time operation, and not during a loop
-    Use [page:Object3D.rotation] for typical real-time mesh rotation.
+		Rotate the geometry about the X axis. This is typically done as a one time operation but not during the render loop.<br>
+		[page:Object3D.rotation] for typical real-time mesh rotation.
 		</div>
 
 		<h3>[method:Geometry rotateY] ( [page:Float radians] )</h3>
 		<div>
-		Rotate the geometry about the Y axis. This is typically done as a one time operation, and not during a loop
-    Use [page:Object3D.rotation] for typical real-time mesh rotation.
+		Rotate the geometry about the Y axis. This is typically done as a one time operation but not during the render loop.<br>
+    	[page:Object3D.rotation] for typical real-time mesh rotation.
 		</div>
 
 		<h3>[method:Geometry rotateZ] ( [page:Float radians] )</h3>
 		<div>
-		Rotate the geometry about the Z axis. This is typically done as a one time operation, and not during a loop
-    Use [page:Object3D.rotation] for typical real-time mesh rotation.
+		Rotate the geometry about the Z axis. This is typically done as a one time operation but not during the render loop.<br>
+	    Use [page:Object3D.rotation] for typical real-time mesh rotation.
 		</div>
 
 		<h3>[method:null sortFacesByMaterialIndex] (  )</h3>
 		<div>
-			Sorts the faces array according to material index. For complex geometries with several materials,
-			this can result in reduced draw call and improved performance.
+		Sorts the faces array according to material index. For complex geometries with several materials,
+		this can result in reduced draw calls and improved performance.
 		</div>
 
 		<h3>[method:Geometry scale] ( [page:Float x], [page:Float y], [page:Float z] )</h3>
 		<div>
-		Scale the geometry data. This is typically done as a one time operation, and not during a loop
+		Scale the geometry data. This is typically done as a one time operation but not during the render loop.<br>
 		Use [page:Object3D.scale] for typical real-time mesh scaling.
 		</div>
 
@@ -332,8 +332,8 @@
 
 		<h3>[method:Geometry translate] ( [page:Float x], [page:Float y], [page:Float z] )</h3>
 		<div>
-		Translate the geometry. This is typically done as a one time operation, and not during a loop
-    Use [page:Object3D.position] for typical real-time mesh translation.
+		Translate the geometry. This is typically done as a one time operation but not during the render loop.<br>
+    	[page:Object3D.position] for typical real-time mesh translation.
 		</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>

+ 0 - 63
docs/api/extras/CurveUtils.html

@@ -1,63 +0,0 @@
-<!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">
-		A class containing utility functions for curves.<br /><br />
-
-		Note that these are all linear functions so it is neccessary to calculate separately for
-		x, y (and z, w if present) components of a curve.
-		</div>
-
-
-		<h2>Methods</h2>
-
-		<h3>[method:Number interpolate]( p0, p1, p2, p3, t )</h3>
-		<div>
-		t -- interpolation weight. <br />
-		p0, p1, p2, p4 -- the points defining the spline curve.<br /><br />
-
-		Used internally by [page:SplineCurve SplineCurve].
-		</div>
-
-		<h3>[method:Number tangentQuadraticBezier]( t, p0, p1, p2 )</h3>
-		<div>
-		t -- the point at which to calculate the tangent. <br />
-		p0, p1, p2 -- the three points defining the quadratic Bézier curve.<br /><br />
-
-		Calculate the tangent at the point t on a quadratic Bézier curve given by the three points.<br /><br />
-
-		Used internally by [page:QuadraticBezierCurve QuadraticBezierCurve].
-		</div>
-
-		<h3>[method:Number tangentCubicBezier]( t, p0, p1, p2, p3 )</h3>
-		<div>
-		t -- the point at which to calculate the tangent. <br />
-		p0, p1, p2, p3 -- the points defining the cubic Bézier curve.<br /><br />
-
-		Calculate the tangent at the point t on a cubic Bézier curve given by the four points.<br /><br />
-
-		Used internally by [page:CubicBezierCurve CubicBezierCurve].
-		</div>
-
-		<h3>[method:Number tangentSpline]( t, p0, p1, p2, p3 )</h3>
-		<div>
-		t -- the point at which to calculate the tangent. <br />
-		p0, p1, p2, p3 -- the points defining the spline curve.<br /><br />
-
-		Calculate the tangent at the point t on a spline curve given by the four points.
-		</div>
-
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-	</body>
-</html>

+ 47 - 0
docs/api/extras/core/Interpolations.html

@@ -0,0 +1,47 @@
+<!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">
+		TODO
+		</div>
+
+		<h2>Methods</h2>
+
+		<h3>[method:Float CatmullRom]( [page:Float t], [page:Float p0], [page:Float p1], [page:Float p2], [page:Float p3] )</h3>
+		<div>
+		t -- interpolation weight.<br />
+		p0, p1, p2, p3 -- the points defining the spline curve.<br /><br />
+
+		Used internally by [page:SplineCurve SplineCurve].
+		</div>
+
+		<h3>[method:Float QuadraticBezier]( [page:Float t], [page:Float p0], [page:Float p1], [page:Float p2] )</h3>
+		<div>
+		t -- interpolation weight.<br />
+		p0, p1, p2 -- the starting, control and end points defining the curve.<br /><br />
+
+		Used internally by [page:QuadraticBezierCurve3 QuadraticBezierCurve3], [page:QuadraticBezierCurve QuadraticBezierCurve] and [page:Font Font].
+		</div>
+
+		<h3>[method:Float CubicBezier]( [page:Float t], [page:Float p0], [page:Float p1], [page:Float p2], [page:Float p3] )</h3>
+		<div>
+		t -- interpolation weight.<br />
+		p0, p1, p2, p3 -- the starting, control(twice) and end points defining the curve.<br /><br />
+
+		Used internally by [page:CubicBezierCurve3 CubicBezierCurve3], [page:CubicBezierCurve CubicBezierCurve] and [page:Font Font].
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 0 - 1
docs/api/extras/core/Shape.html

@@ -41,7 +41,6 @@
 		[example:webgl_geometry_shapes geometry / shapes ]<br/>
 		[example:webgl_geometry_extrude_shapes geometry / extrude / shapes ]<br/>
 		[example:webgl_geometry_extrude_shapes2 geometry / extrude / shapes2 ]<br/>
-		[example:webgl_particles_shapes particles / shapes ]
 		</div>
 
 

+ 1 - 1
docs/api/extras/curves/SplineCurve.html

@@ -14,7 +14,7 @@
 
 		<div class="desc">
 		Create a smooth 2d spline curve from a series of points. Internally this uses
-		[page:CurveUtils.interpolate] to create the curve.
+		[page:Interpolations.CatmullRom] to create the curve.
 		</div>
 
 		<h2>Example</h2>

+ 1 - 1
docs/api/geometries/TextBufferGeometry.html

@@ -40,7 +40,7 @@
 
 		<div>
 		[example:webgl_geometry_text geometry / text ]<br/>
-		[example:webgl_geometry_text2 geometry / text2 ]
+		[example:webgl_geometry_text_pnltri geometry / text2 ]
 		</div>
 
 		<code>

+ 64 - 0
docs/api/helpers/Box3Helper.html

@@ -0,0 +1,64 @@
+<!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>
+		[page:LineSegments] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">
+			Helper object to visualize a [page:Box3].
+		</div>
+
+
+		<h2>Example</h2>
+
+		<code>
+		var box = new THREE.Box3();
+		box.setFromCenterAndSize( new THREE.Vector3( 1, 1, 1 ), new THREE.Vector3( 2, 1, 3 ) );
+
+		var helper = new THREE.Box3Helper( box, 0xffff00 );
+		scene.add( helper );
+		</code>
+
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]( [page:Box3 box], [page:Color color] )</h3>
+		<div>
+		[page:Box3 box]  -- the Box3 to show.<br />
+		[page:Color color] --  (optional) the box's color. Default is 0xffff00.<br /><br />
+
+		Creates a new wireframe box that represents the passed Box3.
+		</div>
+
+		<h2>Properties</h2>
+		<div>See the base [page:LineSegments] class for common properties.</div>
+
+		<h3>[property:Box3 box]</h3>
+		<div>The Box3 being visualized.</div>
+
+
+		<h2>Methods</h2>
+		<div>See the base [page:LineSegments] class for common methods.</div>
+
+
+		<h3>[method:void updateMatrixWorld]( force )</h3>
+		<div>
+			This overrides the method in the base [page:Object3D] class so that it
+			also updates the wireframe box to the extent of the [page:Box3Helper.box .box]
+			property.
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 65 - 0
docs/api/helpers/PlaneHelper.html

@@ -0,0 +1,65 @@
+<!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>
+		[page:LineSegments] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">
+			Helper object to visualize a [page:Plane].
+		</div>
+
+
+		<h2>Example</h2>
+
+		<code>
+		var plane = new THREE.Plane( new THREE.Vector3( 1, 1, 0.2 ), 3 );
+		var helper = new THREE.PlaneHelper( plane, 1, 0xffff00 );
+		scene.add( helper );
+		</code>
+
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]( [page:Plane plane], [page:Float size], [page:Color hex] )</h3>
+		<div>
+		[page:Plane plane] --  the plane to visualize.<br />
+		[page:Float size] -- (optional) side length of plane helper. Default is 1.<br />
+		[page:Color color] --  (optional) the color of the helper. Default is 0xffff00.<br /><br />
+
+		Creates a new wireframe representation of the passed plane.
+		</div>
+
+		<h2>Properties</h2>
+		<div>See the base [page:LineSegments] class for common properties.</div>
+
+		<h3>[property:Plane plane]</h3>
+		<div>The [page:Plane plane] being visualized.</div>
+
+		<h3>[property:Float size]</h3>
+		<div>The side lengths of plane helper.</div>
+
+
+		<h2>Methods</h2>
+		<div>See the base [page:LineSegments] class for common methods.</div>
+
+		<h3>[method:void updateMatrixWorld]( force )</h3>
+		<div>
+			This overrides the method in the base [page:Object3D] class so that it also
+			updates the helper object according to the [page:PlaneHelper.plane .plane] and
+			[page:PlaneHelper.size .size] properties.
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 0 - 2
docs/api/lights/PointLight.html

@@ -27,9 +27,7 @@
 			[example:webgl_lights_pointlights lights / pointlights ]<br />
 			[example:webgl_lights_pointlights2 lights / pointlights2 ]<br />
 			[example:webgldeferred_animation animation ]<br />
-			[example:webgldeferred_pointlights pointlights ]<br />
 			[example:webgl_effects_anaglyph effects / anaglyph ]<br />
-			[example:webgl_geometry_large_mesh geometry / large / mesh ]<br />
 			[example:webgl_geometry_text geometry / text ]<br />
 			[example:webgl_lensflares lensflares ]
 		</div>

+ 0 - 1
docs/api/lights/RectAreaLight.html

@@ -28,7 +28,6 @@
 		<h2>Examples</h2>
 
 		<div>
-			[example:webgl_lights_arealight WebGL / arealight ]<br />
 			[example:webgl_lights_rectarealight WebGL / rectarealight ]
 
 			<code>

+ 1 - 1
docs/api/lights/SpotLight.html

@@ -36,7 +36,7 @@
 			[example:webgl_interactive_draggablecubes interactive / draggablecubes ]<br />
 			[example:webgl_materials_bumpmap_skin materials / bumpmap / skin ]<br />
 			[example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic ]<br />
-			[example:webgl_morphtargets_md2 morphtargets / md2 ]<br />
+			[example:webgl_loader_md2 loader / md2 ]<br />
 			[example:webgl_shading_physical shading / physical ]<br />
 			[example:webgl_materials_bumpmap materials / bumpmap]<br/>
 			[example:webgl_shading_physical shading / physical]<br/>

+ 3 - 3
docs/api/loaders/AnimationLoader.html

@@ -11,7 +11,7 @@
 		<h1>[name]</h1>
 
 		<div class="desc">
-			Class for loading an animation in JSON format.
+			Class for loading [page:AnimationClip AnimationClips] in JSON format.
 			This uses the [page:FileLoader] internally for loading files.
 		</div>
 
@@ -26,8 +26,8 @@
 			// resource URL
 			'animations/animation.js',
 			// Function when resource is loaded
-			function ( animation ) {
-				// do something with the animation
+			function ( animations ) {
+				// animations is an array of AnimationClips
 			},
 			// Function called when download progresses
 			function ( xhr ) {

+ 8 - 0
docs/api/loaders/FontLoader.html

@@ -63,6 +63,8 @@
 			The [page:LoadingManager loadingManager] the loader is using. Default is [page:DefaultLoadingManager].
 		</div>
 
+		<h3>[property:String path]</h3>
+		<div>The base path from which fonts will be loaded. See [page:.setPath]. Default is *undefined*.</div>
 
 		<h2>Methods</h2>
 
@@ -83,6 +85,12 @@
 		Parse a <em>JSON</em> structure and return a [page:Font].
 		</div>
 
+		<h3>[method:FontLoader setPath]( [page:String path] )</h3>
+		<div>
+			Set the base path or URL from which to load fonts. This can be useful if
+			you are loading many fonts from the same directory.
+		</div>
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 17 - 7
docs/api/loaders/TextureLoader.html

@@ -17,6 +17,17 @@
 
 		<h2>Example</h2>
 
+		<code>
+		var texture = new THREE.TextureLoader().load( 'textures/land_ocean_ice_cloud_2048.jpg' );
+
+		// immediately use the texture for material creation
+		var material = new THREE.MeshBasicMaterial( { map: texture } );
+		</code>
+
+		[example:webgl_geometry_cube geometry / cube]
+
+		<h2>Example with Callbacks</h2>
+
 		<code>
 		// instantiate a loader
 		var loader = new THREE.TextureLoader();
@@ -27,24 +38,22 @@
 			'textures/land_ocean_ice_cloud_2048.jpg',
 			// Function when resource is loaded
 			function ( texture ) {
-				// do something with the texture
+				// in this example we create the material when the texture is loaded
 				var material = new THREE.MeshBasicMaterial( {
 					map: texture
 				 } );
 			},
 			// Function called when download progresses
 			function ( xhr ) {
-				console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
+				console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
 			},
 			// Function called when download errors
 			function ( xhr ) {
-				console.log( 'An error happened' );
+				console.error( 'An error happened' );
 			}
 		);
 		</code>
 
-		[example:canvas_geometry_earth]
-
 		<h2>Constructor</h2>
 
 		<h3>[name]( [page:LoadingManager manager] )</h3>
@@ -81,7 +90,7 @@
 
 		<h2>Methods</h2>
 
-		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
+		<h3>[method:Texture load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<div>
 		[page:String url] — the path or URL to the file. This can also be a
 			[link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs Data URI].<br />
@@ -89,7 +98,8 @@
 		[page:Function onProgress] — Will be called while load progresses. The argument will be the XMLHttpRequest instance, which contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
 		[page:Function onError] — Will be called when load errors.<br /><br />
 
-		Begin loading from url and pass the loaded [page:Texture texture] to onLoad.
+		Begin loading from the given URL and pass the fully loaded [page:Texture texture] to onLoad. The method also returns a new texture object which can directly be used for material creation.
+		If you do it this way, the texture may pop up in your scene once the respective loading process is finished.
 		</div>
 
 		<h3>[method:null setCrossOrigin]( [page:String value] )</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>

+ 1 - 1
docs/api/math/Box3.html

@@ -244,7 +244,7 @@
 		<h3>[method:Box3 setFromCenterAndSize]( [page:Vector3 center], [page:Vector3 size] )</h3>
 		<div>
 		[page:Vector3 center] - Desired center position of the box ([page:Vector3]). <br>
-		[page:Vector3 size] - Desired x and y dimensions of the box ([page:Vector3]).<br /><br />
+		[page:Vector3 size] - Desired x, y and z dimensions of the box ([page:Vector3]).<br /><br />
 
 		Centers this box on [page:Vector3 center] and sets this box's width and height to the values specified
 		in [page:Vector3 size].

+ 1 - 1
docs/api/math/Frustum.html

@@ -98,7 +98,7 @@
 		<div>
 			[page:Matrix4 matrix] - [page:Matrix4] used to set the [page:.planes planes]<br /><br />
 
-			This is used by the [page:WebGLRenderer] to set up the Frustum from a [page:Camera Camera's]
+			This is used by the [page:WebGLRenderer] to set up the Frustum from a [page:Camera Camera]'s
 			[page:Camera.projectionMatrix projectionMatrix] and [page:Camera.matrixWorldInverse matrixWorldInverse].
 		</div>
 

+ 4 - 4
docs/api/math/Math.html

@@ -70,11 +70,11 @@
 		Linear mapping of [page:Float x] from range [[page:Float a1], [page:Float a2]] to range [[page:Float b1], [page:Float b2]].
 		</div>
 
-		<h3>[method:Integer nearestPowerOfTwo]( [page:Number n] )</h3>
-		<div>	Returns the nearest power of 2 to a given number [page:Number n].</div>
+		<h3>[method:Integer ceilPowerOfTwo]( [page:Number n] )</h3>
+		<div>Returns the smallest power of 2 that is greater than or equal to [page:Number n].</div>
 
-		<h3>[method:Integer nextPowerOfTwo]( [page:Number n] )</h3>
-		<div>Returns the nearest power of 2 that is bigger than [page:Number n].</div>
+		<h3>[method:Integer floorPowerOfTwo]( [page:Number n] )</h3>
+		<div>Returns the largest power of 2 that is less than or equal to [page:Number n].</div>
 
 		<h3>[method:Float radToDeg]( [page:Float radians] )</h3>
 		<div>Converts radians to degrees.</div>

+ 17 - 0
docs/api/math/Matrix3.html

@@ -169,6 +169,23 @@ m.elements = [ 11, 21, 31,
 		<h3>[method:Matrix3 setFromMatrix4]( [page:Matrix4 m] )</h3>
 		<div>Set this matrx to the upper 3x3 matrix of the Matrix4 [page:Matrix4 m].</div>
 
+		<h3>
+			[method:Matrix3 setUvTransform](
+			[page:Float tx], [page:Float ty], [page:Float sx], [page:Float sy],
+			[page:Float rotation], [page:Float cx], [page:Float cy] )
+		</h3>
+		<div>
+		[page:Float tx] - offset x<br />
+		[page:Float ty] - offset y<br />
+		[page:Float sx] - repeat x<br />
+		[page:Float sy] - repeat y<br />
+		[page:Float rotation] - rotation (in radians)<br />
+		[page:Float cx] - center x of rotation<br />
+		[page:Float cy] - center y of rotation<br /><br />
+
+		Sets the UV transform matrix from offset, repeat, rotation, and center.
+		</div>
+
 		<h3>[method:Array toArray]( [page:Array array], [page:Integer offset] )</h3>
 		<div>
 		[page:Array array] - (optional) array to store the resulting vector in. If not given a new array will be created.<br />

+ 1 - 1
docs/api/math/Matrix4.html

@@ -260,7 +260,7 @@ xAxis.z, yAxis.z, zAxis.z, 0,
 		[link:https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion here].
 		The rest of the matrix is set to the identity. So, given [page:Quaternion q] = w + xi + yj + zk, the resulting matrix will be:
 		<code>
-1-2y²-2z²    2xy-2zw    2xz-2yw    0
+1-2y²-2z²    2xy-2zw    2xz+2yw    0
 2xy+2zw      1-2x²-2z²  2yz-2xw    0
 2xz-2yw      2yz+2xw    1-2x²-2y²  0
 0            0          0          1

+ 5 - 0
docs/api/math/Vector2.html

@@ -97,6 +97,11 @@
 		Computes the angle in radians of this vector with respect to the positive x-axis.
 		</div>
 
+		<h3>[method:Vector2 applyMatrix3]( [page:Matrix3 m] )</h3>
+		<div>
+		Multiplies this vector (with an implicit 1 as the 3rd component) by m.
+		</div>
+
 		<h3>[method:Vector2 ceil]()</h3>
 		<div>
 		The [page:.x x] and [page:.y y] components of the vector are rounded up to the nearest integer value.

+ 2 - 2
docs/api/math/Vector4.html

@@ -231,13 +231,13 @@ var d = a.dot( b );
 
 		<h3>[method:Vector4 max]( [page:Vector4 v] )</h3>
 		<div>
-		If this vector's x, y, z or w value is less than [page:Vector4 v's] x, y, z or w value, replace
+		If this vector's x, y, z or w value is less than [page:Vector4 v]'s x, y, z or w value, replace
 		that value with the corresponding max value.
 		</div>
 
 		<h3>[method:Vector4 min]( [page:Vector4 v] )</h3>
 		<div>
-		If this vector's x, y, z or w value is greater than [page:Vector4 v's] x, y, z or w value, replace
+		If this vector's x, y, z or w value is greater than [page:Vector4 v]'s x, y, z or w value, replace
 		that value with the corresponding min value.
 		</div>
 

+ 26 - 1
docs/api/textures/Texture.html

@@ -114,7 +114,7 @@
 		<h3>[property:number format]</h3>
 		<div>
 		The default is [page:Textures THREE.RGBAFormat], although the [page:TextureLoader TextureLoader] will automatically
-		et this to [page:Textures THREE.RGBFormat] for JPG images. <br /><br />
+		set this to [page:Textures THREE.RGBFormat] for JPG images. <br /><br />
 
 		See the [page:Textures texture constants] page for details of other formats.
 		</div>
@@ -147,6 +147,31 @@
 		assigned to achieve the desired repetiton.
 		</div>
 
+		<h3>[property:number rotation]</h3>
+		<div>
+		How much the texture is rotated around the center point, in radians. Postive values are counter-clockwise. Default is *0*.
+		</div>
+
+		<h3>[property:Vector2 center]</h3>
+		<div>
+		Indicates where the center of rotation is. To rotate around the center point set this value to (0.5, 0.5). Default value is (0.0, 0.0).
+		</div>
+
+		<h3>[property:boolean matrixAutoUpdate]</h3>
+		<div>
+		Whether to update the texture's uv-transform [property:Matrix3 matrix] based on the [property:Vector2 offset],
+		[property:Vector2 repeat], and [property:number rotation] settings. True by default.
+		Set this to false if you are specifying the uv-transform matrix directly.
+		</div>
+
+		<h3>[property:Matrix3 matrix]</h3>
+		<div>
+		The uv-transform matrix for the texture. Updated by the renderer from the texture properties [property:Vector2 offset], [property:Vector2 repeat],
+		and [property:number rotation] when the texture's [property:boolean matrixAutoUpdate] property is true.
+		When [property:boolean matrixAutoUpdate] property is false, this matrix may be set manually.
+		Default is the indentity matrix.
+		</div>
+
 		<h3>[property:boolean generateMipmaps]</h3>
 		<div>
 		Whether to generate mipmaps (if possible) for a texture. True by default. Set this to false if you are

+ 0 - 234
docs/examples/cameras/CombinedCamera.html

@@ -1,234 +0,0 @@
-<!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>
-		[page:Camera] &rarr;
-
-		<h1>[name]</h1>
-
-		<div class="desc">A general purpose camera, for setting FOV, Lens Focal Length,
- 		and switching between perspective and orthographic views easily.
- 		Use this only if you do not wish to manage
- 		both an Orthographic and Perspective Camera</div>
-
-		<h2>Examples</h2>
-
-		<div>[example:canvas_camera_orthographic2 camera / orthographic2 ]</div>
-
-		<code>//Create combined camera
-		camera = new THREE.CombinedCamera( window.innerWidth / 2, window.innerHeight / 2, 70, 1, 1000, - 500, 1000 );
-		</code>
-
-		<h2>Constructor</h2>
-
-
-		<h3>[name]([page:Number width], [page:Number height], [page:Number fov], [page:Number near], [page:Number far], [page:Number orthoNear], [page:Number orthoFar])</h3>
-		<div>
-		width -- Camera frustum width.<br />
-		height -- Camera frustum height.<br />
-		fov — Camera frustum vertical field of view in perspective view.<br />
-		near — Camera frustum near plane in perspective view.<br />
-		far — Camera frustum far plane in perspective view.<br />
-		orthoNear — Camera frustum near plane in orthographic view.<br />
-		orthoFar — Camera frustum far plane in orthographic view.
-		</div>
-		<div>
-		Creates a [name]. This initializes 2 cameras, an OrthographicCamera and a PerspectiveCamera. The default is the perspective Camera.
-		</div>
-
-
-		<h2>Properties</h2>
-
-
-
-		<h3>[property:Number fov]</h3>
-		<div>
-		Gets or sets the camera frustum vertical field of view in perspective view.
-		</div>
-
-		<h3>[property:Float aspect]</h3>
-		<div>Camera frustum aspect ratio, usually the canvas width / canvas height.</div>
-
-		<h3>[property:number left]</h3>
-		<div>
-		Gets or sets the camera frustum left plane in orthographic view.
-		</div>
-
-		<h3>[property:Number right]</h3>
-		<div>
-		Gets or sets the camera frustum right plane in orthographic view.
-		</div>
-
-		<h3>[property:number top]</h3>
-		<div>
-		Gets or sets the camera frustum top plane in orthographic view.
-		</div>
-
-		<h3>[property:Number bottom]</h3>
-		<div>
-		Gets or sets the camera frustum bottom plane in orthographic view.
-		</div>
-
-		<h3>[property:number zoom]</h3>
-		<div>
-		Gets or sets the zoom factor of the camera.
-		</div>
-
-		<h3>[property:number near]</h3>
-		<div>
-		Gets camera frustum near plane.
-		</div>
-
-		<h3>[property:number far]</h3>
-		<div>
-		Gets camera frustum far plane.
-		</div>
-
-		<h3>[property:Object view]</h3>
-		<div>
-			Frustum window specification or null.
-			This is set using the [page:CombinedCamera.setViewOffset .setViewOffset] method
-			and cleared using [page:CombinedCamera.clearViewOffset .clearViewOffset].
-		</div>
-
-		<h3>[property:Matrix4 projectionMatrix]</h3>
-		<div>
-		This is the matrix which contains the projection.
-		</div>
-
-		<h3>[property:OrthographicCamera cameraO]</h3>
-		<div>
-		Gets or sets the internal OrthographicCamera used as camera.
-		</div>
-
-		<h3>[property:PerspectiveCamera cameraP]</h3>
-		<div>
-		Gets or sets the internal PerspectiveCamera used as camera.
-		</div>
-
-		<h3>[property:boolean inOrthographicMode]</h3>
-		<div>
-		Gets whether the combinedCamera is in Orthographic Mode.
-		</div>
-
-		<h3>[property:boolean inPerspectiveMode]</h3>
-		<div>
-		Gets whether the combinedCamera is in Perspective Mode.
-		</div>
-
-		<h2>Methods</h2>
-
-		<h3>[method:null setFov]([page:Number fov])</h3>
-		<div>
-		fov --  Camera frustum vertical field of view in perspective view.
-		</div>
-		<div>
-		sets the camera frustum vertical field of view in perspective view.
-		</div>
-
-		<h3>[method:null setZoom]([page:Number zoom])</h3>
-		<div>
-		zoom -- The zoom factor.
-		</div>
-		<div>
-		Sets the zoomfactor.
-		</div>
-
-		<h3>[method:null setLens]([page:number focalLength], [page:Number filmGauge])</h3>
-		<div>
-		focalLength -- The focal length of a lens is defined as the distance from the optical center of a lens (or, the secondary principal point for a complex lens like a camera lens) to the focal point (sensor) when the lens is focused on an object at infinity. <br />
-		filmGauge -- the size of the frame in mm. (default is *35*)
-		</div>
-		<div>
-		Sets the fov based on lens data.
-		</div>
-
-		<h3>[method:null toFrontView]()</h3>
-		<div>
-		Sets the camera to view the front of the target.
-		</div>
-
-		<h3>[method:null toBackView]()</h3>
-		<div>
-		Sets the camera to view the back of the target.
-		</div>
-
-		<h3>[method:null toLeftView]()</h3>
-		<div>
-		Sets the camera to view the left of the target.
-		</div>
-
-		<h3>[method:null toRightView]()</h3>
-		<div>
-		Sets the camera to view the right of the target.
-		</div>
-
-		<h3>[method:null toTopView]()</h3>
-		<div>
-		Sets the camera to view the top.
-		</div>
-
-		<h3>[method:null toBottomView]()</h3>
-		<div>
-		Sets the camera to view the bottom.
-		</div>
-
-		<h3>[method:null setSize]([page:Number width], [page:Number height])</h3>
-		<div>
-		width -- The width of the orthographic view.<br />
-		height -- The height of the orthographic view.
-		</div>
-		<div>
-		Sets the size of the orthographic view.
-		</div>
-
-		<h3>[method:null toOrthographic]()</h3>
-		<div>
-		Change the camera to orthographic view.
-		</div>
-
-		<h3>[method:null toPerspective]()</h3>
-		<div>
-		Change the camera to Perspective view.
-		</div>
-
-		<h3>[method:null updateProjectionMatrix]()</h3>
-		<div>
-		Updates the ProjectionMatrix.
-		</div>
-
-		<h3>[method:Camera copy]( [page:Camera source] )</h3>
-		<div>
-		Copy the properties from the source camera into this one.
-		</div>
-
-		<h3>[method:null setViewOffset]( [page:Float fullWidth], [page:Float fullHeight], [page:Float x], [page:Float y], [page:Float width], [page:Float height] )</h3>
-		<div>
-		fullWidth — full width of multiview setup<br />
-		fullHeight — full height of multiview setup<br />
-		x — horizontal offset of subcamera<br />
-		y — vertical offset of subcamera<br />
-		width — width of subcamera<br />
-		height — height of subcamera<br /><br />
-
-			Sets an offset in a larger [link:https://en.wikipedia.org/wiki/Viewing_frustum viewing frustum].
-			This is useful for multi-window or multi-monitor/multi-machine setups.
-			For an example on how to use it see [page:PerspectiveCamera.setViewOffset PerspectiveCamera].
-		</div>
-
-
-		<h3>[method:null clearViewOffset]()</h3>
-		<div>
-		Removes any offset set by the .setViewOffset method.
-		</div>
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/cameras/CombinedCamera.js examples/cameras/CombinedCamera.js]
-	</body>
-</html>

+ 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>

+ 2 - 0
docs/examples/geometries/ConvexBufferGeometry.html

@@ -34,6 +34,8 @@
 
 		<h2>Example</h2>
 
+		<div>[example:webgl_geometry_convex geometry / convex ]</div>
+
 		<code>var geometry = new THREE.ConvexBufferGeometry( points );
 		var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
 		var mesh = new THREE.Mesh( geometry, material );

+ 2 - 0
docs/examples/geometries/ConvexGeometry.html

@@ -33,6 +33,8 @@
 
 		<h2>Example</h2>
 
+		<div>[example:webgl_geometry_convex geometry / convex ]</div>
+
 		<code>var geometry = new THREE.ConvexGeometry( points );
 		var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
 		var mesh = new THREE.Mesh( geometry, material );

+ 57 - 0
docs/examples/geometries/DecalGeometry.html

@@ -0,0 +1,57 @@
+<!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>
+		[page:BufferGeometry] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">[name] can be used to create a decal mesh that serves different kinds of purposes e.g. adding unique details to models, performing dynamic visual environmental changes or covering seams.</div>
+
+		<script>
+
+		// iOS iframe auto-resize workaround
+
+		if ( /(iPad|iPhone|iPod)/g.test( navigator.userAgent ) ) {
+
+			var scene = document.getElementById( 'scene' );
+
+			scene.style.width = getComputedStyle( scene ).width;
+			scene.style.height = getComputedStyle( scene ).height;
+			scene.setAttribute( 'scrolling', 'no' );
+
+		}
+
+		</script>
+
+		<h2>Example</h2>
+
+		<div>[example:webgl_decals decals ]</div>
+
+		<code>var geometry =  new THREE.DecalGeometry( mesh, position, orientation, size );
+		var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
+		var mesh = new THREE.Mesh( geometry, material );
+		scene.add( mesh );
+		</code>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [page:Mesh mesh], [page:Vector3 position], [page:Euler orientation], [page:Vector3 size] )</h3>
+		<div>
+		mesh — Any mesh object.<br />
+		position — Position of the decal projector.<br />
+		orientation — Orientation of the decal projector.<br />
+		size — Size of the decal projector.
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/geometries/DecalGeometry.js examples/js/geometries/DecalGeometry.js]
+	</body>
+</html>

+ 18 - 10
docs/examples/loaders/BabylonLoader.html

@@ -8,10 +8,12 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	<body>
-
 		<h1>[name]</h1>
 
-		<div class="desc">A loader for loading a <em>.babylon</em> resource.</div>
+		<div class="desc">A loader for loading a <em>.babylon</em> resource. <br />
+		The <a href="https://doc.babylonjs.com/generals/file_format_map_(.babylon)"> .babylon </a> file format used by
+		<a href="https://www.babylonjs.com/">Babylon.js</a>.
+		</div>
 
 		<h2>Example</h2>
 
@@ -23,17 +25,23 @@
 		loader.load(
 			// resource URL
 			'models/babylon/skull.babylon',
-			// Function when resource is loaded
+			// called when resource is loaded
 			function ( object ) {
+
 				scene.add( object );
+
 			},
-			// Function called when download progresses
+			// called when loading is in progress
 			function ( xhr ) {
-				console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
+
+				console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
+
 			},
-			// Function called when download errors
+			// called when loading has errors
 			function ( xhr ) {
+
 				console.log( 'An error happened' );
+
 			}
 		);
 		</code>
@@ -57,10 +65,10 @@
 
 		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<div>
-		[page:String url] — required<br />
-		[page:function onLoad] — Will be called when load completes. The argument will be the loaded [page:Object3D].<br />
-		[page:function onProgress] — Will be called while load progresses. The argument will be the XMLHttpRequest instance, which contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
-		[page:function onError] — Will be called when load errors.<br />
+		[page:String url] — A string containing the path/URL of the <em>.babylon</em> file.<br />
+		[page:function onLoad] — (optional) A function to be called after loading is successfully completed. The function receives the loaded [page:Object3D] as an argument.<br />
+		[page:function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains [page:Integer total] and [page:Integer loaded] bytes.<br />
+		[page:function onError] — (optional) A function to be called if an error occurs during loading. The function receives the error as an argument.<br />
 		</div>
 		<div>
 		Begin loading from url and call onLoad with the parsed response content.

+ 0 - 103
docs/examples/loaders/ColladaLoader.html

@@ -1,103 +0,0 @@
-<!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">A loader for <em>Collada</em> files.</div>
-
-		<h2>Example</h2>
-
-		<code>
-		// instantiate a loader
-		var loader = new THREE.ColladaLoader();
-
-		loader.load(
-			// resource URL
-			'models/collada/monster/monster.dae',
-			// Function when resource is loaded
-			function ( collada ) {
-				scene.add( collada.scene );
-			},
-			// Function called when download progresses
-			function ( xhr ) {
-				console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
-			}
-		);
-		</code>
-
-		[example:webgl_loader_collada]<br />
-		[example:webgl_loader_collada_keyframe]<br />
-		[example:webgl_loader_collada_skinning]<br />
-		[example:webgl_loader_collada_kinematics]
-
-
-		<h2>Constructor</h2>
-
-		<h3>[name]()</h3>
-		<div>
-		Creates a new [name].
-		</div>
-
-
-		<h2>Properties</h2>
-
-		<h3>[property:Array options]</h3>
-		<div>
-		&nbsp;.[page:Boolean centerGeometry] — Force [page:Geometry] to always be centered at the local origin of the containing [page: Mesh].<br />
-		&nbsp;.[page:Boolean convertUpAxis] — Axis conversion is done for geometries, animations, and controllers.<br />
-		&nbsp;.[page:Boolean subdivideFaces] — Force subdivision into multiple [page: Face3].<br />
-		&nbsp;.[page:String upAxis] — X, Y or Z<br />
-		&nbsp;.[page:Boolean defaultEnvMap] — Cubemap to use for reflective or refractive materials.<br />
-		</div>
-
-		<h3>[property:Object geometries]</h3>
-		<div>
-		Parsed <em>.dae</em> geometries.
-		</div>
-
-
-		<h2>Methods</h2>
-
-		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress] )</h3>
-		<div>
-		[page:String url] — required<br />
-		[page:function onLoad] — Will be called when load completes. The argument will be an [page:Object object] containing loaded resources.<br />
-		[page:function onProgress] — Will be called while load progresses. The argument will be an object containing .[page:Integer total] and .[page:Integer loaded] bytes.<br />
-		</div>
-		<div>
-		Begin loading from url and call onLoad with the parsed response content.
-		</div>
-
-		<h3>[method:Object parse]( [page:Document doc], [page:Function callBack], [page:String url] )</h3>
-		<div>
-		[page:Document doc] — The <em>XML</em> document to parse.<br />
-		[page:Function callBack] — Will be called when parse completes.<br />
-		[page:String url] — The base url from which to find subsequent resources.<br />
-		</div>
-		<div>
-		Parse an <em>XML Document</em> and return an [page:Object object] that contain loaded parts: .[page:Scene scene], .[page:Array morphs], .[page:Array skins], .[page:Array animations], .[page:Object dae]
-		</div>
-
-		<h3>[method:null applySkin]( [page:Geometry geometry], [page:Object instanceCtrl], [page:Integer frame] )</h3>
-		<div>
-		[page:Geometry geometry] — required<br />
-		[page:Object instanceCtrl] — required. A collada <em>skinController</em><br />
-		[page:Integer frame] — optionnal. Default is 40<br />
-		</div>
-		<div>
-		Apply a skin (vertices, animation, bones) from a <em>collada skin controller</em>, on the given [page:Geometry].
-		</div>
-
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/ColladaLoader.js examples/js/loaders/ColladaLoader.js]
-	</body>
-</html>

+ 41 - 24
docs/examples/loaders/GLTF2Loader.html → docs/examples/loaders/GLTFLoader.html

@@ -11,9 +11,7 @@
 		[page:Loader] &rarr;
 		<h1>[name]</h1>
 
-		<div class="desc">
-		A loader for *glTF* 2.0 resources.
-		<br /><br />
+		<div class="desc"> A loader for loading <em>glTF 2.0</em> resource. <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)
@@ -25,7 +23,7 @@
 		<h2>Extensions</h2>
 
 		<div>
-		GLTF2Loader supports the following glTF extensions:
+		GLTFLoader supports the following glTF extensions:
 		</div>
 
 		<ul>
@@ -48,21 +46,40 @@
 		<h2>Example</h2>
 
 		<code>
-		// Instantiate a loader
-		var loader = new THREE.GLTF2Loader();
-
-		// Load a glTF resource
-		loader.load( 'models/gltf/duck/duck.gltf', function ( gltf ) {
-			scene.add( gltf.scene );
-
-			gltf.animations; // Array&lt;THREE.AnimationClip&gt;
-			gltf.scene;      // THREE.Scene
-			gltf.scenes;     // Array&lt;THREE.Scene&gt;
-			gltf.cameras;    // Array&lt;THREE.Camera&gt;
-		} );
-		</code>
-
-		[example:webgl_loader_gltf2]
+			// Instantiate a loader
+			var loader = new THREE.GLTFLoader();
+	
+			// Load a glTF resource
+			loader.load(
+				// resource URL
+				'models/gltf/duck/duck.gltf',
+				// called when the resource is loaded
+				function ( gltf ) {
+	
+					scene.add( gltf.scene );
+	
+					gltf.animations; // Array&lt;THREE.AnimationClip&gt;
+					gltf.scene; // THREE.Scene
+					gltf.scenes; // Array&lt;THREE.Scene&gt;
+					gltf.cameras; // Array&lt;THREE.Camera&gt;
+	
+				},
+				// called when loading is in progresses
+				function ( xhr ) {
+	
+					console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
+	
+				},
+				// called when loading has errors
+				function ( error ) {
+	
+					console.log( 'An error happened' );
+	
+				}
+			);
+			</code>
+
+		[example:webgl_loader_gltf]
 
 		<h2>Constructor</h2>
 
@@ -81,10 +98,10 @@
 
 		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<div>
-		[page:String url] — required<br />
-		[page:Function onLoad] — Will be called when load completes. The argument will be the loaded JSON response returned from [page:Function parse].<br />
-		[page:Function onProgress] — Will be called while load progresses. The argument will be the XMLHttpRequest instance, that contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
-		[page:Function onError] — Will be called when load errors.<br />
+		[page:String url] — A string containing the path/URL of the <em>.gltf</em> or <em>.glb</em> file.<br />
+		[page:Function onLoad] — (optional) A function to be called after the loading is successfully completed. The function receives the loaded JSON response returned from [page:Function parse].<br />
+		[page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, that contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
+		[page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives error as an argument.<br />
 		</div>
 		<div>
 		Begin loading from url and call the callback function with the parsed response content.
@@ -115,6 +132,6 @@
 
 		<h2>Source</h2>
 
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/GLTF2Loader.js examples/js/loaders/GLTF2Loader.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/GLTFLoader.js examples/js/loaders/GLTFLoader.js]
 	</body>
 </html>

+ 622 - 0
docs/examples/loaders/LoaderSupport.html

@@ -0,0 +1,622 @@
+<!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">Supporting classes for file loaders and web worker based loaders.</div>
+
+		<h2>Sub-Classes</h2>
+		[page:LoaderSupport.Builder]<br>
+		[page:LoaderSupport.LoadedMeshUserOverride]<br>
+		[page:LoaderSupport.WorkerSupport]<br>
+		[page:LoaderSupport.WorkerRunnerRefImpl]<br>
+		[page:LoaderSupport.WorkerDirector]<br>
+		[page:LoaderSupport.PrepData]<br>
+		[page:LoaderSupport.Commons]<br>
+		[page:LoaderSupport.Callbacks]<br>
+		[page:LoaderSupport.Validator]<br>
+		[page:LoaderSupport.ConsoleLogger]
+
+
+		<h2>Example</h2>
+
+		[example:webgl_loader_obj2_meshspray] - Example using [page:LoaderSupport.LoaderWorkerDirector] and [page:LoaderSupport.LoaderWorkerSupport].<br>
+
+		<h2>Classes</h2>
+		<br>
+
+		<a name="Builder"></a><h1>Builder</h1>
+		<h2>Constructor</h2>
+
+		<h3>Builder()</h3>
+		<div>
+			Builds one or many [page:Mesh] from one raw set of Arraybuffers, materialGroup descriptions and further parameters.
+			Supports vertex, vertexColor, normal, uv and index buffers.
+		</div>
+
+
+		<h2>Methods</h2>
+
+		<h3>[method:null setMaterials] ( Array of [page:Material materials] )</h3>
+		<div>
+			Array of [page:Material materials] - Array of [page:Material Materials]
+		</div>
+		<div>
+			Set materials loaded by any supplier of an Array of [page:Material Materials].
+		</div>
+
+
+		<h3>[method:Array buildMeshes] (Object payload)</h3>
+		<div>
+			[page:Object payload] - Raw mesh description (buffers, params, materials) used to build one to many meshes.
+		</div>
+		<div>
+			Builds one or multiple meshes from the data described in the payload (buffers, params, material info.
+		</div>
+		<br>
+		<br>
+
+
+		<a name="LoadedMeshUserOverride"></a><h1>LoadedMeshUserOverride</h1>
+		<h2>Constructor</h2>
+
+		<h3>LoadedMeshUserOverride( [page:Boolean disregardMesh], [page:BufferGeometry bufferGeometry] )</h3>
+		<div>
+			[page:Boolean disregardMesh] - Tell implementation to completely disregard this mesh<br>
+			[page:Boolean alteredMesh] - Tell implementation that mesh(es) have been altered or added
+		</div>
+		<div>
+			Object to return by callback onMeshAlter. Used to disregard a certain mesh or to return one to many meshes.
+		</div>
+
+
+		<h2>Methods</h2>
+
+		<h3>[method:null addMesh] ( [page:Mesh mesh] )</h3>
+		<div>
+			[page:Mesh mesh] - Mesh
+		</div>
+		<div>
+			Add a mesh created within callback.
+		</div>
+
+
+		<h3>[method:boolean isDisregardMesh] ()</h3>
+		<div>
+			Answers if mesh shall be disregarded completely.
+		</div>
+
+
+		<h3>[method:boolean providesAlteredMeshes] ()</h3>
+		<div>
+			Answers if new mesh(es) were created.
+		</div>
+		<br>
+		<br>
+
+
+		<a name="WorkerSupport"></a><h1>WorkerSupport</h1>
+		<h2>Constructor</h2>
+
+		<h3>WorkerSupport( [page:LoaderSupport.ConsoleLogger logger] )</h3>
+		<div>
+			[page:LoaderSupport.ConsoleLogger logger] - logger to be used
+		</div>
+		<div>
+			This class provides means to transform existing parser code into a web worker.
+			It defines a simple communication protocol which allows to configure the worker and receive raw mesh data during execution.
+		</div>
+
+
+		<h2>Methods</h2>
+
+		<h3>[method:null validate] ( [page:Function functionCodeBuilder], [page:Boolean forceWorkerReload], [page:LoaderSupport.WorkerRunnerRefImpl runnerImpl] )</h3>
+		<div>
+			[page:Function functionCodeBuilder] - Function that is invoked with funcBuildObject and funcBuildSingelton that allows stringification of objects and singletons.
+			[page:Boolean forceWorkerReload] - Force re-build of the worker code.
+			[page:LoaderSupport.WorkerRunnerRefImpl runnerImpl] - The default worker parser wrapper implementation (communication and execution). An extended class could be passed here.
+		</div>
+		<div>
+			Validate the status of worker code and the derived worker.
+		</div>
+
+
+		<h3>[method:null setTerminateRequested] ( [page:Boolean terminateRequested] )</h3>
+		<div>
+			[page:Boolean terminateRequested] - True or false.
+		</div>
+		<div>
+			Request termination of worker once parser is finished.
+		</div>
+
+
+		<h3>[method:null terminateWorker] ()</h3>
+		<div>
+			Terminate the worker and the code.
+		</div>
+
+
+		<h3>[method:null setCallbacks] ( [page:Function builder], [page:Function onLoad] )</h3>
+		<div>
+			[page:Function builder] - The builder function. Default is [page:LoaderSupport.Builder].
+			[page:Function onLoad] - The function that is called when parsing is complete.
+		</div>
+		<div>
+			Specify functions that should be build when new raw mesh data becomes available and when the parser is finished.
+		</div>
+
+
+		<h3>[method:null run] ( [page:Object payload] )</h3>
+		<div>
+			[page:Object payload] - Raw mesh description (buffers, params, materials) used to build one to many meshes.
+		</div>
+		<div>
+			Runs the parser with the provided configuration.
+		</div>
+		<br>
+		<br>
+
+
+		<a name="WorkerRunnerRefImpl"></a><h1>WorkerRunnerRefImpl</h1>
+		<h2>Constructor</h2>
+
+		<h3>WorkerRunnerRefImpl()</h3>
+		<div>
+			Default implementation of the WorkerRunner responsible for creation and configuration of the parser within the worker.
+		</div>
+
+
+		<h2>Methods</h2>
+
+		<h3>[method:null applyProperties] ( [page:Object parser], [page:Object params] )</h3>
+		<div>
+			[page:Object parser] - The parser instance
+			[page:Object params] - The parameter object
+		</div>
+		<div>
+			Applies values from parameter object via set functions or via direct assignment.
+		</div>
+
+
+		<h3>[method:null run] ( [page:Object payload] )</h3>
+		<div>
+			[page:Object payload] - Raw mesh description (buffers, params, materials) used to build one to many meshes.
+		</div>
+		<div>
+			Configures the Parser implementation according the supplied configuration object.
+		</div>
+		<br>
+		<br>
+
+
+		<a name="WorkerDirector"></a><h1>WorkerDirector</h1>
+		<h2>Constructor</h2>
+
+		<h3>WorkerDirector( [page:String classDef], [page:LoaderSupport.ConsoleLogger logger] )</h3>
+		<div>
+			[page:String classDef] - Class definition to be used for construction<br>
+			[page:LoaderSupport.ConsoleLogger logger] - logger to be used
+		</div>
+		<div>
+			Orchestrate loading of multiple OBJ files/data from an instruction queue with a configurable amount of workers (1-16).<br>
+			- Workflow:<br>
+			- prepareWorkers<br>
+			- enqueueForRun<br>
+			- processQueue<br>
+			- deregister
+		</div>
+
+
+		<h2>Methods</h2>
+
+		<h3>[method:null prepareWorkers]( [page:WWOBJLoader2.Callbacks globalCallbacks], [page:Number maxQueueSize], [page:Number maxWebWorkers] )</h3>
+		<div>
+			[page:LoaderSupport.Callbacks globalCallbacks] - Register global callbacks used by all web workers<br>
+			[page:Number maxQueueSize] - Set the maximum size of the instruction queue (1-1024)<br>
+			[page:Number maxWebWorkers] - Set the maximum amount of workers (1-16)
+		</div>
+		<div>
+			Create or destroy workers according limits. Set the name and register callbacks for dynamically created web workers.
+		</div>
+
+
+		<h3>[method:null enqueueForRun]( [page:LoaderSupport.PrepData runParams] )</h3>
+		<div>
+			[page:LoaderSupport.PrepData runParams]
+		</div>
+		<div>
+			Store run instructions in internal instructionQueue.
+		</div>
+
+
+		<h3>[method:null processQueue]()</h3>
+		<div>
+			Process the instructionQueue until it is depleted.
+		</div>
+
+
+		<h3>[method:null deregister]()</h3>
+		<div>
+			Terminate all workers.
+		</div>
+
+
+		<h3>[method:null getMaxQueueSize]()</h3>
+		<div>
+			Returns the maximum length of the instruction queue.
+		</div>
+
+
+		<h3>[method:null getMaxWebWorkers]()</h3>
+		<div>
+			Returns the maximum number of workers.
+		</div>
+
+
+		<h3>[method:null setCrossOrigin]( [page:String crossOrigin] )</h3>
+		<div>
+			[page:String crossOrigin] - CORS value
+		</div>
+		<div>
+			Sets the CORS string to be used.
+		</div>
+
+
+		<a name="PrepData"></a><h1>PrepData</h1>
+		<h2>Constructor</h2>
+
+		<h3>PrepData( [page:String modelName] )</h3>
+		<div>
+			[page:String modelName] - Overall name of the model
+		</div>
+		<div>
+			Configuration instructions to be used by run method.
+		</div>
+
+
+		<h2>Methods</h2>
+
+		<h3>[method:null setStreamMeshesTo] ( [page:Object3D streamMeshesTo] )</h3>
+		<div>
+			[page:Object3D streamMeshesTo] - Object already attached to scenegraph where new meshes will be attached to
+		</div>
+		<div>
+			Set the node where the loaded objects will be attached directly.
+		</div>
+
+
+		<h3>[method:null setMaterialPerSmoothingGroup] ( [page:boolean materialPerSmoothingGroup] )</h3>
+		<div>
+			[page:boolean materialPerSmoothingGroup]
+		</div>
+		<div>
+			Tells whether a material shall be created per smoothing group.
+		</div>
+
+
+		<h3>[method:null setUseIndices]( [page:Boolean useIndices] )</h3>
+		<div>
+			[page:Boolean useIndices] - Default is false
+		</div>
+		<div>
+			Instructs loaders to create indexed [page:BufferGeometry].
+		</div>
+
+
+		<h3>[method:null setDisregardNormals]( [page:Boolean disregardNormals] )</h3>
+		<div>
+			[page:Boolean disregardNormals]
+		</div>
+		<div>
+			Tells whether normals should be completely disregarded and regenerated.
+		</div>
+
+
+		<h3>[method:Callbacks getCallbacks]()</h3>
+		<div>
+			Returns all callbacks as [page:LoaderSupport.Callbacks].
+		</div>
+
+
+		<h3>[method:null setCrossOrigin]( [page:String crossOrigin] )</h3>
+		<div>
+			[page:String crossOrigin] - CORS value
+		</div>
+		<div>
+			Sets the CORS string to be used.
+		</div>
+
+
+		<h3>[method:null addResource]( [page:LoaderSupport.ResourceDescriptor resource] )</h3>
+		<div>
+			[page:LoaderSupport.ResourceDescriptor resource]
+		</div>
+		<div>
+			Add a resource description.
+		</div>
+
+
+		<h3>[method:null setUseAsync]( [page:Boolean useAsync] )</h3>
+		<div>
+			[page:Boolean useAsync]
+		</div>
+		<div>
+			If true uses async loading with worker, if false loads data synchronously.
+		</div>
+		<br>
+		<br>
+
+
+		<a name="Commons"></a><h1>Commons</h1>
+		<h2>Constructor</h2>
+
+		<h3>Commons( [page:LoaderSupport.ConsoleLogger logger], [page:LoadingManager manager] )</h3>
+		<div>
+			[page:LoaderSupport.ConsoleLogger logger] - logger to be used
+			[page:LoadingManager manager] - The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager].
+		</div>
+		<div>
+			Base class to be used by loaders.
+		</div>
+
+
+		<h2>Methods</h2>
+
+		<h3>[method:ConsoleLogger getLogger] ()</h3>
+		<div>
+			Returns [page:LoaderSupport.ConsoleLogger].
+		</div>
+
+
+		<h3>[method:null setModelName] ( [page:String modelName] )</h3>
+		<div>
+			[page:String modelName]
+		</div>
+		<div>
+			Set the name of the model.
+		</div>
+
+
+		<h3>[method:null setPath] ( [page:String path] )</h3>
+		<div>
+			[page:String path] - URL
+		</div>
+		<div>
+			The URL of the base path.
+		</div>
+
+
+		<h3>[method:null setStreamMeshesTo] ( [page:Object3D streamMeshesTo] )</h3>
+		<div>
+			[page:Object3D streamMeshesTo] - Object already attached to scenegraph where new meshes will be attached to
+		</div>
+		<div>
+			Set the node where the loaded objects will be attached directly.
+		</div>
+
+
+		<h3>[method:null setMaterials] ( Array of [page:Material materials] )</h3>
+		<div>
+			Array of [page:Material materials] - Array of [page:Material Materials]
+		</div>
+		<div>
+			Set materials loaded by MTLLoader or any other supplier of an Array of [page:Material Materials].
+		</div>
+
+
+		<h3>[method:null setUseIndices]( [page:Boolean useIndices] )</h3>
+		<div>
+			[page:Boolean useIndices]
+		</div>
+		<div>
+			Instructs loaders to create indexed [page:BufferGeometry].
+		</div>
+
+
+		<h3>[method:null setDisregardNormals]( [page:Boolean disregardNormals] )</h3>
+		<div>
+			[page:Boolean disregardNormals]
+		</div>
+		<div>
+			Tells whether normals should be completely disregarded and regenerated.
+		</div>
+
+
+		<h3>[method:null onProgress]( [page:String type], [page:String text], [page:Number numericalValue] )</h3>
+		<div>
+			[page:String type] - The type of event<br>
+			[page:String text] - Textual description of the event<br>
+			[page:Number numericalValue] - Numerical value describing the progress
+		</div>
+		<div>
+			Announce feedback which is give to the registered [page:LoaderSupport.Callbacks].
+		</div>
+		<br>
+		<br>
+
+
+		<a name="Callbacks"></a><h1>Callbacks</h1>
+		<h2>Constructor</h2>
+
+		<h3>Callbacks()</h3>
+		<div>
+			Callbacks utilized by loaders and builder.
+		</div>
+
+
+		<h2>Methods</h2>
+
+		<h3>[method:null setCallbackOnProgress]( [page:Function callbackOnProgress] )</h3>
+		<div>
+			[page:Function callbackOnProgress] - Callback function for described functionality
+		</div>
+		<div>
+			Register callback function that is invoked by internal function "announceProgress" to print feedback.
+		</div>
+
+
+		<h3>[method:null setCallbackOnMeshAlter]( [page:Function callbackOnMeshAlter] )</h3>
+		<div>
+			[page:Function callbackOnMeshAlter] - Callback function for described functionality
+		</div>
+		<div>
+			Register callback function that is called every time a mesh was loaded.
+			Use [page:LoadedMeshUserOverride] for alteration instructions (geometry, material or disregard mesh).
+		</div>
+
+
+		<h3>[method:null setCallbackOnLoad]( [page:Function callbackOnLoad] )</h3>
+		<div>
+			[page:Function callbackOnLoad] - Callback function for described functionality
+		</div>
+		<div>
+			Register callback function that is called once loading of the complete OBJ file is completed.
+		</div>
+		<br>
+		<br>
+
+
+		<a name="Validator"></a><h1>Validator</h1>
+		<h2>Constructor</h2>
+
+		<h3>Validator()</h3>
+		<div>
+			Validation functions.
+		</div>
+
+
+		<h2>Methods</h2>
+
+		<h3>[method:null isValid]( [page:Object input] )</h3>
+		<div>
+			[page:Object input] - Can be anything
+		</div>
+		<div>
+			If given input is null or undefined, false is returned otherwise true.
+		</div>
+
+
+		<h3>[method:null verifyInput]( [page:Object input], [page:Object defaultValue] )</h3>
+		<div>
+			[page:Object input] - Can be anything
+			[page:Object defaultValue] - Can be anything
+		</div>
+		<div>
+			If given input is null or undefined, the defaultValue is returned otherwise the given input.
+		</div>
+		<br>
+		<br>
+
+
+		<a name="ConsoleLogger"></a><h1>ConsoleLogger</h1>
+		<h2>Constructor</h2>
+
+		<h3>ConsoleLogger( [page:Boolean enabled], [page:Boolean debug] )</h3>
+		<div>
+			[page:Boolean enabled] - Tell if logger is enabled.
+			[page:Boolean debug] - Toggle debug logging.
+		<div>
+			Logging wrapper for console.
+		</div>
+
+
+		<h2>Methods</h2>
+
+		<h3>[method:null setDebug]( [page:Boolean debug] )</h3>
+		<div>
+			[page:Boolean debug] - True or False
+		</div>
+		<div>
+			Enable or disable debug logging.
+		</div>
+
+
+		<h3>[method:Boolean isDebug]()</h3>
+		<div>
+			Returns if is enabled and debug.
+		</div>
+
+		<h3>[method:null setEnabled]( [page:Boolean enabled] )</h3>
+		<div>
+			[page:Boolean enabled] - True or False
+		</div>
+		<div>
+			Enable or disable info, debug and time logging.
+		</div>
+
+
+		<h3>[method:Boolean isEnabled]()</h3>
+		<div>
+			Returns if is enabled.
+		</div>
+
+
+		<h3>[method:null logDebug]( [page:String message] )</h3>
+		<div>
+			[page:String message] - Message to log
+		</div>
+		<div>
+			Log a debug message if enabled and debug is set.
+		</div>
+
+
+		<h3>[method:null logInfo]( [page:String message] )</h3>
+		<div>
+			[page:String message] - Message to log
+		</div>
+		<div>
+			Log an info message if enabled.
+		</div>
+
+
+		<h3>[method:null logWarn]( [page:String message] )</h3>
+		<div>
+			[page:String message] - Message to log
+		</div>
+		<div>
+			Log a warn message (always).
+		</div>
+
+
+		<h3>[method:null logError]( [page:String message] )</h3>
+		<div>
+			[page:String message] - Message to log
+		</div>
+		<div>
+			Log an error message (always).
+		</div>
+
+
+		<h3>[method:null logTimeStart]( [page:String id] )</h3>
+		<div>
+			[page:String id] - Time identification
+		</div>
+		<div>
+			Start time measurement with provided id.
+		</div>
+
+
+		<h3>[method:null logTimeEnd]( [page:String id] )</h3>
+		<div>
+			[page:String id] - Time identification
+		</div>
+		<div>
+			Stop time measurement started with provided id.
+		</div>
+		<br>
+		<br>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/LoaderSupport.js examples/js/loaders/LoaderSupport.js]
+
+	</body>
+</html>

+ 9 - 6
docs/examples/loaders/MTLLoader.html

@@ -11,7 +11,10 @@
 
 		<h1>[name]</h1>
 
-		<div class="desc">A loader for loading an <em>.mtl</em> resource, used internaly by [page:OBJMTLLoader] and [page:UTF8Loader].</div>
+		<div class="desc">A loader for loading an <em>.mtl</em> resource, used internaly by [page:OBJMTLLoader] and [page:UTF8Loader].<br />
+		The Material Template Library format (MTL) or .MTL File Format is a companion file format to .OBJ that describes surface shading
+		(material) properties of objects within one or more .OBJ files. 		
+		</div>
 
 		<h2>Constructor</h2>
 
@@ -23,7 +26,7 @@
 			Creates a new [name].
 		</div>
 
-		<!-- <h2>Properties</h2> -->
+		<h2>Properties</h2>
 
 
 		<h2>Methods</h2>
@@ -31,10 +34,10 @@
 
 		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<div>
-			[page:String url] — required<br />
-			[page:Function onLoad] — Will be called when load completes. The argument will be the loaded [page:MTLLoaderMaterialCreator MTLLoader.MaterialCreator] instance.<br />
-			[page:Function onProgress] — Will be called while load progresses. The argument will be the XMLHttpRequest instance, which contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
-			[page:Function onError] — Will be called when load errors.<br />
+			[page:String url] — A string containing the path/URL of the <em>.mtl</em> file.<br />
+			[page:Function onLoad] — (optional) A function to be called after the loading is successfully completed. The function receives the loaded [page:MTLLoaderMaterialCreator MTLLoader.MaterialCreator] instance.<br />
+			[page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains [page:Integer total] and [page:Integer loaded] bytes.<br />
+			[page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives the error as an argument.<br />
 		</div>
 		<div>
 			Begin loading from url and return the loaded material.

+ 40 - 21
docs/examples/loaders/OBJLoader.html

@@ -11,27 +11,46 @@
 
 		<h1>[name]</h1>
 
-		<div class="desc">A loader for loading an <em>.obj</em> resource.</div>
+		<div class="desc">A loader for loading a <em>.obj</em> resource.<br />
+		The <a href="https://en.wikipedia.org/wiki/Wavefront_.obj_file">OBJ file format</a> is a simple data-format 
+		that represents 3D geometry in a human redeable format as, the position of each vertex, the UV position of 
+		each texture coordinate vertex, vertex normals, and the faces that make each polygon defined as a list of 
+		vertices, and texture vertices.
+		</div>
+
+
+		<h2>Example</h2>
+
+		<code>
+		// instantiate a loader
+		var loader = new THREE.OBJLoader();
+
+		// load a resource
+		loader.load(
+			// resource URL
+			'models/monster.obj',
+			// called when resource is loaded
+			function ( object ) {
+
+				scene.add( object );
+
+			},
+			// called when loading is in progresses
+			function ( xhr ) {
 
+				console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
 
-				<h2>Example</h2>
+			},
+			// called when loading has errors
+			function ( error ) {
 
-				<code>
-				// instantiate a loader
-				var loader = new THREE.OBJLoader();
+				console.log( 'An error happened' );
 
-				// load a resource
-				loader.load(
-					// resource URL
-					'models/monster.obj',
-					// Function when resource is loaded
-					function ( object ) {
-						scene.add( object );
-					}
-				);
-				</code>
+			}
+		);
+		</code>
 
-				[example:webgl_loader_obj]
+		[example:webgl_loader_obj]
 
 
 		<h2>Constructor</h2>
@@ -51,10 +70,10 @@
 
 		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<div>
-		[page:String url] — required<br />
-		[page:Function onLoad] — Will be called when load completes. The argument will be the loaded [page:Object3D].<br />
-		[page:Function onProgress] — Will be called while load progresses. The argument will be the XMLHttpRequest instance, which contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
-		[page:Function onError] — Will be called when load errors.<br />
+		[page:String url] — A string containing the path/URL of the <em>.obj</em> file.<br />
+		[page:Function onLoad] — (optional) A function to be called after the loading is successfully completed. The function receives the loaded [page:Object3D] as an argument.<br />
+		[page:Function onProgress] — (optional) A function to be called while the loading is in progress. The function receives a XMLHttpRequest instance, which contains [page:Integer total] and [page:Integer loaded] bytes.<br />
+		[page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives error as an argument.<br />
 		</div>
 		<div>
 		Begin loading from url and call onLoad with the parsed response content.
@@ -67,7 +86,7 @@
 		<div>
 		Returns an [page:Object3D]. It contains the parsed meshes as [page:Mesh] and lines as [page:LineSegments].<br />
 		All geometry is created as [page:BufferGeometry]. Default materials are created as [page:MeshPhongMaterial].<br />
-		If an <em>obj</em> object or group uses multiple materials while declaring faces geometry groups and an array of materials are used.
+		If an <em>obj</em> object or group uses multiple materials while declaring faces, geometry groups and an array of materials are used.
 		</div>
 
 		<h2>Source</h2>

+ 92 - 35
docs/examples/loaders/OBJLoader2.html

@@ -11,100 +11,157 @@
 
 		<h1>[name]</h1>
 
-		<div class="desc">A loader for loading an <em>.obj</em> resource.</div>
+		<div class="desc">A loader for loading a <em>.obj</em> resource. <br />
+		The <a href="https://en.wikipedia.org/wiki/Wavefront_.obj_file">OBJ file format</a> is a simple data-format 
+		that represents 3D geometry in a human redeable format as, the position of each vertex, the UV position of 
+		each texture coordinate vertex, vertex normals, and the faces that make each polygon defined as a list of 
+		vertices, and texture vertices.
+		</div>
 
-		<h2>Example</h2>
+		<h2>Examples</h2>
 
 		<code>
 		// instantiate the loader
 		var loader = new THREE.OBJLoader2();
 
 		// function called on successful load
-		var intergrateIntoScene = function ( object ) {
-			scene.add( object );
+		var callbackOnLoad = function ( event ) {
+			scene.add( event.detail.loaderRootNode );
 		};
 
-		// load a resource from provided URL
-		loader.load( 'obj/female02/female02.obj', intergrateIntoScene );
+		// load a resource from provided URL synchronously
+		loader.load( 'obj/female02/female02.obj', callbackOnLoad, null, null, null, false );
 		</code>
 
-		[example:webgl_loader_obj2]
+		[example:webgl_loader_obj2] - Simple example <br>
+		[example:webgl_loader_obj2_options] - Example for multiple use-cases (parse, load and run with instructions (sync and async)<br>
+		[example:webgl_loader_obj2_run_director] - Advanced example using [page:LoaderSupport.LoaderWorkerDirector] for orchestration of multiple workers.
 
 
 		<h2>Constructor</h2>
 
 		<h3>[name]( [page:LoadingManager manager] )</h3>
 		<div>
-		[page:LoadingManager manager] — The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager].
+			[page:LoadingManager manager] - The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager].
 		</div>
 		<div>
 			Use [name] to load OBJ data from files or to parse OBJ data from arraybuffer or text.
 		</div>
 
-		<h2>Properties</h2>
-
 
 		<h2>Methods</h2>
 
-		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError], [page:Boolean useArrayBuffer] )</h3>
+		<h3>[method:Object3D parse]( {[page:arraybuffer content]|[page:String content]] )</h3>
 		<div>
-			[page:String url] — URL of the file to load<br />
-			[page:Function onLoad] — Called after loading was successfully completed. The argument will be the loaded [page:Object3D].<br />
-			[page:Function onProgress] — Called to report progress of loading. The argument will be the XMLHttpRequest instance, which contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
-			[page:Function onError]  Called after an error occurred during loading.<br />
-			[page:boolean useArrayBuffer] — Set this to false to force string based parsing<br />
+			[[page:arraybuffer content]|[page:String content]] OBJ data as Uint8Array or String
 		</div>
 		<div>
-			Use this convenient method to load an OBJ file at the given URL. Per default the fileLoader uses an arraybuffer
+			Parses OBJ data synchronously from arraybuffer or string and returns the [page:Object3D loaderRoorNode].
 		</div>
 
-		<h3>[method:Object3D parse]( [page:ArrayBuffer arrayBuffer] )</h3>
+
+		<h3>[method:Object3D parseAsync]( [page:arraybuffer content], [page:Function onLoad] )</h3>
 		<div>
-			[page:ArrayBuffer arrayBuffer] — OBJ data as Uint8Array
+			[page:arraybuffer content] - OBJ data as Uint8Array<br>
+			[page:Function onLoad] - Called after worker successfully completed loading<br>
 		</div>
 		<div>
-			Default parse function: Parses OBJ file content stored in arrayBuffer and returns the [page:Object3D sceneGraphBaseNode].
+			Parses OBJ content asynchronously from arraybuffer.
 		</div>
 
-		<h3>[method:Object3D parseText]( [page:String test] )</h3>
+
+		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError], [page:Function onMeshAlter], [page:boolean useAsync] )</h3>
 		<div>
-			[page:String text] — OBJ data as string
+			[page:String url] - A string containing the path/URL of the <em>.obj</em> file.<br>
+			[page:Function onLoad] - (optional) A function to be called after loading is successfully completed. The function receives loaded [page:Object3D] as an argument.<br>
+			[page:Function onProgress] - (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains [page:Integer total] and [page:Integer loaded] bytes.<br>
+			[page:Function onError] - (optional) A function to be called if an error occurrs during loading. The function receives the error as an argument.<br>
+			[page:Function onMeshAlter] - (optional) A function to be called after a new mesh raw data becomes available for alteration.<br>
+			[page:boolean useAsync] - (optional) If true, uses async loading with worker, if false loads data synchronously.
 		</div>
 		<div>
-			Legacy parse function: Parses OBJ file content stored in string and returns the [page:Object3D sceneGraphBaseNode].
+			Use this convenient method to load an OBJ file at the given URL. By default the fileLoader uses an arraybuffer.
 		</div>
 
-		<h3>[method:null setMaterials] ( Array of [page:Material materials] )</h3>
+
+		<h3>[method:null run]( [page:LoaderSupport.PrepData params], [page:LoaderSupport.WorkerSupport workerSupportExternal] )</h3>
 		<div>
-			Array of [page:Material materials] — Array of [page:Material Materials] from MTLLoader
+			[page:LoaderSupport.PrepData params] - prepData All parameters and resources required for execution<br>
+			[page:LoaderSupport.WorkerSupport workerSupportExternal] - Use pre-existing WorkerSupport
 		</div>
 		<div>
-			Set materials loaded by MTLLoader or any other supplier of an Array of [page:Material Materials].
+			Run the loader according the provided instructions.
 		</div>
 
+
+		<h3>[method:null setMaterialPerSmoothingGroup] ( [page:boolean materialPerSmoothingGroup] )</h3>
+		<div>
+			[page:boolean materialPerSmoothingGroup]
+		</div>
+		<div>
+			Tells whether a material shall be created per smoothing group.
+		</div>
+
+
+		<h2>The following methods are inherited from [page:LoaderSupport.Commons]</h2>
+
+		<h3>[method:ConsoleLogger getLogger] ()</h3>
+		<div>
+			Returns [page:LoaderSupport.ConsoleLogger].
+		</div>
+
+
+		<h3>[method:null setModelName] ( [page:String modelName] )</h3>
+		<div>
+			[page:String modelName]
+		</div>
+		<div>
+			Set the name of the model.
+		</div>
+
+
 		<h3>[method:null setPath] ( [page:String path] )</h3>
 		<div>
-			[page:String path] — The basePath
+			[page:String path] - URL
+		</div>
+		<div>
+			The URL of the base path.
+		</div>
+
+
+		<h3>[method:null setStreamMeshesTo] ( [page:Object3D streamMeshesTo] )</h3>
+		<div>
+			[page:Object3D streamMeshesTo] - Object already attached to scenegraph where new meshes will be attached to
 		</div>
 		<div>
-			Base path to use.
+			Set the node where the loaded objects will be attached directly.
 		</div>
 
-		<h3>[method:null setSceneGraphBaseNode] ( [page:Object3D sceneGraphBaseNode] )</h3>
+
+		<h3>[method:null setMaterials] ( Array of [page:Material materials] )</h3>
+		<div>
+			Array of [page:Material materials] - Array of [page:Material Materials]
+		</div>
+		<div>
+			Set materials loaded by MTLLoader or any other supplier of an Array of [page:Material Materials].
+		</div>
+
+
+		<h3>[method:null setUseIndices]( [page:Boolean useIndices] )</h3>
 		<div>
-			[page:Object3D sceneGraphBaseNode] — Scenegraph object where meshes will be attached
+			[page:Boolean useIndices]
 		</div>
 		<div>
-			Set the node where the loaded objects will be attached.
+			Instructs loaders to create indexed [page:BufferGeometry].
 		</div>
 
-		<h3>[method:null setDebug]( [page:Boolean parserDebug], [page:Boolean meshCreatorDebug] )</h3>
+
+		<h3>[method:null setDisregardNormals]( [page:Boolean disregardNormals] )</h3>
 		<div>
-			[page:Boolean parserDebug] — Internal Parser will produce debug output<br>
-			[page:Boolean meshCreatorDebug] — Internal MeshCreator will produce debug output
+			[page:Boolean disregardNormals]
 		</div>
 		<div>
-			Allows to set debug mode for the parser and the meshCreator.
+			Tells whether normals should be completely disregarded and regenerated.
 		</div>
 
 		<h2>Source</h2>

+ 24 - 8
docs/examples/loaders/PCDLoader.html

@@ -11,8 +11,10 @@
 
 		<h1>[name]</h1>
 
-		<div class="desc">A loader for <em>PCD</em> files. Loads ascii and binary.
-			Compressed binary files are not supported.</div>
+		<div class="desc">A loader for loading a <em>.pcd</em> resource. <br />
+		Point Cloud Data is a file format for <a href="https://en.wikipedia.org/wiki/Point_Cloud_Library">Point Cloud Library</a>. <br />
+		Loader support ascii and binary. Compressed binary files are not supported.
+		</div>
 
 		<h2>Example</h2>
 
@@ -24,10 +26,24 @@
 		// load a resource
 		loader.load(
 			// resource URL
-			'pointcloud.pcd' ,
-			// Function when resource is loaded
+			'pointcloud.pcd',
+			// called when the resource is loaded
 			function ( mesh ) {
+
 				scene.add( mesh );
+
+			},
+			// called when loading is in progresses
+			function ( xhr ) {
+
+				console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
+
+			},
+			// called when loading has errors
+			function ( error ) {
+
+				console.log( 'An error happened' );
+
 			}
 		);
 		</code>
@@ -56,10 +72,10 @@
 
 		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<div>
-		[page:String url] — required<br />
-		[page:Function onLoad] — Will be called when load completes. The argument will be the loaded [page:Object3D].<br />
-		[page:Function onProgress] — Will be called while load progresses. The argument will be the XMLHttpRequest instance, which contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
-		[page:Function onError] — Will be called when load errors.<br />
+		[page:String url] — A string containing the path/URL of the <em>.pcd</em> file.<br />
+		[page:Function onLoad] — (optional) A function to be called after loading is successfully completed. The function receives loaded [page:Object3D] as an argument.<br />
+		[page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains [page:Integer total] and [page:Integer loaded] bytes.<br />
+		[page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives the error as an argument.<br />
 		</div>
 		<div>
 		Begin loading from url and call onLoad with the parsed response content.

+ 23 - 25
docs/examples/loaders/PDBLoader.html

@@ -11,10 +11,8 @@
 
 		<h1>[name]</h1>
 
-		<div class="desc">
-		A loader for loading a <em>.pdb</em> resource.
-		<br /><br />
-		The <a href="http://en.wikipedia.org/wiki/Protein_Data_Bank_(file_format)">Protein Data Bank file format</a> is a textual file format describing the three-dimensional structures of molecules.
+		<div class="desc">A loader for loading a <em>.pdb</em> resource.<br>
+		The <a href="http://en.wikipedia.org/wiki/Protein_Data_Bank_(file_format)">Protein Data Bank</a> file format is a textual file describing the three-dimensional structures of molecules.
 		</div>
 
 		<h2>Example</h2>
@@ -27,17 +25,27 @@
 		loader.load(
 			// resource URL
 			'models/molecules/caffeine.pdb',
-			// Function when resource is loaded
-			function ( geometryAtoms, geometryBonds, json ) {
+			// called when the resource is loaded
+			function ( pdb ) {
+
+				var geometryAtoms = pdb.geometryAtoms;
+				var geometryBonds = pdb.geometryBonds;
+				var json = pdb.json;
+
 				console.log( 'This molecule has ' + json.atoms.length + ' atoms' );
+
 			},
-			// Function called when download progresses
+			// called when loading is in progresses
 			function ( xhr ) {
-				console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
+
+				console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
+
 			},
-			// Function called when download errors
-			function ( xhr ) {
+			// called when loading has errors
+			function ( error ) {
+
 				console.log( 'An error happened' );
+
 			}
 		);
 		</code>
@@ -62,16 +70,16 @@
 
 		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<div>
-		[page:String url] — required. URL to the <em>.pdb</em> file<br />
-		[page:Function onLoad] — Will be called when load completes. The arguments will be an [page:BufferGeometry geometryAtoms], [page:BufferGeometry geometryBonds] and the [page:Object JSON] structure.<br />
-		[page:Function onProgress] — Will be called while load progresses. The argument will be the XMLHttpRequest instance, which contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
-		[page:Function onError] — Will be called when load errors.<br />
+		[page:String url] — A string containing the path/URL of the <em>.pdb</em> file.<br />
+		[page:Function onLoad] — (optional) A function to be called after loading is successfully completed. The function receives the object having the following properties. [page:BufferGeometry geometryAtoms], [page:BufferGeometry geometryBonds] and the [page:Object JSON] structure.<br />
+		[page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains [page:Integer total] and [page:Integer loaded] bytes.<br />
+		[page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives the error as an argument.<br />
 		</div>
 		<div>
 		Begin loading from url and call onLoad with the parsed response content.
 		</div>
 
-		<h3>[method:Object parsePDB]( [page:String text] )</h3>
+		<h3>[method:Object parse]( [page:String text] )</h3>
 		<div>
 		[page:String text] — The textual <em>pdb</em> structure to parse.
 		</div>
@@ -79,16 +87,6 @@
 		Parse a <em>pdb</em> text and return a <em>JSON</em> structure.<br />
 		</div>
 
-		<h3>[method:null createModel]( [page:Object json], [page:Function callback] )</h3>
-		<div>
-		[page:Object json] — The <em>(JSON) pdb</em> structure to parse.<br />
-		[page:Function callback] — Will be called when parse completes, with three arguments: [page:BufferGeometry geometryAtoms], [page:BufferGeometry geometryBonds] and the original [page:Object json].<br />
-		</div>
-		<div>
-		Parse a <em>(JSON) pdb</em> structure and return two [page:BufferGeometry]: one for atoms, one for bonds.<br />
-		</div>
-
-
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/PDBLoader.js examples/js/loaders/PDBLoader.js]

+ 43 - 5
docs/examples/loaders/SVGLoader.html

@@ -11,9 +11,47 @@
 
 		<h1>[name]</h1>
 
-		<div class="desc">A loader for loading an <em>.svg</em> resource.</div>
+		<div class="desc">A loader for loading a <em>.svg</em> resource.<br >
+		<a href="https://en.wikipedia.org/wiki/Scalable_Vector_Graphics">Scalabe Vector Graphics</a> is an XML-based vector image format for two-dimensional graphics with support for interactivity and animation.			
+		</div>
+
+		<h2>Example</h2>
+		
+		<code>
+		// instantiate a loader
+		var loader = new THREE.PDBLoader();
+
+		// load a PDB resource
+		loader.load(
+			// resource URL
+			'models/molecules/caffeine.pdb',
+			// called when the resource is loaded
+			function ( pdb ) {
+
+				var geometryAtoms = pdb.geometryAtoms;
+				var geometryBonds = pdb.geometryBonds;
+				var json = pdb.json;
+
+				console.log( 'This molecule has ' + json.atoms.length + ' atoms' );
+
+			},
+			// called when loading is in progresses
+			function ( xhr ) {
+
+				console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
+
+			},
+			// called when loading has errors
+			function ( error ) {
+
+				console.log( 'An error happened' );
 
+			}
+		);
+		</code>
 
+		[example:webgl_loader_svg]
+		
 		<h2>Constructor</h2>
 
 		<h3>[name]( [page:LoadingManager manager] )</h3>
@@ -31,10 +69,10 @@
 
 		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<div>
-		[page:String url] — required<br />
-		[page:Function onLoad] — Will be called when load completes. The argument will be the loaded [page:SVGDocument].<br />
-		[page:Function onProgress] — Will be called while load progresses. The argument will be the XMLHttpRequest instance, which contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
-		[page:Function onError] — Will be called when load errors.<br />
+		[page:String url] — A string containing the path/URL of the <em>.svg</em> file.<br />
+		[page:Function onLoad] — (optional) A function to be called after loading is successfully completed. The function receives the loaded [page:SVGDocument] as an argument.<br />
+		[page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains [page:Integer total] and [page:Integer loaded] bytes.<br />
+		[page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives the error as an argument.<br />
 		</div>
 		<div>
 		Begin loading from url and call onLoad with the response content.

+ 19 - 12
docs/examples/loaders/TGALoader.html

@@ -10,8 +10,9 @@
 	<body>
 		<h1>[name]</h1>
 
-		<div class="desc">Class for loading a <em>.tga</em> [page:DataTexture texture].</div>
-
+		<div class="desc">A loader for loading a <em>.tga</em> resource. <br />
+		<a href="https://en.wikipedia.org/wiki/Truevision_TGA">TGA</a> is a raster graphics, image file format.
+		</div>
 
 		<h2>Example</h2>
 
@@ -23,20 +24,26 @@
 		var texture = loader.load(
 			// resource URL
 			'textures/crate_grey8.tga'
-			// Function when resource is loaded
+			// called when loading is completed
 			function ( texture ) {
+
 				console.log( 'Texture is loaded' );
+
 			},
-			// Function called when download progresses
+			// called when the loading is in progresses
 			function ( xhr ) {
-				console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
+
+				console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
+
 			},
-			// Function called when download errors
-			function ( xhr ) {
+			// called when the loading failes
+			function ( error ) {
+
 				console.log( 'An error happened' );
+
 			}
 		);
-
+		
 		var material = new THREE.MeshPhongMaterial( {
 			color: 0xffffff,
 			map: texture
@@ -60,10 +67,10 @@
 
 		<h3>[method:DataTexture load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<div>
-		[page:String url] — required<br />
-		[page:Function onLoad] — Will be called when load completes. The argument will be the loaded [page:DataTexture].<br />
-		[page:Function onProgress] — Will be called while load progresses. The argument will be the XMLHttpRequest instance, which contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
-		[page:Function onError] — Will be called when load errors.<br />
+		[page:String url] — A string containing the path/URL of the <em>.tga</em> file. <br />
+		[page:Function onLoad] — (optional) A function to be called after loading is successfully completed. The function receives loaded [page:DataTexture] as an argument.<br />
+		[page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
+		[page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives the error as an argument.<br />
 		</div>
 		<div>
 		Begin loading from url and pass the loaded [page:DataTexture texture] to onLoad. The [page:DataTexture texture] is also directly returned for immediate use (but may not be fully loaded).

+ 0 - 404
docs/examples/loaders/WWOBJLoader2.html

@@ -1,404 +0,0 @@
-<!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">A loader for loading an <em>.obj</em> resource within a web worker.</div>
-
-		<h2>Sub-Classes</h2>
-		[page:WWOBJLoader2.PrepDataArrayBuffer]<br>
-		[page:WWOBJLoader2.PrepDataFile]<br>
-		[page:WWOBJLoader2.PrepDataCallbacks]<br>
-		[page:WWOBJLoader2.LoadedMeshUserOverride]<br>
-		[page:WWOBJLoader2.WWOBJLoader2Director]
-
-		<h2>Example</h2>
-
-		<code>
-			// instantiate the loader
-			var loader = new THREE.OBJLoader2.WWOBJLoader2();
-
-			// load an OBJ file by providing a name, the path and the file name
-			var prepData = new THREE.OBJLoader2.WWOBJLoader2.PrepDataFile(
-				'female02',
-				'obj/female02/',
-				'female02.obj'
-			);
-
-			// set where to add the loaded data in the scene graph.
-			prepData.setSceneGraphBaseNode( scene );
-
-			// provide the preparation data to the loader and let it run.
-			loader.prepareRun( prepData );
-			loader.run();
-		</code>
-
-		[example:webgl_loader_obj2_ww] — Simple example that allows to load own models via file selection.<br>
-		[example:webgl_loader_obj2_ww_parallels] — Advanced example using [page:WWOBJLoader2.WWOBJLoader2Director] for orchestration of multiple workers.
-
-
-		<h2>Constructor</h2>
-
-		<h3>[name]()</h3>
-		<div>
-			OBJ data will be loaded by dynamically created web worker.<br>
-			First feed instructions with: [page:WWOBJLoader2.prepareRun prepareRun]<br>
-			Then execute with: [page:WWOBJLoader2.run run]
-		</div>
-
-		<h2>Properties</h2>
-
-
-		<h2>Methods</h2>
-
-		<h3>[method:null prepareRun]( [page:Object params] )</h3>
-		<div>
-			[page:Object params] — Either [page:WWOBJLoader2.PrepDataArrayBuffer] or [page:WWOBJLoader2.PrepDataFile]
-		</div>
-		<div>
-			Set all parameters for required for execution of [page:WWOBJLoader2.run run].
-		</div>
-
-
-		<h3>[method:null run]()</h3>
-		<div>
-			Run the loader according the preparation instruction provided in [page:WWOBJLoader2.prepareRun prepareRun].
-		</div>
-
-
-		<h3>[method:null setCrossOrigin]( [page:String crossOrigin] )</h3>
-		<div>
-			[page:String crossOrigin] — CORS value
-		</div>
-		<div>
-			Sets the CORS string to be used.
-		</div>
-
-
-		<h3>[method:null setDebug]( [page:Boolean enabled] )</h3>
-		<div>
-			[page:Boolean enabled] — True or false
-		</div>
-		<div>
-			Enable or disable debug logging.
-		</div>
-
-
-		<h3>[method:null setRequestTerminate]( [page:Boolean requestTerminate] )</h3>
-		<div>
-			[page:Boolean requestTerminate] — True or false
-		</div>
-		<div>
-			Call requestTerminate to terminate the web worker and free local resource after execution.
-		</div>
-
-
-		<h3>[method:null registerCallbackCompletedLoading]( [page:Function callbackCompletedLoading] )</h3>
-		<div>
-			[page:Function callbackCompletedLoading] — 	Callback function for described functionality
-		</div>
-		<div>
-			Register callback function that is called once loading of the complete model is completed.
-		</div>
-
-
-		<h3>[method:null registerCallbackProgress]( [page:Function callbackProgress] )</h3>
-		<div>
-			[page:Function callbackProgress] — 	Callback function for described functionality
-		</div>
-		<div>
-			Register callback function that is invoked by internal function "_announceProgress" to print feedback.
-		</div>
-
-
-		<h3>[method:null registerCallbackMaterialsLoaded]( [page:Function callbackMaterialsLoaded] )</h3>
-		<div>
-			[page:Function callbackMaterialsLoaded] — 	Callback function for described functionality
-		</div>
-		<div>
-			Register callback function that is called once materials have been loaded. It allows to alter and return materials.
-		</div>
-
-
-		<h3>[method:null registerCallbackMeshLoaded]( [page:Function callbackMeshLoaded] )</h3>
-		<div>
-			[page:Function callbackMeshLoaded] — 	Callback function for described functionality
-		</div>
-		<div>
-			Register callback function that is called every time a mesh was loaded. Use [page:WWOBJLoader2.LoadedMeshUserOverride] for alteration instructions (geometry, material or disregard mesh).
-		</div>
-
-		<h3>[method:null registerCallbackErrorWhileLoading]( [page:Function callbackErrorWhileLoading] )</h3>
-		<div>
-			[page:Function callbackErrorWhileLoading] — 	Callback function for described functionality
-		</div>
-		<div>
-			Register callback function that is called to report an error that prevented loading.
-		</div>
-
-
-		<h3>[method:null clearAllCallbacks]()</h3>
-		<div>
-			Clears all registered callbacks.
-		</div>
-
-
-		<h2>Sub-Classes</h2>
-		<br>
-		<a name="PrepDataArrayBuffer"></a><h1>PrepDataArrayBuffer</h1>
-		<h2>Constructor</h2>
-
-		<h3>PrepDataArrayBuffer( [page:String modelName], [page:Uint8Array objAsArrayBuffer], [page:String pathTexture], [page:String mtlAsString] )</h3>
-		<div>
-			[page:String modelName] — Overall name of the model<br>
-			[page:Uint8Array objAsArrayBuffer] — OBJ file content as ArrayBuffer<br>
-			[page:String pathTexture] — Path to texture files<br>
-			[page:String mtlAsString] — MTL file content as string
-		</div>
-		<div>
-			Instruction to configure [page:WWOBJLoader2.prepareRun] to load OBJ from given ArrayBuffer and MTL from given String.
-		</div>
-
-		<h2>Methods</h2>
-
-		<h3>[method:PrepDataCallbacks getCallbacks]()</h3>
-		<div>
-			Returns all callbacks as [page:WWOBJLoader2.PrepDataCallbacks].
-		</div>
-
-
-		<h3>[method:null setRequestTerminate]( [page:Boolean requestTerminate] )</h3>
-		<div>
-			[page:Boolean requestTerminate] — Default is false
-		</div>
-		<div>
-			Request termination of web worker and free local resources after execution.
-		</div>
-
-
-		<h3>[method:null setSceneGraphBaseNode]( [page:THREE.Object3D sceneGraphBaseNode] )</h3>
-		<div>
-			[page:Object3D sceneGraphBaseNode] — Scene graph object
-		</div>
-		<div>
-			[page:Object3D] where meshes will be attached.
-		</div>
-
-
-		<h3>[method:null setStreamMeshes]( [page:Boolean streamMeshes] )</h3>
-		<div>
-			[page:Boolean streamMeshes] — Default is true
-		</div>
-		<div>
-			Singles meshes are directly integrated into scene when loaded or later.
-		</div>
-		<br>
-		<br>
-
-
-		<a name="PrepDataFile"></a><h1>PrepDataFile</h1>
-		<h2>Constructor</h2>
-
-		<h3>PrepDataFile( [page:String modelName], [page:String pathObj], [page:String fileObj], [page:String pathTexture], [page:String fileMtl] )</h3>
-		<div>
-			[page:String modelName] — Overall name of the model<br>
-			[page:String pathObj] — Path to OBJ file<br>
-			[page:String fileObj] — OBJ file name<br>
-			[page:String pathTexture] — Path to texture files<br>
-			[page:String fileMtl] — MTL file name
-		</div>
-		<div>
-			Instruction to configure [page:WWOBJLoader2.prepareRun] to load OBJ and MTL from files.
-		</div>
-
-		<h2>Methods</h2>
-
-		<h3>[method:PrepDataCallbacks getCallbacks]()</h3>
-		<div>
-			Returns all callbacks as [page:WWOBJLoader2.PrepDataCallbacks].
-		</div>
-
-
-		<h3>[method:null setRequestTerminate]( [page:Boolean requestTerminate] )</h3>
-		<div>
-			[page:Boolean requestTerminate] — Default is false
-		</div>
-		<div>
-			Request termination of web worker and free local resources after execution.
-		</div>
-
-
-		<h3>[method:null setSceneGraphBaseNode]( [page:THREE.Object3D sceneGraphBaseNode] )</h3>
-		<div>
-			[page:Object3D sceneGraphBaseNode] — Scene graph object
-		</div>
-		<div>
-			[page:Object3D] where meshes will be attached.
-		</div>
-
-
-		<h3>[method:null setStreamMeshes]( [page:Boolean streamMeshes] )</h3>
-		<div>
-			[page:Boolean streamMeshes] — Default is true
-		</div>
-		<div>
-			Singles meshes are directly integrated into scene when loaded or later.
-		</div>
-		<br>
-		<br>
-
-
-		<a name="PrepDataCallbacks"></a><h1>PrepDataCallbacks</h1>
-		<h2>Constructor</h2>
-
-		<h3>PrepDataCallbacks()</h3>
-		<div>
-			Callbacks utilized by functions working with [page:WWOBJLoader2.PrepDataArrayBuffer] or [page:WWOBJLoader2.PrepDataFile].
-		</div>
-
-		<h2>Methods</h2>
-
-		<h3>[method:null registerCallbackCompletedLoading]( [page:Function callbackCompletedLoading] )</h3>
-		<div>
-			[page:Function callbackCompletedLoading] — Callback function for described functionality
-		</div>
-		<div>
-			Register callback function that is called once loading of the complete model is completed.
-		</div>
-
-
-		<h3>[method:null registerCallbackProgress]( [page:Function callbackProgress] )</h3>
-		<div>
-			[page:Function callbackProgress] — Callback function for described functionality
-		</div>
-		<div>
-			Register callback function that is invoked by internal function "_announceProgress" to print feedback.
-		</div>
-
-
-		<h3>[method:null registerCallbackErrorWhileLoading]( [page:Function callbackErrorWhileLoading] )</h3>
-		<div>
-			[page:Function callbackErrorWhileLoading] — Callback function for described functionality
-		</div>
-		<div>
-			Report if an error prevented loading.
-		</div>
-
-
-		<h3>[method:null registerCallbackMaterialsLoaded]( [page:Function callbackMaterialsLoaded] )</h3>
-		<div>
-			[page:Function callbackMaterialsLoaded] — Callback function for described functionality
-		</div>
-		<div>
-			Register callback function that is called once materials have been loaded. It allows to alter and return materials.
-		</div>
-
-
-		<h3>[method:null registerCallbackMeshLoaded]( [page:Function callbackMeshLoaded] )</h3>
-		<div>
-			[page:Function callbackMeshLoaded] — Callback function for described functionality
-		</div>
-		<div>
-			Register callback function that is called every time a mesh was loaded. Use [page:WWOBJLoader2.LoadedMeshUserOverride] for alteration instructions (geometry, material or disregard mesh).
-		</div>
-		<br>
-		<br>
-
-
-		<a name="LoadedMeshUserOverride"></a><h1>LoadedMeshUserOverride</h1>
-		<h2>Constructor</h2>
-
-		<h3>LoadedMeshUserOverride( [page:Boolean disregardMesh], [page:THREE.BufferGeometry bufferGeometry], [page:THREE.Material material] )</h3>
-		<div>
-			[page:Boolean disregardMesh] — Tell [page:WWOBJLoader2] to completely disregard this mesh<br>
-			[page:BufferGeometry bufferGeometry] — The [page:BufferGeometry] to be used<br>
-			[page:Material material] — The [page:Material] to be used
-		</div>
-		<div>
-			Object to return by THREE.OBJLoader2.WWOBJLoader2.callbacks.meshLoaded. Used to adjust bufferGeometry or material or prevent complete loading of mesh.
-		</div>
-		<br>
-		<br>
-
-
-		<a name="WWOBJLoader2Director"></a><h1>WWOBJLoader2Director</h1>
-		<h2>Constructor</h2>
-
-		<h3>WWOBJLoader2Director()</h3>
-		<div>
-			Orchestrate loading of multiple OBJ files/data from an instruction queue with a configurable amount of workers (1-16).<br>
-			Workflow:<br>
-				prepareWorkers<br>
-				enqueueForRun<br>
-				processQueue<br>
-				deregister
-		</div>
-
-		<h3>[method:null prepareWorkers]( [page:WWOBJLoader2.PrepDataCallbacks globalCallbacks], [page:Number maxQueueSize], [page:Number maxWebWorkers] )</h3>
-		<div>
-			[page:WWOBJLoader2.PrepDataCallbacks globalCallbacks] — Register global callbacks used by all web workers<br>
-			[page:Number maxQueueSize] — Set the maximum size of the instruction queue (1-1024)<br>
-			[page:Number maxWebWorkers] — Set the maximum amount of workers (1-16)
-		</div>
-		<div>
-			Create or destroy workers according limits. Set the name and register callbacks for dynamically created web workers.
-		</div>
-
-
-		<h3>[method:null enqueueForRun]( [page:Object runParams] )</h3>
-		<div>
-			[page:Object runParams] — Either [page:WWOBJLoader2.PrepDataArrayBuffer] or [page:WWOBJLoader2.PrepDataFile]
-		</div>
-		<div>
-			Store run instructions in internal instructionQueue.
-		</div>
-
-
-		<h3>[method:null processQueue]()</h3>
-		<div>
-			Process the instructionQueue until it is depleted.
-		</div>
-
-
-		<h3>[method:null deregister]()</h3>
-		<div>
-			Terminate all workers
-		</div>
-
-
-		<h3>[method:null getMaxQueueSize]()</h3>
-		<div>
-			Returns the maximum length of the instruction queue.
-		</div>
-
-
-		<h3>[method:null getMaxWebWorkers]()</h3>
-		<div>
-			Returns the maximum number of workers.
-		</div>
-
-
-		<h3>[method:null setCrossOrigin]( [page:String crossOrigin] )</h3>
-		<div>
-			[page:String crossOrigin] — CORS value
-		</div>
-		<div>
-			Sets the CORS string to be used.
-		</div>
-
-
-
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/OBJLoader2.js examples/js/loaders/OBJLoader2.js]
-
-	</body>
-</html>

+ 16 - 7
docs/list.js

@@ -103,7 +103,6 @@ var list = {
 		},
 
 		"Extras": {
-			"CurveUtils": "api/extras/CurveUtils",
 			"SceneUtils": "api/extras/SceneUtils",
 			"ShapeUtils": "api/extras/ShapeUtils"
 		},
@@ -112,6 +111,7 @@ var list = {
 			"Curve": "api/extras/core/Curve",
 			"CurvePath": "api/extras/core/CurvePath",
 			"Font": "api/extras/core/Font",
+			"Interpolations": "api/extras/core/Interpolations",
 			"Path": "api/extras/core/Path",
 			"Shape": "api/extras/core/Shape",
 			"ShapePath": "api/extras/core/ShapePath"
@@ -183,12 +183,14 @@ var list = {
 			"ArrowHelper": "api/helpers/ArrowHelper",
 			"AxisHelper": "api/helpers/AxisHelper",
 			"BoxHelper": "api/helpers/BoxHelper",
+			"Box3Helper": "api/helpers/Box3Helper",
 			"CameraHelper": "api/helpers/CameraHelper",
 			"DirectionalLightHelper": "api/helpers/DirectionalLightHelper",
 			"FaceNormalsHelper": "api/helpers/FaceNormalsHelper",
 			"GridHelper": "api/helpers/GridHelper",
 			"PolarGridHelper": "api/helpers/PolarGridHelper",
 			"HemisphereLightHelper": "api/helpers/HemisphereLightHelper",
+			"PlaneHelper": "api/helpers/PlaneHelper",
 			"PointLightHelper": "api/helpers/PointLightHelper",
 			"RectAreaLightHelper": "api/helpers/RectAreaLightHelper",
 			"SkeletonHelper": "api/helpers/SkeletonHelper",
@@ -333,27 +335,34 @@ var list = {
 
 	"Examples": {
 
+		"Controls": {
+			"OrbitControls": "examples/controls/OrbitControls"
+		},
+
 		"Geometries": {
 			"ConvexBufferGeometry": "examples/geometries/ConvexBufferGeometry",
-			"ConvexGeometry": "examples/geometries/ConvexGeometry"
+			"ConvexGeometry": "examples/geometries/ConvexGeometry",
+			"DecalGeometry": "examples/geometries/DecalGeometry"
 		},
 
 		"Loaders": {
 			"BabylonLoader": "examples/loaders/BabylonLoader",
-			"ColladaLoader": "examples/loaders/ColladaLoader",
-			"GLTF2Loader": "examples/loaders/GLTF2Loader",
+			"GLTFLoader": "examples/loaders/GLTFLoader",
 			"MTLLoader": "examples/loaders/MTLLoader",
 			"OBJLoader": "examples/loaders/OBJLoader",
 			"OBJLoader2": "examples/loaders/OBJLoader2",
-			"WWOBJLoader2": "examples/loaders/WWOBJLoader2",
+			"LoaderSupport": "examples/loaders/LoaderSupport",
 			"PCDLoader": "examples/loaders/PCDLoader",
 			"PDBLoader": "examples/loaders/PDBLoader",
 			"SVGLoader": "examples/loaders/SVGLoader",
 			"TGALoader": "examples/loaders/TGALoader"
 		},
 
+		"Exporters": {
+			"GLTFExporter": "examples/exporters/GLTFExporter"
+		},
+
 		"Plugins": {
-			"CombinedCamera": "examples/cameras/CombinedCamera",
 			"LookupTable": "examples/Lut",
 			"SpriteCanvasMaterial": "examples/SpriteCanvasMaterial"
 		},
@@ -391,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>
 

+ 1 - 1
docs/manual/introduction/Animation-system.html

@@ -111,7 +111,7 @@
 				<li>[page:ObjectLoader THREE.ObjectLoader]</li>
 				<li>THREE.BVHLoader</li>
 				<li>THREE.FBXLoader</li>
-				<li>[page:GLTF2Loader THREE.GLTF2Loader]</li>
+				<li>[page:GLTFLoader THREE.GLTFLoader]</li>
 				<li>THREE.MMDLoader</li>
 				<li>THREE.SEA3DLoader</li>
 			</ul>

+ 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>
-			Currenlty 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 - 1
docs/manual/introduction/Useful-links.html

@@ -47,7 +47,7 @@
 				[link:http://blog.cjgammon.com/ Collection of tutorials] by [link:http://www.cjgammon.com/ CJ Gammon].
 			</li>
 			<li>
-				<a href="https://medium.com/@soffritti.pierfrancesco/glossy-spheres-in-three-js-bfd2785d4857">Glossy spheres in three.js</a>.
+				[link:https://medium.com/@soffritti.pierfrancesco/glossy-spheres-in-three-js-bfd2785d4857] Glossy spheres in three.js.
 			</li>
 		 <li>
 			 [link:https://www.udacity.com/course/cs291 Interactive 3D Graphics] - a free course on Udacity that teaches the fundamentals of 3D Graphics,

+ 3 - 1
editor/css/dark.css

@@ -110,11 +110,13 @@ select {
 		}
 
 		#menubar .menu .options {
-			position: absolute;
+			position: fixed;
 			display: none;
 			padding: 5px 0;
 			background: #111;
 			width: 150px;
+			max-height: calc(100% - 80px);
+			overflow: auto;
 		}
 
 		#menubar .menu:hover .options {

+ 3 - 1
editor/css/light.css

@@ -106,11 +106,13 @@ select {
 		}
 
 		#menubar .menu .options {
-			position: absolute;
+			position: fixed;
 			display: none;
 			padding: 5px 0;
 			background: #eee;
 			width: 150px;
+			max-height: calc(100% - 80px);
+			overflow: auto;
 		}
 
 		#menubar .menu:hover .options {

+ 2 - 49
editor/index.html

@@ -21,9 +21,9 @@
 		<script src="../examples/js/loaders/AMFLoader.js"></script>
 		<script src="../examples/js/loaders/AWDLoader.js"></script>
 		<script src="../examples/js/loaders/BabylonLoader.js"></script>
-		<script src="../examples/js/loaders/ColladaLoader2.js"></script>
+		<script src="../examples/js/loaders/ColladaLoader.js"></script>
 		<script src="../examples/js/loaders/FBXLoader.js"></script>
-		<script src="../examples/js/loaders/GLTF2Loader.js"></script>
+		<script src="../examples/js/loaders/GLTFLoader.js"></script>
 		<script src="../examples/js/loaders/KMZLoader.js"></script>
 		<script src="../examples/js/loaders/MD2Loader.js"></script>
 		<script src="../examples/js/loaders/OBJLoader.js"></script>
@@ -85,8 +85,6 @@
 		<script src="js/Player.js"></script>
 		<script src="js/Script.js"></script>
 
-		<script src="../examples/js/effects/VREffect.js"></script>
-		<script src="../examples/js/controls/VRControls.js"></script>
 		<script src="../examples/js/vr/WebVR.js"></script>
 
 		<script src="js/Storage.js"></script>
@@ -392,51 +390,6 @@
 			}, false );
 			*/
 
-			// VR
-
-			var groupVR;
-
-			// TODO: Use editor.signals.enteredVR (WebVR 1.0)
-
-			editor.signals.enterVR.add( function () {
-
-				if ( groupVR === undefined ) {
-
-					groupVR = new THREE.HTMLGroup( viewport.dom );
-					editor.sceneHelpers.add( groupVR );
-
-					var mesh = new THREE.HTMLMesh( sidebar.dom );
-					mesh.position.set( 15, 0, 15 );
-					mesh.rotation.y = - 0.5;
-					groupVR.add( mesh );
-
-					var signals = editor.signals;
-
-					function updateTexture() {
-
-						mesh.material.map.update();
-
-					}
-
-					signals.objectSelected.add( updateTexture );
-					signals.objectAdded.add( updateTexture );
-					signals.objectChanged.add( updateTexture );
-					signals.objectRemoved.add( updateTexture );
-					signals.sceneGraphChanged.add( updateTexture );
-					signals.historyChanged.add( updateTexture );
-
-				}
-
-				groupVR.visible = true;
-
-			} );
-
-			editor.signals.exitedVR.add( function () {
-
-				if ( groupVR !== undefined ) groupVR.visible = false;
-
-			} );
-
 		</script>
 	</body>
 </html>

+ 0 - 7
editor/js/Editor.js

@@ -22,13 +22,6 @@ var Editor = function () {
 		startPlayer: new Signal(),
 		stopPlayer: new Signal(),
 
-		// vr
-
-		enterVR: new Signal(),
-
-		enteredVR: new Signal(),
-		exitedVR: new Signal(),
-
 		// actions
 
 		showModal: new Signal(),

+ 1 - 1
editor/js/Loader.js

@@ -176,7 +176,7 @@ var Loader = function ( editor ) {
 
 					var contents = event.target.result;
 
-					var loader = new THREE.GLTF2Loader();
+					var loader = new THREE.GLTFLoader();
 					loader.parse( contents, '', function ( result ) {
 
 						result.scene.name = filename;

+ 7 - 15
editor/js/Menubar.File.js

@@ -48,13 +48,19 @@ Menubar.File = function ( editor ) {
 
 	// Import
 
+	var form = document.createElement( 'form' );
+	form.style.display = 'none';
+	document.body.appendChild( form );
+
 	var fileInput = document.createElement( 'input' );
 	fileInput.type = 'file';
 	fileInput.addEventListener( 'change', function ( event ) {
 
 		editor.loader.loadFile( fileInput.files[ 0 ] );
+		form.reset();
 
 	} );
+	form.appendChild( fileInput );
 
 	var option = new UI.Row();
 	option.setClass( 'option' );
@@ -273,8 +279,6 @@ Menubar.File = function ( editor ) {
 
 			if ( vr ) {
 
-				includes.push( '<script src="js/VRControls.js"></script>' );
-				includes.push( '<script src="js/VREffect.js"></script>' );
 				includes.push( '<script src="js/WebVR.js"></script>' );
 
 			}
@@ -297,19 +301,7 @@ Menubar.File = function ( editor ) {
 
 		if ( vr ) {
 
-			loader.load( '../examples/js/controls/VRControls.js', function ( content ) {
-
-				zip.file( 'js/VRControls.js', content );
-
-			} );
-
-			loader.load( '../examples/js/effects/VREffect.js', function ( content ) {
-
-				zip.file( 'js/VREffect.js', content );
-
-			} );
-
-			loader.load( '../examples/js/WebVR.js', function ( content ) {
+			loader.load( '../examples/js/vr/WebVR.js', function ( content ) {
 
 				zip.file( 'js/WebVR.js', content );
 

+ 3 - 4
editor/js/Sidebar.Material.js

@@ -26,8 +26,8 @@ Sidebar.Material = function ( editor ) {
 
 	materialSlotRow.add( new UI.Text( 'Slot' ).setWidth( '90px' ) );
 
-	var materialSlotSelect =  new UI.Select().setWidth( '170px' ).setFontSize( '12px' ).onChange( update );
-
+	var materialSlotSelect = new UI.Select().setWidth( '170px' ).setFontSize( '12px' ).onChange( update );
+	materialSlotSelect.setOptions( { 0: '' } ).setValue( 0 );
 	materialSlotRow.add( materialSlotSelect );
 
 	container.add( materialSlotRow );
@@ -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;

+ 3 - 62
editor/js/Viewport.js

@@ -22,18 +22,6 @@ var Viewport = function ( editor ) {
 
 	var objects = [];
 
-	//
-
-	var vrEffect, vrControls;
-
-	if ( WEBVR.isAvailable() === true ) {
-
-		var vrCamera = new THREE.PerspectiveCamera();
-		vrCamera.projectionMatrix = camera.projectionMatrix;
-		camera.add( vrCamera );
-
-	}
-
 	// helpers
 
 	var grid = new THREE.GridHelper( 60, 60 );
@@ -283,12 +271,6 @@ var Viewport = function ( editor ) {
 
 	} );
 
-	signals.enterVR.add( function () {
-
-		vrEffect.isPresenting ? vrEffect.exitPresent() : vrEffect.requestPresent();
-
-	} );
-
 	signals.themeChanged.add( function ( value ) {
 
 		switch ( value ) {
@@ -345,19 +327,6 @@ var Viewport = function ( editor ) {
 
 		container.dom.appendChild( renderer.domElement );
 
-		if ( WEBVR.isAvailable() === true ) {
-
-			vrControls = new THREE.VRControls( vrCamera );
-			vrEffect = new THREE.VREffect( renderer );
-
-			window.addEventListener( 'vrdisplaypresentchange', function ( event ) {
-
-				effect.isPresenting ? signals.enteredVR.dispatch() : signals.exitedVR.dispatch();
-
-			}, false );
-
-		}
-
 		render();
 
 	} );
@@ -557,49 +526,21 @@ var Viewport = function ( editor ) {
 
 	//
 
-	function animate() {
-
-		requestAnimationFrame( animate );
-
-		if ( vrEffect && vrEffect.isPresenting ) {
-
-			render();
-
-		}
-
-	}
-
 	function render() {
 
 		sceneHelpers.updateMatrixWorld();
 		scene.updateMatrixWorld();
 
-		if ( vrEffect && vrEffect.isPresenting ) {
+		renderer.render( scene, camera );
 
-			vrControls.update();
+		if ( renderer instanceof THREE.RaytracingRenderer === false ) {
 
-			camera.updateMatrixWorld();
-
-			vrEffect.render( scene, vrCamera );
-			vrEffect.render( sceneHelpers, vrCamera );
-
-		} else {
-
-			renderer.render( scene, camera );
-
-			if ( renderer instanceof THREE.RaytracingRenderer === false ) {
-
-				renderer.render( sceneHelpers, camera );
-
-			}
+			renderer.render( sceneHelpers, camera );
 
 		}
 
-
 	}
 
-	requestAnimationFrame( animate );
-
 	return container;
 
 };

+ 13 - 13
editor/js/commands/SetMaterialColorCommand.js

@@ -10,7 +10,7 @@
  * @constructor
  */
 
-var SetMaterialColorCommand = function ( object, attributeName, newValue, slot ) {
+var SetMaterialColorCommand = function ( object, attributeName, newValue, materialSlot ) {
 
 	Command.call( this );
 
@@ -19,30 +19,30 @@ var SetMaterialColorCommand = function ( object, attributeName, newValue, slot )
 	this.updatable = true;
 
 	this.object = object;
-	this.attributeName = attributeName;
-	this.slot = slot;
-
-	var material = this.editor.getObjectMaterial( this.object, this.slot );
+	this.material = this.editor.getObjectMaterial( object, materialSlot );
 
-	this.oldValue = ( material !== undefined ) ? material[ this.attributeName ].getHex() : undefined;
+	this.oldValue = ( this.material !== undefined ) ? this.material[ attributeName ].getHex() : undefined;
 	this.newValue = newValue;
-	
+
+	this.attributeName = attributeName;
+
 };
 
 SetMaterialColorCommand.prototype = {
 
 	execute: function () {
-		var material = this.editor.getObjectMaterial( this.object, this.slot )
-		material[ this.attributeName ].setHex( this.newValue );
-		this.editor.signals.materialChanged.dispatch( material );
+
+		this.material[ this.attributeName ].setHex( this.newValue );
+
+		this.editor.signals.materialChanged.dispatch( this.material );
 
 	},
 
 	undo: function () {
-		var material = this.editor.getObjectMaterial( this.object, this.slot )
 
-		material[ this.attributeName ].setHex( this.oldValue );
-		this.editor.signals.materialChanged.dispatch( material );
+		this.material[ this.attributeName ].setHex( this.oldValue );
+
+		this.editor.signals.materialChanged.dispatch( this.material );
 
 	},
 

+ 6 - 13
editor/js/commands/SetMaterialCommand.js

@@ -10,7 +10,7 @@
  */
 
 
-var SetMaterialCommand = function ( object, newMaterial , slot) {
+var SetMaterialCommand = function ( object, newMaterial, materialSlot ) {
 
 	Command.call( this );
 
@@ -18,31 +18,25 @@ var SetMaterialCommand = function ( object, newMaterial , slot) {
 	this.name = 'New Material';
 
 	this.object = object;
+	this.materialSlot = materialSlot;
 
-	this.slot = slot;
-
-	var material = this.editor.getObjectMaterial( this.object, this.slot );
-
-	this.oldMaterial = material;
-
+	this.oldMaterial = this.editor.getObjectMaterial( object, materialSlot );
 	this.newMaterial = newMaterial;
-	
+
 };
 
 SetMaterialCommand.prototype = {
 
 	execute: function () {
-		
-		this.editor.setObjectMaterial( this.object, this.slot, this.newMaterial );
 
+		this.editor.setObjectMaterial( this.object, this.materialSlot, this.newMaterial );
 		this.editor.signals.materialChanged.dispatch( this.newMaterial );
 
 	},
 
 	undo: function () {
-		
-		this.editor.setObjectMaterial( this.object, this.slot, this.oldMaterial );
 
+		this.editor.setObjectMaterial( this.object, this.materialSlot, this.oldMaterial );
 		this.editor.signals.materialChanged.dispatch( this.oldMaterial );
 
 	},
@@ -67,7 +61,6 @@ SetMaterialCommand.prototype = {
 		this.oldMaterial = parseMaterial( json.oldMaterial );
 		this.newMaterial = parseMaterial( json.newMaterial );
 
-
 		function parseMaterial ( json ) {
 
 			var loader = new THREE.ObjectLoader();

+ 15 - 9
editor/js/commands/SetMaterialMapCommand.js

@@ -10,34 +10,40 @@
  * @constructor
  */
 
-var SetMaterialMapCommand = function ( object, mapName, newMap ) {
+var SetMaterialMapCommand = function ( object, mapName, newMap, materialSlot ) {
 
 	Command.call( this );
+
 	this.type = 'SetMaterialMapCommand';
 	this.name = 'Set Material.' + mapName;
 
 	this.object = object;
-	this.mapName = mapName;
-	this.oldMap = ( object !== undefined ) ? object.material[ mapName ] : undefined;
+	this.material = this.editor.getObjectMaterial( object, materialSlot );
+
+	this.oldMap = ( object !== undefined ) ? this.material[ mapName ] : undefined;
 	this.newMap = newMap;
 
+	this.mapName = mapName;
+
 };
 
 SetMaterialMapCommand.prototype = {
 
 	execute: function () {
 
-		this.object.material[ this.mapName ] = this.newMap;
-		this.object.material.needsUpdate = true;
-		this.editor.signals.materialChanged.dispatch( this.object.material );
+		this.material[ this.mapName ] = this.newMap;
+		this.material.needsUpdate = true;
+
+		this.editor.signals.materialChanged.dispatch( this.material );
 
 	},
 
 	undo: function () {
 
-		this.object.material[ this.mapName ] = this.oldMap;
-		this.object.material.needsUpdate = true;
-		this.editor.signals.materialChanged.dispatch( this.object.material );
+		this.material[ this.mapName ] = this.oldMap;
+		this.material.needsUpdate = true;
+
+		this.editor.signals.materialChanged.dispatch( this.material );
 
 	},
 

+ 13 - 13
editor/js/commands/SetMaterialValueCommand.js

@@ -10,21 +10,20 @@
  * @constructor
  */
 
-var SetMaterialValueCommand = function ( object, attributeName, newValue, slot ) {
+var SetMaterialValueCommand = function ( object, attributeName, newValue, materialSlot ) {
 
 	Command.call( this );
 
 	this.type = 'SetMaterialValueCommand';
 	this.name = 'Set Material.' + attributeName;
 	this.updatable = true;
-	this.slot = slot;
 
 	this.object = object;
+	this.material = this.editor.getObjectMaterial( object, materialSlot );
 
-	var material = this.editor.getObjectMaterial( this.object, this.slot );
-	
-	this.oldValue = ( material !== undefined ) ? material[ attributeName ] : undefined;
+	this.oldValue = ( this.material !== undefined ) ? this.material[ attributeName ] : undefined;
 	this.newValue = newValue;
+
 	this.attributeName = attributeName;
 
 };
@@ -32,21 +31,22 @@ var SetMaterialValueCommand = function ( object, attributeName, newValue, slot )
 SetMaterialValueCommand.prototype = {
 
 	execute: function () {
-		var material = this.editor.getObjectMaterial( this.object, this.slot );
-		material[ this.attributeName ] = this.newValue;
-		material.needsUpdate = true;
+
+		this.material[ this.attributeName ] = this.newValue;
+		this.material.needsUpdate = true;
+
 		this.editor.signals.objectChanged.dispatch( this.object );
-		this.editor.signals.materialChanged.dispatch( material );
+		this.editor.signals.materialChanged.dispatch( this.material );
 
 	},
 
 	undo: function () {
-		var material = this.editor.getObjectMaterial( this.object, this.slot );
 
-		material[ this.attributeName ] = this.oldValue;
-		material.needsUpdate = true;
+		this.material[ this.attributeName ] = this.oldValue;
+		this.material.needsUpdate = true;
+
 		this.editor.signals.objectChanged.dispatch( this.object );
-		this.editor.signals.materialChanged.dispatch( material );
+		this.editor.signals.materialChanged.dispatch( this.material );
 
 	},
 

+ 25 - 48
editor/js/libs/app.js

@@ -9,34 +9,29 @@ var APP = {
 		var loader = new THREE.ObjectLoader();
 		var camera, scene, renderer;
 
-		var controls, effect, cameraVR, isVR;
-
 		var events = {};
 
-		this.dom = document.createElement( 'div' );
+		var dom = document.createElement( 'div' );
+
+		this.dom = dom;
 
 		this.width = 500;
 		this.height = 500;
 
 		this.load = function ( json ) {
 
-			isVR = json.project.vr;
-
 			renderer = new THREE.WebGLRenderer( { antialias: true } );
 			renderer.setClearColor( 0x000000 );
 			renderer.setPixelRatio( window.devicePixelRatio );
 
-			if ( json.project.gammaInput ) renderer.gammaInput = true;
-			if ( json.project.gammaOutput ) renderer.gammaOutput = true;
-
-			if ( json.project.shadows ) {
-
-				renderer.shadowMap.enabled = true;
-				// renderer.shadowMap.type = THREE.PCFSoftShadowMap;
+			var project = json.project;
 
-			}
+			if ( project.gammaInput ) renderer.gammaInput = true;
+			if ( project.gammaOutput ) renderer.gammaOutput = true;
+			if ( project.shadows ) renderer.shadowMap.enabled = true;
+			if ( project.vr ) renderer.vr.enabled = true;
 
-			this.dom.appendChild( renderer.domElement );
+			dom.appendChild( renderer.domElement );
 
 			this.setScene( loader.parse( json.scene ) );
 			this.setCamera( loader.parse( json.camera ) );
@@ -116,26 +111,20 @@ var APP = {
 			camera.aspect = this.width / this.height;
 			camera.updateProjectionMatrix();
 
-			if ( isVR === true ) {
-
-				cameraVR = new THREE.PerspectiveCamera();
-				cameraVR.projectionMatrix = camera.projectionMatrix;
-				camera.add( cameraVR );
+			if ( renderer.vr.enabled ) {
 
-				controls = new THREE.VRControls( cameraVR );
-				effect = new THREE.VREffect( renderer );
+				WEBVR.checkAvailability().catch( function( message ) {
 
-				if ( WEBVR.isAvailable() === true ) {
+					dom.appendChild( WEBVR.getMessageContainer( message ) );
 
-					this.dom.appendChild( WEBVR.getButton( effect ) );
+				} );
 
-				}
+				WEBVR.getVRDisplay( function ( device ) {
 
-				if ( WEBVR.isLatestAvailable() === false ) {
+					renderer.vr.setDevice( device );
+					dom.appendChild( WEBVR.getButton( device, renderer.domElement ) );
 
-					this.dom.appendChild( WEBVR.getMessage() );
-
-				}
+				} );
 
 			}
 
@@ -177,12 +166,10 @@ var APP = {
 
 		}
 
-		var prevTime, request;
+		var prevTime;
 
 		function animate( time ) {
 
-			request = requestAnimationFrame( animate );
-
 			try {
 
 				dispatch( events.update, { time: time, delta: time - prevTime } );
@@ -193,18 +180,7 @@ var APP = {
 
 			}
 
-			if ( isVR === true ) {
-
-				camera.updateMatrixWorld();
-
-				controls.update();
-				effect.render( scene, cameraVR );
-
-			} else {
-
-				renderer.render( scene, camera );
-
-			}
+			renderer.render( scene, camera );
 
 			prevTime = time;
 
@@ -212,6 +188,8 @@ var APP = {
 
 		this.play = function () {
 
+			prevTime = performance.now();
+
 			document.addEventListener( 'keydown', onDocumentKeyDown );
 			document.addEventListener( 'keyup', onDocumentKeyUp );
 			document.addEventListener( 'mousedown', onDocumentMouseDown );
@@ -223,8 +201,7 @@ var APP = {
 
 			dispatch( events.start, arguments );
 
-			request = requestAnimationFrame( animate );
-			prevTime = performance.now();
+			renderer.animate( animate );
 
 		};
 
@@ -241,15 +218,15 @@ var APP = {
 
 			dispatch( events.stop, arguments );
 
-			cancelAnimationFrame( request );
+			renderer.animate( null );
 
 		};
 
 		this.dispose = function () {
 
-			while ( this.dom.children.length ) {
+			while ( dom.children.length ) {
 
-				this.dom.removeChild( this.dom.firstChild );
+				dom.removeChild( dom.firstChild );
 
 			}
 

+ 0 - 108
editor/js/libs/tern-threejs/threejs.js

@@ -746,114 +746,6 @@
       "!doc": "Represents a lookup table for colormaps. It is used to determine the color values from a range of data values.",
       "!type": "fn(colormap, numberOfColors)"
     },
-    "CombinedCamera": {
-      "!url": "http://threejs.org/docs/#Reference/examples/cameras/CombinedCamera",
-      "prototype": {
-        "!proto": "THREE.Camera.prototype",
-        "fov": {
-          "!type": "number",
-          "!doc": "Gets or sets the camera frustum vertical field of view in perspective view."
-        },
-        "left": {
-          "!type": "number",
-          "!doc": "Gets or sets the camera frustum left plane in orthographic view."
-        },
-        "right": {
-          "!type": "number",
-          "!doc": "Gets or sets the camera frustum right plane in orthographic view."
-        },
-        "top": {
-          "!type": "number",
-          "!doc": "Gets or sets the camera frustum top plane in orthographic view."
-        },
-        "bottom": {
-          "!type": "number",
-          "!doc": "Gets or sets the camera frustum bottom plane in orthographic view."
-        },
-        "zoom": {
-          "!type": "number",
-          "!doc": "Gets or sets the zoom factor of the camera."
-        },
-        "near": {
-          "!type": "number",
-          "!doc": "Gets camera frustum near plane."
-        },
-        "far": {
-          "!type": "number",
-          "!doc": "Gets camera frustum far plane."
-        },
-        "cameraO": {
-          "!type": "+THREE.OrthographicCamera",
-          "!doc": "Gets or sets the internal OrthographicCamera used as camera."
-        },
-        "cameraP": {
-          "!type": "+THREE.PerspectiveCamera",
-          "!doc": "Gets or sets the internal PerspectiveCamera used as camera."
-        },
-        "inOrthographicMode": {
-          "!type": "boolean",
-          "!doc": "Gets whether the combinedCamera is in Orthographic Mode."
-        },
-        "inPerspectiveMode": {
-          "!type": "boolean",
-          "!doc": "Gets whether the combinedCamera is in Perspective Mode."
-        },
-        "setFov": {
-          "!type": "fn(fov: number)",
-          "!doc": "sets the camera frustum vertical field of view in perspective view."
-        },
-        "setZoom": {
-          "!type": "fn(zoom: number)",
-          "!doc": "Sets the zoomfactor."
-        },
-        "setLens": {
-          "!type": "fn(focalLength: number, frameHeight: number)",
-          "!doc": "Sets the fov based on lens data."
-        },
-        "toFrontView": {
-          "!type": "fn()",
-          "!doc": "Sets the camera to view the front of the target."
-        },
-        "toBackView": {
-          "!type": "fn()",
-          "!doc": "Sets the camera to view the back of the target."
-        },
-        "toLeftView": {
-          "!type": "fn()",
-          "!doc": "Sets the camera to view the left of the target."
-        },
-        "toRightView": {
-          "!type": "fn()",
-          "!doc": "Sets the camera to view the right of the target."
-        },
-        "toTopView": {
-          "!type": "fn()",
-          "!doc": "Sets the camera to view the top."
-        },
-        "toBottomView": {
-          "!type": "fn()",
-          "!doc": "Sets the camera to view the bottom."
-        },
-        "setSize": {
-          "!type": "fn(width: number, height: number)",
-          "!doc": "Sets the size of the orthographic view."
-        },
-        "toOrthographic": {
-          "!type": "fn()",
-          "!doc": "Change the camera to orthographic view."
-        },
-        "toPerspective": {
-          "!type": "fn()",
-          "!doc": "Change the camera to Perspective view."
-        },
-        "updateProjectionMatrix": {
-          "!type": "fn()",
-          "!doc": "Updates the ProjectionMatrix."
-        }
-      },
-      "!doc": "A general purpose camera, for setting FOV, Lens Focal Length,\n \t\tand switching between perspective and orthographic views easily.\n \t\tUse this only if you do not wish to manage\n \t\tboth an Orthographic and Perspective Camera",
-      "!type": "fn(width: number, height: number, fov: number, near: number, far: number, orthoNear: number, orthoFar: number)"
-    },
     "FontUtils": {
       "!url": "http://threejs.org/docs/#Reference/extras/FontUtils",
       "prototype": {

+ 0 - 214
examples/canvas_camera_orthographic2.html

@@ -1,214 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<title>three.js canvas - combo camera - orthographic + perspective</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: #f0f0f0;
-				margin: 0px;
-				overflow: hidden;
-				color: purple;
-			}
-
-			a {
-				color: red;
-			}
-		</style>
-	</head>
-	<body>
-
-		<script src="../build/three.js"></script>
-
-		<script src="js/cameras/CombinedCamera.js"></script>
-
-		<script src="js/renderers/Projector.js"></script>
-		<script src="js/renderers/CanvasRenderer.js"></script>
-
-		<script src="js/libs/stats.min.js"></script>
-
-		<div style="position: absolute; top: 10px; width: 100%; text-align: center; ">
-			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - Combo Camera<br>
-			View: <a href="#" onclick="setOrthographic();return false;"> Orthographic</a> |
-				<a href="#" onclick="setPerspective();return false;">Perspective</a><br>
-			Lens: <a href="#" onclick="setLens(12);return false;">12mm</a> |
-				<a href="#" onclick="setLens(16);return false;">16mm</a> |
-				<a href="#" onclick="setLens(24);return false;">24mm</a> |
-				<a href="#" onclick="setLens(35);return false;">35mm</a> |
-				<a href="#" onclick="setLens(50);return false;">50mm</a> |
-				<a href="#" onclick="setLens(60);return false;">60mm</a> |
-				<a href="#" onclick="setLens(85);return false;">85mm</a> |
-				<a href="#" onclick="setLens(105);return false;">105mm</a><br>
-			Fov: <a href="#" onclick="setFov(30);return false;">30°</a> |
-				<a href="#" onclick="setFov(50);return false;">50°</a> |
-				<a href="#" onclick="setFov(70);return false;">70°</a> |
-				<a href="#" onclick="setFov(100);return false;">100°</a><br>
-			Zoom: <a href="#" onclick="camera.setZoom(0.5);return false;">0.5x</a> |
-					<a href="#" onclick="camera.setZoom(1);return false;">1x</a> |
-					<a href="#" onclick="camera.setZoom(2);return false;">2x</a> |
-
-				<br/>
-			Views: <a href="#" onclick="camera.toTopView();lookAtScene=false;return false;">Top view</a> |
-				<a href="#" onclick="camera.toBottomView();lookAtScene=false;return false;">Bottom view</a> |
-				<a href="#" onclick="camera.toLeftView();lookAtScene=false;return false;">Left view</a> |
-				<a href="#" onclick="camera.toRightView();lookAtScene=false;return false;">Right view</a> |
-				<a href="#" onclick="camera.toFrontView();lookAtScene=false;return false;">Front view</a> |
-				<a href="#" onclick="camera.toBackView();lookAtScene=false;return false;">Back view</a> |
-				<a href="#" onclick="lookAtScene=true;return false;">Look at Scene</a>
-				<br/>
-			<div id="fov"></div>
-		</div>
-
-
-
-		<script>
-
-			var container, stats;
-			var camera, scene, renderer;
-			var lookAtScene = true;
-
-			init();
-			animate();
-
-			function setFov( fov ) {
-
-				camera.setFov( fov );
-
-				document.getElementById('fov').innerHTML = 'FOV '+ fov.toFixed(2) +'&deg;' ;
-
-			}
-
-			function setLens( lens ) {
-
-				// try adding a tween effect while changing focal length, and it'd be even cooler!
-
-				var fov = camera.setLens( lens );
-
-				document.getElementById('fov').innerHTML = 'Converted ' + lens + 'mm lens to FOV '+ fov.toFixed(2) +'&deg;' ;
-
-			}
-
-			function setOrthographic() {
-
-				camera.toOrthographic();
-
-				document.getElementById('fov').innerHTML = 'Orthographic mode' ;
-
-			}
-
-			function setPerspective() {
-
-				camera.toPerspective();
-
-				document.getElementById('fov').innerHTML = 'Perspective mode' ;
-
-			}
-
-			function init() {
-
-				container = document.createElement( 'div' );
-				document.body.appendChild( container );
-
-				camera = new THREE.CombinedCamera( window.innerWidth / 2, window.innerHeight / 2, 70, 1, 1000, - 500, 1000 );
-
-				camera.position.x = 200;
-				camera.position.y = 100;
-				camera.position.z = 200;
-
-				scene = new THREE.Scene();
-				scene.background = new THREE.Color( 0xf0f0f0 );
-
-				// Grid
-
-				var gridHelper = new THREE.GridHelper( 1000, 20 );
-				scene.add( gridHelper );
-
-				// Cubes
-
-				var geometry = new THREE.BoxGeometry( 50, 50, 50 );
-				var material = new THREE.MeshLambertMaterial( { color: 0xffffff, overdraw: 0.5 } );
-
-				for ( var i = 0; i < 100; i ++ ) {
-
-					var cube = new THREE.Mesh( geometry, material );
-
-					cube.scale.y = Math.floor( Math.random() * 2 + 1 );
-
-					cube.position.x = Math.floor( ( Math.random() * 1000 - 500 ) / 50 ) * 50 + 25;
-					cube.position.y = ( cube.scale.y * 50 ) / 2;
-					cube.position.z = Math.floor( ( Math.random() * 1000 - 500 ) / 50 ) * 50 + 25;
-
-					scene.add(cube);
-
-				}
-
-				// Lights
-
-				var ambientLight = new THREE.AmbientLight( Math.random() * 0x10 );
-				scene.add( ambientLight );
-
-				var directionalLight = new THREE.DirectionalLight( Math.random() * 0xffffff );
-				directionalLight.position.x = Math.random() - 0.5;
-				directionalLight.position.y = Math.random() - 0.5;
-				directionalLight.position.z = Math.random() - 0.5;
-				directionalLight.position.normalize();
-				scene.add( directionalLight );
-
-				var directionalLight = new THREE.DirectionalLight( Math.random() * 0xffffff );
-				directionalLight.position.x = Math.random() - 0.5;
-				directionalLight.position.y = Math.random() - 0.5;
-				directionalLight.position.z = Math.random() - 0.5;
-				directionalLight.position.normalize();
-				scene.add( directionalLight );
-
-				renderer = new THREE.CanvasRenderer();
-				renderer.setPixelRatio( window.devicePixelRatio );
-				renderer.setSize( window.innerWidth, window.innerHeight );
-				container.appendChild( renderer.domElement );
-
-				stats = new Stats();
-				container.appendChild( stats.dom );
-
-				window.addEventListener( 'resize', onWindowResize, false );
-
-				function onWindowResize(){
-
-					camera.setSize( window.innerWidth, window.innerHeight );
-					camera.updateProjectionMatrix();
-
-					renderer.setSize( window.innerWidth, window.innerHeight );
-
-				}
-
-			}
-
-			//
-
-			function animate() {
-
-				requestAnimationFrame( animate );
-
-				stats.begin();
-				render();
-				stats.end();
-
-			}
-
-			function render() {
-
-				var timer = Date.now() * 0.0001;
-
-				camera.position.x = Math.cos( timer ) * 200;
-				camera.position.z = Math.sin( timer ) * 200;
-				if ( lookAtScene ) camera.lookAt( scene.position );
-
-				renderer.render( scene, camera );
-
-			}
-
-		</script>
-
-	</body>
-</html>

+ 4 - 1
examples/canvas_geometry_panorama.html

@@ -164,7 +164,10 @@
 
 			function onDocumentMouseWheel( event ) {
 
-				camera.fov += event.deltaY * 0.05;
+				var fov = camera.fov + event.deltaY * 0.05;
+
+				camera.fov = THREE.Math.clamp( fov, 10, 75 );
+
 				camera.updateProjectionMatrix();
 
 			}

+ 4 - 1
examples/canvas_geometry_panorama_fisheye.html

@@ -172,7 +172,10 @@
 
 			function onDocumentMouseWheel( event ) {
 
-				camera.fov += event.deltaY * 0.05;
+				var fov = camera.fov + event.deltaY * 0.05;
+
+				camera.fov = THREE.Math.clamp( fov, 10, 75 );
+
 				camera.updateProjectionMatrix();
 
 			}

+ 8 - 24
examples/css3d_molecules.html

@@ -11,14 +11,7 @@
 
 			body {
 				background-color: #050505;
-
-				background: rgb(43,45,48); /* Old browsers */
-				background: -moz-radial-gradient(center, ellipse cover,  rgba(43,45,48,1) 0%, rgba(0,0,0,1) 100%); /* FF3.6+ */
-				background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,rgba(43,45,48,1)), color-stop(100%,rgba(0,0,0,1))); /* Chrome,Safari4+ */
-				background: -webkit-radial-gradient(center, ellipse cover,  rgba(43,45,48,1) 0%,rgba(0,0,0,1) 100%); /* Chrome10+,Safari5.1+ */
-				background: -o-radial-gradient(center, ellipse cover,  rgba(43,45,48,1) 0%,rgba(0,0,0,1) 100%); /* Opera 12+ */
-				background: -ms-radial-gradient(center, ellipse cover,  rgba(43,45,48,1) 0%,rgba(0,0,0,1) 100%); /* IE10+ */
-				background: radial-gradient(ellipse at center,  rgba(43,45,48,1) 0%,rgba(0,0,0,1) 100%); /* W3C */
+				background: radial-gradient(ellipse at center,  rgba(43,45,48,1) 0%,rgba(0,0,0,1) 100%);
 
 				margin: 0;
 				font-family: Arial;
@@ -286,27 +279,18 @@
 
 			//
 
-			function colorify( ctx, width, height, color, a ) {
+			function colorify( ctx, width, height, color ) {
 
-				var r = color.r;
-				var g = color.g;
-				var b = color.b;
+				var r = color.r, g = color.g, b = color.b;
 
 				var imageData = ctx.getImageData( 0, 0, width, height );
 				var data = imageData.data;
 
-				for ( var y = 0; y < height; y ++ ) {
-
-					for ( var x = 0; x < width; x ++ ) {
-
-						var index = ( y * width + x ) * 4;
+				for ( var i = 0, l = data.length; i < l; i += 4 ) {
 
-						data[ index ]     *= r;
-						data[ index + 1 ] *= g;
-						data[ index + 2 ] *= b;
-						data[ index + 3 ] *= a;
-
-					}
+					data[ i + 0 ] *= r;
+					data[ i + 1 ] *= g;
+					data[ i + 2 ] *= b;
 
 				}
 
@@ -377,7 +361,7 @@
 							var canvas = imageToCanvas( baseSprite );
 							var context = canvas.getContext( '2d' );
 
-							colorify( context, canvas.width, canvas.height, color, 1 );
+							colorify( context, canvas.width, canvas.height, color );
 
 							var dataUrl = canvas.toDataURL();
 

+ 4 - 1
examples/css3d_panorama.html

@@ -156,7 +156,10 @@
 
 			function onDocumentMouseWheel( event ) {
 
-				camera.fov += event.deltaY * 0.05;
+				var fov = camera.fov + event.deltaY * 0.05;
+
+				camera.fov = THREE.Math.clamp( fov, 10, 75 );
+
 				camera.updateProjectionMatrix();
 
 			}

+ 4 - 4
examples/css3d_periodictable.html

@@ -228,12 +228,12 @@
 				"Ds", "Darmstadium", "(281)", 10, 7,
 				"Rg", "Roentgenium", "(280)", 11, 7,
 				"Cn", "Copernicium", "(285)", 12, 7,
-				"Uut", "Unutrium", "(284)", 13, 7,
+				"Nh", "Nihonium", "(286)", 13, 7,
 				"Fl", "Flerovium", "(289)", 14, 7,
-				"Uup", "Ununpentium", "(288)", 15, 7,
+				"Mc", "Moscovium", "(290)", 15, 7,
 				"Lv", "Livermorium", "(293)", 16, 7,
-				"Uus", "Ununseptium", "(294)", 17, 7,
-				"Uuo", "Ununoctium", "(294)", 18, 7
+				"Ts", "Tennessine", "(294)", 17, 7,
+				"Og", "Oganesson", "(294)", 18, 7
 			];
 
 			var camera, scene, renderer;

+ 26 - 20
examples/files.js

@@ -18,8 +18,6 @@ var files = {
 		"webgl_effects_parallaxbarrier",
 		"webgl_effects_peppersghost",
 		"webgl_effects_stereo",
-		"webgl_exporter_gltf2",
-		"webgl_exporter_obj",
 		"webgl_geometries",
 		"webgl_geometries2",
 		"webgl_geometry_colors",
@@ -92,7 +90,7 @@ var files = {
 		"webgl_loader_ctm_materials",
 		"webgl_loader_draco",
 		"webgl_loader_fbx",
-		"webgl_loader_gltf2",
+		"webgl_loader_gltf",
 		"webgl_loader_imagebitmap",
 		"webgl_loader_json_blender",
 		"webgl_loader_json_claraio",
@@ -106,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",
@@ -162,6 +161,7 @@ var files = {
 		"webgl_materials_texture_hdr",
 		"webgl_materials_texture_manualmipmap",
 		"webgl_materials_texture_pvrtc",
+		"webgl_materials_texture_rotation",
 		"webgl_materials_texture_tga",
 		"webgl_materials_transparency",
 		"webgl_materials_variations_basic",
@@ -214,6 +214,7 @@ var files = {
 		"webgl_postprocessing_crossfade",
 		"webgl_postprocessing_dof",
 		"webgl_postprocessing_dof2",
+		"webgl_postprocessing_fxaa",
 		"webgl_postprocessing_glitch",
 		"webgl_postprocessing_godrays",
 		"webgl_postprocessing_masking",
@@ -222,9 +223,10 @@ var files = {
 		"webgl_postprocessing_nodes",
 		"webgl_postprocessing_outline",
 		"webgl_postprocessing_procedural",
+		"webgl_postprocessing_sao",
 		"webgl_postprocessing_smaa",
+		"webgl_postprocessing_sobel",
 		"webgl_postprocessing_ssao",
-		"webgl_postprocessing_sao",
 		"webgl_postprocessing_taa",
 		"webgl_postprocessing_unreal_bloom",
 		"webgl_raycast_texture",
@@ -245,7 +247,6 @@ var files = {
 		"webgl_shadowmap_pointlight",
 		"webgl_shadowmap_viewer",
 		"webgl_shadowmesh",
-		"webgl_simple_gi",
 		"webgl_skinning_simple",
 		"webgl_sprites",
 		"webgl_sprites_nodes",
@@ -280,7 +281,8 @@ var files = {
 		"webgl_custom_attributes_points3",
 		"webgl_materials_modified",
 		"webgl_raymarching_reflect",
-		"webgl_shadowmap_pcss"
+		"webgl_shadowmap_pcss",
+		"webgl_simple_gi"
 	],
 	"webgl deferred": [
 		"webgldeferred_animation"
@@ -290,9 +292,14 @@ var files = {
 		"webgl2_sandbox"
 	],
 	*/
+	"webaudio": [
+		"webaudio_sandbox",
+		"webaudio_visualizer"
+	],
 	"webvr": [
 		"webvr_cubes",
 		"webvr_daydream",
+		"webvr_gearvr",
 		"webvr_panorama",
 		"webvr_rollercoaster",
 		"webvr_sandbox",
@@ -303,15 +310,6 @@ var files = {
 		"webvr_vive_paint",
 		"webvr_vive_sculpt"
 	],
-	"css3d": [
-		"css3d_molecules",
-		"css3d_panorama",
-		"css3d_panorama_deviceorientation",
-		"css3d_periodictable",
-		"css3d_sandbox",
-		"css3d_sprites",
-		"css3d_youtube"
-	],
 	"misc": [
 		"misc_animation_authoring",
 		"misc_animation_keys",
@@ -321,19 +319,27 @@ var files = {
 		"misc_controls_pointerlock",
 		"misc_controls_trackball",
 		"misc_controls_transform",
+		"misc_exporter_gltf",
+		"misc_exporter_obj",
 		"misc_fps",
 		"misc_lights_test",
 		"misc_lookat",
-		"misc_sound",
-		"misc_sound_visualizer",
 		"misc_ubiquity_test",
 		"misc_ubiquity_test2",
 		"misc_uv_tests"
 	],
+	"css3d": [
+		"css3d_molecules",
+		"css3d_panorama",
+		"css3d_panorama_deviceorientation",
+		"css3d_periodictable",
+		"css3d_sandbox",
+		"css3d_sprites",
+		"css3d_youtube"
+	],
 	"canvas": [
 		"canvas_ascii_effect",
 		"canvas_camera_orthographic",
-		"canvas_camera_orthographic2",
 		"canvas_geometry_birds",
 		"canvas_geometry_cube",
 		"canvas_geometry_earth",

+ 13 - 13
examples/index.html

@@ -87,7 +87,7 @@
 				overflow: auto;
 			}
 
-			#button {
+			#viewSrcButton {
 				position: fixed;
 				bottom: 20px;
 				right: 20px;
@@ -97,7 +97,7 @@
 				opacity: 0.7;
 			}
 
-			#button:hover {
+			#viewSrcButton:hover {
 				cursor: pointer;
 				opacity: 1;
 			}
@@ -277,16 +277,12 @@
 		var container = document.createElement( 'div' );
 		content.appendChild( container );
 
-		var button = document.createElement( 'div' );
-		button.id = 'button';
-		button.textContent = 'View source';
-		button.addEventListener( 'click', function ( event ) {
-
-			window.open( 'https://github.com/mrdoob/three.js/blob/master/examples/' + selected + '.html' );
-
-		}, false );
-		button.style.display = 'none';
-		document.body.appendChild( button );
+		var viewSrcButton = document.createElement( 'a' );
+		viewSrcButton.id = 'viewSrcButton';
+		viewSrcButton.target = '_blank';
+		viewSrcButton.textContent = 'View source';
+		viewSrcButton.style.display = 'none';
+		document.body.appendChild( viewSrcButton );
 
 		var links = {};
 		var selected = null;
@@ -350,11 +346,15 @@
 			window.location.hash = file;
 			viewer.focus();
 
-			button.style.display = '';
 			panel.classList.toggle( 'collapsed' );
 
 			selected = file;
 
+			// Reveal "View source" button and set attributes to this example
+			viewSrcButton.style.display = '';
+			viewSrcButton.href = 'https://github.com/mrdoob/three.js/blob/master/examples/' + selected + '.html';
+			viewSrcButton.title = 'View source code for ' + getName(selected) + ' on GitHub';
+
 		}
 
 		if ( window.location.hash !== '' ) {

+ 20 - 33
examples/js/ParametricGeometries.js

@@ -36,7 +36,7 @@ THREE.ParametricGeometries = {
 
 	plane: function ( width, height ) {
 
-		return function( u, v, optionalTarget ) {
+		return function ( u, v, optionalTarget ) {
 
 			var result = optionalTarget || new THREE.Vector3();
 
@@ -50,7 +50,7 @@ THREE.ParametricGeometries = {
 
 	},
 
-	mobius: function( u, t, optionalTarget ) {
+	mobius: function ( u, t, optionalTarget ) {
 
 		var result = optionalTarget || new THREE.Vector3();
 
@@ -71,7 +71,7 @@ THREE.ParametricGeometries = {
 
 	},
 
-	mobius3d: function( u, t, optionalTarget ) {
+	mobius3d: function ( u, t, optionalTarget ) {
 
 		var result = optionalTarget || new THREE.Vector3();
 
@@ -104,7 +104,7 @@ THREE.ParametricGeometries = {
  *
  *********************************************/
 
-THREE.ParametricGeometries.TubeGeometry = function( path, segments, radius, segmentsRadius, closed, debug ) {
+THREE.ParametricGeometries.TubeGeometry = function ( path, segments, radius, segmentsRadius, closed, debug ) {
 
 	this.path = path;
 	this.segments = segments || 64;
@@ -113,17 +113,7 @@ THREE.ParametricGeometries.TubeGeometry = function( path, segments, radius, segm
 	this.closed = closed || false;
 	if ( debug ) this.debug = new THREE.Object3D();
 
-
-	var scope = this,
-
-		tangent, normal, binormal,
-
-		numpoints = this.segments + 1,
-
-		x, y, z, tx, ty, tz, u, v,
-
-		cx, cy, pos,
-		i, j, ip, jp, a, b, c, d, uva, uvb, uvc, uvd;
+	var scope = this, numpoints = this.segments + 1;
 
 	var frames = path.computeFrenetFrames( segments, closed ),
 		tangents = frames.tangents,
@@ -131,26 +121,25 @@ THREE.ParametricGeometries.TubeGeometry = function( path, segments, radius, segm
 		binormals = frames.binormals;
 
 	// proxy internals
+
 	this.tangents = tangents;
 	this.normals = normals;
 	this.binormals = binormals;
 
-
-
-	var ParametricTube = function( u, v, optionalTarget ) {
+	var ParametricTube = function ( u, v, optionalTarget ) {
 
 		var result = optionalTarget || new THREE.Vector3();
 
 		v *= 2 * Math.PI;
 
-		i = u * ( numpoints - 1 );
+		var i = u * ( numpoints - 1 );
 		i = Math.floor( i );
 
-		pos = path.getPointAt( u );
+		var pos = path.getPointAt( u );
 
-		tangent = tangents[ i ];
-		normal = normals[ i ];
-		binormal = binormals[ i ];
+		var tangent = tangents[ i ];
+		var normal = normals[ i ];
+		var binormal = binormals[ i ];
 
 		if ( scope.debug ) {
 
@@ -160,8 +149,8 @@ THREE.ParametricGeometries.TubeGeometry = function( path, segments, radius, segm
 
 		}
 
-		cx = - scope.radius * Math.cos( v ); // TODO: Hack: Negating it so it faces outside.
-		cy = scope.radius * Math.sin( v );
+		var cx = - scope.radius * Math.cos( v ); // TODO: Hack: Negating it so it faces outside.
+		var cy = scope.radius * Math.sin( v );
 
 		pos.x += cx * normal.x + cy * binormal.x;
 		pos.y += cx * normal.y + cy * binormal.y;
@@ -179,15 +168,13 @@ THREE.ParametricGeometries.TubeGeometry.prototype = Object.create( THREE.Geometr
 THREE.ParametricGeometries.TubeGeometry.prototype.constructor = THREE.ParametricGeometries.TubeGeometry;
 
 
- /*********************************************
+/*********************************************
   *
   * Parametric Replacement for TorusKnotGeometry
   *
   *********************************************/
 THREE.ParametricGeometries.TorusKnotGeometry = function ( radius, tube, segmentsT, segmentsR, p, q ) {
 
-	var scope = this;
-
 	this.radius = radius || 200;
 	this.tube = tube || 40;
 	this.segmentsT = segmentsT || 64;
@@ -204,7 +191,7 @@ THREE.ParametricGeometries.TorusKnotGeometry = function ( radius, tube, segments
 	TorusKnotCurve.prototype = Object.create( THREE.Curve.prototype );
 	TorusKnotCurve.prototype.constructor = TorusKnotCurve;
 
-	TorusKnotCurve.prototype.getPoint = function( t ){
+	TorusKnotCurve.prototype.getPoint = function ( t ) {
 
 		t *= Math.PI * 2;
 
@@ -230,12 +217,12 @@ THREE.ParametricGeometries.TorusKnotGeometry.prototype = Object.create( THREE.Ge
 THREE.ParametricGeometries.TorusKnotGeometry.prototype.constructor = THREE.ParametricGeometries.TorusKnotGeometry;
 
 
- /*********************************************
+/*********************************************
   *
   * Parametric Replacement for SphereGeometry
   *
   *********************************************/
-THREE.ParametricGeometries.SphereGeometry = function( size, u, v ) {
+THREE.ParametricGeometries.SphereGeometry = function ( size, u, v ) {
 
 	function sphere( u, v, optionalTarget ) {
 
@@ -260,13 +247,13 @@ THREE.ParametricGeometries.SphereGeometry.prototype = Object.create( THREE.Geome
 THREE.ParametricGeometries.SphereGeometry.prototype.constructor = THREE.ParametricGeometries.SphereGeometry;
 
 
- /*********************************************
+/*********************************************
   *
   * Parametric Replacement for PlaneGeometry
   *
   *********************************************/
 
-THREE.ParametricGeometries.PlaneGeometry = function( width, depth, segmentsWidth, segmentsDepth ) {
+THREE.ParametricGeometries.PlaneGeometry = function ( width, depth, segmentsWidth, segmentsDepth ) {
 
 	function plane( u, v, optionalTarget ) {
 

+ 8 - 9
examples/js/QuickHull.js

@@ -5,7 +5,7 @@
  *
  */
 
-( function() {
+( function () {
 
 	var Visible = 0;
 	var Deleted = 1;
@@ -348,7 +348,7 @@
 
 			// compute the min/max vertex on all six directions
 
-			for ( i = 0, l = this.vertices.length; i < l ; i ++ ) {
+			for ( i = 0, l = this.vertices.length; i < l; i ++ ) {
 
 				var vertex = this.vertices[ i ];
 				var point = vertex.point;
@@ -400,7 +400,7 @@
 
 			var line3, plane, closestPoint;
 
-			return function computeInitialHull () {
+			return function computeInitialHull() {
 
 				if ( line3 === undefined ) {
 
@@ -562,7 +562,7 @@
 
 				for ( i = 0, l = vertices.length; i < l; i ++ ) {
 
-					vertex = vertices[i];
+					vertex = vertices[ i ];
 
 					if ( vertex !== v0 && vertex !== v1 && vertex !== v2 && vertex !== v3 ) {
 
@@ -785,7 +785,6 @@
 		addVertexToHull: function ( eyeVertex ) {
 
 			var horizon = [];
-			var i, face;
 
 			this.unassigned.clear();
 
@@ -856,7 +855,7 @@
 
 	Object.assign( Face, {
 
-		create: function( a, b, c ) {
+		create: function ( a, b, c ) {
 
 			var face = new Face();
 
@@ -908,7 +907,7 @@
 
 			var triangle;
 
-			return function compute () {
+			return function compute() {
 
 				if ( triangle === undefined ) triangle = new THREE.Triangle();
 
@@ -1202,7 +1201,7 @@
 
 		},
 
-		isEmpty: function() {
+		isEmpty: function () {
 
 			return this.head === null;
 
@@ -1215,4 +1214,4 @@
 	THREE.QuickHull = QuickHull;
 
 
-} ) ();
+} )();

+ 0 - 322
examples/js/WaterShader.js

@@ -1,322 +0,0 @@
-/**
- * @author jbouny / https://github.com/jbouny
- *
- * Work based on :
- * @author Slayvin / http://slayvin.net : Flat mirror for three.js
- * @author Stemkoski / http://www.adelphi.edu/~stemkoski : An implementation of water shader based on the flat mirror
- * @author Jonas Wagner / http://29a.ch/ && http://29a.ch/slides/2012/webglwater/ : Water shader explanations in WebGL
- */
-
-THREE.Water = function ( renderer, camera, scene, options ) {
-
-	THREE.Object3D.call( this );
-	this.name = 'water_' + this.id;
-
-	function optionalParameter( value, defaultValue ) {
-
-		return value !== undefined ? value : defaultValue;
-
-	}
-
-	options = options || {};
-
-	this.matrixNeedsUpdate = true;
-
-	var width = optionalParameter( options.textureWidth, 512 );
-	var height = optionalParameter( options.textureHeight, 512 );
-	this.clipBias = optionalParameter( options.clipBias, 0.0 );
-	this.alpha = optionalParameter( options.alpha, 1.0 );
-	this.time = optionalParameter( options.time, 0.0 );
-	this.normalSampler = optionalParameter( options.waterNormals, null );
-	this.sunDirection = optionalParameter( options.sunDirection, new THREE.Vector3( 0.70707, 0.70707, 0.0 ) );
-	this.sunColor = new THREE.Color( optionalParameter( options.sunColor, 0xffffff ) );
-	this.waterColor = new THREE.Color( optionalParameter( options.waterColor, 0x7F7F7F ) );
-	this.eye = optionalParameter( options.eye, new THREE.Vector3( 0, 0, 0 ) );
-	this.distortionScale = optionalParameter( options.distortionScale, 20.0 );
-	this.side = optionalParameter( options.side, THREE.FrontSide );
-	this.fog = optionalParameter( options.fog, false );
-
-	this.renderer = renderer;
-	this.scene = scene;
-	this.mirrorPlane = new THREE.Plane();
-	this.normal = new THREE.Vector3( 0, 0, 1 );
-	this.mirrorWorldPosition = new THREE.Vector3();
-	this.cameraWorldPosition = new THREE.Vector3();
-	this.rotationMatrix = new THREE.Matrix4();
-	this.lookAtPosition = new THREE.Vector3( 0, 0, - 1 );
-	this.clipPlane = new THREE.Vector4();
-
-	if ( camera instanceof THREE.PerspectiveCamera ) {
-
-		this.camera = camera;
-
-	} else {
-
-		this.camera = new THREE.PerspectiveCamera();
-		console.log( this.name + ': camera is not a Perspective Camera!' );
-
-	}
-
-	this.textureMatrix = new THREE.Matrix4();
-
-	this.mirrorCamera = this.camera.clone();
-
-	this.renderTarget = new THREE.WebGLRenderTarget( width, height );
-	this.renderTarget2 = new THREE.WebGLRenderTarget( width, height );
-
-	var mirrorShader = {
-
-		uniforms: THREE.UniformsUtils.merge( [
-			THREE.UniformsLib[ 'fog' ],
-			{
-				normalSampler: { value: null },
-				mirrorSampler: { value: null },
-				alpha: { value: 1.0 },
-				time: { value: 0.0 },
-				distortionScale: { value: 20.0 },
-				noiseScale: { value: 1.0 },
-				textureMatrix: { value: new THREE.Matrix4() },
-				sunColor: { value: new THREE.Color( 0x7F7F7F ) },
-				sunDirection: { value: new THREE.Vector3( 0.70707, 0.70707, 0 ) },
-				eye: { value: new THREE.Vector3() },
-				waterColor: { value: new THREE.Color( 0x555555 ) }
-			}
-		] ),
-
-		vertexShader: [
-			'uniform mat4 textureMatrix;',
-			'uniform float time;',
-
-			'varying vec4 mirrorCoord;',
-			'varying vec3 worldPosition;',
-
-			THREE.ShaderChunk[ 'fog_pars_vertex' ],
-
-			'void main() {',
-			'	mirrorCoord = modelMatrix * vec4( position, 1.0 );',
-			'	worldPosition = mirrorCoord.xyz;',
-			'	mirrorCoord = textureMatrix * mirrorCoord;',
-			'	vec4 mvPosition =  modelViewMatrix * vec4( position, 1.0 );',
-			'	gl_Position = projectionMatrix * mvPosition;',
-
-			THREE.ShaderChunk[ 'fog_vertex' ],
-
-			'}'
-		].join( '\n' ),
-
-		fragmentShader: [
-			'precision highp float;',
-
-			'uniform sampler2D mirrorSampler;',
-			'uniform float alpha;',
-			'uniform float time;',
-			'uniform float distortionScale;',
-			'uniform sampler2D normalSampler;',
-			'uniform vec3 sunColor;',
-			'uniform vec3 sunDirection;',
-			'uniform vec3 eye;',
-			'uniform vec3 waterColor;',
-
-			'varying vec4 mirrorCoord;',
-			'varying vec3 worldPosition;',
-
-			'vec4 getNoise( vec2 uv ) {',
-			'	vec2 uv0 = ( uv / 103.0 ) + vec2(time / 17.0, time / 29.0);',
-			'	vec2 uv1 = uv / 107.0-vec2( time / -19.0, time / 31.0 );',
-			'	vec2 uv2 = uv / vec2( 8907.0, 9803.0 ) + vec2( time / 101.0, time / 97.0 );',
-			'	vec2 uv3 = uv / vec2( 1091.0, 1027.0 ) - vec2( time / 109.0, time / -113.0 );',
-			'	vec4 noise = texture2D( normalSampler, uv0 ) +',
-			'		texture2D( normalSampler, uv1 ) +',
-			'		texture2D( normalSampler, uv2 ) +',
-			'		texture2D( normalSampler, uv3 );',
-			'	return noise * 0.5 - 1.0;',
-			'}',
-
-			'void sunLight( const vec3 surfaceNormal, const vec3 eyeDirection, float shiny, float spec, float diffuse, inout vec3 diffuseColor, inout vec3 specularColor ) {',
-			'	vec3 reflection = normalize( reflect( -sunDirection, surfaceNormal ) );',
-			'	float direction = max( 0.0, dot( eyeDirection, reflection ) );',
-			'	specularColor += pow( direction, shiny ) * sunColor * spec;',
-			'	diffuseColor += max( dot( sunDirection, surfaceNormal ), 0.0 ) * sunColor * diffuse;',
-			'}',
-
-			THREE.ShaderChunk[ 'common' ],
-			THREE.ShaderChunk[ 'fog_pars_fragment' ],
-
-			'void main() {',
-			'	vec4 noise = getNoise( worldPosition.xz );',
-			'	vec3 surfaceNormal = normalize( noise.xzy * vec3( 1.5, 1.0, 1.5 ) );',
-
-			'	vec3 diffuseLight = vec3(0.0);',
-			'	vec3 specularLight = vec3(0.0);',
-
-			'	vec3 worldToEye = eye-worldPosition;',
-			'	vec3 eyeDirection = normalize( worldToEye );',
-			'	sunLight( surfaceNormal, eyeDirection, 100.0, 2.0, 0.5, diffuseLight, specularLight );',
-
-			'	float distance = length(worldToEye);',
-
-			'	vec2 distortion = surfaceNormal.xz * ( 0.001 + 1.0 / distance ) * distortionScale;',
-			'	vec3 reflectionSample = vec3( texture2D( mirrorSampler, mirrorCoord.xy / mirrorCoord.z + distortion ) );',
-
-			'	float theta = max( dot( eyeDirection, surfaceNormal ), 0.0 );',
-			'	float rf0 = 0.3;',
-			'	float reflectance = rf0 + ( 1.0 - rf0 ) * pow( ( 1.0 - theta ), 5.0 );',
-			'	vec3 scatter = max( 0.0, dot( surfaceNormal, eyeDirection ) ) * waterColor;',
-			'	vec3 albedo = mix( sunColor * diffuseLight * 0.3 + scatter, ( vec3( 0.1 ) + reflectionSample * 0.9 + reflectionSample * specularLight ), reflectance );',
-			'	vec3 outgoingLight = albedo;',
-			'	gl_FragColor = vec4( outgoingLight, alpha );',
-
-			THREE.ShaderChunk[ 'fog_fragment' ],
-
-			'}'
-		].join( '\n' )
-
-	};
-
-	var mirrorUniforms = THREE.UniformsUtils.clone( mirrorShader.uniforms );
-
-	this.material = new THREE.ShaderMaterial( {
-		fragmentShader: mirrorShader.fragmentShader,
-		vertexShader: mirrorShader.vertexShader,
-		uniforms: mirrorUniforms,
-		transparent: true,
-		side: this.side,
-		fog: this.fog
-	} );
-
-	this.material.uniforms.mirrorSampler.value = this.renderTarget.texture;
-	this.material.uniforms.textureMatrix.value = this.textureMatrix;
-	this.material.uniforms.alpha.value = this.alpha;
-	this.material.uniforms.time.value = this.time;
-	this.material.uniforms.normalSampler.value = this.normalSampler;
-	this.material.uniforms.sunColor.value = this.sunColor;
-	this.material.uniforms.waterColor.value = this.waterColor;
-	this.material.uniforms.sunDirection.value = this.sunDirection;
-	this.material.uniforms.distortionScale.value = this.distortionScale;
-
-	this.material.uniforms.eye.value = this.eye;
-
-	if ( ! THREE.Math.isPowerOfTwo( width ) || ! THREE.Math.isPowerOfTwo( height ) ) {
-
-		this.renderTarget.texture.generateMipmaps = false;
-		this.renderTarget.texture.minFilter = THREE.LinearFilter;
-		this.renderTarget2.texture.generateMipmaps = false;
-		this.renderTarget2.texture.minFilter = THREE.LinearFilter;
-
-	}
-
-	this.updateTextureMatrix();
-	this.render();
-
-};
-
-THREE.Water.prototype = Object.create( THREE.Object3D.prototype );
-THREE.Water.prototype.constructor = THREE.Water;
-
-THREE.Water.prototype.render = function () {
-
-	if ( this.matrixNeedsUpdate ) this.updateTextureMatrix();
-
-	this.matrixNeedsUpdate = true;
-
-	// Render the mirrored view of the current scene into the target texture
-	var scene = this;
-
-	while ( scene.parent !== null ) {
-
-		scene = scene.parent;
-
-	}
-
-	if ( scene !== undefined && scene instanceof THREE.Scene ) {
-
-		this.material.visible = false;
-
-		this.renderer.render( scene, this.mirrorCamera, this.renderTarget, true );
-
-		this.material.visible = true;
-
-	}
-
-};
-
-
-THREE.Water.prototype.updateTextureMatrix = function () {
-
-	this.updateMatrixWorld();
-	this.camera.updateMatrixWorld();
-
-	this.mirrorWorldPosition.setFromMatrixPosition( this.matrixWorld );
-	this.cameraWorldPosition.setFromMatrixPosition( this.camera.matrixWorld );
-
-	this.rotationMatrix.extractRotation( this.matrixWorld );
-
-	this.normal.set( 0, 0, 1 );
-	this.normal.applyMatrix4( this.rotationMatrix );
-
-	var view = this.mirrorWorldPosition.clone().sub( this.cameraWorldPosition );
-	view.reflect( this.normal ).negate();
-	view.add( this.mirrorWorldPosition );
-
-	this.rotationMatrix.extractRotation( this.camera.matrixWorld );
-
-	this.lookAtPosition.set( 0, 0, - 1 );
-	this.lookAtPosition.applyMatrix4( this.rotationMatrix );
-	this.lookAtPosition.add( this.cameraWorldPosition );
-
-	var target = this.mirrorWorldPosition.clone().sub( this.lookAtPosition );
-	target.reflect( this.normal ).negate();
-	target.add( this.mirrorWorldPosition );
-
-	this.up.set( 0, - 1, 0 );
-	this.up.applyMatrix4( this.rotationMatrix );
-	this.up.reflect( this.normal ).negate();
-
-	this.mirrorCamera.position.copy( view );
-	this.mirrorCamera.up = this.up;
-	this.mirrorCamera.lookAt( target );
-	this.mirrorCamera.aspect = this.camera.aspect;
-
-	this.mirrorCamera.updateProjectionMatrix();
-	this.mirrorCamera.updateMatrixWorld();
-
-	// Update the texture matrix
-	this.textureMatrix.set(
-		0.5, 0.0, 0.0, 0.5,
-		0.0, 0.5, 0.0, 0.5,
-		0.0, 0.0, 0.5, 0.5,
-		0.0, 0.0, 0.0, 1.0
-	);
-	this.textureMatrix.multiply( this.mirrorCamera.projectionMatrix );
-	this.textureMatrix.multiply( this.mirrorCamera.matrixWorldInverse );
-
-	// Now update projection matrix with new clip plane, implementing code from: http://www.terathon.com/code/oblique.html
-	// Paper explaining this technique: http://www.terathon.com/lengyel/Lengyel-Oblique.pdf
-	this.mirrorPlane.setFromNormalAndCoplanarPoint( this.normal, this.mirrorWorldPosition );
-	this.mirrorPlane.applyMatrix4( this.mirrorCamera.matrixWorldInverse );
-
-	this.clipPlane.set( this.mirrorPlane.normal.x, this.mirrorPlane.normal.y, this.mirrorPlane.normal.z, this.mirrorPlane.constant );
-
-	var q = new THREE.Vector4();
-	var projectionMatrix = this.mirrorCamera.projectionMatrix;
-
-	q.x = ( Math.sign( this.clipPlane.x ) + projectionMatrix.elements[ 8 ] ) / projectionMatrix.elements[ 0 ];
-	q.y = ( Math.sign( this.clipPlane.y ) + projectionMatrix.elements[ 9 ] ) / projectionMatrix.elements[ 5 ];
-	q.z = - 1.0;
-	q.w = ( 1.0 + projectionMatrix.elements[ 10 ] ) / projectionMatrix.elements[ 14 ];
-
-	// Calculate the scaled plane vector
-	var c = this.clipPlane.multiplyScalar( 2.0 / this.clipPlane.dot( q ) );
-
-	// Replacing the third row of the projection matrix
-	projectionMatrix.elements[ 2 ] = c.x;
-	projectionMatrix.elements[ 6 ] = c.y;
-	projectionMatrix.elements[ 10 ] = c.z + 1.0 - this.clipBias;
-	projectionMatrix.elements[ 14 ] = c.w;
-
-	var worldCoordinates = new THREE.Vector3();
-	worldCoordinates.setFromMatrixPosition( this.camera.matrixWorld );
-	this.eye = worldCoordinates;
-	this.material.uniforms.eye.value = this.eye;
-
-};

+ 0 - 285
examples/js/cameras/CombinedCamera.js

@@ -1,285 +0,0 @@
-/**
- *	@author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog
- *
- *	A general perpose camera, for setting FOV, Lens Focal Length,
- *		and switching between perspective and orthographic views easily.
- *		Use this only if you do not wish to manage
- *		both a Orthographic and Perspective Camera
- *
- */
-
-
-THREE.CombinedCamera = function ( width, height, fov, near, far, orthoNear, orthoFar ) {
-
-	THREE.Camera.call( this );
-
-	this.fov = fov;
-
-	this.far = far;
-	this.near = near;
-
-	this.left = - width / 2;
-	this.right = width / 2;
-	this.top = height / 2;
-	this.bottom = - height / 2;
-
-	this.aspect =  width / height;
-	this.zoom = 1;
-	this.view = null;
-	// We could also handle the projectionMatrix internally, but just wanted to test nested camera objects
-
-	this.cameraO = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 	orthoNear, orthoFar );
-	this.cameraP = new THREE.PerspectiveCamera( fov, width / height, near, far );
-
-	this.toPerspective();
-
-};
-
-THREE.CombinedCamera.prototype = Object.create( THREE.Camera.prototype );
-THREE.CombinedCamera.prototype.constructor = THREE.CombinedCamera;
-
-THREE.CombinedCamera.prototype.toPerspective = function () {
-
-	// Switches to the Perspective Camera
-
-	this.near = this.cameraP.near;
-	this.far = this.cameraP.far;
-
-	this.cameraP.aspect = this.aspect;
-	this.cameraP.fov =  this.fov / this.zoom ;
-	this.cameraP.view = this.view;
-
-	this.cameraP.updateProjectionMatrix();
-
-	this.projectionMatrix = this.cameraP.projectionMatrix;
-
-	this.inPerspectiveMode = true;
-	this.inOrthographicMode = false;
-
-};
-
-THREE.CombinedCamera.prototype.toOrthographic = function () {
-
-	// Switches to the Orthographic camera estimating viewport from Perspective
-
-	var fov = this.fov;
-	var aspect = this.cameraP.aspect;
-	var near = this.cameraP.near;
-	var far = this.cameraP.far;
-
-	// The size that we set is the mid plane of the viewing frustum
-
-	var hyperfocus = ( near + far ) / 2;
-
-	var halfHeight = Math.tan( fov * Math.PI / 180 / 2 ) * hyperfocus;
-	var halfWidth = halfHeight * aspect;
-
-	halfHeight /= this.zoom;
-	halfWidth /= this.zoom;
-
-	this.cameraO.left = - halfWidth;
-	this.cameraO.right = halfWidth;
-	this.cameraO.top = halfHeight;
-	this.cameraO.bottom = - halfHeight;
-	this.cameraO.view = this.view;
-
-	this.cameraO.updateProjectionMatrix();
-
-	this.near = this.cameraO.near;
-	this.far = this.cameraO.far;
-	this.projectionMatrix = this.cameraO.projectionMatrix;
-
-	this.inPerspectiveMode = false;
-	this.inOrthographicMode = true;
-
-};
-
-THREE.CombinedCamera.prototype.copy = function ( source ) {
-
-	THREE.Camera.prototype.copy.call( this, source );
-
-	this.fov = source.fov;
-	this.far = source.far;
-	this.near = source.near;
-
-	this.left = source.left;
-	this.right = source.right;
-	this.top = source.top;
-	this.bottom = source.bottom;
-
-	this.zoom = source.zoom;
-	this.view = source.view === null ? null : Object.assign( {}, source.view );
-	this.aspect = source.aspect;
-
-	this.cameraO.copy( source.cameraO );
-	this.cameraP.copy( source.cameraP );
-
-	this.inOrthographicMode = source.inOrthographicMode;
-	this.inPerspectiveMode = source.inPerspectiveMode;
-
-	return this;
-
-};
-
-THREE.CombinedCamera.prototype.setViewOffset = function( fullWidth, fullHeight, x, y, width, height ) {
-
-	this.view = {
-		fullWidth: fullWidth,
-		fullHeight: fullHeight,
-		offsetX: x,
-		offsetY: y,
-		width: width,
-		height: height
-	};
-
-	if ( this.inPerspectiveMode ) {
-
-		this.aspect = fullWidth / fullHeight;
-
-		this.toPerspective();
-
-	} else {
-
-		this.toOrthographic();
-
-	}
-
-};
-
-THREE.CombinedCamera.prototype.clearViewOffset = function() {
-
-	this.view = null;
-	this.updateProjectionMatrix();
-
-};
-
-THREE.CombinedCamera.prototype.setSize = function( width, height ) {
-
-	this.cameraP.aspect = width / height;
-	this.left = - width / 2;
-	this.right = width / 2;
-	this.top = height / 2;
-	this.bottom = - height / 2;
-
-};
-
-
-THREE.CombinedCamera.prototype.setFov = function( fov ) {
-
-	this.fov = fov;
-
-	if ( this.inPerspectiveMode ) {
-
-		this.toPerspective();
-
-	} else {
-
-		this.toOrthographic();
-
-	}
-
-};
-
-// For maintaining similar API with PerspectiveCamera
-
-THREE.CombinedCamera.prototype.updateProjectionMatrix = function() {
-
-	if ( this.inPerspectiveMode ) {
-
-		this.toPerspective();
-
-	} else {
-
-		this.toPerspective();
-		this.toOrthographic();
-
-	}
-
-};
-
-/*
-* Uses Focal Length (in mm) to estimate and set FOV
-* 35mm (full frame) camera is used if frame size is not specified;
-* Formula based on http://www.bobatkins.com/photography/technical/field_of_view.html
-*/
-THREE.CombinedCamera.prototype.setLens = function ( focalLength, filmGauge ) {
-
-	if ( filmGauge === undefined ) filmGauge = 35;
-
-	var vExtentSlope = 0.5 * filmGauge /
-			( focalLength * Math.max( this.cameraP.aspect, 1 ) );
-
-	var fov = THREE.Math.RAD2DEG * 2 * Math.atan( vExtentSlope );
-
-	this.setFov( fov );
-
-	return fov;
-
-};
-
-
-THREE.CombinedCamera.prototype.setZoom = function( zoom ) {
-
-	this.zoom = zoom;
-
-	if ( this.inPerspectiveMode ) {
-
-		this.toPerspective();
-
-	} else {
-
-		this.toOrthographic();
-
-	}
-
-};
-
-THREE.CombinedCamera.prototype.toFrontView = function() {
-
-	this.rotation.x = 0;
-	this.rotation.y = 0;
-	this.rotation.z = 0;
-
-	// should we be modifing the matrix instead?
-
-};
-
-THREE.CombinedCamera.prototype.toBackView = function() {
-
-	this.rotation.x = 0;
-	this.rotation.y = Math.PI;
-	this.rotation.z = 0;
-
-};
-
-THREE.CombinedCamera.prototype.toLeftView = function() {
-
-	this.rotation.x = 0;
-	this.rotation.y = - Math.PI / 2;
-	this.rotation.z = 0;
-
-};
-
-THREE.CombinedCamera.prototype.toRightView = function() {
-
-	this.rotation.x = 0;
-	this.rotation.y = Math.PI / 2;
-	this.rotation.z = 0;
-
-};
-
-THREE.CombinedCamera.prototype.toTopView = function() {
-
-	this.rotation.x = - Math.PI / 2;
-	this.rotation.y = 0;
-	this.rotation.z = 0;
-
-};
-
-THREE.CombinedCamera.prototype.toBottomView = function() {
-
-	this.rotation.x = Math.PI / 2;
-	this.rotation.y = 0;
-	this.rotation.z = 0;
-
-};

+ 5 - 5
examples/js/controls/TrackballControls.js

@@ -475,13 +475,13 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 		switch ( event.deltaMode ) {
 
-                        case 2:
-                                // Zoom in pages
-                                _zoomStart.y -= event.deltaY * 0.025;
-                                break;
+			case 2:
+				// Zoom in pages
+				_zoomStart.y -= event.deltaY * 0.025;
+				break;
 
 			case 1:
-                                // Zoom in lines
+				// Zoom in lines
 				_zoomStart.y -= event.deltaY * 0.01;
 				break;
 

+ 271 - 123
examples/js/exporters/GLTFExporter.js

@@ -3,14 +3,47 @@
  */
 
 //------------------------------------------------------------------------------
-// GLTF Exporter
+// Constants
 //------------------------------------------------------------------------------
-THREE.GLTFExporter = function ( renderer ) {
-
-	this.renderer = renderer;
+var WEBGL_CONSTANTS = {
+	POINTS: 0x0000,
+	LINES: 0x0001,
+	LINE_LOOP: 0x0002,
+	LINE_STRIP: 0x0003,
+	TRIANGLES: 0x0004,
+	TRIANGLE_STRIP: 0x0005,
+	TRIANGLE_FAN: 0x0006,
+
+	UNSIGNED_BYTE: 0x1401,
+	UNSIGNED_SHORT: 0x1403,
+	FLOAT: 0x1406,
+	UNSIGNED_INT: 0x1405,
+	ARRAY_BUFFER: 0x8892,
+	ELEMENT_ARRAY_BUFFER: 0x8893,
+
+	NEAREST: 0x2600,
+	LINEAR: 0x2601,
+	NEAREST_MIPMAP_NEAREST: 0x2700,
+	LINEAR_MIPMAP_NEAREST: 0x2701,
+	NEAREST_MIPMAP_LINEAR: 0x2702,
+	LINEAR_MIPMAP_LINEAR: 0x2703
+};
 
+var THREE_TO_WEBGL = {
+	// @TODO Replace with computed property name [THREE.*] when available on es6
+	1003: WEBGL_CONSTANTS.NEAREST,
+	1004: WEBGL_CONSTANTS.NEAREST_MIPMAP_NEAREST,
+	1005: WEBGL_CONSTANTS.NEAREST_MIPMAP_LINEAR,
+	1006: WEBGL_CONSTANTS.LINEAR,
+	1007: WEBGL_CONSTANTS.LINEAR_MIPMAP_NEAREST,
+	1008: WEBGL_CONSTANTS.LINEAR_MIPMAP_LINEAR
 };
 
+//------------------------------------------------------------------------------
+// GLTF Exporter
+//------------------------------------------------------------------------------
+THREE.GLTFExporter = function () {};
+
 THREE.GLTFExporter.prototype = {
 
 	constructor: THREE.GLTFExporter,
@@ -24,24 +57,33 @@ THREE.GLTFExporter.prototype = {
 	 */
 	parse: function ( input, onDone, options ) {
 
-		options = options || {};
+		var DEFAULT_OPTIONS = {
+			trs: false,
+			onlyVisible: true,
+			truncateDrawRange: true
+		};
 
-		var glUtils = new THREE.WebGLUtils( this.renderer.context, this.renderer.extensions );
-		var gl = this.renderer.context;
+		options = Object.assign( {}, DEFAULT_OPTIONS, options );
 
 		var outputJSON = {
 
 			asset: {
 
 				version: "2.0",
-				generator: "THREE.JS GLTFExporter" // @QUESTION Does it support spaces?
+				generator: "THREE.GLTFExporter"
 
-		 	}
+			}
 
-    };
+		};
 
 		var byteOffset = 0;
 		var dataViews = [];
+		var cachedData = {
+
+			images: {},
+			materials: {}
+
+		};
 
 		/**
 		 * Compare two arrays
@@ -52,13 +94,13 @@ THREE.GLTFExporter.prototype = {
 		 * @param  {Array} array2 Array 2 to compare
 		 * @return {Boolean}        Returns true if both arrays are equal
 		 */
-		function equalArray ( array1, array2 ) {
+		function equalArray( array1, array2 ) {
 
-			return ( array1.length === array2.length ) && array1.every( function( element, index ) {
+			return ( array1.length === array2.length ) && array1.every( function ( element, index ) {
 
-    		return element === array2[ index ];
+				return element === array2[ index ];
 
-			});
+			} );
 
 		}
 
@@ -67,7 +109,7 @@ THREE.GLTFExporter.prototype = {
 		 * @param  {THREE.WebGLAttribute} attribute Attribute to find the min/max
 		 * @return {Object} Object containing the `min` and `max` values (As an array of attribute.itemSize components)
 		 */
-		function getMinMax ( attribute ) {
+		function getMinMax( attribute ) {
 
 			var output = {
 
@@ -76,9 +118,9 @@ THREE.GLTFExporter.prototype = {
 
 			};
 
-			for ( var i = 0; i < attribute.count; i++ ) {
+			for ( var i = 0; i < attribute.count; i ++ ) {
 
-				for ( var a = 0; a < attribute.itemSize; a++ ) {
+				for ( var a = 0; a < attribute.itemSize; a ++ ) {
 
 					var value = attribute.array[ i * attribute.itemSize + a ];
 					output.min[ a ] = Math.min( output.min[ a ], value );
@@ -89,6 +131,7 @@ THREE.GLTFExporter.prototype = {
 			}
 
 			return output;
+
 		}
 
 		/**
@@ -97,9 +140,9 @@ THREE.GLTFExporter.prototype = {
 		 * @param  {Integer} componentType Component type (Unsigned short, unsigned int or float)
 		 * @return {Integer}               Index of the buffer created (Currently always 0)
 		 */
-		function processBuffer ( attribute, componentType ) {
+		function processBuffer( attribute, componentType, start, count ) {
 
-			if ( !outputJSON.buffers ) {
+			if ( ! outputJSON.buffers ) {
 
 				outputJSON.buffers = [
 
@@ -114,33 +157,35 @@ THREE.GLTFExporter.prototype = {
 
 			}
 
+			var offset = 0;
+			var componentSize = componentType === WEBGL_CONSTANTS.UNSIGNED_SHORT ? 2 : 4;
+
 			// Create a new dataview and dump the attribute's array into it
-			var dataView = new DataView( new ArrayBuffer( attribute.array.byteLength ) );
+			var byteLength = count * attribute.itemSize * componentSize;
 
-			var offset = 0;
-			var offsetInc = componentType === gl.UNSIGNED_SHORT ? 2 : 4;
+			var dataView = new DataView( new ArrayBuffer( byteLength ) );
 
-			for ( var i = 0; i < attribute.count; i++ ) {
+			for ( var i = start; i < start + count; i ++ ) {
 
-				for (var a = 0; a < attribute.itemSize; a++ ) {
+				for ( var a = 0; a < attribute.itemSize; a ++ ) {
 
 					var value = attribute.array[ i * attribute.itemSize + a ];
 
-					if ( componentType === gl.FLOAT ) {
+					if ( componentType === WEBGL_CONSTANTS.FLOAT ) {
 
 						dataView.setFloat32( offset, value, true );
 
-					} else if ( componentType === gl.UNSIGNED_INT ) {
+					} else if ( componentType === WEBGL_CONSTANTS.UNSIGNED_INT ) {
 
 						dataView.setUint8( offset, value, true );
 
-					} else if ( componentType === gl.UNSIGNED_SHORT ) {
+					} else if ( componentType === WEBGL_CONSTANTS.UNSIGNED_SHORT ) {
 
 						dataView.setUint16( offset, value, true );
 
 					}
 
-					offset += offsetInc;
+					offset += componentSize;
 
 				}
 
@@ -151,6 +196,7 @@ THREE.GLTFExporter.prototype = {
 
 			// Always using just one buffer
 			return 0;
+
 		}
 
 		/**
@@ -158,27 +204,32 @@ THREE.GLTFExporter.prototype = {
 		 * @param  {[type]} data [description]
 		 * @return {[type]}      [description]
 		 */
-		function processBufferView ( data, componentType ) {
+		function processBufferView( data, componentType, start, count ) {
 
-			var isVertexAttributes = componentType === gl.FLOAT;
+			var isVertexAttributes = componentType === WEBGL_CONSTANTS.FLOAT;
 
-			if ( !outputJSON.bufferViews ) {
+			if ( ! outputJSON.bufferViews ) {
 
 				outputJSON.bufferViews = [];
 
 			}
 
+			var componentSize = componentType === WEBGL_CONSTANTS.UNSIGNED_SHORT ? 2 : 4;
+
+			// Create a new dataview and dump the attribute's array into it
+			var byteLength = count * data.itemSize * componentSize;
+
 			var gltfBufferView = {
 
-				buffer: processBuffer( data, componentType ),
+				buffer: processBuffer( data, componentType, start, count ),
 				byteOffset: byteOffset,
-				byteLength: data.array.byteLength,
-				byteStride: data.itemSize * ( componentType === gl.UNSIGNED_SHORT ? 2 : 4 ),
-				target: isVertexAttributes ? gl.ARRAY_BUFFER : gl.ELEMENT_ARRAY_BUFFER
+				byteLength: byteLength,
+				byteStride: data.itemSize * componentSize,
+				target: isVertexAttributes ? WEBGL_CONSTANTS.ARRAY_BUFFER : WEBGL_CONSTANTS.ELEMENT_ARRAY_BUFFER
 
 			};
 
-			byteOffset += data.array.byteLength;
+			byteOffset += byteLength;
 
 			outputJSON.bufferViews.push( gltfBufferView );
 
@@ -199,9 +250,9 @@ THREE.GLTFExporter.prototype = {
 		 * @param  {THREE.WebGLAttribute} attribute Attribute to process
 		 * @return {Integer}           Index of the processed accessor on the "accessors" array
 		 */
-		function processAccessor ( attribute ) {
+		function processAccessor( attribute, geometry ) {
 
-			if ( !outputJSON.accessors ) {
+			if ( ! outputJSON.accessors ) {
 
 				outputJSON.accessors = [];
 
@@ -221,31 +272,43 @@ THREE.GLTFExporter.prototype = {
 			// Detect the component type of the attribute array (float, uint or ushort)
 			if ( attribute.array.constructor === Float32Array ) {
 
-				componentType = gl.FLOAT;
+				componentType = WEBGL_CONSTANTS.FLOAT;
 
 			} else if ( attribute.array.constructor === Uint32Array ) {
 
-				componentType = gl.UNSIGNED_INT;
+				componentType = WEBGL_CONSTANTS.UNSIGNED_INT;
 
 			} else if ( attribute.array.constructor === Uint16Array ) {
 
-				componentType = gl.UNSIGNED_SHORT;
+				componentType = WEBGL_CONSTANTS.UNSIGNED_SHORT;
 
 			} else {
 
-				throw new Error( 'THREE.GLTF2Exporter: Unsupported bufferAttribute component type.' );
+				throw new Error( 'THREE.GLTFExporter: Unsupported bufferAttribute component type.' );
 
 			}
 
 			var minMax = getMinMax( attribute );
-			var bufferView = processBufferView( attribute, componentType );
+
+			var start = 0;
+			var count = attribute.count;
+
+			// @TODO Indexed buffer geometry with drawRange not supported yet
+			if ( options.truncateDrawRange && geometry.index === null ) {
+
+				start = geometry.drawRange.start;
+				count = geometry.drawRange.count !== Infinity ? geometry.drawRange.count : attribute.count;
+
+			}
+
+			var bufferView = processBufferView( attribute, componentType, start, count );
 
 			var gltfAccessor = {
 
 				bufferView: bufferView.id,
 				byteOffset: bufferView.byteOffset,
 				componentType: componentType,
-				count: attribute.count,
+				count: count,
 				max: minMax.max,
 				min: minMax.min,
 				type: types[ attribute.itemSize - 1 ]
@@ -263,9 +326,15 @@ THREE.GLTFExporter.prototype = {
 		 * @param  {Texture} map Texture to process
 		 * @return {Integer}     Index of the processed texture in the "images" array
 		 */
-		function processImage ( map ) {
+		function processImage( map ) {
+
+			if ( cachedData.images[ map.uuid ] ) {
+
+				return cachedData.images[ map.uuid ];
 
-			if ( !outputJSON.images ) {
+			}
+
+			if ( ! outputJSON.images ) {
 
 				outputJSON.images = [];
 
@@ -286,7 +355,10 @@ THREE.GLTFExporter.prototype = {
 
 			outputJSON.images.push( gltfImage );
 
-			return outputJSON.images.length - 1;
+			var index = outputJSON.images.length - 1;
+			cachedData.images[ map.uuid ] = index;
+
+			return index;
 
 		}
 
@@ -295,9 +367,9 @@ THREE.GLTFExporter.prototype = {
 		 * @param  {Texture} map Texture to process
 		 * @return {Integer}     Index of the processed texture in the "samplers" array
 		 */
-		function processSampler ( map ) {
+		function processSampler( map ) {
 
-			if ( !outputJSON.samplers ) {
+			if ( ! outputJSON.samplers ) {
 
 				outputJSON.samplers = [];
 
@@ -305,10 +377,10 @@ THREE.GLTFExporter.prototype = {
 
 			var gltfSampler = {
 
-				magFilter: glUtils.convert( map.magFilter ),
-				minFilter: glUtils.convert( map.minFilter ),
-				wrapS: glUtils.convert( map.wrapS ),
-				wrapT: glUtils.convert( map.wrapT )
+				magFilter: THREE_TO_WEBGL[ map.magFilter ],
+				minFilter: THREE_TO_WEBGL[ map.minFilter ],
+				wrapS: THREE_TO_WEBGL[ map.wrapS ],
+				wrapT: THREE_TO_WEBGL[ map.wrapT ]
 
 			};
 
@@ -323,9 +395,9 @@ THREE.GLTFExporter.prototype = {
 		 * @param  {Texture} map Map to process
 		 * @return {Integer}     Index of the processed texture in the "textures" array
 		 */
-		function processTexture ( map ) {
+		function processTexture( map ) {
 
-			if (!outputJSON.textures) {
+			if ( ! outputJSON.textures ) {
 
 				outputJSON.textures = [];
 
@@ -349,17 +421,31 @@ THREE.GLTFExporter.prototype = {
 		 * @param  {THREE.Material} material Material to process
 		 * @return {Integer}      Index of the processed material in the "materials" array
 		 */
-		function processMaterial ( material ) {
+		function processMaterial( material ) {
 
-			if ( !outputJSON.materials ) {
+			if ( cachedData.materials[ material.uuid ] ) {
+
+				return cachedData.materials[ material.uuid ];
+
+			}
+
+			if ( ! outputJSON.materials ) {
 
 				outputJSON.materials = [];
 
 			}
 
-			if ( !( material instanceof THREE.MeshStandardMaterial ) ) {
+			if ( material instanceof THREE.ShaderMaterial ) {
+
+				console.warn( 'GLTFExporter: THREE.ShaderMaterial not supported.' );
+				return null;
+
+			}
+
 
-				console.warn( 'Currently just THREE.StandardMaterial is supported. Material conversion may lose information.' );
+			if ( ! ( material instanceof THREE.MeshStandardMaterial ) ) {
+
+				console.warn( 'GLTFExporter: Currently just THREE.StandardMaterial is supported. Material conversion may lose information.' );
 
 			}
 
@@ -373,7 +459,7 @@ THREE.GLTFExporter.prototype = {
 			// pbrMetallicRoughness.baseColorFactor
 			var color = material.color.toArray().concat( [ material.opacity ] );
 
-			if ( !equalArray( color, [ 1, 1, 1, 1 ] ) ) {
+			if ( ! equalArray( color, [ 1, 1, 1, 1 ] ) ) {
 
 				gltfMaterial.pbrMetallicRoughness.baseColorFactor = color;
 
@@ -384,10 +470,10 @@ THREE.GLTFExporter.prototype = {
 				gltfMaterial.pbrMetallicRoughness.metallicFactor = material.metalness;
 				gltfMaterial.pbrMetallicRoughness.roughnessFactor = material.roughness;
 
- 			} else {
+			} else {
 
-					gltfMaterial.pbrMetallicRoughness.metallicFactor = 0.5;
-					gltfMaterial.pbrMetallicRoughness.roughnessFactor = 0.5;
+				gltfMaterial.pbrMetallicRoughness.metallicFactor = 0.5;
+				gltfMaterial.pbrMetallicRoughness.roughnessFactor = 0.5;
 
 			}
 
@@ -396,8 +482,7 @@ THREE.GLTFExporter.prototype = {
 
 				gltfMaterial.pbrMetallicRoughness.baseColorTexture = {
 
-					index: processTexture( material.map ),
-					texCoord: 0 // @FIXME
+					index: processTexture( material.map )
 
 				};
 
@@ -412,7 +497,7 @@ THREE.GLTFExporter.prototype = {
 				// emissiveFactor
 				var emissive = material.emissive.clone().multiplyScalar( material.emissiveIntensity ).toArray();
 
-				if ( !equalArray( emissive, [ 0, 0, 0 ] ) ) {
+				if ( ! equalArray( emissive, [ 0, 0, 0 ] ) ) {
 
 					gltfMaterial.emissiveFactor = emissive;
 
@@ -423,8 +508,7 @@ THREE.GLTFExporter.prototype = {
 
 					gltfMaterial.emissiveTexture = {
 
-						index: processTexture( material.emissiveMap ),
-						texCoord: 0 // @FIXME
+						index: processTexture( material.emissiveMap )
 
 					};
 
@@ -437,11 +521,22 @@ THREE.GLTFExporter.prototype = {
 
 				gltfMaterial.normalTexture = {
 
-					index: processTexture( material.normalMap ),
-					texCoord: 0 // @FIXME
+					index: processTexture( material.normalMap )
 
 				};
 
+				if ( material.normalScale.x !== - 1 ) {
+
+					if ( material.normalScale.x !== material.normalScale.y ) {
+
+						console.warn( 'THREE.GLTFExporter: Normal scale components are different, ignoring Y and exporting X.' );
+
+					}
+
+					gltfMaterial.normalTexture.scale = material.normalScale.x;
+
+				}
+
 			}
 
 			// occlusionTexture
@@ -449,17 +544,28 @@ THREE.GLTFExporter.prototype = {
 
 				gltfMaterial.occlusionTexture = {
 
-					index: processTexture( material.aoMap ),
-					texCoord: 0 // @FIXME
+					index: processTexture( material.aoMap )
 
 				};
 
+				if ( material.aoMapIntensity !== 1.0 ) {
+
+					gltfMaterial.occlusionTexture.strength = material.aoMapIntensity;
+
+				}
+
 			}
 
 			// alphaMode
 			if ( material.transparent ) {
 
-				gltfMaterial.alphaMode = 'BLEND'; // @FIXME We should detect MASK or BLEND
+				gltfMaterial.alphaMode = 'MASK'; // @FIXME We should detect MASK or BLEND
+
+				if ( material.alphaTest !== 0.5 ) {
+
+					gltfMaterial.alphaCutoff = material.alphaTest;
+
+				}
 
 			}
 
@@ -478,7 +584,10 @@ THREE.GLTFExporter.prototype = {
 
 			outputJSON.materials.push( gltfMaterial );
 
-			return outputJSON.materials.length - 1;
+			var index = outputJSON.materials.length - 1;
+			cachedData.materials[ material.uuid ] = index;
+
+			return index;
 
 		}
 
@@ -489,7 +598,7 @@ THREE.GLTFExporter.prototype = {
 		 */
 		function processMesh( mesh ) {
 
-			if ( !outputJSON.meshes ) {
+			if ( ! outputJSON.meshes ) {
 
 				outputJSON.meshes = [];
 
@@ -497,26 +606,28 @@ THREE.GLTFExporter.prototype = {
 
 			var geometry = mesh.geometry;
 
+			var mode;
+
 			// Use the correct mode
 			if ( mesh instanceof THREE.LineSegments ) {
 
-				mode = gl.LINES;
+				mode = WEBGL_CONSTANTS.LINES;
 
 			} else if ( mesh instanceof THREE.LineLoop ) {
 
-				mode = gl.LINE_LOOP;
+				mode = WEBGL_CONSTANTS.LINE_LOOP;
 
 			} else if ( mesh instanceof THREE.Line ) {
 
-				mode = gl.LINE_STRIP;
+				mode = WEBGL_CONSTANTS.LINE_STRIP;
 
 			} else if ( mesh instanceof THREE.Points ) {
 
-				mode = gl.POINTS;
+				mode = WEBGL_CONSTANTS.POINTS;
 
 			} else {
 
-				if ( !( geometry instanceof THREE.BufferGeometry) ) {
+				if ( ! geometry.isBufferGeometry ) {
 
 					var geometryTemp = new THREE.BufferGeometry();
 					geometryTemp.fromGeometry( geometry );
@@ -527,15 +638,15 @@ THREE.GLTFExporter.prototype = {
 				if ( mesh.drawMode === THREE.TriangleFanDrawMode ) {
 
 					console.warn( 'GLTFExporter: TriangleFanDrawMode and wireframe incompatible.' );
-					mode = gl.TRIANGLE_FAN;
+					mode = WEBGL_CONSTANTS.TRIANGLE_FAN;
 
 				} else if ( mesh.drawMode === THREE.TriangleStripDrawMode ) {
 
-					mode = mesh.material.wireframe ? gl.LINE_STRIP : gl.TRIANGLE_STRIP;
+					mode = mesh.material.wireframe ? WEBGL_CONSTANTS.LINE_STRIP : WEBGL_CONSTANTS.TRIANGLE_STRIP;
 
 				} else {
 
-					mode = mesh.material.wireframe ? gl.LINES : gl.TRIANGLES;
+					mode = mesh.material.wireframe ? WEBGL_CONSTANTS.LINES : WEBGL_CONSTANTS.TRIANGLES;
 
 				}
 
@@ -546,20 +657,26 @@ THREE.GLTFExporter.prototype = {
 					{
 						mode: mode,
 						attributes: {},
-						material: processMaterial( mesh.material )
 					}
 				]
 			};
 
+			var material = processMaterial( mesh.material );
+			if ( material !== null ) {
+
+				gltfMesh.primitives[ 0 ].material = material;
+
+			}
+
+
 			if ( geometry.index ) {
 
-				gltfMesh.primitives[ 0 ].indices = processAccessor( geometry.index );
+				gltfMesh.primitives[ 0 ].indices = processAccessor( geometry.index, geometry );
 
 			}
 
 			// We've just one primitive per mesh
 			var gltfAttributes = gltfMesh.primitives[ 0 ].attributes;
-			var attributes = geometry.attributes;
 
 			// Conversion between attributes names in threejs and gltf spec
 			var nameConversion = {
@@ -578,13 +695,14 @@ THREE.GLTFExporter.prototype = {
 
 				var attribute = geometry.attributes[ attributeName ];
 				attributeName = nameConversion[ attributeName ] || attributeName.toUpperCase();
-				gltfAttributes[ attributeName ] = processAccessor( attribute );
+				gltfAttributes[ attributeName ] = processAccessor( attribute, geometry );
 
 			}
 
 			outputJSON.meshes.push( gltfMesh );
 
 			return outputJSON.meshes.length - 1;
+
 		}
 
 		/**
@@ -594,7 +712,7 @@ THREE.GLTFExporter.prototype = {
 		 */
 		function processCamera( camera ) {
 
-			if ( !outputJSON.cameras ) {
+			if ( ! outputJSON.cameras ) {
 
 				outputJSON.cameras = [];
 
@@ -641,6 +759,7 @@ THREE.GLTFExporter.prototype = {
 			outputJSON.cameras.push( gltfCamera );
 
 			return outputJSON.cameras.length - 1;
+
 		}
 
 		/**
@@ -648,9 +767,16 @@ THREE.GLTFExporter.prototype = {
 		 * @param  {THREE.Object3D} node Object3D to processNode
 		 * @return {Integer}      Index of the node in the nodes list
 		 */
-		function processNode ( object ) {
+		function processNode( object ) {
+
+			if ( object instanceof THREE.Light ) {
+
+				console.warn( 'GLTFExporter: Unsupported node type:', object.constructor.name );
+				return null;
+
+			}
 
-			if ( !outputJSON.nodes ) {
+			if ( ! outputJSON.nodes ) {
 
 				outputJSON.nodes = [];
 
@@ -664,19 +790,19 @@ THREE.GLTFExporter.prototype = {
 				var position = object.position.toArray();
 				var scale = object.scale.toArray();
 
-				if ( !equalArray( rotation, [ 0, 0, 0, 1 ] ) ) {
+				if ( ! equalArray( rotation, [ 0, 0, 0, 1 ] ) ) {
 
 					gltfNode.rotation = rotation;
 
 				}
 
-				if ( !equalArray( position, [ 0, 0, 0 ] ) ) {
+				if ( ! equalArray( position, [ 0, 0, 0 ] ) ) {
 
 					gltfNode.position = position;
 
 				}
 
-				if ( !equalArray( scale, [ 1, 1, 1 ] ) ) {
+				if ( ! equalArray( scale, [ 1, 1, 1 ] ) ) {
 
 					gltfNode.scale = scale;
 
@@ -685,7 +811,7 @@ THREE.GLTFExporter.prototype = {
 			} else {
 
 				object.updateMatrix();
-				if (! equalArray( object.matrix.elements, [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ] ) ) {
+				if ( ! equalArray( object.matrix.elements, [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ] ) ) {
 
 					gltfNode.matrix = object.matrix.elements;
 
@@ -705,9 +831,9 @@ THREE.GLTFExporter.prototype = {
 
 					gltfNode.extras = JSON.parse( JSON.stringify( object.userData ) );
 
-				} catch (e) {
+				} catch ( e ) {
 
-					throw new Error( 'GLTFExporter: userData can\'t be serialized' );
+					throw new Error( 'THREE.GLTFExporter: userData can\'t be serialized' );
 
 				}
 
@@ -727,23 +853,33 @@ THREE.GLTFExporter.prototype = {
 
 			if ( object.children.length > 0 ) {
 
-				gltfNode.children = [];
+				var children = [];
 
 				for ( var i = 0, l = object.children.length; i < l; i ++ ) {
 
 					var child = object.children[ i ];
-					if ( child instanceof THREE.Mesh ||
-						child instanceof THREE.Camera ||
-						child instanceof THREE.Group ||
-						child instanceof THREE.Line ||
-						child instanceof THREE.Points) {
 
-						gltfNode.children.push( processNode( child ) );
+					if ( child.visible || options.onlyVisible === false ) {
+
+						var node = processNode( child );
+
+						if ( node !== null ) {
+
+							children.push( node );
+
+						}
 
 					}
 
 				}
 
+				if ( children.length > 0 ) {
+
+					gltfNode.children = children;
+
+				}
+
+
 			}
 
 			outputJSON.nodes.push( gltfNode );
@@ -758,7 +894,7 @@ THREE.GLTFExporter.prototype = {
 		 */
 		function processScene( scene ) {
 
-			if ( !outputJSON.scenes ) {
+			if ( ! outputJSON.scenes ) {
 
 				outputJSON.scenes = [];
 				outputJSON.scene = 0;
@@ -779,35 +915,44 @@ THREE.GLTFExporter.prototype = {
 
 			outputJSON.scenes.push( gltfScene );
 
+			var nodes = [];
+
 			for ( var i = 0, l = scene.children.length; i < l; i ++ ) {
 
 				var child = scene.children[ i ];
 
-				// @TODO We don't process lights yet
-				if ( child instanceof THREE.Mesh ||
-					child instanceof THREE.Camera ||
-					child instanceof THREE.Group ||
-					child instanceof THREE.Line ||
-					child instanceof THREE.Points) {
+				if ( child.visible || options.onlyVisible === false ) {
+
+					var node = processNode( child );
 
-					gltfScene.nodes.push( processNode( child ) );
+					if ( node !== null ) {
+
+						nodes.push( node );
+
+					}
 
 				}
 
 			}
 
+			if ( nodes.length > 0 ) {
+
+				gltfScene.nodes = nodes;
+
+			}
+
 		}
 
 		/**
 		 * Creates a THREE.Scene to hold a list of objects and parse it
 		 * @param  {Array} objects List of objects to process
 		 */
-		function processObjects ( objects ) {
+		function processObjects( objects ) {
 
 			var scene = new THREE.Scene();
 			scene.name = 'AuxScene';
 
-			for ( var i = 0; i < objects.length; i++ ) {
+			for ( var i = 0; i < objects.length; i ++ ) {
 
 				// We push directly to children instead of calling `add` to prevent
 				// modify the .parent and break its original scene and hierarchy
@@ -824,7 +969,8 @@ THREE.GLTFExporter.prototype = {
 			input = input instanceof Array ? input : [ input ];
 
 			var objectsWithoutScene = [];
-			for ( i = 0; i < input.length; i++ ) {
+
+			for ( var i = 0; i < input.length; i ++ ) {
 
 				if ( input[ i ] instanceof THREE.Scene ) {
 
@@ -850,28 +996,30 @@ THREE.GLTFExporter.prototype = {
 
 		// Generate buffer
 		// Create a new blob with all the dataviews from the buffers
-		var blob = new Blob( dataViews, { type: 'application/octet-binary' } );
+		var blob = new Blob( dataViews, { type: 'application/octet-stream' } );
 
 		// Update the bytlength of the only main buffer and update the uri with the base64 representation of it
 		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 );
-			 reader.onloadend = function() {
+			reader.readAsDataURL( blob );
+			reader.onloadend = function () {
 
-				 base64data = reader.result;
-				 outputJSON.buffers[ 0 ].uri = base64data;
-				 onDone( outputJSON );
+				var base64data = reader.result;
+				outputJSON.buffers[ 0 ].uri = base64data;
+				onDone( outputJSON );
 
-			 };
+			};
 
 		} else {
 
-			onDone ( outputJSON );
+			onDone( outputJSON );
 
 		}
+
 	}
+
 };

+ 5 - 6
examples/js/exporters/MMDExporter.js

@@ -37,7 +37,7 @@ THREE.MMDExporter = function () {
 
 		for ( var i = 0, il = str.length; i < il; i ++ ) {
 
-			var code = str.charCodeAt( i )
+			var code = str.charCodeAt( i );
 
 			var value = u2sTable[ code ];
 
@@ -104,7 +104,7 @@ THREE.MMDExporter = function () {
 
 			var a = num.toString();
 
-			if ( a.indexOf( '.' ) === -1 ) {
+			if ( a.indexOf( '.' ) === - 1 ) {
 
 				a += '.';
 
@@ -180,9 +180,9 @@ THREE.MMDExporter = function () {
 			var qArray = quaternion2.copy( bone2.quaternion ).conjugate().multiply( quaternion ).toArray();
 
 			// right to left
-			pArray[ 2 ] = -pArray[ 2 ];
-			qArray[ 0 ] = -qArray[ 0 ];
-			qArray[ 1 ] = -qArray[ 1 ];
+			pArray[ 2 ] = - pArray[ 2 ];
+			qArray[ 0 ] = - qArray[ 0 ];
+			qArray[ 1 ] = - qArray[ 1 ];
 
 			array.push( 'Bone' + i + '{' + bone.name );
 			array.push( '  ' + toStringsFromArray( pArray ) + ';' );
@@ -208,4 +208,3 @@ THREE.MMDExporter = function () {
 	*/
 
 };
-

+ 16 - 15
examples/js/exporters/OBJExporter.js

@@ -51,14 +51,16 @@ THREE.OBJExporter.prototype = {
 
 				// name of the mesh material
 				if ( mesh.material && mesh.material.name ) {
+
 					output += 'usemtl ' + mesh.material.name + '\n';
+
 				}
 
 				// vertices
 
-				if( vertices !== undefined ) {
+				if ( vertices !== undefined ) {
 
-					for ( i = 0, l = vertices.count; i < l; i ++, nbVertex++ ) {
+					for ( i = 0, l = vertices.count; i < l; i ++, nbVertex ++ ) {
 
 						vertex.x = vertices.getX( i );
 						vertex.y = vertices.getY( i );
@@ -76,9 +78,9 @@ THREE.OBJExporter.prototype = {
 
 				// uvs
 
-				if( uvs !== undefined ) {
+				if ( uvs !== undefined ) {
 
-					for ( i = 0, l = uvs.count; i < l; i ++, nbVertexUvs++ ) {
+					for ( i = 0, l = uvs.count; i < l; i ++, nbVertexUvs ++ ) {
 
 						uv.x = uvs.getX( i );
 						uv.y = uvs.getY( i );
@@ -92,11 +94,11 @@ THREE.OBJExporter.prototype = {
 
 				// normals
 
-				if( normals !== undefined ) {
+				if ( normals !== undefined ) {
 
 					normalMatrixWorld.getNormalMatrix( mesh.matrixWorld );
 
-					for ( i = 0, l = normals.count; i < l; i ++, nbNormals++ ) {
+					for ( i = 0, l = normals.count; i < l; i ++, nbNormals ++ ) {
 
 						normal.x = normals.getX( i );
 						normal.y = normals.getY( i );
@@ -114,11 +116,11 @@ THREE.OBJExporter.prototype = {
 
 				// faces
 
-				if( indices !== null ) {
+				if ( indices !== null ) {
 
 					for ( i = 0, l = indices.count; i < l; i += 3 ) {
 
-						for( m = 0; m < 3; m ++ ){
+						for ( m = 0; m < 3; m ++ ) {
 
 							j = indices.getX( i + m ) + 1;
 
@@ -135,7 +137,7 @@ THREE.OBJExporter.prototype = {
 
 					for ( i = 0, l = vertices.count; i < l; i += 3 ) {
 
-						for( m = 0; m < 3; m ++ ){
+						for ( m = 0; m < 3; m ++ ) {
 
 							j = i + m + 1;
 
@@ -163,7 +165,7 @@ THREE.OBJExporter.prototype = {
 
 		};
 
-		var parseLine = function( line ) {
+		var parseLine = function ( line ) {
 
 			var nbVertex = 0;
 
@@ -180,14 +182,13 @@ THREE.OBJExporter.prototype = {
 
 				// shortcuts
 				var vertices = geometry.getAttribute( 'position' );
-				var indices = geometry.getIndex();
 
 				// name of the line object
 				output += 'o ' + line.name + '\n';
 
-				if( vertices !== undefined ) {
+				if ( vertices !== undefined ) {
 
-					for ( i = 0, l = vertices.count; i < l; i ++, nbVertex++ ) {
+					for ( i = 0, l = vertices.count; i < l; i ++, nbVertex ++ ) {
 
 						vertex.x = vertices.getX( i );
 						vertex.y = vertices.getY( i );
@@ -207,7 +208,7 @@ THREE.OBJExporter.prototype = {
 
 					output += 'l ';
 
-					for ( j = 1, l = vertices.count; j <= l; j++ ) {
+					for ( j = 1, l = vertices.count; j <= l; j ++ ) {
 
 						output += ( indexVertex + j ) + ' ';
 
@@ -229,7 +230,7 @@ THREE.OBJExporter.prototype = {
 
 			} else {
 
-				console.warn('THREE.OBJExporter.parseLine(): geometry type unsupported', geometry );
+				console.warn( 'THREE.OBJExporter.parseLine(): geometry type unsupported', geometry );
 
 			}
 

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

@@ -27,7 +27,7 @@ THREE.STLExporter.prototype = {
 					var geometry = object.geometry;
 					var matrixWorld = object.matrixWorld;
 
-					if( geometry instanceof THREE.BufferGeometry ) {
+					if ( geometry instanceof THREE.BufferGeometry ) {
 
 						geometry = new THREE.Geometry().fromBufferGeometry( geometry );
 

+ 2 - 2
examples/js/exporters/TypedGeometryExporter.js

@@ -23,7 +23,7 @@ THREE.TypedGeometryExporter.prototype = {
 		for ( var key in attributes ) {
 
 			var attribute = attributes[ key ];
-			
+
 			var typedArray = geometry[ attribute ];
 			var array = [];
 
@@ -44,7 +44,7 @@ THREE.TypedGeometryExporter.prototype = {
 			output.boundingSphere = {
 				center: boundingSphere.center.toArray(),
 				radius: boundingSphere.radius
-			}
+			};
 
 		}
 

+ 2 - 2
examples/js/geometries/ConvexGeometry.js

@@ -2,7 +2,7 @@
  * @author Mugen87 / https://github.com/Mugen87
  */
 
-( function() {
+( function () {
 
 	// ConvexGeometry
 
@@ -82,4 +82,4 @@
 	THREE.ConvexGeometry = ConvexGeometry;
 	THREE.ConvexBufferGeometry = ConvexBufferGeometry;
 
-} ) ();
+} )();

+ 23 - 23
examples/js/geometries/DecalGeometry.js

@@ -16,9 +16,9 @@
  *
  */
 
-( function() {
+( function () {
 
-  function DecalGeometry( mesh, position, orientation, size ) {
+	function DecalGeometry( mesh, position, orientation, size ) {
 
   	THREE.BufferGeometry.call( this );
 
@@ -54,7 +54,7 @@
 
   	function generate() {
 
-  		var i, j;
+  		var i;
   		var geometry = new THREE.BufferGeometry();
   		var decalVertices = [];
 
@@ -113,12 +113,12 @@
 
   		// second, clip the geometry so that it doesn't extend out from the projector
 
-  		decalVertices = clipGeometry( decalVertices, plane.set(   1,   0,   0 ) );
-  		decalVertices = clipGeometry( decalVertices, plane.set( - 1,   0,   0 ) );
-  		decalVertices = clipGeometry( decalVertices, plane.set(   0,   1,   0 ) );
-  		decalVertices = clipGeometry( decalVertices, plane.set(   0, - 1,   0 ) );
-  		decalVertices = clipGeometry( decalVertices, plane.set(   0,   0,   1 ) );
-  		decalVertices = clipGeometry( decalVertices, plane.set(   0,   0, - 1 ) );
+  		decalVertices = clipGeometry( decalVertices, plane.set( 1, 0, 0 ) );
+  		decalVertices = clipGeometry( decalVertices, plane.set( - 1, 0, 0 ) );
+  		decalVertices = clipGeometry( decalVertices, plane.set( 0, 1, 0 ) );
+  		decalVertices = clipGeometry( decalVertices, plane.set( 0, - 1, 0 ) );
+  		decalVertices = clipGeometry( decalVertices, plane.set( 0, 0, 1 ) );
+  		decalVertices = clipGeometry( decalVertices, plane.set( 0, 0, - 1 ) );
 
   		// third, generate final vertices, normals and uvs
 
@@ -332,28 +332,28 @@
 
   	}
 
-  }
+	}
 
-  DecalGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
-  DecalGeometry.prototype.constructor = DecalGeometry;
+	DecalGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
+	DecalGeometry.prototype.constructor = DecalGeometry;
 
-  // helper
+	// helper
 
-  function DecalVertex( position, normal ) {
+	function DecalVertex( position, normal ) {
 
-  	this.position = position;
-  	this.normal = normal;
+		this.position = position;
+		this.normal = normal;
 
-  }
+	}
 
-  DecalVertex.prototype.clone = function() {
+	DecalVertex.prototype.clone = function () {
 
-  	return new DecalVertex( this.position.clone(), this.normal.clone() );
+		return new DecalVertex( this.position.clone(), this.normal.clone() );
 
-  };
+	};
 
-  // export
+	// export
 
-  THREE.DecalGeometry = DecalGeometry;
+	THREE.DecalGeometry = DecalGeometry;
 
-} ) ();
+} )();

+ 7 - 7
examples/js/geometries/hilbert2D.js

@@ -18,9 +18,9 @@
 function hilbert2D( center, size, iterations, v0, v1, v2, v3 ) {
 
 	// Default Vars
-	var center     = undefined !== center ? center : new THREE.Vector3( 0, 0, 0 ),
-		size       = undefined !== size ? size : 10,
-		half       = size / 2,
+	var center = undefined !== center ? center : new THREE.Vector3( 0, 0, 0 ),
+		size = undefined !== size ? size : 10,
+		half = size / 2,
 		iterations = undefined !== iterations ? iterations : 1,
 		v0 = undefined !== v0 ? v0 : 0,
 		v1 = undefined !== v1 ? v1 : 1,
@@ -47,10 +47,10 @@ function hilbert2D( center, size, iterations, v0, v1, v2, v3 ) {
 
 		var tmp = [];
 
-		Array.prototype.push.apply( tmp, hilbert2D ( vec[ 0 ], half, iterations, v0, v3, v2, v1 ) );
-		Array.prototype.push.apply( tmp, hilbert2D ( vec[ 1 ], half, iterations, v0, v1, v2, v3 ) );
-		Array.prototype.push.apply( tmp, hilbert2D ( vec[ 2 ], half, iterations, v0, v1, v2, v3 ) );
-		Array.prototype.push.apply( tmp, hilbert2D ( vec[ 3 ], half, iterations, v2, v1, v0, v3 ) );
+		Array.prototype.push.apply( tmp, hilbert2D( vec[ 0 ], half, iterations, v0, v3, v2, v1 ) );
+		Array.prototype.push.apply( tmp, hilbert2D( vec[ 1 ], half, iterations, v0, v1, v2, v3 ) );
+		Array.prototype.push.apply( tmp, hilbert2D( vec[ 2 ], half, iterations, v0, v1, v2, v3 ) );
+		Array.prototype.push.apply( tmp, hilbert2D( vec[ 3 ], half, iterations, v2, v1, v0, v3 ) );
 
 		// Return recursive call
 		return tmp;

+ 11 - 11
examples/js/geometries/hilbert3D.js

@@ -27,9 +27,9 @@
 function hilbert3D( center, size, iterations, v0, v1, v2, v3, v4, v5, v6, v7 ) {
 
 	// Default Vars
-	var center     = undefined !== center ? center : new THREE.Vector3( 0, 0, 0 ),
-		size       = undefined !== size ? size : 10,
-		half       = size / 2,
+	var center = undefined !== center ? center : new THREE.Vector3( 0, 0, 0 ),
+		size = undefined !== size ? size : 10,
+		half = size / 2,
 		iterations = undefined !== iterations ? iterations : 1,
 		v0 = undefined !== v0 ? v0 : 0,
 		v1 = undefined !== v1 ? v1 : 1,
@@ -68,14 +68,14 @@ function hilbert3D( center, size, iterations, v0, v1, v2, v3, v4, v5, v6, v7 ) {
 
 		var tmp = [];
 
-		Array.prototype.push.apply( tmp, hilbert3D ( vec[ 0 ], half, iterations, v0, v3, v4, v7, v6, v5, v2, v1 ) );
-		Array.prototype.push.apply( tmp, hilbert3D ( vec[ 1 ], half, iterations, v0, v7, v6, v1, v2, v5, v4, v3 ) );
-		Array.prototype.push.apply( tmp, hilbert3D ( vec[ 2 ], half, iterations, v0, v7, v6, v1, v2, v5, v4, v3 ) );
-		Array.prototype.push.apply( tmp, hilbert3D ( vec[ 3 ], half, iterations, v2, v3, v0, v1, v6, v7, v4, v5 ) );
-		Array.prototype.push.apply( tmp, hilbert3D ( vec[ 4 ], half, iterations, v2, v3, v0, v1, v6, v7, v4, v5 ) );
-		Array.prototype.push.apply( tmp, hilbert3D ( vec[ 5 ], half, iterations, v4, v3, v2, v5, v6, v1, v0, v7 ) );
-		Array.prototype.push.apply( tmp, hilbert3D ( vec[ 6 ], half, iterations, v4, v3, v2, v5, v6, v1, v0, v7 ) );
-		Array.prototype.push.apply( tmp, hilbert3D ( vec[ 7 ], half, iterations, v6, v5, v2, v1, v0, v3, v4, v7 ) );
+		Array.prototype.push.apply( tmp, hilbert3D( vec[ 0 ], half, iterations, v0, v3, v4, v7, v6, v5, v2, v1 ) );
+		Array.prototype.push.apply( tmp, hilbert3D( vec[ 1 ], half, iterations, v0, v7, v6, v1, v2, v5, v4, v3 ) );
+		Array.prototype.push.apply( tmp, hilbert3D( vec[ 2 ], half, iterations, v0, v7, v6, v1, v2, v5, v4, v3 ) );
+		Array.prototype.push.apply( tmp, hilbert3D( vec[ 3 ], half, iterations, v2, v3, v0, v1, v6, v7, v4, v5 ) );
+		Array.prototype.push.apply( tmp, hilbert3D( vec[ 4 ], half, iterations, v2, v3, v0, v1, v6, v7, v4, v5 ) );
+		Array.prototype.push.apply( tmp, hilbert3D( vec[ 5 ], half, iterations, v4, v3, v2, v5, v6, v1, v0, v7 ) );
+		Array.prototype.push.apply( tmp, hilbert3D( vec[ 6 ], half, iterations, v4, v3, v2, v5, v6, v1, v0, v7 ) );
+		Array.prototype.push.apply( tmp, hilbert3D( vec[ 7 ], half, iterations, v6, v5, v2, v1, v0, v3, v4, v7 ) );
 
 		// Return recursive call
 		return tmp;

+ 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) {

+ 41 - 37
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 );
 
@@ -88,22 +88,22 @@ THREE.ThreeMFLoader.prototype = {
 
 			}
 
+			if ( window.TextDecoder === undefined ) {
+
+				console.error( 'THREE.ThreeMFLoader: TextDecoder not present. Please use a TextDecoder polyfill.' );
+				return null;
+
+			}
+
 			var relsView = new DataView( zip.file( relsName ).asArrayBuffer() );
 			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() );
 
-				if ( TextDecoder === undefined ) {
-
-					console.error( 'THREE.ThreeMFLoader: TextDecoder not present. Please use a TextDecoder polyfill.' );
-					return null;
-
-				}
-
 				var fileText = new TextDecoder( 'utf-8' ).decode( view );
 				var xmlData = new DOMParser().parseFromString( fileText, 'application/xml' );
 
@@ -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 );
 

+ 11 - 11
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 ) {
 
@@ -146,15 +146,15 @@ THREE.AMFLoader.prototype = {
 
 			var loadedMaterial = null;
 
-			for ( var i = 0; i < node.children.length; i ++ ) {
+			for ( var i = 0; i < node.childNodes.length; i ++ ) {
 
-				var matChildEl = node.children[ i ];
+				var matChildEl = node.childNodes[ i ];
 
 				if ( matChildEl.nodeName === 'metadata' && matChildEl.attributes.type !== undefined ) {
 
 					if ( matChildEl.attributes.type.value === 'name' ) {
 
-						matname = matChildEl.textContent;
+						matName = matChildEl.textContent;
 
 					}
 
@@ -187,9 +187,9 @@ THREE.AMFLoader.prototype = {
 
 			var color = { r: 1.0, g: 1.0, b: 1.0, a: 1.0 };
 
-			for ( var i = 0; i < node.children.length; i ++ ) {
+			for ( var i = 0; i < node.childNodes.length; i ++ ) {
 
-				var matColor = node.children[ i ];
+				var matColor = node.childNodes[ i ];
 
 				if ( matColor.nodeName === 'r' ) {
 
@@ -371,13 +371,13 @@ THREE.AMFLoader.prototype = {
 		var amfScale = loadDocumentScale( xmlData );
 		var amfMaterials = {};
 		var amfObjects = {};
-		var children = xmlData.documentElement.children;
+		var childNodes = xmlData.documentElement.childNodes;
 
 		var i, j;
 
-		for ( i = 0; i < children.length; i ++ ) {
+		for ( i = 0; i < childNodes.length; i ++ ) {
 
-			var child = children[ i ];
+			var child = childNodes[ i ];
 
 			if ( child.nodeName === 'metadata' ) {
 
@@ -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 );
 
 	}

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