Browse Source

Merge branch 'dev' of https://github.com/mrdoob/three.js into dev

Jaume Sanchez 9 years ago
parent
commit
c7645c27ab
100 changed files with 4435 additions and 1014 deletions
  1. 9 8
      .github/CONTRIBUTING.md
  2. 28 0
      .github/ISSUE_TEMPLATE.md
  3. 1 1
      README.md
  4. 347 171
      build/three.js
  5. 185 181
      build/three.min.js
  6. 9 19
      docs/api/core/BufferGeometry.html
  7. 58 0
      docs/api/extras/geometries/BoxBufferGeometry.html
  8. 44 0
      docs/api/extras/geometries/CircleBufferGeometry.html
  9. 4 9
      docs/api/extras/geometries/CircleGeometry.html
  10. 56 0
      docs/api/extras/geometries/CylinderBufferGeometry.html
  11. 52 0
      docs/api/extras/geometries/LatheBufferGeometry.html
  12. 6 5
      docs/api/extras/geometries/LatheGeometry.html
  13. 50 0
      docs/api/extras/geometries/PlaneBufferGeometry.html
  14. 45 0
      docs/api/extras/geometries/RingBufferGeometry.html
  15. 57 0
      docs/api/extras/geometries/SphereBufferGeometry.html
  16. 51 0
      docs/api/extras/geometries/TorusBufferGeometry.html
  17. 57 0
      docs/api/extras/geometries/TorusKnotBufferGeometry.html
  18. 9 8
      docs/api/extras/geometries/TorusKnotGeometry.html
  19. 1 1
      docs/api/extras/geometries/TubeGeometry.html
  20. 14 4
      docs/api/lights/AmbientLight.html
  21. 1 6
      docs/api/lights/DirectionalLight.html
  22. 6 5
      docs/api/lights/HemisphereLight.html
  23. 15 6
      docs/api/lights/PointLight.html
  24. 32 30
      docs/api/lights/SpotLight.html
  25. 0 88
      docs/api/loaders/OBJMTLLoader.html
  26. 2 1
      docs/api/materials/LineBasicMaterial.html
  27. 5 6
      docs/api/materials/LineDashedMaterial.html
  28. 20 16
      docs/api/materials/MeshBasicMaterial.html
  29. 8 8
      docs/api/materials/MeshDepthMaterial.html
  30. 24 10
      docs/api/materials/MeshLambertMaterial.html
  31. 1 1
      docs/api/materials/MeshNormalMaterial.html
  32. 45 25
      docs/api/materials/MeshPhongMaterial.html
  33. 221 0
      docs/api/materials/MeshStandardMaterial.html
  34. 9 8
      docs/api/materials/PointsMaterial.html
  35. 1 0
      docs/api/materials/ShaderMaterial.html
  36. 3 3
      docs/api/materials/SpriteMaterial.html
  37. 10 0
      docs/api/math/Vector2.html
  38. 10 0
      docs/api/math/Vector3.html
  39. 4 4
      docs/api/objects/LineSegments.html
  40. 0 5
      docs/api/renderers/WebGLRenderTarget.html
  41. 3 0
      docs/api/renderers/WebGLRenderer.html
  42. 5 0
      docs/api/textures/Texture.html
  43. 1 1
      docs/index.html
  44. 10 1
      docs/list.js
  45. 7 12
      docs/manual/introduction/Creating-a-scene.html
  46. 1 0
      docs/page.css
  47. 10 10
      docs/scenes/bones-browser.html
  48. 21 19
      docs/scenes/geometry-browser.html
  49. 357 10
      docs/scenes/js/geometry.js
  50. 43 0
      docs/scenes/js/material.js
  51. 12 12
      docs/scenes/material-browser.html
  52. 1 1
      editor/css/light.css
  53. 23 0
      editor/css/main.css
  54. 6 4
      editor/index.html
  55. 1 0
      editor/js/Config.js
  56. 1 9
      editor/js/Editor.js
  57. 3 4
      editor/js/Menubar.Add.js
  58. 10 2
      editor/js/Sidebar.Geometry.LatheGeometry.js
  59. 12 23
      editor/js/Sidebar.Geometry.TorusKnotGeometry.js
  60. 14 0
      editor/js/Sidebar.Project.js
  61. 3 1
      editor/js/Storage.js
  62. 10 10
      editor/js/libs/app.js
  63. 34 2
      editor/js/libs/app/index.html
  64. 0 1
      editor/js/libs/sortable.min.js
  65. 0 4
      editor/js/libs/tern-threejs/threejs.js
  66. 142 51
      editor/js/libs/ui.three.js
  67. 2 1
      examples/canvas_ascii_effect.html
  68. 2 1
      examples/canvas_camera_orthographic.html
  69. 2 1
      examples/canvas_camera_orthographic2.html
  70. 2 1
      examples/canvas_geometry_birds.html
  71. 2 1
      examples/canvas_geometry_cube.html
  72. 11 1
      examples/files.js
  73. 202 44
      examples/index.html
  74. 26 0
      examples/js/Encodings.js
  75. 51 0
      examples/js/Half.js
  76. 0 4
      examples/js/Ocean.js
  77. 6 8
      examples/js/ParametricGeometries.js
  78. 544 0
      examples/js/RollerCoaster.js
  79. 4 10
      examples/js/ShaderSkin.js
  80. 0 2
      examples/js/ShaderTerrain.js
  81. 448 0
      examples/js/Volume.js
  82. 217 0
      examples/js/VolumeSlice.js
  83. 97 0
      examples/js/WebVR.js
  84. 6 12
      examples/js/controls/EditorControls.js
  85. 21 39
      examples/js/controls/OrbitControls.js
  86. 19 0
      examples/js/controls/TrackballControls.js
  87. 48 18
      examples/js/controls/VRControls.js
  88. 5 3
      examples/js/effects/AnaglyphEffect.js
  89. 4 2
      examples/js/effects/CardboardEffect.js
  90. 5 3
      examples/js/effects/ParallaxBarrierEffect.js
  91. 132 23
      examples/js/effects/VREffect.js
  92. 71 4
      examples/js/exporters/OBJExporter.js
  93. 25 19
      examples/js/exporters/STLBinaryExporter.js
  94. 15 0
      examples/js/libs/inflate.min.js
  95. 51 0
      examples/js/libs/zlib_and_gzip.min.js
  96. 4 0
      examples/js/libs/zlib_and_gzip.min.js.map
  97. 99 6
      examples/js/loaders/ColladaLoader2.js
  98. 83 0
      examples/js/loaders/HDRCubeTextureLoader.js
  99. 0 2
      examples/js/loaders/MMDLoader.js
  100. 1 3
      examples/js/loaders/MTLLoader.js

+ 9 - 8
CONTRIBUTING.md → .github/CONTRIBUTING.md

@@ -1,27 +1,28 @@
-### The issues section is for bug reports and feature requests only. If you need help, please use [stackoverflow](http://stackoverflow.com/questions/tagged/three.js).
 
-
-Before reporting a bug
+# Help 
+#### The issues section is for bug reports and feature requests only. If you need help, please use [stackoverflow](http://stackoverflow.com/questions/tagged/three.js).
 ---
