Sfoglia il codice sorgente

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

gogoend 6 anni fa
parent
commit
d237adea33
100 ha cambiato i file con 4668 aggiunte e 2602 eliminazioni
  1. 2 2
      README.md
  2. 596 502
      build/three.js
  3. 123 273
      build/three.min.js
  4. 282 242
      build/three.module.js
  5. 3 3
      docs/api/en/cameras/OrthographicCamera.html
  6. 3 2
      docs/api/en/cameras/PerspectiveCamera.html
  7. 1 1
      docs/api/en/core/BufferGeometry.html
  8. 2 2
      docs/api/en/core/Clock.html
  9. 4 2
      docs/api/en/core/Geometry.html
  10. 6 2
      docs/api/en/core/Object3D.html
  11. 6 6
      docs/api/en/helpers/BoxHelper.html
  12. 3 2
      docs/api/en/lights/Light.html
  13. 2 2
      docs/api/en/materials/Material.html
  14. 22 2
      docs/api/en/math/Box3.html
  15. 1 0
      docs/api/en/math/Matrix4.html
  16. 7 4
      docs/api/en/renderers/WebGLRenderer.html
  17. 3 2
      docs/api/en/scenes/Scene.html
  18. 2 2
      docs/api/en/textures/Texture.html
  19. 2 2
      docs/api/zh/core/Clock.html
  20. 1 1
      docs/examples/controls/OrbitControls.html
  21. 7 0
      docs/examples/renderers/SVGRenderer.html
  22. 0 20
      docs/examples/utils/SceneUtils.html
  23. 53 11
      docs/index.html
  24. 1 1
      docs/manual/en/introduction/Drawing-lines.html
  25. 160 2
      docs/manual/en/introduction/Import-via-modules.html
  26. 1 4
      docs/manual/en/introduction/Useful-links.html
  27. 96 38
      docs/page.css
  28. 2 2
      docs/prettify/threejs.css
  29. 2 0
      editor/index.html
  30. 145 0
      editor/js/Sidebar.Geometry.ExtrudeGeometry.js
  31. 3 84
      editor/js/Sidebar.Geometry.LatheGeometry.js
  32. 55 0
      editor/js/Sidebar.Geometry.ShapeGeometry.js
  33. 2 83
      editor/js/Sidebar.Geometry.TubeGeometry.js
  34. 18 1
      editor/js/Sidebar.Project.js
  35. 13 0
      editor/js/Strings.js
  36. 256 0
      editor/js/libs/ui.three.js
  37. 5 4
      editor/manifest.json
  38. 2 2
      examples/css3d_panorama_deviceorientation.html
  39. 2 1
      examples/files.js
  40. 61 24
      examples/index.html
  41. 0 71
      examples/js/ImprovedNoise.js
  42. 0 324
      examples/js/SimplexNoise.js
  43. 2 2
      examples/js/cameras/CinematicCamera.js
  44. 251 150
      examples/js/controls/TransformControls.js
  45. 8 8
      examples/js/curves/NURBSUtils.js
  46. 6 0
      examples/js/effects/AsciiEffect.js
  47. 11 14
      examples/js/effects/OutlineEffect.js
  48. 6 1
      examples/js/exporters/GLTFExporter.js
  49. 3 3
      examples/js/geometries/LightningStrike.js
  50. 0 64
      examples/js/geometries/hilbert2D.js
  51. 0 84
      examples/js/geometries/hilbert3D.js
  52. 43 0
      examples/js/libs/basis/README.md
  53. 0 0
      examples/js/libs/basis/basis_transcoder.js
  54. BIN
      examples/js/libs/basis/basis_transcoder.wasm
  55. 362 47
      examples/js/loaders/3MFLoader.js
  56. 3 1
      examples/js/loaders/AssimpLoader.js
  57. 402 0
      examples/js/loaders/BasisTextureLoader.js
  58. 53 0
      examples/js/loaders/ColladaLoader.js
  59. 26 17
      examples/js/loaders/EXRLoader.js
  60. 127 122
      examples/js/loaders/GCodeLoader.js
  61. 4 2
      examples/js/loaders/GLTFLoader.js
  62. 3 3
      examples/js/loaders/KTXLoader.js
  63. 587 125
      examples/js/loaders/LDrawLoader.js
  64. 3 1
      examples/js/loaders/MTLLoader.js
  65. 2 5
      examples/js/loaders/RGBELoader.js
  66. 169 82
      examples/js/loaders/SVGLoader.js
  67. 15 3
      examples/js/loaders/VTKLoader.js
  68. 72 0
      examples/js/math/ImprovedNoise.js
  69. 0 15
      examples/js/math/Lut.js
  70. 405 0
      examples/js/math/SimplexNoise.js
  71. 0 5
      examples/js/objects/Reflector.js
  72. 4 0
      examples/js/objects/ReflectorRTT.js
  73. 19 29
      examples/js/objects/Refractor.js
  74. 10 10
      examples/js/objects/ShadowMesh.js
  75. 2 2
      examples/js/postprocessing/AdaptiveToneMappingPass.js
  76. 4 6
      examples/js/postprocessing/BokehPass.js
  77. 1 1
      examples/js/postprocessing/ClearPass.js
  78. 1 1
      examples/js/postprocessing/CubeTexturePass.js
  79. 1 1
      examples/js/postprocessing/DotScreenPass.js
  80. 2 2
      examples/js/postprocessing/EffectComposer.js
  81. 1 1
      examples/js/postprocessing/FilmPass.js
  82. 1 1
      examples/js/postprocessing/GlitchPass.js
  83. 1 1
      examples/js/postprocessing/HalftonePass.js
  84. 2 2
      examples/js/postprocessing/MaskPass.js
  85. 1 1
      examples/js/postprocessing/RenderPass.js
  86. 2 2
      examples/js/postprocessing/SAOPass.js
  87. 19 14
      examples/js/postprocessing/SMAAPass.js
  88. 2 2
      examples/js/postprocessing/SSAOPass.js
  89. 2 1
      examples/js/postprocessing/ShaderPass.js
  90. 2 2
      examples/js/postprocessing/TAARenderPass.js
  91. 2 1
      examples/js/postprocessing/TexturePass.js
  92. 2 1
      examples/js/postprocessing/UnrealBloomPass.js
  93. 28 0
      examples/js/renderers/SVGRenderer.js
  94. 1 1
      examples/js/shaders/BleachBypassShader.js
  95. 2 2
      examples/js/shaders/BlendShader.js
  96. 11 11
      examples/js/shaders/BokehShader.js
  97. 21 21
      examples/js/shaders/BokehShader2.js
  98. 2 2
      examples/js/shaders/BrightnessContrastShader.js
  99. 3 3
      examples/js/shaders/ColorCorrectionShader.js
  100. 1 1
      examples/js/shaders/ColorifyShader.js

+ 2 - 2
README.md

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

File diff suppressed because it is too large
+ 596 - 502
build/three.js


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


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


+ 3 - 3
docs/api/en/cameras/OrthographicCamera.html

@@ -130,12 +130,12 @@ scene.add( camera );</code>
 		Updates the camera projection matrix. Must be called after any change of parameters.
 		</p>
 
-		<h3>[method:JSON toJSON]()</h3>
+		<h3>[method:Object toJSON](param:object meta])</h3>
 		<p>
-		Return the camera's data in JSON format.
+		meta -- object containing metadata such as textures or images in objects' descendants.<br />
+		Convert the camera to three.js [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene format].
 		</p>
 
-
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 3 - 2
docs/api/en/cameras/PerspectiveCamera.html

@@ -190,9 +190,10 @@ camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
 		Updates the camera projection matrix. Must be called after any change of parameters.
 		</p>
 
-		<h3>[method:JSON toJSON]()</h3>
+		<h3>[method:Object toJSON](param:object meta])</h3>
 		<p>
-		Return camera data in JSON format.
+		meta -- object containing metadata such as textures or images in objects' descendants.<br />
+		Convert the camera to three.js [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene format].
 		</p>
 
 		<h2>Source</h2>

+ 1 - 1
docs/api/en/core/BufferGeometry.html

@@ -327,7 +327,7 @@
 		<p>Sets the attributes for this BufferGeometry from an array of points.</p>
 
 		<h3>[method:Object toJSON]()</h3>
-		<p>Returns a JSON object representation of the BufferGeometry.</p>
+		<p>Convert the buffer geometry to three.js [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene format].</p>
 
 		<h3>[method:BufferGeometry toNonIndexed]()</h3>
 		<p>Return a non-index version of an indexed BufferGeometry.</p>

+ 2 - 2
docs/api/en/core/Clock.html

@@ -11,8 +11,8 @@
 		<h1>[name]</h1>
 
 		<p class="desc">