+# Bugs
+#### Before reporting a bug
+
 1. Search issue tracker for similar issues.
 2. Try the latest dev branch version of three.js.
 3. Refer to the [Migration Guide](https://github.com/mrdoob/three.js/wiki/Migration) when upgrading to the dev version.
 
+#### How to report a bug
 
-How to report a bug
----
 1. Specify the revision number of the three.js library where the bug occurred.
 2. Specify your browser version, operating system, and graphics card. (for example, Chrome 23.0.1271.95, Windows 7, Nvidia Quadro 2000M)
 3. Describe the problem in detail. Explain what happened, and what you expected would happen.
 4. Provide a small test-case (http://jsfiddle.net). [Here is a fiddle](http://jsfiddle.net/akmcv7Lh/) you can edit that runs the current version. [And here is a fiddle](http://jsfiddle.net/hw9rcLL8/) that uses the dev branch. If a test-case is not possible, provide a link to a live version of your application.
 5. If helpful, include a screenshot. Annotate the screenshot for clarity.
 
-
-How to contribute to three.js
 ---
+# Contribution
+#### How to contribute to three.js
+
 1. Make sure you have a GitHub account.
 2. Fork the repository on GitHub.
 3. Check the [Contribution Guidelines](https://github.com/mrdoob/three.js/wiki/How-to-contribute-to-three.js).
 4. Make changes to your clone of the repository.
 5. Submit a pull request.
-

+ 28 - 0
.github/ISSUE_TEMPLATE.md

@@ -0,0 +1,28 @@
+##### Description of the problem 
+
+...
+
+##### Three.js version
+
+- [ ] Dev
+- [ ] r74
+- [ ] ...
+
+##### Browser
+
+- [x] All of them
+- [ ] Chrome
+- [ ] Firefox
+- [ ] Internet Explorer
+
+##### OS
+
+- [x] All of them
+- [ ] Windows
+- [ ] Linux
+- [ ] Android
+- [ ] IOS
+
+##### Hardware Requirements (graphics card, VR Device, ...)
+
+

+ 1 - 1
README.md

@@ -61,7 +61,7 @@ This code creates a scene, a camera, and a geometric cube, and it adds the cube
 
 </script>
 ```
-If everything went well you should see [this](http://jsfiddle.net/f17Lz5ux/).
+If everything went well you should see [this](http://jsfiddle.net/hfj7gm6t/).
 
 ### Change log ###
 

File diff suppressed because it is too large
+ 347 - 171
build/three.js


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


+ 9 - 19
docs/api/core/BufferGeometry.html

@@ -27,25 +27,15 @@
 		var geometry = new THREE.BufferGeometry();
 		// create a simple square shape. We duplicate the top left and bottom right
 		// vertices because each vertex needs to appear once per triangle.
-		var vertexPositions = [
-			[-1.0, -1.0,  1.0],
-			[ 1.0, -1.0,  1.0],
-			[ 1.0,  1.0,  1.0],
-
-			[ 1.0,  1.0,  1.0],
-			[-1.0,  1.0,  1.0],
-			[-1.0, -1.0,  1.0]
-		];
-		var vertices = new Float32Array( vertexPositions.length * 3 ); // three components per vertex
-
-		// components of the position vector for each vertex are stored
-		// contiguously in the buffer.
-		for ( var i = 0; i < vertexPositions.length; i++ )
-		{
-			vertices[ i*3 + 0 ] = vertexPositions[i][0];
-			vertices[ i*3 + 1 ] = vertexPositions[i][1];
-			vertices[ i*3 + 2 ] = vertexPositions[i][2];
-		}
+		var vertices = new Float32Array( [
+			-1.0, -1.0,  1.0,
+			 1.0, -1.0,  1.0,
+			 1.0,  1.0,  1.0,
+
+			 1.0,  1.0,  1.0,
+			-1.0,  1.0,  1.0,
+			-1.0, -1.0,  1.0
+		] );
 
 		// itemSize = 3 because there are 3 values (components) per vertex
 		geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );

+ 58 - 0
docs/api/extras/geometries/BoxBufferGeometry.html

@@ -0,0 +1,58 @@
+<!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">This is the [page:BufferGeometry] port of [page:BoxGeometry].</div>
+
+		<iframe src='scenes/geometry-browser.html#BoxBufferGeometry'></iframe>
+
+		<h2>Example</h2>
+
+		<code>var geometry = new THREE.BoxBufferGeometry( 1, 1, 1 );
+		var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
+		var cube = new THREE.Mesh( geometry, material );
+		scene.add( cube );
+		</code>
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:Float width], [page:Float height], [page:Float depth], [page:Integer widthSegments], [page:Integer heightSegments], [page:Integer depthSegments])</h3>
+		<div>
+		width — Width of the sides on the X axis.<br />
+		height — Height of the sides on the Y axis.<br />
+		depth — Depth of the sides on the Z axis.<br />
+		widthSegments — Optional. Number of segmented faces along the width of the sides. Default is 1.<br />
+		heightSegments — Optional. Number of segmented faces along the height of the sides. Default is 1.<br />
+		depthSegments — Optional. Number of segmented faces along the depth of the sides. Default is 1.
+		</div>
+
+
+		<h2>Properties</h2>
+
+		<h3>.parameters</h3>
+ 		<div>
+			<p>Using the above example code above as our basis:</p>
+			<code>
+		geometry.parameters; // outputs an object {width: 1, height: 1, depth: 1, widthSegments: undefined, heightSegments: undefined}
+		cube.geometry.parameters; // as above
+		cube.geometry.parameters.width; // === 1
+		cube.geometry.parameters.widthSegments // === undefined.
+			</code>
+ 		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 44 - 0
docs/api/extras/geometries/CircleBufferGeometry.html

@@ -0,0 +1,44 @@
+<!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">This is the [page:BufferGeometry] port of [page:CircleGeometry].</div>
+
+		<h2>Example</h2>
+
+		<iframe src='scenes/geometry-browser.html#CircleBufferGeometry'></iframe>
+
+		<code>
+		var geometry = new THREE.CircleBufferGeometry( 5, 32 );
+		var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
+		var circle = new THREE.Mesh( geometry, material );
+		scene.add( circle );
+		</code>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]([page:Float radius], [page:Integer segments], [page:Float thetaStart], [page:Float thetaLength])</h3>
+		<div>
+		radius — Radius of the circle, default = 50.<br />
+		segments — Number of segments (triangles), minimum = 3, default = 8.<br />
+		thetaStart — Start angle for first segment, default = 0 (three o'clock position).<br />
+		thetaLength — The central angle, often called theta, of the circular sector. The default is 2*Pi, which makes for a complete circle.
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 4 - 9
docs/api/extras/geometries/CircleGeometry.html

@@ -19,15 +19,10 @@
 
 		<iframe src='scenes/geometry-browser.html#CircleGeometry'></iframe>
 
-		<code>var material = new THREE.MeshBasicMaterial({
-			color: 0x0000ff
-		});
-
-		var radius = 5;
-		var segments = 32;
-
-		var circleGeometry = new THREE.CircleGeometry( radius, segments );
-		var circle = new THREE.Mesh( circleGeometry, material );
+		<code>
+		var geometry = new THREE.CircleGeometry( 5, 32 );
+		var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
+		var circle = new THREE.Mesh( geometry, material );
 		scene.add( circle );
 		</code>
 

+ 56 - 0
docs/api/extras/geometries/CylinderBufferGeometry.html

@@ -0,0 +1,56 @@
+<!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">This is the [page:BufferGeometry] port of [page:CylinderGeometry].</div>
+
+
+		<h2>Example</h2>
+
+		<iframe src='scenes/geometry-browser.html#CylinderBufferGeometry'></iframe>
+
+		<code>var geometry = new THREE.CylinderBufferGeometry( 5, 5, 20, 32 );
+		var material = new THREE.MeshBasicMaterial( {color: 0xffff00} );
+		var cylinder = new THREE.Mesh( geometry, material );
+		scene.add( cylinder );
+		</code>
+
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:Float radiusTop], [page:Float radiusBottom], [page:Float height], [page:Integer radiusSegments], [page:Integer heightSegments], [page:Boolean openEnded], [page:Float thetaStart], [page:Float thetaLength])</h3>
+		<div>
+		radiusTop — Radius of the cylinder at the top. Default is 20.<br />
+		radiusBottom — Radius of the cylinder at the bottom. Default is 20.<br />
+		height — Height of the cylinder. Default is 100.<br />
+		radiusSegments — Number of segmented faces around the circumference of the cylinder. Default is 8<br />
+		heightSegments — Number of rows of faces along the height of the cylinder. Default is 1.<br />
+		openEnded — A Boolean indicating whether the ends of the cylinder are open or capped. Default is false, meaning capped.<br />
+		thetaStart — Start angle for first segment, default = 0 (three o'clock position).<br />
+		thetaLength — The central angle, often called theta, of the circular sector. The default is 2*Pi, which makes for a complete cylinder.
+		</div>
+
+
+		<h2>Properties</h2>
+
+		<div>
+		Each of the constructor parameters is accessible as a property of the same name. Any modification of these properties after instantiation does not change the geometry.
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 52 - 0
docs/api/extras/geometries/LatheBufferGeometry.html

@@ -0,0 +1,52 @@
+<!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">This is the [page:BufferGeometry] port of [page:LatheGeometry].</div>
+
+
+		<h2>Example</h2>
+
+		<iframe src='scenes/geometry-browser.html#LatheBufferGeometry'></iframe>
+
+		<code>
+		var points = [];
+		for ( var i = 0; i < 10; i ++ ) {
+			points.push( new THREE.Vector2( Math.sin( i * 0.2 ) * 10 + 5, ( i - 5 ) * 2 ) );
+		}
+		var geometry = new THREE.LatheBufferGeometry( points );
+		var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
+		var lathe = new THREE.Mesh( geometry, material );
+		scene.add( lathe );
+		</code>
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:Array points], [page:Integer segments], [page:Float phiStart], [page:Float phiLength])</h3>
+		<div>
+		points — Array of Vector2s. The x-coordinate of each point must be greater than zero.<br />
+		segments — the number of circumference segments to generate. Default is 12.<br />
+		phiStart — the starting angle in radians. Default is 0.<br />
+		phiLength — the radian (0 to 2PI) range of the lathed section 2PI is a closed lathe, less than 2PI is a portion. Default is 2PI.
+		</div>
+		<div>
+		This creates a LatheBufferGeometry based on the parameters.
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 6 - 5
docs/api/extras/geometries/LatheGeometry.html

@@ -17,11 +17,12 @@
 
 		<h2>Example</h2>
 
+		<iframe src='scenes/geometry-browser.html#LatheGeometry'></iframe>
+
 		<code>
 		var points = [];
 		for ( var i = 0; i < 10; i ++ ) {
-			points.push( new THREE.Vector2( Math.sin( i * 0.2 ) * 15 + 50, ( i - 5 ) * 2 ) );
-
+			points.push( new THREE.Vector2( Math.sin( i * 0.2 ) * 10 + 5, ( i - 5 ) * 2 ) );
 		}
 		var geometry = new THREE.LatheGeometry( points );
 		var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
@@ -34,13 +35,13 @@
 
 		<h3>[name]([page:Array points], [page:Integer segments], [page:Float phiStart], [page:Float phiLength])</h3>
 		<div>
-		points — Array of Vector2s.<br />
+		points — Array of Vector2s. The x-coordinate of each point must be greater than zero.<br />
 		segments — the number of circumference segments to generate. Default is 12.<br />
 		phiStart — the starting angle in radians. Default is 0.<br />
-		phiLength — the radian (0 to 2*PI) range of the lathed section 2*PI is a closed lathe, less than 2PI is a portion. Default is 2*PI
+		phiLength — the radian (0 to 2PI) range of the lathed section 2PI is a closed lathe, less than 2PI is a portion. Default is 2PI.
 		</div>
 		<div>
-		This creates a LatheGeometry based on the parameters.
+		This creates a LatheBufferGeometry based on the parameters.
 		</div>
 
 

+ 50 - 0
docs/api/extras/geometries/PlaneBufferGeometry.html

@@ -0,0 +1,50 @@
+<!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">This is the [page:BufferGeometry] port of [page:PlaneGeometry].</div>
+
+		<h2>Example</h2>
+
+		<iframe src='scenes/geometry-browser.html#PlaneBufferGeometry'></iframe>
+
+		<code>var geometry = new THREE.PlaneBufferGeometry( 5, 20, 32 );
+		var material = new THREE.MeshBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} );
+		var plane = new THREE.Mesh( geometry, material );
+		scene.add( plane );
+		</code>
+
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:Float width], [page:Float height], [page:Integer widthSegments], [page:Integer heightSegments])</h3>
+		<div>
+		width — Width along the X axis.<br />
+		height — Height along the Y axis.<br />
+		widthSegments — Optional. Default is 1. <br />
+		heightSegments — Optional. Default is 1.
+		</div>
+
+
+		<h2>Properties</h2>
+
+		<div>
+		Each of the contructor parameters is accessible as a property of the same name. Any modification of these properties after instantiation does not change the geometry.
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 45 - 0
docs/api/extras/geometries/RingBufferGeometry.html

@@ -0,0 +1,45 @@
+<!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">This is the [page:BufferGeometry] port of [page:RingGeometry].</div>
+
+		<iframe src='scenes/geometry-browser.html#RingBufferGeometry'></iframe>
+
+		<h2>Example</h2>
+
+		<code>var geometry = new THREE.RingBufferGeometry( 1, 5, 32 );
+		var material = new THREE.MeshBasicMaterial( { color: 0xffff00, side: THREE.DoubleSide } );
+		var mesh = new THREE.Mesh( geometry, material );
+		scene.add( mesh );
+		</code>
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:Float innerRadius], [page:Float outerRadius], [page:Integer thetaSegments], [page:Integer phiSegments], [page:Float thetaStart], [page:Float thetaLength])</h3>
+		<div>
+		innerRadius — Default is 0, but it doesn't work right when innerRadius is set to 0.<br />
+		outerRadius — Default is 50. <br />
+		thetaSegments — Number of segments.  A higher number means the ring will be more round.  Minimum is 3.  Default is 8. <br />
+		phiSegments — Minimum is 1.  Default is 8.<br />
+		thetaStart — Starting angle. Default is 0. <br />
+		thetaLength — Central angle.  Default is Math.PI * 2.
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 57 - 0
docs/api/extras/geometries/SphereBufferGeometry.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">This is the [page:BufferGeometry] port of [page:SphereGeometry].</div>
+
+		<h2>Example</h2>
+
+		<iframe src='scenes/geometry-browser.html#SphereBufferGeometry'></iframe>
+
+		<code>var geometry = new THREE.SphereBufferGeometry( 5, 32, 32 );
+		var material = new THREE.MeshBasicMaterial( {color: 0xffff00} );
+		var sphere = new THREE.Mesh( geometry, material );
+		scene.add( sphere );
+		</code>
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:Float radius], [page:Integer widthSegments], [page:Integer heightSegments], [page:Float phiStart], [page:Float phiLength], [page:Float thetaStart], [page:Float thetaLength])</h3>
+
+		<div>
+		radius — sphere radius. Default is 50.<br />
+		widthSegments — number of horizontal segments. Minimum value is 3, and the default is 8.<br />
+		heightSegments — number of vertical segments. Minimum value is 2, and the default is 6.<br />
+		phiStart — specify horizontal starting angle. Default is 0.<br />
+		phiLength — specify horizontal sweep angle size. Default is Math.PI * 2.<br />
+		thetaStart — specify vertical starting angle. Default is 0.<br />
+		thetaLength — specify vertical sweep angle size. Default is Math.PI.<br />
+		</div>
+
+		<div>
+		The geometry is created by sweeping and calculating vertexes around the Y axis (horizontal sweep) and the Z axis (vertical sweep). Thus, incomplete spheres (akin to <em>'sphere slices'</em>) can be created through the use of different values of phiStart, phiLength, thetaStart and thetaLength, in order to define the points in which we start (or end) calculating those vertices.
+		</div>
+
+
+		<h2>Properties</h2>
+
+		<div>
+		Each of the contructor parameters is accessible as a property of the same name. Any modification of these properties after instantiation does not change the geometry.
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 51 - 0
docs/api/extras/geometries/TorusBufferGeometry.html

@@ -0,0 +1,51 @@
+<!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">This is the [page:BufferGeometry] port of [page:TorusGeometry].</div>
+
+		<iframe src='scenes/geometry-browser.html#TorusBufferGeometry'></iframe>
+
+		<h2>Example</h2>
+
+		<code>var geometry = new THREE.TorusBufferGeometry( 10, 3, 16, 100 );
+		var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
+		var torus = new THREE.Mesh( geometry, material );
+		scene.add( torus );
+		</code>
+
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:Float radius], [page:Float tube], [page:Integer radialSegments], [page:Integer tubularSegments], [page:Float arc])</h3>
+		<div>
+		radius — Default is 100. <br />
+		tube — Diameter of the tube.  Default is 40. <br />
+		radialSegments — Default is 8 <br />
+		tubularSegments — Default is 6. <br />
+		arc — Central angle.  Default is Math.PI * 2.
+		</div>
+
+
+		<h2>Properties</h2>
+
+		<div>
+		Each of the contructor parameters is accessible as a property of the same name. Any modification of these properties after instantiation does not change the geometry.
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 57 - 0
docs/api/extras/geometries/TorusKnotBufferGeometry.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">This is the [page:BufferGeometry] port of [page:TorusKnotGeometry].</div>
+
+		<iframe src='scenes/geometry-browser.html#TorusKnotBufferGeometry'></iframe>
+
+
+		<h2>Example</h2>
+
+		<code>var geometry = new THREE.TorusKnotBufferGeometry( 10, 3, 100, 16 );
+		var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
+		var torusKnot = new THREE.Mesh( geometry, material );
+		scene.add( torusKnot );
+		</code>
+
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:Float radius], [page:Float tube], [page:Integer tubularSegments], [page:Integer radialSegments], [page:Integer p], [page:Integer q])</h3>
+		<div>
+			<ul>
+				<li>radius — Default is 100.</li>
+				<li>tube — Diameter of the tube. Default is 40.</li>
+				<li>tubularSegments — Default is 64.</li>
+				<li>radialSegments — Default is 8.</li>
+				<li>p — This value determines, how many times the geometry winds around its axis of rotational symmetry. Default is 2.</li>
+				<li>q — This value determines, how many times the geometry winds around a circle in the interior of the torus. Default is 3.</li>
+			</ul>
+		</div>
+
+
+		<h2>Properties</h2>
+
+
+		<div>
+		Each of the contructor parameters is accessible as a property of the same name. Any modification of these properties after instantiation does not change the geometry.
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 9 - 8
docs/api/extras/geometries/TorusKnotGeometry.html

@@ -29,15 +29,16 @@
 		<h2>Constructor</h2>
 
 
-		<h3>[name]([page:Float radius], [page:Float tube], [page:Integer radialSegments], [page:Integer tubularSegments], [page:Integer p], [page:Integer q], [page:Float heightScale])</h3>
+		<h3>[name]([page:Float radius], [page:Float tube], [page:Integer tubularSegments], [page:Integer radialSegments], [page:Integer p], [page:Integer q])</h3>
 		<div>
-		radius — Default is 100. <br />
-		tube — Default is 40. <br />
-		radialSegments — Default is 64. <br />
-		tubularSegments — Default is 8. <br />
-		p — Default is 2. <br />
-		q — Default is 3. <br />
-		heightScale — Default is 1.
+			<ul>
+				<li>radius — Default is 100.</li>
+				<li>tube — Diameter of the tube. Default is 40.</li>
+				<li>tubularSegments — Default is 64.</li>
+				<li>radialSegments — Default is 8.</li>
+				<li>p — This value determines, how many times the geometry winds around its axis of rotational symmetry. Default is 2.</li>
+				<li>q — This value determines, how many times the geometry winds around a circle in the interior of the torus. Default is 3.</li>
+			</ul>
 		</div>
 
 

+ 1 - 1
docs/api/extras/geometries/TubeGeometry.html

@@ -51,7 +51,7 @@ var geometry = new THREE.TubeGeometry(
 		segments — [page:Integer] - The number of segments that make up the tube, default is 64<br />
 		radius — [page:Float] - The radius of the tube, default is 1<br />
 		radiusSegments — [page:Integer] - The number of segments that make up the cross-section, default is 8 <br />
-		closed — [page:Float] Is the tube open or closed, default is false <br />
+		closed — [page:Boolean] Is the tube open or closed, default is false <br />
 		</div>
 
 

+ 14 - 4
docs/api/lights/AmbientLight.html

@@ -24,7 +24,7 @@
 		<div>[example:canvas_sandbox sandbox ]</div>
 		<div>[example:webgl_animation_cloth animation / cloth ]</div>
 		<div>[example:webgl_animation_skinning_blending animation / skinning / blending ]</div>
-		
+
 <code>var light = new THREE.AmbientLight( 0x404040 ); // soft white light
 scene.add( light );</code>
 
@@ -39,19 +39,29 @@ scene.add( light );</code>
 		This creates an Ambientlight with a color.
 		</div>
 
+		<h2>Properties</h2>
+
+		<h3>[property:Float intensity]</h3>
+		<div>
+			Light's intensity.<br />
+			In "physically correct" mode, the product of color * intensity is interpreted as luminous irradiance measured in lux at the material surface.<br/>
+			Default — *1.0*.
+		</div>
+
+
 		<h2>Methods</h2>
-		
+
 		<h3>[method:AmbientLight clone]()</h3>
 		<div>
 		<br />
 		It returns a clone of Ambientlight.
 		</div>
-		
+
 		<h3>[method:JSON toJSON]()</h3>
 		<div>
 		Return Ambientlight data in JSON format.
 		</div>
-		
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 1 - 6
docs/api/lights/DirectionalLight.html

@@ -60,15 +60,10 @@ scene.add( directionalLight );</code>
 		<h3>[property:Float intensity]</h3>
 		<div>
 			Light's intensity.<br />
+			In "physically correct" mode, the product of intensity * color is interpreted as luminous irradiance measured in lux at the material's surface.<br/>
 			Default — *1.0*.
 		</div>
 
-		<h3>[property:Boolean onlyShadow]</h3>
-		<div>
-			If set to *true* light will only cast shadow but not contribute any lighting (as if *intensity* was 0 but cheaper to compute).<br />
-			Default — *false*.
-		</div>
-
 		<h3>[property:Boolean castShadow]</h3>
 		<div>
 			If set to true light will cast dynamic shadows. Warning: This is expensive and requires tweaking to get shadows looking right.<br />

+ 6 - 5
docs/api/lights/HemisphereLight.html

@@ -13,16 +13,16 @@
 		<h1>[name]</h1>
 
 		<div class="desc">A light source positioned directly above the scene.</div>
-		
+
 		<h2>Example</h2>
-		
+
 		<div>[example:webgl_lights_hemisphere lights / hemisphere ]</div>
 		<div>[example:misc_controls_pointerlock controls / pointerlock ]</div>
 		<div>[example:webgl_decals decals ]</div>
 		<div>[example:webgl_loader_collada_kinematics loader / collada / kinematics ]</div>
 		<div>[example:webgl_materials_lightmap materials / lightmap ]</div>
 		<div>[example:webgl_shaders_ocean shaders / ocean ]</div>
-		
+
 <code>var light = new THREE.HemisphereLight( 0xffffbb, 0x080820, 1 );
 scene.add( light );</code>
 
@@ -47,17 +47,18 @@ scene.add( light );</code>
 		<h3>[property:Float intensity]</h3>
 		<div>
 			Light's intensity.<br />
+			In "physically correct" mode, the product of intensity * color (or intensity * groundColor) is interpreted as luminous irradiance measured in lux at the material's surface.<br/>
 			Default — *1.0*.
 		</div>
 
 		<h2>Methods</h2>
-		
+
 		<h3>[method:HemisphereLight clone]()</h3>
 		<div>
 		<br />
 		It returns a clone of HemisphereLight.
 		</div>
-		
+
 		<h3>[method:JSON toJSON]()</h3>
 		<div>
 		Return HemisphereLight data in JSON format.

+ 15 - 6
docs/api/lights/PointLight.html

@@ -28,7 +28,7 @@
 		<div>[example:webgl_geometry_large_mesh geometry / large / mesh ]</div>
 		<div>[example:webgl_geometry_text geometry / text ]</div>
 		<div>[example:webgl_lensflares lensflares ]</div>
-		
+
 		<code>var light = new THREE.PointLight( 0xff0000, 1, 100 );
 light.position.set( 50, 50, 50 );
 scene.add( light );</code>
@@ -46,7 +46,7 @@ scene.add( light );</code>
 		</div>
 		<div>
 		Creates a light at a specific position in the scene.  The light shines in all directions (roughly similar to a light bulb.)
-	
+
 		</div>
 
 
@@ -55,29 +55,38 @@ scene.add( light );</code>
 		<h3>[property:Float intensity]</h3>
 		<div>
 			Light's intensity.<br />
+			In "physically correct" mode, the product of color * intensity is interpreted as luminous intensity measured in candela.<br/>
 			Default - *1.0*.
 		</div>
 
+		<h3>[property:Float power]</h3>
+		<div>
+			Light's power.<br />
+			In "physically correct" mode, the luminous power of the light measured in lumens.<br/>
+			Default - *4PI*.
+		</div>
+
 		<h3>[property:Float distance]</h3>
 		<div>
 			If non-zero, light will attenuate linearly from maximum intensity at light *position* down to zero at *distance*.<br />
 			Default — *0.0*.
 		</div>
-		
+
 		<h3>[property:Float decay]</h3>
 		<div>
 			The amount the light dims along the distance of the light<br />
+			In "physically correct" mode, decay = 2 leads to physically realistic light falloff.<br/>
 			Default — *1*.
 		</div>
-		
+
 		<h2>Methods</h2>
-		
+
 		<h3>[method:PointLight clone]()</h3>
 		<div>
 		<br />
 		It returns a clone of PointLight.
 		</div>
-		
+
 		<h3>[method:JSON toJSON]()</h3>
 		<div>
 		Return PointLight data in JSON format.

+ 32 - 30
docs/api/lights/SpotLight.html

@@ -13,7 +13,7 @@
 		<h1>[name]</h1>
 
 		<div class="desc">A point light that can cast shadow in one direction.</div>
-		
+
 		<div class="desc">Affects objects using [page:MeshLambertMaterial] or [page:MeshPhongMaterial].</div>
 
 
@@ -24,7 +24,7 @@
 		<div>[example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic ]</div>
 		<div>[example:webgl_morphtargets_md2 morphtargets / md2 ]</div>
 		<div>[example:webgl_shading_physical shading / physical ]</div>
-		
+
 		<code>
 		// white spotlight shining from the side, casting shadow
 
@@ -55,13 +55,13 @@
 		<h2>Constructor</h2>
 
 
-		<h3>[name]([page:Integer hex], [page:Float intensity], [page:Float distance], [page:Radians angle], [page:Float exponent], [page:Float decay])</h3>
+		<h3>[name]([page:Integer hex], [page:Float intensity], [page:Float distance], [page:Radians angle], [page:Float penumbra], [page:Float decay])</h3>
 		<div>
 		[page:Integer hex] — Numeric value of the RGB component of the color. <br />
 		[page:Float intensity] — Numeric value of the light's strength/intensity. <br />
 		[page:Float distance] -- Maximum distance from origin where light will shine whose intensity is attenuated linearly based on distance from origin. <br />
 		[page:Radians angle] -- Maximum angle of light dispersion from its direction whose upper bound is Math.PI/2.<br />
-		[page:Float exponent] -- Rapidity of the falloff of light from its target direction.<br />
+		[page:Float penumbra] -- Percent of the spotlight cone that is attenuated due to penumbra. Takes values between zero and 1. Default is zero.<br />
 		[page:Float decay] -- The amount the light dims along the distance of the light.
 		</div>
 
@@ -73,50 +73,52 @@
 			Default position — *(0,0,0)*.<br />
 			*Note*: Currently for target property to work properly, it must be part of the [page:Scene scene], e.g. this will help: <code>scene.add( light.target )</code>
 		</div>
-	
+
 		<h3>[property:Float intensity]</h3>
 		<div>
 			Light's intensity.<br />
+			In "physically correct" mode, the product of color * intensity is interpreted as luminous intensity measured in candela.<br/>
 			Default — *1.0*.
 		</div>
-	
+
+		<h3>[property:Float power]</h3>
+		<div>
+			Light's power.<br />
+			In "physically correct" mode, the luminous power of the light measured in lumens.<br/>
+			Default - *4PI*.
+		</div>
+
 		<h3>[property:Float distance]</h3>
 		<div>
 			If non-zero, light will attenuate linearly from maximum intensity at light *position* down to zero at *distance*.<br />
 			Default — *0.0*.
 		</div>
-	
+
 		<h3>[property:Float angle]</h3>
 		<div>
 			Maximum extent of the spotlight, in radians, from its direction. Should be no more than *Math.PI/2*.<br />
 			Default — *Math.PI/3*.
 		</div>
-	
-		<h3>[property:Float exponent]</h3>
+
+		<h3>[property:Float penumbra]</h3>
 		<div>
-			Rapidity of the falloff of light from its target direction. A lower value spreads out the light, while a higher
-			focuses it towards the center.<br />
-			Default — *10.0*.
+			Percent of the spotlight cone that is attenuated due to penumbra. Takes values between zero and 1.<br />
+			Default — *0.0*.
 		</div>
-		
+
 		<h3>[property:Float decay]</h3>
 		<div>
 			The amount the light dims along the distance of the light<br />
+			In "physically correct" mode, decay = 2 leads to physically realistic light falloff.<br/>
 			Default — *1*.
 		</div>
-	
+
 		<h3>[property:Boolean castShadow]</h3>
 		<div>
 			If set to *true* light will cast dynamic shadows. *Warning*: This is expensive and requires tweaking to get shadows looking right.<br />
 			Default — *false*.
 		</div>
-		
-		<h3>[property:Boolean onlyShadow]</h3>
-		<div>
-			If set to *true* light will only cast shadow but not contribute any lighting (as if *intensity* was 0 but cheaper to compute).<br />
-			Default — *false*.
-		</div>
-		
+
 		<h3>[property:Float shadowCameraNear]</h3>
 		<div>
 			Perspective shadow camera frustum <em>near</em> parameter.<br />
@@ -134,13 +136,13 @@
 			Perspective shadow camera frustum <em>field of view</em> parameter.<br />
 			Default — *50*.
 		</div>
-		
+
 		<h3>[property:Boolean shadowCameraVisible]</h3>
 		<div>
 			Show debug shadow camera frustum.<br />
 			Default — *false*.
 		</div>
-		
+
 		<h3>[property:Float shadowBias]</h3>
 		<div>
 			Shadow map bias, how much to add or subtract from the normalized depth when deciding whether a surface is in shadow.<br />
@@ -158,34 +160,34 @@
 			Shadow map texture height in pixels.<br />
 			Default — *512*.
 		</div>
-		
+
 		<h3>[property:Vector2 shadowMapSize]</h3>
 		<div>
 			The shadowMapWidth and shadowMapHeight stored in a [page:Vector2 THREE.Vector2]. Set internally during rendering.
-		</div> 
+		</div>
 
 		<h3>[property:PerspectiveCamera shadowCamera]</h3>
 		<div>
 			The shadow's view of the world. Computed internally during rendering from the shadowCamera* settings.
-		</div> 
+		</div>
 
 		<h3>[property:Matrix4 shadowMatrix]</h3>
 		<div>
 			Model to shadow camera space, to compute location and depth in shadow map. Computed internally during rendering.
-		</div> 
+		</div>
 
 		<h3>[property:WebGLRenderTarget shadowMap]</h3>
 		<div>
 		    The depth map generated using the shadowCamera; a location beyond a pixel's depth is in shadow. Computed internally during rendering.
-		</div> 
+		</div>
 
-		<h2>Methods</h2>		
+		<h2>Methods</h2>
 		<h3>[method:SpotLight clone]()</h3>
 		<div>
 		<br />
 		It returns a clone of SpotLight.
 		</div>
-		
+
 		<h3>[method:JSON toJSON]()</h3>
 		<div>
 		Return SpotLight data in JSON format.

+ 0 - 88
docs/api/loaders/OBJMTLLoader.html

@@ -1,88 +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 a <em>.obj</em> and its <em>.mtl</em> together.</div>
-
-
-		<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].
-		</div>
-		<div>
-		Creates a new [name].
-		</div>
-
-		<h2>Properties</h2>
-
-
-		<h2>Methods</h2>
-
-		<h3>[method:null load]( [page:String objUrl], [page:String mtlUrl], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
-		<div>
-		[page:String objUrl] — required. URL to the <em>.obj</em> resource<br />
-		[page:String mtlUrl] — required. URL to the <em>.mtl</em> resource<br />
-		[page:Function onLoad] — Will be called when both resources load complete. The argument will be the loaded [page:Object3D].<br />
-		[page:Function onProgress] — Will be called while both load progress. The argument will be the XmlHttpRequest instance, that contain .[page:Integer total] and .[page:Integer loaded] bytes.<br />
-		[page:Function onError] — Will be called when load errors.<br />
-		</div>
-		<div>
-		Begin loading from urls and call onLoad with the parsed response content.
-		</div>
-
-		<h3>[method:Object3D parse]( [page:String text], [page:Function mtllibCallback] )</h3>
-		<div>
-		[page:String text] — required. The textual <em>obj</em> structure to parse.<br/>
-		[page:Function mtllibCallback] — optional. Callback to handle <em>mtllib</em> declaration.<br/>
-		</div>
-		<div>
-		Parse an <em>obj</em> text structure and return an [page:Object3D].<br />
-		Found objects are converted to a [page:Mesh] and materials are converted to [page:MeshLambertMaterial].
-		</div>
-
-		<h2>Example</h2>
-
-		<code>
-		// instantiate a loader
-		var loader = new THREE.OBJMTLLoader();
-
-		// load an obj / mtl resource pair
-		loader.load(
-			// OBJ resource URL
-			'obj/male02/male02.obj',
-			// MTL resource URL
-			'obj/male02/male02_dds.mtl',
-			// Function when both resources are loaded
-			function ( object ) {
-				scene.add( object );
-			},
-			// Function called when downloads progress
-			function ( xhr ) {
-				console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
-			},
-			// Function called when downloads error
-			function ( xhr ) {
-				console.log( 'An error happened' );
-			}
-		);
-		</code>
-
-		[example:webgl_loader_obj_mtl]
-
-
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/OBJMTLLoader.js examples/js/loaders/OBJMTLLoader.js]
-	</body>
-</html>

+ 2 - 1
docs/api/materials/LineBasicMaterial.html

@@ -31,6 +31,7 @@
 		</div>
 
 		<h2>Properties</h2>
+		<div>See the base [page:Material] class for common properties.</div>
 
 		<h3>[property:Integer color]</h3>
 		<div>Sets the color of the line. Default is 0xffffff.</div>
@@ -55,7 +56,7 @@
 		<div>Define whether the material color is affected by global fog settings.</div>
 		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:CanvasRenderer Canvas] renderer, but does work with the [page:WebGLRenderer WebGL] renderer.</div>
 
-		
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 5 - 6
docs/api/materials/LineDashedMaterial.html

@@ -32,13 +32,12 @@
 
 
 		<h2>Properties</h2>
-
-
+		<div>See the base [page:Material] class for common properties.</div>
 
 		<h3>[property:Color color]</h3>
 		<div>
 		Sets the color of the line. Default is 0xffffff.
-		</div> 
+		</div>
 
 		<h3>[property:number linewidth]</h3>
 		<div>Controls line thickness. Default is 1.</div>
@@ -47,17 +46,17 @@
 		<h3>[property:number scale]</h3>
 		<div>
 		The scale of the dashed part of a line.
-		</div> 
+		</div>
 
 		<h3>[property:number dashSize]</h3>
 		<div>
 		The size of the dash. This is both the gap with the stroke. Default is 3.
-		</div> 
+		</div>
 
 		<h3>[property:number gapSize]</h3>
 		<div>
 		The size of the gap. Default is 1.
-		</div> 
+		</div>
 
 		<h3>[property:boolean vertexColors]</h3>
 		<div>Define how the vertices gets colored. Possible values are THREE.NoColors, THREE.FaceColors and THREE.VertexColors. Default is THREE.NoColors.</div>

+ 20 - 16
docs/api/materials/MeshBasicMaterial.html

@@ -26,10 +26,14 @@
 		<div>
 		color — geometry color in hexadecimal. Default is 0xffffff.<br />
 		map — Set texture map. Default is null <br />
-		aoMap — Set ambient occlusion map. Default is null <br />
+		aoMap — Set ao map. Default is null.<br />
+		aoMapIntensity — Set ao map intensity. Default is 1.<br />
 		specularMap — Set specular map. Default is null.<br />
 		alphaMap — Set alpha map. Default is null.<br />
 		envMap — Set env map. Default is null.<br />
+		combine — Set combine operation. Default is THREE.MultiplyOperation.<br />
+		reflectivity — Set reflectivity. Default is 1.<br />
+		refractionRatio — Set refraction ratio. Default is 0.98.<br />
 		fog — Define whether the material color is affected by global fog settings. Default is true.<br />
 		shading — Define shading type. Default is THREE.SmoothShading.<br />
 		wireframe — render geometry as wireframe. Default is false.<br />
@@ -42,6 +46,7 @@
 		</div>
 
 		<h2>Properties</h2>
+		<div>See the base [page:Material] class for common properties.</div>
 
 		<h3>[property:Integer color]</h3>
 		<div>Sets the color of the geometry. Default is 0xffffff.</div>
@@ -54,6 +59,9 @@
 		<h3>[property:Texture aoMap]</h3>
 		<div>Set ambient occlusion map. Default is null.</div>
 
+		<h3>[property:Float aoMapIntensity]</h3>
+		<div>TODO</div>
+
 		<h3>[property:Texture specularMap]</h3>
 		<div>Set specular map. Default is null.</div>
 
@@ -64,6 +72,17 @@
 		<h3>[property:TextureCube envMap]</h3>
 		<div>Set env map. Default is null.</div>
 
+		<h3>[property:Integer combine]</h3>
+		<div>How to combine the result of the surface's color with the environment map, if any.</div>
+
+		<div>Options are [page:Textures THREE.Multiply] (default), [page:Textures THREE.MixOperation], [page:Textures THREE.AddOperation]. If mix is chosen, the reflectivity is used to blend between the two colors.</div>
+
+		<h3>[property:Float reflectivity]</h3>
+		<div>How much the environment map affects the surface; also see "combine".</div>
+
+		<h3>[property:Float refractionRatio]</h3>
+		<div>The index of refraction for an environment map using [page:Textures THREE.CubeRefractionMapping]. Default is *0.98*.</div>
+
 		<h3>[property:Boolean fog]</h3>
 		<div>Define whether the material color is affected by global fog settings.</div>
 		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:CanvasRenderer Canvas] renderer, but does work with the [page:WebGLRenderer WebGL] renderer.</div>
@@ -96,21 +115,6 @@
 		<h3>[property:Boolean morphTargets]</h3>
 		<div>Define whether the material uses morphTargets. Default is false.</div>
 
-		<h3>[property:number combine]</h3>
-		<div>
-		How to combine the result of the surface's color with the environment map, if any.
-		</div>
-
-		<h3>[property:number reflectivity]</h3>
-		<div>
-		How much the environment map affects the surface; also see "combine".
-		</div>
-
-		<h3>[property:number refractionRatio]</h3>
-		<div>
-		The index of refraction for an environment map using [page:Textures THREE.CubeRefractionMapping]. Default is *0.98*.
-		</div>
-
 		<h2>Methods</h2>
 
 		<h2>Source</h2>

+ 8 - 8
docs/api/materials/MeshDepthMaterial.html

@@ -13,7 +13,7 @@
 		<h1>[name]</h1>
 
 		<div class="desc">A material for drawing geometry by depth. Depth is based off of the camera near and far plane. White is nearest, black is farthest.</div>
-		
+
 		<iframe src='scenes/material-browser.html#MeshDepthMaterial'></iframe>
 
 		<h2>Constructor</h2>
@@ -21,7 +21,7 @@
 
 		<h3>[name]([page:Object parameters])</h3>
 		<div>
-		parameters is an object with one or more properties defining the material's appearance. 
+		parameters is an object with one or more properties defining the material's appearance.
 		</div>
 		<div>
 		morphTargets -- Define whether the material uses morphTargets. Default is false.<br/>
@@ -31,20 +31,20 @@
 
 
 		<h2>Properties</h2>
-
+		<div>See the base [page:Material] class for common properties.</div>
 
 		<h3>[property:boolean morphTargets]</h3>
-		<div>Define whether the material uses morphTargets. Default is false.</div> 
+		<div>Define whether the material uses morphTargets. Default is false.</div>
 
 		<h3>[property:boolean wireframe]</h3>
-		<div>Render geometry as wireframe. Default is false (i.e. render as smooth shaded).</div> 
-		
+		<div>Render geometry as wireframe. Default is false (i.e. render as smooth shaded).</div>
+
 		<h3>[property:number wireframeLinewidth]</h3>
 		<div>
 			Controls wireframe thickness. Default is 1.<br/><br/>
 			Due to limitations in the ANGLE layer, on Windows platforms linewidth will always be 1 regardless of the set value.
-		</div> 
-		
+		</div>
+
 		<h2>Methods</h2>
 
 

+ 24 - 10
docs/api/materials/MeshLambertMaterial.html

@@ -27,11 +27,18 @@
 		color — Line color in hexadecimal. Default is 0xffffff.<br />
 		map — Sets the texture map. Default is null <br />
 		lightMap — Set light map. Default is null.<br />
+		lightMapIntensity — Set light map intensity. Default is 1.<br />
 		aoMap — Set ao map. Default is null.<br />
+		aoMapIntensity — Set ao map intensity. Default is 1.<br />
+		emissive - Set emissive color. Default is 0x000000.<br />
 		emissiveMap — Set emissive map. Default is null.<br />
+		emissiveIntensity — Set emissive map intensity. Default is 1.<br />
 		specularMap — Set specular map. Default is null.<br />
 		alphaMap — Set alpha map. Default is null.<br />
 		envMap — Set env map. Default is null.<br />
+		combine — Set combine operation. Default is THREE.MultiplyOperation.<br />
+		reflectivity — Set reflectivity. Default is 1.<br />
+		refractionRatio — Set refraction ratio. Default is 0.98.<br />
 		fog — Define whether the material color is affected by global fog settings. Default is false.<br />
 		wireframe — Render geometry as wireframe. Default is false (i.e. render as smooth shaded).<br/>
 		wireframeLinewidth — Controls wireframe thickness. Default is 1.<br/>
@@ -39,38 +46,45 @@
 		wireframeLinejoin — Define appearance of line joints. Default is 'round'.<br />
 		vertexColors — Define how the vertices gets colored. Default is THREE.NoColors.<br />
 		skinning — Define whether the material uses skinning. Default is false.<br />
-		morphTargets — Define whether the material uses morphTargets. Default is false.<br/>
+		morphTargets — Define whether the material uses morphTargets. Default is false.<br />
+		morphNormals — Define whether the material uses morphNormals. Default is false.
 		</div>
 
 
 		<h2>Properties</h2>
-		<div>See the base [page:Material] class for common parameters.</div>
+		<div>See the base [page:Material] class for common properties.</div>
 
 		<h3>[property:Color color]</h3>
 		<div>
 		Diffuse color of the material. Default is white.<br />
 		</div>
 
-		<h3>[property:Color emissive]</h3>
-		<div>
-		Emissive (light) color of the material, essentially a solid color unaffected by other lighting. Default is black.<br />
-		</div>
-
-		<h3>[property:Float emissiveIntensity]</h3>
-		<div>Intensity of the emissive light. Modulates the emissive color. Default is 1.</div>
-
 		<h3>[property:Texture map]</h3>
 		<div>Set color texture map. Default is null.</div>
 
 		<h3>[property:Texture lightMap]</h3>
 		<div>Set light map. Default is null. The lightMap requires a second set of UVs.</div>
 
+		<h3>[property:Float lightMapIntensity]</h3>
+		<div>TODO</div>
+
 		<h3>[property:Texture aoMap]</h3>
 		<div>Set ambient occlusion map. Default is null. The aoMap requires a second set of UVs.</div>
 
+		<h3>[property:Float aoMapIntensity]</h3>
+		<div>TODO</div>
+
+		<h3>[property:Color emissive]</h3>
+		<div>
+		Emissive (light) color of the material, essentially a solid color unaffected by other lighting. Default is black.<br />
+		</div>
+
 		<h3>[property:Texture emissiveMap]</h3>
 		<div>Set emisssive (glow) map. Default is null. The emissive map color is modulated by the emissive color and the emissive intensity. If you have an emissive map, be sure to set the emissive color to something other than black.</div>
 
+		<h3>[property:Float emissiveIntensity]</h3>
+		<div>Intensity of the emissive light. Modulates the emissive color. Default is 1.</div>
+
 		<h3>[property:Texture specularMap]</h3>
 		<div>Since this material does not have a specular component, the specular value affects only how much of the environment map affects the surface. Default is null.</div>
 

+ 1 - 1
docs/api/materials/MeshNormalMaterial.html

@@ -32,7 +32,7 @@
 
 
 		<h2>Properties</h2>
-
+		<div>See the base [page:Material] class for common properties.</div>
 
 		<h3>[property:boolean wireframe]</h3>
 		<div>

+ 45 - 25
docs/api/materials/MeshPhongMaterial.html

@@ -21,20 +21,33 @@
 
 		<h3>[name]([page:Object parameters])</h3>
 		<div>
-		parameters -- an object with one or more of the material's properties defining the its appearance.
+		parameters -- an object with one or more of the material's properties defining the material's appearance.
 		</div>
 		<div>
 		color — geometry color in hexadecimal. Default is 0xffffff.<br />
-		map — Set texture map. Default is null <br />
+		specular — Set specular color. Default is 0x111111 .<br />
+		shininess — Set shininess Default is 30.<br />
+		map — Set texture map. Default is null.<br />
 		lightMap — Set light map. Default is null.<br />
+		lightMapIntensity — Set light map intensity. Default is 1.<br />
 		aoMap — Set ao map. Default is null.<br />
+		aoMapIntensity — Set ao map intensity. Default is 1.<br />
+		emissive - Set emissive color. Default is 0x000000.<br />
 		emissiveMap — Set emissive map. Default is null.<br />
-		specularMap — Set specular map. Default is null.<br />
-		alphaMap — Set alpha map. Default is null.<br />
+		emissiveIntensity — Set emissive map intensity. Default is 1.<br />
+		bumpMap — Set bump map. Default is null.<br />
+		bumpMapScale — Set bump map scale. Default is 1.<br />
+		normalMap — Set normal map. Default is null.<br />
+		normalMapScale — Set normal map scale. Default is (1, 1).<br />
 		displacementMap — Set displacement map. Default is null.<br />
 		displacementScale — Set displacement scale. Default is 1.<br />
 		displacementBias — Set displacement offset. Default is 0.<br />
+		specularMap — Set specular map. Default is null.<br />
+		alphaMap — Set alpha map. Default is null.<br />
 		envMap — Set env map. Default is null.<br />
+		combine — Set combine operation. Default is THREE.MultiplyOperation.<br />
+		reflectivity — Set reflectivity. Default is 1.<br />
+		refractionRatio — Set refraction ratio. Default is 0.98.<br />
 		fog — Define whether the material color is affected by global fog settings. Default is true.<br />
 		shading — Define shading type. Default is THREE.SmoothShading.<br />
 		wireframe — render geometry as wireframe. Default is false.<br />
@@ -43,7 +56,8 @@
 		wireframeLinejoin — Define appearance of line joints. Default is 'round'.<br />
 		vertexColors — Define how the vertices gets colored. Default is THREE.NoColors.<br />
 		skinning — Define whether the material uses skinning. Default is false.<br />
-		morphTargets — Define whether the material uses morphTargets. Default is false.
+		morphTargets — Define whether the material uses morphTargets. Default is false.<br />
+		morphNormals — Define whether the material uses morphNormals. Default is false.
 		</div>
 		<div>
 		Example:<br>
@@ -53,21 +67,13 @@
 
 
 		<h2>Properties</h2>
-		<div>See the base [page:Material] class for common parameters.</div>
+		<div>See the base [page:Material] class for common properties.</div>
 
 		<h3>[property:Color color]</h3>
 		<div>
 		Diffuse color of the material. Default is white.<br />
 		</div>
 
-		<h3>[property:Color emissive]</h3>
-		<div>
-		Emissive (light) color of the material, essentially a solid color unaffected by other lighting. Default is black.<br />
-		</div>
-
-		<h3>[property:Float emissiveIntensity]</h3>
-		<div>Intensity of the emissive light. Modulates the emissive color. Default is 1.</div>
-
 		<h3>[property:Color specular]</h3>
 		<div>
 		Specular color of the material, i.e., how shiny the material is and the color of its shine. Setting this the same color as the diffuse value (times some intensity) makes the material more metallic-looking; setting this to some gray makes the material look more plastic. Default is dark gray.<br />
@@ -82,12 +88,26 @@
 		<h3>[property:Texture lightMap]</h3>
 		<div>Set light map. Default is null. The lightMap requires a second set of UVs.</div>
 
+		<h3>[property:Float lightMapIntensity]</h3>
+		<div>TODO</div>
+
 		<h3>[property:Texture aoMap]</h3>
 		<div>Set ambient occlusion map. Default is null. The aoMap requires a second set of UVs.</div>
 
+		<h3>[property:Float aoMapIntensity]</h3>
+		<div>TODO</div>
+
+		<h3>[property:Color emissive]</h3>
+		<div>
+		Emissive (light) color of the material, essentially a solid color unaffected by other lighting. Default is black.<br />
+		</div>
+
 		<h3>[property:Texture emissiveMap]</h3>
 		<div>Set emisssive (glow) map. Default is null. The emissive map color is modulated by the emissive color and the emissive intensity. If you have an emissive map, be sure to set the emissive color to something other than black.</div>
 
+		<h3>[property:Float emissiveIntensity]</h3>
+		<div>Intensity of the emissive light. Modulates the emissive color. Default is 1.</div>
+
 		<h3>[property:Texture bumpMap]</h3>
 		<div>
 			The texture to create a bump map. The black and white values map to the perceived depth in relation to the lights.
@@ -111,29 +131,29 @@
 			How much the normal map affects the material. Typical ranges are 0-1. Default is (1,1).
 		</div>
 
-		<h3>[property:Texture specularMap]</h3>
-		<div>The specular map value affects both how much the specular surface highlight contributes and how much of the environment map affects the surface. Default is null.</div>
-
-		<h3>[property:Texture alphaMap]</h3>
-		<div>The alpha map is a grayscale texture that controls the opacity across the surface (black: fully transparent; white: fully opaque). Default is null.</div>
-		<div>Only the color of the texture is used, ignoring the alpha channel if one exists. For RGB and RGBA textures, the [page:WebGLRenderer WebGL] renderer will use the green channel when sampling this texture due to the extra bit of precision provided for green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and luminance/alpha textures will also still work as expected.</div>
-
 		<h3>[property:Texture displacementMap]</h3>
 		<div>
-			The displacement map affects the position of the mesh's vertices. Unlike other maps which only affect the light and shade of the material the displaced vertices can cast shadows, block other objects, and otherwise act as real geometry. 
+			The displacement map affects the position of the mesh's vertices. Unlike other maps which only affect the light and shade of the material the displaced vertices can cast shadows, block other objects, and otherwise act as real geometry.
 			The displacement texture is an image where the value of each pixel (white being the highest) is mapped against, and repositions, the vertices of the mesh.
 		</div>
-		
+
 		<h3>[property:Float displacementScale]</h3>
 		<div>
 			How much the displacement map affects the mesh (where black is no displacement, and white is maximum displacement). Without a displacement map set, this value is not applied. Default is 1.
 		</div>
-		
+
 		<h3>[property:Float displacementBias]</h3>
 		<div>
 			The offset of the displacement map's values on the mesh's vertices. Without a displacement map set, this value is not applied. Default is 0.
 		</div>
-		
+
+		<h3>[property:Texture specularMap]</h3>
+		<div>The specular map value affects both how much the specular surface highlight contributes and how much of the environment map affects the surface. Default is null.</div>
+
+		<h3>[property:Texture alphaMap]</h3>
+		<div>The alpha map is a grayscale texture that controls the opacity across the surface (black: fully transparent; white: fully opaque). Default is null.</div>
+		<div>Only the color of the texture is used, ignoring the alpha channel if one exists. For RGB and RGBA textures, the [page:WebGLRenderer WebGL] renderer will use the green channel when sampling this texture due to the extra bit of precision provided for green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and luminance/alpha textures will also still work as expected.</div>
+
 		<h3>[property:TextureCube envMap]</h3>
 		<div>Set env map. Default is null.</div>
 

+ 221 - 0
docs/api/materials/MeshStandardMaterial.html

@@ -0,0 +1,221 @@
+<!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:Material] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">TODO</div>
+
+		<iframe src='scenes/material-browser.html#MeshStandardMaterial'></iframe>
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:Object parameters])</h3>
+		<div>
+		parameters -- an object with one or more of the material's properties defining the material's appearance.
+		</div>
+		<div>
+		color — geometry color in hexadecimal. Default is 0xffffff.<br />
+		roughness — Set roughness. Default is 0.5.<br />
+		metalness — Set metalness. Default is 0.5.<br />
+		map — Set texture map. Default is null.<br />
+		lightMap — Set light map. Default is null.<br />
+		lightMapIntensity — Set light map intensity. Default is 1.<br />
+		aoMap — Set ao map. Default is null.<br />
+		aoMapIntensity — Set ao map intensity. Default is 1.<br />
+		emissive - Set emissive color. Default is 0x000000.<br />
+		emissiveMap — Set emissive map. Default is null.<br />
+		emissiveIntensity — Set emissive map intensity. Default is 1.<br />
+		bumpMap — Set bump map. Default is null.<br />
+		bumpMapScale — Set bump map scale. Default is 1.<br />
+		normalMap — Set normal map. Default is null.<br />
+		normalMapScale — Set normal map scale. Default is (1, 1).<br />
+		displacementMap — Set displacement map. Default is null.<br />
+		displacementScale — Set displacement scale. Default is 1.<br />
+		displacementBias — Set displacement offset. Default is 0.<br />
+		roughnessMap - Set roughness map. Default is null.<br />
+		metalnessMap - Set metalness map. Default is null.<br />
+		alphaMap — Set alpha map. Default is null.<br />
+		envMap — Set env map. Default is null.<br />
+		envMapIntensity — Set env map intensity. Default is 1.0.<br />
+		refractionRatio — Set refraction ratio. Default is 0.98.<br />
+		fog — Define whether the material color is affected by global fog settings. Default is true.<br />
+		shading — Define shading type. Default is THREE.SmoothShading.<br />
+		wireframe — render geometry as wireframe. Default is false.<br />
+		wireframeLinewidth — Line thickness. Default is 1.<br />
+		wireframeLinecap — Define appearance of line ends. Default is 'round'.<br />
+		wireframeLinejoin — Define appearance of line joints. Default is 'round'.<br />
+		vertexColors — Define how the vertices gets colored. Default is THREE.NoColors.<br />
+		skinning — Define whether the material uses skinning. Default is false.<br />
+		morphTargets — Define whether the material uses morphTargets. Default is false.<br />
+		morphNormals — Define whether the material uses morphNormals. Default is false.
+		</div>
+		<div>
+		Example:<br>
+		materials.push( new THREE.MeshStandardMaterial( { color: 0x550000, envMap: reflectionCube, roughness: 0.1, metalness: 1.0 } ) );
+
+		</div>
+
+
+		<h2>Properties</h2>
+		<div>See the base [page:Material] class for common properties.</div>
+
+		<h3>[property:Color color]</h3>
+		<div>
+		Diffuse color of the material. Default is white.<br />
+		</div>
+
+		<h3>[property:Float roughness]</h3>
+		<div>
+		TODO.<br />
+		</div>
+
+		<h3>[property:Float metalness]</h3>
+		<div>
+		TODO<br />
+		</div>
+
+		<h3>[property:Texture map]</h3>
+		<div>Set color texture map. Default is null. The texture map color is modulated by the diffuse color.</div>
+
+		<h3>[property:Texture lightMap]</h3>
+		<div>Set light map. Default is null. The lightMap requires a second set of UVs.</div>
+
+		<h3>[property:Float lightMapIntensity]</h3>
+		<div>TODO</div>
+
+		<h3>[property:Texture aoMap]</h3>
+		<div>Set ambient occlusion map. Default is null. The aoMap requires a second set of UVs.</div>
+
+		<h3>[property:Float aoMapIntensity]</h3>
+		<div>TODO</div>
+
+		<h3>[property:Color emissive]</h3>
+		<div>
+			Emissive (light) color of the material, essentially a solid color unaffected by other lighting. Default is black.<br />
+		</div>
+
+		<h3>[property:Texture emissiveMap]</h3>
+		<div>Set emisssive (glow) map. Default is null. The emissive map color is modulated by the emissive color and the emissive intensity. If you have an emissive map, be sure to set the emissive color to something other than black.</div>
+
+		<h3>[property:Float emissiveIntensity]</h3>
+		<div>Intensity of the emissive light. Modulates the emissive color. Default is 1.</div>
+
+		<h3>[property:Texture bumpMap]</h3>
+		<div>
+			The texture to create a bump map. The black and white values map to the perceived depth in relation to the lights.
+			Bump doesn't actually affect the geometry of the object, only the lighting. If a normal map is defined this will
+			be ignored.
+		</div>
+
+		<h3>[property:Float bumpScale]</h3>
+		<div>
+			How much the bump map affects the material. Typical ranges are 0-1. Default is 1.
+		</div>
+
+		<h3>[property:Texture normalMap]</h3>
+		<div>
+			The texture to create a normal map. The RGB values affect the surface normal for each pixel fragment and change
+			the way the color is lit. Normal maps do not change the actual shape of the surface, only the lighting.
+		</div>
+
+		<h3>[property:Vector2 normalScale]</h3>
+		<div>
+			How much the normal map affects the material. Typical ranges are 0-1. Default is (1, 1).
+		</div>
+
+		<h3>[property:Texture displacementMap]</h3>
+		<div>
+			The displacement map affects the position of the mesh's vertices. Unlike other maps which only affect the light and shade of the material the displaced vertices can cast shadows, block other objects, and otherwise act as real geometry.
+			The displacement texture is an image where the value of each pixel (white being the highest) is mapped against, and repositions, the vertices of the mesh.
+		</div>
+
+		<h3>[property:Float displacementScale]</h3>
+		<div>
+			How much the displacement map affects the mesh (where black is no displacement, and white is maximum displacement). Without a displacement map set, this value is not applied. Default is 1.
+		</div>
+
+		<h3>[property:Float displacementBias]</h3>
+		<div>
+			The offset of the displacement map's values on the mesh's vertices. Without a displacement map set, this value is not applied. Default is 0.
+		</div>
+
+		<h3>[property:Texture roughnessMap]</h3>
+		<div>
+			TODO.
+		</div>
+
+		<h3>[property:Texture metalnessMap]</h3>
+		<div>
+			TODO.
+		</div>
+
+		<h3>[property:Texture alphaMap]</h3>
+		<div>The alpha map is a grayscale texture that controls the opacity across the surface (black: fully transparent; white: fully opaque). Default is null.</div>
+		<div>Only the color of the texture is used, ignoring the alpha channel if one exists. For RGB and RGBA textures, the [page:WebGLRenderer WebGL] renderer will use the green channel when sampling this texture due to the extra bit of precision provided for green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and luminance/alpha textures will also still work as expected.</div>
+
+		<h3>[property:TextureCube envMap]</h3>
+		<div>Set env map. Default is null.</div>
+
+		<h3>[property:Float envMapIntensity]</h3>
+		<div>TODO</div>
+
+		<h3>[property:Float refractionRatio]</h3>
+		<div>The index of refraction for an environment map using [page:Textures THREE.CubeRefractionMapping]. Default is *0.98*.</div>
+
+		<h3>[property:Boolean fog]</h3>
+		<div>Define whether the material color is affected by global fog settings. Default is *true*.</div>
+		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:CanvasRenderer Canvas] renderer, but does work with the [page:WebGLRenderer WebGL] renderer.</div>
+
+		<h3>[property:Integer shading]</h3>
+		<div>How the triangles of a curved surface are rendered: as a smooth surface, as flat separate facets, or no shading at all.</div>
+
+		<div>Options are [page:Materials THREE.SmoothShading] (default), [page:Materials THREE.FlatShading].</div>
+
+		<h3>[property:Boolean wireframe]</h3>
+		<div>Whether the triangles' edges are displayed instead of surfaces. Default is *false*.</div>
+
+		<h3>[property:Float wireframeLinewidth]</h3>
+		<div>Line thickness for wireframe mode. Default is *1.0*.</div>
+		<div>Due to limitations in the <a href="https://code.google.com/p/angleproject/" target="_blank">ANGLE layer</a>, on Windows platforms linewidth will always be 1 regardless of the set value.</div>
+
+		<h3>[property:String wireframeLinecap]</h3>
+		<div>Define appearance of line ends. Possible values are "butt", "round" and "square". Default is 'round'.</div>
+		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:WebGLRenderer WebGL] renderer, but does work with the [page:CanvasRenderer Canvas] renderer.</div>
+
+		<h3>[property:String wireframeLinejoin]</h3>
+		<div>Define appearance of line joints. Possible values are "round", "bevel" and "miter". Default is 'round'.</div>
+		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:WebGLRenderer WebGL] renderer, but does work with the [page:CanvasRenderer Canvas] renderer.</div>
+
+		<h3>[property:Integer vertexColors]</h3>
+		<div>Define how the vertices gets colored. Possible values are THREE.NoColors, THREE.FaceColors and THREE.VertexColors. Default is THREE.NoColors.</div>
+		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:CanvasRenderer Canvas] renderer, but does work with the [page:WebGLRenderer WebGL] renderer.</div>
+
+		<h3>[property:Boolean skinning]</h3>
+		<div>Define whether the material uses skinning. Default is *false*.</div>
+
+		<h3>[property:Boolean morphTargets]</h3>
+		<div>Define whether the material uses morphTargets. Default is *false*.</div>
+
+		<h3>[property:boolean morphNormals]</h3>
+		<div>
+			Defines whether the material uses morphNormals. Set as true to pass morphNormal attributes from the [page:Geometry]
+			to the shader. Default is *false*.
+		</div>
+
+		<h2>Methods</h2>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 9 - 8
docs/api/materials/PointsMaterial.html

@@ -20,7 +20,7 @@
 		<h3>[name]( [page:Object parameters] )</h3>
 
 		<div>parameters is an object with one or more properties defining the material's appearance.</div>
-		
+
 		<div>
 		color — Particle color in hexadecimal. Default is 0xffffff.<br />
 		map — a [page:Texture texture].If defined, then a point has the data from texture as colors. Default is null.<br />
@@ -31,27 +31,28 @@
 		</div>
 
 		<h2>Properties</h2>
+		<div>See the base [page:Material] class for common properties.</div>
 
 		<h3>[property:Number color]</h3>
-		
+
 		<div>Sets the color of the particles. Default is 0xffffff.</div>
-		
+
 		<h3>[property:Texture map]</h3>
-		
+
 		<div>Sets the color of the particles using data from a texture.</div>
-		
+
 		<h3>[property:Number size]</h3>
-		
+
 		<div>Sets the size of the particles. Default is 1.0.</div>
 
 		<h3>[property:Boolean sizeAttenuation]</h3>
-		
+
 		<div>Specify whether particles' size will get smaller with the distance. Default is true.</div>
 
 		<h3>[property:Boolean vertexColors]</h3>
 		<div>Define how the vertices gets colored. Possible values are THREE.NoColors, THREE.FaceColors and THREE.VertexColors. Default is THREE.NoColors.</div>
 		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:CanvasRenderer Canvas] renderer, but does work with the [page:WebGLRenderer WebGL] renderer.</div>
-		
+
 		<h3>[property:Boolean fog]</h3>
 		<div>Define whether the material color is affected by global fog settings.</div>
 		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:CanvasRenderer Canvas] renderer, but does work with the [page:WebGLRenderer WebGL] renderer.</div>

+ 1 - 0
docs/api/materials/ShaderMaterial.html

@@ -211,6 +211,7 @@
 		</div>
 
 		<h2>Properties</h2>
+		<div>See the base [page:Material] class for common properties.</div>
 
 		<h3>[property:Object uniforms]</h3>
 		<div>

+ 3 - 3
docs/api/materials/SpriteMaterial.html

@@ -31,13 +31,13 @@
 
 
 		<h2>Properties</h2>
-
+		<div>See the base [page:Material] class for common properties.</div>
 
 		<h3>[property:Color color]</h3>
-		<div>The texture is multiplied by this color. The default is 0xffffff</div> 
+		<div>The texture is multiplied by this color. The default is 0xffffff</div>
 
 		<h3>[property:Texture map]</h3>
-		<div>The texture map. Default is null.</div> 
+		<div>The texture map. Default is null.</div>
 
 		<h3>[property:Radians rotation]</h3>
 		<div>The rotation of the sprite in radians. Default is 0.</div>

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

@@ -171,6 +171,16 @@
 		If this vector's x or y values are less than the min value, they are replaced by the min value.
 		</div>
 
+		<h3>[method:Vector2 clampLength]([page:Float min], [page:Float max]) [page:Vector2 this]</h3>
+		<div>
+		min -- [page:Float] the minimum value the length will be clamped to <br />
+		max -- [page:Float] the maximum value the length will be clamped to
+		</div>
+		<div>
+		If this vector's length is greater than the max value, it is replaced by the max value. <br /><br />
+		If this vector's length is less than the min value, it is replaced by the min value.
+		</div>
+
 		<h3>[method:Vector2 floor]()</h3>
 		<div>
 		The components of the vector are rounded downwards (towards negative infinity) to an integer value.

+ 10 - 0
docs/api/math/Vector3.html

@@ -206,6 +206,16 @@
 		If this vector's x, y or z values are less than the min value, they are replaced by the min value.
 		</div>
 
+		<h3>[method:Vector3 clampLength]([page:Float min], [page:Float max]) [page:Vector3 this]</h3>
+		<div>
+		min -- [page:Float] the minimum value the length will be clamped to <br />
+		max -- [page:Float] the maximum value the length will be clamped to
+		</div>
+		<div>
+		If this vector's length is greater than the max value, it is replaced by the max value. <br /><br />
+		If this vector's length is less than the min value, it is replaced by the min value.
+		</div>
+
 		<h3>[method:Vector3 floor]()</h3>
 		<div>
 		The components of the vector are rounded downwards (towards negative infinity) to an integer value.

+ 4 - 4
docs/api/objects/LineSegments.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en">
 	<head>
-		<meta charset="utf-8" />
+		<meta charset="utf-8" />
 		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
@@ -12,7 +12,7 @@
 
 		<h1>[name]</h1>
 
-		<div class="desc">A series of lines.</div>
+		<div class="desc">A series of lines drawn between pairs of vertices.</div>
 
 
 		<h2>Constructor</h2>
@@ -20,7 +20,7 @@
 		<h3>[name]( [page:Geometry geometry], [page:Material material] )</h3>
 
 		<div>
-		geometry — Vertices representing the line segment(s).<br />
+		geometry — Pair(s) of vertices representing each line segment(s).<br />
 		material — Material for the line. Default is [page:LineBasicMaterial LineBasicMaterial].
 		</div>
 
@@ -31,7 +31,7 @@
 
 		<h3>[property:Geometry geometry]</h3>
 		<div>
-		Vertices representing the line segment(s).
+		Pair(s) of vertices representing the line segment(s).
 		</div>
 
 		<h3>[property:Material material]</h3>

+ 0 - 5
docs/api/renderers/WebGLRenderTarget.html

@@ -88,11 +88,6 @@
 		Whether to generate mipmaps (if possible) for a texture. True by default.
 		</div>
 
-		<h3>[property:WebGLRenderTarget shareDepthFrom]</h3>
-		<div>
-		Shares the depth from another WebGLRenderTarget. Default is null.
-		</div>
-
 		
 		<h2>Methods</h2>
 		

+ 3 - 0
docs/api/renderers/WebGLRenderer.html

@@ -163,6 +163,9 @@
 		<div>
 		Return a [page:Boolean] true if the context supports vertex textures.
 		</div>
+		
+		<h3>[method:Object getSize]()</h3>
+		<div>Returns an object containing the width and height of the renderer's output canvas, in pixels.</div>
 
 		<h3>[method:null setSize]( [page:Integer width], [page:Integer height], [page:Boolean updateStyle] )</h3>
 		<div>Resizes the output canvas to (width, height), and also sets the viewport to fit that size, starting in (0, 0). Setting updateStyle to true adds explicit pixel units to the output canvas style.</div>

+ 5 - 0
docs/api/textures/Texture.html

@@ -128,6 +128,11 @@
 		False by default, which is the norm for PNG images. Set to true if the RGB values have been stored premultiplied by alpha.
 		</div>
 
+		<h3>[property:number encoding]</h3>
+		<div>
+		Set to THREE.LinearEncoding by default, but supports sRGB, RGBE, RGBM, RGBD, LogLuv and Gamma corrected encodings.  IMPORTANT: If this value is changed on a texture after the material has been used, it is necessary to trigger a Material.needsUpdate for this value to be realized in the shader.
+		</div>
+
 		<h3>[property:object onUpdate]</h3>
 		<div>
 		A callback function, called when the texture is updated (e.g., when needsUpdate has been set to true and then the texture is used).

+ 1 - 1
docs/index.html

@@ -1,4 +1,4 @@
-<!doctype html>
+<!DOCTYPE html>
 <html lang="en">
 	<head>
 		<meta charset="utf-8">

+ 10 - 1
docs/list.js

@@ -57,7 +57,6 @@ var list = {
 			[ "MaterialLoader", "api/loaders/MaterialLoader" ],
 			[ "MTLLoader", "api/loaders/MTLLoader" ],
 			[ "OBJLoader", "api/loaders/OBJLoader" ],
-			[ "OBJMTLLoader", "api/loaders/OBJMTLLoader" ],
 			[ "ObjectLoader", "api/loaders/ObjectLoader" ],
 			[ "PDBLoader", "api/loaders/PDBLoader" ],
 			[ "SVGLoader", "api/loaders/SVGLoader" ],
@@ -76,6 +75,7 @@ var list = {
 			[ "MeshLambertMaterial", "api/materials/MeshLambertMaterial" ],
 			[ "MeshNormalMaterial", "api/materials/MeshNormalMaterial" ],
 			[ "MeshPhongMaterial", "api/materials/MeshPhongMaterial" ],
+			[ "MeshStandardMaterial", "api/materials/MeshStandardMaterial" ],
 			[ "PointsMaterial", "api/materials/PointsMaterial" ],
 			[ "RawShaderMaterial", "api/materials/RawShaderMaterial" ],
 			[ "ShaderMaterial", "api/materials/ShaderMaterial" ],
@@ -191,23 +191,32 @@ var list = {
 		],
 
 		"Extras / Geometries": [
+			[ "BoxBufferGeometry", "api/extras/geometries/BoxBufferGeometry" ],
 			[ "BoxGeometry", "api/extras/geometries/BoxGeometry" ],
+			[ "CircleBufferGeometry", "api/extras/geometries/CircleBufferGeometry" ],
 			[ "CircleGeometry", "api/extras/geometries/CircleGeometry" ],
+			[ "CylinderBufferGeometry", "api/extras/geometries/CylinderBufferGeometry" ],
 			[ "CylinderGeometry", "api/extras/geometries/CylinderGeometry" ],
 			[ "DodecahedronGeometry", "api/extras/geometries/DodecahedronGeometry" ],
 			[ "ExtrudeGeometry", "api/extras/geometries/ExtrudeGeometry" ],
 			[ "IcosahedronGeometry", "api/extras/geometries/IcosahedronGeometry" ],
+			[ "LatheBufferGeometry", "api/extras/geometries/LatheBufferGeometry" ],
 			[ "LatheGeometry", "api/extras/geometries/LatheGeometry" ],
 			[ "OctahedronGeometry", "api/extras/geometries/OctahedronGeometry" ],
 			[ "ParametricGeometry", "api/extras/geometries/ParametricGeometry" ],
+			[ "PlaneBufferGeometry", "api/extras/geometries/PlaneBufferGeometry" ],
 			[ "PlaneGeometry", "api/extras/geometries/PlaneGeometry" ],
 			[ "PolyhedronGeometry", "api/extras/geometries/PolyhedronGeometry" ],
+			[ "RingBufferGeometry", "api/extras/geometries/RingBufferGeometry" ],
 			[ "RingGeometry", "api/extras/geometries/RingGeometry" ],
 			[ "ShapeGeometry", "api/extras/geometries/ShapeGeometry" ],
+			[ "SphereBufferGeometry", "api/extras/geometries/SphereBufferGeometry" ],
 			[ "SphereGeometry", "api/extras/geometries/SphereGeometry" ],
 			[ "TetrahedronGeometry", "api/extras/geometries/TetrahedronGeometry" ],
 			[ "TextGeometry", "api/extras/geometries/TextGeometry" ],
+			[ "TorusBufferGeometry", "api/extras/geometries/TorusBufferGeometry" ],
 			[ "TorusGeometry", "api/extras/geometries/TorusGeometry" ],
+			[ "TorusKnotBufferGeometry", "api/extras/geometries/TorusKnotBufferGeometry" ],
 			[ "TorusKnotGeometry", "api/extras/geometries/TorusKnotGeometry" ],
 			[ "TubeGeometry", "api/extras/geometries/TubeGeometry" ]
 		],

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

@@ -8,18 +8,13 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	<body>
-		<h1>[name]</h1>
+		<h1>[name]</h1><br />
 
 		<div>The goal of this section is to give a brief introduction to Three.js. We will start by setting up a scene, with a spinning cube. A working example is provided at the bottom of the page in case you get stuck and need help.</div>
 
-		<h2>What is Three.js?</h2>
-
-		<div>Let's try to describe it briefly:</div>
-
-		<div>Three.js is a library that makes WebGL - 3D in the browser - easy to use. While a simple cube in raw WebGL would turn out hundreds of lines of Javascript and shader code, a Three.js equivalent is only a fraction of that.</div>
-
 		<h2>Before we start</h2>
-		<div>Before you can use Three.js, you need somewhere to display it. Save the following HTML to a file on your computer, along with a copy of <a href="http://threejs.org/build/three.min.js">three.min.js</a> in the js/ directory, and open it in your browser.</div>
+
+		<div>Before you can use Three.js, you need somewhere to display it. Save the following HTML to a file on your computer, along with a copy of <a href="http://threejs.org/build/three.js">three.js</a> in the js/ directory, and open it in your browser.</div>
 
 		<code>
 		&lt;!DOCTYPE html&gt;
@@ -33,7 +28,7 @@
 				&lt;/style&gt;
 			&lt;/head&gt;
 			&lt;body&gt;
-				&lt;script src="js/three.min.js"&gt;&lt;/script&gt;
+				&lt;script src="js/three.js"&gt;&lt;/script&gt;
 				&lt;script&gt;
 					// Our Javascript will go here.
 				&lt;/script&gt;
@@ -65,9 +60,9 @@
 		<div>Next up is the renderer. This is where the magic happens. In addition to the WebGLRenderer we use here, Three.js comes with a few others, often used as fallbacks for users with older browsers or for those who don't have WebGL support for some reason.</div>
 
 		<div>In addition to creating the renderer instance, we also need to set the size at which we want it to render our app. It's a good idea to use the width and height of the area we want to fill with our app - in this case, the width and height of the browser window. For performance intensive apps, you can also give <strong>setSize</strong> smaller values, like <strong>window.innerWidth/2</strong> and <strong>window.innerHeight/2</strong>, which will make the app render at half size.</div>
-		
+
 		<div>If you wish to keep the size of your app but render it at a lower resolution, you can do so by calling <strong>setSize</strong> with false as <strong>updateStyle</strong>. For example, <strong>setSize(window.innerWidth/2, window.innerHeight/2, false)</strong> will render your app at half resolution, given that your &lt;canvas&gt; has 100% width and height.</div>
-		
+
 		<div>Last but not least, we add the <strong>renderer</strong> element to our HTML document. This is a &lt;canvas&gt; element the renderer uses to display the scene to us.</div>
 
 		<div><em>"That's all good, but where's that cube you promised?"</em> Let's add it now.</div>
@@ -132,7 +127,7 @@
 				&lt;/style&gt;
 			&lt;/head&gt;
 			&lt;body&gt;
-				&lt;script src="js/three.min.js"&gt;&lt;/script&gt;
+				&lt;script src="js/three.js"&gt;&lt;/script&gt;
 				&lt;script&gt;
 					var scene = new THREE.Scene();
 					var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );

+ 1 - 0
docs/page.css

@@ -11,6 +11,7 @@ body {
 	font-family: 'inconsolata';
 	font-size: 15px;
 	line-height: 18px;
+	tab-size: 4;
 	overflow: auto;
 }
 

+ 10 - 10
docs/scenes/bones-browser.html

@@ -1,4 +1,4 @@
-<!doctype html>
+<!DOCTYPE html>
 <html lang="en">
 	<head>
 		<meta charset="utf-8">
@@ -57,7 +57,7 @@
 				camera.position.y = 30;
 
 				renderer = new THREE.WebGLRenderer( { antialias: true } );
-				renderer.setPixelRatio( window.devicePixelRatio );				
+				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				document.body.appendChild( renderer.domElement );
 
@@ -74,7 +74,7 @@
 
 				lights[ 0 ].position.set( 0, 200, 0 );
 				lights[ 1 ].position.set( 100, 200, 100 );
-				lights[ 2 ].position.set( -100, -200, -100 );
+				lights[ 2 ].position.set( - 100, - 200, - 100 );
 
 				scene.add( lights[ 0 ] );
 				scene.add( lights[ 1 ] );
@@ -128,7 +128,7 @@
 
 				var prevBone = new THREE.Bone();
 				bones.push( prevBone );
-				prevBone.position.y = -sizing.halfHeight;
+				prevBone.position.y = - sizing.halfHeight;
 
 				for ( var i = 0; i < sizing.segmentCount; i ++ ) {
 
@@ -187,13 +187,13 @@
 
 					folder = gui.addFolder( "Bone " + i );
 
-					folder.add( bone.position, 'x', -10 + bone.position.x, 10 + bone.position.x );
-					folder.add( bone.position, 'y', -10 + bone.position.y, 10 + bone.position.y );
-					folder.add( bone.position, 'z', -10 + bone.position.z, 10 + bone.position.z );
+					folder.add( bone.position, 'x', - 10 + bone.position.x, 10 + bone.position.x );
+					folder.add( bone.position, 'y', - 10 + bone.position.y, 10 + bone.position.y );
+					folder.add( bone.position, 'z', - 10 + bone.position.z, 10 + bone.position.z );
 
-					folder.add( bone.rotation, 'x', -Math.PI * 0.5, Math.PI * 0.5 );
-					folder.add( bone.rotation, 'y', -Math.PI * 0.5, Math.PI * 0.5 );
-					folder.add( bone.rotation, 'z', -Math.PI * 0.5, Math.PI * 0.5 );
+					folder.add( bone.rotation, 'x', - Math.PI * 0.5, Math.PI * 0.5 );
+					folder.add( bone.rotation, 'y', - Math.PI * 0.5, Math.PI * 0.5 );
+					folder.add( bone.rotation, 'z', - Math.PI * 0.5, Math.PI * 0.5 );
 
 					folder.add( bone.scale, 'x', 0, 2 );
 					folder.add( bone.scale, 'y', 0, 2 );

+ 21 - 19
docs/scenes/geometry-browser.html

@@ -1,4 +1,4 @@
-<!doctype html>
+<!DOCTYPE html>
 <html lang="en">
 	<head>
 		<meta charset="utf-8">
@@ -42,11 +42,11 @@
 
 		<script>
 
-			document.getElementById('newWindow').href += window.location.hash;
+			document.getElementById( 'newWindow' ).href += window.location.hash;
 
 			var gui = new dat.GUI();
 			var scene = new THREE.Scene();
-			var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 50 );
+			var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 50 );
 			camera.position.z = 30;
 
 			var renderer = new THREE.WebGLRenderer( { antialias: true } );
@@ -61,17 +61,17 @@
 			scene.add( ambientLight );
 
 			var lights = [];
-			lights[0] = new THREE.PointLight( 0xffffff, 1, 0 );
-			lights[1] = new THREE.PointLight( 0xffffff, 1, 0 );
-			lights[2] = new THREE.PointLight( 0xffffff, 1, 0 );
+			lights[ 0 ] = new THREE.PointLight( 0xffffff, 1, 0 );
+			lights[ 1 ] = new THREE.PointLight( 0xffffff, 1, 0 );
+			lights[ 2 ] = new THREE.PointLight( 0xffffff, 1, 0 );
 
-			lights[0].position.set( 0, 200, 0 );
-			lights[1].position.set( 100, 200, 100 );
-			lights[2].position.set( -100, -200, -100 );
+			lights[ 0 ].position.set( 0, 200, 0 );
+			lights[ 1 ].position.set( 100, 200, 100 );
+			lights[ 2 ].position.set( - 100, - 200, - 100 );
 
-			scene.add( lights[0] );
-			scene.add( lights[1] );
-			scene.add( lights[2] );
+			scene.add( lights[ 0 ] );
+			scene.add( lights[ 1 ] );
+			scene.add( lights[ 2 ] );
 
 			var mesh = new THREE.Object3D()
 
@@ -79,26 +79,26 @@
 
 				new THREE.Geometry(),
 
-				new THREE.LineBasicMaterial({
+				new THREE.LineBasicMaterial( {
 					color: 0xffffff,
 					transparent: true,
 					opacity: 0.5
-				})
+				} )
 
-			));
+			) );
 
 			mesh.add( new THREE.Mesh(
 
 				new THREE.Geometry(),
 
-				new THREE.MeshPhongMaterial({
+				new THREE.MeshPhongMaterial( {
 					color: 0x156289,
 					emissive: 0x072534,
 					side: THREE.DoubleSide,
 					shading: THREE.FlatShading
-				})
+				} )
 
-			));
+			) );
 
 			var options = chooseFromHash( mesh );
 
@@ -112,9 +112,11 @@
 
 				var time = Date.now() * 0.001;
 
-				if( !options.fixed ) {
+				if ( ! options.fixed ) {
+
 					mesh.rotation.x += 0.005;
 					mesh.rotation.y += 0.005;
+
 				}
 
 				renderer.render( scene, camera );

+ 357 - 10
docs/scenes/js/geometry.js

@@ -93,6 +93,40 @@ function updateGroupGeometry( mesh, geometry ) {
 
 var guis = {
 
+	BoxBufferGeometry : function( mesh ) {
+
+		var data = {
+			width : 15,
+			height : 15,
+			depth : 15,
+			widthSegments : 1,
+			heightSegments : 1,
+			depthSegments : 1
+		};
+
+		function generateGeometry() {
+
+			updateGroupGeometry( mesh,
+				new THREE.BoxBufferGeometry(
+					data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments
+				)
+			);
+
+		}
+
+		var folder = gui.addFolder( 'THREE.BoxBufferGeometry' );
+
+		folder.add( data, 'width', 1, 30 ).onChange( generateGeometry );
+		folder.add( data, 'height', 1, 30 ).onChange( generateGeometry );
+		folder.add( data, 'depth', 1, 30 ).onChange( generateGeometry );
+		folder.add( data, 'widthSegments', 1, 10 ).step( 1 ).onChange( generateGeometry );
+		folder.add( data, 'heightSegments', 1, 10 ).step( 1 ).onChange( generateGeometry );
+		folder.add( data, 'depthSegments', 1, 10 ).step( 1 ).onChange( generateGeometry );
+
+		generateGeometry();
+
+	},
+
 	BoxGeometry : function( mesh ) {
 
 		var data = {
@@ -127,6 +161,52 @@ var guis = {
 
 	},
 
+	CylinderBufferGeometry : function( mesh ) {
+
+		var data = {
+			radiusTop : 5,
+			radiusBottom : 5,
+			height : 10,
+			radiusSegments : 8,
+			heightSegments : 1,
+			openEnded : false,
+			thetaStart : 0,
+			thetaLength : twoPi,
+		};
+
+		function generateGeometry() {
+
+			updateGroupGeometry( mesh,
+				new THREE.CylinderBufferGeometry(
+					data.radiusTop,
+					data.radiusBottom,
+					data.height,
+					data.radiusSegments,
+					data.heightSegments,
+					data.openEnded,
+					data.thetaStart,
+					data.thetaLength
+				)
+			);
+
+		}
+
+		var folder = gui.addFolder( 'THREE.CylinderBufferGeometry' );
+
+		folder.add( data, 'radiusTop', 1, 30 ).onChange( generateGeometry );
+		folder.add( data, 'radiusBottom', 1, 30 ).onChange( generateGeometry );
+		folder.add( data, 'height', 1, 50 ).onChange( generateGeometry );
+		folder.add( data, 'radiusSegments', 3, 64 ).step( 1 ).onChange( generateGeometry );
+		folder.add( data, 'heightSegments', 1, 64 ).step( 1 ).onChange( generateGeometry );
+		folder.add( data, 'openEnded' ).onChange( generateGeometry );
+		folder.add( data, 'thetaStart', 0, twoPi ).onChange( generateGeometry );
+		folder.add( data, 'thetaLength', 0, twoPi ).onChange( generateGeometry );
+
+
+		generateGeometry();
+
+	},
+
 	CylinderGeometry : function( mesh ) {
 
 		var data = {
@@ -173,6 +253,36 @@ var guis = {
 
 	},
 
+	CircleBufferGeometry : function( mesh ) {
+
+		var data = {
+			radius : 10,
+			segments : 32,
+			thetaStart : 0,
+			thetaLength : twoPi,
+		};
+
+		function generateGeometry() {
+
+			updateGroupGeometry( mesh,
+				new THREE.CircleBufferGeometry(
+					data.radius, data.segments, data.thetaStart, data.thetaLength
+				)
+			);
+
+		}
+
+		var folder = gui.addFolder( 'THREE.CircleBufferGeometry' );
+
+		folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry );
+		folder.add( data, 'segments', 0, 128 ).step( 1 ).onChange( generateGeometry );
+		folder.add( data, 'thetaStart', 0, twoPi ).onChange( generateGeometry );
+		folder.add( data, 'thetaLength', 0, twoPi ).onChange( generateGeometry );
+
+		generateGeometry();
+
+	},
+
 	CircleGeometry : function( mesh ) {
 
 		var data = {
@@ -255,6 +365,78 @@ var guis = {
 
 	},
 
+	LatheBufferGeometry : function() {
+
+		var points = [];
+
+		for ( var i = 0; i < 10; i ++ ) {
+
+			points.push( new THREE.Vector2( Math.sin( i * 0.2 ) * 10 + 5, ( i - 5 ) * 2 ) );
+
+		}
+
+		var data = {
+			segments : 12,
+			phiStart : 0,
+			phiLength : twoPi,
+		};
+
+		function generateGeometry() {
+
+			var geometry = new THREE.LatheBufferGeometry(
+				points, data.segments, data.phiStart, data.phiLength
+			);
+
+			updateGroupGeometry( mesh, geometry );
+
+		}
+
+		var folder = gui.addFolder( 'THREE.LatheBufferGeometry' );
+
+		folder.add( data, 'segments', 1, 30 ).step( 1 ).onChange( generateGeometry );
+		folder.add( data, 'phiStart', 0, twoPi ).onChange( generateGeometry );
+		folder.add( data, 'phiLength', 0, twoPi ).onChange( generateGeometry );
+
+		generateGeometry();
+
+	},
+
+	LatheGeometry : function() {
+
+		var points = [];
+
+		for ( var i = 0; i < 10; i ++ ) {
+
+			points.push( new THREE.Vector2( Math.sin( i * 0.2 ) * 10 + 5, ( i - 5 ) * 2 ) );
+
+		}
+
+		var data = {
+			segments : 12,
+			phiStart : 0,
+			phiLength : twoPi,
+		};
+
+		function generateGeometry() {
+
+			var geometry = new THREE.LatheGeometry(
+				points, data.segments, data.phiStart, data.phiLength
+			);
+
+			updateGroupGeometry( mesh, geometry );
+
+		}
+
+		var folder = gui.addFolder( 'THREE.LatheGeometry' );
+
+		folder.add( data, 'segments', 1, 30 ).step( 1 ).onChange( generateGeometry );
+		folder.add( data, 'phiStart', 0, twoPi ).onChange( generateGeometry );
+		folder.add( data, 'phiLength', 0, twoPi ).onChange( generateGeometry );
+
+		generateGeometry();
+
+	},
+
 	OctahedronGeometry : function() {
 
 		var data = {
@@ -281,6 +463,36 @@ var guis = {
 
 	},
 
+	PlaneBufferGeometry : function( mesh ) {
+
+		var data = {
+			width : 10,
+			height : 10,
+			widthSegments : 1,
+			heightSegments : 1
+		};
+
+		function generateGeometry() {
+
+			updateGroupGeometry( mesh,
+				new THREE.PlaneBufferGeometry(
+					data.width, data.height, data.widthSegments, data.heightSegments
+				)
+			);
+
+		}
+
+		var folder = gui.addFolder( 'THREE.PlaneBufferGeometry' );
+
+		folder.add( data, 'width', 1, 30 ).onChange( generateGeometry );
+		folder.add( data, 'height', 1, 30 ).onChange( generateGeometry );
+		folder.add( data, 'widthSegments', 1, 30 ).step( 1 ).onChange( generateGeometry );
+		folder.add( data, 'heightSegments', 1, 30 ).step( 1 ).onChange( generateGeometry );
+
+		generateGeometry();
+
+	},
+
 	PlaneGeometry : function( mesh ) {
 
 		var data = {
@@ -311,6 +523,40 @@ var guis = {
 
 	},
 
+	RingBufferGeometry : function( mesh ) {
+
+		var data = {
+			innerRadius : 5,
+			outerRadius : 10,
+			thetaSegments : 8,
+			phiSegments : 8,
+			thetaStart : 0,
+			thetaLength : twoPi,
+		};
+
+		function generateGeometry() {
+
+			updateGroupGeometry( mesh,
+				new THREE.RingBufferGeometry(
+					data.innerRadius, data.outerRadius, data.thetaSegments, data.phiSegments, data.thetaStart, data.thetaLength
+				)
+			);
+
+		}
+
+		var folder = gui.addFolder( 'THREE.RingBufferGeometry' );
+
+		folder.add( data, 'innerRadius', 0, 30 ).onChange( generateGeometry );
+		folder.add( data, 'outerRadius', 1, 30 ).onChange( generateGeometry );
+		folder.add( data, 'thetaSegments', 1, 30 ).step( 1 ).onChange( generateGeometry );
+		folder.add( data, 'phiSegments', 1, 30 ).step( 1 ).onChange( generateGeometry );
+		folder.add( data, 'thetaStart', 0, twoPi ).onChange( generateGeometry );
+		folder.add( data, 'thetaLength', 0, twoPi ).onChange( generateGeometry );
+
+		generateGeometry();
+
+	},
+
 	RingGeometry : function( mesh ) {
 
 		var data = {
@@ -345,6 +591,42 @@ var guis = {
 
 	},
 
+	SphereBufferGeometry : function( mesh ) {
+
+		var data = {
+			radius : 15,
+			widthSegments : 8,
+			heightSegments : 6,
+			phiStart : 0,
+			phiLength : twoPi,
+			thetaStart : 0,
+			thetaLength : Math.PI,
+		};
+
+		function generateGeometry() {
+
+			updateGroupGeometry( mesh,
+				new THREE.SphereBufferGeometry(
+					data.radius, data.widthSegments, data.heightSegments, data.phiStart, data.phiLength, data.thetaStart, data.thetaLength
+				)
+			);
+
+		}
+
+		var folder = gui.addFolder( 'THREE.SphereBufferGeometry' );
+
+		folder.add( data, 'radius', 1, 30 ).onChange( generateGeometry );
+		folder.add( data, 'widthSegments', 3, 32 ).step( 1 ).onChange( generateGeometry );
+		folder.add( data, 'heightSegments', 2, 32 ).step( 1 ).onChange( generateGeometry );
+		folder.add( data, 'phiStart', 0, twoPi ).onChange( generateGeometry );
+		folder.add( data, 'phiLength', 0, twoPi ).onChange( generateGeometry );
+		folder.add( data, 'thetaStart', 0, twoPi ).onChange( generateGeometry );
+		folder.add( data, 'thetaLength', 0, twoPi ).onChange( generateGeometry );
+
+		generateGeometry();
+
+	},
+
 	SphereGeometry : function( mesh ) {
 
 		var data = {
@@ -473,6 +755,38 @@ var guis = {
 
 	},
 
+	TorusBufferGeometry : function( mesh ) {
+
+		var data = {
+			radius : 10,
+			tube : 3,
+			radialSegments : 16,
+			tubularSegments : 100,
+			arc : twoPi
+		};
+
+		function generateGeometry() {
+
+			updateGroupGeometry( mesh,
+				new THREE.TorusBufferGeometry(
+					data.radius, data.tube, data.radialSegments, data.tubularSegments, data.arc
+				)
+			);
+
+		}
+
+		var folder = gui.addFolder( 'THREE.TorusBufferGeometry' );
+
+		folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry );
+		folder.add( data, 'tube', 0.1, 10 ).onChange( generateGeometry );
+		folder.add( data, 'radialSegments', 2, 30 ).step( 1 ).onChange( generateGeometry );
+		folder.add( data, 'tubularSegments', 3, 200 ).step( 1 ).onChange( generateGeometry );
+		folder.add( data, 'arc', 0.1, twoPi ).onChange( generateGeometry );
+
+		generateGeometry();
+
+	},
+
 	TorusGeometry : function( mesh ) {
 
 		var data = {
@@ -505,38 +819,71 @@ var guis = {
 
 	},
 
+	TorusKnotBufferGeometry : function( mesh ) {
+
+		var data = {
+			radius : 10,
+			tube : 3,
+			tubularSegments : 64,
+			radialSegments : 8,
+			p : 2,
+			q : 3
+		};
+
+		function generateGeometry() {
+
+			updateGroupGeometry( mesh,
+				new THREE.TorusKnotBufferGeometry(
+					data.radius, data.tube, data.tubularSegments, data.radialSegments,
+					data.p, data.q
+				)
+			);
+
+		}
+
+		var folder = gui.addFolder( 'THREE.TorusKnotBufferGeometry' );
+
+		folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry );
+		folder.add( data, 'tube', 0.1, 10 ).onChange( generateGeometry );
+		folder.add( data, 'tubularSegments', 3, 300 ).step( 1 ).onChange( generateGeometry );
+		folder.add( data, 'radialSegments', 3, 20 ).step( 1 ).onChange( generateGeometry );
+		folder.add( data, 'p', 1, 20 ).step( 1 ).onChange( generateGeometry );
+		folder.add( data, 'q', 1, 20 ).step( 1 ).onChange( generateGeometry );
+
+		generateGeometry();
+
+	},
+
 	TorusKnotGeometry : function( mesh ) {
 
 		var data = {
 			radius : 10,
 			tube : 3,
-			radialSegments : 64,
-			tubularSegments : 8,
+			tubularSegments : 64,
+			radialSegments : 8,
 			p : 2,
-			q : 3,
-			heightScale : 1
+			q : 3
 		};
 
 		function generateGeometry() {
 
 			updateGroupGeometry( mesh,
 				new THREE.TorusKnotGeometry(
-					data.radius, data.tube, data.radialSegments, data.tubularSegments,
-					data.p, data.q, data.heightScale
+					data.radius, data.tube, data.tubularSegments, data.radialSegments,
+					data.p, data.q
 				)
 			);
 
 		}
 
-		var folder = gui.addFolder( 'THREE.TorusGeometry' );
+		var folder = gui.addFolder( 'THREE.TorusKnotGeometry' );
 
 		folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry );
 		folder.add( data, 'tube', 0.1, 10 ).onChange( generateGeometry );
-		folder.add( data, 'radialSegments', 3, 300 ).step( 1 ).onChange( generateGeometry );
-		folder.add( data, 'tubularSegments', 3, 20 ).step( 1 ).onChange( generateGeometry );
+		folder.add( data, 'tubularSegments', 3, 300 ).step( 1 ).onChange( generateGeometry );
+		folder.add( data, 'radialSegments', 3, 20 ).step( 1 ).onChange( generateGeometry );
 		folder.add( data, 'p', 1, 20 ).step( 1 ).onChange( generateGeometry );
 		folder.add( data, 'q', 1, 20 ).step( 1 ).onChange( generateGeometry );
-		folder.add( data, 'heightScale', 1, 20 ).onChange( generateGeometry );
 
 		generateGeometry();
 

+ 43 - 0
docs/scenes/js/material.js

@@ -453,6 +453,39 @@ function guiMeshPhongMaterial ( gui, mesh, material, geometry ) {
 
 }
 
+function guiMeshStandardMaterial ( gui, mesh, material, geometry ) {
+
+	var data = {
+		color : material.color.getHex(),
+		emissive : material.emissive.getHex(),
+		envMaps : envMapKeys,
+		map : textureMapKeys,
+		lightMap : textureMapKeys,
+		specularMap : textureMapKeys,
+		alphaMap : textureMapKeys
+	};
+
+	var folder = gui.addFolder('THREE.MeshStandardMaterial');
+
+	folder.addColor( data, 'color' ).onChange( handleColorChange( material.color ) );
+	folder.addColor( data, 'emissive' ).onChange( handleColorChange( material.emissive ) );
+
+	folder.add( material, 'roughness', 0, 1 );
+	folder.add( material, 'metalness', 0, 1 );
+	folder.add( material, 'shading', constants.shading).onChange( needsUpdate( material, geometry ) );
+	folder.add( material, 'wireframe' );
+	folder.add( material, 'wireframeLinewidth', 0, 10 );
+	folder.add( material, 'vertexColors', constants.colors);
+	folder.add( material, 'fog' );
+	folder.add( data, 'envMaps', envMapKeys ).onChange( updateTexture( material, 'envMap', envMaps ) );
+	folder.add( data, 'map', textureMapKeys ).onChange( updateTexture( material, 'map', textureMaps ) );
+	folder.add( data, 'lightMap', textureMapKeys ).onChange( updateTexture( material, 'lightMap', textureMaps ) );
+	folder.add( data, 'alphaMap', textureMapKeys ).onChange( updateTexture( material, 'alphaMap', textureMaps ) );
+
+	// TODO roughnessMap and metalnessMap
+
+}
+
 function chooseFromHash ( gui, mesh, geometry ) {
 
 	var selectedMaterial = window.location.hash.substring(1) || "MeshBasicMaterial";
@@ -490,6 +523,16 @@ function chooseFromHash ( gui, mesh, geometry ) {
 
 		break;
 
+	case "MeshStandardMaterial" :
+
+		material = new THREE.MeshStandardMaterial({color: 0x2194CE});
+		guiMaterial( gui, mesh, material, geometry );
+		guiMeshStandardMaterial( gui, mesh, material, geometry );
+
+		return material;
+
+		break;
+
 	case "MeshDepthMaterial" :
 
 		material = new THREE.MeshDepthMaterial({color: 0x2194CE});

+ 12 - 12
docs/scenes/material-browser.html

@@ -1,4 +1,4 @@
-<!doctype html>
+<!DOCTYPE html>
 <html lang="en">
 	<head>
 		<meta charset="utf-8">
@@ -40,11 +40,11 @@
 
 		<script>
 
-			document.getElementById('newWindow').href += window.location.hash;
+			document.getElementById( 'newWindow' ).href += window.location.hash;
 
 			var gui = new dat.GUI();
 			var scene = new THREE.Scene();
-			var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 50 );
+			var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 50 );
 			camera.position.z = 30;
 
 			var renderer = new THREE.WebGLRenderer( { antialias: true } );
@@ -56,17 +56,17 @@
 			scene.add( ambientLight );
 
 			var lights = [];
-			lights[0] = new THREE.PointLight( 0xffffff, 1, 0 );
-			lights[1] = new THREE.PointLight( 0xffffff, 1, 0 );
-			lights[2] = new THREE.PointLight( 0xffffff, 1, 0 );
+			lights[ 0 ] = new THREE.PointLight( 0xffffff, 1, 0 );
+			lights[ 1 ] = new THREE.PointLight( 0xffffff, 1, 0 );
+			lights[ 2 ] = new THREE.PointLight( 0xffffff, 1, 0 );
 
-			lights[0].position.set( 0, 200, 0 );
-			lights[1].position.set( 100, 200, 100 );
-			lights[2].position.set( -100, -200, -100 );
+			lights[ 0 ].position.set( 0, 200, 0 );
+			lights[ 1 ].position.set( 100, 200, 100 );
+			lights[ 2 ].position.set( - 100, - 200, - 100 );
 
-			scene.add( lights[0] );
-			scene.add( lights[1] );
-			scene.add( lights[2] );
+			scene.add( lights[ 0 ] );
+			scene.add( lights[ 1 ] );
+			scene.add( lights[ 2 ] );
 
 			guiScene( gui, scene, camera );
 

+ 1 - 1
editor/css/light.css

@@ -17,7 +17,7 @@
 	}
 
 	.Outliner .option.active {
-		background-color: #f8f8f8;
+		background-color: rgba(0,0,0,0.02);
 	}
 
 input.Number {

+ 23 - 0
editor/css/main.css

@@ -94,6 +94,29 @@ textarea, input { outline: none; } /* osx */
 
 /* outliner */
 
+#outliner .option {
+
+	border: 1px solid transparent;
+}
+
+#outliner .option.drag {
+
+	border: 1px dashed #999;
+
+}
+
+#outliner .option.dragTop {
+
+	border-top: 1px dashed #999;
+
+}
+
+#outliner .option.dragBottom {
+
+	border-bottom: 1px dashed #999;
+
+}
+
 #outliner .type {
 	position:relative;
 	top:-2px;

+ 6 - 4
editor/index.html

@@ -73,7 +73,6 @@
 		<script src="js/libs/ternjs/doc_comment.js"></script>
 		<script src="js/libs/tern-threejs/threejs.js"></script>
 
-		<script src="js/libs/sortable.min.js"></script>
 		<script src="js/libs/signals.min.js"></script>
 		<script src="js/libs/ui.js"></script>
 		<script src="js/libs/ui.three.js"></script>
@@ -193,6 +192,8 @@
 
 				editor.storage.get( function ( state ) {
 
+					if ( isLoadingFromHash ) return;
+
 					if ( state !== undefined ) {
 
 						editor.fromJSON( state );
@@ -324,6 +325,7 @@
 
 			//
 
+			var isLoadingFromHash = false;
 			var hash = window.location.hash;
 
 			if ( hash.substr( 1, 5 ) === 'file=' ) {
@@ -336,13 +338,13 @@
 					loader.crossOrigin = '';
 					loader.load( file, function ( text ) {
 
-						var json = JSON.parse( text );
-
 						editor.clear();
-						editor.fromJSON( json );
+						editor.fromJSON( JSON.parse( text ) );
 
 					} );
 
+					isLoadingFromHash = true;
+
 				}
 
 			}

+ 1 - 0
editor/js/Config.js

@@ -13,6 +13,7 @@ var Config = function () {
 		'project/renderer': 'WebGLRenderer',
 		'project/renderer/antialias': true,
 		'project/renderer/shadows': true,
+		'project/editable': false,
 		'project/vr': false,
 
 		'settings/history': false,

+ 1 - 9
editor/js/Editor.js

@@ -446,15 +446,6 @@ Editor.prototype = {
 
 		}
 
-		// TODO: Clean this up somehow
-
-		if ( json.project !== undefined ) {
-
-			this.config.setKey( 'project/renderer/shadows', json.project.shadows );
-			this.config.setKey( 'project/vr', json.project.vr );
-
-		}
-
 		var camera = loader.parse( json.camera );
 
 		this.camera.copy( camera );
@@ -494,6 +485,7 @@ Editor.prototype = {
 			metadata: {},
 			project: {
 				shadows: this.config.getKey( 'project/renderer/shadows' ),
+				editable: this.config.getKey( 'project/editable' ),
 				vr: this.config.getKey( 'project/vr' )
 			},
 			camera: this.camera.toJSON(),

+ 3 - 4
editor/js/Menubar.Add.js

@@ -198,13 +198,12 @@ Menubar.Add = function ( editor ) {
 
 		var radius = 2;
 		var tube = 0.8;
-		var radialSegments = 64;
-		var tubularSegments = 12;
+		var tubularSegments = 64;
+		var radialSegments = 12;
 		var p = 2;
 		var q = 3;
-		var heightScale = 1;
 
-		var geometry = new THREE.TorusKnotGeometry( radius, tube, radialSegments, tubularSegments, p, q, heightScale );
+		var geometry = new THREE.TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q );
 		var mesh = new THREE.Mesh( geometry, new THREE.MeshStandardMaterial() );
 		mesh.name = 'TorusKnot ' + ( ++ meshCount );
 

+ 10 - 2
editor/js/Sidebar.Geometry.LatheGeometry.js

@@ -63,9 +63,17 @@ Sidebar.Geometry.LatheGeometry = function( editor, object ) {
 
 	var addPointButton = new UI.Button( '+' ).onClick( function() {
 
-		var point = pointsUI[ pointsUI.length - 1 ];
+		if( pointsUI.length === 0 ){
 
-		pointsList.add( createPointRow( point.x.getValue(), point.y.getValue() ) );
+			pointsList.add( createPointRow( 0, 0 ) );
+
+		} else {
+
+			var point = pointsUI[ pointsUI.length - 1 ];
+
+			pointsList.add( createPointRow( point.x.getValue(), point.y.getValue() ) );
+
+		}
 
 		update();
 

+ 12 - 23
editor/js/Sidebar.Geometry.TorusKnotGeometry.js

@@ -30,16 +30,6 @@ Sidebar.Geometry.TorusKnotGeometry = function ( editor, object ) {
 
 	container.add( tubeRow );
 
-	// radialSegments
-
-	var radialSegmentsRow = new UI.Row();
-	var radialSegments = new UI.Integer( parameters.radialSegments ).setRange( 1, Infinity ).onChange( update );
-
-	radialSegmentsRow.add( new UI.Text( 'Radial segments' ).setWidth( '90px' ) );
-	radialSegmentsRow.add( radialSegments );
-
-	container.add( radialSegmentsRow );
-
 	// tubularSegments
 
 	var tubularSegmentsRow = new UI.Row();
@@ -50,6 +40,16 @@ Sidebar.Geometry.TorusKnotGeometry = function ( editor, object ) {
 
 	container.add( tubularSegmentsRow );
 
+	// radialSegments
+
+	var radialSegmentsRow = new UI.Row();
+	var radialSegments = new UI.Integer( parameters.radialSegments ).setRange( 1, Infinity ).onChange( update );
+
+	radialSegmentsRow.add( new UI.Text( 'Radial segments' ).setWidth( '90px' ) );
+	radialSegmentsRow.add( radialSegments );
+
+	container.add( radialSegmentsRow );
+
 	// p
 
 	var pRow = new UI.Row();
@@ -70,16 +70,6 @@ Sidebar.Geometry.TorusKnotGeometry = function ( editor, object ) {
 
 	container.add( qRow );
 
-	// heightScale
-
-	var heightScaleRow = new UI.Row();
-	var heightScale = new UI.Number( parameters.heightScale ).onChange( update );
-
-	pRow.add( new UI.Text( 'Height scale' ).setWidth( '90px' ) );
-	pRow.add( heightScale );
-
-	container.add( heightScaleRow );
-
 
 	//
 
@@ -88,11 +78,10 @@ Sidebar.Geometry.TorusKnotGeometry = function ( editor, object ) {
 		editor.execute( new SetGeometryCommand( object, new THREE.TorusKnotGeometry(
 			radius.getValue(),
 			tube.getValue(),
-			radialSegments.getValue(),
 			tubularSegments.getValue(),
+			radialSegments.getValue(),
 			p.getValue(),
-			q.getValue(),
-			heightScale.getValue()
+			q.getValue()
 		) ) );
 
 	}

+ 14 - 0
editor/js/Sidebar.Project.js

@@ -80,6 +80,20 @@ Sidebar.Project = function ( editor ) {
 
 	container.add( rendererPropertiesRow );
 
+	// Editable
+
+	var editableRow = new UI.Row();
+	var editable = new UI.Checkbox( config.getKey( 'project/editable' ) ).setLeft( '100px' ).onChange( function () {
+
+		config.setKey( 'project/editable', this.getValue() );
+
+	} );
+
+	editableRow.add( new UI.Text( 'Editable' ).setWidth( '90px' ) );
+	editableRow.add( editable );
+
+	container.add( editableRow );
+
 	// VR
 
 	var vrRow = new UI.Row();

+ 3 - 1
editor/js/Storage.js

@@ -7,8 +7,10 @@ var Storage = function () {
 	var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
 
 	if ( indexedDB === undefined  ) {
+
 		console.warn( 'Storage: IndexedDB not available.' );
 		return { init: function () {}, get: function () {}, set: function () {}, clear: function () {} };
+
 	}
 
 	var name = 'threejs-editor';
@@ -89,6 +91,6 @@ var Storage = function () {
 
 		}
 
-	}
+	};
 
 };

+ 10 - 10
editor/js/libs/app.js

@@ -177,15 +177,7 @@ var APP = {
 
 			for ( var i = 0, l = array.length; i < l; i ++ ) {
 
-				try {
-
-					array[ i ]( event );
-
-				} catch ( e ) {
-
-					console.error( ( e.message || e ), ( e.stack || "" ) );
-
-				}
+				array[ i ]( event );
 
 			}
 
@@ -197,7 +189,15 @@ var APP = {
 
 			request = requestAnimationFrame( animate );
 
-			dispatch( events.update, { time: time, delta: time - prevTime } );
+			try {
+
+				dispatch( events.update, { time: time, delta: time - prevTime } );
+
+			} catch ( e ) {
+
+				console.error( ( e.message || e ), ( e.stack || "" ) );
+
+			}
 
 			if ( vr === true ) {
 

+ 34 - 2
editor/js/libs/app/index.html

@@ -6,10 +6,25 @@
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<style>
 		body {
+			font-family: Helvetica, Arial, sans-serif;
+			font-size: 12px;
 			background-color: #000;
 			margin: 0px;
 			overflow: hidden;
 		}
+		#edit {
+			position: absolute;
+			bottom: 20px;
+			right: 20px;
+			padding: 8px;
+			color: #555;
+			background-color: #fff;
+			opacity: 0.5;
+		}
+		#edit:hover {
+			cursor: pointer;
+			opacity: 1;
+		}
 		</style>
 	</head>
 	<body ontouchstart="">
@@ -20,13 +35,30 @@
 			var loader = new THREE.XHRLoader();
 			loader.load( 'app.json', function ( text ) {
 
+				var json = JSON.parse( text );
+
 				var player = new APP.Player();
-				player.load( JSON.parse( text ) );
+				player.load( json );
 				player.setSize( window.innerWidth, window.innerHeight );
 				player.play();
 
 				document.body.appendChild( player.dom );
 
+				if ( json.project.editable === true ) {
+
+					var button = document.createElement( 'div' );
+					button.id = 'edit';
+					button.textContent = 'EDIT';
+					button.addEventListener( 'click', function ( event ) {
+
+						var url = location.href.split( '/' ).slice( 0, - 1 ).join( '/' );
+						window.open( 'http://threejs.org/editor/#file=https://crossorigin.me/' + url + '/app.json' );
+
+					}, false );
+					document.body.appendChild( button );
+
+				}
+
 				window.addEventListener( 'resize', function () {
 					player.setSize( window.innerWidth, window.innerHeight );
 				} );
@@ -35,4 +67,4 @@
 
 		</script>
 	</body>
-</html>'
+</html>

File diff suppressed because it is too large
+ 0 - 1
editor/js/libs/sortable.min.js


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

@@ -5292,10 +5292,6 @@
           "!type": "boolean",
           "!doc": "Whether to generate mipmaps (if possible) for a texture. True by default."
         },
-        "shareDepthFrom": {
-          "!type": "+THREE.WebGLRenderTarget",
-          "!doc": "Shares the depth from another WebGLRenderTarget. Default is null."
-        },
         "setSize": {
           "!type": "fn(width: number, height: number)",
           "!doc": "Sets the size of the renderTarget."

+ 142 - 51
editor/js/libs/ui.three.js

@@ -146,33 +146,8 @@ UI.Outliner = function ( editor ) {
 	dom.className = 'Outliner';
 	dom.tabIndex = 0;	// keyup event is ignored without setting tabIndex
 
-	var scene = editor.scene;
-
-	var sortable = Sortable.create( dom, {
-		draggable: '.draggable',
-		onUpdate: function ( event ) {
-
-			var item = event.item;
-
-			var object = scene.getObjectById( item.value );
-
-			if ( item.nextSibling === null ) {
-
-				editor.execute( new MoveObjectCommand( object, editor.scene ) );
-
-			} else {
-
-				var nextObject = scene.getObjectById( item.nextSibling.value );
-				editor.execute( new MoveObjectCommand( object, nextObject.parent, nextObject ) );
-
-			}
-
-		}
-	} );
-
-	// Broadcast for object selection after arrow navigation
-	var changeEvent = document.createEvent( 'HTMLEvents' );
-	changeEvent.initEvent( 'change', true, true );
+	// hack
+	this.scene = editor.scene;
 
 	// Prevent native scroll behavior
 	dom.addEventListener( 'keydown', function ( event ) {
@@ -190,26 +165,12 @@ UI.Outliner = function ( editor ) {
 	// Keybindings to support arrow navigation
 	dom.addEventListener( 'keyup', function ( event ) {
 
-		function select( index ) {
-
-			if ( index >= 0 && index < scope.options.length ) {
-
-				scope.selectedIndex = index;
-
-				// Highlight selected dom elem and scroll parent if needed
-				scope.setValue( scope.options[ index ].value );
-				scope.dom.dispatchEvent( changeEvent );
-
-			}
-
-		}
-
 		switch ( event.keyCode ) {
 			case 38: // up
-				select( scope.selectedIndex - 1 );
+				scope.selectIndex( scope.selectedIndex - 1 );
 				break;
 			case 40: // down
-				select( scope.selectedIndex + 1 );
+				scope.selectIndex( scope.selectedIndex + 1 );
 				break;
 		}
 
@@ -228,19 +189,140 @@ UI.Outliner = function ( editor ) {
 UI.Outliner.prototype = Object.create( UI.Element.prototype );
 UI.Outliner.prototype.constructor = UI.Outliner;
 
+UI.Outliner.prototype.selectIndex = function ( index ) {
+
+	if ( index >= 0 && index < this.options.length ) {
+
+		this.setValue( this.options[ index ].value );
+
+		var changeEvent = document.createEvent( 'HTMLEvents' );
+		changeEvent.initEvent( 'change', true, true );
+		this.dom.dispatchEvent( changeEvent );
+
+	}
+
+};
+
 UI.Outliner.prototype.setOptions = function ( options ) {
 
 	var scope = this;
 
-	var changeEvent = document.createEvent( 'HTMLEvents' );
-	changeEvent.initEvent( 'change', true, true );
-
 	while ( scope.dom.children.length > 0 ) {
 
 		scope.dom.removeChild( scope.dom.firstChild );
 
 	}
 
+	function onClick() {
+
+		scope.setValue( this.value );
+
+		var changeEvent = document.createEvent( 'HTMLEvents' );
+		changeEvent.initEvent( 'change', true, true );
+		scope.dom.dispatchEvent( changeEvent );
+
+	}
+
+	// Drag
+
+	var currentDrag;
+
+	function onDrag( event ) {
+
+		currentDrag = this;
+
+	}
+
+	function onDragStart( event ) {
+
+		event.dataTransfer.setData( 'text', 'foo' );
+
+	}
+
+	function onDragOver( event ) {
+
+		if ( this === currentDrag ) return;
+
+		var area = event.offsetY / this.clientHeight;
+
+		if ( area < 0.25 ) {
+
+			this.className = 'option dragTop';
+
+		} else if ( area > 0.75 ) {
+
+			this.className = 'option dragBottom';
+
+		} else {
+
+			this.className = 'option drag';
+
+		}
+
+	}
+
+	function onDragLeave() {
+
+		if ( this === currentDrag ) return;
+
+		this.className = 'option';
+
+	}
+
+	function onDrop( event ) {
+
+		if ( this === currentDrag ) return;
+
+		this.className = 'option';
+
+		var scene = scope.scene;
+		var object = scene.getObjectById( currentDrag.value );
+
+		var area = event.offsetY / this.clientHeight;
+
+		if ( area < 0.25 ) {
+
+			var nextObject = scene.getObjectById( this.value );
+			moveObject( object, nextObject.parent, nextObject );
+
+		} else if ( area > 0.75 ) {
+
+			var nextObject = scene.getObjectById( this.nextSibling.value );
+			moveObject( object, nextObject.parent, nextObject );
+
+		} else {
+
+			var parentObject = scene.getObjectById( this.value );
+			moveObject( object, parentObject );
+
+		}
+
+	}
+
+	function moveObject( object, newParent, nextObject ) {
+
+		if ( nextObject === null ) nextObject = undefined;
+
+		var newParentIsChild = false;
+
+		object.traverse( function ( child ) {
+
+			if ( child === newParent ) newParentIsChild = true;
+
+		} );
+
+		if ( newParentIsChild ) return;
+
+		editor.execute( new MoveObjectCommand( object, newParent, nextObject ) );
+
+		var changeEvent = document.createEvent( 'HTMLEvents' );
+		changeEvent.initEvent( 'change', true, true );
+		scope.dom.dispatchEvent( changeEvent );
+
+	}
+
+	//
+
 	scope.options = [];
 
 	for ( var i = 0; i < options.length; i ++ ) {
@@ -248,19 +330,28 @@ UI.Outliner.prototype.setOptions = function ( options ) {
 		var option = options[ i ];
 
 		var div = document.createElement( 'div' );
-		div.className = 'option ' + ( option.static === true ? '' : 'draggable' );
+		div.className = 'option';
 		div.innerHTML = option.html;
 		div.value = option.value;
 		scope.dom.appendChild( div );
 
 		scope.options.push( div );
 
-		div.addEventListener( 'click', function ( event ) {
+		div.addEventListener( 'click', onClick, false );
+
+		if ( option.static !== true ) {
+
+			div.draggable = true;
 
-			scope.setValue( this.value );
-			scope.dom.dispatchEvent( changeEvent );
+			div.addEventListener( 'drag', onDrag, false );
+			div.addEventListener( 'dragstart', onDragStart, false ); // Firefox needs this
+
+			div.addEventListener( 'dragover', onDragOver, false );
+			div.addEventListener( 'dragleave', onDragLeave, false );
+			div.addEventListener( 'drop', onDrop, false );
+
+		}
 
-		}, false );
 
 	}
 

+ 2 - 1
examples/canvas_ascii_effect.html

@@ -116,8 +116,9 @@
 
 				requestAnimationFrame( animate );
 
+				stats.begin();
 				render();
-				stats.update();
+				stats.end();
 
 			}
 

+ 2 - 1
examples/canvas_camera_orthographic.html

@@ -145,8 +145,9 @@
 
 				requestAnimationFrame( animate );
 
+				stats.begin();
 				render();
-				stats.update();
+				stats.end();
 
 			}
 

+ 2 - 1
examples/canvas_camera_orthographic2.html

@@ -208,8 +208,9 @@
 
 				requestAnimationFrame( animate );
 
+				stats.begin();
 				render();
-				stats.update();
+				stats.end();
 
 			}
 

+ 2 - 1
examples/canvas_geometry_birds.html

@@ -420,8 +420,9 @@
 
 				requestAnimationFrame( animate );
 
+				stats.begin();
 				render();
-				stats.update();
+				stats.end();
 
 			}
 

+ 2 - 1
examples/canvas_geometry_cube.html

@@ -193,8 +193,9 @@
 
 				requestAnimationFrame( animate );
 
+				stats.begin();
 				render();
-				stats.update();
+				stats.end();
 
 			}
 

+ 11 - 1
examples/files.js

@@ -57,6 +57,7 @@ var files = {
 		"webgl_kinect",
 		"webgl_lensflares",
 		"webgl_lights_hemisphere",
+		"webgl_lights_physical",
 		"webgl_lights_pointlights",
 		"webgl_lights_pointlights2",
 		"webgl_lines_colors",
@@ -88,6 +89,7 @@ var files = {
 		"webgl_loader_msgpack",
 		"webgl_loader_obj",
 		"webgl_loader_obj_mtl",
+		"webgl_loader_nrrd",
 		"webgl_loader_pcd",
 		"webgl_loader_pdb",
 		"webgl_loader_ply",
@@ -119,6 +121,7 @@ var files = {
 		"webgl_materials_cubemap_refraction",
 		"webgl_materials_displacementmap",
 		"webgl_materials_envmaps",
+		"webgl_materials_envmaps_hdr",
 		"webgl_materials_grass",
 		"webgl_materials_lightmap",
 		"webgl_materials_nodes",
@@ -134,11 +137,11 @@ var files = {
 		"webgl_materials_texture_manualmipmap",
 		"webgl_materials_texture_pvrtc",
 		"webgl_materials_texture_tga",
+		"webgl_materials_transparency",
 		"webgl_materials_variations_basic",
 		"webgl_materials_variations_lambert",
 		"webgl_materials_variations_phong",
 		"webgl_materials_variations_standard",
-		"webgl_materials_variations_standard2",
 		"webgl_materials_video",
 		"webgl_materials_wireframe",
 		"webgl_mirror",
@@ -159,6 +162,7 @@ var files = {
 		"webgl_objects_update",
 		"webgl_octree",
 		"webgl_octree_raycasting",
+		"webgl_panorama_dualfisheye",
 		"webgl_panorama_equirectangular",
 		"webgl_particles_general",
 		"webgl_performance",
@@ -177,8 +181,11 @@ var files = {
 		"webgl_postprocessing_glitch",
 		"webgl_postprocessing_godrays",
 		"webgl_postprocessing_masking",
+		"webgl_postprocessing_msaa",
 		"webgl_postprocessing_nodes",
+		"webgl_postprocessing_smaa",
 		"webgl_postprocessing_ssao",
+		"webgl_postprocessing_taa",
 		"webgl_raycast_texture",
 		"webgl_read_float_buffer",
 		"webgl_rtt",
@@ -202,6 +209,7 @@ var files = {
 		"webgl_terrain_dynamic",
 		"webgl_test_memory",
 		"webgl_test_memory2",
+		"webgl_tonemapping",
 		"webgl_trails",
 		"webgl_video_panorama_equirectangular"
 	],
@@ -229,6 +237,8 @@ var files = {
 	],
 	"webvr": [
 		"webvr_cubes",
+		"webvr_panorama",
+		"webvr_rollercoaster",
 		"webvr_video"
 	],
 	"css3d": [

+ 202 - 44
examples/index.html

@@ -59,24 +59,24 @@
 				background: #fafafa;
 			}
 
-				#panel #content {
-					padding: 0px 20px 20px 20px;
-				}
+			#panel #content {
+				padding: 0px 20px 20px 20px;
+			}
 
-				#panel #content .link {
-					color: #2194CE;
-					text-decoration: none;
-					cursor: pointer;
-					display: block;
-				}
+			#panel #content .link {
+				color: #2194CE;
+				text-decoration: none;
+				cursor: pointer;
+				display: block;
+			}
 
-				#panel #content .selected {
-					color: #ff0000;
-				}
+			#panel #content .selected {
+				color: #ff0000;
+			}
 
-					#panel #content .link:hover {
-						text-decoration: underline;
-					}
+			#panel #content .link:hover {
+				text-decoration: underline;
+			}
 
 			#viewer {
 				position: absolute;
@@ -97,10 +97,59 @@
 				opacity: 0.7;
 			}
 
-				#button:hover {
-					cursor: pointer;
-					opacity: 1;
-				}
+			#button:hover {
+				cursor: pointer;
+				opacity: 1;
+			}
+
+			.filterBlock{
+				margin: 20px;
+				position: relative;
+			}
+
+			.filterBlock p {
+				margin: 0;
+			}
+
+			#filterInput {
+				width: 100%;
+				padding: 5px;
+				font-family: inherit;
+				font-size: 15px;
+				outline: none;
+				border: 1px solid #dedede;
+			}
+
+			#filterInput:focus{
+				border: 1px solid #2194CE;
+			}
+
+			#clearFilterButton {
+				position: absolute;
+				right: 6px;
+				top: 50%;
+				margin-top: -8px;
+				width: 16px;
+				height: 16px;
+				font-size: 14px;
+				color: grey;
+				text-align: center;
+				line-height: 0;
+				padding-top: 7px;
+				opacity: .5;
+			}
+
+			#clearFilterButton:hover {
+				opacity: 1;
+			}
+
+			.filtered {
+				display: none !important;
+			}
+
+			#panel li b {
+				font-weight: bold;
+			}
 
 			/* mobile */
 
@@ -113,22 +162,22 @@
 				height: 32px;
 			}
 
-				#expandButton span {
-					height: 2px;
-					background-color: #2194CE;
-					width: 16px;
-					position: absolute;
-					left: 8px;
-					top: 10px;
-				}
+			#expandButton span {
+				height: 2px;
+				background-color: #2194CE;
+				width: 16px;
+				position: absolute;
+				left: 8px;
+				top: 10px;
+			}
 
-				#expandButton span:nth-child(1) {
-					top: 16px;
-				}
+			#expandButton span:nth-child(1) {
+				top: 16px;
+			}
 
-				#expandButton span:nth-child(2) {
-					top: 22px;
-				}
+			#expandButton span:nth-child(2) {
+				top: 22px;
+			}
 
 			@media all and ( max-width: 640px ) {
 				h1{
@@ -149,7 +198,7 @@
 				#content{
 					position: absolute;
 					left: 0;
-					top: 60px;
+					top: 90px;
 					right: 0;
 					bottom: 0;
 					font-size: 17px;
@@ -182,6 +231,10 @@
 				<span></span>
 				<span></span>
 			</a>
+			<div class="filterBlock" >
+				<input type="text" id="filterInput" placeholder="Type to filter"/>
+				<a href="#" id="clearFilterButton" >x</a>
+			</div>
 			<div id="content"></div>
 		</div>
 		<iframe id="viewer" allowfullscreen onmousewheel=""></iframe>
@@ -193,6 +246,9 @@
 		var content = document.getElementById( 'content' );
 		var viewer = document.getElementById( 'viewer' );
 
+		var filterInput = document.getElementById( 'filterInput' );
+		var clearFilterButton = document.getElementById( 'clearFilterButton' );
+
 		var expandButton = document.getElementById( 'expandButton' );
 		expandButton.addEventListener( 'click', function ( event ) {
 			panel.classList.toggle( 'collapsed' );
@@ -220,10 +276,7 @@
 		button.textContent = 'View source';
 		button.addEventListener( 'click', function ( event ) {
 
-			var array = location.href.split( '/' );
-			array.pop();
-
-			window.open( 'view-source:' + array.join( '/' ) + '/' + selected + '.html' );
+			window.open( 'https://github.com/mrdoob/three.js/blob/master/examples/' + selected + '.html' );
 
 		}, false );
 		button.style.display = 'none';
@@ -236,17 +289,16 @@
 
 			var section = files[ key ];
 
-			var div = document.createElement( 'h2' );
-			div.textContent = key;
-			container.appendChild( div );
+			var header = document.createElement( 'h2' );
+			header.textContent = key;
+			header.setAttribute( 'data-category', key );
+			container.appendChild( header );
 
 			for ( var i = 0; i < section.length; i ++ ) {
 
 				( function ( file ) {
 
-					var name = file.split( '_' );
-					name.shift();
-					name = name.join( ' / ' );
+					var name = getName( file );
 
 					var link = document.createElement( 'a' );
 					link.className = 'link';
@@ -296,6 +348,112 @@
 
 		}
 
+		// filter
+
+		filterInput.addEventListener( 'input', function( e ) {
+
+			updateFilter();
+
+		} );
+
+		clearFilterButton.addEventListener( 'click', function( e ) {
+
+			filterInput.value = '';
+			updateFilter();
+			e.preventDefault();
+
+		} );
+
+		function updateFilter() {
+
+			var exp = new RegExp( filterInput.value, 'gi' );
+
+			for ( var key in files ) {
+
+				var section = files[ key ];
+
+				for ( var i = 0; i < section.length; i ++ ) {
+
+					filterExample( section[ i ], exp );
+
+				}
+
+			}
+
+			layoutList();
+
+		}
+
+		function filterExample( file, exp ){
+
+			var link = links[ file ];
+			var name = getName( file );
+			var res = file.match( exp );
+			var text;
+
+			if ( res && res.length > 0 ) {
+
+				link.classList.remove( 'filtered' );
+
+				for( var i = 0; i < res.length; i++ ) {
+					text = name.replace( res[ i ], '<b>' + res[ i ] + '</b>' );
+				}
+
+				link.innerHTML = text;
+
+			} else {
+
+				link.classList.add( 'filtered' );
+				link.innerHTML = name;
+
+			}
+		}
+
+		function getName( file ) {
+
+			var name = file.split( '_' );
+			name.shift();
+			return name.join( ' / ' );
+
+		}
+
+		function layoutList() {
+
+			for ( var key in files ) {
+
+				var collapsed = true;
+
+				var section = files[ key ];
+
+				for ( var i = 0; i < section.length; i ++ ) {
+
+					var file = section[ i ];
+
+					if( !links[ file ].classList.contains( 'filtered' ) ){
+
+						collapsed = false;
+						break;
+
+					}
+
+				}
+
+				var element = document.querySelector( 'h2[data-category="' + key + '"]' );
+
+				if( collapsed ){
+
+					element.classList.add( 'filtered' );
+
+				} else {
+
+					element.classList.remove( 'filtered' );
+
+				}
+
+			}
+
+		}
+
 		</script>
 
 	</body>

+ 26 - 0
examples/js/Encodings.js

@@ -0,0 +1,26 @@
+/**
+ * @author Ben Houston / http://clara.io / bhouston
+ * @author Prashant Sharma / spidersharma03
+ */
+
+THREE.Encodings = function() {
+  if( THREE.toHalf === undefined ) throw new Error("THREE.Encodings is required for HDRCubeMapLoader when loading half data.");
+}
+
+THREE.Encodings.RGBEByteToRGBFloat = function( sourceArray, sourceOffset, destArray, destOffset ) {
+  var e = sourceArray[sourceOffset+3];
+  var scale = Math.pow(2.0, e - 128.0) / 255.0;
+
+  destArray[destOffset+0] = sourceArray[sourceOffset+0] * scale;
+  destArray[destOffset+1] = sourceArray[sourceOffset+1] * scale;
+  destArray[destOffset+2] = sourceArray[sourceOffset+2] * scale;
+}
+
+THREE.Encodings.RGBEByteToRGBHalf = function( sourceArray, sourceOffset, destArray, destOffset ) {
+  var e = sourceArray[sourceOffset+3];
+  var scale = Math.pow(2.0, e - 128.0) / 255.0;
+
+  destArray[destOffset+0] = THREE.toHalf( sourceArray[sourceOffset+0] * scale );
+  destArray[destOffset+1] = THREE.toHalf( sourceArray[sourceOffset+1] * scale );
+  destArray[destOffset+2] = THREE.toHalf( sourceArray[sourceOffset+2] * scale );
+}

+ 51 - 0
examples/js/Half.js

@@ -0,0 +1,51 @@
+/**
+ * Source: http://gamedev.stackexchange.com/questions/17326/conversion-of-a-number-from-single-precision-floating-point-representation-to-a/17410#17410
+ */
+
+THREE.toHalf = (function() {
+  var floatView = new Float32Array(1);
+  var int32View = new Int32Array(floatView.buffer);
+
+  /* This method is faster than the OpenEXR implementation (very often
+   * used, eg. in Ogre), with the additional benefit of rounding, inspired
+   * by James Tursa?s half-precision code. */
+  return function toHalf(val) {
+
+    floatView[0] = val;
+    var x = int32View[0];
+
+    var bits = (x >> 16) & 0x8000; /* Get the sign */
+    var m = (x >> 12) & 0x07ff; /* Keep one extra bit for rounding */
+    var e = (x >> 23) & 0xff; /* Using int is faster here */
+
+    /* If zero, or denormal, or exponent underflows too much for a denormal
+     * half, return signed zero. */
+    if (e < 103) {
+      return bits;
+    }
+
+    /* If NaN, return NaN. If Inf or exponent overflow, return Inf. */
+    if (e > 142) {
+      bits |= 0x7c00;
+      /* If exponent was 0xff and one mantissa bit was set, it means NaN,
+           * not Inf, so make sure we set one mantissa bit too. */
+      bits |= ((e == 255) ? 0 : 1) && (x & 0x007fffff);
+      return bits;
+    }
+
+    /* If exponent underflows but not too much, return a denormal */
+    if (e < 113) {
+      m |= 0x0800;
+      /* Extra rounding may overflow and set mantissa to 0 and exponent
+       * to 1, which is OK. */
+      bits |= (m >> (114 - e)) + ((m >> (113 - e)) & 1);
+      return bits;
+    }
+
+    bits |= ((e - 112) << 10) | (m >> 1);
+    /* Extra rounding. An overflow will set mantissa to 0 and increment
+     * the exponent, which is OK. */
+    bits += m & 1;
+    return bits;
+  };
+}());

+ 0 - 4
examples/js/Ocean.js

@@ -12,10 +12,6 @@
 
 	this.scene = new THREE.Scene();
 
-	// Enable necessary extensions
-	this.renderer.context.getExtension( 'OES_texture_float' );
-	this.renderer.context.getExtension( 'OES_texture_float_linear' );
-
 	// Assign optional parameters as variables and object properties
 	function optionalParameter( value, defaultValue ) {
 

+ 6 - 8
examples/js/ParametricGeometries.js

@@ -170,18 +170,16 @@ THREE.ParametricGeometries.TubeGeometry.prototype.constructor = THREE.Parametric
   * Parametric Replacement for TorusKnotGeometry
   *
   *********************************************/
-THREE.ParametricGeometries.TorusKnotGeometry = function ( radius, tube, segmentsR, segmentsT, p, q, heightScale ) {
+THREE.ParametricGeometries.TorusKnotGeometry = function ( radius, tube, segmentsT, segmentsR, p, q ) {
 
 	var scope = this;
 
 	this.radius = radius || 200;
 	this.tube = tube || 40;
-	this.segmentsR = segmentsR || 64;
-	this.segmentsT = segmentsT || 8;
+	this.segmentsT = segmentsT || 64;
+	this.segmentsR = segmentsR || 8;
 	this.p = p || 2;
 	this.q = q || 3;
-	this.heightScale = heightScale || 1;
-
 
 	var TorusKnotCurve = THREE.Curve.create(
 
@@ -198,13 +196,13 @@ THREE.ParametricGeometries.TorusKnotGeometry = function ( radius, tube, segments
 				ty = ( 1 + r * Math.cos( q * t ) ) * Math.sin( p * t ),
 				tz = r * Math.sin( q * t );
 
-			return new THREE.Vector3( tx, ty * heightScale, tz ).multiplyScalar( radius );
+			return new THREE.Vector3( tx, ty, tz ).multiplyScalar( radius );
 
 		}
 
 	);
-	var segments = segmentsR;
-	var radiusSegments = segmentsT;
+	var segments = segmentsT;
+	var radiusSegments = segmentsR;
 	var extrudePath = new TorusKnotCurve();
 
 	THREE.ParametricGeometries.TubeGeometry.call( this, extrudePath, segments, tube, radiusSegments, true, false );

+ 544 - 0
examples/js/RollerCoaster.js

@@ -0,0 +1,544 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+var RollerCoasterGeometry = function ( curve, size ) {
+
+	THREE.BufferGeometry.call( this );
+
+	var vertices = [];
+	var normals = [];
+	var colors = [];
+
+	var color1 = [ 1, 1, 1 ];
+	var color2 = [ 1, 1, 0 ];
+
+	var up = new THREE.Vector3( 0, 1, 0 );
+	var forward = new THREE.Vector3();
+	var right = new THREE.Vector3();
+
+	var quaternion = new THREE.Quaternion();
+	var prevQuaternion = new THREE.Quaternion();
+	prevQuaternion.setFromAxisAngle( up , Math.PI / 2 );
+
+	var point = new THREE.Vector3();
+	var prevPoint = new THREE.Vector3();
+	prevPoint.copy( curve.getPointAt( 0 ) );
+
+	// shapes
+
+	var step = [
+		new THREE.Vector3( -2.25,  0, 0 ),
+		new THREE.Vector3(  0,  -0.5, 0 ),
+		new THREE.Vector3(  0, -1.75, 0 ),
+
+		new THREE.Vector3(  0,  -0.5, 0 ),
+		new THREE.Vector3(  2.25,  0, 0 ),
+		new THREE.Vector3(  0, -1.75, 0 )
+	];
+
+	var PI2 = Math.PI * 2;
+
+	var sides = 5;
+	var tube1 = [];
+
+	for ( var i = 0; i < sides; i ++ ) {
+
+		var angle = ( i / sides ) * PI2;
+		tube1.push( new THREE.Vector3( Math.sin( angle ) * 0.6, Math.cos( angle ) * 0.6, 0 ) );
+
+	}
+
+	var sides = 6;
+	var tube2 = [];
+
+	for ( var i = 0; i < sides; i ++ ) {
+
+		var angle = ( i / sides ) * PI2;
+		tube2.push( new THREE.Vector3( Math.sin( angle ) * 0.25, Math.cos( angle ) * 0.25, 0 ) );
+
+	}
+
+	var vector = new THREE.Vector3();
+	var normal = new THREE.Vector3();
+
+	var drawShape = function ( shape, color ) {
+
+		normal.set( 0, 0, -1 ).applyQuaternion( quaternion );
+
+		for ( var j = 0; j < shape.length; j ++ ) {
+
+			vector.copy( shape[ j ] );
+			vector.applyQuaternion( quaternion );
+			vector.add( point );
+
+			vertices.push( vector.x, vector.y, vector.z );
+			normals.push( normal.x, normal.y, normal.z );
+			colors.push( color[ 0 ], color[ 1 ], color[ 2 ] );
+
+		}
+
+		normal.set( 0, 0, 1 ).applyQuaternion( quaternion );
+
+		for ( var j = shape.length - 1; j >= 0; j -- ) {
+
+			vector.copy( shape[ j ] );
+			vector.applyQuaternion( quaternion );
+			vector.add( point );
+
+			vertices.push( vector.x, vector.y, vector.z );
+			normals.push( normal.x, normal.y, normal.z );
+			colors.push( color[ 0 ], color[ 1 ], color[ 2 ] );
+
+		}
+
+	};
+
+	var vector1 = new THREE.Vector3();
+	var vector2 = new THREE.Vector3();
+	var vector3 = new THREE.Vector3();
+	var vector4 = new THREE.Vector3();
+
+	var normal1 = new THREE.Vector3();
+	var normal2 = new THREE.Vector3();
+	var normal3 = new THREE.Vector3();
+	var normal4 = new THREE.Vector3();
+
+	var extrudeShape = function ( shape, offset, color ) {
+
+		for ( var j = 0, jl = shape.length; j < jl; j ++ ) {
+
+			var point1 = shape[ j ];
+			var point2 = shape[ ( j + 1 ) % jl ];
+
+			vector1.copy( point1 ).add( offset );
+			vector1.applyQuaternion( quaternion );
+			vector1.add( point );
+
+			vector2.copy( point2 ).add( offset );
+			vector2.applyQuaternion( quaternion );
+			vector2.add( point );
+
+			vector3.copy( point2 ).add( offset );
+			vector3.applyQuaternion( prevQuaternion );
+			vector3.add( prevPoint );
+
+			vector4.copy( point1 ).add( offset );
+			vector4.applyQuaternion( prevQuaternion );
+			vector4.add( prevPoint );
+
+			vertices.push( vector1.x, vector1.y, vector1.z );
+			vertices.push( vector2.x, vector2.y, vector2.z );
+			vertices.push( vector4.x, vector4.y, vector4.z );
+
+			vertices.push( vector2.x, vector2.y, vector2.z );
+			vertices.push( vector3.x, vector3.y, vector3.z );
+			vertices.push( vector4.x, vector4.y, vector4.z );
+
+			//
+
+			normal1.copy( point1 );
+			normal1.applyQuaternion( quaternion );
+			normal1.normalize();
+
+			normal2.copy( point2 );
+			normal2.applyQuaternion( quaternion );
+			normal2.normalize();
+
+			normal3.copy( point2 );
+			normal3.applyQuaternion( prevQuaternion );
+			normal3.normalize();
+
+			normal4.copy( point1 );
+			normal4.applyQuaternion( prevQuaternion );
+			normal4.normalize();
+
+			normals.push( normal1.x, normal1.y, normal1.z );
+			normals.push( normal2.x, normal2.y, normal2.z );
+			normals.push( normal4.x, normal4.y, normal4.z );
+
+			normals.push( normal2.x, normal2.y, normal2.z );
+			normals.push( normal3.x, normal3.y, normal3.z );
+			normals.push( normal4.x, normal4.y, normal4.z );
+
+			colors.push( color[ 0 ], color[ 1 ], color[ 2 ] );
+			colors.push( color[ 0 ], color[ 1 ], color[ 2 ] );
+			colors.push( color[ 0 ], color[ 1 ], color[ 2 ] );
+
+			colors.push( color[ 0 ], color[ 1 ], color[ 2 ] );
+			colors.push( color[ 0 ], color[ 1 ], color[ 2 ] );
+			colors.push( color[ 0 ], color[ 1 ], color[ 2 ] );
+
+		}
+
+	};
+
+	var offset = new THREE.Vector3();
+
+	for ( var i = 1; i <= size; i ++ ) {
+
+		point.copy( curve.getPointAt( i / size ) );
+
+		up.set( 0, 1, 0 );
+
+		forward.subVectors( point, prevPoint ).normalize();
+		right.crossVectors( up, forward ).normalize();
+		up.crossVectors( forward, right );
+
+		var angle = Math.atan2( forward.x, forward.z );
+
+		quaternion.setFromAxisAngle( up, angle );
+
+		if ( i % 2 === 0 ) {
+
+			drawShape( step, color2 );
+
+		}
+
+		extrudeShape( tube1, offset.set( 0, -1.25, 0 ), color2 );
+		extrudeShape( tube2, offset.set( 2, 0, 0 ), color1 );
+		extrudeShape( tube2, offset.set( -2, 0, 0 ), color1 );
+
+		prevPoint.copy( point );
+		prevQuaternion.copy( quaternion );
+
+	}
+
+	// console.log( vertices.length );
+
+	this.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) );
+	this.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( normals ), 3 ) );
+	this.addAttribute( 'color', new THREE.BufferAttribute( new Float32Array( colors ), 3 ) );
+
+};
+
+RollerCoasterGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
+
+var RollerCoasterLiftersGeometry = function ( curve, size ) {
+
+	THREE.BufferGeometry.call( this );
+
+	var vertices = [];
+	var normals = [];
+
+	var quaternion = new THREE.Quaternion();
+
+	var up = new THREE.Vector3( 0, 1, 0 );
+
+	var point = new THREE.Vector3();
+	var tangent = new THREE.Vector3();
+
+	// shapes
+
+	var tube1 = [
+		new THREE.Vector3(  0,  0.5, -0.5 ),
+		new THREE.Vector3(  0,  0.5,  0.5 ),
+		new THREE.Vector3(  0, -0.5,  0 )
+	];
+
+	var tube2 = [
+		new THREE.Vector3( -0.5, 0,  0.5 ),
+		new THREE.Vector3( -0.5, 0, -0.5 ),
+		new THREE.Vector3(  0.5, 0,  0 )
+	];
+
+	var tube3 = [
+		new THREE.Vector3(  0.5, 0, -0.5 ),
+		new THREE.Vector3(  0.5, 0,  0.5 ),
+		new THREE.Vector3( -0.5, 0,  0 )
+	];
+
+	var vector1 = new THREE.Vector3();
+	var vector2 = new THREE.Vector3();
+	var vector3 = new THREE.Vector3();
+	var vector4 = new THREE.Vector3();
+
+	var normal1 = new THREE.Vector3();
+	var normal2 = new THREE.Vector3();
+	var normal3 = new THREE.Vector3();
+	var normal4 = new THREE.Vector3();
+
+	var extrudeShape = function ( shape, fromPoint, toPoint ) {
+
+		for ( var j = 0, jl = shape.length; j < jl; j ++ ) {
+
+			var point1 = shape[ j ];
+			var point2 = shape[ ( j + 1 ) % jl ];
+
+			vector1.copy( point1 )
+			vector1.applyQuaternion( quaternion );
+			vector1.add( fromPoint );
+
+			vector2.copy( point2 )
+			vector2.applyQuaternion( quaternion );
+			vector2.add( fromPoint );
+
+			vector3.copy( point2 )
+			vector3.applyQuaternion( quaternion );
+			vector3.add( toPoint );
+
+			vector4.copy( point1 )
+			vector4.applyQuaternion( quaternion );
+			vector4.add( toPoint );
+
+			vertices.push( vector1.x, vector1.y, vector1.z );
+			vertices.push( vector2.x, vector2.y, vector2.z );
+			vertices.push( vector4.x, vector4.y, vector4.z );
+
+			vertices.push( vector2.x, vector2.y, vector2.z );
+			vertices.push( vector3.x, vector3.y, vector3.z );
+			vertices.push( vector4.x, vector4.y, vector4.z );
+
+			//
+
+			normal1.copy( point1 );
+			normal1.applyQuaternion( quaternion );
+			normal1.normalize();
+
+			normal2.copy( point2 );
+			normal2.applyQuaternion( quaternion );
+			normal2.normalize();
+
+			normal3.copy( point2 );
+			normal3.applyQuaternion( quaternion );
+			normal3.normalize();
+
+			normal4.copy( point1 );
+			normal4.applyQuaternion( quaternion );
+			normal4.normalize();
+
+			normals.push( normal1.x, normal1.y, normal1.z );
+			normals.push( normal2.x, normal2.y, normal2.z );
+			normals.push( normal4.x, normal4.y, normal4.z );
+
+			normals.push( normal2.x, normal2.y, normal2.z );
+			normals.push( normal3.x, normal3.y, normal3.z );
+			normals.push( normal4.x, normal4.y, normal4.z );
+
+		}
+
+	};
+
+	var fromPoint = new THREE.Vector3();
+	var toPoint = new THREE.Vector3();
+
+	for ( var i = 1; i <= size; i ++ ) {
+
+		point.copy( curve.getPointAt( i / size ) );
+		tangent.copy( curve.getTangentAt( i / size ) );
+
+		var angle = Math.atan2( tangent.x, tangent.z );
+
+		quaternion.setFromAxisAngle( up, angle );
+
+		//
+
+		if ( point.y > 100 ) {
+
+			fromPoint.set( -7.5, -3.5, 0 );
+			fromPoint.applyQuaternion( quaternion );
+			fromPoint.add( point );
+
+			toPoint.set( 7.5, -3.5, 0 );
+			toPoint.applyQuaternion( quaternion );
+			toPoint.add( point );
+
+			extrudeShape( tube1, fromPoint, toPoint );
+
+			fromPoint.set( -7, -3, 0 );
+			fromPoint.applyQuaternion( quaternion );
+			fromPoint.add( point );
+
+			toPoint.set( -7, -point.y, 0 );
+			toPoint.applyQuaternion( quaternion );
+			toPoint.add( point );
+
+			extrudeShape( tube2, fromPoint, toPoint );
+
+			fromPoint.set( 7, -3, 0 );
+			fromPoint.applyQuaternion( quaternion );
+			fromPoint.add( point );
+
+			toPoint.set( 7, -point.y, 0 );
+			toPoint.applyQuaternion( quaternion );
+			toPoint.add( point );
+
+			extrudeShape( tube3, fromPoint, toPoint );
+
+		} else {
+
+			fromPoint.set( 0, -2, 0 );
+			fromPoint.applyQuaternion( quaternion );
+			fromPoint.add( point );
+
+			toPoint.set( 0, -point.y, 0 );
+			toPoint.applyQuaternion( quaternion );
+			toPoint.add( point );
+
+			extrudeShape( tube3, fromPoint, toPoint );
+
+		}
+
+	}
+
+	this.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) );
+	this.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( normals ), 3 ) );
+
+};
+
+RollerCoasterLiftersGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
+
+var RollerCoasterShadowGeometry = function ( curve, size ) {
+
+	THREE.BufferGeometry.call( this );
+
+	var vertices = [];
+
+	var up = new THREE.Vector3( 0, 1, 0 );
+	var forward = new THREE.Vector3();
+
+	var quaternion = new THREE.Quaternion();
+	var prevQuaternion = new THREE.Quaternion();
+	prevQuaternion.setFromAxisAngle( up , Math.PI / 2 );
+
+	var point = new THREE.Vector3();
+
+	var prevPoint = new THREE.Vector3();
+	prevPoint.copy( curve.getPointAt( 0 ) );
+	prevPoint.y = 0;
+
+	var vector1 = new THREE.Vector3();
+	var vector2 = new THREE.Vector3();
+	var vector3 = new THREE.Vector3();
+	var vector4 = new THREE.Vector3();
+
+	for ( var i = 1; i <= size; i ++ ) {
+
+		point.copy( curve.getPointAt( i / size ) );
+		point.y = 0;
+
+		forward.subVectors( point, prevPoint );
+
+		var angle = Math.atan2( forward.x, forward.z );
+
+		quaternion.setFromAxisAngle( up, angle );
+
+		vector1.set( -3, 0, 0 );
+		vector1.applyQuaternion( quaternion );
+		vector1.add( point );
+
+		vector2.set(  3, 0, 0 );
+		vector2.applyQuaternion( quaternion );
+		vector2.add( point );
+
+		vector3.set(  3, 0, 0 );
+		vector3.applyQuaternion( prevQuaternion );
+		vector3.add( prevPoint );
+
+		vector4.set( -3, 0, 0 );
+		vector4.applyQuaternion( prevQuaternion );
+		vector4.add( prevPoint );
+
+		vertices.push( vector1.x, vector1.y, vector1.z );
+		vertices.push( vector2.x, vector2.y, vector2.z );
+		vertices.push( vector4.x, vector4.y, vector4.z );
+
+		vertices.push( vector2.x, vector2.y, vector2.z );
+		vertices.push( vector3.x, vector3.y, vector3.z );
+		vertices.push( vector4.x, vector4.y, vector4.z );
+
+		prevPoint.copy( point );
+		prevQuaternion.copy( quaternion );
+
+	}
+
+	this.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) );
+
+};
+
+RollerCoasterShadowGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
+
+var SkyGeometry = function () {
+
+	THREE.BufferGeometry.call( this );
+
+	var vertices = [];
+
+	for ( var i = 0; i < 100; i ++ ) {
+
+		var x = Math.random() * 8000 - 4000;
+		var y = Math.random() * 500 + 500;
+		var z = Math.random() * 8000 - 4000;
+
+		var size = Math.random() * 400 + 200;
+
+		vertices.push( x - size, y, z - size );
+		vertices.push( x + size, y, z - size );
+		vertices.push( x - size, y, z + size );
+
+		vertices.push( x + size, y, z - size );
+		vertices.push( x + size, y, z + size );
+		vertices.push( x - size, y, z + size );
+
+	}
+
+
+	this.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) );
+
+};
+
+SkyGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
+
+var TreesGeometry = function ( landscape ) {
+
+	THREE.BufferGeometry.call( this );
+
+	var vertices = [];
+	var colors = [];
+
+	var raycaster = new THREE.Raycaster();
+	raycaster.ray.direction.set( 0, -1, 0 );
+
+	for ( var i = 0; i < 2000; i ++ ) {
+
+		var x = Math.random() * 5000 - 2500;
+		var z = Math.random() * 5000 - 2500;
+
+		raycaster.ray.origin.set( x, 500, z );
+
+		var intersections = raycaster.intersectObject( landscape );
+
+		if ( intersections.length === 0 ) continue;
+
+		var y = intersections[ 0 ].point.y;
+
+		var height = Math.random() * 50 + 5;
+
+		var angle = Math.random() * Math.PI * 2;
+
+		vertices.push( x + Math.sin( angle ) * 10, y, z + Math.cos( angle ) * 10 );
+		vertices.push( x, y + height, z );
+		vertices.push( x + Math.sin( angle + Math.PI ) * 10, y, z + Math.cos( angle + Math.PI ) * 10 );
+
+		angle += Math.PI / 2;
+
+		vertices.push( x + Math.sin( angle ) * 10, y, z + Math.cos( angle ) * 10 );
+		vertices.push( x, y + height, z );
+		vertices.push( x + Math.sin( angle + Math.PI ) * 10, y, z + Math.cos( angle + Math.PI ) * 10 );
+
+		var random = Math.random() * 0.1;
+
+		for ( var j = 0; j < 6; j ++ ) {
+
+			colors.push( 0.2 + random, 0.4 + random, 0 );
+
+		}
+
+	}
+
+	this.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) );
+	this.addAttribute( 'color', new THREE.BufferAttribute( new Float32Array( colors ), 3 ) );
+
+};
+
+TreesGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );

+ 4 - 10
examples/js/ShaderSkin.js

@@ -25,7 +25,6 @@ THREE.ShaderSkin = {
 		uniforms: THREE.UniformsUtils.merge( [
 
 			THREE.UniformsLib[ "fog" ],
-			THREE.UniformsLib[ "ambient" ],
 			THREE.UniformsLib[ "lights" ],
 
 			{
@@ -84,7 +83,6 @@ THREE.ShaderSkin = {
 
 			THREE.ShaderChunk[ "common" ],
 			THREE.ShaderChunk[ "bsdfs" ],
-			THREE.ShaderChunk[ "ambient_pars" ],
 			THREE.ShaderChunk[ "lights_pars" ],
 			THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
 			THREE.ShaderChunk[ "fog_pars_fragment" ],
@@ -247,11 +245,9 @@ THREE.ShaderSkin = {
 
 				"outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * diffuse ) + totalSpecularLight;",
 
-				THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
-				THREE.ShaderChunk[ "fog_fragment" ],
-
-				"gl_FragColor = vec4( outgoingLight, diffuseColor.a );",	// TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects
+				"gl_FragColor = linearToOutputTexel( vec4( outgoingLight, diffuseColor.a ) );",	// TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects
 
+				THREE.ShaderChunk[ "fog_fragment" ],
 
 			"}"
 
@@ -311,7 +307,6 @@ THREE.ShaderSkin = {
 		uniforms: THREE.UniformsUtils.merge( [
 
 			THREE.UniformsLib[ "fog" ],
-			THREE.UniformsLib[ "ambient" ],
 			THREE.UniformsLib[ "lights" ],
 
 			{
@@ -370,7 +365,6 @@ THREE.ShaderSkin = {
 			"varying vec3 vViewPosition;",
 
 			THREE.ShaderChunk[ "common" ],
-			THREE.ShaderChunk[ "ambient_pars" ],
 			THREE.ShaderChunk[ "lights_pars" ],
 			THREE.ShaderChunk[ "fog_pars_fragment" ],
 
@@ -550,10 +544,10 @@ THREE.ShaderSkin = {
 
 				"}",
 
-				THREE.ShaderChunk[ "fog_fragment" ],
-
 				"gl_FragColor = vec4( outgoingLight, diffuseColor.a );",	// TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects
 
+				THREE.ShaderChunk[ "fog_fragment" ],
+
 			"}"
 
 		].join( "\n" ),

+ 0 - 2
examples/js/ShaderTerrain.js

@@ -18,7 +18,6 @@ THREE.ShaderTerrain = {
 		uniforms: THREE.UniformsUtils.merge( [
 
 			THREE.UniformsLib[ "fog" ],
-			THREE.UniformsLib[ "ambient" ],
 			THREE.UniformsLib[ "lights" ],
 
 			{
@@ -88,7 +87,6 @@ THREE.ShaderTerrain = {
 
 			THREE.ShaderChunk[ "common" ],
 			THREE.ShaderChunk[ "bsdfs" ],
-			THREE.ShaderChunk[ "ambient_pars" ],
 			THREE.ShaderChunk[ "lights_pars" ],
 			THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
 			THREE.ShaderChunk[ "fog_pars_fragment" ],

+ 448 - 0
examples/js/Volume.js

@@ -0,0 +1,448 @@
+/**
+ * This class had been written to handle the output of the NRRD loader.
+ * It contains a volume of data and informations about it.
+ * For now it only handles 3 dimensional data.
+ * See the webgl_loader_nrrd.html example and the loaderNRRD.js file to see how to use this class.
+ * @class
+ * @author Valentin Demeusy / https://github.com/stity
+ * @param   {number}        xLength         Width of the volume
+ * @param   {number}        yLength         Length of the volume
+ * @param   {number}        zLength         Depth of the volume
+ * @param   {string}        type            The type of data (uint8, uint16, ...)
+ * @param   {ArrayBuffer}   arrayBuffer     The buffer with volume data
+ */
+THREE.Volume = function( xLength, yLength, zLength, type, arrayBuffer ) {
+
+	if ( arguments.length > 0 ) {
+
+		/**
+		 * @member {number} xLength Width of the volume in the IJK coordinate system
+		 */
+		this.xLength = Number( xLength ) || 1;
+		/**
+		 * @member {number} yLength Height of the volume in the IJK coordinate system
+		 */
+		this.yLength = Number( yLength ) || 1;
+		/**
+		 * @member {number} zLength Depth of the volume in the IJK coordinate system
+		 */
+		this.zLength = Number( zLength ) || 1;
+
+		/**
+		 * @member {TypedArray} data Data of the volume
+		 */
+
+		switch ( type ) {
+
+			case 'Uint8' :
+			case 'uint8' :
+			case 'uchar' :
+			case 'unsigned char' :
+			case 'uint8_t' :
+				this.data = new Uint8Array( arrayBuffer );
+				break;
+			case 'Int8' :
+			case 'int8' :
+			case 'signed char' :
+			case 'int8_t' :
+				this.data = new Int8Array( arrayBuffer );
+				break;
+			case 'Int16' :
+			case 'int16' :
+			case 'short' :
+			case 'short int' :
+			case 'signed short' :
+			case 'signed short int' :
+			case 'int16_t' :
+				this.data = new Int16Array( arrayBuffer );
+				break;
+			case 'Uint16' :
+			case 'uint16' :
+			case 'ushort' :
+			case 'unsigned short' :
+			case 'unsigned short int' :
+			case 'uint16_t' :
+				this.data = new Uint16Array( arrayBuffer );
+				break;
+			case 'Int32' :
+			case 'int32' :
+			case 'int' :
+			case 'signed int' :
+			case 'int32_t' :
+				this.data = new Int32Array( arrayBuffer );
+				break;
+			case 'Uint32' :
+			case 'uint32' :
+			case 'uint' :
+			case 'unsigned int' :
+			case 'uint32' :
+			case 'uint32_t' :
+				this.data = new Uint32Array( arrayBuffer );
+				break;
+			case 'longlong' :
+			case 'long long' :
+			case 'long long int' :
+			case 'signed long long' :
+			case 'signed long long int' :
+			case 'int64' :
+			case 'int64_t' :
+			case 'ulonglong' :
+			case 'unsigned long long' :
+			case 'unsigned long long int' :
+			case 'uint64' :
+			case 'uint64_t' :
+				throw 'Error in THREE.Volume constructor : this type is not supported in JavaScript';
+				break;
+			case 'Float32' :
+			case 'float32' :
+			case 'float' :
+				this.data = new Float32Array( arrayBuffer );
+				break;
+			case 'Float64' :
+			case 'float64' :
+			case 'double' :
+				this.data = new Float64Array( arrayBuffer );
+				break;
+			default :
+				this.data = new Uint8Array( arrayBuffer );
+
+		}
+
+		if ( this.data.length !== this.xLength * this.yLength * this.zLength ) {
+
+			throw 'Error in THREE.Volume constructor, lengths are not matching arrayBuffer size';
+
+		}
+
+	}
+
+	/**
+	 * @member {Array}  spacing Spacing to apply to the volume from IJK to RAS coordinate system
+	 */
+	this.spacing = [ 1, 1, 1 ];
+	/**
+	 * @member {Array}  offset Offset of the volume in the RAS coordinate system
+	 */
+	this.offset = [ 0, 0, 0 ];
+	/**
+	 * @member {THREE.Martrix3} matrix The IJK to RAS matrix
+	 */
+	this.matrix = new THREE.Matrix3();
+	this.matrix.identity();
+	/**
+	 * @member {THREE.Martrix3} inverseMatrix The RAS to IJK matrix
+	 */
+	/**
+	 * @member {number} lowerThreshold The voxels with values under this threshold won't appear in the slices.
+	 *                      If changed, geometryNeedsUpdate is automatically set to true on all the slices associated to this volume
+	 */
+	var lowerThreshold = - Infinity;
+	Object.defineProperty( this, 'lowerThreshold', {
+		get : function() {
+
+			return lowerThreshold;
+
+		},
+		set : function( value ) {
+
+			lowerThreshold = value;
+			this.sliceList.forEach( function( slice ) {
+
+				slice.geometryNeedsUpdate = true
+
+			} );
+
+		}
+	} );
+	/**
+	 * @member {number} upperThreshold The voxels with values over this threshold won't appear in the slices.
+	 *                      If changed, geometryNeedsUpdate is automatically set to true on all the slices associated to this volume
+	 */
+	var upperThreshold = Infinity;
+	Object.defineProperty( this, 'upperThreshold', {
+		get : function() {
+
+			return upperThreshold;
+
+		},
+		set : function( value ) {
+
+			upperThreshold = value;
+			this.sliceList.forEach( function( slice ) {
+
+				slice.geometryNeedsUpdate = true;
+
+			} );
+
+		}
+	} );
+
+
+	/**
+	 * @member {Array} sliceList The list of all the slices associated to this volume
+	 */
+	this.sliceList = [];
+
+
+	/**
+	 * @member {Array} RASDimensions This array holds the dimensions of the volume in the RAS space
+	 */
+
+}
+
+THREE.Volume.prototype = {
+
+	constructor : THREE.Volume,
+
+	/**
+	 * @member {Function} getData Shortcut for data[access(i,j,k)]
+	 * @memberof THREE.Volume
+	 * @param {number} i    First coordinate
+	 * @param {number} j    Second coordinate
+	 * @param {number} k    Third coordinate
+	 * @returns {number}  value in the data array
+	 */
+	getData : function( i, j, k ) {
+
+		return this.data[ k * this.xLength * this.yLength + j * this.xLength + i ];
+
+	},
+
+	/**
+	 * @member {Function} access compute the index in the data array corresponding to the given coordinates in IJK system
+	 * @memberof THREE.Volume
+	 * @param {number} i    First coordinate
+	 * @param {number} j    Second coordinate
+	 * @param {number} k    Third coordinate
+	 * @returns {number}  index
+	 */
+	access : function( i, j, k ) {
+
+		return k * this.xLength * this.yLength + j * this.xLength + i;
+
+	},
+
+	/**
+	 * @member {Function} reverseAccess Retrieve the IJK coordinates of the voxel corresponding of the given index in the data
+	 * @memberof THREE.Volume
+	 * @param {number} index index of the voxel
+	 * @returns {Array}  [x,y,z]
+	 */
+	reverseAccess : function( index ) {
+
+		var z = Math.floor( index / ( this.yLength * this.xLength ) );
+		var y = Math.floor( ( index - z * this.yLength * this.xLength ) / this.xLength );
+		var x = index - z * this.yLength * this.xLength - y * this.xLength;
+		return [ x, y, z ];
+
+	},
+
+	/**
+	 * @member {Function} map Apply a function to all the voxels, be careful, the value will be replaced
+	 * @memberof THREE.Volume
+	 * @param {Function} functionToMap A function to apply to every voxel, will be called with the following parameters :
+	 *                                 value of the voxel
+	 *                                 index of the voxel
+	 *                                 the data (TypedArray)
+	 * @param {Object}   context    You can specify a context in which call the function, default if this Volume
+	 * @returns {THREE.Volume}   this
+	 */
+	map : function( functionToMap, context ) {
+
+		var length = this.data.length;
+		context = context || this;
+
+		for ( var i = 0; i < length; i ++ ) {
+
+			this.data[ i ] = functionToMap.call( context, this.data[ i ], i, this.data );
+
+		}
+
+		return this;
+
+	},
+
+	/**
+	 * @member {Function} extractPerpendicularPlane Compute the orientation of the slice and returns all the information relative to the geometry such as sliceAccess, the plane matrix (orientation and position in RAS coordinate) and the dimensions of the plane in both coordinate system.
+	 * @memberof THREE.Volume
+	 * @param {string}            axis  the normal axis to the slice 'x' 'y' or 'z'
+	 * @param {number}            index the index of the slice
+	 * @returns {Object} an object containing all the usefull information on the geometry of the slice
+	 */
+	extractPerpendicularPlane : function( axis, RASIndex ) {
+
+		var iLength,
+		jLength,
+		sliceAccess,
+		planeMatrix = ( new THREE.Matrix4() ).identity(),
+		volume = this,
+		planeWidth,
+		planeHeight,
+		firstSpacing,
+		secondSpacing,
+		positionOffset,
+		IJKIndex;
+
+		var axisInIJK = new THREE.Vector3(),
+		firstDirection = new THREE.Vector3(),
+		secondDirection = new THREE.Vector3();
+
+		var dimensions = new THREE.Vector3( this.xLength, this.yLength, this.zLength );
+
+
+		switch ( axis ) {
+
+			case 'x' :
+				axisInIJK.set( 1, 0, 0 );
+				firstDirection.set( 0, 0, - 1 );
+				secondDirection.set( 0, - 1, 0 );
+				firstSpacing = this.spacing[ 2 ];
+				secondSpacing = this.spacing[ 1 ];
+				IJKIndex = new THREE.Vector3( RASIndex, 0, 0 );
+
+				planeMatrix.multiply( ( new THREE.Matrix4() ).makeRotationY( Math.PI / 2 ) );
+				positionOffset = ( volume.RASDimensions[ 0 ] - 1 ) / 2;
+				planeMatrix.setPosition( new THREE.Vector3( RASIndex - positionOffset, 0, 0 ) );
+				break;
+			case 'y' :
+				axisInIJK.set( 0, 1, 0 );
+				firstDirection.set( 1, 0, 0 );
+				secondDirection.set( 0, 0, 1 );
+				firstSpacing = this.spacing[ 0 ];
+				secondSpacing = this.spacing[ 2 ];
+				IJKIndex = new THREE.Vector3( 0, RASIndex, 0 );
+
+				planeMatrix.multiply( ( new THREE.Matrix4() ).makeRotationX( - Math.PI / 2 ) );
+				positionOffset = ( volume.RASDimensions[ 1 ] - 1 ) / 2;
+				planeMatrix.setPosition( new THREE.Vector3( 0, RASIndex - positionOffset, 0 ) );
+				break;
+			case 'z' :
+			default :
+				axisInIJK.set( 0, 0, 1 );
+				firstDirection.set( 1, 0, 0 );
+				secondDirection.set( 0, - 1, 0 );
+				firstSpacing = this.spacing[ 0 ];
+				secondSpacing = this.spacing[ 1 ];
+				IJKIndex = new THREE.Vector3( 0, 0, RASIndex );
+
+				positionOffset = ( volume.RASDimensions[ 2 ] - 1 ) / 2;
+				planeMatrix.setPosition( new THREE.Vector3( 0, 0, RASIndex - positionOffset ) );
+				break;
+		}
+
+		firstDirection.applyMatrix4( volume.inverseMatrix ).normalize();
+		firstDirection.argVar = 'i';
+		secondDirection.applyMatrix4( volume.inverseMatrix ).normalize();
+		secondDirection.argVar = 'j';
+		axisInIJK.applyMatrix4( volume.inverseMatrix ).normalize();
+		iLength = Math.floor( Math.abs( firstDirection.dot( dimensions ) ) );
+		jLength = Math.floor( Math.abs( secondDirection.dot( dimensions ) ) );
+		planeWidth = Math.abs( iLength * firstSpacing );
+		planeHeight = Math.abs( jLength * secondSpacing );
+
+		IJKIndex = Math.abs( Math.round( IJKIndex.applyMatrix4( volume.inverseMatrix ).dot( axisInIJK ) ) );
+		var base = [ new THREE.Vector3( 1, 0, 0 ), new THREE.Vector3( 0, 1, 0 ), new THREE.Vector3( 0, 0, 1 ) ];
+		var iDirection = [ firstDirection, secondDirection, axisInIJK ].find( function( x ) {
+
+			return Math.abs( x.dot( base[ 0 ] ) ) > 0.9;
+
+		} );
+		var jDirection = [ firstDirection, secondDirection, axisInIJK ].find( function( x ) {
+
+			return Math.abs( x.dot( base[ 1 ] ) ) > 0.9;
+
+		} );
+		var kDirection = [ firstDirection, secondDirection, axisInIJK ].find( function( x ) {
+
+			return Math.abs( x.dot( base[ 2 ] ) ) > 0.9;
+
+		} );
+		var argumentsWithInversion = [ 'volume.xLength-1-', 'volume.yLength-1-', 'volume.zLength-1-' ];
+		var arguments = [ 'i', 'j', 'k' ];
+		var argArray = [ iDirection, jDirection, kDirection ].map( function( direction, n ) {
+
+			return ( direction.dot( base[ n ] ) > 0 ? '' : argumentsWithInversion[ n ] ) + ( direction === axisInIJK ? 'IJKIndex' : direction.argVar )
+
+		} );
+		var argString = argArray.join( ',' );
+		sliceAccess = eval( '(function sliceAccess (i,j) {return volume.access( ' + argString + ');})' );
+
+
+		return {
+			iLength : iLength,
+			jLength : jLength,
+			sliceAccess : sliceAccess,
+			matrix : planeMatrix,
+			planeWidth : planeWidth,
+			planeHeight : planeHeight
+		}
+
+	},
+
+	/**
+	 * @member {Function} extractSlice Returns a slice corresponding to the given axis and index
+	 *                        The coordinate are given in the Right Anterior Superior coordinate format
+	 * @memberof THREE.Volume
+	 * @param {string}            axis  the normal axis to the slice 'x' 'y' or 'z'
+	 * @param {number}            index the index of the slice
+	 * @returns {THREE.VolumeSlice} the extracted slice
+	 */
+	extractSlice : function( axis, index ) {
+
+		var slice = new THREE.VolumeSlice( this, index, axis );
+		this.sliceList.push( slice );
+		return slice;
+
+	},
+
+	/**
+	 * @member {Function} repaintAllSlices Call repaint on all the slices extracted from this volume
+	 * @see THREE.VolumeSlice.repaint
+	 * @memberof THREE.Volume
+	 * @returns {THREE.Volume} this
+	 */
+	repaintAllSlices : function() {
+
+		this.sliceList.forEach( function( slice ) {
+
+			slice.repaint();
+
+		} );
+
+		return this;
+
+	},
+
+	/**
+	 * @member {Function} computeMinMax Compute the minimum and the maximum of the data in the volume
+	 * @memberof THREE.Volume
+	 * @returns {Array} [min,max]
+	 */
+	computeMinMax : function() {
+
+		var min = Infinity;
+		var max = - Infinity;
+
+		// buffer the length
+		var datasize = this.data.length;
+
+		var i = 0;
+		for ( i = 0; i < datasize; i ++ ) {
+
+			if ( ! isNaN( this.data[ i ] ) ) {
+
+				var value = this.data[ i ];
+				min = Math.min( min, value );
+				max = Math.max( max, value );
+
+			}
+
+		}
+		this.min = min;
+		this.max = max;
+
+		return [ min, max ];
+
+	}
+
+}

+ 217 - 0
examples/js/VolumeSlice.js

@@ -0,0 +1,217 @@
+/**
+ * This class has been made to hold a slice of a volume data
+ * @class
+ * @author Valentin Demeusy / https://github.com/stity
+ * @param   {THREE.Volume} volume    The associated volume
+ * @param   {number}       [index=0] The index of the slice
+ * @param   {string}       [axis='z']      For now only 'x', 'y' or 'z' but later it will change to a normal vector
+ * @see THREE.Volume
+ */
+THREE.VolumeSlice = function( volume, index, axis ) {
+
+	var slice = this;
+	/**
+	 * @member {THREE.Volume} volume The associated volume
+	 */
+	this.volume = volume;
+	/**
+	 * @member {Number} index The index of the slice, if changed, will automatically call updateGeometry at the next repaint
+	 */
+	index = index || 0;
+	Object.defineProperty( this, 'index', {
+		get : function() {
+
+			return index;
+
+		},
+		set : function( value ) {
+
+			index = value;
+			slice.geometryNeedsUpdate = true;
+			return index;
+
+		}
+	} );
+	/**
+	 * @member {String} axis The normal axis
+	 */
+	this.axis = axis || 'z';
+
+	/**
+	 * @member {HTMLCanvasElement} canvas The final canvas used for the texture
+	 */
+	/**
+	 * @member {CanvasRenderingContext2D} ctx Context of the canvas
+	 */
+	this.canvas = document.createElement( 'canvas' );
+	/**
+	 * @member {HTMLCanvasElement} canvasBuffer The intermediary canvas used to paint the data
+	 */
+	/**
+	 * @member {CanvasRenderingContext2D} ctxBuffer Context of the canvas buffer
+	 */
+	this.canvasBuffer = document.createElement( 'canvas' );
+	this.updateGeometry();
+
+
+	var canvasMap = new THREE.Texture( this.canvas );
+	canvasMap.minFilter = THREE.LinearFilter;
+	canvasMap.wrapS = canvasMap.wrapT = THREE.ClampToEdgeWrapping;
+	var material = new THREE.MeshBasicMaterial( { map: canvasMap, side: THREE.DoubleSide, transparent : true } );
+	/**
+	 * @member {THREE.Mesh} mesh The mesh ready to get used in the scene
+	 */
+	this.mesh = new THREE.Mesh( this.geometry, material );
+	/**
+	 * @member {Boolean} geometryNeedsUpdate If set to true, updateGeometry will be triggered at the next repaint
+	 */
+	this.geometryNeedsUpdate = true;
+	this.repaint();
+
+	/**
+	 * @member {Number} iLength Width of slice in the original coordinate system, corresponds to the width of the buffer canvas
+	 */
+
+	/**
+	 * @member {Number} jLength Height of slice in the original coordinate system, corresponds to the height of the buffer canvas
+	 */
+
+	/**
+	 * @member {Function} sliceAccess Function that allow the slice to access right data
+	 * @see THREE.Volume.extractPerpendicularPlane
+	 * @param {Number} i The first coordinate
+	 * @param {Number} j The second coordinate
+	 * @returns {Number} the index corresponding to the voxel in volume.data of the given position in the slice
+	 */
+
+
+}
+
+THREE.VolumeSlice.prototype = {
+
+	constructor : THREE.VolumeSlice,
+
+	/**
+	 * @member {Function} repaint Refresh the texture and the geometry if geometryNeedsUpdate is set to true
+	 * @memberof THREE.VolumeSlice
+	 */
+	repaint : function() {
+
+		if ( this.geometryNeedsUpdate ) {
+
+			this.updateGeometry();
+
+		}
+
+		var iLength = this.iLength,
+		jLength = this.jLength,
+		sliceAccess = this.sliceAccess,
+		volume = this.volume,
+		axis = this.axis,
+		index = this.index,
+		canvas = this.canvasBuffer,
+		ctx = this.ctxBuffer;
+
+
+		// get the imageData and pixel array from the canvas
+		var imgData = ctx.getImageData( 0, 0, iLength, jLength );
+		var data = imgData.data;
+		var volumeData = volume.data;
+		var upperThreshold = volume.upperThreshold;
+		var lowerThreshold = volume.lowerThreshold;
+		var windowLow = volume.windowLow;
+		var windowHigh = volume.windowHigh;
+
+		// manipulate some pixel elements
+		var pixelCount = 0;
+
+		if ( volume.dataType === 'label' ) {
+
+			//this part is currently useless but will be used when colortables will be handled
+			for ( var j = 0; j < jLength; j ++ ) {
+
+				for ( var i = 0; i < iLength; i ++ ) {
+
+					var label = volumeData[ sliceAccess( i, j ) ];
+					label = label >= this.colorMap.length ? ( label % this.colorMap.length ) + 1 : label;
+					var color = this.colorMap[ label ];
+					data[ 4 * pixelCount ] = ( color >> 24 ) & 0xff;
+					data[ 4 * pixelCount + 1 ] = ( color >> 16 ) & 0xff;
+					data[ 4 * pixelCount + 2 ] = ( color >> 8 ) & 0xff;
+					data[ 4 * pixelCount + 3 ] = color & 0xff;
+					pixelCount ++;
+
+				}
+
+			}
+
+		}
+		else {
+
+			for ( var j = 0; j < jLength; j ++ ) {
+
+				for ( var i = 0; i < iLength; i ++ ) {
+
+					var value = volumeData[ sliceAccess( i, j ) ];
+					var alpha = 0xff;
+					//apply threshold
+					alpha = upperThreshold >= value ? ( lowerThreshold <= value ? alpha : 0 ) : 0;
+					//apply window level
+					value = Math.floor( 255 * ( value - windowLow ) / ( windowHigh - windowLow ) );
+					value = value > 255 ? 255 : ( value < 0 ? 0 : value | 0 );
+
+					data[ 4 * pixelCount ] = value;
+					data[ 4 * pixelCount + 1 ] = value;
+					data[ 4 * pixelCount + 2 ] = value;
+					data[ 4 * pixelCount + 3 ] = alpha;
+					pixelCount ++;
+
+				}
+
+			}
+
+		}
+		ctx.putImageData( imgData, 0, 0 );
+		this.ctx.drawImage( canvas, 0, 0, iLength, jLength, 0, 0, this.canvas.width, this.canvas.height );
+
+
+		this.mesh.material.map.needsUpdate = true;
+
+	},
+
+	/**
+	 * @member {Function} Refresh the geometry according to axis and index
+	 * @see THREE.Volume.extractPerpendicularPlane
+	 * @memberof THREE.VolumeSlice
+	 */
+	updateGeometry : function() {
+
+		var extracted = this.volume.extractPerpendicularPlane( this.axis, this.index );
+		this.sliceAccess = extracted.sliceAccess;
+		this.jLength = extracted.jLength;
+		this.iLength = extracted.iLength;
+		this.matrix = extracted.matrix;
+
+		this.canvas.width = extracted.planeWidth;
+		this.canvas.height = extracted.planeHeight;
+		this.canvasBuffer.width = this.iLength;
+		this.canvasBuffer.height = this.jLength;
+		this.ctx = this.canvas.getContext( '2d' );
+		this.ctxBuffer = this.canvasBuffer.getContext( '2d' );
+
+		this.geometry = new THREE.PlaneGeometry( extracted.planeWidth, extracted.planeHeight );
+
+		if ( this.mesh ) {
+
+			this.mesh.geometry = this.geometry;
+			//reset mesh matrix
+			this.mesh.matrix = ( new THREE.Matrix4() ).identity();
+			this.mesh.applyMatrix( this.matrix );
+
+		}
+
+		this.geometryNeedsUpdate = false;
+
+	}
+
+}

+ 97 - 0
examples/js/WebVR.js

@@ -0,0 +1,97 @@
+/**
+ * @author mrdoob / http://mrdoob.com
+ * Based on @tojiro's vr-samples-utils.js
+ */
+
+var WEBVR = {
+
+	isLatestAvailable: function () {
+
+		return navigator.getVRDisplays !== undefined;
+
+	},
+
+	isAvailable: function () {
+
+		return navigator.getVRDisplays !== undefined || navigator.getVRDevices !== undefined;
+
+	},
+
+	getMessage: function () {
+
+		var message;
+
+		if ( navigator.getVRDisplays ) {
+
+			navigator.getVRDisplays().then( function ( displays ) {
+
+				if ( displays.length === 0 ) message = 'WebVR supported, but no VRDisplays found.';
+
+			} );
+
+		} else if ( navigator.getVRDevices ) {
+
+			message = 'Your browser supports WebVR but not the latest version. See <a href="http://webvr.info">webvr.info</a> for more info.';
+
+		} else {
+
+			message = 'Your browser does not support WebVR. See <a href="http://webvr.info">webvr.info</a> for assistance.';
+
+		}
+
+		if ( message !== undefined ) {
+
+			var container = document.createElement( 'div' );
+			container.style.position = 'absolute';
+			container.style.left = '0';
+			container.style.top = '0';
+			container.style.right = '0';
+			container.style.zIndex = '999';
+			container.align = 'center';
+
+			var error = document.createElement( 'div' );
+			error.style.fontFamily = 'sans-serif';
+			error.style.fontSize = '16px';
+			error.style.fontStyle = 'normal';
+			error.style.lineHeight = '26px';
+			error.style.backgroundColor = '#fff';
+			error.style.color = '#000';
+			error.style.padding = '10px 20px';
+			error.style.margin = '50px';
+			error.style.display = 'inline-block';
+			error.innerHTML = message;
+			container.appendChild( error );
+
+			return container;
+
+		}
+
+	},
+
+	getButton: function ( effect ) {
+
+		var button = document.createElement( 'button' );
+		button.style.position = 'absolute';
+		button.style.left = 'calc(50% - 30px)';
+		button.style.bottom = '20px';
+		button.style.border = '0';
+		button.style.padding = '8px';
+		button.style.cursor = 'pointer';
+		button.style.backgroundColor = '#000';
+		button.style.color = '#fff';
+		button.style.fontFamily = 'sans-serif';
+		button.style.fontSize = '13px';
+		button.style.fontStyle = 'normal';
+		button.style.zIndex = '999';
+		button.textContent = 'ENTER VR';
+		button.onclick = function() {
+
+			effect.setFullScreen( true );
+
+		};
+
+		return button;
+
+	}
+
+};

+ 6 - 12
examples/js/controls/EditorControls.js

@@ -26,6 +26,7 @@ THREE.EditorControls = function ( object, domElement ) {
 	var normalMatrix = new THREE.Matrix3();
 	var pointer = new THREE.Vector2();
 	var pointerOld = new THREE.Vector2();
+	var spherical = new THREE.Spherical();
 
 	// events
 
@@ -86,21 +87,14 @@ THREE.EditorControls = function ( object, domElement ) {
 
 		vector.copy( object.position ).sub( center );
 
-		var theta = Math.atan2( vector.x, vector.z );
-		var phi = Math.atan2( Math.sqrt( vector.x * vector.x + vector.z * vector.z ), vector.y );
+		spherical.setFromVector3( vector );
 
-		theta += delta.x;
-		phi += delta.y;
+		spherical.theta += delta.x;
+		spherical.phi += delta.y;
 
-		var EPS = 0.000001;
+		spherical.makeSafe();
 
-		phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );
-
-		var radius = vector.length();
-
-		vector.x = radius * Math.sin( phi ) * Math.sin( theta );
-		vector.y = radius * Math.cos( phi );
-		vector.z = radius * Math.sin( phi ) * Math.cos( theta );
+		vector.setFromSpherical( spherical );
 
 		object.position.copy( center ).add( vector );
 

+ 21 - 39
examples/js/controls/OrbitControls.js

@@ -133,12 +133,7 @@ THREE.OrbitControls = function ( object, domElement ) {
 			offset.applyQuaternion( quat );
 
 			// angle from z-axis around y-axis
-
-			theta = Math.atan2( offset.x, offset.z );
-
-			// angle from y-axis
-
-			phi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y );
+			spherical.setFromVector3( offset );
 
 			if ( scope.autoRotate && state === STATE.NONE ) {
 
@@ -146,29 +141,27 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 			}
 
-			theta += thetaDelta;
-			phi += phiDelta;
+			spherical.theta += sphericalDelta.theta;
+			spherical.phi += sphericalDelta.phi;
 
 			// restrict theta to be between desired limits
-			theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, theta ) );
+			spherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );
 
 			// restrict phi to be between desired limits
-			phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, phi ) );
+			spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );
+
+			spherical.makeSafe();
 
-			// restrict phi to be betwee EPS and PI-EPS
-			phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );
 
-			var radius = offset.length() * scale;
+			spherical.radius *= scale;
 
 			// restrict radius to be between desired limits
-			radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, radius ) );
+			spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );
 
 			// move target to panned location
 			scope.target.add( panOffset );
 
-			offset.x = radius * Math.sin( phi ) * Math.sin( theta );
-			offset.y = radius * Math.cos( phi );
-			offset.z = radius * Math.sin( phi ) * Math.cos( theta );
+			offset.setFromSpherical( spherical );
 
 			// rotate offset back to "camera-up-vector-is-up" space
 			offset.applyQuaternion( quatInverse );
@@ -179,13 +172,12 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 			if ( scope.enableDamping === true ) {
 
-				thetaDelta *= ( 1 - scope.dampingFactor );
-				phiDelta *= ( 1 - scope.dampingFactor );
+				sphericalDelta.theta *= ( 1 - scope.dampingFactor );
+				sphericalDelta.phi *= ( 1 - scope.dampingFactor );
 
 			} else {
 
-				thetaDelta = 0;
-				phiDelta = 0;
+				sphericalDelta.set( 0, 0, 0 );
 
 			}
 
@@ -254,11 +246,9 @@ THREE.OrbitControls = function ( object, domElement ) {
 	var EPS = 0.000001;
 
 	// current position in spherical coordinates
-	var theta;
-	var phi;
+	var spherical = new THREE.Spherical();
+	var sphericalDelta = new THREE.Spherical();
 
-	var phiDelta = 0;
-	var thetaDelta = 0;
 	var scale = 1;
 	var panOffset = new THREE.Vector3();
 	var zoomChanged = false;
@@ -289,13 +279,13 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function rotateLeft( angle ) {
 
-		thetaDelta -= angle;
+		sphericalDelta.theta -= angle;
 
 	}
 
 	function rotateUp( angle ) {
 
-		phiDelta -= angle;
+		sphericalDelta.phi -= angle;
 
 	}
 
@@ -305,11 +295,7 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 		return function panLeft( distance, objectMatrix ) {
 
-			var te = objectMatrix.elements;
-
-			// get X column of objectMatrix
-			v.set( te[ 0 ], te[ 1 ], te[ 2 ] );
-
+			v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix
 			v.multiplyScalar( - distance );
 
 			panOffset.add( v );
@@ -324,11 +310,7 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 		return function panUp( distance, objectMatrix ) {
 
-			var te = objectMatrix.elements;
-
-			// get Y column of objectMatrix
-			v.set( te[ 4 ], te[ 5 ], te[ 6 ] );
-
+			v.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix
 			v.multiplyScalar( distance );
 
 			panOffset.add( v );
@@ -363,8 +345,8 @@ THREE.OrbitControls = function ( object, domElement ) {
 			} else if ( scope.object instanceof THREE.OrthographicCamera ) {
 
 				// orthographic
-				panLeft( deltaX * ( scope.object.right - scope.object.left ) / element.clientWidth, scope.object.matrix );
-				panUp( deltaY * ( scope.object.top - scope.object.bottom ) / element.clientHeight, scope.object.matrix );
+				panLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );
+				panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );
 
 			} else {
 

+ 19 - 0
examples/js/controls/TrackballControls.js

@@ -356,6 +356,8 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 		if ( _this.enabled === false ) return;
 
+		window.removeEventListener( 'keydown', keydown );
+
 		_prevState = _state;
 
 		if ( _state !== STATE.NONE ) {
@@ -384,12 +386,17 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 		_state = _prevState;
 
+		window.addEventListener( 'keydown', keydown, false );
+
 	}
 
 	function mousedown( event ) {
 
 		if ( _this.enabled === false ) return;
 
+		event.preventDefault();
+		event.stopPropagation();
+
 		if ( _state === STATE.NONE ) {
 
 			_state = event.button;
@@ -424,6 +431,9 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 		if ( _this.enabled === false ) return;
 
+		event.preventDefault();
+		event.stopPropagation();
+
 		if ( _state === STATE.ROTATE && ! _this.noRotate ) {
 
 			_movePrev.copy( _moveCurr );
@@ -445,6 +455,9 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 		if ( _this.enabled === false ) return;
 
+		event.preventDefault();
+		event.stopPropagation();
+
 		_state = STATE.NONE;
 
 		document.removeEventListener( 'mousemove', mousemove );
@@ -457,6 +470,9 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 		if ( _this.enabled === false ) return;
 
+		event.preventDefault();
+		event.stopPropagation();
+
 		var delta = 0;
 
 		if ( event.wheelDelta ) {
@@ -513,6 +529,9 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 		if ( _this.enabled === false ) return;
 
+		event.preventDefault();
+		event.stopPropagation();
+
 		switch ( event.touches.length ) {
 
 			case 1:

+ 48 - 18
examples/js/controls/VRControls.js

@@ -7,30 +7,37 @@ THREE.VRControls = function ( object, onError ) {
 
 	var scope = this;
 
-	var vrInputs = [];
+	var vrInput;
 
 	function gotVRDevices( devices ) {
 
 		for ( var i = 0; i < devices.length; i ++ ) {
 
-			if ( devices[ i ] instanceof PositionSensorVRDevice ) {
+			if ( ( 'VRDisplay' in window && devices[ i ] instanceof VRDisplay ) ||
+				 ( 'PositionSensorVRDevice' in window && devices[ i ] instanceof PositionSensorVRDevice ) ) {
 
-				vrInputs.push( devices[ i ] );
+				vrInput = devices[ i ];
+				break;  // We keep the first we encounter
 
 			}
 
 		}
 
-		if ( vrInputs.length === 0 ) {
+		if ( !vrInput ) {
 
-			if ( onError ) onError( 'PositionSensorVRDevice not available' );
+			if ( onError ) onError( 'VR input not available.' );
 
 		}
 
 	}
 
-	if ( navigator.getVRDevices ) {
+	if ( navigator.getVRDisplays ) {
 
+		navigator.getVRDisplays().then( gotVRDevices );
+
+	} else if ( navigator.getVRDevices ) {
+
+		// Deprecated API.
 		navigator.getVRDevices().then( gotVRDevices );
 
 	}
@@ -43,21 +50,40 @@ THREE.VRControls = function ( object, onError ) {
 
 	this.update = function () {
 
-		for ( var i = 0; i < vrInputs.length; i ++ ) {
+		if ( vrInput ) {
 
-			var vrInput = vrInputs[ i ];
+			if ( vrInput.getPose ) {
 
-			var state = vrInput.getState();
+				var pose = vrInput.getPose();
 
-			if ( state.orientation !== null ) {
+				if ( pose.orientation !== null ) {
 
-				object.quaternion.copy( state.orientation );
+					object.quaternion.fromArray( pose.orientation );
 
-			}
+				}
+
+				if ( pose.position !== null ) {
+
+					object.position.fromArray( pose.position ).multiplyScalar( scope.scale );
+
+				}
+
+			} else {
 
-			if ( state.position !== null ) {
+				// Deprecated API.
+				var state = vrInput.getState();
 
-				object.position.copy( state.position ).multiplyScalar( scope.scale );
+				if ( state.orientation !== null ) {
+
+					object.quaternion.copy( state.orientation );
+
+				}
+
+				if ( state.position !== null ) {
+
+					object.position.copy( state.position ).multiplyScalar( scope.scale );
+
+				}
 
 			}
 
@@ -67,16 +93,20 @@ THREE.VRControls = function ( object, onError ) {
 
 	this.resetSensor = function () {
 
-		for ( var i = 0; i < vrInputs.length; i ++ ) {
+		if ( vrInput ) {
+
+			if ( vrInput.resetPose !== undefined ) {
 
-			var vrInput = vrInputs[ i ];
+				vrInput.resetPose();
 
-			if ( vrInput.resetSensor !== undefined ) {
+			} else if ( vrInput.resetSensor !== undefined ) {
 
+				// Deprecated API.
 				vrInput.resetSensor();
 
 			} else if ( vrInput.zeroSensor !== undefined ) {
 
+				// Really deprecated API.
 				vrInput.zeroSensor();
 
 			}
@@ -94,7 +124,7 @@ THREE.VRControls = function ( object, onError ) {
 
 	this.dispose = function () {
 
-		vrInputs = [];
+		vrInput = null;
 
 	};
 

+ 5 - 3
examples/js/effects/AnaglyphEffect.js

@@ -71,11 +71,13 @@ THREE.AnaglyphEffect = function ( renderer, width, height ) {
 
 	this.setSize = function ( width, height ) {
 
-		_renderTargetL.setSize( width, height );
-		_renderTargetR.setSize( width, height );
-
 		renderer.setSize( width, height );
 
+		var pixelRatio = renderer.getPixelRatio();
+
+		_renderTargetL.setSize( width * pixelRatio, height * pixelRatio );
+		_renderTargetR.setSize( width * pixelRatio, height * pixelRatio );
+
 	};
 
 	this.render = function ( scene, camera ) {

+ 4 - 2
examples/js/effects/CardboardEffect.js

@@ -70,10 +70,12 @@ THREE.CardboardEffect = function ( renderer ) {
 
 	this.setSize = function ( width, height ) {
 
-		_renderTarget.setSize( width, height );
-
 		renderer.setSize( width, height );
 
+		var pixelRatio = renderer.getPixelRatio();
+
+		_renderTarget.setSize( width * pixelRatio, height * pixelRatio );
+
 	};
 
 	this.render = function ( scene, camera ) {

+ 5 - 3
examples/js/effects/ParallaxBarrierEffect.js

@@ -70,11 +70,13 @@ THREE.ParallaxBarrierEffect = function ( renderer ) {
 
 	this.setSize = function ( width, height ) {
 
-		_renderTargetL.setSize( width, height );
-		_renderTargetR.setSize( width, height );
-
 		renderer.setSize( width, height );
 
+		var pixelRatio = renderer.getPixelRatio();
+
+		_renderTargetL.setSize( width * pixelRatio, height * pixelRatio );
+		_renderTargetR.setSize( width * pixelRatio, height * pixelRatio );
+
 	};
 
 	this.render = function ( scene, camera ) {

+ 132 - 23
examples/js/effects/VREffect.js

@@ -12,17 +12,26 @@
 THREE.VREffect = function ( renderer, onError ) {
 
 	var vrHMD;
-	var eyeTranslationL, eyeFOVL;
-	var eyeTranslationR, eyeFOVR;
+	var deprecatedAPI = false;
+	var eyeTranslationL = new THREE.Vector3();
+	var eyeTranslationR = new THREE.Vector3();
+	var renderRectL, renderRectR;
+	var eyeFOVL, eyeFOVR;
 
 	function gotVRDevices( devices ) {
 
 		for ( var i = 0; i < devices.length; i ++ ) {
 
-			if ( devices[ i ] instanceof HMDVRDevice ) {
+			if ( 'VRDisplay' in window && devices[ i ] instanceof VRDisplay ) {
 
 				vrHMD = devices[ i ];
+				deprecatedAPI = false;
+				break; // We keep the first we encounter
+
+			} else if ( 'HMDVRDevice' in window && devices[ i ] instanceof HMDVRDevice ) {
 
+				vrHMD = devices[ i ];
+				deprecatedAPI = true;
 				break; // We keep the first we encounter
 
 			}
@@ -37,8 +46,13 @@ THREE.VREffect = function ( renderer, onError ) {
 
 	}
 
-	if ( navigator.getVRDevices ) {
+	if ( navigator.getVRDisplays ) {
+
+		navigator.getVRDisplays().then( gotVRDevices );
 
+	} else if ( navigator.getVRDevices ) {
+
+		// Deprecated API.
 		navigator.getVRDevices().then( gotVRDevices );
 
 	}
@@ -55,31 +69,90 @@ THREE.VREffect = function ( renderer, onError ) {
 
 	// fullscreen
 
-	var isFullscreen = false;
+	var isPresenting = false;
 
 	var canvas = renderer.domElement;
 	var fullscreenchange = canvas.mozRequestFullScreen ? 'mozfullscreenchange' : 'webkitfullscreenchange';
 
-	document.addEventListener( fullscreenchange, function ( event ) {
+	document.addEventListener( fullscreenchange, function () {
+
+		if ( vrHMD && deprecatedAPI ) {
 
-		isFullscreen = document.mozFullScreenElement || document.webkitFullscreenElement;
+			isPresenting = document.mozFullScreenElement || document.webkitFullscreenElement;
+
+		}
+
+	}, false );
+
+	window.addEventListener( 'vrdisplaypresentchange', function () {
+
+		isPresenting = vrHMD && vrHMD.isPresenting;
 
 	}, false );
 
 	this.setFullScreen = function ( boolean ) {
 
-		if ( vrHMD === undefined ) return;
-		if ( isFullscreen === boolean ) return;
+		return new Promise( function ( resolve, reject ) {
 
-		if ( canvas.mozRequestFullScreen ) {
+			if ( vrHMD === undefined ) {
 
-			canvas.mozRequestFullScreen( { vrDisplay: vrHMD } );
+				reject( new Error( 'No VR hardware found.' ) );
+				return;
 
-		} else if ( canvas.webkitRequestFullscreen ) {
+			}
+			if ( isPresenting === boolean ) {
 
-			canvas.webkitRequestFullscreen( { vrDisplay: vrHMD } );
+				resolve();
+				return;
 
-		}
+			}
+
+			if ( !deprecatedAPI ) {
+
+				if ( boolean ) {
+
+					resolve( vrHMD.requestPresent( { source: canvas } ) );
+
+				} else {
+
+					resolve( vrHMD.exitPresent() );
+
+				}
+
+			} else {
+
+				if ( canvas.mozRequestFullScreen ) {
+
+					canvas.mozRequestFullScreen( { vrDisplay: vrHMD } );
+					resolve();
+
+				} else if ( canvas.webkitRequestFullscreen ) {
+
+					canvas.webkitRequestFullscreen( { vrDisplay: vrHMD } );
+					resolve();
+
+				} else {
+
+					console.error( 'No compatible requestFullscreen method found.' );
+					reject( new Error( 'No compatible requestFullscreen method found.' ) );
+
+				}
+
+			}
+
+		});
+
+	};
+
+	this.requestPresent = function () {
+
+		return this.setFullScreen( true );
+
+	};
+
+	this.exitPresent = function () {
+
+		return this.setFullScreen( false );
 
 	};
 
@@ -93,15 +166,35 @@ THREE.VREffect = function ( renderer, onError ) {
 
 	this.render = function ( scene, camera ) {
 
-		if ( vrHMD ) {
+		if ( vrHMD && isPresenting ) {
+
+			var autoUpdate = scene.autoUpdate;
+
+			if ( autoUpdate ) {
+
+				scene.updateMatrixWorld();
+				scene.autoUpdate = false;
+
+			}
 
 			var eyeParamsL = vrHMD.getEyeParameters( 'left' );
 			var eyeParamsR = vrHMD.getEyeParameters( 'right' );
 
-			eyeTranslationL = eyeParamsL.eyeTranslation;
-			eyeTranslationR = eyeParamsR.eyeTranslation;
-			eyeFOVL = eyeParamsL.recommendedFieldOfView;
-			eyeFOVR = eyeParamsR.recommendedFieldOfView;
+			if ( !deprecatedAPI ) {
+
+				eyeTranslationL.fromArray( eyeParamsL.offset );
+				eyeTranslationR.fromArray( eyeParamsR.offset );
+				eyeFOVL = eyeParamsL.fieldOfView;
+				eyeFOVR = eyeParamsR.fieldOfView;
+
+			} else {
+
+				eyeTranslationL.copy( eyeParamsL.eyeTranslation );
+				eyeTranslationR.copy( eyeParamsR.eyeTranslation );
+				eyeFOVL = eyeParamsL.recommendedFieldOfView;
+				eyeFOVR = eyeParamsR.recommendedFieldOfView;
+
+			}
 
 			if ( Array.isArray( scene ) ) {
 
@@ -110,7 +203,11 @@ THREE.VREffect = function ( renderer, onError ) {
 
 			}
 
+			// When rendering we don't care what the recommended size is, only what the actual size
+			// of the backbuffer is.
 			var size = renderer.getSize();
+			renderRectL = { x: 0, y: 0, width: size.width / 2, height: size.height };
+			renderRectR = { x: size.width / 2, y: 0, width: size.width / 2, height: size.height };
 
 			renderer.setScissorTest( true );
 			renderer.clear();
@@ -127,17 +224,29 @@ THREE.VREffect = function ( renderer, onError ) {
 			cameraR.translateX( eyeTranslationR.x * this.scale );
 
 			// render left eye
-			renderer.setViewport( 0, 0, size.width / 2, size.height );
-			renderer.setScissor( 0, 0, size.width / 2, size.height );
+			renderer.setViewport( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
+			renderer.setScissor( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
 			renderer.render( scene, cameraL );
 
 			// render right eye
-			renderer.setViewport( size.width / 2, 0, size.width / 2, size.height );
-			renderer.setScissor( size.width / 2, 0, size.width / 2, size.height );
+			renderer.setViewport( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
+			renderer.setScissor( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
 			renderer.render( scene, cameraR );
 
 			renderer.setScissorTest( false );
 
+			if ( autoUpdate ) {
+
+				scene.autoUpdate = true;
+
+			}
+
+			if ( !deprecatedAPI ) {
+
+				vrHMD.submitFrame();
+
+			}
+
 			return;
 
 		}

+ 71 - 4
examples/js/exporters/OBJExporter.js

@@ -123,11 +123,11 @@ THREE.OBJExporter.prototype = {
 					var face = faces[ i ];
 
 					for ( var m = 0; m < 3; m ++ ) {
-					
+
 					    indices[ m ] = ( indexVertex + face[ faceVertexKeys[ m ] ] + 1 ) + '/' + ( hasVertexUvs ? ( indexVertexUvs + j + m + 1 ) : '' ) + '/' + ( indexNormals + j + m + 1 );
-					
+
 					}
-					
+
 					output += 'f ' + indices.join( ' ' ) + "\n";
 
 				}
@@ -145,9 +145,76 @@ THREE.OBJExporter.prototype = {
 
 		};
 
+		var parseLine = function( line ) {
+
+			var geometry = line.geometry;
+			var type = line.type;
+
+			if ( geometry instanceof THREE.BufferGeometry ) {
+
+				geometry = new THREE.Geometry().fromBufferGeometry( geometry );
+
+			}
+
+			if ( geometry instanceof THREE.Geometry ) {
+
+				output += 'o ' + line.name + '\n';
+
+				var vertices = geometry.vertices;
+
+				for ( var i = 0, l = vertices.length; i < l; i++ ) {
+
+					var vertex = vertices[ i ].clone();
+					vertex.applyMatrix4( line.matrixWorld );
+
+					output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n';
+
+				}
+
+				if ( type === 'Line' ) {
+
+					output += 'l ';
+
+					for ( var j = 1, m = vertices.length; j <= m; j++ ) {
+
+						output += j + ' ';
+
+					}
+
+					output += '\n';
+
+				}
+
+				if ( type === 'LineSegments' ) {
+
+					for ( var j = 1, k = j + 1, m = vertices.length; j < m; j += 2, k = j + 1 ) {
+
+						output += 'l ' + j + ' ' + k + '\n';
+
+					}
+
+				}
+
+			} else {
+
+				console.warn('THREE.OBJExporter.parseLine(): geometry type unsupported', line);
+
+			}
+		};
+
 		object.traverse( function ( child ) {
 
-			if ( child instanceof THREE.Mesh ) parseMesh( child );
+			if ( child instanceof THREE.Mesh ) {
+
+				parseMesh( child );
+
+			}
+
+			if ( child instanceof THREE.Line ) {
+
+				parseLine( child );
+
+			}
 
 		} );
 

+ 25 - 19
examples/js/exporters/STLBinaryExporter.js

@@ -17,11 +17,29 @@ THREE.STLBinaryExporter.prototype = {
 
 		return function parse( scene ) {
 
+			// We collect objects first, as we may need to convert from BufferGeometry to Geometry
+			var objects = [];
 			var triangles = 0;
 			scene.traverse( function ( object ) {
 
 				if ( ! ( object instanceof THREE.Mesh ) ) return;
-				triangles += object.geometry.faces.length;
+
+				var geometry = object.geometry;
+				if ( geometry instanceof THREE.BufferGeometry ) {
+
+					geometry = new THREE.Geometry().fromBufferGeometry( geometry );
+
+				}
+
+				if ( ! ( geometry instanceof THREE.Geometry ) ) return;
+				triangles += geometry.faces.length;
+
+				objects.push( {
+
+					geometry: geometry,
+					matrix: object.matrixWorld
+
+				} );
 
 			} );
 
@@ -31,25 +49,13 @@ THREE.STLBinaryExporter.prototype = {
 			var output = new DataView( arrayBuffer );
 			output.setUint32( offset, triangles, true ); offset += 4;
 
-			scene.traverse( function ( object ) {
-
-				if ( ! ( object instanceof THREE.Mesh ) ) return;
-
-				var geometry = object.geometry;
-				if ( geometry instanceof THREE.BufferGeometry ) {
-                            
-					geometry = new THREE.Geometry().fromBufferGeometry( geometry );
-                            
-				}
-
-				if ( ! ( geometry instanceof THREE.Geometry ) ) return;
-
-				var matrixWorld = object.matrixWorld;
+			// Traversing our collected objects
+			objects.forEach( function ( object ) {
 
-				var vertices = geometry.vertices;
-				var faces = geometry.faces;
+				var vertices = object.geometry.vertices;
+				var faces = object.geometry.faces;
 
-				normalMatrixWorld.getNormalMatrix( matrixWorld );
+				normalMatrixWorld.getNormalMatrix( object.matrix );
 
 				for ( var i = 0, l = faces.length; i < l; i ++ ) {
 
@@ -65,7 +71,7 @@ THREE.STLBinaryExporter.prototype = {
 
 					for ( var j = 0; j < 3; j ++ ) {
 
-						vector.copy( vertices[ indices[ j ] ] ).applyMatrix4( matrixWorld );
+						vector.copy( vertices[ indices[ j ] ] ).applyMatrix4( object.matrix );
 
 						output.setFloat32( offset, vector.x, true ); offset += 4; // vertices
 						output.setFloat32( offset, vector.y, true ); offset += 4;

+ 15 - 0
examples/js/libs/inflate.min.js

@@ -0,0 +1,15 @@
+/** @license zlib.js 2012 - imaya [ https://github.com/imaya/zlib.js ] The MIT License */(function() {'use strict';var m=this;function q(c,d){var a=c.split("."),b=m;!(a[0]in b)&&b.execScript&&b.execScript("var "+a[0]);for(var e;a.length&&(e=a.shift());)!a.length&&void 0!==d?b[e]=d:b=b[e]?b[e]:b[e]={}};var s="undefined"!==typeof Uint8Array&&"undefined"!==typeof Uint16Array&&"undefined"!==typeof Uint32Array&&"undefined"!==typeof DataView;function t(c){var d=c.length,a=0,b=Number.POSITIVE_INFINITY,e,f,g,h,k,l,p,n,r,K;for(n=0;n<d;++n)c[n]>a&&(a=c[n]),c[n]<b&&(b=c[n]);e=1<<a;f=new (s?Uint32Array:Array)(e);g=1;h=0;for(k=2;g<=a;){for(n=0;n<d;++n)if(c[n]===g){l=0;p=h;for(r=0;r<g;++r)l=l<<1|p&1,p>>=1;K=g<<16|n;for(r=l;r<e;r+=k)f[r]=K;++h}++g;h<<=1;k<<=1}return[f,a,b]};function u(c,d){this.g=[];this.h=32768;this.d=this.f=this.a=this.l=0;this.input=s?new Uint8Array(c):c;this.m=!1;this.i=v;this.s=!1;if(d||!(d={}))d.index&&(this.a=d.index),d.bufferSize&&(this.h=d.bufferSize),d.bufferType&&(this.i=d.bufferType),d.resize&&(this.s=d.resize);switch(this.i){case w:this.b=32768;this.c=new (s?Uint8Array:Array)(32768+this.h+258);break;case v:this.b=0;this.c=new (s?Uint8Array:Array)(this.h);this.e=this.A;this.n=this.w;this.j=this.z;break;default:throw Error("invalid inflate mode");
+}}var w=0,v=1,x={u:w,t:v};
+u.prototype.k=function(){for(;!this.m;){var c=y(this,3);c&1&&(this.m=!0);c>>>=1;switch(c){case 0:var d=this.input,a=this.a,b=this.c,e=this.b,f=d.length,g=void 0,h=void 0,k=b.length,l=void 0;this.d=this.f=0;if(a+1>=f)throw Error("invalid uncompressed block header: LEN");g=d[a++]|d[a++]<<8;if(a+1>=f)throw Error("invalid uncompressed block header: NLEN");h=d[a++]|d[a++]<<8;if(g===~h)throw Error("invalid uncompressed block header: length verify");if(a+g>d.length)throw Error("input buffer is broken");switch(this.i){case w:for(;e+
+g>b.length;){l=k-e;g-=l;if(s)b.set(d.subarray(a,a+l),e),e+=l,a+=l;else for(;l--;)b[e++]=d[a++];this.b=e;b=this.e();e=this.b}break;case v:for(;e+g>b.length;)b=this.e({p:2});break;default:throw Error("invalid inflate mode");}if(s)b.set(d.subarray(a,a+g),e),e+=g,a+=g;else for(;g--;)b[e++]=d[a++];this.a=a;this.b=e;this.c=b;break;case 1:this.j(z,A);break;case 2:B(this);break;default:throw Error("unknown BTYPE: "+c);}}return this.n()};
+var C=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],D=s?new Uint16Array(C):C,E=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,258,258],F=s?new Uint16Array(E):E,G=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0],H=s?new Uint8Array(G):G,I=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],J=s?new Uint16Array(I):I,L=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,
+13],M=s?new Uint8Array(L):L,N=new (s?Uint8Array:Array)(288),O,P;O=0;for(P=N.length;O<P;++O)N[O]=143>=O?8:255>=O?9:279>=O?7:8;var z=t(N),Q=new (s?Uint8Array:Array)(30),R,S;R=0;for(S=Q.length;R<S;++R)Q[R]=5;var A=t(Q);function y(c,d){for(var a=c.f,b=c.d,e=c.input,f=c.a,g=e.length,h;b<d;){if(f>=g)throw Error("input buffer is broken");a|=e[f++]<<b;b+=8}h=a&(1<<d)-1;c.f=a>>>d;c.d=b-d;c.a=f;return h}
+function T(c,d){for(var a=c.f,b=c.d,e=c.input,f=c.a,g=e.length,h=d[0],k=d[1],l,p;b<k&&!(f>=g);)a|=e[f++]<<b,b+=8;l=h[a&(1<<k)-1];p=l>>>16;c.f=a>>p;c.d=b-p;c.a=f;return l&65535}
+function B(c){function d(a,c,b){var d,e=this.q,f,g;for(g=0;g<a;)switch(d=T(this,c),d){case 16:for(f=3+y(this,2);f--;)b[g++]=e;break;case 17:for(f=3+y(this,3);f--;)b[g++]=0;e=0;break;case 18:for(f=11+y(this,7);f--;)b[g++]=0;e=0;break;default:e=b[g++]=d}this.q=e;return b}var a=y(c,5)+257,b=y(c,5)+1,e=y(c,4)+4,f=new (s?Uint8Array:Array)(D.length),g,h,k,l;for(l=0;l<e;++l)f[D[l]]=y(c,3);if(!s){l=e;for(e=f.length;l<e;++l)f[D[l]]=0}g=t(f);h=new (s?Uint8Array:Array)(a);k=new (s?Uint8Array:Array)(b);c.q=0;
+c.j(t(d.call(c,a,g,h)),t(d.call(c,b,g,k)))}u.prototype.j=function(c,d){var a=this.c,b=this.b;this.o=c;for(var e=a.length-258,f,g,h,k;256!==(f=T(this,c));)if(256>f)b>=e&&(this.b=b,a=this.e(),b=this.b),a[b++]=f;else{g=f-257;k=F[g];0<H[g]&&(k+=y(this,H[g]));f=T(this,d);h=J[f];0<M[f]&&(h+=y(this,M[f]));b>=e&&(this.b=b,a=this.e(),b=this.b);for(;k--;)a[b]=a[b++-h]}for(;8<=this.d;)this.d-=8,this.a--;this.b=b};
+u.prototype.z=function(c,d){var a=this.c,b=this.b;this.o=c;for(var e=a.length,f,g,h,k;256!==(f=T(this,c));)if(256>f)b>=e&&(a=this.e(),e=a.length),a[b++]=f;else{g=f-257;k=F[g];0<H[g]&&(k+=y(this,H[g]));f=T(this,d);h=J[f];0<M[f]&&(h+=y(this,M[f]));b+k>e&&(a=this.e(),e=a.length);for(;k--;)a[b]=a[b++-h]}for(;8<=this.d;)this.d-=8,this.a--;this.b=b};
+u.prototype.e=function(){var c=new (s?Uint8Array:Array)(this.b-32768),d=this.b-32768,a,b,e=this.c;if(s)c.set(e.subarray(32768,c.length));else{a=0;for(b=c.length;a<b;++a)c[a]=e[a+32768]}this.g.push(c);this.l+=c.length;if(s)e.set(e.subarray(d,d+32768));else for(a=0;32768>a;++a)e[a]=e[d+a];this.b=32768;return e};
+u.prototype.A=function(c){var d,a=this.input.length/this.a+1|0,b,e,f,g=this.input,h=this.c;c&&("number"===typeof c.p&&(a=c.p),"number"===typeof c.v&&(a+=c.v));2>a?(b=(g.length-this.a)/this.o[2],f=258*(b/2)|0,e=f<h.length?h.length+f:h.length<<1):e=h.length*a;s?(d=new Uint8Array(e),d.set(h)):d=h;return this.c=d};
+u.prototype.n=function(){var c=0,d=this.c,a=this.g,b,e=new (s?Uint8Array:Array)(this.l+(this.b-32768)),f,g,h,k;if(0===a.length)return s?this.c.subarray(32768,this.b):this.c.slice(32768,this.b);f=0;for(g=a.length;f<g;++f){b=a[f];h=0;for(k=b.length;h<k;++h)e[c++]=b[h]}f=32768;for(g=this.b;f<g;++f)e[c++]=d[f];this.g=[];return this.buffer=e};
+u.prototype.w=function(){var c,d=this.b;s?this.s?(c=new Uint8Array(d),c.set(this.c.subarray(0,d))):c=this.c.subarray(0,d):(this.c.length>d&&(this.c.length=d),c=this.c);return this.buffer=c};function U(c,d){var a,b;this.input=c;this.a=0;if(d||!(d={}))d.index&&(this.a=d.index),d.verify&&(this.B=d.verify);a=c[this.a++];b=c[this.a++];switch(a&15){case V:this.method=V;break;default:throw Error("unsupported compression method");}if(0!==((a<<8)+b)%31)throw Error("invalid fcheck flag:"+((a<<8)+b)%31);if(b&32)throw Error("fdict flag is not supported");this.r=new u(c,{index:this.a,bufferSize:d.bufferSize,bufferType:d.bufferType,resize:d.resize})}
+U.prototype.k=function(){var c=this.input,d,a;d=this.r.k();this.a=this.r.a;if(this.B){a=(c[this.a++]<<24|c[this.a++]<<16|c[this.a++]<<8|c[this.a++])>>>0;var b=d;if("string"===typeof b){var e=b.split(""),f,g;f=0;for(g=e.length;f<g;f++)e[f]=(e[f].charCodeAt(0)&255)>>>0;b=e}for(var h=1,k=0,l=b.length,p,n=0;0<l;){p=1024<l?1024:l;l-=p;do h+=b[n++],k+=h;while(--p);h%=65521;k%=65521}if(a!==(k<<16|h)>>>0)throw Error("invalid adler-32 checksum");}return d};var V=8;q("Zlib.Inflate",U);q("Zlib.Inflate.prototype.decompress",U.prototype.k);var W={ADAPTIVE:x.t,BLOCK:x.u},X,Y,Z,$;if(Object.keys)X=Object.keys(W);else for(Y in X=[],Z=0,W)X[Z++]=Y;Z=0;for($=X.length;Z<$;++Z)Y=X[Z],q("Zlib.Inflate.BufferType."+Y,W[Y]);}).call(this);

+ 51 - 0
examples/js/libs/zlib_and_gzip.min.js

@@ -0,0 +1,51 @@
+/** @license zlib.js 2012 - imaya [ https://github.com/imaya/zlib.js ] The MIT License */(function() {'use strict';function q(b){throw b;}var t=void 0,u=!0,aa=this;function A(b,a){var c=b.split("."),d=aa;!(c[0]in d)&&d.execScript&&d.execScript("var "+c[0]);for(var e;c.length&&(e=c.shift());)!c.length&&a!==t?d[e]=a:d=d[e]?d[e]:d[e]={}};var B="undefined"!==typeof Uint8Array&&"undefined"!==typeof Uint16Array&&"undefined"!==typeof Uint32Array&&"undefined"!==typeof DataView;function F(b,a){this.index="number"===typeof a?a:0;this.m=0;this.buffer=b instanceof(B?Uint8Array:Array)?b:new (B?Uint8Array:Array)(32768);2*this.buffer.length<=this.index&&q(Error("invalid index"));this.buffer.length<=this.index&&this.f()}F.prototype.f=function(){var b=this.buffer,a,c=b.length,d=new (B?Uint8Array:Array)(c<<1);if(B)d.set(b);else for(a=0;a<c;++a)d[a]=b[a];return this.buffer=d};
+F.prototype.d=function(b,a,c){var d=this.buffer,e=this.index,f=this.m,g=d[e],k;c&&1<a&&(b=8<a?(H[b&255]<<24|H[b>>>8&255]<<16|H[b>>>16&255]<<8|H[b>>>24&255])>>32-a:H[b]>>8-a);if(8>a+f)g=g<<a|b,f+=a;else for(k=0;k<a;++k)g=g<<1|b>>a-k-1&1,8===++f&&(f=0,d[e++]=H[g],g=0,e===d.length&&(d=this.f()));d[e]=g;this.buffer=d;this.m=f;this.index=e};F.prototype.finish=function(){var b=this.buffer,a=this.index,c;0<this.m&&(b[a]<<=8-this.m,b[a]=H[b[a]],a++);B?c=b.subarray(0,a):(b.length=a,c=b);return c};
+var ba=new (B?Uint8Array:Array)(256),ca;for(ca=0;256>ca;++ca){for(var K=ca,da=K,ea=7,K=K>>>1;K;K>>>=1)da<<=1,da|=K&1,--ea;ba[ca]=(da<<ea&255)>>>0}var H=ba;function ja(b,a,c){var d,e="number"===typeof a?a:a=0,f="number"===typeof c?c:b.length;d=-1;for(e=f&7;e--;++a)d=d>>>8^O[(d^b[a])&255];for(e=f>>3;e--;a+=8)d=d>>>8^O[(d^b[a])&255],d=d>>>8^O[(d^b[a+1])&255],d=d>>>8^O[(d^b[a+2])&255],d=d>>>8^O[(d^b[a+3])&255],d=d>>>8^O[(d^b[a+4])&255],d=d>>>8^O[(d^b[a+5])&255],d=d>>>8^O[(d^b[a+6])&255],d=d>>>8^O[(d^b[a+7])&255];return(d^4294967295)>>>0}
+var ka=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,
+2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,
+2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,
+2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,
+3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,
+936918E3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117],O=B?new Uint32Array(ka):ka;function P(){}P.prototype.getName=function(){return this.name};P.prototype.getData=function(){return this.data};P.prototype.Y=function(){return this.Z};A("Zlib.GunzipMember",P);A("Zlib.GunzipMember.prototype.getName",P.prototype.getName);A("Zlib.GunzipMember.prototype.getData",P.prototype.getData);A("Zlib.GunzipMember.prototype.getMtime",P.prototype.Y);function la(b){this.buffer=new (B?Uint16Array:Array)(2*b);this.length=0}la.prototype.getParent=function(b){return 2*((b-2)/4|0)};la.prototype.push=function(b,a){var c,d,e=this.buffer,f;c=this.length;e[this.length++]=a;for(e[this.length++]=b;0<c;)if(d=this.getParent(c),e[c]>e[d])f=e[c],e[c]=e[d],e[d]=f,f=e[c+1],e[c+1]=e[d+1],e[d+1]=f,c=d;else break;return this.length};
+la.prototype.pop=function(){var b,a,c=this.buffer,d,e,f;a=c[0];b=c[1];this.length-=2;c[0]=c[this.length];c[1]=c[this.length+1];for(f=0;;){e=2*f+2;if(e>=this.length)break;e+2<this.length&&c[e+2]>c[e]&&(e+=2);if(c[e]>c[f])d=c[f],c[f]=c[e],c[e]=d,d=c[f+1],c[f+1]=c[e+1],c[e+1]=d;else break;f=e}return{index:b,value:a,length:this.length}};function ma(b){var a=b.length,c=0,d=Number.POSITIVE_INFINITY,e,f,g,k,h,l,s,p,m,n;for(p=0;p<a;++p)b[p]>c&&(c=b[p]),b[p]<d&&(d=b[p]);e=1<<c;f=new (B?Uint32Array:Array)(e);g=1;k=0;for(h=2;g<=c;){for(p=0;p<a;++p)if(b[p]===g){l=0;s=k;for(m=0;m<g;++m)l=l<<1|s&1,s>>=1;n=g<<16|p;for(m=l;m<e;m+=h)f[m]=n;++k}++g;k<<=1;h<<=1}return[f,c,d]};function na(b,a){this.k=qa;this.I=0;this.input=B&&b instanceof Array?new Uint8Array(b):b;this.b=0;a&&(a.lazy&&(this.I=a.lazy),"number"===typeof a.compressionType&&(this.k=a.compressionType),a.outputBuffer&&(this.a=B&&a.outputBuffer instanceof Array?new Uint8Array(a.outputBuffer):a.outputBuffer),"number"===typeof a.outputIndex&&(this.b=a.outputIndex));this.a||(this.a=new (B?Uint8Array:Array)(32768))}var qa=2,ra={NONE:0,v:1,o:qa,ba:3},sa=[],S;
+for(S=0;288>S;S++)switch(u){case 143>=S:sa.push([S+48,8]);break;case 255>=S:sa.push([S-144+400,9]);break;case 279>=S:sa.push([S-256+0,7]);break;case 287>=S:sa.push([S-280+192,8]);break;default:q("invalid literal: "+S)}
+na.prototype.g=function(){var b,a,c,d,e=this.input;switch(this.k){case 0:c=0;for(d=e.length;c<d;){a=B?e.subarray(c,c+65535):e.slice(c,c+65535);c+=a.length;var f=a,g=c===d,k=t,h=t,l=t,s=t,p=t,m=this.a,n=this.b;if(B){for(m=new Uint8Array(this.a.buffer);m.length<=n+f.length+5;)m=new Uint8Array(m.length<<1);m.set(this.a)}k=g?1:0;m[n++]=k|0;h=f.length;l=~h+65536&65535;m[n++]=h&255;m[n++]=h>>>8&255;m[n++]=l&255;m[n++]=l>>>8&255;if(B)m.set(f,n),n+=f.length,m=m.subarray(0,n);else{s=0;for(p=f.length;s<p;++s)m[n++]=
+f[s];m.length=n}this.b=n;this.a=m}break;case 1:var r=new F(B?new Uint8Array(this.a.buffer):this.a,this.b);r.d(1,1,u);r.d(1,2,u);var v=ta(this,e),x,Q,y;x=0;for(Q=v.length;x<Q;x++)if(y=v[x],F.prototype.d.apply(r,sa[y]),256<y)r.d(v[++x],v[++x],u),r.d(v[++x],5),r.d(v[++x],v[++x],u);else if(256===y)break;this.a=r.finish();this.b=this.a.length;break;case qa:var E=new F(B?new Uint8Array(this.a.buffer):this.a,this.b),Ka,R,X,Y,Z,pb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],fa,La,ga,Ma,oa,wa=Array(19),
+Na,$,pa,C,Oa;Ka=qa;E.d(1,1,u);E.d(Ka,2,u);R=ta(this,e);fa=ua(this.W,15);La=va(fa);ga=ua(this.V,7);Ma=va(ga);for(X=286;257<X&&0===fa[X-1];X--);for(Y=30;1<Y&&0===ga[Y-1];Y--);var Pa=X,Qa=Y,J=new (B?Uint32Array:Array)(Pa+Qa),w,L,z,ha,I=new (B?Uint32Array:Array)(316),G,D,M=new (B?Uint8Array:Array)(19);for(w=L=0;w<Pa;w++)J[L++]=fa[w];for(w=0;w<Qa;w++)J[L++]=ga[w];if(!B){w=0;for(ha=M.length;w<ha;++w)M[w]=0}w=G=0;for(ha=J.length;w<ha;w+=L){for(L=1;w+L<ha&&J[w+L]===J[w];++L);z=L;if(0===J[w])if(3>z)for(;0<
+z--;)I[G++]=0,M[0]++;else for(;0<z;)D=138>z?z:138,D>z-3&&D<z&&(D=z-3),10>=D?(I[G++]=17,I[G++]=D-3,M[17]++):(I[G++]=18,I[G++]=D-11,M[18]++),z-=D;else if(I[G++]=J[w],M[J[w]]++,z--,3>z)for(;0<z--;)I[G++]=J[w],M[J[w]]++;else for(;0<z;)D=6>z?z:6,D>z-3&&D<z&&(D=z-3),I[G++]=16,I[G++]=D-3,M[16]++,z-=D}b=B?I.subarray(0,G):I.slice(0,G);oa=ua(M,7);for(C=0;19>C;C++)wa[C]=oa[pb[C]];for(Z=19;4<Z&&0===wa[Z-1];Z--);Na=va(oa);E.d(X-257,5,u);E.d(Y-1,5,u);E.d(Z-4,4,u);for(C=0;C<Z;C++)E.d(wa[C],3,u);C=0;for(Oa=b.length;C<
+Oa;C++)if($=b[C],E.d(Na[$],oa[$],u),16<=$){C++;switch($){case 16:pa=2;break;case 17:pa=3;break;case 18:pa=7;break;default:q("invalid code: "+$)}E.d(b[C],pa,u)}var Ra=[La,fa],Sa=[Ma,ga],N,Ta,ia,za,Ua,Va,Wa,Xa;Ua=Ra[0];Va=Ra[1];Wa=Sa[0];Xa=Sa[1];N=0;for(Ta=R.length;N<Ta;++N)if(ia=R[N],E.d(Ua[ia],Va[ia],u),256<ia)E.d(R[++N],R[++N],u),za=R[++N],E.d(Wa[za],Xa[za],u),E.d(R[++N],R[++N],u);else if(256===ia)break;this.a=E.finish();this.b=this.a.length;break;default:q("invalid compression type")}return this.a};
+function xa(b,a){this.length=b;this.Q=a}
+var ya=function(){function b(a){switch(u){case 3===a:return[257,a-3,0];case 4===a:return[258,a-4,0];case 5===a:return[259,a-5,0];case 6===a:return[260,a-6,0];case 7===a:return[261,a-7,0];case 8===a:return[262,a-8,0];case 9===a:return[263,a-9,0];case 10===a:return[264,a-10,0];case 12>=a:return[265,a-11,1];case 14>=a:return[266,a-13,1];case 16>=a:return[267,a-15,1];case 18>=a:return[268,a-17,1];case 22>=a:return[269,a-19,2];case 26>=a:return[270,a-23,2];case 30>=a:return[271,a-27,2];case 34>=a:return[272,
+a-31,2];case 42>=a:return[273,a-35,3];case 50>=a:return[274,a-43,3];case 58>=a:return[275,a-51,3];case 66>=a:return[276,a-59,3];case 82>=a:return[277,a-67,4];case 98>=a:return[278,a-83,4];case 114>=a:return[279,a-99,4];case 130>=a:return[280,a-115,4];case 162>=a:return[281,a-131,5];case 194>=a:return[282,a-163,5];case 226>=a:return[283,a-195,5];case 257>=a:return[284,a-227,5];case 258===a:return[285,a-258,0];default:q("invalid length: "+a)}}var a=[],c,d;for(c=3;258>=c;c++)d=b(c),a[c]=d[2]<<24|d[1]<<
+16|d[0];return a}(),Aa=B?new Uint32Array(ya):ya;
+function ta(b,a){function c(a,c){var b=a.Q,d=[],e=0,f;f=Aa[a.length];d[e++]=f&65535;d[e++]=f>>16&255;d[e++]=f>>24;var g;switch(u){case 1===b:g=[0,b-1,0];break;case 2===b:g=[1,b-2,0];break;case 3===b:g=[2,b-3,0];break;case 4===b:g=[3,b-4,0];break;case 6>=b:g=[4,b-5,1];break;case 8>=b:g=[5,b-7,1];break;case 12>=b:g=[6,b-9,2];break;case 16>=b:g=[7,b-13,2];break;case 24>=b:g=[8,b-17,3];break;case 32>=b:g=[9,b-25,3];break;case 48>=b:g=[10,b-33,4];break;case 64>=b:g=[11,b-49,4];break;case 96>=b:g=[12,b-
+65,5];break;case 128>=b:g=[13,b-97,5];break;case 192>=b:g=[14,b-129,6];break;case 256>=b:g=[15,b-193,6];break;case 384>=b:g=[16,b-257,7];break;case 512>=b:g=[17,b-385,7];break;case 768>=b:g=[18,b-513,8];break;case 1024>=b:g=[19,b-769,8];break;case 1536>=b:g=[20,b-1025,9];break;case 2048>=b:g=[21,b-1537,9];break;case 3072>=b:g=[22,b-2049,10];break;case 4096>=b:g=[23,b-3073,10];break;case 6144>=b:g=[24,b-4097,11];break;case 8192>=b:g=[25,b-6145,11];break;case 12288>=b:g=[26,b-8193,12];break;case 16384>=
+b:g=[27,b-12289,12];break;case 24576>=b:g=[28,b-16385,13];break;case 32768>=b:g=[29,b-24577,13];break;default:q("invalid distance")}f=g;d[e++]=f[0];d[e++]=f[1];d[e++]=f[2];var h,k;h=0;for(k=d.length;h<k;++h)m[n++]=d[h];v[d[0]]++;x[d[3]]++;r=a.length+c-1;p=null}var d,e,f,g,k,h={},l,s,p,m=B?new Uint16Array(2*a.length):[],n=0,r=0,v=new (B?Uint32Array:Array)(286),x=new (B?Uint32Array:Array)(30),Q=b.I,y;if(!B){for(f=0;285>=f;)v[f++]=0;for(f=0;29>=f;)x[f++]=0}v[256]=1;d=0;for(e=a.length;d<e;++d){f=k=0;
+for(g=3;f<g&&d+f!==e;++f)k=k<<8|a[d+f];h[k]===t&&(h[k]=[]);l=h[k];if(!(0<r--)){for(;0<l.length&&32768<d-l[0];)l.shift();if(d+3>=e){p&&c(p,-1);f=0;for(g=e-d;f<g;++f)y=a[d+f],m[n++]=y,++v[y];break}0<l.length?(s=Ba(a,d,l),p?p.length<s.length?(y=a[d-1],m[n++]=y,++v[y],c(s,0)):c(p,-1):s.length<Q?p=s:c(s,0)):p?c(p,-1):(y=a[d],m[n++]=y,++v[y])}l.push(d)}m[n++]=256;v[256]++;b.W=v;b.V=x;return B?m.subarray(0,n):m}
+function Ba(b,a,c){var d,e,f=0,g,k,h,l,s=b.length;k=0;l=c.length;a:for(;k<l;k++){d=c[l-k-1];g=3;if(3<f){for(h=f;3<h;h--)if(b[d+h-1]!==b[a+h-1])continue a;g=f}for(;258>g&&a+g<s&&b[d+g]===b[a+g];)++g;g>f&&(e=d,f=g);if(258===g)break}return new xa(f,a-e)}
+function ua(b,a){var c=b.length,d=new la(572),e=new (B?Uint8Array:Array)(c),f,g,k,h,l;if(!B)for(h=0;h<c;h++)e[h]=0;for(h=0;h<c;++h)0<b[h]&&d.push(h,b[h]);f=Array(d.length/2);g=new (B?Uint32Array:Array)(d.length/2);if(1===f.length)return e[d.pop().index]=1,e;h=0;for(l=d.length/2;h<l;++h)f[h]=d.pop(),g[h]=f[h].value;k=Ca(g,g.length,a);h=0;for(l=f.length;h<l;++h)e[f[h].index]=k[h];return e}
+function Ca(b,a,c){function d(b){var c=h[b][l[b]];c===a?(d(b+1),d(b+1)):--g[c];++l[b]}var e=new (B?Uint16Array:Array)(c),f=new (B?Uint8Array:Array)(c),g=new (B?Uint8Array:Array)(a),k=Array(c),h=Array(c),l=Array(c),s=(1<<c)-a,p=1<<c-1,m,n,r,v,x;e[c-1]=a;for(n=0;n<c;++n)s<p?f[n]=0:(f[n]=1,s-=p),s<<=1,e[c-2-n]=(e[c-1-n]/2|0)+a;e[0]=f[0];k[0]=Array(e[0]);h[0]=Array(e[0]);for(n=1;n<c;++n)e[n]>2*e[n-1]+f[n]&&(e[n]=2*e[n-1]+f[n]),k[n]=Array(e[n]),h[n]=Array(e[n]);for(m=0;m<a;++m)g[m]=c;for(r=0;r<e[c-1];++r)k[c-
+1][r]=b[r],h[c-1][r]=r;for(m=0;m<c;++m)l[m]=0;1===f[c-1]&&(--g[0],++l[c-1]);for(n=c-2;0<=n;--n){v=m=0;x=l[n+1];for(r=0;r<e[n];r++)v=k[n+1][x]+k[n+1][x+1],v>b[m]?(k[n][r]=v,h[n][r]=a,x+=2):(k[n][r]=b[m],h[n][r]=m,++m);l[n]=0;1===f[n]&&d(n)}return g}
+function va(b){var a=new (B?Uint16Array:Array)(b.length),c=[],d=[],e=0,f,g,k,h;f=0;for(g=b.length;f<g;f++)c[b[f]]=(c[b[f]]|0)+1;f=1;for(g=16;f<=g;f++)d[f]=e,e+=c[f]|0,e<<=1;f=0;for(g=b.length;f<g;f++){e=d[b[f]];d[b[f]]+=1;k=a[f]=0;for(h=b[f];k<h;k++)a[f]=a[f]<<1|e&1,e>>>=1}return a};function Da(b,a){this.input=b;this.b=this.c=0;this.i={};a&&(a.flags&&(this.i=a.flags),"string"===typeof a.filename&&(this.filename=a.filename),"string"===typeof a.comment&&(this.A=a.comment),a.deflateOptions&&(this.l=a.deflateOptions));this.l||(this.l={})}
+Da.prototype.g=function(){var b,a,c,d,e,f,g,k,h=new (B?Uint8Array:Array)(32768),l=0,s=this.input,p=this.c,m=this.filename,n=this.A;h[l++]=31;h[l++]=139;h[l++]=8;b=0;this.i.fname&&(b|=Ea);this.i.fcomment&&(b|=Fa);this.i.fhcrc&&(b|=Ga);h[l++]=b;a=(Date.now?Date.now():+new Date)/1E3|0;h[l++]=a&255;h[l++]=a>>>8&255;h[l++]=a>>>16&255;h[l++]=a>>>24&255;h[l++]=0;h[l++]=Ha;if(this.i.fname!==t){g=0;for(k=m.length;g<k;++g)f=m.charCodeAt(g),255<f&&(h[l++]=f>>>8&255),h[l++]=f&255;h[l++]=0}if(this.i.comment){g=
+0;for(k=n.length;g<k;++g)f=n.charCodeAt(g),255<f&&(h[l++]=f>>>8&255),h[l++]=f&255;h[l++]=0}this.i.fhcrc&&(c=ja(h,0,l)&65535,h[l++]=c&255,h[l++]=c>>>8&255);this.l.outputBuffer=h;this.l.outputIndex=l;e=new na(s,this.l);h=e.g();l=e.b;B&&(l+8>h.buffer.byteLength?(this.a=new Uint8Array(l+8),this.a.set(new Uint8Array(h.buffer)),h=this.a):h=new Uint8Array(h.buffer));d=ja(s,t,t);h[l++]=d&255;h[l++]=d>>>8&255;h[l++]=d>>>16&255;h[l++]=d>>>24&255;k=s.length;h[l++]=k&255;h[l++]=k>>>8&255;h[l++]=k>>>16&255;h[l++]=
+k>>>24&255;this.c=p;B&&l<h.length&&(this.a=h=h.subarray(0,l));return h};var Ha=255,Ga=2,Ea=8,Fa=16;A("Zlib.Gzip",Da);A("Zlib.Gzip.prototype.compress",Da.prototype.g);function T(b,a){this.p=[];this.q=32768;this.e=this.j=this.c=this.u=0;this.input=B?new Uint8Array(b):b;this.w=!1;this.r=Ia;this.M=!1;if(a||!(a={}))a.index&&(this.c=a.index),a.bufferSize&&(this.q=a.bufferSize),a.bufferType&&(this.r=a.bufferType),a.resize&&(this.M=a.resize);switch(this.r){case Ja:this.b=32768;this.a=new (B?Uint8Array:Array)(32768+this.q+258);break;case Ia:this.b=0;this.a=new (B?Uint8Array:Array)(this.q);this.f=this.U;this.B=this.R;this.s=this.T;break;default:q(Error("invalid inflate mode"))}}
+var Ja=0,Ia=1,Ya={O:Ja,N:Ia};
+T.prototype.h=function(){for(;!this.w;){var b=U(this,3);b&1&&(this.w=u);b>>>=1;switch(b){case 0:var a=this.input,c=this.c,d=this.a,e=this.b,f=a.length,g=t,k=t,h=d.length,l=t;this.e=this.j=0;c+1>=f&&q(Error("invalid uncompressed block header: LEN"));g=a[c++]|a[c++]<<8;c+1>=f&&q(Error("invalid uncompressed block header: NLEN"));k=a[c++]|a[c++]<<8;g===~k&&q(Error("invalid uncompressed block header: length verify"));c+g>a.length&&q(Error("input buffer is broken"));switch(this.r){case Ja:for(;e+g>d.length;){l=
+h-e;g-=l;if(B)d.set(a.subarray(c,c+l),e),e+=l,c+=l;else for(;l--;)d[e++]=a[c++];this.b=e;d=this.f();e=this.b}break;case Ia:for(;e+g>d.length;)d=this.f({F:2});break;default:q(Error("invalid inflate mode"))}if(B)d.set(a.subarray(c,c+g),e),e+=g,c+=g;else for(;g--;)d[e++]=a[c++];this.c=c;this.b=e;this.a=d;break;case 1:this.s(Za,$a);break;case 2:ab(this);break;default:q(Error("unknown BTYPE: "+b))}}return this.B()};
+var bb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],cb=B?new Uint16Array(bb):bb,db=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,258,258],eb=B?new Uint16Array(db):db,fb=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0],gb=B?new Uint8Array(fb):fb,hb=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],ib=B?new Uint16Array(hb):hb,jb=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,
+10,11,11,12,12,13,13],kb=B?new Uint8Array(jb):jb,lb=new (B?Uint8Array:Array)(288),V,mb;V=0;for(mb=lb.length;V<mb;++V)lb[V]=143>=V?8:255>=V?9:279>=V?7:8;var Za=ma(lb),nb=new (B?Uint8Array:Array)(30),ob,qb;ob=0;for(qb=nb.length;ob<qb;++ob)nb[ob]=5;var $a=ma(nb);function U(b,a){for(var c=b.j,d=b.e,e=b.input,f=b.c,g=e.length,k;d<a;)f>=g&&q(Error("input buffer is broken")),c|=e[f++]<<d,d+=8;k=c&(1<<a)-1;b.j=c>>>a;b.e=d-a;b.c=f;return k}
+function rb(b,a){for(var c=b.j,d=b.e,e=b.input,f=b.c,g=e.length,k=a[0],h=a[1],l,s;d<h&&!(f>=g);)c|=e[f++]<<d,d+=8;l=k[c&(1<<h)-1];s=l>>>16;b.j=c>>s;b.e=d-s;b.c=f;return l&65535}
+function ab(b){function a(a,b,c){var d,e=this.J,f,g;for(g=0;g<a;)switch(d=rb(this,b),d){case 16:for(f=3+U(this,2);f--;)c[g++]=e;break;case 17:for(f=3+U(this,3);f--;)c[g++]=0;e=0;break;case 18:for(f=11+U(this,7);f--;)c[g++]=0;e=0;break;default:e=c[g++]=d}this.J=e;return c}var c=U(b,5)+257,d=U(b,5)+1,e=U(b,4)+4,f=new (B?Uint8Array:Array)(cb.length),g,k,h,l;for(l=0;l<e;++l)f[cb[l]]=U(b,3);if(!B){l=e;for(e=f.length;l<e;++l)f[cb[l]]=0}g=ma(f);k=new (B?Uint8Array:Array)(c);h=new (B?Uint8Array:Array)(d);
+b.J=0;b.s(ma(a.call(b,c,g,k)),ma(a.call(b,d,g,h)))}T.prototype.s=function(b,a){var c=this.a,d=this.b;this.C=b;for(var e=c.length-258,f,g,k,h;256!==(f=rb(this,b));)if(256>f)d>=e&&(this.b=d,c=this.f(),d=this.b),c[d++]=f;else{g=f-257;h=eb[g];0<gb[g]&&(h+=U(this,gb[g]));f=rb(this,a);k=ib[f];0<kb[f]&&(k+=U(this,kb[f]));d>=e&&(this.b=d,c=this.f(),d=this.b);for(;h--;)c[d]=c[d++-k]}for(;8<=this.e;)this.e-=8,this.c--;this.b=d};
+T.prototype.T=function(b,a){var c=this.a,d=this.b;this.C=b;for(var e=c.length,f,g,k,h;256!==(f=rb(this,b));)if(256>f)d>=e&&(c=this.f(),e=c.length),c[d++]=f;else{g=f-257;h=eb[g];0<gb[g]&&(h+=U(this,gb[g]));f=rb(this,a);k=ib[f];0<kb[f]&&(k+=U(this,kb[f]));d+h>e&&(c=this.f(),e=c.length);for(;h--;)c[d]=c[d++-k]}for(;8<=this.e;)this.e-=8,this.c--;this.b=d};
+T.prototype.f=function(){var b=new (B?Uint8Array:Array)(this.b-32768),a=this.b-32768,c,d,e=this.a;if(B)b.set(e.subarray(32768,b.length));else{c=0;for(d=b.length;c<d;++c)b[c]=e[c+32768]}this.p.push(b);this.u+=b.length;if(B)e.set(e.subarray(a,a+32768));else for(c=0;32768>c;++c)e[c]=e[a+c];this.b=32768;return e};
+T.prototype.U=function(b){var a,c=this.input.length/this.c+1|0,d,e,f,g=this.input,k=this.a;b&&("number"===typeof b.F&&(c=b.F),"number"===typeof b.P&&(c+=b.P));2>c?(d=(g.length-this.c)/this.C[2],f=258*(d/2)|0,e=f<k.length?k.length+f:k.length<<1):e=k.length*c;B?(a=new Uint8Array(e),a.set(k)):a=k;return this.a=a};
+T.prototype.B=function(){var b=0,a=this.a,c=this.p,d,e=new (B?Uint8Array:Array)(this.u+(this.b-32768)),f,g,k,h;if(0===c.length)return B?this.a.subarray(32768,this.b):this.a.slice(32768,this.b);f=0;for(g=c.length;f<g;++f){d=c[f];k=0;for(h=d.length;k<h;++k)e[b++]=d[k]}f=32768;for(g=this.b;f<g;++f)e[b++]=a[f];this.p=[];return this.buffer=e};
+T.prototype.R=function(){var b,a=this.b;B?this.M?(b=new Uint8Array(a),b.set(this.a.subarray(0,a))):b=this.a.subarray(0,a):(this.a.length>a&&(this.a.length=a),b=this.a);return this.buffer=b};function sb(b){this.input=b;this.c=0;this.t=[];this.D=!1}sb.prototype.X=function(){this.D||this.h();return this.t.slice()};
+sb.prototype.h=function(){for(var b=this.input.length;this.c<b;){var a=new P,c=t,d=t,e=t,f=t,g=t,k=t,h=t,l=t,s=t,p=this.input,m=this.c;a.G=p[m++];a.H=p[m++];(31!==a.G||139!==a.H)&&q(Error("invalid file signature:"+a.G+","+a.H));a.z=p[m++];switch(a.z){case 8:break;default:q(Error("unknown compression method: "+a.z))}a.n=p[m++];l=p[m++]|p[m++]<<8|p[m++]<<16|p[m++]<<24;a.Z=new Date(1E3*l);a.fa=p[m++];a.ea=p[m++];0<(a.n&4)&&(a.aa=p[m++]|p[m++]<<8,m+=a.aa);if(0<(a.n&Ea)){h=[];for(k=0;0<(g=p[m++]);)h[k++]=
+String.fromCharCode(g);a.name=h.join("")}if(0<(a.n&Fa)){h=[];for(k=0;0<(g=p[m++]);)h[k++]=String.fromCharCode(g);a.A=h.join("")}0<(a.n&Ga)&&(a.S=ja(p,0,m)&65535,a.S!==(p[m++]|p[m++]<<8)&&q(Error("invalid header crc16")));c=p[p.length-4]|p[p.length-3]<<8|p[p.length-2]<<16|p[p.length-1]<<24;p.length-m-4-4<512*c&&(f=c);d=new T(p,{index:m,bufferSize:f});a.data=e=d.h();m=d.c;a.ca=s=(p[m++]|p[m++]<<8|p[m++]<<16|p[m++]<<24)>>>0;ja(e,t,t)!==s&&q(Error("invalid CRC-32 checksum: 0x"+ja(e,t,t).toString(16)+
+" / 0x"+s.toString(16)));a.da=c=(p[m++]|p[m++]<<8|p[m++]<<16|p[m++]<<24)>>>0;(e.length&4294967295)!==c&&q(Error("invalid input size: "+(e.length&4294967295)+" / "+c));this.t.push(a);this.c=m}this.D=u;var n=this.t,r,v,x=0,Q=0,y;r=0;for(v=n.length;r<v;++r)Q+=n[r].data.length;if(B){y=new Uint8Array(Q);for(r=0;r<v;++r)y.set(n[r].data,x),x+=n[r].data.length}else{y=[];for(r=0;r<v;++r)y[r]=n[r].data;y=Array.prototype.concat.apply([],y)}return y};A("Zlib.Gunzip",sb);A("Zlib.Gunzip.prototype.decompress",sb.prototype.h);A("Zlib.Gunzip.prototype.getMembers",sb.prototype.X);function tb(b){if("string"===typeof b){var a=b.split(""),c,d;c=0;for(d=a.length;c<d;c++)a[c]=(a[c].charCodeAt(0)&255)>>>0;b=a}for(var e=1,f=0,g=b.length,k,h=0;0<g;){k=1024<g?1024:g;g-=k;do e+=b[h++],f+=e;while(--k);e%=65521;f%=65521}return(f<<16|e)>>>0};function ub(b,a){var c,d;this.input=b;this.c=0;if(a||!(a={}))a.index&&(this.c=a.index),a.verify&&(this.$=a.verify);c=b[this.c++];d=b[this.c++];switch(c&15){case vb:this.method=vb;break;default:q(Error("unsupported compression method"))}0!==((c<<8)+d)%31&&q(Error("invalid fcheck flag:"+((c<<8)+d)%31));d&32&&q(Error("fdict flag is not supported"));this.L=new T(b,{index:this.c,bufferSize:a.bufferSize,bufferType:a.bufferType,resize:a.resize})}
+ub.prototype.h=function(){var b=this.input,a,c;a=this.L.h();this.c=this.L.c;this.$&&(c=(b[this.c++]<<24|b[this.c++]<<16|b[this.c++]<<8|b[this.c++])>>>0,c!==tb(a)&&q(Error("invalid adler-32 checksum")));return a};var vb=8;function wb(b,a){this.input=b;this.a=new (B?Uint8Array:Array)(32768);this.k=W.o;var c={},d;if((a||!(a={}))&&"number"===typeof a.compressionType)this.k=a.compressionType;for(d in a)c[d]=a[d];c.outputBuffer=this.a;this.K=new na(this.input,c)}var W=ra;
+wb.prototype.g=function(){var b,a,c,d,e,f,g,k=0;g=this.a;b=vb;switch(b){case vb:a=Math.LOG2E*Math.log(32768)-8;break;default:q(Error("invalid compression method"))}c=a<<4|b;g[k++]=c;switch(b){case vb:switch(this.k){case W.NONE:e=0;break;case W.v:e=1;break;case W.o:e=2;break;default:q(Error("unsupported compression type"))}break;default:q(Error("invalid compression method"))}d=e<<6|0;g[k++]=d|31-(256*c+d)%31;f=tb(this.input);this.K.b=k;g=this.K.g();k=g.length;B&&(g=new Uint8Array(g.buffer),g.length<=
+k+4&&(this.a=new Uint8Array(g.length+4),this.a.set(g),g=this.a),g=g.subarray(0,k+4));g[k++]=f>>24&255;g[k++]=f>>16&255;g[k++]=f>>8&255;g[k++]=f&255;return g};function xb(b,a){var c,d,e,f;if(Object.keys)c=Object.keys(a);else for(d in c=[],e=0,a)c[e++]=d;e=0;for(f=c.length;e<f;++e)d=c[e],A(b+"."+d,a[d])};A("Zlib.Inflate",ub);A("Zlib.Inflate.prototype.decompress",ub.prototype.h);xb("Zlib.Inflate.BufferType",{ADAPTIVE:Ya.N,BLOCK:Ya.O});A("Zlib.Deflate",wb);A("Zlib.Deflate.compress",function(b,a){return(new wb(b,a)).g()});A("Zlib.Deflate.prototype.compress",wb.prototype.g);xb("Zlib.Deflate.CompressionType",{NONE:W.NONE,FIXED:W.v,DYNAMIC:W.o});}).call(this); //@ sourceMappingURL=zlib_and_gzip.min.js.map

File diff suppressed because it is too large
+ 4 - 0
examples/js/libs/zlib_and_gzip.min.js.map


+ 99 - 6
examples/js/loaders/ColladaLoader2.js

@@ -420,7 +420,87 @@ THREE.ColladaLoader.prototype = {
 						break;
 
 					case 'texture':
-						data[ child.nodeName ] = child.getAttribute( 'texture' );
+						data[ child.nodeName ] = { id: child.getAttribute( 'texture' ), extra: parseEffectParameterTexture( child ) };
+						break;
+
+				}
+
+			}
+
+			return data;
+
+		}
+
+		function parseEffectParameterTexture( xml ) {
+
+			var data = {};
+
+			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
+
+				var child = xml.childNodes[ i ];
+
+				if ( child.nodeType !== 1 ) continue;
+
+				switch ( child.nodeName ) {
+
+					case 'extra':
+						data = parseEffectParameterTextureExtra( child );
+						break;
+
+				}
+
+			}
+
+			return data;
+
+		}
+
+		function parseEffectParameterTextureExtra( xml ) {
+
+			var data = {};
+
+			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
+
+				var child = xml.childNodes[ i ];
+
+				if ( child.nodeType !== 1 ) continue;
+
+				switch ( child.nodeName ) {
+
+					case 'technique':
+						data[ child.nodeName ] = parseEffectParameterTextureExtraTechnique( child );
+						break;
+
+				}
+
+			}
+
+			return data;
+
+		}
+
+		function parseEffectParameterTextureExtraTechnique( xml ) {
+
+			var data = {};
+
+			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
+
+				var child = xml.childNodes[ i ];
+
+				if ( child.nodeType !== 1 ) continue;
+
+				switch ( child.nodeName ) {
+
+					case 'repeatU':
+					case 'repeatV':
+					case 'offsetU':
+					case 'offsetV':
+						data[ child.nodeName ] = parseFloat( child.textContent );
+						break;
+
+					case 'wrapU':
+					case 'wrapV':
+						data[ child.nodeName ] = parseInt( child.textContent );
 						break;
 
 				}
@@ -497,24 +577,37 @@ THREE.ColladaLoader.prototype = {
 
 			material.name = data.name;
 
-			function getTexture( sid ) {
+			function getTexture( textureObject ) {
 
-				var sampler = effect.profile.samplers[ sid ];
+				var sampler = effect.profile.samplers[ textureObject.id ];
 
 				if ( sampler !== undefined ) {
 
 					var surface = effect.profile.surfaces[ sampler.source ];
 
 					var texture = new THREE.Texture( getImage( surface.init_from ) );
-					texture.wrapS = THREE.RepeatWrapping;
-					texture.wrapT = THREE.RepeatWrapping;
+
+					var extra = textureObject.extra;
+
+					if ( extra !== undefined && extra.technique !== undefined ) {
+
+						var technique = extra.technique;
+
+						texture.wrapS = technique.wrapU ? THREE.RepeatWrapping : THREE.ClampToEdgeWrapping;
+						texture.wrapT = technique.wrapV ? THREE.RepeatWrapping : THREE.ClampToEdgeWrapping;
+
+						texture.offset.set( technique.offsetU, technique.offsetV );
+						texture.repeat.set( technique.repeatU, technique.repeatV );
+
+					}
+
 					texture.needsUpdate = true;
 
 					return texture;
 
 				}
 
-				console.error( 'ColladaLoder: Undefined sampler', sid );
+				console.error( 'ColladaLoder: Undefined sampler', textureObject.id );
 
 				return null;
 

+ 83 - 0
examples/js/loaders/HDRCubeTextureLoader.js

@@ -0,0 +1,83 @@
+/**
+* @author Prashant Sharma / spidersharma03
+* @author Ben Houston / http://clara.io / bhouston
+*/
+
+THREE.HDRCubeTextureLoader = function (manager) {
+  this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
+  // override in sub classes
+  this.hdrLoader = new THREE.RGBELoader();
+
+  if( THREE.Encodings === undefined ) throw new Error( "HDRCubeMapLoader requires THREE.Encodings" );
+}
+
+THREE.HDRCubeTextureLoader.prototype.load = function(type, urls, onLoad, onProgress, onError) {
+  var texture = new THREE.CubeTexture();
+
+  texture.type = type;
+  texture.encoding = (type === THREE.UnsignedByteType) ? THREE.RGBEEncoding : THREE.LinearEncoding;
+  texture.format = (type === THREE.UnsignedByteType ) ? THREE.RGBAFormat : THREE.RGBFormat;
+  texture.minFilter = (texture.encoding === THREE.RGBEEncoding ) ? THREE.NearestFilter : THREE.LinearFilter;
+  texture.magFilter = (texture.encoding === THREE.RGBEEncoding ) ? THREE.NearestFilter : THREE.LinearFilter;
+  texture.generateMipmaps = (texture.encoding !== THREE.RGBEEncoding );
+  texture.anisotropy = 0;
+
+  var scope = this.hdrLoader;
+
+  var loaded = 0;
+
+  function loadHDRData(i, onLoad, onProgress, onError) {
+    var loader = new THREE.XHRLoader( this.manager );
+    loader.setResponseType( 'arraybuffer' );
+
+    loader.load( urls[i], function ( buffer ) {
+      loaded++;
+
+      var texData = scope._parser( buffer );
+
+      if ( ! texData ) return;
+
+      if(type === THREE.FloatType) {
+        var numElements = ( texData.data.length / 4 )*3;
+        var floatdata = new Float32Array( numElements );
+        for( var j=0; j<numElements; j++) {
+          THREE.Encodings.RGBEByteToRGBFloat( texData.data, j*4, floatdata, j*3 );
+        }
+        texData.data = floatdata;
+      }
+      else if(type === THREE.HalfFloatType) {
+        var numElements = ( texData.data.length / 4 )*3;
+        var halfdata = new Uint16Array( numElements );
+        for( var j=0; j<numElements; j++) {
+          THREE.Encodings.RGBEByteToRGBHalf( texData.data, j*4, halfdata, j*3 );
+        }
+        texData.data = halfdata;
+      }
+
+      if ( undefined !== texData.image ) {
+        texture[i].images = texData.image;
+      }
+      else if ( undefined !== texData.data ) {
+        var dataTexture = new THREE.DataTexture(texData.data, texData.width, texData.height);
+        dataTexture.format = texture.format;
+        dataTexture.type = texture.type;
+        dataTexture.encoding = texture.encoding;
+        dataTexture.minFilter = texture.minFilter;
+        dataTexture.magFilter = texture.magFilter;
+        dataTexture.generateMipmaps = texture.generateMipmaps;
+
+        texture.images[i] = dataTexture;
+      }
+
+      if(loaded === 6) {
+        texture.needsUpdate = true;
+        if ( onLoad ) onLoad( texture );
+      }
+    }, onProgress, onError );
+  }
+
+  for(var i=0; i<urls.length; i++) {
+    loadHDRData(i, onLoad, onProgress, onError);
+  }
+  return texture;
+};

+ 0 - 2
examples/js/loaders/MMDLoader.js

@@ -3634,7 +3634,6 @@ THREE.ShaderLib[ 'mmd' ] = {
 		THREE.UniformsLib[ "normalmap" ],
 		THREE.UniformsLib[ "displacementmap" ],
 		THREE.UniformsLib[ "fog" ],
-		THREE.UniformsLib[ "ambient" ],
 		THREE.UniformsLib[ "lights" ],
 
 		{
@@ -3755,7 +3754,6 @@ THREE.ShaderLib[ 'mmd' ] = {
 		THREE.ShaderChunk[ "envmap_pars_fragment" ],
 		THREE.ShaderChunk[ "fog_pars_fragment" ],
 		THREE.ShaderChunk[ "bsdfs" ],
-		THREE.ShaderChunk[ "ambient_pars" ],
 		THREE.ShaderChunk[ "lights_pars" ],
 		THREE.ShaderChunk[ "lights_phong_pars_fragment" ],
 		THREE.ShaderChunk[ "shadowmap_pars_fragment" ],

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

@@ -303,9 +303,7 @@ THREE.MTLLoader.MaterialCreator.prototype = {
 
 			var value = mat[ prop ];
 
-			if ( value === '' ) {
-				continue;
-			}
+			if ( value === '' ) continue;
 
 			switch ( prop.toLowerCase() ) {
 

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