-		Object for keeping track of time. This uses <a href="https://developer.mozilla.org/en-US/docs/Web/API/Performance/now">performance.now()</a>
-		if it is available, otherwise it reverts to the less accurate <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date/now">Date.now()</a>.
+		Object for keeping track of time. This uses [link:https://developer.mozilla.org/en-US/docs/Web/API/Performance/now performance.now]
+		if it is available, otherwise it reverts to the less accurate [link:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date/now Date.now].
 		</p>
 
 

+ 4 - 2
docs/api/en/core/Geometry.html

@@ -327,8 +327,10 @@
 		Use [page:Object3D.scale] for typical real-time mesh scaling.
 		</p>
 
-		<h3>[method:JSON toJSON] ( )</h3>
-		<p>Convert the geometry to JSON format.</p>
+		<h3>[method:Object toJSON] ( )</h3>
+		<p>Convert the geometry to JSON format.<br />
+		Convert the geometry to three.js [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene format].
+		</p>
 
 		<h3>[method:Geometry translate] ( [param:Float x], [param:Float y], [param:Float z] )</h3>
 		<p>

+ 6 - 2
docs/api/en/core/Object3D.html

@@ -217,6 +217,9 @@
 		<h3>[method:this applyQuaternion]( [param:Quaternion quaternion] )</h3>
 		<p>Applies the rotation represented by the quaternion to the object.</p>
 
+		<h3>[method:this attach]( [param:Object3D object] )</h3>
+		<p>Adds *object* as a child of this, while maintaining the object's world transform.</p>
+
 		<h3>[method:Object3D clone]( [param:Boolean recursive] )</h3>
 		<p>
 		recursive -- if true, descendants of the object are also cloned. Default is true.<br /><br />
@@ -389,9 +392,10 @@
 			Copy the given quaternion into [page:.quaternion].
 		</p>
 
-		<h3>[method:null toJSON]( [param:Quaternion q] )</h3>
+		<h3>[method:Object toJSON]( [param:object meta] )</h3>
 		<p>
-			Convert the object to JSON format.
+		meta -- object containing metadata such as materials, textures or images for the object.<br />
+		Convert the object to three.js [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene format].
 		</p>
 
 		<h3>[method:this translateOnAxis]( [param:Vector3 axis], [param:Float distance] )</h3>

+ 6 - 6
docs/api/en/helpers/BoxHelper.html

@@ -13,8 +13,8 @@
 		<h1>[name]</h1>
 
 		<p class="desc">
-			Helper object to show the world-axis-aligned bounding box around an object.
-
+			Helper object to graphically show the world-axis-aligned bounding box around an object. The actual bounding box is handled with [page:Box3], this is just a visual helper for debugging.
+			It can be automatically resized with the [page:BoxHelper.update] method when the object it's created from is transformed.
 			Note that the object must have a [page:Geometry] or [page:BufferGeometry] for this to work,
 			so it won't work with [page:Sprite Sprites].
 		</p>
@@ -28,10 +28,10 @@
 
 
 		<code>
-		var sphere = new THREE.SphereGeometry();
-		var object = new THREE.Mesh( sphere, new THREE.MeshBasicMaterial( 0xff0000 ) );
-		var box = new THREE.BoxHelper( object, 0xffff00 );
-		scene.add( box );
+			var sphere = new THREE.SphereGeometry();
+			var object = new THREE.Mesh( sphere, new THREE.MeshBasicMaterial( 0xff0000 ) );
+			var box = new THREE.BoxHelper( object, 0xffff00 );
+			scene.add( box );
 		</code>
 
 

+ 3 - 2
docs/api/en/lights/Light.html

@@ -67,9 +67,10 @@
 		[page:Light source] light into this one.
 		</p>
 
-		<h3>[method:JSON toJSON]( [param:String meta] )</h3>
+		<h3>[method:Object toJSON]( [param:object meta] )</h3>
 		<p>
-		Return Light data in JSON format.
+		meta -- object containing metadata such as materials, textures for objects.<br />
+		Convert the light to three.js [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene format].
 		</p>
 
 		<h2>Source</h2>

+ 2 - 2
docs/api/en/materials/Material.html

@@ -307,10 +307,10 @@
 		Sets the properties based on the *values*.
 		</p>
 
-		<h3>[method:null toJSON]( [param:object meta] )</h3>
+		<h3>[method:Object toJSON]( [param:object meta] )</h3>
 		<p>
 		meta -- object containing metadata such as textures or images for the material.<br />
-		Convert the material to three.js JSON format.
+		Convert the material to three.js [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene format].
 		</p>
 
 		<h2>Source</h2>

+ 22 - 2
docs/api/en/math/Box3.html

@@ -12,11 +12,31 @@
 
 		<p class="desc">
 			Represents a box or cube in 3D space. The main purpose of this is to represent
-			the [link:https://en.wikipedia.org/wiki/Minimum_bounding_box Minimum Bounding Boxes]
-			for objects.
+			the world-axis-aligned bounding boxes for objects. 
 		</p>
 
+		
+		<h2>Example</h2>
 
+		<code>
+		// Creating the object whose bounding box we want to compute
+		var sphereObject = new THREE.Mesh( 
+			new THREE.SphereGeometry(), 
+			new THREE.MeshBasicMaterial( 0xff0000 ) 
+		);
+		// Creating the actual bounding box with Box3
+		sphereObject.geometry.computeBoundingBox();
+		var box = sphereObject.geometry.boundingBox.clone();
+
+		// ...
+		
+		// In the animation loop, to keep the bounding box updated after move/rotate/scale operations
+		sphereObject.updateMatrixWorld( true );
+		box.copy( sphereObject.geometry.boundingBox ).applyMatrix4( sphereObject.matrixWorld );
+		</code>
+
+
+		
 		<h2>Constructor</h2>
 
 

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

@@ -375,6 +375,7 @@ x, y, 1, 0,
 		</p>
 
 		<h3>[method:this setPosition]( [param:Vector3 v] )</h3>
+		<h3>[method:this setPosition]( [param:Float x], [param:Float y], [param:Float z] ) // optional API</h3>
 		<p>
 			Sets the position component for this matrix from vector [page:Vector3 v], without affecting the
 			rest of the matrix - i.e. if the matrix is currently:

+ 7 - 4
docs/api/en/renderers/WebGLRenderer.html

@@ -55,7 +55,10 @@
 
 		[page:String powerPreference] - Provides a hint to the user agent indicating what configuration
 		of GPU is suitable for this WebGL context. Can be *"high-performance"*, *"low-power"* or *"default"*. Default is *"default"*.
-		See the [link:https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.2 WebGL spec] for more information.<br />
+		See [link:https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.12 WebGL spec] for details.<br />
+
+		[page:Boolean failIfMajorPerformanceCaveat] - whether the renderer creation will fail upon low perfomance is detected. Default is *false*.
+		See [link:https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.12 WebGL spec] for details.<br />
 
 		[page:Boolean depth] - whether the drawing buffer has a
 		[link:https://en.wikipedia.org/wiki/Z-buffering depth buffer] of at least 16 bits.
@@ -394,11 +397,11 @@
 		<h3>[method:null resetGLState]( )</h3>
 		<p>Reset the GL state to default. Called internally if the WebGL context is lost.</p>
 
-		<h3>[method:null readRenderTargetPixels]( [param:WebGLRenderTarget renderTarget], [param:Float x], [param:Float y], [param:Float width], [param:Float height], [param:TypedArray buffer] )</h3>
+		<h3>[method:null readRenderTargetPixels]( [param:WebGLRenderTarget renderTarget], [param:Float x], [param:Float y], [param:Float width], [param:Float height], [param:TypedArray buffer], [param:Integer activeCubeFaceIndex] )</h3>
 		<p>buffer - Uint8Array is the only destination type supported in all cases, other types are renderTarget and platform dependent. See [link:https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.12 WebGL spec] for details.</p>
 		<p>Reads the pixel data from the renderTarget into the buffer you pass in. This is a wrapper around [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/readPixels WebGLRenderingContext.readPixels]().</p>
-		<p>See the [example:webgl_interactive_cubes_gpu interactive / cubes / gpu] example.
-		</p>
+		<p>See the [example:webgl_interactive_cubes_gpu interactive / cubes / gpu] example.</p>
+		<p>For reading out a [page:WebGLRenderTargetCube WebGLRenderTargetCube] use the optional parameter activeCubeFaceIndex to determine which face should be read.</p>
 
 
 		<h3>[method:null render]( [param:Scene scene], [param:Camera camera] )</h3>

+ 3 - 2
docs/api/en/scenes/Scene.html

@@ -46,9 +46,10 @@
 
 		<h2>Methods</h2>
 
-		<h3>[method:JSON toJSON]</h3>
+		<h3>[method:Object toJSON]</h3>
 		<p>
-		Return the scene data in JSON format.
+		meta -- object containing metadata such as textures or images for the scene.<br />
+		Convert the scene to three.js [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene format].
 		</p>
 
 		<h3>[method:null dispose]()</h3>

+ 2 - 2
docs/api/en/textures/Texture.html

@@ -251,10 +251,10 @@
 		Make copy of the texture. Note this is not a "deep copy", the image is shared.
 		</p>
 
-		<h3>[method:Texture toJSON]( [param:Object meta] )</h3>
+		<h3>[method:Object toJSON]( [param:Object meta] )</h3>
 		<p>
 		meta -- optional object containing metadata.<br />
-		Convert the material to three.js JSON format.
+		Convert the texture to three.js [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene format].
 		</p>
 
 		<h3>[method:null dispose]()</h3>

+ 2 - 2
docs/api/zh/core/Clock.html

@@ -10,8 +10,8 @@
 	<body>
 		<h1>[name]</h1>
 		<p class="desc">
-			该对象用于跟踪时间。如果<a href="https://developer.mozilla.org/en-US/docs/Web/API/Performance/now">performance.now()</a>可用,则
-			Clock 对象通过该方法实现,否则通过歉精准的<a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date/now">Date.now()</a>实现。
+			该对象用于跟踪时间。如果[link:https://developer.mozilla.org/en-US/docs/Web/API/Performance/now performance.now]可用,则
+			Clock 对象通过该方法实现,否则通过歉精准的[link:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date/now Date.now]实现。
 		</p>
 
 

+ 1 - 1
docs/examples/controls/OrbitControls.html

@@ -54,7 +54,7 @@ function animate() {
 
 		<h3>[name]( [param:Camera object], [param:HTMLDOMElement domElement] )</h3>
 		<p>
-			[page:Camera object]: (required) The camera to be controlled.<br><br>
+			[page:Camera object]: (required) The camera to be controlled. The camera must not be a child of another object, unless that object is the scene itself.<br><br>
 
 			[page:HTMLDOMElement domElement]: (optional) The HTML element used for event listeners. By default this is the whole document,
 			however if you only want the controls to work over a specific element (e.g. the canvas) you can specify that here.

+ 7 - 0
docs/examples/renderers/SVGRenderer.html

@@ -61,6 +61,13 @@
 
 		<h3>[name]()</h3>
 
+		<h2>Properties</h2>
+
+		<h3>[property:Number overdraw]</h3>
+		<p>
+		Number of fractional pixels to enlarge polygons in order to prevent anti-aliasing gaps. Range is [0..1]. Default is *0.5*.
+		</p>
+
 		<h2>Methods</h2>
 
 		<h3>[method:null clear]()</h3>

+ 0 - 20
docs/examples/utils/SceneUtils.html

@@ -26,26 +26,6 @@
 		This is mostly useful for objects that need both a material and a wireframe implementation.
 		</p>
 
-		<h3>[method:null attach]( [param:Object3D child], [param:Object3D scene], [param:Object3D parent] )</h3>
-		<p>
-		child -- The object to add to the parent  <br />
-		scene -- The scene to detach the object from. <br />
-		parent -- The parent to attach the object to.
-		</p>
-		<p>
-		Attaches the object to the parent without the moving the object in the worldspace. Beware that to do this the matrixWorld needs to be updated. This can be done by calling the updateMatrixWorld method on the parent object.
-		</p>
-
-		<h3>[method:null detach]( [param:Object3D child], [param:Object3D parent], [param:Object3D scene] )</h3>
-		<p>
-		child -- The object to remove from the parent  <br />
-		scene -- The scene to attach the object on. <br />
-		parent -- The parent to detach the object from.
-		</p>
-		<p>
-		Detaches the object from the parent and adds it back to the scene without moving in worldspace. Beware that to do this the matrixWorld needs to be updated. This can be done by calling the updateMatrixWorld method on the parent object.
-		</p>
-
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/utils/SceneUtils.js examples/js/utils/SceneUtils.js]

+ 53 - 11
docs/index.html

@@ -10,30 +10,33 @@
 		<script src="../build/three.min.js" async defer></script>
 	</head>
 	<body>
-
-		<div id="panel" class="collapsed">
+		<div id="panel" class="">
 
 			<div id="header">
-
 				<h1><a href="http://threejs.org">three.js</a></h1>
 
-				<img id="expandButton" src="../files/ic_menu_black_24dp.svg">
-
 				<div id="sections">
-					<span class="selected">docs</span> <a href="../examples/">examples</a>
+					<span class="selected">docs</span>
+					<a href="../examples/">examples</a>
 				</div>
 
-				<input type="text" id="filter" autocorrect="off" autocapitalize="off" spellcheck="false">
+				<img id="expandButton" src="../files/ic_menu_black_24dp.svg">
+			</div>
+
+			<div id="panelScrim"></div>
+
+			<div id="contentWrapper">
+				<input placeholder="Search" type="text" id="filter" autocorrect="off" autocapitalize="off" spellcheck="false" />
+				<div id="exitSearchButton"></div>
 
 				<select id="language">
 					<option value="en">en</option>
 					<option value="zh">zh</option>
 				</select>
 
+				<div id="content"></div>
 			</div>
 
-			<div id="content"></div>
-
 		</div>
 
 		<iframe name="viewer"></iframe>
@@ -89,6 +92,8 @@
 			var panel = document.getElementById( 'panel' );
 			var content = document.getElementById( 'content' );
 			var expandButton = document.getElementById( 'expandButton' );
+			var exitSearchButton = document.getElementById( 'exitSearchButton' );
+			var panelScrim = document.getElementById( 'panelScrim' );
 			var filterInput = document.getElementById( 'filter' );
 			var iframe = document.querySelector( 'iframe' );
 
@@ -104,12 +109,40 @@
 			expandButton.onclick = function ( event ) {
 
 				event.preventDefault();
-				panel.classList.toggle( 'collapsed' );
+				panel.classList.toggle( 'open' );
+
+			};
+
+			panelScrim.onclick = function ( event ) {
+
+				event.preventDefault();
+				panel.classList.toggle( 'open' );
 
 			};
 
 
 			// Functionality for search/filter input field
+			filterInput.onfocus = function ( event ) {
+
+				panel.classList.add('searchFocused');
+
+			}
+
+			filterInput.onblur = function ( event ) {
+
+				if(filterInput.value === '') {
+					panel.classList.remove('searchFocused');
+				}
+
+			}
+
+			exitSearchButton.onclick = function( event ) {
+
+				filterInput.value = '';
+				updateFilter();
+				panel.classList.remove('searchFocused');
+
+			}
 
 			filterInput.oninput = function ( event ) {
 
@@ -139,7 +172,16 @@
 					if ( event.button !== 0 || event.ctrlKey || event.altKey || event.metaKey ) return;
 
 					window.location.hash = pageURL;
-					panel.classList.add( 'collapsed' );
+					panel.classList.remove( 'open' );
+
+
+					content.querySelectorAll( 'a' ).forEach( function ( item ) {
+
+						item.classList.remove( 'selected' );
+
+					} );
+
+					link.classList.add('selected');
 
 				} );
 

+ 1 - 1
docs/manual/en/introduction/Drawing-lines.html

@@ -12,7 +12,7 @@
 		<div>
 			<p>
 				Let's say you want to draw a line or a circle, not a wireframe [page:Mesh].
-				First we need to setup the [page:WebGLRenderer renderer], [page:Scene scene] and camera (see the Creating a scene page).
+				First we need to set up the [page:WebGLRenderer renderer], [page:Scene scene] and camera (see the Creating a scene page).
 			</p>
 
 			<p>Here is the code that we will use:</p>

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

@@ -27,7 +27,7 @@
 
 		<h2>Importing the module</h2>
 
-		<p>Assuming that you're bundling your files with a tool such as [link:https://webpack.github.io/ Webpack] or [link:https://github.com/substack/node-browserify Browserify], which allow you to "require('modules') in the browser by bundling up all of your dependencies."</p>
+		<p>Assuming that you're bundling your files with a tool such as [link:https://webpack.github.io/ Webpack] or [link:https://github.com/substack/node-browserify Browserify], which allow you to "require('modules')" in the browser by bundling up all of your dependencies.</p>
 
 		<p>
 			You should now be able to import the module into your source files and continue to use it as per normal.
@@ -76,11 +76,41 @@
 		<p>
 			The following examples files are already available as modules:
 			<ul>
+				<li>cameras
+					<ul>
+						<li>CinematicCamera</li>
+					</ul>
+				</li>
 				<li>controls
 					<ul>
+						<li>DeviceOrientationControls</li>
+						<li>DragControls</li>
+						<li>EditorControls</li>
+						<li>FirstPersonControls</li>
+						<li>FlyControls</li>
 						<li>MapControls</li>
 						<li>OrbitControls</li>
+						<li>OrthographicTrackballControls</li>
+						<li>PointerLockControls</li>
 						<li>TrackballControls</li>
+						<li>TransformControls</li>
+					</ul>
+				</li>
+				<li>curves
+					<ul>
+						<li>NURBSCurve</li>
+						<li>NURBSSurface</li>
+						<li>NURBSUtils</li>
+					</ul>
+				</li>
+				<li>effects
+					<ul>
+						<li>AnaglyphEffect</li>
+						<li>AsciiEffect</li>
+						<li>OutlineEffect</li>
+						<li>ParallaxBarrierEffect</li>
+						<li>PeppersGhostEffect</li>
+						<li>StereoEffect</li>
 					</ul>
 				</li>
 				<li>exporters
@@ -96,10 +126,51 @@
 				</li>
 				<li>loaders
 					<ul>
+						<li>3MFLoader</li>
+						<li>AMFLoader</li>
+						<li>AssimpJSONLoader</li>
+						<li>AssimpLoader</li>
+						<li>BabylonLoader</li>
+						<li>BVHLoader</li>
+						<li>ColladaLoader</li>
+						<li>DDSLoader</li>
+						<li>EXRLoader</li>
+						<li>FBXLoader</li>
+						<li>GCodeLoader</li>
 						<li>GLTFLoader</li>
+						<li>KMZLoader</li>
+						<li>KTXLoader</li>
 						<li>MTLLoader</li>
 						<li>OBJLoader</li>
+						<li>PCDLoader</li>
+						<li>PDBLoader</li>
+						<li>PlayCanvasLoader</li>
+						<li>PLYLoader</li>
+						<li>RGBELoader</li>
 						<li>STLLoader</li>
+						<li>SVGLoader</li>
+						<li>TGALoader</li>
+						<li>VRMLLoader</li>
+					</ul>
+				</li>
+				<li>math
+					<ul>
+						<li>ColorConverter</li>
+						<li>ImprovedNoise</li>
+						<li>Lut</li>
+						<li>SimplexNoise</li>
+					</ul>
+				</li>
+				<li>objects
+					<ul>
+						<li>Lensflare</li>
+						<li>Reflector</li>
+						<li>Refractor</li>
+						<li>ReflectorRTT</li>
+						<li>ShadowMesh</li>
+						<li>Sky</li>
+						<li>Water</li>
+						<li>Water2</li>
 					</ul>
 				</li>
 				<li>pmrem
@@ -108,6 +179,93 @@
 						<li>PMREMGenerator</li>
 					</ul>
 				</li>
+				<li>postprocessing
+					<ul>
+						<li>AdaptiveToneMappingPass</li>
+						<li>AfterimagePass</li>
+						<li>BloomPass</li>
+						<li>BokehPass</li>
+						<li>ClearPass</li>
+						<li>CubeTexturePass</li>
+						<li>DotScreenPass</li>
+						<li>EffectComposer</li>
+						<li>FilmPass</li>
+						<li>GlitchPass</li>
+						<li>HalftonePass</li>
+						<li>MaskPass</li>
+						<li>OutlinePass</li>
+						<li>RenderPass</li>
+						<li>SAOPass</li>
+						<li>SavePass</li>
+						<li>ShaderPass</li>
+						<li>SMAAPass</li>
+						<li>SSAARenderPass</li>
+						<li>SSAOPass</li>
+						<li>TAARenderPass</li>
+						<li>TexturePass</li>
+						<li>UnrealBloomPass</li>
+					</ul>
+				</li>
+				<li>renderers
+					<ul>
+						<li>CSS2DRenderer</li>
+						<li>CSS3DRenderer</li>
+						<li>Projector</li>
+						<li>SoftwareRenderer</li>
+						<li>SVGRenderer</li>
+						<li>RaytracingRenderer</li>
+					</ul>
+				</li>
+				<li>shaders
+					<ul>
+						<li>AfterimageShader</li>
+						<li>BasicShader</li>
+						<li>BleachBypassShader</li>
+						<li>BlendShader</li>
+						<li>BokehShader</li>
+						<li>BokehShader2</li>
+						<li>BrightnessContrastShader</li>
+						<li>ColorCorrectionShader</li>
+						<li>ColorifyShader</li>
+						<li>ConvolutionShader</li>
+						<li>CopyShader</li>
+						<li>DepthLimitedBlurShader</li>
+						<li>DigitalGlitch</li>
+						<li>DOFMipMapShader</li>
+						<li>DotScreenShader</li>
+						<li>FilmShader</li>
+						<li>FocusShader</li>
+						<li>FreiChenShader</li>
+						<li>FresnelShader</li>
+						<li>FXAAShader</li>
+						<li>GammaCorrectionShader</li>
+						<li>HalftoneShader</li>
+						<li>HorizontalBlurShader</li>
+						<li>HorizontalTiltShiftShader</li>
+						<li>HueSaturationShader</li>
+						<li>KaleidoShader</li>
+						<li>LuminosityHighPassShader</li>
+						<li>LuminosityShader</li>
+						<li>MirrorShader</li>
+						<li>NormalMapShader</li>
+						<li>ParallaxShader</li>
+						<li>PixelShader</li>
+						<li>RGBShiftShader</li>
+						<li>SAOShader</li>
+						<li>SepiaShader</li>
+						<li>SMAAShader</li>
+						<li>SobelOperatorShader</li>
+						<li>SSAOShader</li>
+						<li>TechnicolorShader</li>
+						<li>ToneMapShader</li>
+						<li>TriangleBlurShader</li>
+						<li>UnpackDepthRGBAShader</li>
+						<li>VerticalBlurShader</li>
+						<li>VerticalTiltShiftShader</li>
+						<li>VignetteShader</li>
+						<li>WaterRefractionShader</li>
+					</ul>
+				</li>
 				<li>utils
 					<ul>
 						<li>BufferGeometryUtils</li>
@@ -124,7 +282,7 @@
 		</p>
 		<p>
 			Note: When using code from the examples directory, it's important that all files match the version of
-			your three.js main file. For example it's no good approach to use *GLTFLoader* and *OrbitControls* from R96 together
+			your three.js main file. For example, it's not acceptable to use *GLTFLoader* and *OrbitControls* from R96 together
 			with three.js R103. You can easily keep your files in sync by using the modules from the JSM directory. If the file
 			is not available as a module, you can still use third-party npm packages or convert the file to a module by yourself.
 			In both cases, ensure the code is compatible with your three.js main file.

+ 1 - 4
docs/manual/en/introduction/Useful-links.html

@@ -17,10 +17,7 @@
 
 			Note also that as three.js is under rapid development, a lot of these links will contain information that is
 			out of date - if something isn't working as you'd expect or as one of these links says it should,
-			check the browser console for warnings or errors, the relevant docs pages and especially the [page:DeprecatedList].<br /><br />
-
-			In addition to this page, mrdoob maintains a collection of links related to three.js over on Google+.
-			Check them out <a href="https://plus.google.com/+ThreejsOrg">here</a>.
+			check the browser console for warnings or errors, the relevant docs pages and especially the [page:DeprecatedList].
 		</p>
 
 		<h2>Help forums</h2>

+ 96 - 38
docs/page.css

@@ -1,6 +1,13 @@
+:root {
+	--color-blue: #049EF4;
+	--text-color: #444;
+	--border-style: 1px solid #EEE;
+	--header-height: 56px;
+}
+
 @font-face {
-	font-family: 'RobotoMono';
-	src: local('RobotoMono'), url('../files/RobotoMono-Regular.woff2') format('woff2');
+	font-family: 'Roboto Mono';
+	src: local('Roboto Mono'), url('../files/RobotoMono-Regular.woff2') format('woff2');
 	font-weight: normal;
 	font-style: normal;
 }
@@ -13,54 +20,86 @@
 }
 
 body {
-	margin: 78px auto;
-	padding: 0px 24px;
-	max-width: 780px;
-	color: #555;
+	padding: 20px 24px 40px 24px;
+	margin: 0;
+	color: var(--text-color);
 	font-family: 'SF-Pro-Text', sans-serif;
 	font-size: 16px;
-	line-height: 23px;
+	line-height: 24px;
 	tab-size: 4;
 	overflow: auto;
 }
 
 a {
-	color: #1184CE;
+	color: var(--color-blue);
 	cursor: pointer;
-	text-decoration: underline;
+	text-decoration: none;
 }
 
 h1 {
-	color: #049EF4;
-	font-size: 32px;
+	color: var(--color-blue);
+	font-size: 2.4em;
 	font-weight: normal;
-	line-height: 42px;
+	line-height: 1.36em;
+	margin-top: 16px;
+	margin-bottom: -16px;
+	text-indent: -2px;
 }
 
 h2 {
-	color: #4B0;
-
-	font-size: 22px;
+	color: var(--color-blue);
+	font-size: 1.8em;
+	line-height: 1.32em;
 	font-weight: normal;
-	line-height: 31px;
+	margin-top: 40px;
+	margin-bottom: 12px;
+	text-indent: -1px;
 }
 
 h3 {
-	color: #000;
-	font-size: 16px;
+	font-size: 1.32em;
+	line-height: 1.48em;
 	font-weight: normal;
+	text-indent: -1px;
+	margin-top: 24px;
+	margin-bottom: 12px;
+}
 
-	margin-top: 40px;
+p {
+	margin-top: 24px;
+	margin-bottom: 24px;
+}
+ul, ol {
+	box-sizing: border-box;
+	padding-left: 20px;
+}
+ul li,
+ol li {
+	padding-left: 4px;
+	margin-bottom: 4px;
 }
 
-p, ul, ol {
-	margin-top: 0;
+li ul,
+li ol {
+	margin-top: 4px;
+}
+
+body {
+	max-width: 760px;
+	margin-left: auto;
+	margin-right: auto;
+}
+
+table,
+pre,
+code:not(.inline) {
+	margin-left: -24px;
+	margin-right: -24px;
+	margin-top: 20px;
 	margin-bottom: 20px;
-	max-width: 780px;
 }
 
 div {
-	/* padding-left: 30px; */
 	margin-bottom: 20px;
 }
 
@@ -68,17 +107,37 @@ div {
 	padding-left: 0px;
 }
 
-pre, code {
-	margin-top: 20px;
-	margin-bottom: 20px;
+br {
+	display: none;
+}
+
+table {
+	border-spacing: 24px 4px;
+}
+table,
+table tr,
+table td {
+	text-align: left;
+}
+
+table th {
+	text-decoration: none;
+	padding: 2px 0;
 }
 
 code {
 	display: block;
-	padding: 20px;
+	padding: 20px 24px;
 	white-space: pre-wrap;
-	background-color: #f9f9f9;
 	overflow: auto;
+	box-sizing: border-box;
+}
+
+code.inline {
+	display: inline-block;
+	vertical-align: middle;
+	border-radius: 4px;
+	padding: 2px 5px;
 }
 
 iframe {
@@ -109,15 +168,15 @@ strong {
 
 #button {
 	position: fixed;
-	bottom: 16px;
-	right: 16px;
+	bottom: 12px;
+	right: 12px;
 
 	padding: 8px;
 	border-radius: 50%;
-	margin-bottom: 0px; /* TODO div sets it to 20px */
+	margin-bottom: 0px;
 
-	background-color: #dddddd;
-	opacity: 0.4;
+	background-color: #E5E5E5;
+	opacity: .9;
 }
 
 	#button:hover {
@@ -127,6 +186,7 @@ strong {
 
 	#button img {
 		display: block;
+		width: 20px;
 	}
 
 a.permalink {
@@ -157,19 +217,17 @@ sub {
 /* mobile */
 
 @media all and ( max-width: 640px ) {
-
 	body {
-		margin: 14px auto;
-		padding: 0px 14px;
-		font-size: 14px;
-		line-height: 22px;
+		padding: 16px 20px;
 	}
 
 	h1 {
+		margin-top: 0;
 		font-size: 26px;
 	}
 
 	h2 {
+		margin-top: 20px;
 		font-size: 18px;
 		line-height: 25px;
 	}

+ 2 - 2
docs/prettify/threejs.css

@@ -11,7 +11,7 @@ pre .dec, code .dec { color: #22c0c4; } /* decimal */
 
 pre.prettyprint, code.prettyprint {
 	background-color: #F5F5F5;
-	font-family: 'RobotoMono', monospace;
+	font-family: 'Roboto Mono', monospace;
 	font-size: 14px;
-	line-height: 21px;
+	line-height: 24px;
 }

+ 2 - 0
editor/index.html

@@ -126,11 +126,13 @@
 		<script src="js/Sidebar.Geometry.BoxGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.CircleGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.CylinderGeometry.js"></script>
+		<script src="js/Sidebar.Geometry.ExtrudeGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.IcosahedronGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.OctahedronGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.PlaneGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.RingGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.SphereGeometry.js"></script>
+		<script src="js/Sidebar.Geometry.ShapeGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.TetrahedronGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.TorusGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.TorusKnotGeometry.js"></script>

+ 145 - 0
editor/js/Sidebar.Geometry.ExtrudeGeometry.js

@@ -0,0 +1,145 @@
+/**
+ * @author Temdog007 / http://github.com/Temdog007
+ */
+
+Sidebar.Geometry.ExtrudeGeometry = function ( editor, object ) {
+
+	var strings = editor.strings;
+
+	var signals = editor.signals;
+
+	var container = new UI.Row();
+
+	var geometry = object.geometry;
+	var parameters = geometry.parameters;
+	var options = parameters.options;
+	options.curveSegments = options.curveSegments != undefined ? options.curveSegments : 12;
+	options.steps = options.steps != undefined ? options.steps : 1;
+	options.depth = options.depth != undefined ? options.depth : 100;
+	options.bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6;
+	options.bevelSize = options.bevelSize !== undefined ? options.bevelSize : 4;
+	options.bevelOffset = options.bevelOffset !== undefined ? options.bevelOffset : 0;
+	options.bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;
+
+
+	// curveSegments
+
+	var curveSegmentsRow = new UI.Row();
+	var curveSegments = new UI.Integer( options.curveSegments ).onChange( update ).setRange( 1, Infinity );
+
+	curveSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/extrude_geometry/curveSegments' ) ).setWidth( '90px' ) );
+	curveSegmentsRow.add( curveSegments );
+
+	container.add( curveSegmentsRow );
+
+	// steps
+
+	var stepsRow = new UI.Row();
+	var steps = new UI.Integer( options.steps ).onChange( update ).setRange( 1, Infinity );
+
+	stepsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/extrude_geometry/steps' ) ).setWidth( '90px' ) );
+	stepsRow.add( steps );
+
+	container.add( stepsRow );
+
+	// depth
+
+	var depthRow = new UI.Row();
+	var depth = new UI.Number( options.depth ).onChange( update ).setRange( 1, Infinity );
+
+	depthRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/extrude_geometry/depth' ) ).setWidth( '90px' ) );
+	depthRow.add( depth );
+
+	container.add( depthRow );
+
+	// enabled
+
+	var enabledRow = new UI.Row();
+	var enabled = new UI.Checkbox( options.bevelEnabled ).onChange( update );
+
+	enabledRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelEnabled' ) ).setWidth( '90px' ) );
+	enabledRow.add( enabled );
+
+	container.add( enabledRow );
+
+	if ( options.bevelEnabled === true ) {
+
+		// thickness
+
+		var thicknessRow = new UI.Row();
+		var thickness = new UI.Number( options.bevelThickness ).onChange( update );
+
+		thicknessRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelThickness' ) ).setWidth( '90px' ) );
+		thicknessRow.add( thickness );
+
+		container.add( thicknessRow );
+
+		// size
+
+		var sizeRow = new UI.Row();
+		var size = new UI.Number( options.bevelSize ).onChange( update );
+
+		sizeRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelSize' ) ).setWidth( '90px' ) );
+		sizeRow.add( size );
+
+		container.add( sizeRow );
+
+		// offset
+
+		var offsetRow = new UI.Row();
+		var offset = new UI.Number( options.bevelOffset ).onChange( update );
+
+		offsetRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelOffset' ) ).setWidth( '90px' ) );
+		offsetRow.add( offset );
+
+		container.add( offsetRow );
+
+		// segments
+
+		var segmentsRow = new UI.Row();
+		var segments = new UI.Integer( options.bevelSegments ).onChange( update ).setRange( 0, Infinity );
+
+		segmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelSegments' ) ).setWidth( '90px' ) );
+		segmentsRow.add( segments );
+
+		container.add( segmentsRow );
+
+	}
+
+	var button = new UI.Button( strings.getKey( 'sidebar/geometry/extrude_geometry/shape' ) ).onClick( toShape ).setWidth( '90px' ).setMarginLeft( '90px' );
+	container.add( button );
+
+	//
+
+	function update() {
+
+		editor.execute( new SetGeometryCommand( object, new THREE[ geometry.type ](
+			parameters.shapes,
+			{
+				curveSegments: curveSegments.getValue(),
+				steps: steps.getValue(),
+				depth: depth.getValue(),
+				bevelEnabled: enabled.getValue(),
+				bevelThickness: thickness !== undefined ? thickness.getValue() : options.bevelThickness,
+				bevelSize: size !== undefined ? size.getValue() : options.bevelSize,
+				bevelOffset: offset !== undefined ? offset.getValue() : options.bevelOffset,
+				bevelSegments: segments !== undefined ? segments.getValue() : options.bevelSegments
+			}
+		) ) );
+
+	}
+
+	function toShape() {
+
+		editor.execute( new SetGeometryCommand( object, new THREE.ShapeBufferGeometry(
+			parameters.shapes,
+			options.curveSegments
+		) ) );
+
+	}
+
+	return container;
+
+};
+
+Sidebar.Geometry.ExtrudeBufferGeometry = Sidebar.Geometry.ExtrudeGeometry;

+ 3 - 84
editor/js/Sidebar.Geometry.LatheGeometry.js

@@ -2,7 +2,7 @@
  * @author rfm1201
  */
 
-Sidebar.Geometry.LatheGeometry = function( editor, object ) {
+Sidebar.Geometry.LatheGeometry = function ( editor, object ) {
 
 	var strings = editor.strings;
 
@@ -45,99 +45,18 @@ Sidebar.Geometry.LatheGeometry = function( editor, object ) {
 
 	// points
 
-	var lastPointIdx = 0;
-	var pointsUI = [];
-
 	var pointsRow = new UI.Row();
 	pointsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/lathe_geometry/points' ) ).setWidth( '90px' ) );
 
-	var points = new UI.Span().setDisplay( 'inline-block' );
+	var points = new UI.Points2().setValue( parameters.points ).onChange( update );
 	pointsRow.add( points );
 
-	var pointsList = new UI.Div();
-	points.add( pointsList );
-
-	for ( var i = 0; i < parameters.points.length; i ++ ) {
-
-		var point = parameters.points[ i ];
-		pointsList.add( createPointRow( point.x, point.y ) );
-
-	}
-
-	var addPointButton = new UI.Button( '+' ).onClick( function() {
-
-		if( pointsUI.length === 0 ){
-
-			pointsList.add( createPointRow( 0, 0 ) );
-
-		} else {
-
-			var point = pointsUI[ pointsUI.length - 1 ];
-
-			pointsList.add( createPointRow( point.x.getValue(), point.y.getValue() ) );
-
-		}
-
-		update();
-
-	} );
-	points.add( addPointButton );
-
 	container.add( pointsRow );
 
-	//
-
-	function createPointRow( x, y ) {
-
-		var pointRow = new UI.Div();
-		var lbl = new UI.Text( lastPointIdx + 1 ).setWidth( '20px' );
-		var txtX = new UI.Number( x ).setRange( 0, Infinity ).setWidth( '40px' ).onChange( update );
-		var txtY = new UI.Number( y ).setWidth( '40px' ).onChange( update );
-		var idx = lastPointIdx;
-		var btn = new UI.Button( '-' ).onClick( function() {
-
-			deletePointRow( idx );
-
-		} );
-
-		pointsUI.push( { row: pointRow, lbl: lbl, x: txtX, y: txtY } );
-		lastPointIdx ++;
-		pointRow.add( lbl, txtX, txtY, btn );
-
-		return pointRow;
-
-	}
-
-	function deletePointRow( idx ) {
-
-		if ( ! pointsUI[ idx ] ) return;
-
-		pointsList.remove( pointsUI[ idx ].row );
-		pointsUI[ idx ] = null;
-
-		update();
-
-	}
-
 	function update() {
 
-		var points = [];
-		var count = 0;
-
-		for ( var i = 0; i < pointsUI.length; i ++ ) {
-
-			var pointUI = pointsUI[ i ];
-
-			if ( ! pointUI ) continue;
-
-			points.push( new THREE.Vector2( pointUI.x.getValue(), pointUI.y.getValue() ) );
-			count ++;
-			pointUI.lbl.setValue( count );
-
-		}
-
 		editor.execute( new SetGeometryCommand( object, new THREE[ geometry.type ](
-			points,
+			points.getValue(),
 			segments.getValue(),
 			phiStart.getValue() / 180 * Math.PI,
 			phiLength.getValue() / 180 * Math.PI

+ 55 - 0
editor/js/Sidebar.Geometry.ShapeGeometry.js

@@ -0,0 +1,55 @@
+/**
+ * @author Temdog007 / http://github.com/Temdog007
+ */
+
+Sidebar.Geometry.ShapeGeometry = function ( editor, object ) {
+
+	var strings = editor.strings;
+
+	var signals = editor.signals;
+
+	var container = new UI.Row();
+
+	var geometry = object.geometry;
+	var parameters = geometry.parameters;
+
+	// curveSegments
+
+	var curveSegmentsRow = new UI.Row();
+	var curveSegments = new UI.Integer( parameters.curveSegments || 12 ).onChange( changeShape ).setRange( 1, Infinity );
+
+	curveSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/shape_geometry/curveSegments' ) ).setWidth( '90px' ) );
+	curveSegmentsRow.add( curveSegments );
+
+	container.add( curveSegmentsRow );
+
+	// to extrude
+	var button = new UI.Button( strings.getKey( 'sidebar/geometry/shape_geometry/extrude' ) ).onClick( toExtrude ).setWidth( '90px' ).setMarginLeft( '90px' );
+	container.add( button );
+
+	//
+
+	function changeShape() {
+
+		editor.execute( new SetGeometryCommand( object, new THREE[ geometry.type ](
+			parameters.shapes,
+			curveSegments.getValue()
+		) ) );
+
+	}
+
+	function toExtrude() {
+
+		editor.execute( new SetGeometryCommand( object, new THREE.ExtrudeBufferGeometry(
+			parameters.shapes, {
+				curveSegments: curveSegments.getValue()
+			}
+		) ) );
+
+	}
+
+	return container;
+
+};
+
+Sidebar.Geometry.ShapeBufferGeometry = Sidebar.Geometry.ShapeGeometry;

+ 2 - 83
editor/js/Sidebar.Geometry.TubeGeometry.js

@@ -15,45 +15,12 @@ Sidebar.Geometry.TubeGeometry = function ( editor, object ) {
 
 	// points
 
-	var lastPointIdx = 0;
-	var pointsUI = [];
-
 	var pointsRow = new UI.Row();
 	pointsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tube_geometry/path' ) ).setWidth( '90px' ) );
 
-	var points = new UI.Span().setDisplay( 'inline-block' );
+	var points = new UI.Points3().setValue( parameters.path.points ).onChange( update );
 	pointsRow.add( points );
 
-	var pointsList = new UI.Div();
-	points.add( pointsList );
-
-	var parameterPoints = parameters.path.points;
-	for ( var i = 0; i < parameterPoints.length; i ++ ) {
-
-		var point = parameterPoints[ i ];
-		pointsList.add( createPointRow( point.x, point.y, point.z ) );
-
-	}
-
-	var addPointButton = new UI.Button( '+' ).onClick( function () {
-
-		if ( pointsUI.length === 0 ) {
-
-			pointsList.add( createPointRow( 0, 0, 0 ) );
-
-		} else {
-
-			var point = pointsUI[ pointsUI.length - 1 ];
-
-			pointsList.add( createPointRow( point.x.getValue(), point.y.getValue(), point.z.getValue() ) );
-
-		}
-
-		update();
-
-	} );
-	points.add( addPointButton );
-
 	container.add( pointsRow );
 
 	// radius
@@ -118,25 +85,10 @@ Sidebar.Geometry.TubeGeometry = function ( editor, object ) {
 
 	function update() {
 
-		var points = [];
-		var count = 0;
-
-		for ( var i = 0; i < pointsUI.length; i ++ ) {
-
-			var pointUI = pointsUI[ i ];
-
-			if ( ! pointUI ) continue;
-
-			points.push( new THREE.Vector3( pointUI.x.getValue(), pointUI.y.getValue(), pointUI.z.getValue() ) );
-			count ++;
-			pointUI.lbl.setValue( count );
-
-		}
-
 		tensionRow.setDisplay( curveType.getValue() == 'catmullrom' ? '' : 'none' );
 
 		editor.execute( new SetGeometryCommand( object, new THREE[ geometry.type ](
-			new THREE.CatmullRomCurve3( points, closed.getValue(), curveType.getValue(), tension.getValue() ),
+			new THREE.CatmullRomCurve3( points.getValue(), closed.getValue(), curveType.getValue(), tension.getValue() ),
 			tubularSegments.getValue(),
 			radius.getValue(),
 			radialSegments.getValue(),
@@ -145,39 +97,6 @@ Sidebar.Geometry.TubeGeometry = function ( editor, object ) {
 
 	}
 
-	function createPointRow( x, y, z ) {
-
-		var pointRow = new UI.Div();
-		var lbl = new UI.Text( lastPointIdx + 1 ).setWidth( '20px' );
-		var txtX = new UI.Number( x ).setWidth( '30px' ).onChange( update );
-		var txtY = new UI.Number( y ).setWidth( '30px' ).onChange( update );
-		var txtZ = new UI.Number( z ).setWidth( '30px' ).onChange( update );
-		var idx = lastPointIdx;
-		var btn = new UI.Button( '-' ).onClick( function () {
-
-			deletePointRow( idx );
-
-		} );
-
-		pointsUI.push( { row: pointRow, lbl: lbl, x: txtX, y: txtY, z: txtZ } );
-		lastPointIdx ++;
-		pointRow.add( lbl, txtX, txtY, txtZ, btn );
-
-		return pointRow;
-
-	}
-
-	function deletePointRow( idx ) {
-
-		if ( ! pointsUI[ idx ] ) return;
-
-		pointsList.remove( pointsUI[ idx ].row );
-		pointsUI[ idx ] = null;
-
-		update();
-
-	}
-
 	return container;
 
 };

+ 18 - 1
editor/js/Sidebar.Project.js

@@ -133,7 +133,24 @@ Sidebar.Project = function ( editor ) {
 
 		rendererPropertiesRow.setDisplay( type === 'WebGLRenderer' ? '' : 'none' );
 
-		var renderer = new rendererTypes[ type ]( { antialias: antialias } );
+		var parameters = {};
+
+		switch ( type ) {
+
+			case 'WebGLRenderer':
+				parameters.antialias = antialias;
+				break;
+
+			case 'RaytracingRenderer':
+				parameters.workers = navigator.hardwareConcurrency || 4;
+				parameters.workerPath = '../examples/js/renderers/RaytracingWorker.js';
+				parameters.randomize = true;
+				parameters.blockSize = 64;
+				break;
+
+		}
+
+		var renderer = new rendererTypes[ type ]( parameters );
 
 		if ( shadows && renderer.shadowMap ) {
 

+ 13 - 0
editor/js/Strings.js

@@ -135,6 +135,16 @@ var Strings = function ( config ) {
 			'sidebar/geometry/cylinder_geometry/heightsegments': 'Height segments',
 			'sidebar/geometry/cylinder_geometry/openended': 'Open ended',
 
+			'sidebar/geometry/extrude_geometry/curveSegments': 'Curve Segments',
+			'sidebar/geometry/extrude_geometry/steps': 'Steps',
+			'sidebar/geometry/extrude_geometry/depth': 'Depth',
+			'sidebar/geometry/extrude_geometry/bevelEnabled': 'Bevel?',
+			'sidebar/geometry/extrude_geometry/bevelThickness': 'Thickness',
+			'sidebar/geometry/extrude_geometry/bevelSize': 'Size',
+			'sidebar/geometry/extrude_geometry/bevelOffset': 'Offset',
+			'sidebar/geometry/extrude_geometry/bevelSegments': 'Segments',
+			'sidebar/geometry/extrude_geometry/shape': 'Convert to Shape',
+
 			'sidebar/geometry/geometry/vertices': 'Vertices',
 			'sidebar/geometry/geometry/faces': 'Faces',
 
@@ -164,6 +174,9 @@ var Strings = function ( config ) {
 			'sidebar/geometry/ring_geometry/thetastart': 'Theta start',
 			'sidebar/geometry/ring_geometry/thetalength': 'Theta length',
 
+			'sidebar/geometry/shape_geometry/curveSegments': 'Curve Segments',
+			'sidebar/geometry/shape_geometry/extrude': 'Extrude',
+
 			'sidebar/geometry/sphere_geometry/radius': 'Radius',
 			'sidebar/geometry/sphere_geometry/widthsegments': 'Width segments',
 			'sidebar/geometry/sphere_geometry/heightsegments': 'Height segments',

+ 256 - 0
editor/js/libs/ui.three.js

@@ -453,6 +453,262 @@ UI.Outliner.prototype.setValue = function ( value ) {
 
 };
 
+var Points = function ( onAddClicked ) {
+
+	UI.Element.call( this );
+
+	var span = new UI.Span().setDisplay( 'inline-block' );
+
+	this.pointsList = new UI.Div();
+	span.add( this.pointsList );
+
+	var row = new UI.Row();
+	span.add( row );
+
+	var addPointButton = new UI.Button( '+' ).onClick( onAddClicked );
+	row.add( addPointButton );
+
+	this.update = function () {
+
+		if ( this.onChangeCallback !== null ) {
+
+			this.onChangeCallback();
+
+		}
+
+	}.bind( this );
+
+	this.dom = span.dom;
+	this.pointsUI = [];
+	this.lastPointIdx = 0;
+	this.onChangeCallback = null;
+	return this;
+
+};
+
+Points.prototype = Object.create( UI.Element.prototype );
+Points.prototype.constructor = Points;
+
+Points.prototype.onChange = function ( callback ) {
+
+	this.onChangeCallback = callback;
+
+	return this;
+
+};
+
+Points.prototype.clear = function () {
+
+	for ( var i = 0; i < this.pointsUI.length; ++ i ) {
+
+		if ( this.pointsUI[ i ] ) {
+
+			this.deletePointRow( i, true );
+
+		}
+
+	}
+
+	this.lastPointIdx = 0;
+
+};
+
+Points.prototype.deletePointRow = function ( idx, dontUpdate ) {
+
+	if ( ! this.pointsUI[ idx ] ) return;
+
+	this.pointsList.remove( this.pointsUI[ idx ].row );
+	this.pointsUI[ idx ] = null;
+
+	if ( dontUpdate !== true ) {
+
+		this.update();
+
+	}
+
+};
+
+UI.Points2 = function () {
+
+	Points.call( this, UI.Points2.addRow.bind( this ) );
+
+	return this;
+
+};
+
+UI.Points2.prototype = Object.create( Points.prototype );
+UI.Points2.prototype.constructor = UI.Points2;
+
+UI.Points2.addRow = function () {
+
+	if ( this.pointsUI.length === 0 ) {
+
+		this.pointsList.add( this.createPointRow( 0, 0 ) );
+
+	} else {
+
+		var point = this.pointsUI[ this.pointsUI.length - 1 ];
+
+		this.pointsList.add( this.createPointRow( point.x.getValue(), point.y.getValue() ) );
+
+	}
+
+	this.update();
+
+};
+
+UI.Points2.prototype.getValue = function () {
+
+	var points = [];
+	var count = 0;
+
+	for ( var i = 0; i < this.pointsUI.length; i ++ ) {
+
+		var pointUI = this.pointsUI[ i ];
+
+		if ( ! pointUI ) continue;
+
+		points.push( new THREE.Vector2( pointUI.x.getValue(), pointUI.y.getValue() ) );
+		++ count;
+		pointUI.lbl.setValue( count );
+
+	}
+
+	return points;
+
+};
+
+UI.Points2.prototype.setValue = function ( points ) {
+
+	this.clear();
+
+	for ( var i = 0; i < points.length; i ++ ) {
+
+		var point = points[ i ];
+		this.pointsList.add( this.createPointRow( point.x, point.y ) );
+
+	}
+
+	this.update();
+	return this;
+
+};
+
+UI.Points2.prototype.createPointRow = function ( x, y ) {
+
+	var pointRow = new UI.Div();
+	var lbl = new UI.Text( this.lastPointIdx + 1 ).setWidth( '20px' );
+	var txtX = new UI.Number( x ).setWidth( '30px' ).onChange( this.update );
+	var txtY = new UI.Number( y ).setWidth( '30px' ).onChange( this.update );
+
+	var idx = this.lastPointIdx;
+	var scope = this;
+	var btn = new UI.Button( '-' ).onClick( function () {
+
+		if ( scope.isEditing ) return;
+		scope.deletePointRow( idx );
+
+	} );
+
+	this.pointsUI.push( { row: pointRow, lbl: lbl, x: txtX, y: txtY } );
+	++ this.lastPointIdx;
+	pointRow.add( lbl, txtX, txtY, btn );
+
+	return pointRow;
+
+};
+
+UI.Points3 = function () {
+
+	Points.call( this, UI.Points3.addRow.bind( this ) );
+
+	return this;
+
+};
+
+UI.Points3.prototype = Object.create( Points.prototype );
+UI.Points3.prototype.constructor = UI.Points3;
+
+UI.Points3.addRow = function () {
+
+	if ( this.pointsUI.length === 0 ) {
+
+		this.pointsList.add( this.createPointRow( 0, 0, 0 ) );
+
+	} else {
+
+		var point = this.pointsUI[ this.pointsUI.length - 1 ];
+
+		this.pointsList.add( this.createPointRow( point.x.getValue(), point.y.getValue(), point.z.getValue() ) );
+
+	}
+
+	this.update();
+
+};
+
+UI.Points3.prototype.getValue = function () {
+
+	var points = [];
+	var count = 0;
+
+	for ( var i = 0; i < this.pointsUI.length; i ++ ) {
+
+		var pointUI = this.pointsUI[ i ];
+
+		if ( ! pointUI ) continue;
+
+		points.push( new THREE.Vector3( pointUI.x.getValue(), pointUI.y.getValue(), pointUI.z.getValue() ) );
+		++ count;
+		pointUI.lbl.setValue( count );
+
+	}
+
+	return points;
+
+};
+
+UI.Points3.prototype.setValue = function ( points ) {
+
+	this.clear();
+
+	for ( var i = 0; i < points.length; i ++ ) {
+
+		var point = points[ i ];
+		this.pointsList.add( this.createPointRow( point.x, point.y, point.z ) );
+
+	}
+
+	this.update();
+	return this;
+
+};
+
+UI.Points3.prototype.createPointRow = function ( x, y, z ) {
+
+	var pointRow = new UI.Div();
+	var lbl = new UI.Text( this.lastPointIdx + 1 ).setWidth( '20px' );
+	var txtX = new UI.Number( x ).setWidth( '30px' ).onChange( this.update );
+	var txtY = new UI.Number( y ).setWidth( '30px' ).onChange( this.update );
+	var txtZ = new UI.Number( z ).setWidth( '30px' ).onChange( this.update );
+
+	var idx = this.lastPointIdx;
+	var scope = this;
+	var btn = new UI.Button( '-' ).onClick( function () {
+
+		if ( scope.isEditing ) return;
+		scope.deletePointRow( idx );
+
+	} );
+
+	this.pointsUI.push( { row: pointRow, lbl: lbl, x: txtX, y: txtY, z: txtZ } );
+	++ this.lastPointIdx;
+	pointRow.add( lbl, txtX, txtY, txtZ, btn );
+
+	return pointRow;
+
+};
+
 UI.THREE = {};
 
 UI.THREE.Boolean = function ( boolean, text ) {

+ 5 - 4
editor/manifest.json

@@ -1,13 +1,14 @@
 {
-  "short_name": "Editor",
   "name": "Three.js Editor",
+  "short_name": "Three.js",
+  "start_url": ".",
+  "scope": ".",
+  "display": "standalone",
   "icons": [
     {
       "src": "./images/icon.png",
       "type": "image/png",
       "sizes": "144x144"
     }
-  ],
-  "start_url": ".",
-  "display": "standalone"
+  ]
 }

+ 2 - 2
examples/css3d_panorama_deviceorientation.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html>
 	<head>
-		<title>three.js css3d - panorama - deviceorientation</title>
+		<title>three.js css3d - panorama - device orientation</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<style>
@@ -34,7 +34,7 @@
 		<script src="js/controls/DeviceOrientationControls.js"></script>
 		<script src="js/renderers/CSS3DRenderer.js"></script>
 
-		<div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">three.js css3d</a> - panorama - decideorientation. cubemap by <a href="http://www.humus.name/index.php?page=Textures" target="_blank" rel="noopener">Humus</a>.</div>
+		<div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">three.js css3d</a> - panorama - device orientation. cubemap by <a href="http://www.humus.name/index.php?page=Textures" target="_blank" rel="noopener">Humus</a>.</div>
 
 		<script>
 

+ 2 - 1
examples/files.js

@@ -45,7 +45,6 @@ var files = {
 		"webgl_geometry_text",
 		"webgl_geometry_text_shapes",
 		"webgl_geometry_text_stroke",
-		"webgl_hdr",
 		"webgl_helpers",
 		"webgl_interactive_buffergeometry",
 		"webgl_interactive_cubes",
@@ -75,6 +74,7 @@ var files = {
 		"webgl_lines_sphere",
 		"webgl_loader_3ds",
 		"webgl_loader_3mf",
+		"webgl_loader_3mf_materials",
 		"webgl_loader_amf",
 		"webgl_loader_assimp",
 		"webgl_loader_assimp2json",
@@ -131,6 +131,7 @@ var files = {
 		"webgl_loader_texture_hdr",
 		"webgl_loader_texture_ktx",
 		"webgl_loader_texture_pvrtc",
+		"webgl_loader_texture_rgbm",
 		"webgl_loader_texture_tga",
 		"webgl_loader_ttf",
 		"webgl_loader_vrm",

+ 61 - 24
examples/index.html

@@ -9,24 +9,29 @@
 		<style>
 			#panel #content .link {
 				display: block;
-				text-decoration: none;
-				cursor: pointer;
 			}
-
-			#viewSrcButton {
+			#button {
 				position: fixed;
-				bottom: 20px;
-				right: 20px;
+				bottom: 12px;
+				right: 12px;
+
 				padding: 8px;
-				color: #fff;
-				background-color: #555;
-				opacity: 0.7;
+				border-radius: 50%;
+				margin-bottom: 0px; /* TODO div sets it to 20px */
+
+				background-color: #E5E5E5;
+				opacity: .9;
 			}
 
-			#viewSrcButton:hover {
+			#button:hover {
 				cursor: pointer;
 				opacity: 1;
 			}
+
+			#button img {
+				display: block;
+				width: 20px;
+			}
 		</style>
 	</head>
 	<body>
@@ -34,25 +39,31 @@
 		<div id="panel">
 
 			<div id="header">
-
 				<h1><a href="http://threejs.org">three.js</a></h1>
 
-				<img id="expandButton" src="../files/ic_menu_black_24dp.svg">
-
 				<div id="sections">
-					<a href="../docs/">docs</a> <span class="selected">examples</span>
+					<a href="../docs/">docs</a>
+					<span class="selected">examples</span>
 				</div>
 
-				<input type="text" id="filter" autocorrect="off" autocapitalize="off" spellcheck="false"/>
-
+				<img id="expandButton" src="../files/ic_menu_black_24dp.svg">
 			</div>
 
-			<div id="content"></div>
+			<div id="panelScrim"></div>
+
+			<div id="contentWrapper">
+				<input placeholder="Search" type="text" id="filter" autocorrect="off" autocapitalize="off" spellcheck="false" />
+				<div id="exitSearchButton"></div>
+
+				<div id="content"></div>
+			</div>
 
 		</div>
 
 		<iframe id="viewer" name="viewer" allowfullscreen allowvr onmousewheel=""></iframe>
 
+		<a id="button" target="_blank"><img src="../files/ic_code_black_24dp.svg"></a>
+
 		<script src="files.js"></script>
 
 		<script>
@@ -70,13 +81,22 @@
 		var viewer = document.getElementById( 'viewer' );
 
 		var filterInput = document.getElementById( 'filter' );
+		var exitSearchButton = document.getElementById( 'exitSearchButton' );
 
 		var expandButton = document.getElementById( 'expandButton' );
 		expandButton.addEventListener( 'click', function ( event ) {
 			event.preventDefault();
-			panel.classList.toggle( 'collapsed' );
+			panel.classList.toggle( 'open' );
 		} );
 
+		var panelScrim = document.getElementById( 'panelScrim' );
+		panelScrim.onclick = function ( event ) {
+
+			event.preventDefault();
+			panel.classList.toggle( 'open' );
+
+		};
+
 		// iOS iframe auto-resize workaround
 
 		if ( /(iPad|iPhone|iPod)/g.test( navigator.userAgent ) ) {
@@ -90,12 +110,8 @@
 		var container = document.createElement( 'div' );
 		content.appendChild( container );
 
-		var viewSrcButton = document.createElement( 'a' );
-		viewSrcButton.id = 'viewSrcButton';
-		viewSrcButton.target = '_blank';
-		viewSrcButton.textContent = 'View source';
+		var viewSrcButton = document.getElementById( 'button' );
 		viewSrcButton.style.display = 'none';
-		document.body.appendChild( viewSrcButton );
 
 		var links = {};
 		var selected = null;
@@ -157,7 +173,7 @@
 			window.location.hash = file;
 			viewer.focus();
 
-			panel.classList.add( 'collapsed' );
+			panel.classList.remove( 'open' );
 
 			selected = file;
 
@@ -175,6 +191,27 @@
 		}
 
 		// filter
+		filterInput.onfocus = function ( event ) {
+
+			panel.classList.add('searchFocused');
+
+		}
+
+		filterInput.onblur = function ( event ) {
+
+			if(filterInput.value === '') {
+				panel.classList.remove('searchFocused');
+			}
+
+		}
+
+		exitSearchButton.onclick = function( event ) {
+
+			filterInput.value = '';
+			updateFilter();
+			panel.classList.remove('searchFocused');
+
+		}
 
 		filterInput.addEventListener( 'input', function( e ) {
 

+ 0 - 71
examples/js/ImprovedNoise.js

@@ -1,71 +0,0 @@
-// http://mrl.nyu.edu/~perlin/noise/
-
-var ImprovedNoise = function () {
-
-	var p = [ 151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,
-		 23,190,6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,88,237,149,56,87,
-		 174,20,125,136,171,168,68,175,74,165,71,134,139,48,27,166,77,146,158,231,83,111,229,122,60,211,
-		 133,230,220,105,92,41,55,46,245,40,244,102,143,54,65,25,63,161,1,216,80,73,209,76,132,187,208,
-		 89,18,169,200,196,135,130,116,188,159,86,164,100,109,198,173,186,3,64,52,217,226,250,124,123,5,
-		 202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,223,183,170,213,119,
-		 248,152,2,44,154,163,70,221,153,101,155,167,43,172,9,129,22,39,253,19,98,108,110,79,113,224,232,
-		 178,185,112,104,218,246,97,228,251,34,242,193,238,210,144,12,191,179,162,241,81,51,145,235,249,
-		 14,239,107,49,192,214,31,181,199,106,157,184,84,204,176,115,121,50,45,127,4,150,254,138,236,205,
-		 93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180 ];
-
-	for (var i = 0; i < 256 ; i ++) {
-
-		p[256 + i] = p[i];
-
-	}
-
-	function fade(t) {
-
-		return t * t * t * (t * (t * 6 - 15) + 10);
-
-	}
-
-	function lerp(t, a, b) {
-
-		return a + t * (b - a);
-
-	}
-
-	function grad(hash, x, y, z) {
-
-		var h = hash & 15;
-		var u = h < 8 ? x : y, v = h < 4 ? y : h == 12 || h == 14 ? x : z;
-		return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v);
-
-	}
-
-	return {
-
-		noise: function (x, y, z) {
-
-			var floorX = Math.floor(x), floorY = Math.floor(y), floorZ = Math.floor(z);
-
-			var X = floorX & 255, Y = floorY & 255, Z = floorZ & 255;
-
-			x -= floorX;
-			y -= floorY;
-			z -= floorZ;
-
-			var xMinus1 = x - 1, yMinus1 = y - 1, zMinus1 = z - 1;
-
-			var u = fade(x), v = fade(y), w = fade(z);
-
-			var A = p[X] + Y, AA = p[A] + Z, AB = p[A + 1] + Z, B = p[X + 1] + Y, BA = p[B] + Z, BB = p[B + 1] + Z;
-
-			return lerp(w, lerp(v, lerp(u, grad(p[AA], x, y, z),
-							grad(p[BA], xMinus1, y, z)),
-						lerp(u, grad(p[AB], x, yMinus1, z),
-							grad(p[BB], xMinus1, yMinus1, z))),
-					lerp(v, lerp(u, grad(p[AA + 1], x, y, zMinus1),
-							grad(p[BA + 1], xMinus1, y, z - 1)),
-						lerp(u, grad(p[AB + 1], x, yMinus1, zMinus1),
-							grad(p[BB + 1], xMinus1, yMinus1, zMinus1))));
-
-		}
-	}
-};

+ 0 - 324
examples/js/SimplexNoise.js

@@ -1,324 +0,0 @@
-// Ported from Stefan Gustavson's java implementation
-// http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
-// Read Stefan's excellent paper for details on how this code works.
-//
-// Sean McCullough [email protected]
-//
-// Added 4D noise
-// Joshua Koo [email protected] 
-
-/**
- * You can pass in a random number generator object if you like.
- * It is assumed to have a random() method.
- */
-var SimplexNoise = function(r) {
-	if (r == undefined) r = Math;
-	this.grad3 = [[ 1,1,0 ],[ -1,1,0 ],[ 1,-1,0 ],[ -1,-1,0 ], 
-                                 [ 1,0,1 ],[ -1,0,1 ],[ 1,0,-1 ],[ -1,0,-1 ], 
-                                 [ 0,1,1 ],[ 0,-1,1 ],[ 0,1,-1 ],[ 0,-1,-1 ]]; 
-
-	this.grad4 = [[ 0,1,1,1 ], [ 0,1,1,-1 ], [ 0,1,-1,1 ], [ 0,1,-1,-1 ],
-	     [ 0,-1,1,1 ], [ 0,-1,1,-1 ], [ 0,-1,-1,1 ], [ 0,-1,-1,-1 ],
-	     [ 1,0,1,1 ], [ 1,0,1,-1 ], [ 1,0,-1,1 ], [ 1,0,-1,-1 ],
-	     [ -1,0,1,1 ], [ -1,0,1,-1 ], [ -1,0,-1,1 ], [ -1,0,-1,-1 ],
-	     [ 1,1,0,1 ], [ 1,1,0,-1 ], [ 1,-1,0,1 ], [ 1,-1,0,-1 ],
-	     [ -1,1,0,1 ], [ -1,1,0,-1 ], [ -1,-1,0,1 ], [ -1,-1,0,-1 ],
-	     [ 1,1,1,0 ], [ 1,1,-1,0 ], [ 1,-1,1,0 ], [ 1,-1,-1,0 ],
-	     [ -1,1,1,0 ], [ -1,1,-1,0 ], [ -1,-1,1,0 ], [ -1,-1,-1,0 ]];
-
-	this.p = [];
-	for (var i = 0; i < 256; i ++) {
-		this.p[i] = Math.floor(r.random() * 256);
-	}
-  // To remove the need for index wrapping, double the permutation table length 
-	this.perm = []; 
-	for (var i = 0; i < 512; i ++) {
-		this.perm[i] = this.p[i & 255];
-	} 
-
-  // A lookup table to traverse the simplex around a given point in 4D. 
-  // Details can be found where this table is used, in the 4D noise method. 
-	this.simplex = [ 
-    [ 0,1,2,3 ],[ 0,1,3,2 ],[ 0,0,0,0 ],[ 0,2,3,1 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 1,2,3,0 ], 
-    [ 0,2,1,3 ],[ 0,0,0,0 ],[ 0,3,1,2 ],[ 0,3,2,1 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 1,3,2,0 ], 
-    [ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ], 
-    [ 1,2,0,3 ],[ 0,0,0,0 ],[ 1,3,0,2 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 2,3,0,1 ],[ 2,3,1,0 ], 
-    [ 1,0,2,3 ],[ 1,0,3,2 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 2,0,3,1 ],[ 0,0,0,0 ],[ 2,1,3,0 ], 
-    [ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ], 
-    [ 2,0,1,3 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 3,0,1,2 ],[ 3,0,2,1 ],[ 0,0,0,0 ],[ 3,1,2,0 ], 
-    [ 2,1,0,3 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 0,0,0,0 ],[ 3,1,0,2 ],[ 0,0,0,0 ],[ 3,2,0,1 ],[ 3,2,1,0 ]]; 
-};
-
-SimplexNoise.prototype.dot = function(g, x, y) { 
-	return g[0] * x + g[1] * y;
-};
-
-SimplexNoise.prototype.dot3 = function(g, x, y, z) {
-	return g[0] * x + g[1] * y + g[2] * z; 
-};
-
-SimplexNoise.prototype.dot4 = function(g, x, y, z, w) {
-	return g[0] * x + g[1] * y + g[2] * z + g[3] * w;
-};
-
-SimplexNoise.prototype.noise = function(xin, yin) { 
-	var n0, n1, n2; // Noise contributions from the three corners 
-  // Skew the input space to determine which simplex cell we're in 
-	var F2 = 0.5 * (Math.sqrt(3.0) - 1.0); 
-	var s = (xin + yin) * F2; // Hairy factor for 2D 
-	var i = Math.floor(xin + s); 
-	var j = Math.floor(yin + s); 
-	var G2 = (3.0 - Math.sqrt(3.0)) / 6.0; 
-	var t = (i + j) * G2; 
-	var X0 = i - t; // Unskew the cell origin back to (x,y) space 
-	var Y0 = j - t; 
-	var x0 = xin - X0; // The x,y distances from the cell origin 
-	var y0 = yin - Y0; 
-  // For the 2D case, the simplex shape is an equilateral triangle. 
-  // Determine which simplex we are in. 
-	var i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords 
-	if (x0 > y0) {i1 = 1; j1 = 0;} // lower triangle, XY order: (0,0)->(1,0)->(1,1) 
-	else {i1 = 0; j1 = 1;}      // upper triangle, YX order: (0,0)->(0,1)->(1,1) 
-  // A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and 
-  // a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where 
-  // c = (3-sqrt(3))/6 
-	var x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords 
-	var y1 = y0 - j1 + G2; 
-	var x2 = x0 - 1.0 + 2.0 * G2; // Offsets for last corner in (x,y) unskewed coords 
-	var y2 = y0 - 1.0 + 2.0 * G2; 
-  // Work out the hashed gradient indices of the three simplex corners 
-	var ii = i & 255; 
-	var jj = j & 255; 
-	var gi0 = this.perm[ii + this.perm[jj]] % 12; 
-	var gi1 = this.perm[ii + i1 + this.perm[jj + j1]] % 12; 
-	var gi2 = this.perm[ii + 1 + this.perm[jj + 1]] % 12; 
-  // Calculate the contribution from the three corners 
-	var t0 = 0.5 - x0 * x0 - y0 * y0; 
-	if (t0 < 0) n0 = 0.0; 
-	else { 
-		t0 *= t0; 
-		n0 = t0 * t0 * this.dot(this.grad3[gi0], x0, y0);  // (x,y) of grad3 used for 2D gradient 
-	} 
-	var t1 = 0.5 - x1 * x1 - y1 * y1; 
-	if (t1 < 0) n1 = 0.0; 
-	else { 
-		t1 *= t1; 
-		n1 = t1 * t1 * this.dot(this.grad3[gi1], x1, y1); 
-	}
-	var t2 = 0.5 - x2 * x2 - y2 * y2; 
-	if (t2 < 0) n2 = 0.0; 
-	else { 
-		t2 *= t2; 
-		n2 = t2 * t2 * this.dot(this.grad3[gi2], x2, y2); 
-	} 
-  // Add contributions from each corner to get the final noise value. 
-  // The result is scaled to return values in the interval [-1,1]. 
-	return 70.0 * (n0 + n1 + n2); 
-};
-
-// 3D simplex noise 
-SimplexNoise.prototype.noise3d = function(xin, yin, zin) { 
-	var n0, n1, n2, n3; // Noise contributions from the four corners 
-  // Skew the input space to determine which simplex cell we're in 
-	var F3 = 1.0 / 3.0; 
-	var s = (xin + yin + zin) * F3; // Very nice and simple skew factor for 3D 
-	var i = Math.floor(xin + s); 
-	var j = Math.floor(yin + s); 
-	var k = Math.floor(zin + s); 
-	var G3 = 1.0 / 6.0; // Very nice and simple unskew factor, too 
-	var t = (i + j + k) * G3; 
-	var X0 = i - t; // Unskew the cell origin back to (x,y,z) space 
-	var Y0 = j - t; 
-	var Z0 = k - t; 
-	var x0 = xin - X0; // The x,y,z distances from the cell origin 
-	var y0 = yin - Y0; 
-	var z0 = zin - Z0; 
-  // For the 3D case, the simplex shape is a slightly irregular tetrahedron. 
-  // Determine which simplex we are in. 
-	var i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords 
-	var i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords 
-	if (x0 >= y0) { 
-		if (y0 >= z0) 
-      { i1 = 1; j1 = 0; k1 = 0; i2 = 1; j2 = 1; k2 = 0; } // X Y Z order 
-      else if (x0 >= z0) { i1 = 1; j1 = 0; k1 = 0; i2 = 1; j2 = 0; k2 = 1; } // X Z Y order 
-		else { i1 = 0; j1 = 0; k1 = 1; i2 = 1; j2 = 0; k2 = 1; } // Z X Y order 
-	} 
-	else { // x0<y0 
-		if (y0 < z0) { i1 = 0; j1 = 0; k1 = 1; i2 = 0; j2 = 1; k2 = 1; } // Z Y X order 
-    else if (x0 < z0) { i1 = 0; j1 = 1; k1 = 0; i2 = 0; j2 = 1; k2 = 1; } // Y Z X order 
-		else { i1 = 0; j1 = 1; k1 = 0; i2 = 1; j2 = 1; k2 = 0; } // Y X Z order 
-	} 
-  // A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z), 
-  // a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and 
-  // a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where 
-  // c = 1/6.
-	var x1 = x0 - i1 + G3; // Offsets for second corner in (x,y,z) coords 
-	var y1 = y0 - j1 + G3; 
-	var z1 = z0 - k1 + G3; 
-	var x2 = x0 - i2 + 2.0 * G3; // Offsets for third corner in (x,y,z) coords 
-	var y2 = y0 - j2 + 2.0 * G3; 
-	var z2 = z0 - k2 + 2.0 * G3; 
-	var x3 = x0 - 1.0 + 3.0 * G3; // Offsets for last corner in (x,y,z) coords 
-	var y3 = y0 - 1.0 + 3.0 * G3; 
-	var z3 = z0 - 1.0 + 3.0 * G3; 
-  // Work out the hashed gradient indices of the four simplex corners 
-	var ii = i & 255; 
-	var jj = j & 255; 
-	var kk = k & 255; 
-	var gi0 = this.perm[ii + this.perm[jj + this.perm[kk]]] % 12; 
-	var gi1 = this.perm[ii + i1 + this.perm[jj + j1 + this.perm[kk + k1]]] % 12; 
-	var gi2 = this.perm[ii + i2 + this.perm[jj + j2 + this.perm[kk + k2]]] % 12; 
-	var gi3 = this.perm[ii + 1 + this.perm[jj + 1 + this.perm[kk + 1]]] % 12; 
-  // Calculate the contribution from the four corners 
-	var t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0; 
-	if (t0 < 0) n0 = 0.0; 
-	else { 
-		t0 *= t0; 
-		n0 = t0 * t0 * this.dot3(this.grad3[gi0], x0, y0, z0); 
-	}
-	var t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1; 
-	if (t1 < 0) n1 = 0.0; 
-	else { 
-		t1 *= t1; 
-		n1 = t1 * t1 * this.dot3(this.grad3[gi1], x1, y1, z1); 
-	} 
-	var t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2; 
-	if (t2 < 0) n2 = 0.0; 
-	else { 
-		t2 *= t2; 
-		n2 = t2 * t2 * this.dot3(this.grad3[gi2], x2, y2, z2); 
-	} 
-	var t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3; 
-	if (t3 < 0) n3 = 0.0; 
-	else { 
-		t3 *= t3; 
-		n3 = t3 * t3 * this.dot3(this.grad3[gi3], x3, y3, z3); 
-	} 
-  // Add contributions from each corner to get the final noise value. 
-  // The result is scaled to stay just inside [-1,1] 
-	return 32.0 * (n0 + n1 + n2 + n3); 
-};
-
-// 4D simplex noise
-SimplexNoise.prototype.noise4d = function( x, y, z, w ) {
-	// For faster and easier lookups
-	var grad4 = this.grad4;
-	var simplex = this.simplex;
-	var perm = this.perm;
-	
-   // The skewing and unskewing factors are hairy again for the 4D case
-	var F4 = (Math.sqrt(5.0) - 1.0) / 4.0;
-	var G4 = (5.0 - Math.sqrt(5.0)) / 20.0;
-	var n0, n1, n2, n3, n4; // Noise contributions from the five corners
-   // Skew the (x,y,z,w) space to determine which cell of 24 simplices we're in
-	var s = (x + y + z + w) * F4; // Factor for 4D skewing
-	var i = Math.floor(x + s);
-	var j = Math.floor(y + s);
-	var k = Math.floor(z + s);
-	var l = Math.floor(w + s);
-	var t = (i + j + k + l) * G4; // Factor for 4D unskewing
-	var X0 = i - t; // Unskew the cell origin back to (x,y,z,w) space
-	var Y0 = j - t;
-	var Z0 = k - t;
-	var W0 = l - t;
-	var x0 = x - X0;  // The x,y,z,w distances from the cell origin
-	var y0 = y - Y0;
-	var z0 = z - Z0;
-	var w0 = w - W0;
-
-   // For the 4D case, the simplex is a 4D shape I won't even try to describe.
-   // To find out which of the 24 possible simplices we're in, we need to
-   // determine the magnitude ordering of x0, y0, z0 and w0.
-   // The method below is a good way of finding the ordering of x,y,z,w and
-   // then find the correct traversal order for the simplex we’re in.
-   // First, six pair-wise comparisons are performed between each possible pair
-   // of the four coordinates, and the results are used to add up binary bits
-   // for an integer index.
-	var c1 = (x0 > y0) ? 32 : 0;
-	var c2 = (x0 > z0) ? 16 : 0;
-	var c3 = (y0 > z0) ? 8 : 0;
-	var c4 = (x0 > w0) ? 4 : 0;
-	var c5 = (y0 > w0) ? 2 : 0;
-	var c6 = (z0 > w0) ? 1 : 0;
-	var c = c1 + c2 + c3 + c4 + c5 + c6;
-	var i1, j1, k1, l1; // The integer offsets for the second simplex corner
-	var i2, j2, k2, l2; // The integer offsets for the third simplex corner
-	var i3, j3, k3, l3; // The integer offsets for the fourth simplex corner
-   // simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order.
-   // Many values of c will never occur, since e.g. x>y>z>w makes x<z, y<w and x<w
-   // impossible. Only the 24 indices which have non-zero entries make any sense.
-   // We use a thresholding to set the coordinates in turn from the largest magnitude.
-   // The number 3 in the "simplex" array is at the position of the largest coordinate.
-	i1 = simplex[c][0] >= 3 ? 1 : 0;
-	j1 = simplex[c][1] >= 3 ? 1 : 0;
-	k1 = simplex[c][2] >= 3 ? 1 : 0;
-	l1 = simplex[c][3] >= 3 ? 1 : 0;
-   // The number 2 in the "simplex" array is at the second largest coordinate.
-	i2 = simplex[c][0] >= 2 ? 1 : 0;
-	j2 = simplex[c][1] >= 2 ? 1 : 0;    k2 = simplex[c][2] >= 2 ? 1 : 0;
-	l2 = simplex[c][3] >= 2 ? 1 : 0;
-   // The number 1 in the "simplex" array is at the second smallest coordinate.
-	i3 = simplex[c][0] >= 1 ? 1 : 0;
-	j3 = simplex[c][1] >= 1 ? 1 : 0;
-	k3 = simplex[c][2] >= 1 ? 1 : 0;
-	l3 = simplex[c][3] >= 1 ? 1 : 0;
-   // The fifth corner has all coordinate offsets = 1, so no need to look that up.
-	var x1 = x0 - i1 + G4; // Offsets for second corner in (x,y,z,w) coords
-	var y1 = y0 - j1 + G4;
-	var z1 = z0 - k1 + G4;
-	var w1 = w0 - l1 + G4;
-	var x2 = x0 - i2 + 2.0 * G4; // Offsets for third corner in (x,y,z,w) coords
-	var y2 = y0 - j2 + 2.0 * G4;
-	var z2 = z0 - k2 + 2.0 * G4;
-	var w2 = w0 - l2 + 2.0 * G4;
-	var x3 = x0 - i3 + 3.0 * G4; // Offsets for fourth corner in (x,y,z,w) coords
-	var y3 = y0 - j3 + 3.0 * G4;
-	var z3 = z0 - k3 + 3.0 * G4;
-	var w3 = w0 - l3 + 3.0 * G4;
-	var x4 = x0 - 1.0 + 4.0 * G4; // Offsets for last corner in (x,y,z,w) coords
-	var y4 = y0 - 1.0 + 4.0 * G4;
-	var z4 = z0 - 1.0 + 4.0 * G4;
-	var w4 = w0 - 1.0 + 4.0 * G4;
-   // Work out the hashed gradient indices of the five simplex corners
-	var ii = i & 255;
-	var jj = j & 255;
-	var kk = k & 255;
-	var ll = l & 255;
-	var gi0 = perm[ii + perm[jj + perm[kk + perm[ll]]]] % 32;
-	var gi1 = perm[ii + i1 + perm[jj + j1 + perm[kk + k1 + perm[ll + l1]]]] % 32;
-	var gi2 = perm[ii + i2 + perm[jj + j2 + perm[kk + k2 + perm[ll + l2]]]] % 32;
-	var gi3 = perm[ii + i3 + perm[jj + j3 + perm[kk + k3 + perm[ll + l3]]]] % 32;
-	var gi4 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] % 32;
-   // Calculate the contribution from the five corners
-	var t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0;
-	if (t0 < 0) n0 = 0.0;
-	else {
-		t0 *= t0;
-		n0 = t0 * t0 * this.dot4(grad4[gi0], x0, y0, z0, w0);
-	}
-	var t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1;
-	if (t1 < 0) n1 = 0.0;
-	else {
-		t1 *= t1;
-		n1 = t1 * t1 * this.dot4(grad4[gi1], x1, y1, z1, w1);
-	}
-	var t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2;
-	if (t2 < 0) n2 = 0.0;
-	else {
-		t2 *= t2;
-		n2 = t2 * t2 * this.dot4(grad4[gi2], x2, y2, z2, w2);
-	}   var t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3;
-	if (t3 < 0) n3 = 0.0;
-	else {
-		t3 *= t3;
-		n3 = t3 * t3 * this.dot4(grad4[gi3], x3, y3, z3, w3);
-	}
-	var t4 = 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4;
-	if (t4 < 0) n4 = 0.0;
-	else {
-		t4 *= t4;
-		n4 = t4 * t4 * this.dot4(grad4[gi4], x4, y4, z4, w4);
-	}
-   // Sum up and scale the result to cover the range [-1,1]
-	return 27.0 * (n0 + n1 + n2 + n3 + n4);
-};

+ 2 - 2
examples/js/cameras/CinematicCamera.js

@@ -186,14 +186,14 @@ THREE.CinematicCamera.prototype.renderCinematic = function ( scene, renderer ) {
 		scene.overrideMaterial = null;
 		renderer.setRenderTarget( this.postprocessing.rtTextureColor );
 		renderer.clear();
-		renderer.render( scene, camera );
+		renderer.render( scene, this );
 
 		// Render depth into texture
 
 		scene.overrideMaterial = this.materialDepth;
 		renderer.setRenderTarget( this.postprocessing.rtTextureDepth );
 		renderer.clear();
-		renderer.render( scene, camera );
+		renderer.render( scene, this );
 
 		// Render bokeh composite
 

File diff suppressed because it is too large
+ 251 - 150
examples/js/controls/TransformControls.js


+ 8 - 8
examples/js/curves/NURBSUtils.js

@@ -22,7 +22,7 @@ THREE.NURBSUtils = {
 
 	returns the span
 	*/
-	findSpan: function( p,  u,  U ) {
+	findSpan: function ( p, u, U ) {
 
 		var n = U.length - p - 1;
 
@@ -73,7 +73,7 @@ THREE.NURBSUtils = {
 
 	returns array[p+1] with basis functions values.
 	*/
-	calcBasisFunctions: function( span, u, p, U ) {
+	calcBasisFunctions: function ( span, u, p, U ) {
 
 		var N = [];
 		var left = [];
@@ -116,7 +116,7 @@ THREE.NURBSUtils = {
 
 	returns point for given u
 	*/
-	calcBSplinePoint: function( p, U, P, u ) {
+	calcBSplinePoint: function ( p, U, P, u ) {
 
 		var span = this.findSpan( p, u, U );
 		var N = this.calcBasisFunctions( span, u, p, U );
@@ -150,7 +150,7 @@ THREE.NURBSUtils = {
 
 	returns array[n+1][p+1] with basis functions derivatives
 	*/
-	calcBasisFunctionDerivatives: function( span,  u,  p,  n,  U ) {
+	calcBasisFunctionDerivatives: function ( span, u, p, n, U ) {
 
 		var zeroArr = [];
 		for ( var i = 0; i <= p; ++ i )
@@ -225,7 +225,7 @@ THREE.NURBSUtils = {
 				}
 
 				var j1 = ( rk >= - 1 ) ? 1 : - rk;
-				var j2 = ( r - 1 <= pk ) ? k - 1 :  p - r;
+				var j2 = ( r - 1 <= pk ) ? k - 1 : p - r;
 
 				for ( var j = j1; j <= j2; ++ j ) {
 
@@ -280,7 +280,7 @@ THREE.NURBSUtils = {
 
 		returns array[d+1] with derivatives
 		*/
-	calcBSplineDerivatives: function( p,  U,  P,  u,  nd ) {
+	calcBSplineDerivatives: function ( p, U, P, u, nd ) {
 
 		var du = nd < p ? nd : p;
 		var CK = [];
@@ -330,7 +330,7 @@ THREE.NURBSUtils = {
 
 	returns k!/(i!(k-i)!)
 	*/
-	calcKoverI: function( k, i ) {
+	calcKoverI: function ( k, i ) {
 
 		var nom = 1;
 
@@ -412,7 +412,7 @@ THREE.NURBSUtils = {
 
 	returns array with derivatives.
 	*/
-	calcNURBSDerivatives: function( p,  U,  P,  u,  nd ) {
+	calcNURBSDerivatives: function ( p, U, P, u, nd ) {
 
 		var Pders = this.calcBSplineDerivatives( p, U, P, u, nd );
 		return this.calcRationalCurveDerivatives( Pders );

+ 6 - 0
examples/js/effects/AsciiEffect.js

@@ -159,11 +159,13 @@ THREE.AsciiEffect = function ( renderer, charSet, options ) {
 	if ( strResolution == "low" ) {
 
 		switch ( iScale ) {
+
 			case 1 : fLetterSpacing = - 1; break;
 			case 2 :
 			case 3 : fLetterSpacing = - 2.1; break;
 			case 4 : fLetterSpacing = - 3.1; break;
 			case 5 : fLetterSpacing = - 4.15; break;
+
 		}
 
 	}
@@ -171,11 +173,13 @@ THREE.AsciiEffect = function ( renderer, charSet, options ) {
 	if ( strResolution == "medium" ) {
 
 		switch ( iScale ) {
+
 			case 1 : fLetterSpacing = 0; break;
 			case 2 : fLetterSpacing = - 1; break;
 			case 3 : fLetterSpacing = - 1.04; break;
 			case 4 :
 			case 5 : fLetterSpacing = - 2.1; break;
+
 		}
 
 	}
@@ -183,11 +187,13 @@ THREE.AsciiEffect = function ( renderer, charSet, options ) {
 	if ( strResolution == "high" ) {
 
 		switch ( iScale ) {
+
 			case 1 :
 			case 2 : fLetterSpacing = 0; break;
 			case 3 :
 			case 4 :
 			case 5 : fLetterSpacing = - 1; break;
+
 		}
 
 	}

+ 11 - 14
examples/js/effects/OutlineEffect.js

@@ -108,8 +108,6 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 	var vertexShaderChunk = [
 
-		"#include <fog_pars_vertex>",
-
 		"uniform float outlineThickness;",
 
 		"vec4 calculateOutline( vec4 pos, vec3 objectNormal, vec4 skinned ) {",
@@ -175,7 +173,6 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 		var shaderID = shaderIDs[ originalMaterial.type ];
 		var originalUniforms, originalVertexShader;
-		var outlineParameters = originalMaterial.userData.outlineParameters;
 
 		if ( shaderID !== undefined ) {
 
@@ -212,15 +209,15 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 		var uniforms = Object.assign( {}, originalUniforms, uniformsChunk );
 
 		var vertexShader = originalVertexShader
-					// put vertexShaderChunk right before "void main() {...}"
-					.replace( /void\s+main\s*\(\s*\)/, vertexShaderChunk + '\nvoid main()' )
-					// put vertexShaderChunk2 the end of "void main() {...}"
-					// Note: here assums originalVertexShader ends with "}" of "void main() {...}"
-					.replace( /\}\s*$/, vertexShaderChunk2 + '\n}' )
-					// remove any light related lines
-					// Note: here is very sensitive to originalVertexShader
-					// TODO: consider safer way
-					.replace( /#include\s+<[\w_]*light[\w_]*>/g, '' );
+			// put vertexShaderChunk right before "void main() {...}"
+			.replace( /void\s+main\s*\(\s*\)/, vertexShaderChunk + '\nvoid main()' )
+			// put vertexShaderChunk2 the end of "void main() {...}"
+			// Note: here assums originalVertexShader ends with "}" of "void main() {...}"
+			.replace( /\}\s*$/, vertexShaderChunk2 + '\n}' )
+			// remove any light related lines
+			// Note: here is very sensitive to originalVertexShader
+			// TODO: consider safer way
+			.replace( /#include\s+<[\w_]*light[\w_]*>/g, '' );
 
 		var defines = {};
 
@@ -322,7 +319,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 	}
 
-	function onBeforeRender( renderer, scene, camera, geometry, material, group ) {
+	function onBeforeRender( renderer, scene, camera, geometry, material ) {
 
 		var originalMaterial = originalMaterials[ material.uuid ];
 
@@ -418,7 +415,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 			if ( cache[ key ].used === false ) {
 
-				cache[ key ].count++;
+				cache[ key ].count ++;
 
 				if ( cache[ key ].keepAlive === false && cache[ key ].count > removeThresholdCount ) {
 

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

@@ -1740,7 +1740,12 @@ THREE.GLTFExporter.prototype = {
 
 			} else {
 
-				object.updateMatrix();
+				if ( object.matrixAutoUpdate ) {
+
+					object.updateMatrix();
+
+				}
+
 				if ( ! equalArray( object.matrix.elements, [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ] ) ) {
 
 					gltfNode.matrix = object.matrix.elements;

+ 3 - 3
examples/js/geometries/LightningStrike.js

@@ -381,9 +381,9 @@ THREE.LightningStrike.prototype.init = function ( rayParameters ) {
 	this.positionAttribute = null;
 	this.uvsAttribute = null;
 
-	this.simplexX = new SimplexNoise( this.seedGenerator );
-	this.simplexY = new SimplexNoise( this.seedGenerator );
-	this.simplexZ = new SimplexNoise( this.seedGenerator );
+	this.simplexX = new THREE.SimplexNoise( this.seedGenerator );
+	this.simplexY = new THREE.SimplexNoise( this.seedGenerator );
+	this.simplexZ = new THREE.SimplexNoise( this.seedGenerator );
 
 	// Temp vectors
 	this.forwards = new THREE.Vector3();

+ 0 - 64
examples/js/geometries/hilbert2D.js

@@ -1,64 +0,0 @@
-/**
- * Hilbert Curve: Generates 2D-Coordinates in a very fast way.
- *
- * @author Dylan Grafmyre
- *
- * Based on work by:
- * @author Thomas Diewald
- * @link http://www.openprocessing.org/sketch/15493
- *
- * @param center     Center of Hilbert curve.
- * @param size       Total width of Hilbert curve.
- * @param iterations Number of subdivisions.
- * @param v0         Corner index -X, -Z.
- * @param v1         Corner index -X, +Z.
- * @param v2         Corner index +X, +Z.
- * @param v3         Corner index +X, -Z.
- */
-
-function hilbert2D( center, size, iterations, v0, v1, v2, v3 ) {
-
-	// Default Vars
-	var center = center !== undefined ? center : new THREE.Vector3( 0, 0, 0 ),
-		size = size !== undefined ? size : 10,
-		half = size / 2,
-		iterations = iterations !== undefined ? iterations : 1,
-		v0 = v0 !== undefined ? v0 : 0,
-		v1 = v1 !== undefined ? v1 : 1,
-		v2 = v2 !== undefined ? v2 : 2,
-		v3 = v3 !== undefined ? v3 : 3
-	;
-
-	var vec_s = [
-		new THREE.Vector3( center.x - half, center.y, center.z - half ),
-		new THREE.Vector3( center.x - half, center.y, center.z + half ),
-		new THREE.Vector3( center.x + half, center.y, center.z + half ),
-		new THREE.Vector3( center.x + half, center.y, center.z - half )
-	];
-
-	var vec = [
-		vec_s[ v0 ],
-		vec_s[ v1 ],
-		vec_s[ v2 ],
-		vec_s[ v3 ]
-	];
-
-	// Recurse iterations
-	if ( 0 <= -- iterations ) {
-
-		var tmp = [];
-
-		Array.prototype.push.apply( tmp, hilbert2D( vec[ 0 ], half, iterations, v0, v3, v2, v1 ) );
-		Array.prototype.push.apply( tmp, hilbert2D( vec[ 1 ], half, iterations, v0, v1, v2, v3 ) );
-		Array.prototype.push.apply( tmp, hilbert2D( vec[ 2 ], half, iterations, v0, v1, v2, v3 ) );
-		Array.prototype.push.apply( tmp, hilbert2D( vec[ 3 ], half, iterations, v2, v1, v0, v3 ) );
-
-		// Return recursive call
-		return tmp;
-
-	}
-
-	// Return complete Hilbert Curve.
-	return vec;
-
-}

+ 0 - 84
examples/js/geometries/hilbert3D.js

@@ -1,84 +0,0 @@
-/**
- * Hilbert Curve: Generates 2D-Coordinates in a very fast way.
- *
- * @author Dylan Grafmyre
- *
- * Based on work by:
- * @author Thomas Diewald
- * @link http://www.openprocessing.org/visuals/?visualID=15599
- *
- * @param center     Center of Hilbert curve.
- * @param size       Total width of Hilbert curve.
- * @param iterations Number of subdivisions.
- * @param v0         Corner index -X, +Y, -Z.
- * @param v1         Corner index -X, +Y, +Z.
- * @param v2         Corner index -X, -Y, +Z.
- * @param v3         Corner index -X, -Y, -Z.
- * @param v4         Corner index +X, -Y, -Z.
- * @param v5         Corner index +X, -Y, +Z.
- * @param v6         Corner index +X, +Y, +Z.
- * @param v7         Corner index +X, +Y, -Z.
- */
-
-function hilbert3D( center, size, iterations, v0, v1, v2, v3, v4, v5, v6, v7 ) {
-
-	// Default Vars
-	var center = center !== undefined ? center : new THREE.Vector3( 0, 0, 0 ),
-		size = size !== undefined ? size : 10,
-		half = size / 2,
-		iterations = iterations !== undefined ? iterations : 1,
-		v0 = v0 !== undefined ? v0 : 0,
-		v1 = v1 !== undefined ? v1 : 1,
-		v2 = v2 !== undefined ? v2 : 2,
-		v3 = v3 !== undefined ? v3 : 3,
-		v4 = v4 !== undefined ? v4 : 4,
-		v5 = v5 !== undefined ? v5 : 5,
-		v6 = v6 !== undefined ? v6 : 6,
-		v7 = v7 !== undefined ? v7 : 7
-	;
-
-	var vec_s = [
-		new THREE.Vector3( center.x - half, center.y + half, center.z - half ),
-		new THREE.Vector3( center.x - half, center.y + half, center.z + half ),
-		new THREE.Vector3( center.x - half, center.y - half, center.z + half ),
-		new THREE.Vector3( center.x - half, center.y - half, center.z - half ),
-		new THREE.Vector3( center.x + half, center.y - half, center.z - half ),
-		new THREE.Vector3( center.x + half, center.y - half, center.z + half ),
-		new THREE.Vector3( center.x + half, center.y + half, center.z + half ),
-		new THREE.Vector3( center.x + half, center.y + half, center.z - half )
-	];
-
-	var vec = [
-		vec_s[ v0 ],
-		vec_s[ v1 ],
-		vec_s[ v2 ],
-		vec_s[ v3 ],
-		vec_s[ v4 ],
-		vec_s[ v5 ],
-		vec_s[ v6 ],
-		vec_s[ v7 ]
-	];
-
-	// Recurse iterations
-	if ( -- iterations >= 0 ) {
-
-		var tmp = [];
-
-		Array.prototype.push.apply( tmp, hilbert3D( vec[ 0 ], half, iterations, v0, v3, v4, v7, v6, v5, v2, v1 ) );
-		Array.prototype.push.apply( tmp, hilbert3D( vec[ 1 ], half, iterations, v0, v7, v6, v1, v2, v5, v4, v3 ) );
-		Array.prototype.push.apply( tmp, hilbert3D( vec[ 2 ], half, iterations, v0, v7, v6, v1, v2, v5, v4, v3 ) );
-		Array.prototype.push.apply( tmp, hilbert3D( vec[ 3 ], half, iterations, v2, v3, v0, v1, v6, v7, v4, v5 ) );
-		Array.prototype.push.apply( tmp, hilbert3D( vec[ 4 ], half, iterations, v2, v3, v0, v1, v6, v7, v4, v5 ) );
-		Array.prototype.push.apply( tmp, hilbert3D( vec[ 5 ], half, iterations, v4, v3, v2, v5, v6, v1, v0, v7 ) );
-		Array.prototype.push.apply( tmp, hilbert3D( vec[ 6 ], half, iterations, v4, v3, v2, v5, v6, v1, v0, v7 ) );
-		Array.prototype.push.apply( tmp, hilbert3D( vec[ 7 ], half, iterations, v6, v5, v2, v1, v0, v3, v4, v7 ) );
-
-		// Return recursive call
-		return tmp;
-
-	}
-
-	// Return complete Hilbert Curve.
-	return vec;
-
-}

+ 43 - 0
examples/js/libs/basis/README.md

@@ -0,0 +1,43 @@
+# Basis Universal GPU Texture Compression
+
+Basis Universal is a "[supercompressed](http://gamma.cs.unc.edu/GST/gst.pdf)"
+GPU texture and texture video compression system that outputs a highly
+compressed intermediate file format (.basis) that can be quickly transcoded to
+a wide variety of GPU texture compression formats.
+
+[GitHub](https://github.com/BinomialLLC/basis_universal)
+
+## Contents
+
+This folder contains two files:
+
+* `basis_transcoder.js` — JavaScript wrapper for the WebAssembly transcoder.
+* `basis_transcoder.wasm` — WebAssembly transcoder.
+
+Both are dependencies of `THREE.BasisTextureLoader`:
+
+```js
+var basisLoader = new THREE.BasisTextureLoader();
+basisLoader.setTranscoderPath( 'examples/js/libs/basis/' );
+basisLoader.detectSupport( renderer );
+basisLoader.load( 'diffuse.basis', function ( texture ) {
+
+  var material = new THREE.MeshStandardMaterial( { map: texture } );
+
+}, function () {
+
+  console.log( 'onProgress' );
+
+}, function ( e ) {
+
+  console.error( e );
+
+} );
+```
+
+For further documentation about the Basis compressor and transcoder, refer to
+the [Basis GitHub repository](https://github.com/BinomialLLC/basis_universal).
+
+## License
+
+[Apache License 2.0](https://github.com/BinomialLLC/basis_universal/blob/master/LICENSE)

File diff suppressed because it is too large
+ 0 - 0
examples/js/libs/basis/basis_transcoder.js


BIN
examples/js/libs/basis/basis_transcoder.wasm


+ 362 - 47
examples/js/loaders/3MFLoader.js

@@ -1,5 +1,17 @@
 /**
  * @author technohippy / https://github.com/technohippy
+ * @author Mugen87 / https://github.com/Mugen87
+ *
+ * 3D Manufacturing Format (3MF) specification: https://3mf.io/specification/
+ *
+ * The following features from the core specification are supported:
+ *
+ * - 3D Models
+ * - Object Resources (Meshes and Components)
+ * - Material Resources (Base Materials)
+ *
+ * 3MF Materials and Properties Extension (e.g. textures) are not yet supported.
+ *
  */
 
 THREE.ThreeMFLoader = function ( manager ) {
@@ -63,7 +75,7 @@ THREE.ThreeMFLoader.prototype = {
 
 				if ( e instanceof ReferenceError ) {
 
-					console.error( 'THREE.ThreeMFLoader: jszip missing and file is compressed.' );
+					console.error( 'THREE.3MFLoader: jszip missing and file is compressed.' );
 					return null;
 
 				}
@@ -72,7 +84,7 @@ THREE.ThreeMFLoader.prototype = {
 
 			for ( file in zip.files ) {
 
-				if ( file.match( /\.rels$/ ) ) {
+				if ( file.match( /\_rels\/.rels$/ ) ) {
 
 					relsName = file;
 
@@ -110,7 +122,7 @@ THREE.ThreeMFLoader.prototype = {
 
 				if ( xmlData.documentElement.nodeName.toLowerCase() !== 'model' ) {
 
-					console.error( 'THREE.ThreeMFLoader: Error loading 3MF - no 3MF document found: ', modelPart );
+					console.error( 'THREE.3MFLoader: Error loading 3MF - no 3MF document found: ', modelPart );
 
 				}
 
@@ -206,9 +218,38 @@ THREE.ThreeMFLoader.prototype = {
 		}
 
 		function parseBasematerialsNode( basematerialsNode ) {
+
+			var basematerialsData = {
+				id: basematerialsNode.getAttribute( 'id' ), // required
+				basematerials: []
+			};
+
+			var basematerialNodes = basematerialsNode.querySelectorAll( 'base' );
+
+			for ( var i = 0; i < basematerialNodes.length; i ++ ) {
+
+				var basematerialNode = basematerialNodes[ i ];
+				var basematerialData = parseBasematerialNode( basematerialNode );
+				basematerialsData.basematerials.push( basematerialData );
+
+			}
+
+			return basematerialsData;
+
 		}
 
-		function parseMeshNode( meshNode, extensions ) {
+		function parseBasematerialNode( basematerialNode ) {
+
+			var basematerialData = {};
+
+			basematerialData[ 'name' ] = basematerialNode.getAttribute( 'name' ); // required
+			basematerialData[ 'displaycolor' ] = basematerialNode.getAttribute( 'displaycolor' ); // required
+
+			return basematerialData;
+
+		}
+
+		function parseMeshNode( meshNode ) {
 
 			var meshData = {};
 
@@ -300,6 +341,59 @@ THREE.ThreeMFLoader.prototype = {
 
 		function parseComponentsNode( componentsNode ) {
 
+			var components = [];
+
+			var componentNodes = componentsNode.querySelectorAll( 'component' );
+
+			for ( var i = 0; i < componentNodes.length; i ++ ) {
+
+				var componentNode = componentNodes[ i ];
+				var componentData = parseComponentNode( componentNode );
+				components.push( componentData );
+
+			}
+
+			return components;
+
+		}
+
+		function parseComponentNode( componentNode ) {
+
+			var componentData = {};
+
+			componentData[ 'objectId' ] = componentNode.getAttribute( 'objectid' ); // required
+
+			var transform = componentNode.getAttribute( 'transform' );
+
+			if ( transform ) {
+
+				componentData[ 'transform' ] = parseTransform( transform );
+
+			}
+
+			return componentData;
+
+		}
+
+		function parseTransform( transform ) {
+
+			var t = [];
+			transform.split( ' ' ).forEach( function ( s ) {
+
+				t.push( parseFloat( s ) );
+
+			} );
+
+			var matrix = new THREE.Matrix4();
+			matrix.set(
+				t[ 0 ], t[ 3 ], t[ 6 ], t[ 9 ],
+				t[ 1 ], t[ 4 ], t[ 7 ], t[ 10 ],
+				t[ 2 ], t[ 5 ], t[ 8 ], t[ 11 ],
+				 0.0, 0.0, 0.0, 1.0
+			);
+
+			return matrix;
+
 		}
 
 		function parseObjectNode( objectNode ) {
@@ -383,7 +477,7 @@ THREE.ThreeMFLoader.prototype = {
 
 			if ( basematerialsNode ) {
 
-				resourcesData[ 'basematerial' ] = parseBasematerialsNode( basematerialsNode );
+				resourcesData[ 'basematerials' ] = parseBasematerialsNode( basematerialsNode );
 
 			}
 
@@ -411,25 +505,13 @@ THREE.ThreeMFLoader.prototype = {
 
 				var itemNode = itemNodes[ i ];
 				var buildItem = {
-					objectid: itemNode.getAttribute( 'objectid' )
+					objectId: itemNode.getAttribute( 'objectid' )
 				};
 				var transform = itemNode.getAttribute( 'transform' );
 
 				if ( transform ) {
 
-					var t = [];
-					transform.split( ' ' ).forEach( function ( s ) {
-
-						t.push( parseFloat( s ) );
-
-					} );
-					var mat4 = new THREE.Matrix4();
-					buildItem[ 'transform' ] = mat4.set(
-						t[ 0 ], t[ 3 ], t[ 6 ], t[ 9 ],
-						t[ 1 ], t[ 4 ], t[ 7 ], t[ 10 ],
-						t[ 2 ], t[ 5 ], t[ 8 ], t[ 11 ],
-						 0.0, 0.0, 0.0, 1.0
-					);
+					buildItem[ 'transform' ] = parseTransform( transform );
 
 				}
 
@@ -472,40 +554,176 @@ THREE.ThreeMFLoader.prototype = {
 
 		}
 
-		function buildMesh( meshData, data3mf ) {
+		function buildMesh( meshData, objects, modelData, objectData ) {
+
+			// geometry
 
 			var geometry = new THREE.BufferGeometry();
 			geometry.setIndex( new THREE.BufferAttribute( meshData[ 'triangles' ], 1 ) );
 			geometry.addAttribute( 'position', new THREE.BufferAttribute( meshData[ 'vertices' ], 3 ) );
 
-			if ( meshData[ 'colors' ] ) {
+			// groups
+
+			var basematerialsData = modelData[ 'resources' ][ 'basematerials' ];
+			var triangleProperties = meshData[ 'triangleProperties' ];
+
+			var start = 0;
+			var count = 0;
+			var currentMaterialIndex = - 1;
 
-				geometry.addAttribute( 'color', new THREE.BufferAttribute( meshData[ 'colors' ], 3 ) );
+			for ( var i = 0, l = triangleProperties.length; i < l; i ++ ) {
+
+				var triangleProperty = triangleProperties[ i ];
+				var pid = triangleProperty.pid;
+
+				// only proceed if the triangle refers to a basematerials definition
+
+				if ( basematerialsData && ( basematerialsData.id === pid ) ) {
+
+					if ( currentMaterialIndex === - 1 ) currentMaterialIndex = triangleProperty.p1;
+
+					if ( currentMaterialIndex === triangleProperty.p1 ) {
+
+						count += 3; // primitves per triangle
+
+					} else {
+
+						geometry.addGroup( start, count, currentMaterialIndex );
+
+						start += count;
+						count = 3;
+						currentMaterialIndex = triangleProperty.p1;
+
+					}
+
+				}
 
 			}
 
+			if ( geometry.groups.length > 0 ) mergeGroups( geometry );
+
 			geometry.computeBoundingSphere();
 
-			var materialOpts = {
-				flatShading: true
-			};
+			// material
 
-			if ( meshData[ 'colors' ] && 0 < meshData[ 'colors' ].length ) {
+			var material;
 
-				materialOpts[ 'vertexColors' ] = THREE.VertexColors;
+			// add material if an object-level definition is present
 
-			} else {
+			if ( basematerialsData && ( basematerialsData.id === objectData.pid ) ) {
+
+				var materialIndex = objectData.pindex;
+				var basematerialData = basematerialsData.basematerials[ materialIndex ];
 
-				materialOpts[ 'color' ] = 0xaaaaff;
+				material = getBuild( basematerialData, objects, modelData, objectData, buildBasematerial );
 
 			}
 
-			var material = new THREE.MeshPhongMaterial( materialOpts );
+			// add/overwrite material if definitions on triangles are present
+
+			if ( geometry.groups.length > 0 ) {
+
+				var groups = geometry.groups;
+				material = [];
+
+				for ( var i = 0, l = groups.length; i < l; i ++ ) {
+
+					var group = groups[ i ];
+					var basematerialData = basematerialsData.basematerials[ group.materialIndex ];
+
+					material.push( getBuild( basematerialData, objects, modelData, objectData, buildBasematerial ) );
+
+				}
+
+			}
+
+			// default material
+
+			if ( material === undefined ) material = new THREE.MeshPhongMaterial( { color: 0xaaaaff, flatShading: true } );
+
 			return new THREE.Mesh( geometry, material );
 
 		}
 
-		function applyExtensions( extensions, meshData, modelXml, data3mf ) {
+		function mergeGroups( geometry ) {
+
+			// sort by material index
+
+			var groups = geometry.groups.sort( function ( a, b ) {
+
+				if ( a.materialIndex !== b.materialIndex ) return a.materialIndex - b.materialIndex;
+
+				return a.start - b.start;
+
+			} );
+
+			// reorganize index buffer
+
+			var index = geometry.index;
+
+			var itemSize = index.itemSize;
+			var srcArray = index.array;
+
+			var targetOffset = 0;
+
+			var targetArray = new srcArray.constructor( srcArray.length );
+
+			for ( var i = 0; i < groups.length; i ++ ) {
+
+				var group = groups[ i ];
+
+				var groupLength = group.count * itemSize;
+				var groupStart = group.start * itemSize;
+
+				var sub = srcArray.subarray( groupStart, groupStart + groupLength );
+
+				targetArray.set( sub, targetOffset );
+
+				targetOffset += groupLength;
+
+			}
+
+			srcArray.set( targetArray );
+
+			// update groups
+
+			var start = 0;
+
+			for ( i = 0; i < groups.length; i ++ ) {
+
+				group = groups[ i ];
+
+				group.start = start;
+				start += group.count;
+
+			}
+
+			// merge groups
+
+			var lastGroup = groups[ 0 ];
+
+			geometry.groups = [ lastGroup ];
+
+			for ( i = 1; i < groups.length; i ++ ) {
+
+				group = groups[ i ];
+
+				if ( lastGroup.materialIndex === group.materialIndex ) {
+
+					lastGroup.count += group.count;
+
+				} else {
+
+					lastGroup = group;
+					geometry.groups.push( lastGroup );
+
+				}
+
+			}
+
+		}
+
+		function applyExtensions( extensions, meshData, modelXml ) {
 
 			if ( ! extensions ) {
 
@@ -543,38 +761,131 @@ THREE.ThreeMFLoader.prototype = {
 
 		}
 
-		function buildMeshes( data3mf ) {
+		function getBuild( data, objects, modelData, objectData, builder ) {
+
+			if ( data.build !== undefined ) return data.build;
+
+			data.build = builder( data, objects, modelData, objectData );
+
+			return data.build;
+
+		}
+
+		function buildBasematerial( materialData ) {
+
+			var material = new THREE.MeshPhongMaterial( { flatShading: true } );
+
+			material.name = materialData.name;
+
+			// displaycolor MUST be specified with a value of a 6 or 8 digit hexadecimal number, e.g. "#RRGGBB" or "#RRGGBBAA"
+
+			var displaycolor = materialData.displaycolor;
+
+			var color = displaycolor.substring( 0, 7 );
+			material.color.setStyle( color );
+			material.color.convertSRGBToLinear(); // displaycolor is in sRGB
+
+			// process alpha if set
+
+			if ( displaycolor.length === 9 ) {
+
+				material.opacity = parseInt( displaycolor.charAt( 7 ) + displaycolor.charAt( 8 ), 16 ) / 255;
+
+			}
+
+			return material;
+
+		}
+
+		function buildComposite( compositeData, objects, modelData ) {
+
+			var composite = new THREE.Group();
+
+			for ( var j = 0; j < compositeData.length; j ++ ) {
+
+				var component = compositeData[ j ];
+				var build = objects[ component.objectId ];
+
+				if ( build === undefined ) {
+
+					buildObject( component.objectId, objects, modelData );
+					build = objects[ component.objectId ];
+
+				}
+
+				var object3D = build.clone();
+
+				// apply component transfrom
+
+				var transform = component.transform;
+
+				if ( transform ) {
+
+					object3D.applyMatrix( transform );
+
+				}
+
+				composite.add( object3D );
+
+			}
+
+			return composite;
+
+		}
+
+		function buildObject( objectId, objects, modelData ) {
+
+			var objectData = modelData[ 'resources' ][ 'object' ][ objectId ];
+
+			if ( objectData[ 'mesh' ] ) {
+
+				var meshData = objectData[ 'mesh' ];
+
+				var extensions = modelData[ 'extensions' ];
+				var modelXml = modelData[ 'xml' ];
+
+				applyExtensions( extensions, meshData, modelXml );
+
+				objects[ objectData.id ] = getBuild( meshData, objects, modelData, objectData, buildMesh );
+
+			} else {
+
+				var compositeData = objectData[ 'components' ];
+
+				objects[ objectData.id ] = getBuild( compositeData, objects, modelData, objectData, buildComposite );
+
+			}
+
+		}
+
+		function buildObjects( data3mf ) {
 
 			var modelsData = data3mf.model;
-			var meshes = {};
+			var objects = {};
 			var modelsKeys = Object.keys( modelsData );
 
 			for ( var i = 0; i < modelsKeys.length; i ++ ) {
 
 				var modelsKey = modelsKeys[ i ];
 				var modelData = modelsData[ modelsKey ];
-				var modelXml = modelData[ 'xml' ];
-				var extensions = modelData[ 'extensions' ];
 
 				var objectIds = Object.keys( modelData[ 'resources' ][ 'object' ] );
 
 				for ( var j = 0; j < objectIds.length; j ++ ) {
 
 					var objectId = objectIds[ j ];
-					var objectData = modelData[ 'resources' ][ 'object' ][ objectId ];
-					var meshData = objectData[ 'mesh' ];
-					applyExtensions( extensions, meshData, modelXml, data3mf );
-					meshes[ objectId ] = buildMesh( meshData, data3mf );
+
+					buildObject( objectId, objects, modelData );
 
 				}
 
 			}
 
-			return meshes;
+			return objects;
 
 		}
 
-		function build( meshes, refs, data3mf ) {
+		function build( objects, refs, data3mf ) {
 
 			var group = new THREE.Group();
 			var buildData = data3mf.model[ refs[ 'target' ].substring( 1 ) ][ 'build' ];
@@ -582,15 +893,19 @@ THREE.ThreeMFLoader.prototype = {
 			for ( var i = 0; i < buildData.length; i ++ ) {
 
 				var buildItem = buildData[ i ];
-				var mesh = meshes[ buildItem[ 'objectid' ] ];
+				var object3D = objects[ buildItem[ 'objectId' ] ];
+
+				// apply transform
 
-				if ( buildItem[ 'transform' ] ) {
+				var transform = buildItem[ 'transform' ];
+
+				if ( transform ) {
 
-					mesh.geometry.applyMatrix( buildItem[ 'transform' ] );
+					object3D.applyMatrix( transform );
 
 				}
 
-				group.add( mesh );
+				group.add( object3D );
 
 			}
 
@@ -599,9 +914,9 @@ THREE.ThreeMFLoader.prototype = {
 		}
 
 		var data3mf = loadDocument( data );
-		var meshes = buildMeshes( data3mf );
+		var objects = buildObjects( data3mf );
 
-		return build( meshes, data3mf[ 'rels' ], data3mf );
+		return build( objects, data3mf[ 'rels' ], data3mf );
 
 	},
 

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

@@ -773,8 +773,10 @@ THREE.AssimpLoader.prototype = {
 					mesh = new THREE.Mesh( geometry, mat );
 
 				if ( this.mBones.length > 0 ) {
+
 					mesh = new THREE.SkinnedMesh( geometry, mat );
 					mesh.normalizeSkinWeights();
+
 				}
 
 				this.threeNode = mesh;
@@ -1853,7 +1855,7 @@ THREE.AssimpLoader.prototype = {
 
 				} else {
 
-				// else write as usual
+					// else write as usual
 
 					mesh.mTextureCoords[ n ] = [];
 					//note that assbin always writes 3d texcoords

+ 402 - 0
examples/js/loaders/BasisTextureLoader.js

@@ -0,0 +1,402 @@
+/**
+ * @author Don McCurdy / https://www.donmccurdy.com
+ * @author Austin Eng / https://github.com/austinEng
+ * @author Shrek Shao / https://github.com/shrekshao
+ */
+
+/**
+ * Loader for Basis Universal GPU Texture Codec.
+ *
+ * Basis Universal is a "supercompressed" GPU texture and texture video
+ * compression system that outputs a highly compressed intermediate file format
+ * (.basis) that can be quickly transcoded to a wide variety of GPU texture
+ * compression formats.
+ *
+ * This loader parallelizes the transcoding process across a configurable number
+ * of web workers, before transferring the transcoded compressed texture back
+ * to the main thread.
+ */
+// TODO(donmccurdy): Don't use ES6 classes.
+THREE.BasisTextureLoader = class BasisTextureLoader {
+
+	constructor ( manager ) {
+
+		// TODO(donmccurdy): Loading manager is unused.
+		this.manager = manager || THREE.DefaultLoadingManager;
+
+		this.transcoderPath = '';
+		this.transcoderBinary = null;
+		this.transcoderPending = null;
+
+		this.workerLimit = 4;
+		this.workerPool = [];
+		this.workerNextTaskID = 1;
+		this.workerSourceURL = '';
+		this.workerConfig = {
+			format: null,
+			etcSupported: false,
+			dxtSupported: false,
+			pvrtcSupported: false,
+		};
+
+	}
+
+	setTranscoderPath ( path ) {
+
+		this.transcoderPath = path;
+
+	}
+
+	detectSupport ( renderer ) {
+
+		var context = renderer.context;
+		var config = this.workerConfig;
+
+		config.etcSupported = !! context.getExtension('WEBGL_compressed_texture_etc1');
+		config.dxtSupported = !! context.getExtension('WEBGL_compressed_texture_s3tc');
+		config.pvrtcSupported = !! context.getExtension('WEBGL_compressed_texture_pvrtc')
+			|| !! context.getExtension('WEBKIT_WEBGL_compressed_texture_pvrtc');
+
+		if ( config.etcSupported ) {
+
+			config.format = THREE.BasisTextureLoader.BASIS_FORMAT.cTFETC1;
+
+		} else if ( config.dxtSupported ) {
+
+			config.format = THREE.BasisTextureLoader.BASIS_FORMAT.cTFBC1;
+
+		} else if ( config.pvrtcSupported ) {
+
+			config.format = THREE.BasisTextureLoader.BASIS_FORMAT.cTFPVRTC1_4_OPAQUE_ONLY;
+
+		} else {
+
+			throw new Error( 'THREE.BasisTextureLoader: No suitable compressed texture format found.' );
+
+		}
+
+		return this;
+
+	}
+
+	load ( url, onLoad, onProgress, onError ) {
+
+		// TODO(donmccurdy): Use THREE.FileLoader.
+		fetch( url )
+			.then( ( res ) => res.arrayBuffer() )
+			.then( ( buffer ) => this._createTexture( buffer ) )
+			.then( onLoad )
+			.catch( onError );
+
+	}
+
+	/**
+	 * @param  {ArrayBuffer} buffer
+	 * @return {Promise<THREE.CompressedTexture>}
+	 */
+	_createTexture ( buffer ) {
+
+		return this.getWorker()
+			.then( ( worker ) => {
+
+				return new Promise( ( resolve ) => {
+
+					var taskID = this.workerNextTaskID++;
+
+					worker._callbacks[ taskID ] = resolve;
+					worker._taskCosts[ taskID ] = buffer.byteLength;
+					worker._taskLoad += worker._taskCosts[ taskID ];
+					worker._taskCount++;
+
+					worker.postMessage( { type: 'transcode', id: taskID, buffer }, [ buffer ] );
+
+				} );
+
+			} )
+			.then( ( message ) => {
+
+				var config = this.workerConfig;
+
+				var { data, width, height } = message;
+
+				var mipmaps = [ { data, width, height } ];
+
+				var texture;
+
+				if ( config.etcSupported ) {
+
+					texture = new THREE.CompressedTexture( mipmaps, width, height, THREE.RGB_ETC1_Format );
+
+				} else if ( config.dxtSupported ) {
+
+					texture = new THREE.CompressedTexture( mipmaps, width, height, THREE.BasisTextureLoader.DXT_FORMAT_MAP[ config.format ], THREE.UnsignedByteType );
+
+				} else if ( config.pvrtcSupported ) {
+
+					texture = new THREE.CompressedTexture( mipmaps, width, height, THREE.RGB_PVRTC_4BPPV1_Format );
+
+				} else {
+
+					throw new Error( 'THREE.BasisTextureLoader: No supported format available.' );
+
+				}
+
+				texture.minFilter = THREE.LinearMipMapLinearFilter;
+				texture.magFilter = THREE.LinearFilter;
+				texture.encoding = THREE.sRGBEncoding;
+				texture.generateMipmaps = false;
+				texture.flipY = false;
+				texture.needsUpdate = true;
+
+				return texture;
+
+			});
+
+	}
+
+	_initTranscoder () {
+
+		if ( ! this.transcoderBinary ) {
+
+			// TODO(donmccurdy): Use THREE.FileLoader.
+			var jsContent = fetch( this.transcoderPath + 'basis_transcoder.js' )
+				.then( ( response ) => response.text() );
+
+			var binaryContent = fetch( this.transcoderPath + 'basis_transcoder.wasm' )
+				.then( ( response ) => response.arrayBuffer() );
+
+			this.transcoderPending = Promise.all( [ jsContent, binaryContent ] )
+				.then( ( [ jsContent, binaryContent ] ) => {
+
+					var fn = THREE.BasisTextureLoader.BasisWorker.toString();
+
+					var body = [
+						'/* basis_transcoder.js */',
+						'var Module;',
+						'function createBasisModule () {',
+						'  ' + jsContent,
+						'  return Module;',
+						'}',
+						'',
+						'/* worker */',
+						fn.substring( fn.indexOf( '{' ) + 1, fn.lastIndexOf( '}' ) )
+					].join( '\n' );
+
+					this.workerSourceURL = URL.createObjectURL( new Blob( [ body ] ) );
+					this.transcoderBinary = binaryContent;
+
+				} );
+
+		}
+
+		return this.transcoderPending;
+
+	}
+
+	getWorker () {
+
+		return this._initTranscoder().then( () => {
+
+			if ( this.workerPool.length < this.workerLimit ) {
+
+				var worker = new Worker( this.workerSourceURL );
+
+				worker._callbacks = {};
+				worker._taskCosts = {};
+				worker._taskLoad = 0;
+				worker._taskCount = 0;
+
+				worker.postMessage( {
+					type: 'init',
+					config: this.workerConfig,
+					transcoderBinary: this.transcoderBinary,
+				} );
+
+				worker.onmessage = function ( e ) {
+
+					var message = e.data;
+
+					switch ( message.type ) {
+
+						case 'transcode':
+							worker._callbacks[ message.id ]( message );
+							worker._taskLoad -= worker._taskCosts[ message.id ];
+							delete worker._callbacks[ message.id ];
+							delete worker._taskCosts[ message.id ];
+							break;
+
+						default:
+							throw new Error( 'THREE.BasisTextureLoader: Unexpected message, "' + message.type + '"' );
+
+					}
+
+				}
+
+				this.workerPool.push( worker );
+
+			} else {
+
+				this.workerPool.sort( function ( a, b ) { return a._taskLoad > b._taskLoad ? -1 : 1; } );
+
+			}
+
+			return this.workerPool[ this.workerPool.length - 1 ];
+
+		} );
+
+	}
+
+	dispose () {
+
+		for ( var i = 0; i < this.workerPool.length; i++ ) {
+
+			this.workerPool[ i ].terminate();
+
+		}
+
+		this.workerPool.length = 0;
+
+	}
+}
+
+/* CONSTANTS */
+
+THREE.BasisTextureLoader.BASIS_FORMAT = {
+	cTFETC1: 0,
+	cTFBC1: 1,
+	cTFBC4: 2,
+	cTFPVRTC1_4_OPAQUE_ONLY: 3,
+	cTFBC7_M6_OPAQUE_ONLY: 4,
+	cTFETC2: 5,
+	cTFBC3: 6,
+	cTFBC5: 7,
+};
+
+// DXT formats, from:
+// http://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc/
+THREE.BasisTextureLoader.DXT_FORMAT = {
+	COMPRESSED_RGB_S3TC_DXT1_EXT: 0x83F0,
+	COMPRESSED_RGBA_S3TC_DXT1_EXT: 0x83F1,
+	COMPRESSED_RGBA_S3TC_DXT3_EXT: 0x83F2,
+	COMPRESSED_RGBA_S3TC_DXT5_EXT: 0x83F3,
+};
+THREE.BasisTextureLoader.DXT_FORMAT_MAP = {};
+THREE.BasisTextureLoader.DXT_FORMAT_MAP[ THREE.BasisTextureLoader.BASIS_FORMAT.cTFBC1 ] =
+	THREE.BasisTextureLoader.DXT_FORMAT.COMPRESSED_RGB_S3TC_DXT1_EXT;
+THREE.BasisTextureLoader.DXT_FORMAT_MAP[ THREE.BasisTextureLoader.BASIS_FORMAT.cTFBC3 ] =
+	THREE.BasisTextureLoader.DXT_FORMAT.COMPRESSED_RGBA_S3TC_DXT5_EXT;
+
+/* WEB WORKER */
+
+THREE.BasisTextureLoader.BasisWorker = function () {
+	var config;
+	var transcoderPending;
+	var _BasisFile;
+
+	onmessage = function ( e ) {
+
+		var message = e.data;
+
+		switch ( message.type ) {
+
+			case 'init':
+				config = message.config;
+				init( message.transcoderBinary );
+				break;
+
+			case 'transcode':
+				transcoderPending.then( () => {
+
+					var { data, width, height } = transcode( message.buffer );
+
+					self.postMessage( { type: 'transcode', id: message.id, data, width, height }, [ data.buffer ] );
+
+				} );
+				break;
+
+		}
+
+	};
+
+	function init ( wasmBinary ) {
+
+		transcoderPending = new Promise( ( resolve ) => {
+
+			// The 'Module' global is used by the Basis wrapper, which will check for
+			// the 'wasmBinary' property before trying to load the file itself.
+
+			// TODO(donmccurdy): This only works with a modified version of the
+			// emscripten-generated wrapper. The default seems to have a bug making it
+			// impossible to override the WASM binary.
+			Module = { wasmBinary, onRuntimeInitialized: resolve };
+
+		} ).then( () => {
+
+			var { BasisFile, initializeBasis } = Module;
+
+			_BasisFile = BasisFile;
+
+			initializeBasis();
+
+		} );
+
+		createBasisModule();
+
+	}
+
+	function transcode ( buffer ) {
+
+		var basisFile = new _BasisFile( new Uint8Array( buffer ) );
+
+		var width = basisFile.getImageWidth( 0, 0 );
+		var height = basisFile.getImageHeight( 0, 0 );
+		var images = basisFile.getNumImages();
+		var levels = basisFile.getNumLevels( 0 );
+
+		function cleanup () {
+
+			basisFile.close();
+			basisFile.delete();
+
+		}
+
+		if ( ! width || ! height || ! images || ! levels ) {
+
+			cleanup();
+			throw new Error( 'THREE.BasisTextureLoader:  Invalid .basis file' );
+
+		}
+
+		if ( ! basisFile.startTranscoding() ) {
+
+			cleanup();
+			throw new Error( 'THREE.BasisTextureLoader: .startTranscoding failed' );
+
+		}
+
+		var dst = new Uint8Array( basisFile.getImageTranscodedSizeInBytes( 0, 0, config.format ) );
+
+		var startTime = performance.now();
+
+		var status = basisFile.transcodeImage(
+			dst,
+			0,
+			0,
+			config.format,
+			config.etcSupported ? 0 : ( config.dxtSupported ? 1 : 0 ),
+			0
+		);
+
+		cleanup();
+
+		if ( ! status ) {
+
+			throw new Error( 'THREE.BasisTextureLoader: .transcodeImage failed.' );
+
+		}
+
+		return { data: dst, width, height };
+
+	}
+
+};

+ 53 - 0
examples/js/loaders/ColladaLoader.js

@@ -3814,6 +3814,35 @@ THREE.ColladaLoader.prototype = {
 
 		}
 
+		// convert the parser error element into text with each child elements text
+		// separated by new lines.
+
+		function parserErrorToText( parserError ) {
+
+			var result = '';
+			var stack = [ parserError ];
+
+			while ( stack.length ) {
+
+				var node = stack.shift();
+
+				if ( node.nodeType === Node.TEXT_NODE ) {
+
+					result += node.textContent;
+
+				} else {
+
+					result += '\n';
+					stack.push.apply( stack, node.childNodes );
+
+				}
+
+			}
+
+			return result.trim();
+
+		}
+
 		if ( text.length === 0 ) {
 
 			return { scene: new THREE.Scene() };
@@ -3824,6 +3853,30 @@ THREE.ColladaLoader.prototype = {
 
 		var collada = getElementsByTagName( xml, 'COLLADA' )[ 0 ];
 
+		var parserError = xml.getElementsByTagName( 'parsererror' )[ 0 ];
+		if ( parserError !== undefined ) {
+
+			// Chrome will return parser error with a div in it
+
+			var errorElement = getElementsByTagName( parserError, 'div' )[ 0 ];
+			var errorText;
+
+			if ( errorElement ) {
+
+				errorText = errorElement.textContent;
+
+			} else {
+
+				errorText = parserErrorToText( parserError );
+
+			}
+
+			console.error( 'THREE.ColladaLoader: Failed to parse collada file.\n', errorText );
+
+			return null;
+
+		}
+
 		// metadata
 
 		var version = collada.getAttribute( 'version' );

+ 26 - 17
examples/js/loaders/EXRLoader.js

@@ -83,14 +83,14 @@ THREE.EXRLoader.prototype = Object.create( THREE.DataTextureLoader.prototype );
 
 THREE.EXRLoader.prototype._parser = function ( buffer ) {
 
-	const USHORT_RANGE = (1 << 16);
-	const BITMAP_SIZE = (USHORT_RANGE >> 3);
+	const USHORT_RANGE = ( 1 << 16 );
+	const BITMAP_SIZE = ( USHORT_RANGE >> 3 );
 
-	const HUF_ENCBITS = 16;  // literal (value) bit length
-	const HUF_DECBITS = 14;  // decoding bit size (>= 8)
+	const HUF_ENCBITS = 16; // literal (value) bit length
+	const HUF_DECBITS = 14; // decoding bit size (>= 8)
 
-	const HUF_ENCSIZE = (1 << HUF_ENCBITS) + 1;  // encoding table size
-	const HUF_DECSIZE = 1 << HUF_DECBITS;        // decoding table size
+	const HUF_ENCSIZE = ( 1 << HUF_ENCBITS ) + 1; // encoding table size
+	const HUF_DECSIZE = 1 << HUF_DECBITS; // decoding table size
 	const HUF_DECMASK = HUF_DECSIZE - 1;
 
 	const SHORT_ZEROCODE_RUN = 59;
@@ -157,6 +157,7 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) {
 		getBitsReturn.l = ( c >> lc ) & ( ( 1 << nBits ) - 1 );
 		getBitsReturn.c = c;
 		getBitsReturn.lc = lc;
+
 	}
 
 	const hufTableBuffer = new Array( 59 );
@@ -249,9 +250,17 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) {
 
 	}
 
-	function hufLength( code ) { return code & 63; }
+	function hufLength( code ) {
+
+		return code & 63;
+
+	}
 
-	function hufCode( code ) { return code >> 6; }
+	function hufCode( code ) {
+
+		return code >> 6;
+
+	}
 
 	function hufBuildDecTable( hcode, im, iM, hdecod ) {
 
@@ -355,7 +364,7 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) {
 			lc -= 8;
 
 			var cs = ( c >> lc );
-			var cs = new Uint8Array([cs])[0];
+			var cs = new Uint8Array( [ cs ] )[ 0 ];
 
 			if ( outBufferOffset.value + cs > outBufferEndOffset ) {
 
@@ -365,7 +374,7 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) {
 
 			var s = outBuffer[ outBufferOffset.value - 1 ];
 
-			while ( cs-- > 0 ) {
+			while ( cs -- > 0 ) {
 
 				outBuffer[ outBufferOffset.value ++ ] = s;
 
@@ -805,7 +814,7 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) {
 
 	function parseUint32( dataView, offset ) {
 
-		var Uint32 = dataView.getUint32(offset.value, true);
+		var Uint32 = dataView.getUint32( offset.value, true );
 
 		offset.value = offset.value + INT32_SIZE;
 
@@ -815,7 +824,7 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) {
 
 	function parseUint8Array( uInt8Array, offset ) {
 
-		var Uint8 = uInt8Array[offset.value];
+		var Uint8 = uInt8Array[ offset.value ];
 
 		offset.value = offset.value + INT8_SIZE;
 
@@ -825,7 +834,7 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) {
 
 	function parseUint8( dataView, offset ) {
 
-		var Uint8 = dataView.getUint8(offset.value);
+		var Uint8 = dataView.getUint8( offset.value );
 
 		offset.value = offset.value + INT8_SIZE;
 
@@ -835,7 +844,7 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) {
 
 	function parseFloat32( dataView, offset ) {
 
-		var float = dataView.getFloat32(offset.value, true);
+		var float = dataView.getFloat32( offset.value, true );
 
 		offset.value += FLOAT32_SIZE;
 
@@ -873,7 +882,7 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) {
 
 	function parseFloat16( buffer, offset ) {
 
-		return decodeFloat16( parseUint16( buffer, offset) );
+		return decodeFloat16( parseUint16( buffer, offset ) );
 
 	}
 
@@ -1021,8 +1030,8 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) {
 
 	}
 
-	var bufferDataView = new DataView(buffer);
-	var uInt8Array = new Uint8Array(buffer);
+	var bufferDataView = new DataView( buffer );
+	var uInt8Array = new Uint8Array( buffer );
 
 	var EXRHeader = {};
 

+ 127 - 122
examples/js/loaders/GCodeLoader.js

@@ -1,5 +1,3 @@
-'use strict';
-
 /**
  * THREE.GCodeLoader is used to load gcode files usually used for 3D printing or CNC applications.
  *
@@ -10,6 +8,7 @@
  * @author tentone
  * @author joewalnes
  */
+
 THREE.GCodeLoader = function ( manager ) {
 
 	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
@@ -18,208 +17,214 @@ THREE.GCodeLoader = function ( manager ) {
 
 };
 
-THREE.GCodeLoader.prototype.load = function ( url, onLoad, onProgress, onError ) {
+THREE.GCodeLoader.prototype = {
 
-	var self = this;
+	constructor: THREE.GCodeLoader,
 
-	var loader = new THREE.FileLoader( self.manager );
-	loader.setPath( self.path );
-	loader.load( url, function ( text ) {
+	load: function ( url, onLoad, onProgress, onError ) {
 
-		onLoad( self.parse( text ) );
+		var self = this;
 
-	}, onProgress, onError );
+		var loader = new THREE.FileLoader( self.manager );
+		loader.setPath( self.path );
+		loader.load( url, function ( text ) {
 
-};
+			onLoad( self.parse( text ) );
 
-THREE.GCodeLoader.prototype.setPath = function ( value ) {
+		}, onProgress, onError );
 
-	this.path = value;
-	return this;
+	},
 
-};
+	setPath: function ( value ) {
 
-THREE.GCodeLoader.prototype.parse = function ( data ) {
+		this.path = value;
+		return this;
 
-	var state = { x: 0, y: 0, z: 0, e: 0, f: 0, extruding: false, relative: false };
-	var layers = [];
+	},
 
-	var currentLayer = undefined;
+	parse: function ( data ) {
 
-	var pathMaterial = new THREE.LineBasicMaterial( { color: 0xFF0000 } );
-	pathMaterial.name = 'path';
+		var state = { x: 0, y: 0, z: 0, e: 0, f: 0, extruding: false, relative: false };
+		var layers = [];
 
-	var extrudingMaterial = new THREE.LineBasicMaterial( { color: 0x00FF00 } );
-	extrudingMaterial.name = 'extruded';
+		var currentLayer = undefined;
 
-	function newLayer( line ) {
+		var pathMaterial = new THREE.LineBasicMaterial( { color: 0xFF0000 } );
+		pathMaterial.name = 'path';
 
-		currentLayer = { vertex: [], pathVertex: [], z: line.z };
-		layers.push( currentLayer );
+		var extrudingMaterial = new THREE.LineBasicMaterial( { color: 0x00FF00 } );
+		extrudingMaterial.name = 'extruded';
 
-	}
+		function newLayer( line ) {
 
-	//Create lie segment between p1 and p2
-	function addSegment( p1, p2 ) {
+			currentLayer = { vertex: [], pathVertex: [], z: line.z };
+			layers.push( currentLayer );
 
-		if ( currentLayer === undefined ) {
+		}
 
-			newLayer( p1 );
+		//Create lie segment between p1 and p2
+		function addSegment( p1, p2 ) {
 
-		}
+			if ( currentLayer === undefined ) {
 
-		if ( line.extruding ) {
+				newLayer( p1 );
 
-			currentLayer.vertex.push( p1.x, p1.y, p1.z );
-			currentLayer.vertex.push( p2.x, p2.y, p2.z );
+			}
 
-		} else {
+			if ( line.extruding ) {
 
-			currentLayer.pathVertex.push( p1.x, p1.y, p1.z );
-			currentLayer.pathVertex.push( p2.x, p2.y, p2.z );
+				currentLayer.vertex.push( p1.x, p1.y, p1.z );
+				currentLayer.vertex.push( p2.x, p2.y, p2.z );
+
+			} else {
+
+				currentLayer.pathVertex.push( p1.x, p1.y, p1.z );
+				currentLayer.pathVertex.push( p2.x, p2.y, p2.z );
+
+			}
 
 		}
 
-	}
+		function delta( v1, v2 ) {
 
-	function delta( v1, v2 ) {
+			return state.relative ? v2 : v2 - v1;
 
-		return state.relative ? v2 : v2 - v1;
+		}
 
-	}
+		function absolute( v1, v2 ) {
 
-	function absolute( v1, v2 ) {
+			return state.relative ? v1 + v2 : v2;
 
-		return state.relative ? v1 + v2 : v2;
+		}
 
-	}
+		var lines = data.replace( /;.+/g, '' ).split( '\n' );
 
-	var lines = data.replace( /;.+/g, '' ).split( '\n' );
+		for ( var i = 0; i < lines.length; i ++ ) {
 
-	for ( var i = 0; i < lines.length; i ++ ) {
+			var tokens = lines[ i ].split( ' ' );
+			var cmd = tokens[ 0 ].toUpperCase();
 
-		var tokens = lines[ i ].split( ' ' );
-		var cmd = tokens[ 0 ].toUpperCase();
+			//Argumments
+			var args = {};
+			tokens.splice( 1 ).forEach( function ( token ) {
 
-		//Argumments
-		var args = {};
-		tokens.splice( 1 ).forEach( function ( token ) {
+				if ( token[ 0 ] !== undefined ) {
 
-			if ( token[ 0 ] !== undefined ) {
+					var key = token[ 0 ].toLowerCase();
+					var value = parseFloat( token.substring( 1 ) );
+					args[ key ] = value;
 
-				var key = token[ 0 ].toLowerCase();
-				var value = parseFloat( token.substring( 1 ) );
-				args[ key ] = value;
+				}
 
-			}
+			} );
 
-		} );
+			//Process commands
+			//G0/G1 – Linear Movement
+			if ( cmd === 'G0' || cmd === 'G1' ) {
 
-		//Process commands
-		//G0/G1 – Linear Movement
-		if ( cmd === 'G0' || cmd === 'G1' ) {
+				var line = {
+					x: args.x !== undefined ? absolute( state.x, args.x ) : state.x,
+					y: args.y !== undefined ? absolute( state.y, args.y ) : state.y,
+					z: args.z !== undefined ? absolute( state.z, args.z ) : state.z,
+					e: args.e !== undefined ? absolute( state.e, args.e ) : state.e,
+					f: args.f !== undefined ? absolute( state.f, args.f ) : state.f,
+				};
 
-			var line = {
-				x: args.x !== undefined ? absolute( state.x, args.x ) : state.x,
-				y: args.y !== undefined ? absolute( state.y, args.y ) : state.y,
-				z: args.z !== undefined ? absolute( state.z, args.z ) : state.z,
-				e: args.e !== undefined ? absolute( state.e, args.e ) : state.e,
-				f: args.f !== undefined ? absolute( state.f, args.f ) : state.f,
-			};
+				//Layer change detection is or made by watching Z, it's made by watching when we extrude at a new Z position
+				if ( delta( state.e, line.e ) > 0 ) {
 
-			//Layer change detection is or made by watching Z, it's made by watching when we extrude at a new Z position
-			if ( delta( state.e, line.e ) > 0 ) {
+					line.extruding = delta( state.e, line.e ) > 0;
 
-				line.extruding = delta( state.e, line.e ) > 0;
+					if ( currentLayer == undefined || line.z != currentLayer.z ) {
 
-				if ( currentLayer == undefined || line.z != currentLayer.z ) {
+						newLayer( line );
 
-					newLayer( line );
+					}
 
 				}
 
-			}
+				addSegment( state, line );
+				state = line;
 
-			addSegment( state, line );
-			state = line;
+			} else if ( cmd === 'G2' || cmd === 'G3' ) {
 
-		} else if ( cmd === 'G2' || cmd === 'G3' ) {
+				//G2/G3 - Arc Movement ( G2 clock wise and G3 counter clock wise )
+				//console.warn( 'THREE.GCodeLoader: Arc command not supported' );
 
-			//G2/G3 - Arc Movement ( G2 clock wise and G3 counter clock wise )
-			//console.warn( 'THREE.GCodeLoader: Arc command not supported' );
+			} else if ( cmd === 'G90' ) {
 
-		} else if ( cmd === 'G90' ) {
+				//G90: Set to Absolute Positioning
+				state.relative = false;
 
-			//G90: Set to Absolute Positioning
-			state.relative = false;
+			} else if ( cmd === 'G91' ) {
 
-		} else if ( cmd === 'G91' ) {
+				//G91: Set to state.relative Positioning
+				state.relative = true;
 
-			//G91: Set to state.relative Positioning
-			state.relative = true;
+			} else if ( cmd === 'G92' ) {
 
-		} else if ( cmd === 'G92' ) {
+				//G92: Set Position
+				var line = state;
+				line.x = args.x !== undefined ? args.x : line.x;
+				line.y = args.y !== undefined ? args.y : line.y;
+				line.z = args.z !== undefined ? args.z : line.z;
+				line.e = args.e !== undefined ? args.e : line.e;
+				state = line;
 
-			//G92: Set Position
-			var line = state;
-			line.x = args.x !== undefined ? args.x : line.x;
-			line.y = args.y !== undefined ? args.y : line.y;
-			line.z = args.z !== undefined ? args.z : line.z;
-			line.e = args.e !== undefined ? args.e : line.e;
-			state = line;
+			} else {
 
-		} else {
+				//console.warn( 'THREE.GCodeLoader: Command not supported:' + cmd );
 
-			//console.warn( 'THREE.GCodeLoader: Command not supported:' + cmd );
+			}
 
 		}
 
-	}
+		function addObject( vertex, extruding ) {
 
-	function addObject( vertex, extruding ) {
+			var geometry = new THREE.BufferGeometry();
+			geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( vertex, 3 ) );
 
-		var geometry = new THREE.BufferGeometry();
-		geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( vertex, 3 ) );
+			var segments = new THREE.LineSegments( geometry, extruding ? extrudingMaterial : pathMaterial );
+			segments.name = 'layer' + i;
+			object.add( segments );
 
-		var segments = new THREE.LineSegments( geometry, extruding ? extrudingMaterial : pathMaterial );
-		segments.name = 'layer' + i;
-		object.add( segments );
+		}
 
-	}
+		var object = new THREE.Group();
+		object.name = 'gcode';
 
-	var object = new THREE.Group();
-	object.name = 'gcode';
+		if ( this.splitLayer ) {
 
-	if ( this.splitLayer ) {
+			for ( var i = 0; i < layers.length; i ++ ) {
 
-		for ( var i = 0; i < layers.length; i ++ ) {
+				var layer = layers[ i ];
+				addObject( layer.vertex, true );
+				addObject( layer.pathVertex, false );
 
-			var layer = layers[ i ];
-			addObject( layer.vertex, true );
-			addObject( layer.pathVertex, false );
+			}
 
-		}
+		} else {
+
+			var vertex = [], pathVertex = [];
 
-	} else {
+			for ( var i = 0; i < layers.length; i ++ ) {
 
-		var vertex = [], pathVertex = [];
+				var layer = layers[ i ];
 
-		for ( var i = 0; i < layers.length; i ++ ) {
+				vertex = vertex.concat( layer.vertex );
+				pathVertex = pathVertex.concat( layer.pathVertex );
 
-			var layer = layers[ i ];
+			}
 
-			vertex = vertex.concat( layer.vertex );
-			pathVertex = pathVertex.concat( layer.pathVertex );
+			addObject( vertex, true );
+			addObject( pathVertex, false );
 
 		}
 
-		addObject( vertex, true );
-		addObject( pathVertex, false );
-
-	}
+		object.quaternion.setFromEuler( new THREE.Euler( - Math.PI / 2, 0, 0 ) );
 
-	object.quaternion.setFromEuler( new THREE.Euler( - Math.PI / 2, 0, 0 ) );
+		return object;
 
-	return object;
+	}
 
 };

+ 4 - 2
examples/js/loaders/GLTFLoader.js

@@ -841,7 +841,8 @@ THREE.GLTFLoader = ( function () {
 
 				for ( var i = 0, il = params.length; i < il; i ++ ) {
 
-					target[ params[ i ] ] = source[ params[ i ] ];
+					var value = source[ params[ i ] ];
+					target[ params[ i ] ] = ( value && value.isColor ) ? value.clone() : value;
 
 				}
 
@@ -1299,7 +1300,7 @@ THREE.GLTFLoader = ( function () {
 
 			if ( typeof gltfDef.extras === 'object' ) {
 
-				object.userData = gltfDef.extras;
+				Object.assign( object.userData, gltfDef.extras );
 
 			} else {
 
@@ -2996,6 +2997,7 @@ THREE.GLTFLoader = ( function () {
 
 			if ( nodeDef.name !== undefined ) {
 
+				node.userData.name = nodeDef.name;
 				node.name = THREE.PropertyBinding.sanitizeNodeName( nodeDef.name );
 
 			}

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

@@ -42,7 +42,7 @@ var KhronosTextureContainer = ( function () {
 	 * @param {boolean} threeDExpected- provision for indicating that data should be a 3D texture, not implemented
 	 * @param {boolean} textureArrayExpected- provision for indicating that data should be a texture array, not implemented
 	 */
-	function KhronosTextureContainer( arrayBuffer, facesExpected, threeDExpected, textureArrayExpected ) {
+	function KhronosTextureContainer( arrayBuffer, facesExpected /*, threeDExpected, textureArrayExpected */ ) {
 
 		this.arrayBuffer = arrayBuffer;
 
@@ -138,13 +138,13 @@ var KhronosTextureContainer = ( function () {
 
 			var imageSize = new Int32Array( this.arrayBuffer, dataOffset, 1 )[ 0 ]; // size per face, since not supporting array cubemaps
 			dataOffset += 4; // size of the image + 4 for the imageSize field
-			
+
 			for ( var face = 0; face < this.numberOfFaces; face ++ ) {
 
 				var byteArray = new Uint8Array( this.arrayBuffer, dataOffset, imageSize );
 
 				mipmaps.push( { "data": byteArray, "width": width, "height": height } );
-				
+
 				dataOffset += imageSize;
 				dataOffset += 3 - ( ( imageSize + 3 ) % 4 ); // add padding for odd sized image
 

File diff suppressed because it is too large
+ 587 - 125
examples/js/loaders/LDrawLoader.js


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

@@ -14,6 +14,8 @@ THREE.MTLLoader.prototype = {
 
 	constructor: THREE.MTLLoader,
 
+	crossOrigin: 'anonymous',
+
 	/**
 	 * Loads and parses a MTL asset from a URL.
 	 *
@@ -149,7 +151,7 @@ THREE.MTLLoader.prototype = {
 
 			} else {
 
-				if ( key === 'ka' || key === 'kd' || key === 'ks' || key ==='ke' ) {
+				if ( key === 'ka' || key === 'kd' || key === 'ks' || key === 'ke' ) {
 
 					var ss = value.split( delimiter_pattern, 3 );
 					info[ key ] = [ parseFloat( ss[ 0 ] ), parseFloat( ss[ 1 ] ), parseFloat( ss[ 2 ] ) ];

+ 2 - 5
examples/js/loaders/RGBELoader.js

@@ -5,7 +5,7 @@
 // https://github.com/mrdoob/three.js/issues/5552
 // http://en.wikipedia.org/wiki/RGBE_image_format
 
-THREE.HDRLoader = THREE.RGBELoader = function ( manager ) {
+THREE.RGBELoader = function ( manager ) {
 
 	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
 	this.type = THREE.UnsignedByteType;
@@ -316,8 +316,7 @@ THREE.RGBELoader.prototype._parser = function ( buffer ) {
 		}
 	;
 
-	var byteArray = new Uint8Array( buffer ),
-		byteLength = byteArray.byteLength;
+	var byteArray = new Uint8Array( buffer );
 	byteArray.pos = 0;
 	var rgbe_header_info = RGBE_ReadHeader( byteArray );
 
@@ -392,5 +391,3 @@ THREE.RGBELoader.prototype.setType = function ( value ) {
 	return this;
 
 };
-
-

+ 169 - 82
examples/js/loaders/SVGLoader.js

@@ -136,7 +136,7 @@ THREE.SVGLoader.prototype = {
 
 		}
 
-		function parsePathNode( node, style ) {
+		function parsePathNode( node ) {
 
 			var path = new THREE.ShapePath();
 
@@ -161,8 +161,10 @@ THREE.SVGLoader.prototype = {
 				var data = command.substr( 1 ).trim();
 
 				if ( isFirstPoint === true ) {
+
 					doSetFirstPoint = true;
 					isFirstPoint = false;
+
 				}
 
 				switch ( type ) {
@@ -170,56 +172,78 @@ THREE.SVGLoader.prototype = {
 					case 'M':
 						var numbers = parseFloats( data );
 						for ( var j = 0, jl = numbers.length; j < jl; j += 2 ) {
+
 							point.x = numbers[ j + 0 ];
 							point.y = numbers[ j + 1 ];
 							control.x = point.x;
 							control.y = point.y;
+
 							if ( j === 0 ) {
+
 								path.moveTo( point.x, point.y );
+
 							} else {
+
 								path.lineTo( point.x, point.y );
+
 							}
+
 							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
+
 						}
 						break;
 
 					case 'H':
 						var numbers = parseFloats( data );
+
 						for ( var j = 0, jl = numbers.length; j < jl; j ++ ) {
+
 							point.x = numbers[ j ];
 							control.x = point.x;
 							control.y = point.y;
 							path.lineTo( point.x, point.y );
+
 							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
+
 						}
 						break;
 
 					case 'V':
 						var numbers = parseFloats( data );
+
 						for ( var j = 0, jl = numbers.length; j < jl; j ++ ) {
+
 							point.y = numbers[ j ];
 							control.x = point.x;
 							control.y = point.y;
 							path.lineTo( point.x, point.y );
+
 							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
+
 						}
 						break;
 
 					case 'L':
 						var numbers = parseFloats( data );
+
 						for ( var j = 0, jl = numbers.length; j < jl; j += 2 ) {
+
 							point.x = numbers[ j + 0 ];
 							point.y = numbers[ j + 1 ];
 							control.x = point.x;
 							control.y = point.y;
 							path.lineTo( point.x, point.y );
+
 							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
+
 						}
 						break;
 
 					case 'C':
 						var numbers = parseFloats( data );
+
 						for ( var j = 0, jl = numbers.length; j < jl; j += 6 ) {
+
 							path.bezierCurveTo(
 								numbers[ j + 0 ],
 								numbers[ j + 1 ],
@@ -232,13 +256,17 @@ THREE.SVGLoader.prototype = {
 							control.y = numbers[ j + 3 ];
 							point.x = numbers[ j + 4 ];
 							point.y = numbers[ j + 5 ];
+
 							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
+
 						}
 						break;
 
 					case 'S':
 						var numbers = parseFloats( data );
+
 						for ( var j = 0, jl = numbers.length; j < jl; j += 4 ) {
+
 							path.bezierCurveTo(
 								getReflection( point.x, control.x ),
 								getReflection( point.y, control.y ),
@@ -251,13 +279,17 @@ THREE.SVGLoader.prototype = {
 							control.y = numbers[ j + 1 ];
 							point.x = numbers[ j + 2 ];
 							point.y = numbers[ j + 3 ];
+
 							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
+
 						}
 						break;
 
 					case 'Q':
 						var numbers = parseFloats( data );
+
 						for ( var j = 0, jl = numbers.length; j < jl; j += 4 ) {
+
 							path.quadraticCurveTo(
 								numbers[ j + 0 ],
 								numbers[ j + 1 ],
@@ -268,13 +300,17 @@ THREE.SVGLoader.prototype = {
 							control.y = numbers[ j + 1 ];
 							point.x = numbers[ j + 2 ];
 							point.y = numbers[ j + 3 ];
+
 							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
+
 						}
 						break;
 
 					case 'T':
 						var numbers = parseFloats( data );
+
 						for ( var j = 0, jl = numbers.length; j < jl; j += 2 ) {
+
 							var rx = getReflection( point.x, control.x );
 							var ry = getReflection( point.y, control.y );
 							path.quadraticCurveTo(
@@ -287,13 +323,17 @@ THREE.SVGLoader.prototype = {
 							control.y = ry;
 							point.x = numbers[ j + 0 ];
 							point.y = numbers[ j + 1 ];
+
 							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
+
 						}
 						break;
 
 					case 'A':
 						var numbers = parseFloats( data );
+
 						for ( var j = 0, jl = numbers.length; j < jl; j += 7 ) {
+
 							var start = point.clone();
 							point.x = numbers[ j + 5 ];
 							point.y = numbers[ j + 6 ];
@@ -302,65 +342,88 @@ THREE.SVGLoader.prototype = {
 							parseArcCommand(
 								path, numbers[ j ], numbers[ j + 1 ], numbers[ j + 2 ], numbers[ j + 3 ], numbers[ j + 4 ], start, point
 							);
+
 							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
+
 						}
 						break;
 
-					//
-
 					case 'm':
 						var numbers = parseFloats( data );
+
 						for ( var j = 0, jl = numbers.length; j < jl; j += 2 ) {
+
 							point.x += numbers[ j + 0 ];
 							point.y += numbers[ j + 1 ];
 							control.x = point.x;
 							control.y = point.y;
+
 							if ( j === 0 ) {
+
 								path.moveTo( point.x, point.y );
+
 							} else {
+
 								path.lineTo( point.x, point.y );
+
 							}
+
 							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
+
 						}
 						break;
 
 					case 'h':
 						var numbers = parseFloats( data );
+
 						for ( var j = 0, jl = numbers.length; j < jl; j ++ ) {
+
 							point.x += numbers[ j ];
 							control.x = point.x;
 							control.y = point.y;
 							path.lineTo( point.x, point.y );
+
 							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
+
 						}
 						break;
 
 					case 'v':
 						var numbers = parseFloats( data );
+
 						for ( var j = 0, jl = numbers.length; j < jl; j ++ ) {
+
 							point.y += numbers[ j ];
 							control.x = point.x;
 							control.y = point.y;
 							path.lineTo( point.x, point.y );
+
 							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
+
 						}
 						break;
 
 					case 'l':
 						var numbers = parseFloats( data );
+
 						for ( var j = 0, jl = numbers.length; j < jl; j += 2 ) {
+
 							point.x += numbers[ j + 0 ];
 							point.y += numbers[ j + 1 ];
 							control.x = point.x;
 							control.y = point.y;
 							path.lineTo( point.x, point.y );
+
 							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
+
 						}
 						break;
 
 					case 'c':
 						var numbers = parseFloats( data );
+
 						for ( var j = 0, jl = numbers.length; j < jl; j += 6 ) {
+
 							path.bezierCurveTo(
 								point.x + numbers[ j + 0 ],
 								point.y + numbers[ j + 1 ],
@@ -373,13 +436,17 @@ THREE.SVGLoader.prototype = {
 							control.y = point.y + numbers[ j + 3 ];
 							point.x += numbers[ j + 4 ];
 							point.y += numbers[ j + 5 ];
+
 							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
+
 						}
 						break;
 
 					case 's':
 						var numbers = parseFloats( data );
+
 						for ( var j = 0, jl = numbers.length; j < jl; j += 4 ) {
+
 							path.bezierCurveTo(
 								getReflection( point.x, control.x ),
 								getReflection( point.y, control.y ),
@@ -392,13 +459,17 @@ THREE.SVGLoader.prototype = {
 							control.y = point.y + numbers[ j + 1 ];
 							point.x += numbers[ j + 2 ];
 							point.y += numbers[ j + 3 ];
+
 							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
+
 						}
 						break;
 
 					case 'q':
 						var numbers = parseFloats( data );
+
 						for ( var j = 0, jl = numbers.length; j < jl; j += 4 ) {
+
 							path.quadraticCurveTo(
 								point.x + numbers[ j + 0 ],
 								point.y + numbers[ j + 1 ],
@@ -409,13 +480,17 @@ THREE.SVGLoader.prototype = {
 							control.y = point.y + numbers[ j + 1 ];
 							point.x += numbers[ j + 2 ];
 							point.y += numbers[ j + 3 ];
+
 							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
+
 						}
 						break;
 
 					case 't':
 						var numbers = parseFloats( data );
+
 						for ( var j = 0, jl = numbers.length; j < jl; j += 2 ) {
+
 							var rx = getReflection( point.x, control.x );
 							var ry = getReflection( point.y, control.y );
 							path.quadraticCurveTo(
@@ -428,13 +503,17 @@ THREE.SVGLoader.prototype = {
 							control.y = ry;
 							point.x = point.x + numbers[ j + 0 ];
 							point.y = point.y + numbers[ j + 1 ];
+
 							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
+
 						}
 						break;
 
 					case 'a':
 						var numbers = parseFloats( data );
+
 						for ( var j = 0, jl = numbers.length; j < jl; j += 7 ) {
+
 							var start = point.clone();
 							point.x += numbers[ j + 5 ];
 							point.y += numbers[ j + 6 ];
@@ -443,20 +522,23 @@ THREE.SVGLoader.prototype = {
 							parseArcCommand(
 								path, numbers[ j ], numbers[ j + 1 ], numbers[ j + 2 ], numbers[ j + 3 ], numbers[ j + 4 ], start, point
 							);
+
 							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
+
 						}
 						break;
 
-					//
-
 					case 'Z':
 					case 'z':
 						path.currentPath.autoClose = true;
+
 						if ( path.currentPath.curves.length > 0 ) {
+
 							// Reset point to beginning of Path
 							point.copy( firstPoint );
 							path.currentPath.currentPoint.copy( point );
 							isFirstPoint = true;
+
 						}
 						break;
 
@@ -540,8 +622,8 @@ THREE.SVGLoader.prototype = {
 		function svgAngle( ux, uy, vx, vy ) {
 
 			var dot = ux * vx + uy * vy;
-			var len = Math.sqrt( ux * ux + uy * uy ) *  Math.sqrt( vx * vx + vy * vy );
-			var ang = Math.acos( Math.max( -1, Math.min( 1, dot / len ) ) ); // floating point precision, slightly over values appear
+			var len = Math.sqrt( ux * ux + uy * uy ) * Math.sqrt( vx * vx + vy * vy );
+			var ang = Math.acos( Math.max( - 1, Math.min( 1, dot / len ) ) ); // floating point precision, slightly over values appear
 			if ( ( ux * vy - uy * vx ) < 0 ) ang = - ang;
 			return ang;
 
@@ -551,7 +633,7 @@ THREE.SVGLoader.prototype = {
 		* According to https://www.w3.org/TR/SVG/shapes.html#RectElementRXAttribute
 		* rounded corner should be rendered to elliptical arc, but bezier curve does the job well enough
 		*/
-		function parseRectNode( node, style ) {
+		function parseRectNode( node ) {
 
 			var x = parseFloat( node.getAttribute( 'x' ) || 0 );
 			var y = parseFloat( node.getAttribute( 'y' ) || 0 );
@@ -586,7 +668,7 @@ THREE.SVGLoader.prototype = {
 
 		}
 
-		function parsePolygonNode( node, style ) {
+		function parsePolygonNode( node ) {
 
 			function iterator( match, a, b ) {
 
@@ -594,9 +676,13 @@ THREE.SVGLoader.prototype = {
 				var y = parseFloat( b );
 
 				if ( index === 0 ) {
+
 					path.moveTo( x, y );
+
 				} else {
+
 					path.lineTo( x, y );
+
 				}
 
 				index ++;
@@ -609,7 +695,7 @@ THREE.SVGLoader.prototype = {
 
 			var index = 0;
 
-			node.getAttribute( 'points' ).replace(regex, iterator);
+			node.getAttribute( 'points' ).replace( regex, iterator );
 
 			path.currentPath.autoClose = true;
 
@@ -617,7 +703,7 @@ THREE.SVGLoader.prototype = {
 
 		}
 
-		function parsePolylineNode( node, style ) {
+		function parsePolylineNode( node ) {
 
 			function iterator( match, a, b ) {
 
@@ -625,9 +711,13 @@ THREE.SVGLoader.prototype = {
 				var y = parseFloat( b );
 
 				if ( index === 0 ) {
+
 					path.moveTo( x, y );
+
 				} else {
+
 					path.lineTo( x, y );
+
 				}
 
 				index ++;
@@ -640,7 +730,7 @@ THREE.SVGLoader.prototype = {
 
 			var index = 0;
 
-			node.getAttribute( 'points' ).replace(regex, iterator);
+			node.getAttribute( 'points' ).replace( regex, iterator );
 
 			path.currentPath.autoClose = false;
 
@@ -648,7 +738,7 @@ THREE.SVGLoader.prototype = {
 
 		}
 
-		function parseCircleNode( node, style ) {
+		function parseCircleNode( node ) {
 
 			var x = parseFloat( node.getAttribute( 'cx' ) );
 			var y = parseFloat( node.getAttribute( 'cy' ) );
@@ -664,7 +754,7 @@ THREE.SVGLoader.prototype = {
 
 		}
 
-		function parseEllipseNode( node, style ) {
+		function parseEllipseNode( node ) {
 
 			var x = parseFloat( node.getAttribute( 'cx' ) );
 			var y = parseFloat( node.getAttribute( 'cy' ) );
@@ -681,7 +771,7 @@ THREE.SVGLoader.prototype = {
 
 		}
 
-		function parseLineNode( node, style ) {
+		function parseLineNode( node ) {
 
 			var x1 = parseFloat( node.getAttribute( 'x1' ) );
 			var y1 = parseFloat( node.getAttribute( 'y1' ) );
@@ -705,7 +795,11 @@ THREE.SVGLoader.prototype = {
 
 			function addStyle( svgName, jsName, adjustFunction ) {
 
-				if ( adjustFunction === undefined ) adjustFunction = function copy( v ) { return v; };
+				if ( adjustFunction === undefined ) adjustFunction = function copy( v ) {
+
+					return v;
+
+				};
 
 				if ( node.hasAttribute( svgName ) ) style[ jsName ] = adjustFunction( node.getAttribute( svgName ) );
 				if ( node.style[ svgName ] !== '' ) style[ jsName ] = adjustFunction( node.style[ svgName ] );
@@ -780,7 +874,9 @@ THREE.SVGLoader.prototype = {
 		function getNodeTransform( node ) {
 
 			if ( ! node.hasAttribute( 'transform' ) ) {
+
 				return null;
+
 			}
 
 			var transform = parseNodeTransform( node );
@@ -788,7 +884,9 @@ THREE.SVGLoader.prototype = {
 			if ( transform ) {
 
 				if ( transformStack.length > 0 ) {
+
 					transform.premultiply( transformStack[ transformStack.length - 1 ] );
+
 				}
 
 				currentTransform.copy( transform );
@@ -864,7 +962,7 @@ THREE.SVGLoader.prototype = {
 								}
 
 								// Rotate around center (cx, cy)
-								tempTransform1.identity().translate( -cx, -cy );
+								tempTransform1.identity().translate( - cx, - cy );
 								tempTransform2.identity().rotate( angle );
 								tempTransform3.multiplyMatrices( tempTransform2, tempTransform1 );
 								tempTransform1.identity().translate( cx, cy );
@@ -882,7 +980,9 @@ THREE.SVGLoader.prototype = {
 								var scaleY = scaleX;
 
 								if ( array.length >= 2 ) {
+
 									scaleY = array[ 1 ];
+
 								}
 
 								currentTransform.scale( scaleX, scaleY );
@@ -932,6 +1032,7 @@ THREE.SVGLoader.prototype = {
 							}
 
 							break;
+
 					}
 
 				}
@@ -958,12 +1059,12 @@ THREE.SVGLoader.prototype = {
 
 			var subPaths = path.subPaths;
 
-			for ( var i = 0, n = subPaths.length; i < n; i++ ) {
+			for ( var i = 0, n = subPaths.length; i < n; i ++ ) {
 
 				var subPath = subPaths[ i ];
 				var curves = subPath.curves;
 
-				for ( var j = 0; j < curves.length; j++ ) {
+				for ( var j = 0; j < curves.length; j ++ ) {
 
 					var curve = curves[ j ];
 
@@ -988,7 +1089,9 @@ THREE.SVGLoader.prototype = {
 					} else if ( curve.isEllipseCurve ) {
 
 						if ( isRotated ) {
+
 							console.warn( "SVGLoader: Elliptic arc or ellipse rotation or skewing is not implemented." );
+
 						}
 
 						tempV2.set( curve.aX, curve.aY );
@@ -1008,17 +1111,23 @@ THREE.SVGLoader.prototype = {
 		}
 
 		function isTransformRotated( m ) {
+
 			return m.elements[ 1 ] !== 0 || m.elements[ 3 ] !== 0;
+
 		}
 
 		function getTransformScaleX( m ) {
+
 			var te = m.elements;
-			return Math.sqrt( te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] )
+			return Math.sqrt( te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] );
+
 		}
 
 		function getTransformScaleY( m ) {
+
 			var te = m.elements;
-			return Math.sqrt( te[ 3 ] * te[ 3 ] + te[ 4 ] * te[ 4 ] )
+			return Math.sqrt( te[ 3 ] * te[ 3 ] + te[ 4 ] * te[ 4 ] );
+
 		}
 
 		//
@@ -1038,8 +1147,6 @@ THREE.SVGLoader.prototype = {
 
 		var currentTransform = new THREE.Matrix3();
 
-		var scope = this;
-
 		console.time( 'THREE.SVGLoader: DOMParser' );
 
 		var xml = new DOMParser().parseFromString( text, 'image/svg+xml' ); // application/xml
@@ -1071,7 +1178,7 @@ THREE.SVGLoader.prototype = {
 
 };
 
-THREE.SVGLoader.getStrokeStyle = function ( width, color, opacity, lineJoin, lineCap,  miterLimit ) {
+THREE.SVGLoader.getStrokeStyle = function ( width, color, opacity, lineJoin, lineCap, miterLimit ) {
 
 	// Param width: Stroke width
 	// Param color: As returned by THREE.Color.getStyle()
@@ -1136,7 +1243,6 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 	var tempV2_5 = new THREE.Vector2();
 	var tempV2_6 = new THREE.Vector2();
 	var tempV2_7 = new THREE.Vector2();
-	var tempV3_1 = new THREE.Vector3();
 	var lastPointL = new THREE.Vector2();
 	var lastPointR = new THREE.Vector2();
 	var point0L = new THREE.Vector2();
@@ -1147,9 +1253,6 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 	var nextPointR = new THREE.Vector2();
 	var innerPoint = new THREE.Vector2();
 	var outerPoint = new THREE.Vector2();
-	var tempTransform0 = new THREE.Matrix3();
-	var tempTransform1 = new THREE.Matrix3();
-	var tempTransform2 = new THREE.Matrix3();
 
 	return function ( points, style, arcDivisions, minDistance, vertices, normals, uvs, vertexOffset ) {
 
@@ -1160,7 +1263,7 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 		// if 'vertices' parameter is undefined no triangles will be generated, but the returned vertices count will still be valid (useful to preallocate the buffers)
 		// 'normals' and 'uvs' buffers are optional
 
-		arcLengthDivisions = arcDivisions !== undefined ? arcDivisions : 12;
+		arcDivisions = arcDivisions !== undefined ? arcDivisions : 12;
 		minDistance = minDistance !== undefined ? minDistance : 0.001;
 		vertexOffset = vertexOffset !== undefined ? vertexOffset : 0;
 
@@ -1210,11 +1313,9 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 					// Skip duplicated initial point
 					nextPoint = points[ 1 ];
 
-				}
-				else nextPoint = undefined;
+				} else nextPoint = undefined;
 
-			}
-			else {
+			} else {
 
 				nextPoint = points[ iPoint + 1 ];
 
@@ -1250,8 +1351,8 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 				}
 				if ( iPoint === 1 ) initialJoinIsOnLeftSide = joinIsOnLeftSide;
 
-				tempV2_3.subVectors( nextPoint, currentPoint )
-				var maxInnerDistance = tempV2_3.normalize();
+				tempV2_3.subVectors( nextPoint, currentPoint );
+				tempV2_3.normalize();
 				var dot = Math.abs( normal1.dot( tempV2_3 ) );
 
 				// If path is straight, don't create join
@@ -1287,16 +1388,14 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 							nextPointR.copy( innerPoint );
 							currentPointR.copy( innerPoint );
 
-						}
-						else {
+						} else {
 
 							nextPointL.copy( innerPoint );
 							currentPointL.copy( innerPoint );
 
 						}
 
-					}
-					else {
+					} else {
 
 						// The segment triangles are generated here if there was overlapping
 
@@ -1324,8 +1423,7 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 
 								makeCircularSector( currentPoint, currentPointL, nextPointL, u1, 0 );
 
-							}
-							else {
+							} else {
 
 								makeCircularSector( currentPoint, nextPointR, currentPointR, u1, 1 );
 
@@ -1348,8 +1446,7 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 									makeSegmentWithBevelJoin( joinIsOnLeftSide, innerSideModified, u1 );
 									break;
 
-								}
-								else {
+								} else {
 
 									// Segment triangles
 
@@ -1374,8 +1471,7 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 										addVertex( tempV2_7, u1, 0 );
 										addVertex( nextPointL, u1, 0 );
 
-									}
-									else {
+									} else {
 
 										tempV2_6.subVectors( outerPoint, currentPointR ).multiplyScalar( miterFraction ).add( currentPointR );
 										tempV2_7.subVectors( outerPoint, nextPointR ).multiplyScalar( miterFraction ).add( nextPointR );
@@ -1396,8 +1492,7 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 
 								}
 
-							}
-							else {
+							} else {
 
 								// Miter join segment triangles
 
@@ -1415,8 +1510,7 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 										addVertex( outerPoint, u1, 0 );
 										addVertex( innerPoint, u1, 1 );
 
-									}
-									else {
+									} else {
 
 										addVertex( lastPointR, u0, 1 );
 										addVertex( lastPointL, u0, 0 );
@@ -1433,16 +1527,14 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 
 										nextPointL.copy( outerPoint );
 
-									}
-									else {
+									} else {
 
 										nextPointR.copy( outerPoint );
 
 									}
 
 
-								}
-								else {
+								} else {
 
 									// Add extra miter join triangles
 
@@ -1456,8 +1548,7 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 										addVertex( outerPoint, u1, 0 );
 										addVertex( nextPointL, u1, 0 );
 
-									}
-									else {
+									} else {
 
 										addVertex( currentPointR, u1, 1 );
 										addVertex( outerPoint, u1, 1 );
@@ -1479,8 +1570,7 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 
 					}
 
-				}
-				else {
+				} else {
 
 					// The segment triangles are generated here when two consecutive points are collinear
 
@@ -1488,8 +1578,7 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 
 				}
 
-			}
-			else {
+			} else {
 
 				// The segment triangles are generated here if it is the ending segment
 
@@ -1520,16 +1609,18 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 			// Ending line endcap
 			addCapGeometry( currentPoint, currentPointL, currentPointR, joinIsOnLeftSide, false, u1 );
 
-		}
-		else if ( innerSideModified && vertices ) {
+		} else if ( innerSideModified && vertices ) {
 
 			// Modify path first segment vertices to adjust to the segments inner and outer intersections
 
 			var lastOuter = outerPoint;
 			var lastInner = innerPoint;
-			if ( initialJoinIsOnLeftSide !== joinIsOnLeftSide) {
+
+			if ( initialJoinIsOnLeftSide !== joinIsOnLeftSide ) {
+
 				lastOuter = innerPoint;
 				lastInner = outerPoint;
+
 			}
 
 			if ( joinIsOnLeftSide ) {
@@ -1540,10 +1631,10 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 				if ( isMiter ) {
 
 					lastOuter.toArray( vertices, 1 * 3 );
+
 				}
 
-			}
-			else {
+			} else {
 
 				lastInner.toArray( vertices, 1 * 3 );
 				lastInner.toArray( vertices, 3 * 3 );
@@ -1551,6 +1642,7 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 				if ( isMiter ) {
 
 					lastOuter.toArray( vertices, 0 * 3 );
+
 				}
 
 			}
@@ -1615,11 +1707,11 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 			var dot = tempV2_1.dot( tempV2_2 );
 			if ( Math.abs( dot ) < 1 ) angle = Math.abs( Math.acos( dot ) );
 
-			angle /= arcLengthDivisions;
+			angle /= arcDivisions;
 
 			tempV2_3.copy( p1 );
 
-			for ( var i = 0, il = arcLengthDivisions - 1; i < il; i++ ) {
+			for ( var i = 0, il = arcDivisions - 1; i < il; i ++ ) {
 
 				tempV2_4.copy( tempV2_3 ).rotateAround( center, angle );
 
@@ -1628,6 +1720,7 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 				addVertex( center, u, 0.5 );
 
 				tempV2_3.copy( tempV2_4 );
+
 			}
 
 			addVertex( tempV2_4, u, v );
@@ -1672,8 +1765,7 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 					addVertex( nextPointL, u, 0 );
 					addVertex( innerPoint, u, 0.5 );
 
-				}
-				else {
+				} else {
 
 					// Path segments triangles
 
@@ -1693,8 +1785,7 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 
 				}
 
-			}
-			else {
+			} else {
 
 				// Bevel join triangle. The segment triangles are done in the main loop
 
@@ -1704,8 +1795,7 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 					addVertex( nextPointL, u, 0 );
 					addVertex( currentPoint, u, 0.5 );
 
-				}
-				else {
+				} else {
 
 					addVertex( currentPointR, u, 1 );
 					addVertex( nextPointR, u, 0 );
@@ -1739,8 +1829,7 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 					addVertex( nextPointL, u0, 0 );
 					addVertex( innerPoint, u1, 1 );
 
-				}
-				else {
+				} else {
 
 					addVertex( lastPointR, u0, 1 );
 					addVertex( lastPointL, u0, 0 );
@@ -1777,8 +1866,7 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 
 						makeCircularSector( center, p2, p1, u, 0.5 );
 
-					}
-					else {
+					} else {
 
 						makeCircularSector( center, p1, p2, u, 0.5 );
 
@@ -1803,8 +1891,7 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 							tempV2_4.toArray( vertices, 0 * 3 );
 							tempV2_4.toArray( vertices, 3 * 3 );
 
-						}
-						else {
+						} else {
 
 							tempV2_3.toArray( vertices, 1 * 3 );
 							tempV2_3.toArray( vertices, 3 * 3 );
@@ -1812,8 +1899,7 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 
 						}
 
-					}
-					else {
+					} else {
 
 						tempV2_1.subVectors( p2, center );
 						tempV2_2.set( tempV2_1.y, - tempV2_1.x );
@@ -1830,8 +1916,7 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 							tempV2_4.toArray( vertices, vl - 2 * 3 );
 							tempV2_4.toArray( vertices, vl - 4 * 3 );
 
-						}
-						else {
+						} else {
 
 							tempV2_3.toArray( vertices, vl - 2 * 3 );
 							tempV2_4.toArray( vertices, vl - 1 * 3 );
@@ -1882,6 +1967,7 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 					newPoints.push( points[ i ] );
 
 				}
+
 			}
 
 			newPoints.push( points[ points.length - 1 ] );
@@ -1889,6 +1975,7 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () {
 			return newPoints;
 
 		}
+
 	};
 
 }();

+ 15 - 3
examples/js/loaders/VTKLoader.js

@@ -99,7 +99,13 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 
 				var line = lines[ i ];
 
-				if ( inPointsSection ) {
+				if ( line.indexOf( 'DATASET' ) === 0 ) {
+
+					var dataset = line.split( ' ' )[ 1 ];
+
+					if ( dataset !== 'POLYDATA' ) throw new Error( 'Unsupported DATASET type: ' + dataset );
+
+				} else if ( inPointsSection ) {
 
 					// get the vertices
 					while ( ( result = pat3Floats.exec( line ) ) !== null ) {
@@ -354,7 +360,13 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 				state = findString( buffer, index );
 				line = state.parsedString;
 
-				if ( line.indexOf( 'POINTS' ) === 0 ) {
+				if ( line.indexOf( 'DATASET' ) === 0 ) {
+
+					var dataset = line.split( ' ' )[ 1 ];
+
+					if ( dataset !== 'POLYDATA' ) throw new Error( 'Unsupported DATASET type: ' + dataset );
+
+				} else if ( line.indexOf( 'POINTS' ) === 0 ) {
 
 					vtk.push( line );
 					// Add the points
@@ -1117,7 +1129,7 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 
 			} else {
 
-				// TODO for vtu,vti,and other xml formats
+				throw new Error( 'Unsupported DATASET type' );
 
 			}
 

+ 72 - 0
examples/js/math/ImprovedNoise.js

@@ -0,0 +1,72 @@
+// http://mrl.nyu.edu/~perlin/noise/
+
+THREE.ImprovedNoise = function () {
+
+	var p = [ 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10,
+		 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87,
+		 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211,
+		 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208,
+		 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5,
+		 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119,
+		 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232,
+		 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249,
+		 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205,
+		 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180 ];
+
+	for ( var i = 0; i < 256; i ++ ) {
+
+		p[ 256 + i ] = p[ i ];
+
+	}
+
+	function fade( t ) {
+
+		return t * t * t * ( t * ( t * 6 - 15 ) + 10 );
+
+	}
+
+	function lerp( t, a, b ) {
+
+		return a + t * ( b - a );
+
+	}
+
+	function grad( hash, x, y, z ) {
+
+		var h = hash & 15;
+		var u = h < 8 ? x : y, v = h < 4 ? y : h == 12 || h == 14 ? x : z;
+		return ( ( h & 1 ) == 0 ? u : - u ) + ( ( h & 2 ) == 0 ? v : - v );
+
+	}
+
+	return {
+
+		noise: function ( x, y, z ) {
+
+			var floorX = Math.floor( x ), floorY = Math.floor( y ), floorZ = Math.floor( z );
+
+			var X = floorX & 255, Y = floorY & 255, Z = floorZ & 255;
+
+			x -= floorX;
+			y -= floorY;
+			z -= floorZ;
+
+			var xMinus1 = x - 1, yMinus1 = y - 1, zMinus1 = z - 1;
+
+			var u = fade( x ), v = fade( y ), w = fade( z );
+
+			var A = p[ X ] + Y, AA = p[ A ] + Z, AB = p[ A + 1 ] + Z, B = p[ X + 1 ] + Y, BA = p[ B ] + Z, BB = p[ B + 1 ] + Z;
+
+			return lerp( w, lerp( v, lerp( u, grad( p[ AA ], x, y, z ),
+				grad( p[ BA ], xMinus1, y, z ) ),
+			lerp( u, grad( p[ AB ], x, yMinus1, z ),
+				grad( p[ BB ], xMinus1, yMinus1, z ) ) ),
+			lerp( v, lerp( u, grad( p[ AA + 1 ], x, y, zMinus1 ),
+				grad( p[ BA + 1 ], xMinus1, y, z - 1 ) ),
+			lerp( u, grad( p[ AB + 1 ], x, yMinus1, zMinus1 ),
+				grad( p[ BB + 1 ], xMinus1, yMinus1, zMinus1 ) ) ) );
+
+		}
+	};
+
+};

+ 0 - 15
examples/js/math/Lut.js

@@ -10,20 +10,6 @@ THREE.Lut = function ( colormap, numberofcolors ) {
 
 };
 
-var defaultLabelParameters = {
-	fontsize: 24,
-	fontface: 'Arial',
-	title: '',
-	um: '',
-	ticks: 0,
-	decimal: 2,
-	notation: 'standard'
-};
-
-var defaultBackgroundColor = { r: 255, g: 100, b: 100, a: 0.8 };
-var defaultBorderColor = { r: 255, g: 0, b: 0, a: 1.0 };
-var defaultBorderThickness = 4;
-
 THREE.Lut.prototype = {
 
 	constructor: THREE.Lut,
@@ -189,7 +175,6 @@ THREE.Lut.prototype = {
 	}
 };
 
-
 THREE.ColorMapKeywords = {
 
 	"rainbow": [[ 0.0, 0x0000FF ], [ 0.2, 0x00FFFF ], [ 0.5, 0x00FF00 ], [ 0.8, 0xFFFF00 ], [ 1.0, 0xFF0000 ]],

+ 405 - 0
examples/js/math/SimplexNoise.js

@@ -0,0 +1,405 @@
+// Ported from Stefan Gustavson's java implementation
+// http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
+// Read Stefan's excellent paper for details on how this code works.
+//
+// Sean McCullough [email protected]
+//
+// Added 4D noise
+// Joshua Koo [email protected]
+
+/**
+ * You can pass in a random number generator object if you like.
+ * It is assumed to have a random() method.
+ */
+THREE.SimplexNoise = function ( r ) {
+
+	if ( r == undefined ) r = Math;
+	this.grad3 = [[ 1, 1, 0 ], [ - 1, 1, 0 ], [ 1, - 1, 0 ], [ - 1, - 1, 0 ],
+		[ 1, 0, 1 ], [ - 1, 0, 1 ], [ 1, 0, - 1 ], [ - 1, 0, - 1 ],
+		[ 0, 1, 1 ], [ 0, - 1, 1 ], [ 0, 1, - 1 ], [ 0, - 1, - 1 ]];
+
+	this.grad4 = [[ 0, 1, 1, 1 ], [ 0, 1, 1, - 1 ], [ 0, 1, - 1, 1 ], [ 0, 1, - 1, - 1 ],
+	     [ 0, - 1, 1, 1 ], [ 0, - 1, 1, - 1 ], [ 0, - 1, - 1, 1 ], [ 0, - 1, - 1, - 1 ],
+	     [ 1, 0, 1, 1 ], [ 1, 0, 1, - 1 ], [ 1, 0, - 1, 1 ], [ 1, 0, - 1, - 1 ],
+	     [ - 1, 0, 1, 1 ], [ - 1, 0, 1, - 1 ], [ - 1, 0, - 1, 1 ], [ - 1, 0, - 1, - 1 ],
+	     [ 1, 1, 0, 1 ], [ 1, 1, 0, - 1 ], [ 1, - 1, 0, 1 ], [ 1, - 1, 0, - 1 ],
+	     [ - 1, 1, 0, 1 ], [ - 1, 1, 0, - 1 ], [ - 1, - 1, 0, 1 ], [ - 1, - 1, 0, - 1 ],
+	     [ 1, 1, 1, 0 ], [ 1, 1, - 1, 0 ], [ 1, - 1, 1, 0 ], [ 1, - 1, - 1, 0 ],
+	     [ - 1, 1, 1, 0 ], [ - 1, 1, - 1, 0 ], [ - 1, - 1, 1, 0 ], [ - 1, - 1, - 1, 0 ]];
+
+	this.p = [];
+	for ( var i = 0; i < 256; i ++ ) {
+
+		this.p[ i ] = Math.floor( r.random() * 256 );
+
+	}
+	// To remove the need for index wrapping, double the permutation table length
+	this.perm = [];
+	for ( var i = 0; i < 512; i ++ ) {
+
+		this.perm[ i ] = this.p[ i & 255 ];
+
+	}
+
+	// A lookup table to traverse the simplex around a given point in 4D.
+	// Details can be found where this table is used, in the 4D noise method.
+	this.simplex = [
+		[ 0, 1, 2, 3 ], [ 0, 1, 3, 2 ], [ 0, 0, 0, 0 ], [ 0, 2, 3, 1 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 1, 2, 3, 0 ],
+		[ 0, 2, 1, 3 ], [ 0, 0, 0, 0 ], [ 0, 3, 1, 2 ], [ 0, 3, 2, 1 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 1, 3, 2, 0 ],
+		[ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ],
+		[ 1, 2, 0, 3 ], [ 0, 0, 0, 0 ], [ 1, 3, 0, 2 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 2, 3, 0, 1 ], [ 2, 3, 1, 0 ],
+		[ 1, 0, 2, 3 ], [ 1, 0, 3, 2 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 2, 0, 3, 1 ], [ 0, 0, 0, 0 ], [ 2, 1, 3, 0 ],
+		[ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ],
+		[ 2, 0, 1, 3 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 3, 0, 1, 2 ], [ 3, 0, 2, 1 ], [ 0, 0, 0, 0 ], [ 3, 1, 2, 0 ],
+		[ 2, 1, 0, 3 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 3, 1, 0, 2 ], [ 0, 0, 0, 0 ], [ 3, 2, 0, 1 ], [ 3, 2, 1, 0 ]];
+
+};
+
+THREE.SimplexNoise.prototype.dot = function ( g, x, y ) {
+
+	return g[ 0 ] * x + g[ 1 ] * y;
+
+};
+
+THREE.SimplexNoise.prototype.dot3 = function ( g, x, y, z ) {
+
+	return g[ 0 ] * x + g[ 1 ] * y + g[ 2 ] * z;
+
+};
+
+THREE.SimplexNoise.prototype.dot4 = function ( g, x, y, z, w ) {
+
+	return g[ 0 ] * x + g[ 1 ] * y + g[ 2 ] * z + g[ 3 ] * w;
+
+};
+
+THREE.SimplexNoise.prototype.noise = function ( xin, yin ) {
+
+	var n0, n1, n2; // Noise contributions from the three corners
+	// Skew the input space to determine which simplex cell we're in
+	var F2 = 0.5 * ( Math.sqrt( 3.0 ) - 1.0 );
+	var s = ( xin + yin ) * F2; // Hairy factor for 2D
+	var i = Math.floor( xin + s );
+	var j = Math.floor( yin + s );
+	var G2 = ( 3.0 - Math.sqrt( 3.0 ) ) / 6.0;
+	var t = ( i + j ) * G2;
+	var X0 = i - t; // Unskew the cell origin back to (x,y) space
+	var Y0 = j - t;
+	var x0 = xin - X0; // The x,y distances from the cell origin
+	var y0 = yin - Y0;
+	// For the 2D case, the simplex shape is an equilateral triangle.
+	// Determine which simplex we are in.
+	var i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords
+	if ( x0 > y0 ) {
+
+		i1 = 1; j1 = 0;
+
+		// lower triangle, XY order: (0,0)->(1,0)->(1,1)
+
+	}	else {
+
+		i1 = 0; j1 = 1;
+
+	} // upper triangle, YX order: (0,0)->(0,1)->(1,1)
+	// A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
+	// a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
+	// c = (3-sqrt(3))/6
+	var x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords
+	var y1 = y0 - j1 + G2;
+	var x2 = x0 - 1.0 + 2.0 * G2; // Offsets for last corner in (x,y) unskewed coords
+	var y2 = y0 - 1.0 + 2.0 * G2;
+	// Work out the hashed gradient indices of the three simplex corners
+	var ii = i & 255;
+	var jj = j & 255;
+	var gi0 = this.perm[ ii + this.perm[ jj ] ] % 12;
+	var gi1 = this.perm[ ii + i1 + this.perm[ jj + j1 ] ] % 12;
+	var gi2 = this.perm[ ii + 1 + this.perm[ jj + 1 ] ] % 12;
+	// Calculate the contribution from the three corners
+	var t0 = 0.5 - x0 * x0 - y0 * y0;
+	if ( t0 < 0 ) n0 = 0.0;
+	else {
+
+		t0 *= t0;
+		n0 = t0 * t0 * this.dot( this.grad3[ gi0 ], x0, y0 ); // (x,y) of grad3 used for 2D gradient
+
+	}
+	var t1 = 0.5 - x1 * x1 - y1 * y1;
+	if ( t1 < 0 ) n1 = 0.0;
+	else {
+
+		t1 *= t1;
+		n1 = t1 * t1 * this.dot( this.grad3[ gi1 ], x1, y1 );
+
+	}
+	var t2 = 0.5 - x2 * x2 - y2 * y2;
+	if ( t2 < 0 ) n2 = 0.0;
+	else {
+
+		t2 *= t2;
+		n2 = t2 * t2 * this.dot( this.grad3[ gi2 ], x2, y2 );
+
+	}
+	// Add contributions from each corner to get the final noise value.
+	// The result is scaled to return values in the interval [-1,1].
+	return 70.0 * ( n0 + n1 + n2 );
+
+};
+
+// 3D simplex noise
+THREE.SimplexNoise.prototype.noise3d = function ( xin, yin, zin ) {
+
+	var n0, n1, n2, n3; // Noise contributions from the four corners
+	// Skew the input space to determine which simplex cell we're in
+	var F3 = 1.0 / 3.0;
+	var s = ( xin + yin + zin ) * F3; // Very nice and simple skew factor for 3D
+	var i = Math.floor( xin + s );
+	var j = Math.floor( yin + s );
+	var k = Math.floor( zin + s );
+	var G3 = 1.0 / 6.0; // Very nice and simple unskew factor, too
+	var t = ( i + j + k ) * G3;
+	var X0 = i - t; // Unskew the cell origin back to (x,y,z) space
+	var Y0 = j - t;
+	var Z0 = k - t;
+	var x0 = xin - X0; // The x,y,z distances from the cell origin
+	var y0 = yin - Y0;
+	var z0 = zin - Z0;
+	// For the 3D case, the simplex shape is a slightly irregular tetrahedron.
+	// Determine which simplex we are in.
+	var i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords
+	var i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords
+	if ( x0 >= y0 ) {
+
+		if ( y0 >= z0 ) {
+
+			i1 = 1; j1 = 0; k1 = 0; i2 = 1; j2 = 1; k2 = 0;
+
+			// X Y Z order
+
+		} else if ( x0 >= z0 ) {
+
+			i1 = 1; j1 = 0; k1 = 0; i2 = 1; j2 = 0; k2 = 1;
+
+			// X Z Y order
+
+		} else {
+
+			i1 = 0; j1 = 0; k1 = 1; i2 = 1; j2 = 0; k2 = 1;
+
+		} // Z X Y order
+
+	} else { // x0<y0
+
+		if ( y0 < z0 ) {
+
+			i1 = 0; j1 = 0; k1 = 1; i2 = 0; j2 = 1; k2 = 1;
+
+			// Z Y X order
+
+		} else if ( x0 < z0 ) {
+
+			i1 = 0; j1 = 1; k1 = 0; i2 = 0; j2 = 1; k2 = 1;
+
+			// Y Z X order
+
+		} else {
+
+			i1 = 0; j1 = 1; k1 = 0; i2 = 1; j2 = 1; k2 = 0;
+
+		} // Y X Z order
+
+	}
+	// A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z),
+	// a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and
+	// a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where
+	// c = 1/6.
+	var x1 = x0 - i1 + G3; // Offsets for second corner in (x,y,z) coords
+	var y1 = y0 - j1 + G3;
+	var z1 = z0 - k1 + G3;
+	var x2 = x0 - i2 + 2.0 * G3; // Offsets for third corner in (x,y,z) coords
+	var y2 = y0 - j2 + 2.0 * G3;
+	var z2 = z0 - k2 + 2.0 * G3;
+	var x3 = x0 - 1.0 + 3.0 * G3; // Offsets for last corner in (x,y,z) coords
+	var y3 = y0 - 1.0 + 3.0 * G3;
+	var z3 = z0 - 1.0 + 3.0 * G3;
+	// Work out the hashed gradient indices of the four simplex corners
+	var ii = i & 255;
+	var jj = j & 255;
+	var kk = k & 255;
+	var gi0 = this.perm[ ii + this.perm[ jj + this.perm[ kk ] ] ] % 12;
+	var gi1 = this.perm[ ii + i1 + this.perm[ jj + j1 + this.perm[ kk + k1 ] ] ] % 12;
+	var gi2 = this.perm[ ii + i2 + this.perm[ jj + j2 + this.perm[ kk + k2 ] ] ] % 12;
+	var gi3 = this.perm[ ii + 1 + this.perm[ jj + 1 + this.perm[ kk + 1 ] ] ] % 12;
+	// Calculate the contribution from the four corners
+	var t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0;
+	if ( t0 < 0 ) n0 = 0.0;
+	else {
+
+		t0 *= t0;
+		n0 = t0 * t0 * this.dot3( this.grad3[ gi0 ], x0, y0, z0 );
+
+	}
+	var t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1;
+	if ( t1 < 0 ) n1 = 0.0;
+	else {
+
+		t1 *= t1;
+		n1 = t1 * t1 * this.dot3( this.grad3[ gi1 ], x1, y1, z1 );
+
+	}
+	var t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2;
+	if ( t2 < 0 ) n2 = 0.0;
+	else {
+
+		t2 *= t2;
+		n2 = t2 * t2 * this.dot3( this.grad3[ gi2 ], x2, y2, z2 );
+
+	}
+	var t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3;
+	if ( t3 < 0 ) n3 = 0.0;
+	else {
+
+		t3 *= t3;
+		n3 = t3 * t3 * this.dot3( this.grad3[ gi3 ], x3, y3, z3 );
+
+	}
+	// Add contributions from each corner to get the final noise value.
+	// The result is scaled to stay just inside [-1,1]
+	return 32.0 * ( n0 + n1 + n2 + n3 );
+
+};
+
+// 4D simplex noise
+THREE.SimplexNoise.prototype.noise4d = function ( x, y, z, w ) {
+
+	// For faster and easier lookups
+	var grad4 = this.grad4;
+	var simplex = this.simplex;
+	var perm = this.perm;
+
+	// The skewing and unskewing factors are hairy again for the 4D case
+	var F4 = ( Math.sqrt( 5.0 ) - 1.0 ) / 4.0;
+	var G4 = ( 5.0 - Math.sqrt( 5.0 ) ) / 20.0;
+	var n0, n1, n2, n3, n4; // Noise contributions from the five corners
+	// Skew the (x,y,z,w) space to determine which cell of 24 simplices we're in
+	var s = ( x + y + z + w ) * F4; // Factor for 4D skewing
+	var i = Math.floor( x + s );
+	var j = Math.floor( y + s );
+	var k = Math.floor( z + s );
+	var l = Math.floor( w + s );
+	var t = ( i + j + k + l ) * G4; // Factor for 4D unskewing
+	var X0 = i - t; // Unskew the cell origin back to (x,y,z,w) space
+	var Y0 = j - t;
+	var Z0 = k - t;
+	var W0 = l - t;
+	var x0 = x - X0; // The x,y,z,w distances from the cell origin
+	var y0 = y - Y0;
+	var z0 = z - Z0;
+	var w0 = w - W0;
+
+	// For the 4D case, the simplex is a 4D shape I won't even try to describe.
+	// To find out which of the 24 possible simplices we're in, we need to
+	// determine the magnitude ordering of x0, y0, z0 and w0.
+	// The method below is a good way of finding the ordering of x,y,z,w and
+	// then find the correct traversal order for the simplex we’re in.
+	// First, six pair-wise comparisons are performed between each possible pair
+	// of the four coordinates, and the results are used to add up binary bits
+	// for an integer index.
+	var c1 = ( x0 > y0 ) ? 32 : 0;
+	var c2 = ( x0 > z0 ) ? 16 : 0;
+	var c3 = ( y0 > z0 ) ? 8 : 0;
+	var c4 = ( x0 > w0 ) ? 4 : 0;
+	var c5 = ( y0 > w0 ) ? 2 : 0;
+	var c6 = ( z0 > w0 ) ? 1 : 0;
+	var c = c1 + c2 + c3 + c4 + c5 + c6;
+	var i1, j1, k1, l1; // The integer offsets for the second simplex corner
+	var i2, j2, k2, l2; // The integer offsets for the third simplex corner
+	var i3, j3, k3, l3; // The integer offsets for the fourth simplex corner
+	// simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order.
+	// Many values of c will never occur, since e.g. x>y>z>w makes x<z, y<w and x<w
+	// impossible. Only the 24 indices which have non-zero entries make any sense.
+	// We use a thresholding to set the coordinates in turn from the largest magnitude.
+	// The number 3 in the "simplex" array is at the position of the largest coordinate.
+	i1 = simplex[ c ][ 0 ] >= 3 ? 1 : 0;
+	j1 = simplex[ c ][ 1 ] >= 3 ? 1 : 0;
+	k1 = simplex[ c ][ 2 ] >= 3 ? 1 : 0;
+	l1 = simplex[ c ][ 3 ] >= 3 ? 1 : 0;
+	// The number 2 in the "simplex" array is at the second largest coordinate.
+	i2 = simplex[ c ][ 0 ] >= 2 ? 1 : 0;
+	j2 = simplex[ c ][ 1 ] >= 2 ? 1 : 0; k2 = simplex[ c ][ 2 ] >= 2 ? 1 : 0;
+	l2 = simplex[ c ][ 3 ] >= 2 ? 1 : 0;
+	// The number 1 in the "simplex" array is at the second smallest coordinate.
+	i3 = simplex[ c ][ 0 ] >= 1 ? 1 : 0;
+	j3 = simplex[ c ][ 1 ] >= 1 ? 1 : 0;
+	k3 = simplex[ c ][ 2 ] >= 1 ? 1 : 0;
+	l3 = simplex[ c ][ 3 ] >= 1 ? 1 : 0;
+	// The fifth corner has all coordinate offsets = 1, so no need to look that up.
+	var x1 = x0 - i1 + G4; // Offsets for second corner in (x,y,z,w) coords
+	var y1 = y0 - j1 + G4;
+	var z1 = z0 - k1 + G4;
+	var w1 = w0 - l1 + G4;
+	var x2 = x0 - i2 + 2.0 * G4; // Offsets for third corner in (x,y,z,w) coords
+	var y2 = y0 - j2 + 2.0 * G4;
+	var z2 = z0 - k2 + 2.0 * G4;
+	var w2 = w0 - l2 + 2.0 * G4;
+	var x3 = x0 - i3 + 3.0 * G4; // Offsets for fourth corner in (x,y,z,w) coords
+	var y3 = y0 - j3 + 3.0 * G4;
+	var z3 = z0 - k3 + 3.0 * G4;
+	var w3 = w0 - l3 + 3.0 * G4;
+	var x4 = x0 - 1.0 + 4.0 * G4; // Offsets for last corner in (x,y,z,w) coords
+	var y4 = y0 - 1.0 + 4.0 * G4;
+	var z4 = z0 - 1.0 + 4.0 * G4;
+	var w4 = w0 - 1.0 + 4.0 * G4;
+	// Work out the hashed gradient indices of the five simplex corners
+	var ii = i & 255;
+	var jj = j & 255;
+	var kk = k & 255;
+	var ll = l & 255;
+	var gi0 = perm[ ii + perm[ jj + perm[ kk + perm[ ll ] ] ] ] % 32;
+	var gi1 = perm[ ii + i1 + perm[ jj + j1 + perm[ kk + k1 + perm[ ll + l1 ] ] ] ] % 32;
+	var gi2 = perm[ ii + i2 + perm[ jj + j2 + perm[ kk + k2 + perm[ ll + l2 ] ] ] ] % 32;
+	var gi3 = perm[ ii + i3 + perm[ jj + j3 + perm[ kk + k3 + perm[ ll + l3 ] ] ] ] % 32;
+	var gi4 = perm[ ii + 1 + perm[ jj + 1 + perm[ kk + 1 + perm[ ll + 1 ] ] ] ] % 32;
+	// Calculate the contribution from the five corners
+	var t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0;
+	if ( t0 < 0 ) n0 = 0.0;
+	else {
+
+		t0 *= t0;
+		n0 = t0 * t0 * this.dot4( grad4[ gi0 ], x0, y0, z0, w0 );
+
+	}
+	var t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1;
+	if ( t1 < 0 ) n1 = 0.0;
+	else {
+
+		t1 *= t1;
+		n1 = t1 * t1 * this.dot4( grad4[ gi1 ], x1, y1, z1, w1 );
+
+	}
+	var t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2;
+	if ( t2 < 0 ) n2 = 0.0;
+	else {
+
+		t2 *= t2;
+		n2 = t2 * t2 * this.dot4( grad4[ gi2 ], x2, y2, z2, w2 );
+
+	} var t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3;
+	if ( t3 < 0 ) n3 = 0.0;
+	else {
+
+		t3 *= t3;
+		n3 = t3 * t3 * this.dot4( grad4[ gi3 ], x3, y3, z3, w3 );
+
+	}
+	var t4 = 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4;
+	if ( t4 < 0 ) n4 = 0.0;
+	else {
+
+		t4 *= t4;
+		n4 = t4 * t4 * this.dot4( grad4[ gi4 ], x4, y4, z4, w4 );
+
+	}
+	// Sum up and scale the result to cover the range [-1,1]
+	return 27.0 * ( n0 + n1 + n2 + n3 + n4 );
+
+};

+ 0 - 5
examples/js/objects/Reflector.js

@@ -28,12 +28,10 @@ THREE.Reflector = function ( geometry, options ) {
 	var rotationMatrix = new THREE.Matrix4();
 	var lookAtPosition = new THREE.Vector3( 0, 0, - 1 );
 	var clipPlane = new THREE.Vector4();
-	var viewport = new THREE.Vector4();
 
 	var view = new THREE.Vector3();
 	var target = new THREE.Vector3();
 	var q = new THREE.Vector4();
-	var size = new THREE.Vector2();
 
 	var textureMatrix = new THREE.Matrix4();
 	var virtualCamera = new THREE.PerspectiveCamera();
@@ -198,17 +196,14 @@ THREE.Reflector.ReflectorShader = {
 	uniforms: {
 
 		'color': {
-			type: 'c',
 			value: null
 		},
 
 		'tDiffuse': {
-			type: 't',
 			value: null
 		},
 
 		'textureMatrix': {
-			type: 'm4',
 			value: null
 		}
 

+ 4 - 0
examples/js/objects/ReflectorRTT.js

@@ -1,3 +1,7 @@
+/**
+ * RTT version
+ */
+
 THREE.ReflectorRTT = function ( geometry, options ) {
 
 	THREE.Reflector.call( this, geometry, options );

+ 19 - 29
examples/js/objects/Refractor.js

@@ -184,43 +184,36 @@ THREE.Refractor = function ( geometry, options ) {
 
 	//
 
-	var render = ( function () {
+	function render( renderer, scene, camera ) {
 
-		var viewport = new THREE.Vector4();
-		var size = new THREE.Vector2();
+		scope.visible = false;
 
-		return function render( renderer, scene, camera ) {
+		var currentRenderTarget = renderer.getRenderTarget();
+		var currentVrEnabled = renderer.vr.enabled;
+		var currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;
 
-			scope.visible = false;
+		renderer.vr.enabled = false; // avoid camera modification
+		renderer.shadowMap.autoUpdate = false; // avoid re-computing shadows
 
-			var currentRenderTarget = renderer.getRenderTarget();
-			var currentVrEnabled = renderer.vr.enabled;
-			var currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;
+		renderer.setRenderTarget( renderTarget );
+		renderer.clear();
+		renderer.render( scene, virtualCamera );
 
-			renderer.vr.enabled = false; // avoid camera modification
-			renderer.shadowMap.autoUpdate = false; // avoid re-computing shadows
+		renderer.vr.enabled = currentVrEnabled;
+		renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
+		renderer.setRenderTarget( currentRenderTarget );
 
-			renderer.setRenderTarget( renderTarget );
-			renderer.clear();
-			renderer.render( scene, virtualCamera );
+		// restore viewport
 
-			renderer.vr.enabled = currentVrEnabled;
-			renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
-			renderer.setRenderTarget( currentRenderTarget );
+		if ( camera.isArrayCamera ) {
 
-			// restore viewport
+			renderer.state.viewport( camera.viewport );
 
-			if ( camera.isArrayCamera ) {
-
-				renderer.state.viewport( camera.viewport );
-
-			}
+		}
 
-			scope.visible = true;
+		scope.visible = true;
 
-		};
-
-	} )();
+	}
 
 	//
 
@@ -262,17 +255,14 @@ THREE.Refractor.RefractorShader = {
 	uniforms: {
 
 		'color': {
-			type: 'c',
 			value: null
 		},
 
 		'tDiffuse': {
-			type: 't',
 			value: null
 		},
 
 		'textureMatrix': {
-			type: 'm4',
 			value: null
 		}
 

+ 10 - 10
examples/js/objects/ShadowMesh.js

@@ -42,23 +42,23 @@ THREE.ShadowMesh.prototype.update = function () {
 
 		var sme = shadowMatrix.elements;
 
-		sme[ 0 ]  = dot - lightPosition4D.x * plane.normal.x;
-		sme[ 4 ]  = - lightPosition4D.x * plane.normal.y;
-		sme[ 8 ]  = - lightPosition4D.x * plane.normal.z;
+		sme[ 0 ] = dot - lightPosition4D.x * plane.normal.x;
+		sme[ 4 ] = - lightPosition4D.x * plane.normal.y;
+		sme[ 8 ] = - lightPosition4D.x * plane.normal.z;
 		sme[ 12 ] = - lightPosition4D.x * - plane.constant;
 
-		sme[ 1 ]  = - lightPosition4D.y * plane.normal.x;
-		sme[ 5 ]  = dot - lightPosition4D.y * plane.normal.y;
-		sme[ 9 ]  = - lightPosition4D.y * plane.normal.z;
+		sme[ 1 ] = - lightPosition4D.y * plane.normal.x;
+		sme[ 5 ] = dot - lightPosition4D.y * plane.normal.y;
+		sme[ 9 ] = - lightPosition4D.y * plane.normal.z;
 		sme[ 13 ] = - lightPosition4D.y * - plane.constant;
 
-		sme[ 2 ]  = - lightPosition4D.z * plane.normal.x;
-		sme[ 6 ]  = - lightPosition4D.z * plane.normal.y;
+		sme[ 2 ] = - lightPosition4D.z * plane.normal.x;
+		sme[ 6 ] = - lightPosition4D.z * plane.normal.y;
 		sme[ 10 ] = dot - lightPosition4D.z * plane.normal.z;
 		sme[ 14 ] = - lightPosition4D.z * - plane.constant;
 
-		sme[ 3 ]  = - lightPosition4D.w * plane.normal.x;
-		sme[ 7 ]  = - lightPosition4D.w * plane.normal.y;
+		sme[ 3 ] = - lightPosition4D.w * plane.normal.x;
+		sme[ 7 ] = - lightPosition4D.w * plane.normal.y;
 		sme[ 11 ] = - lightPosition4D.w * plane.normal.z;
 		sme[ 15 ] = dot - lightPosition4D.w * - plane.constant;
 

+ 2 - 2
examples/js/postprocessing/AdaptiveToneMappingPass.js

@@ -125,7 +125,7 @@ THREE.AdaptiveToneMappingPass.prototype = Object.assign( Object.create( THREE.Pa
 
 	constructor: THREE.AdaptiveToneMappingPass,
 
-	render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
+	render: function ( renderer, writeBuffer, readBuffer, deltaTime/*, maskActive*/ ) {
 
 		if ( this.needsInit ) {
 
@@ -183,7 +183,7 @@ THREE.AdaptiveToneMappingPass.prototype = Object.assign( Object.create( THREE.Pa
 
 	},
 
-	reset: function ( renderer ) {
+	reset: function () {
 
 		// render targets
 		if ( this.luminanceRT ) {

+ 4 - 6
examples/js/postprocessing/BokehPass.js

@@ -2,7 +2,6 @@
  * Depth-of-field post-process with bokeh shader
  */
 
-
 THREE.BokehPass = function ( scene, camera, params ) {
 
 	THREE.Pass.call( this );
@@ -69,7 +68,6 @@ THREE.BokehPass = function ( scene, camera, params ) {
 	this.fsQuad = new THREE.Pass.FullScreenQuad( this.materialBokeh );
 
 	this.oldClearColor = new THREE.Color();
-	this.oldClearAlpha = 1;
 
 };
 
@@ -77,14 +75,14 @@ THREE.BokehPass.prototype = Object.assign( Object.create( THREE.Pass.prototype )
 
 	constructor: THREE.BokehPass,
 
-	render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
+	render: function ( renderer, writeBuffer, readBuffer/*, deltaTime, maskActive*/ ) {
 
 		// Render depth into texture
 
 		this.scene.overrideMaterial = this.materialDepth;
 
 		this.oldClearColor.copy( renderer.getClearColor() );
-		this.oldClearAlpha = renderer.getClearAlpha();
+		var oldClearAlpha = renderer.getClearAlpha();
 		var oldAutoClear = renderer.autoClear;
 		renderer.autoClear = false;
 
@@ -115,8 +113,8 @@ THREE.BokehPass.prototype = Object.assign( Object.create( THREE.Pass.prototype )
 
 		this.scene.overrideMaterial = null;
 		renderer.setClearColor( this.oldClearColor );
-		renderer.setClearAlpha( this.oldClearAlpha );
-		renderer.autoClear = this.oldAutoClear;
+		renderer.setClearAlpha( oldClearAlpha );
+		renderer.autoClear = oldAutoClear;
 
 	}
 

+ 1 - 1
examples/js/postprocessing/ClearPass.js

@@ -17,7 +17,7 @@ THREE.ClearPass.prototype = Object.assign( Object.create( THREE.Pass.prototype )
 
 	constructor: THREE.ClearPass,
 
-	render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
+	render: function ( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) {
 
 		var oldClearColor, oldClearAlpha;
 

+ 1 - 1
examples/js/postprocessing/CubeTexturePass.js

@@ -36,7 +36,7 @@ THREE.CubeTexturePass.prototype = Object.assign( Object.create( THREE.Pass.proto
 
 	constructor: THREE.CubeTexturePass,
 
-	render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
+	render: function ( renderer, writeBuffer, readBuffer/*, deltaTime, maskActive*/ ) {
 
 		var oldAutoClear = renderer.autoClear;
 		renderer.autoClear = false;

+ 1 - 1
examples/js/postprocessing/DotScreenPass.js

@@ -33,7 +33,7 @@ THREE.DotScreenPass.prototype = Object.assign( Object.create( THREE.Pass.prototy
 
 	constructor: THREE.DotScreenPass,
 
-	render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
+	render: function ( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) {
 
 		this.uniforms[ "tDiffuse" ].value = readBuffer.texture;
 		this.uniforms[ "tSize" ].value.set( readBuffer.width, readBuffer.height );

+ 2 - 2
examples/js/postprocessing/EffectComposer.js

@@ -240,9 +240,9 @@ THREE.Pass = function () {
 
 Object.assign( THREE.Pass.prototype, {
 
-	setSize: function ( width, height ) {},
+	setSize: function ( /* width, height */ ) {},
 
-	render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
+	render: function ( /* renderer, writeBuffer, readBuffer, deltaTime, maskActive */ ) {
 
 		console.error( 'THREE.Pass: .render() must be implemented in derived pass.' );
 

+ 1 - 1
examples/js/postprocessing/FilmPass.js

@@ -34,7 +34,7 @@ THREE.FilmPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ),
 
 	constructor: THREE.FilmPass,
 
-	render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
+	render: function ( renderer, writeBuffer, readBuffer, deltaTime /*, maskActive */ ) {
 
 		this.uniforms[ "tDiffuse" ].value = readBuffer.texture;
 		this.uniforms[ "time" ].value += deltaTime;

+ 1 - 1
examples/js/postprocessing/GlitchPass.js

@@ -35,7 +35,7 @@ THREE.GlitchPass.prototype = Object.assign( Object.create( THREE.Pass.prototype
 
 	constructor: THREE.GlitchPass,
 
-	render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
+	render: function ( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) {
 
 		this.uniforms[ "tDiffuse" ].value = readBuffer.texture;
 		this.uniforms[ 'seed' ].value = Math.random();//default seeding

+ 1 - 1
examples/js/postprocessing/HalftonePass.js

@@ -44,7 +44,7 @@ THREE.HalftonePass.prototype = Object.assign( Object.create( THREE.Pass.prototyp
 
 	constructor: THREE.HalftonePass,
 
-	render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
+	render: function ( renderer, writeBuffer, readBuffer/*, deltaTime, maskActive*/ ) {
 
  		this.material.uniforms[ "tDiffuse" ].value = readBuffer.texture;
 

+ 2 - 2
examples/js/postprocessing/MaskPass.js

@@ -20,7 +20,7 @@ THREE.MaskPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ),
 
 	constructor: THREE.MaskPass,
 
-	render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
+	render: function ( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) {
 
 		var context = renderer.context;
 		var state = renderer.state;
@@ -93,7 +93,7 @@ THREE.ClearMaskPass.prototype = Object.create( THREE.Pass.prototype );
 
 Object.assign( THREE.ClearMaskPass.prototype, {
 
-	render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
+	render: function ( renderer /*, writeBuffer, readBuffer, deltaTime, maskActive */ ) {
 
 		renderer.state.buffers.stencil.setTest( false );
 

+ 1 - 1
examples/js/postprocessing/RenderPass.js

@@ -24,7 +24,7 @@ THREE.RenderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype
 
 	constructor: THREE.RenderPass,
 
-	render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
+	render: function ( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) {
 
 		var oldAutoClear = renderer.autoClear;
 		renderer.autoClear = false;

+ 2 - 2
examples/js/postprocessing/SAOPass.js

@@ -147,7 +147,7 @@ THREE.SAOPass = function ( scene, camera, depthTexture, useNormals, resolution )
 	this.materialCopy.blendDstAlpha = THREE.ZeroFactor;
 	this.materialCopy.blendEquationAlpha = THREE.AddEquation;
 
-	if ( THREE.CopyShader === undefined ) {
+	if ( THREE.UnpackDepthRGBAShader === undefined ) {
 
 		console.error( 'THREE.SAOPass relies on THREE.UnpackDepthRGBAShader' );
 
@@ -175,7 +175,7 @@ THREE.SAOPass.OUTPUT = {
 THREE.SAOPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), {
 	constructor: THREE.SAOPass,
 
-	render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
+	render: function ( renderer, writeBuffer, readBuffer/*, deltaTime, maskActive*/ ) {
 
 		// Rendering readBuffer first when rendering to screen
 		if ( this.renderToScreen ) {

File diff suppressed because it is too large
+ 19 - 14
examples/js/postprocessing/SMAAPass.js


+ 2 - 2
examples/js/postprocessing/SSAOPass.js

@@ -357,13 +357,13 @@ THREE.SSAOPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ),
 
 		var width = 4, height = 4;
 
-		if ( SimplexNoise === undefined ) {
+		if ( THREE.SimplexNoise === undefined ) {
 
 			console.error( 'THREE.SSAOPass: The pass relies on THREE.SimplexNoise.' );
 
 		}
 
-		var simplex = new SimplexNoise();
+		var simplex = new THREE.SimplexNoise();
 
 		var size = width * height;
 		var data = new Float32Array( size * 4 );

+ 2 - 1
examples/js/postprocessing/ShaderPass.js

@@ -30,13 +30,14 @@ THREE.ShaderPass = function ( shader, textureID ) {
 	}
 
 	this.fsQuad = new THREE.Pass.FullScreenQuad( this.material );
+
 };
 
 THREE.ShaderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), {
 
 	constructor: THREE.ShaderPass,
 
-	render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
+	render: function ( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) {
 
 		if ( this.uniforms[ this.textureID ] ) {
 

+ 2 - 2
examples/js/postprocessing/TAARenderPass.js

@@ -12,7 +12,7 @@
  *
  */
 
-THREE.TAARenderPass = function ( scene, camera, params ) {
+THREE.TAARenderPass = function ( scene, camera, clearColor, clearAlpha ) {
 
 	if ( THREE.SSAARenderPass === undefined ) {
 
@@ -20,7 +20,7 @@ THREE.TAARenderPass = function ( scene, camera, params ) {
 
 	}
 
-	THREE.SSAARenderPass.call( this, scene, camera, params );
+	THREE.SSAARenderPass.call( this, scene, camera, clearColor, clearAlpha );
 
 	this.sampleLevel = 0;
 	this.accumulate = false;

+ 2 - 1
examples/js/postprocessing/TexturePass.js

@@ -36,7 +36,7 @@ THREE.TexturePass.prototype = Object.assign( Object.create( THREE.Pass.prototype
 
 	constructor: THREE.TexturePass,
 
-	render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
+	render: function ( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) {
 
 		var oldAutoClear = renderer.autoClear;
 		renderer.autoClear = false;
@@ -52,6 +52,7 @@ THREE.TexturePass.prototype = Object.assign( Object.create( THREE.Pass.prototype
 		this.fsQuad.render( renderer );
 
 		renderer.autoClear = oldAutoClear;
+
 	}
 
 } );

+ 2 - 1
examples/js/postprocessing/UnrealBloomPass.js

@@ -4,6 +4,7 @@
  * Inspired from Unreal Engine
  * https://docs.unrealengine.com/latest/INT/Engine/Rendering/PostProcessEffects/Bloom/
  */
+
 THREE.UnrealBloomPass = function ( resolution, strength, radius, threshold ) {
 
 	THREE.Pass.call( this );
@@ -106,7 +107,7 @@ THREE.UnrealBloomPass = function ( resolution, strength, radius, threshold ) {
 	// copy material
 	if ( THREE.CopyShader === undefined ) {
 
-		console.error( "THREE.BloomPass relies on THREE.CopyShader" );
+		console.error( "THREE.UnrealBloomPass relies on THREE.CopyShader" );
 
 	}
 

+ 28 - 0
examples/js/renderers/SVGRenderer.js

@@ -57,6 +57,8 @@ THREE.SVGRenderer = function () {
 	this.sortObjects = true;
 	this.sortElements = true;
 
+	this.overdraw = 0.5;
+
 	this.info = {
 
 		render: {
@@ -227,6 +229,14 @@ THREE.SVGRenderer = function () {
 				_v2.positionScreen.x *= _svgWidthHalf; _v2.positionScreen.y *= - _svgHeightHalf;
 				_v3.positionScreen.x *= _svgWidthHalf; _v3.positionScreen.y *= - _svgHeightHalf;
 
+				if ( this.overdraw > 0 ) {
+
+					expand( _v1.positionScreen, _v2.positionScreen, this.overdraw );
+					expand( _v2.positionScreen, _v3.positionScreen, this.overdraw );
+					expand( _v3.positionScreen, _v1.positionScreen, this.overdraw );
+
+				}
+
 				_elemBox.setFromPoints( [
 					_v1.positionScreen,
 					_v2.positionScreen,
@@ -451,6 +461,24 @@ THREE.SVGRenderer = function () {
 
 	}
 
+	// Hide anti-alias gaps
+
+	function expand( v1, v2, pixels ) {
+
+		var x = v2.x - v1.x, y = v2.y - v1.y,
+			det = x * x + y * y, idet;
+
+		if ( det === 0 ) return;
+
+		idet = pixels / Math.sqrt( det );
+
+		x *= idet; y *= idet;
+
+		v2.x += x; v2.y += y;
+		v1.x -= x; v1.y -= y;
+
+	}
+
 	function addPath( style, path ) {
 
 		if ( _currentStyle === style ) {

+ 1 - 1
examples/js/shaders/BleachBypassShader.js

@@ -11,7 +11,7 @@ THREE.BleachBypassShader = {
 	uniforms: {
 
 		"tDiffuse": { value: null },
-		"opacity":  { value: 1.0 }
+		"opacity": { value: 1.0 }
 
 	},
 

+ 2 - 2
examples/js/shaders/BlendShader.js

@@ -10,8 +10,8 @@ THREE.BlendShader = {
 
 		"tDiffuse1": { value: null },
 		"tDiffuse2": { value: null },
-		"mixRatio":  { value: 0.5 },
-		"opacity":   { value: 1.0 }
+		"mixRatio": { value: 0.5 },
+		"opacity": { value: 1.0 }
 
 	},
 

+ 11 - 11
examples/js/shaders/BokehShader.js

@@ -15,14 +15,14 @@ THREE.BokehShader = {
 
 	uniforms: {
 
-		"tColor":   { value: null },
-		"tDepth":   { value: null },
-		"focus":    { value: 1.0 },
-		"aspect":   { value: 1.0 },
+		"tColor": { value: null },
+		"tDepth": { value: null },
+		"focus": { value: 1.0 },
+		"aspect": { value: 1.0 },
 		"aperture": { value: 0.025 },
-		"maxblur":  { value: 1.0 },
-		"nearClip":  { value: 1.0 },
-		"farClip":  { value: 1000.0 },
+		"maxblur": { value: 1.0 },
+		"nearClip": { value: 1.0 },
+		"farClip": { value: 1000.0 },
 
 	},
 
@@ -47,7 +47,7 @@ THREE.BokehShader = {
 		"uniform sampler2D tColor;",
 		"uniform sampler2D tDepth;",
 
-		"uniform float maxblur;",  // max blur amount
+		"uniform float maxblur;", // max blur amount
 		"uniform float aperture;", // aperture - bigger values for shallower depth of field
 
 		"uniform float nearClip;",
@@ -73,15 +73,15 @@ THREE.BokehShader = {
 		"	return orthographicDepthToViewZ( depth, nearClip, farClip );",
 		"	#endif",
 		"}",
-		
+
 
 		"void main() {",
 
 			"vec2 aspectcorrect = vec2( 1.0, aspect );",
-	
+
 			"float viewZ = getViewZ( getDepth( vUv ) );",
 
-			"float factor = ( focus + viewZ );",  // viewZ is <= 0, so this is a difference equation
+			"float factor = ( focus + viewZ );", // viewZ is <= 0, so this is a difference equation
 
 			"vec2 dofblur = vec2 ( clamp( factor * aperture, -maxblur, maxblur ) );",
 

+ 21 - 21
examples/js/shaders/BokehShader2.js

@@ -14,37 +14,37 @@ THREE.BokehShader = {
 
 	uniforms: {
 
-		"textureWidth":  { value: 1.0 },
-		"textureHeight":  { value: 1.0 },
+		"textureWidth": { value: 1.0 },
+		"textureHeight": { value: 1.0 },
 
-		"focalDepth":   { value: 1.0 },
-		"focalLength":   { value: 24.0 },
+		"focalDepth": { value: 1.0 },
+		"focalLength": { value: 24.0 },
 		"fstop": { value: 0.9 },
 
-		"tColor":   { value: null },
-		"tDepth":   { value: null },
+		"tColor": { value: null },
+		"tDepth": { value: null },
 
-		"maxblur":  { value: 1.0 },
+		"maxblur": { value: 1.0 },
 
-		"showFocus":   { value: 0 },
-		"manualdof":   { value: 0 },
-		"vignetting":   { value: 0 },
-		"depthblur":   { value: 0 },
+		"showFocus": { value: 0 },
+		"manualdof": { value: 0 },
+		"vignetting": { value: 0 },
+		"depthblur": { value: 0 },
 
-		"threshold":  { value: 0.5 },
-		"gain":  { value: 2.0 },
-		"bias":  { value: 0.5 },
-		"fringe":  { value: 0.7 },
+		"threshold": { value: 0.5 },
+		"gain": { value: 2.0 },
+		"bias": { value: 0.5 },
+		"fringe": { value: 0.7 },
 
-		"znear":  { value: 0.1 },
-		"zfar":  { value: 100 },
+		"znear": { value: 0.1 },
+		"zfar": { value: 100 },
 
-		"noise":  { value: 1 },
-		"dithering":  { value: 0.0001 },
+		"noise": { value: 1 },
+		"dithering": { value: 0.0001 },
 		"pentagon": { value: 0 },
 
-		"shaderFocus":  { value: 1 },
-		"focusCoords":  { value: new THREE.Vector2() }
+		"shaderFocus": { value: 1 },
+		"focusCoords": { value: new THREE.Vector2() }
 
 
 	},

+ 2 - 2
examples/js/shaders/BrightnessContrastShader.js

@@ -11,9 +11,9 @@ THREE.BrightnessContrastShader = {
 
 	uniforms: {
 
-		"tDiffuse":   { value: null },
+		"tDiffuse": { value: null },
 		"brightness": { value: 0 },
-		"contrast":   { value: 0 }
+		"contrast": { value: 0 }
 
 	},
 

+ 3 - 3
examples/js/shaders/ColorCorrectionShader.js

@@ -9,9 +9,9 @@ THREE.ColorCorrectionShader = {
 	uniforms: {
 
 		"tDiffuse": { value: null },
-		"powRGB":   { value: new THREE.Vector3( 2, 2, 2 ) },
-		"mulRGB":   { value: new THREE.Vector3( 1, 1, 1 ) },
-		"addRGB":   { value: new THREE.Vector3( 0, 0, 0 ) }
+		"powRGB": { value: new THREE.Vector3( 2, 2, 2 ) },
+		"mulRGB": { value: new THREE.Vector3( 1, 1, 1 ) },
+		"addRGB": { value: new THREE.Vector3( 0, 0, 0 ) }
 
 	},
 

+ 1 - 1
examples/js/shaders/ColorifyShader.js

@@ -9,7 +9,7 @@ THREE.ColorifyShader = {
 	uniforms: {
 
 		"tDiffuse": { value: null },
-		"color":    { value: new THREE.Color( 0xffffff ) }
+		"color": { value: new THREE.Color( 0xffffff ) }
 
 	},
 

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