Browse Source

Merge pull request #1 from mrdoob/dev

update to latest
luis Wang 7 years ago
parent
commit
d147a35d96
100 changed files with 1902 additions and 1818 deletions
  1. 1 1
      .github/ISSUE_TEMPLATE.md
  2. 50 38
      build/three.js
  3. 394 390
      build/three.min.js
  4. 50 38
      build/three.module.js
  5. 10 4
      docs/api/core/BufferGeometry.html
  6. 15 15
      docs/api/core/Object3D.html
  7. 1 2
      docs/api/extras/core/Font.html
  8. 5 2
      docs/api/geometries/BoxBufferGeometry.html
  9. 5 2
      docs/api/geometries/BoxGeometry.html
  10. 7 0
      docs/api/geometries/CircleBufferGeometry.html
  11. 7 0
      docs/api/geometries/CircleGeometry.html
  12. 2 1
      docs/api/geometries/ConeBufferGeometry.html
  13. 2 1
      docs/api/geometries/ConeGeometry.html
  14. 2 1
      docs/api/geometries/CylinderBufferGeometry.html
  15. 2 1
      docs/api/geometries/CylinderGeometry.html
  16. 1 1
      docs/api/geometries/DodecahedronBufferGeometry.html
  17. 1 1
      docs/api/geometries/DodecahedronGeometry.html
  18. 7 0
      docs/api/geometries/EdgesGeometry.html
  19. 7 0
      docs/api/geometries/ExtrudeBufferGeometry.html
  20. 7 0
      docs/api/geometries/ExtrudeGeometry.html
  21. 1 1
      docs/api/geometries/IcosahedronBufferGeometry.html
  22. 1 1
      docs/api/geometries/IcosahedronGeometry.html
  23. 7 0
      docs/api/geometries/LatheBufferGeometry.html
  24. 7 0
      docs/api/geometries/LatheGeometry.html
  25. 1 1
      docs/api/geometries/OctahedronBufferGeometry.html
  26. 1 1
      docs/api/geometries/OctahedronGeometry.html
  27. 9 2
      docs/api/geometries/ParametricBufferGeometry.html
  28. 8 0
      docs/api/geometries/ParametricGeometry.html
  29. 2 1
      docs/api/geometries/PlaneBufferGeometry.html
  30. 2 1
      docs/api/geometries/PlaneGeometry.html
  31. 1 1
      docs/api/geometries/PolyhedronBufferGeometry.html
  32. 1 1
      docs/api/geometries/PolyhedronGeometry.html
  33. 9 0
      docs/api/geometries/RingBufferGeometry.html
  34. 8 0
      docs/api/geometries/RingGeometry.html
  35. 7 0
      docs/api/geometries/ShapeBufferGeometry.html
  36. 7 0
      docs/api/geometries/ShapeGeometry.html
  37. 2 1
      docs/api/geometries/SphereBufferGeometry.html
  38. 2 1
      docs/api/geometries/SphereGeometry.html
  39. 3 1
      docs/api/geometries/TetrahedronBufferGeometry.html
  40. 1 1
      docs/api/geometries/TetrahedronGeometry.html
  41. 7 0
      docs/api/geometries/TextBufferGeometry.html
  42. 7 0
      docs/api/geometries/TextGeometry.html
  43. 2 1
      docs/api/geometries/TorusBufferGeometry.html
  44. 2 1
      docs/api/geometries/TorusGeometry.html
  45. 2 1
      docs/api/geometries/TorusKnotBufferGeometry.html
  46. 2 1
      docs/api/geometries/TorusKnotGeometry.html
  47. 1 1
      docs/api/geometries/TubeBufferGeometry.html
  48. 1 1
      docs/api/geometries/TubeGeometry.html
  49. 4 3
      docs/api/loaders/ImageBitmapLoader.html
  50. 1 2
      docs/api/loaders/ImageLoader.html
  51. 1 1
      docs/api/loaders/JSONLoader.html
  52. 3 0
      docs/api/materials/PointsMaterial.html
  53. 14 14
      docs/api/math/Matrix3.html
  54. 29 29
      docs/api/math/Matrix4.html
  55. 34 34
      docs/api/math/Vector2.html
  56. 52 52
      docs/api/math/Vector3.html
  57. 35 35
      docs/api/math/Vector4.html
  58. 1 1
      docs/api/objects/Line.html
  59. 1 1
      docs/api/objects/Mesh.html
  60. 1 1
      docs/api/objects/Points.html
  61. 4 1
      docs/api/objects/SkinnedMesh.html
  62. 1 1
      docs/api/objects/Sprite.html
  63. 4 4
      docs/api/renderers/WebGLRenderer.html
  64. 1 0
      docs/api/textures/DataTexture.html
  65. 1 1
      docs/examples/controls/OrbitControls.html
  66. 1 1
      docs/examples/exporters/GLTFExporter.html
  67. 62 0
      docs/examples/exporters/PLYExporter.html
  68. 1 1
      docs/examples/loaders/MMDLoader.html
  69. 2 2
      docs/examples/quickhull/QuickHull.html
  70. 1 0
      docs/examples/renderers/CSS2DRenderer.html
  71. 3 1
      docs/list.js
  72. 5 5
      docs/manual/introduction/Animation-system.html
  73. 4 4
      docs/manual/introduction/Creating-a-scene.html
  74. 3 3
      docs/manual/introduction/FAQ.html
  75. 3 3
      docs/manual/introduction/Import-via-modules.html
  76. 129 0
      docs/manual/introduction/Loading-3D-models.html
  77. 7 0
      docs/manual/introduction/Useful-links.html
  78. 1 1
      docs/page.js
  79. 11 27
      docs/scenes/geometry-browser.html
  80. 4 4
      editor/index.html
  81. 2 2
      editor/js/libs/app.js
  82. 2 2
      examples/canvas_lines_colors.html
  83. 150 0
      examples/css2d_label.html
  84. 6 2
      examples/files.js
  85. 2 7
      examples/js/BufferGeometryUtils.js
  86. 14 10
      examples/js/Cloth.js
  87. 77 67
      examples/js/ConvexObjectBreaker.js
  88. 9 8
      examples/js/MorphBlendMesh.js
  89. 14 28
      examples/js/ParametricGeometries.js
  90. 1 1
      examples/js/animation/CCDIKSolver.js
  91. 8 5
      examples/js/animation/MMDAnimationHelper.js
  92. 14 6
      examples/js/cameras/CinematicCamera.js
  93. 0 149
      examples/js/controls/VRControls.js
  94. 2 4
      examples/js/curves/NURBSSurface.js
  95. 11 14
      examples/js/curves/NURBSUtils.js
  96. 1 1
      examples/js/effects/OutlineEffect.js
  97. 0 533
      examples/js/effects/VREffect.js
  98. 68 23
      examples/js/exporters/GLTFExporter.js
  99. 417 112
      examples/js/exporters/PLYExporter.js
  100. 0 94
      examples/js/exporters/STLBinaryExporter.js

+ 1 - 1
.github/ISSUE_TEMPLATE.md

@@ -19,7 +19,7 @@ Please also include a live example if possible. You can start from these templat
 ##### Three.js version
 
 - [ ] Dev
-- [ ] r92
+- [ ] r93
 - [ ] ...
 
 ##### Browser

File diff suppressed because it is too large
+ 50 - 38
build/three.js


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


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


+ 10 - 4
docs/api/core/BufferGeometry.html

@@ -185,6 +185,12 @@
 		Optional name for this bufferGeometry instance. Default is an empty string.
 		</p>
 
+		<h3>[property:Object userData]</h3>
+		<p>
+		An object that can be used to store custom data about the BufferGeometry. It should not hold
+		references to functions as these will not be cloned.
+		</p>
+
 		<h3>[property:String uuid]</h3>
 		<p>
 		[link:http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] of this object instance.
@@ -195,7 +201,7 @@
 
 		<h3>[page:EventDispatcher EventDispatcher] methods are available on this class.</h3>
 
-		<h3>[method:null addAttribute]( [param:String name], [param:BufferAttribute attribute] )</h3>
+		<h3>[method:BufferGeometry addAttribute]( [param:String name], [param:BufferAttribute attribute] )</h3>
 		<p>
 		Adds an attribute to this geometry. Use this rather than the attributes property,
 		because an internal hashmap of [page:.attributes] is maintained to speed up iterating over
@@ -242,19 +248,19 @@
 		<h3>[method:null dispose]()</h3>
 		<p>
 		Disposes the object from memory. <br />
-		You need to call this when you want the bufferGeometry removed while the application is running.
+		You need to call this when you want the BufferGeometry removed while the application is running.
 		</p>
 
 		<h3>[method:BufferGeometry fromDirectGeometry]( [param:Geometry] )</h3>
 		<p>
-			Populates this BufferGeometry with data from a [page:DirectGeometry] object.<br /><br />
+			Populates this BufferGeometry with data from a [page:DirectGeometry] object containing faces. Not implemented for a line geometry.<br /><br />
 
 			Note: [page:DirectGeometry] is mainly used as an intermediary object for converting between [page:Geometry]
 			and BufferGeometry.
 		</p>
 
 		<h3>[method:BufferGeometry fromGeometry]( [param:Geometry] )</h3>
-		<p>Populates this BufferGeometry with data from a [page:Geometry] object.</p>
+		<p>Populates this BufferGeometry with data from a [page:Geometry] object containing faces. Not implemented for a line geometry.</p>
 
 		<h3>[method:BufferAttribute getAttribute]( [param:String name] )</h3>
 		<p>Returns the [page:BufferAttribute attribute] with the specified name.</p>

+ 15 - 15
docs/api/core/Object3D.html

@@ -45,7 +45,7 @@
 		<h3>[property:Integer id]</h3>
 		<p>readonly – Unique number for this object instance.</p>
 
-		<h3>[property:Boolean isObject]</h3>
+		<h3>[property:Boolean isObject3D]</h3>
 		<p>
 			Used to check whether this or derived classes are Object3Ds. Default is *true*.<br /><br />
 
@@ -191,7 +191,7 @@
 
 		<h3>[method:null add]( [param:Object3D object], ... )</h3>
 		<p>
-		Adds *object* as child of this object. An arbitrary number of objects may be added. Any current parent on an 
+		Adds *object* as child of this object. An arbitrary number of objects may be added. Any current parent on an
 		object passed in here will be removed, since an object can have at most one parent.<br /><br />
 
 		See [page:Group] for info on manually grouping objects.
@@ -210,7 +210,7 @@
 		Returns a clone of this object and optionally all descendants.
 		</p>
 
-		<h3>[method:Object3D copy]( [param:Object3D object], [param:Boolean recursive] )</h3>
+		<h3>[method:this copy]( [param:Object3D object], [param:Boolean recursive] )</h3>
 		<p>
 		recursive -- if true, descendants of the object are also copied. Default is true.<br /><br />
 
@@ -301,7 +301,7 @@
 		Removes *object* as child of this object. An arbitrary number of objects may be removed.
 		</p>
 
-		<h3>[method:Object3D rotateOnAxis]( [param:Vector3 axis], [param:Float angle] )</h3>
+		<h3>[method:this rotateOnAxis]( [param:Vector3 axis], [param:Float angle] )</h3>
 		<p>
 		axis -- A normalized vector in object space. <br />
 		angle -- The angle in radians.<br /><br />
@@ -309,7 +309,7 @@
 		Rotate an object along an axis in object space. The axis is assumed to be normalized.
 		</p>
 
-		<h3>[method:Object3D rotateOnWorldAxis]( [param:Vector3 axis], [param:Float angle] )</h3>
+		<h3>[method:this rotateOnWorldAxis]( [param:Vector3 axis], [param:Float angle] )</h3>
 		<p>
 		axis -- A normalized vector in world space. <br />
 		angle -- The angle in radians.<br /><br />
@@ -318,21 +318,21 @@
 		Method Assumes no rotated parent.
 		</p>
 
-		<h3>[method:null rotateX]( [param:Float rad] )</h3>
+		<h3>[method:this rotateX]( [param:Float rad] )</h3>
 		<p>
 		rad - the angle to rotate in radians.<br /><br />
 
 		Rotates the object around x axis in local space.
 		</p>
 
-		<h3>[method:null rotateY]( [param:Float rad] )</h3>
+		<h3>[method:this rotateY]( [param:Float rad] )</h3>
 		<p>
 		rad - the angle to rotate in radians.<br /><br />
 
 		Rotates the object around y axis in local space.
 		</p>
 
-		<h3>[method:null rotateZ]( [param:Float rad] )</h3>
+		<h3>[method:this rotateZ]( [param:Float rad] )</h3>
 		<p>
 		rad - the angle to rotate in radians.<br /><br />
 
@@ -378,7 +378,7 @@
 			Convert the object to JSON format.
 		</p>
 
-		<h3>[method:Object3D translateOnAxis]( [param:Vector3 axis], [param:Float distance] )</h3>
+		<h3>[method:this translateOnAxis]( [param:Vector3 axis], [param:Float distance] )</h3>
 		<p>
 		axis -- A normalized vector in object space.<br />
 		distance -- The distance to translate.<br /><br />
@@ -386,14 +386,14 @@
 		Translate an object by distance along an axis in object space. The axis is assumed to be normalized.
 		</p>
 
-		<h3>[method:null translateX]( [param:Float distance] )</h3>
-		<p>Translates object along x axis by *distance* units.</p>
+		<h3>[method:this translateX]( [param:Float distance] )</h3>
+		<p>Translates object along x axis in object space by *distance* units.</p>
 
-		<h3>[method:null translateY]( [param:Float distance] )</h3>
-		<p>Translates object along y axis by *distance* units.</p>
+		<h3>[method:this translateY]( [param:Float distance] )</h3>
+		<p>Translates object along y axis in object space by *distance* units.</p>
 
-		<h3>[method:null translateZ]( [param:Float distance] )</h3>
-		<p>Translates object along z axis by *distance* units.</p>
+		<h3>[method:this translateZ]( [param:Float distance] )</h3>
+		<p>Translates object along z axis in object space by *distance* units.</p>
 
 		<h3>[method:null traverse]( [param:Function callback] )</h3>
 		<p>

+ 1 - 2
docs/api/extras/core/Font.html

@@ -46,11 +46,10 @@
 
 		<h2>Methods</h2>
 
-		<h3>[method:null generateShapes]( [param:String text], [param:Float size], [param:Integer divisions] )</h3>
+		<h3>[method:null generateShapes]( [param:String text], [param:Float size] )</h3>
 		<p>
 			[page:String text] -- string of text.<br />
 			[page:Float size] -- (optional) scale for the [page:Shape Shapes]. Default is *100*.<br />
-			[page:Integer divisions] -- (optional) fineness of the [page:Shape Shapes]. Default is *4*.<br />
 
 			Creates an array of [page:Shape Shapes] representing the text in the font.
 		</p>

+ 5 - 2
docs/api/geometries/BoxBufferGeometry.html

@@ -54,9 +54,12 @@
 
 		<h2>Properties</h2>
 
-		<h3>.parameters</h3>
+		<h3>[property:Object parameters]</h3>
+		<p>
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
+		</p>
  		<p>
-			<p>Using the above example code above as our basis:</p>
+			Using the above example code above as our basis:
 			<code>
 		geometry.parameters; // outputs an object {width: 1, height: 1, depth: 1, widthSegments: undefined, heightSegments: undefined}
 		cube.geometry.parameters; // as above

+ 5 - 2
docs/api/geometries/BoxGeometry.html

@@ -54,9 +54,12 @@
 
 		<h2>Properties</h2>
 
-		<h3>.parameters</h3>
+		<h3>[property:Object parameters]</h3>
+		<p>
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
+		</p>
  		<p>
-			<p>Using the above example code above as our basis:</p>
+			Using the above example code above as our basis:
 			<code>
 				geometry.parameters; // outputs an object {width: 1, height: 1, depth: 1, widthSegments: undefined, heightSegments: undefined}
 				cube.geometry.parameters; // as above

+ 7 - 0
docs/api/geometries/CircleBufferGeometry.html

@@ -51,6 +51,13 @@
 		thetaLength — The central angle, often called theta, of the circular sector. The default is 2*Pi, which makes for a complete circle.
 		</p>
 
+		<h2>Properties</h2>
+
+		<h3>[property:Object parameters]</h3>
+		<p>
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
+		</p>
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/geometries/CircleGeometry.js src/geometries/CircleGeometry.js]

+ 7 - 0
docs/api/geometries/CircleGeometry.html

@@ -52,6 +52,13 @@
 		thetaLength — The central angle, often called theta, of the circular sector. The default is 2*Pi, which makes for a complete circle.
 		</p>
 
+		<h2>Properties</h2>
+
+		<h3>[property:Object parameters]</h3>
+		<p>
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
+		</p>
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 2 - 1
docs/api/geometries/ConeBufferGeometry.html

@@ -55,8 +55,9 @@
 
 		<h2>Properties</h2>
 
+		<h3>[property:Object parameters]</h3>
 		<p>
-		Each of the constructor parameters is accessible as a property of the same name. Any modification of these properties after instantiation does not change the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
 		<h2>Source</h2>

+ 2 - 1
docs/api/geometries/ConeGeometry.html

@@ -55,8 +55,9 @@
 
 		<h2>Properties</h2>
 
+		<h3>[property:Object parameters]</h3>
 		<p>
-		Each of the constructor parameters is accessible as a property of the same name. Any modification of these properties after instantiation does not change the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
 		<h2>Source</h2>

+ 2 - 1
docs/api/geometries/CylinderBufferGeometry.html

@@ -56,8 +56,9 @@
 
 		<h2>Properties</h2>
 
+		<h3>[property:Object parameters]</h3>
 		<p>
-		Each of the constructor parameters is accessible as a property of the same name. Any modification of these properties after instantiation does not change the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
 		<h2>Source</h2>

+ 2 - 1
docs/api/geometries/CylinderGeometry.html

@@ -56,8 +56,9 @@
 
 		<h2>Properties</h2>
 
+		<h3>[property:Object parameters]</h3>
 		<p>
-		Each of the constructor parameters is accessible as a property of the same name. Any modification of these properties after instantiation does not change the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
 		<h2>Source</h2>

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

@@ -44,7 +44,7 @@
 
 		<h3>[property:Object parameters]</h3>
 		<p>
-		An object with all of the parameters that were used to generate the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
 		<h2>Source</h2>

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

@@ -44,7 +44,7 @@
 
 		<h3>[property:Object parameters]</h3>
 		<p>
-		An object with all of the parameters that were used to generate the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
 		<h2>Source</h2>

+ 7 - 0
docs/api/geometries/EdgesGeometry.html

@@ -33,6 +33,13 @@ scene.add( line );
 		thresholdAngle — An edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree.
 		</p>
 
+		<h2>Properties</h2>
+
+		<h3>[property:Object parameters]</h3>
+		<p>
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
+		</p>
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 7 - 0
docs/api/geometries/ExtrudeBufferGeometry.html

@@ -92,6 +92,13 @@
 			applied to the face; the second material will be applied to the sides.
 		</p>
 
+		<h2>Properties</h2>
+
+		<h3>[property:Object parameters]</h3>
+		<p>
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
+		</p>
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/geometries/ExtrudeGeometry.js src/geometries/ExtrudeGeometry.js]

+ 7 - 0
docs/api/geometries/ExtrudeGeometry.html

@@ -92,6 +92,13 @@
 			applied to the face; the second material will be applied to the sides.
 		</p>
 
+		<h2>Properties</h2>
+
+		<h3>[property:Object parameters]</h3>
+		<p>
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
+		</p>
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

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

@@ -43,7 +43,7 @@
 
 		<h3>[property:Object parameters]</h3>
 		<p>
-		An object with all of the parameters that were used to generate the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
 		<h2>Source</h2>

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

@@ -44,7 +44,7 @@
 
 		<h3>[property:Object parameters]</h3>
 		<p>
-		An object with all of the parameters that were used to generate the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
 		<h2>Source</h2>

+ 7 - 0
docs/api/geometries/LatheBufferGeometry.html

@@ -58,6 +58,13 @@
 		This creates a LatheBufferGeometry based on the parameters.
 		</p>
 
+		<h2>Properties</h2>
+
+		<h3>[property:Object parameters]</h3>
+		<p>
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
+		</p>
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/geometries/LatheGeometry.js src/geometries/LatheGeometry.js]

+ 7 - 0
docs/api/geometries/LatheGeometry.html

@@ -58,6 +58,13 @@
 		This creates a LatheGeometry based on the parameters.
 		</p>
 
+		<h2>Properties</h2>
+
+		<h3>[property:Object parameters]</h3>
+		<p>
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
+		</p>
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

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

@@ -43,7 +43,7 @@
 
 		<h3>[property:Object parameters]</h3>
 		<p>
-		An object with all of the parameters that were used to generate the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
 		<h2>Source</h2>

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

@@ -44,7 +44,7 @@
 
 		<h3>[property:Object parameters]</h3>
 		<p>
-		An object with all of the parameters that were used to generate the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
 		<h2>Source</h2>

+ 9 - 2
docs/api/geometries/ParametricBufferGeometry.html

@@ -37,8 +37,8 @@
 		<code>
 		var geometry = new THREE.ParametricBufferGeometry( THREE.ParametricGeometries.klein, 25, 25 );
 		var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
-		var cube = new THREE.Mesh( geometry, material );
-		scene.add( cube );
+		var klein = new THREE.Mesh( geometry, material );
+		scene.add( klein );
 		</code>
 
 
@@ -52,6 +52,13 @@
 		stacks — The count of stacks to use for the parametric function
 		</p>
 
+		<h2>Properties</h2>
+
+		<h3>[property:Object parameters]</h3>
+		<p>
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
+		</p>
+
 
 		<h2>Source</h2>
 

+ 8 - 0
docs/api/geometries/ParametricGeometry.html

@@ -53,6 +53,14 @@
 		</p>
 
 
+		<h2>Properties</h2>
+
+		<h3>[property:Object parameters]</h3>
+		<p>
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
+		</p>
+
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 2 - 1
docs/api/geometries/PlaneBufferGeometry.html

@@ -52,8 +52,9 @@
 
 		<h2>Properties</h2>
 
+		<h3>.parameters</h3>
 		<p>
-		Each of the contructor parameters is accessible as a property of the same name. Any modification of these properties after instantiation does not change the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
 		<h2>Source</h2>

+ 2 - 1
docs/api/geometries/PlaneGeometry.html

@@ -52,8 +52,9 @@
 
 		<h2>Properties</h2>
 
+		<h3>.parameters</h3>
 		<p>
-		Each of the contructor parameters is accessible in the parameters property of the object. Any modification of these properties after instantiation does not change the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
 		<h2>Source</h2>

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

@@ -53,7 +53,7 @@ var geometry = new THREE.PolyhedronBufferGeometry( verticesOfCube, indicesOfFace
 
 		<h3>[property:Object parameters]</h3>
 		<p>
-		An object with all of the parameters that were used to generate the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
 

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

@@ -51,7 +51,7 @@ var geometry = new THREE.PolyhedronGeometry( verticesOfCube, indicesOfFaces, 6,
 
 		<h3>[property:Object parameters]</h3>
 		<p>
-		An object with all of the parameters that were used to generate the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
 

+ 9 - 0
docs/api/geometries/RingBufferGeometry.html

@@ -52,6 +52,15 @@
 		thetaLength — Central angle.  Default is Math.PI * 2.
 		</p>
 
+
+		<h2>Properties</h2>
+
+		<h3>[property:Object parameters]</h3>
+		<p>
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
+		</p>
+
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/geometries/RingGeometry.js src/geometries/RingGeometry.js]

+ 8 - 0
docs/api/geometries/RingGeometry.html

@@ -52,6 +52,14 @@
 		thetaLength — Central angle.  Default is Math.PI * 2.
 		</p>
 
+		<h2>Properties</h2>
+
+		<h3>[property:Object parameters]</h3>
+		<p>
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
+		</p>
+		
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 7 - 0
docs/api/geometries/ShapeBufferGeometry.html

@@ -64,6 +64,13 @@
 		curveSegments - [page:Integer] - Number of segments per shape. Default is 12.
 		</p>
 
+		<h2>Properties</h2>
+
+		<h3>[property:Object parameters]</h3>
+		<p>
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
+		</p>
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/geometries/ShapeGeometry.js src/geometries/ShapeGeometry.js]

+ 7 - 0
docs/api/geometries/ShapeGeometry.html

@@ -64,6 +64,13 @@
 		curveSegments - [page:Integer] - Number of segments per shape. Default is 12.
 		</p>
 
+		<h2>Properties</h2>
+
+		<h3>[property:Object parameters]</h3>
+		<p>
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
+		</p>
+
 
 		<h2>Source</h2>
 

+ 2 - 1
docs/api/geometries/SphereBufferGeometry.html

@@ -60,8 +60,9 @@
 
 		<h2>Properties</h2>
 
+		<h3>.parameters</h3>
 		<p>
-		Each of the contructor parameters is accessible as a property of the same name. Any modification of these properties after instantiation does not change the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
 		<h2>Source</h2>

+ 2 - 1
docs/api/geometries/SphereGeometry.html

@@ -60,8 +60,9 @@
 
 		<h2>Properties</h2>
 
+		<h3>.parameters</h3>
 		<p>
-		Each of the contructor parameters is accessible as a property of the same name. Any modification of these properties after instantiation does not change the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
 		<h2>Source</h2>

+ 3 - 1
docs/api/geometries/TetrahedronBufferGeometry.html

@@ -44,9 +44,11 @@
 
 		<h3>[property:Object parameters]</h3>
 		<p>
-		An object with all of the parameters that were used to generate the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
+
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/geometries/TetrahedronGeometry.js src/geometries/TetrahedronGeometry.js]

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

@@ -44,7 +44,7 @@
 
 		<h3>[property:Object parameters]</h3>
 		<p>
-		An object with all of the parameters that were used to generate the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
 		<h2>Source</h2>

+ 7 - 0
docs/api/geometries/TextBufferGeometry.html

@@ -153,6 +153,13 @@
 			</tr>
 		</table>
 
+		<h2>Properties</h2>
+
+		<h3>[property:Object parameters]</h3>
+		<p>
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
+		</p>
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/geometries/TextGeometry.js src/geometries/TextGeometry.js]

+ 7 - 0
docs/api/geometries/TextGeometry.html

@@ -153,6 +153,13 @@
 			</tr>
 		</table>
 
+		<h2>Properties</h2>
+
+		<h3>[property:Object parameters]</h3>
+		<p>
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
+		</p>
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 2 - 1
docs/api/geometries/TorusBufferGeometry.html

@@ -53,8 +53,9 @@
 
 		<h2>Properties</h2>
 
+		<h3>.parameters</h3>
 		<p>
-		Each of the contructor parameters is accessible as a property of the same name. Any modification of these properties after instantiation does not change the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
 		<h2>Source</h2>

+ 2 - 1
docs/api/geometries/TorusGeometry.html

@@ -53,8 +53,9 @@
 
 		<h2>Properties</h2>
 
+		<h3>.parameters</h3>
 		<p>
-		Each of the contructor parameters is accessible as a property of the same name. Any modification of these properties after instantiation does not change the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
 		<h2>Source</h2>

+ 2 - 1
docs/api/geometries/TorusKnotBufferGeometry.html

@@ -56,8 +56,9 @@
 
 		<h2>Properties</h2>
 
+		<h3>.parameters</h3>
 		<p>
-		Each of the contructor parameters is accessible as a property of the same name. Any modification of these properties after instantiation does not change the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
 		<h2>Source</h2>

+ 2 - 1
docs/api/geometries/TorusKnotGeometry.html

@@ -56,8 +56,9 @@
 
 		<h2>Properties</h2>
 
+		<h3>.parameters</h3>
 		<p>
-		Each of the contructor parameters is accessible as a property of the same name. Any modification of these properties after instantiation does not change the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
 		<h2>Source</h2>

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

@@ -80,7 +80,7 @@
 
 		<h3>[property:Object parameters]</h3>
 		<p>
-		An object with all of the parameters that were used to generate the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
 		<h3>[property:Array tangents]</h3>

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

@@ -80,7 +80,7 @@
 
 		<h3>[property:Object parameters]</h3>
 		<p>
-		An object with all of the parameters that were used to generate the geometry.
+		An object with a property for each of the constructor parameters. Any modification after instantiation does not change the geometry.
 		</p>
 
 		<h3>[property:Array tangents]</h3>

+ 4 - 3
docs/api/loaders/ImageBitmapLoader.html

@@ -11,8 +11,9 @@
 		<h1>[name]</h1>
 
 		<p class="desc">
-			A loader for loading an [page:Image] as an [link:https://developer.mozilla.org/de/docs/Web/API/ImageBitmap ImageBitmap]. An ImageBitmap provides an asynchronous and resource efficient pathway to prepare textures for rendering in WebGL.
-
+			A loader for loading an [page:Image] as an [link:https://developer.mozilla.org/de/docs/Web/API/ImageBitmap ImageBitmap].
+			An ImageBitmap provides an asynchronous and resource efficient pathway to prepare textures for rendering in WebGL.<br/>
+			Unlike [page:FileLoader], [name] does not avoid multiple concurrent requests to the same URL.
 		</p>
 
 		<h2>Example</h2>
@@ -76,7 +77,7 @@
 		[page:String url] — the path or URL to the file. This can also be a
 			[link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs Data URI].<br />
 		[page:Function onLoad] — Will be called when load completes. The argument will be the loaded [page:Image image].<br />
-		[page:Function onProgress] — Will be called while load progresses. The argument will be the progress event.<br />
+		[page:Function onProgress] — This callback function is currently not supported.<br />
 		[page:Function onError] — Will be called when load errors.<br />
 		</p>
 		<p>

+ 1 - 2
docs/api/loaders/ImageLoader.html

@@ -12,7 +12,6 @@
 
 		<p class="desc">
 			A loader for loading an [page:Image].
-
 			This uses the [page:FileLoader] internally for loading files, and is used internally by the
 			[page:CubeTextureLoader], [page:ObjectLoader] and [page:TextureLoader].
 		</p>
@@ -88,7 +87,7 @@
 		[page:String url] — the path or URL to the file. This can also be a
 			[link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs Data URI].<br />
 		[page:Function onLoad] — Will be called when load completes. The argument will be the loaded [page:Image image].<br />
-		[page:Function onProgress] — Will be called while load progresses. The argument will be the progress event.<br />
+		[page:Function onProgress] — This callback function is currently not supported.<br />
 		[page:Function onError] — Will be called when load errors.<br />
 		</p>
 		<p>

+ 1 - 1
docs/api/loaders/JSONLoader.html

@@ -18,7 +18,7 @@
 		<h2>Example</h2>
 
 		<p>
-		[example:webgl_loader_json_blender WebGL / loader / json / blender]<br />
+		[example:webgl_loader_json WebGL / loader / json]<br />
 		[example:webgl_loader_json_objconverter WebGL / loader / json / objconverter]
 		</p>
 

+ 3 - 0
docs/api/materials/PointsMaterial.html

@@ -84,6 +84,9 @@ scene.add( starField );
 
 		<p>Sets the color of the points using data from a [page:Texture].</p>
 
+		<h3>[property:Boolean morphTargets]</h3>
+		<p>Define whether the material uses morphTargets. Default is false.</p>
+
 		<h3>[property:Number size]</h3>
 		<p>Sets the size of the points. Default is 1.0.</p>
 

+ 14 - 14
docs/api/math/Matrix3.html

@@ -83,7 +83,7 @@ m.elements = [ 11, 21, 31,
 		<h3>[method:Matrix3 clone]()</h3>
 		<p>Creates a new Matrix3 and with identical elements to this one.</p>
 
-		<h3>[method:Matrix3 copy]( [param:Matrix3 m] )</h3>
+		<h3>[method:this copy]( [param:Matrix3 m] )</h3>
 		<p>Copies the elements of matrix [page:Matrix3 m] into this matrix.</p>
 
 		<h3>[method:Float determinant]()</h3>
@@ -95,7 +95,7 @@ m.elements = [ 11, 21, 31,
 		<h3>[method:Boolean equals]( [param:Matrix3 m] )</h3>
 		<p>Return true if this matrix and [page:Matrix3 m] are equal.</p>
 
-		<h3>[method:Matrix3 fromArray]( [param:Array array], [param:Integer offset] )</h3>
+		<h3>[method:this fromArray]( [param:Array array], [param:Integer offset] )</h3>
 		<p>
 		[page:Array array] - the array to read the elements from.<br />
 		[page:Integer offset] - (optional) index of first element in the array. Default is 0.<br /><br />
@@ -104,7 +104,7 @@ m.elements = [ 11, 21, 31,
 		[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major] format.
 		</p>
 
-		<h3>[method:Matrix3 getInverse]( [param:Matrix3 m], [param:Boolean throwOnDegenerate] )</h3>
+		<h3>[method:this getInverse]( [param:Matrix3 m], [param:Boolean throwOnDegenerate] )</h3>
 		<p>
 		[page:Matrix3 m] - the matrix to take the inverse of.<br />
 		[page:Boolean throwOnDegenerate] - (optional) If true, throw an error if the matrix is degenerate (not invertible).<br /><br />
@@ -115,7 +115,7 @@ m.elements = [ 11, 21, 31,
 		If [page:Boolean throwOnDegenerate] is not set and the matrix is not invertible, set this to the 3x3 identity matrix.
 		</p>
 
-		<h3>[method:Matrix3 getNormalMatrix]( [param:Matrix4 m] )</h3>
+		<h3>[method:this getNormalMatrix]( [param:Matrix4 m] )</h3>
 		<p>
 		[page:Matrix4 m] - [page:Matrix4]<br /><br />
 
@@ -124,7 +124,7 @@ m.elements = [ 11, 21, 31,
 	  of the matrix [page:Matrix4 m].
 		</p>
 
-		<h3>[method:Matrix3 identity]()</h3>
+		<h3>[method:this identity]()</h3>
 		<p>
 		Resets this matrix to the 3x3 identity matrix:
 		<code>
@@ -135,17 +135,17 @@ m.elements = [ 11, 21, 31,
 
 		</p>
 
-		<h3>[method:Matrix3 multiply]( [param:Matrix3 m] )</h3>
+		<h3>[method:this multiply]( [param:Matrix3 m] )</h3>
 		<p>Post-multiplies this matrix by [page:Matrix3 m].</p>
 
-		<h3>[method:Matrix3 multiplyMatrices]( [param:Matrix3 a], [param:Matrix3 b] )</h3>
+		<h3>[method:this multiplyMatrices]( [param:Matrix3 a], [param:Matrix3 b] )</h3>
 		<p>Sets this matrix to [page:Matrix3 a] x [page:Matrix3 b].</p>
 
-		<h3>[method:Matrix3 multiplyScalar]( [param:Float s] )</h3>
+		<h3>[method:this multiplyScalar]( [param:Float s] )</h3>
 		<p>Multiplies every component of the matrix by the scalar value *s*.</p>
 
 		<h3>
-			[method:Matrix3 set](
+			[method:this set](
 			[page:Float n11], [page:Float n12], [page:Float n13],
 			[page:Float n21], [page:Float n22], [page:Float n23],
 			[page:Float n31], [page:Float n32], [page:Float n33] )
@@ -163,14 +163,14 @@ m.elements = [ 11, 21, 31,
 		sequence of values.
 		</p>
 
-		<h3>[method:Matrix3 premultiply]( [param:Matrix3 m] )</h3>
+		<h3>[method:this premultiply]( [param:Matrix3 m] )</h3>
 		<p>Pre-multiplies this matrix by [page:Matrix3 m].</p>
 
-		<h3>[method:Matrix3 setFromMatrix4]( [param:Matrix4 m] )</h3>
+		<h3>[method:this setFromMatrix4]( [param:Matrix4 m] )</h3>
 		<p>Set this matrx to the upper 3x3 matrix of the Matrix4 [page:Matrix4 m].</p>
 
 		<h3>
-			[method:Matrix3 setUvTransform](
+			[method:this setUvTransform](
 			[page:Float tx], [page:Float ty], [page:Float sx], [page:Float sy],
 			[page:Float rotation], [page:Float cx], [page:Float cy] )
 		</h3>
@@ -195,10 +195,10 @@ m.elements = [ 11, 21, 31,
 		[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major] format.
 		</p>
 
-		<h3>[method:Matrix3 transpose]()</h3>
+		<h3>[method:this transpose]()</h3>
 		<p>[link:https://en.wikipedia.org/wiki/Transpose Transposes] this matrix in place.</p>
 
-		<h3>[method:Matrix3 transposeIntoArray]( [param:Array array] )</h3>
+		<h3>[method:this transposeIntoArray]( [param:Array array] )</h3>
 		<p>
 		[page:Array array] -  array to store the resulting vector in.<br /><br />
 

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

@@ -119,7 +119,7 @@ m.elements = [ 11, 21, 31, 41,
 		<h3>[method:Matrix4 clone]()</h3>
 		<p>Creates a new Matrix4 with identical [page:.elements elements] to this one.</p>
 
-		<h3>[method:Matrix4 compose]( [param:Vector3 position], [param:Quaternion quaternion], [param:Vector3 scale] )</h3>
+		<h3>[method:this compose]( [param:Vector3 position], [param:Quaternion quaternion], [param:Vector3 scale] )</h3>
 		<p>
 		Sets this matrix to the transformation composed of [page:Vector3 position],
 		[page:Quaternion quaternion] and [page:Vector3 scale]. Internally this calls
@@ -128,10 +128,10 @@ m.elements = [ 11, 21, 31, 41,
 		[page:.setPosition setPosition]( [page:Vector3 position] ).
 		</p>
 
-		<h3>[method:Matrix4 copy]( [param:Matrix4 m] )</h3>
+		<h3>[method:this copy]( [param:Matrix4 m] )</h3>
 		<p>Copies the [page:.elements elements] of matrix [page:Matrix4 m] into this matrix.</p>
 
-		<h3>[method:Matrix4 copyPosition]( [param:Matrix4 m] )</h3>
+		<h3>[method:this copyPosition]( [param:Matrix4 m] )</h3>
 		<p>
 		Copies the translation component of the supplied matrix [page:Matrix4 m] into this
 		matrix's translation component.
@@ -154,7 +154,7 @@ m.elements = [ 11, 21, 31, 41,
 		<h3>[method:Boolean equals]( [param:Matrix4 m] )</h3>
 		<p>Return true if this matrix and [page:Matrix4 m] are equal.</p>
 
-		<h3>[method:Matrix4 extractBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
+		<h3>[method:this extractBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
 		<p>
 		Extracts the [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis] of this
 		matrix into the three axis vectors provided. If this matrix is:
@@ -172,13 +172,13 @@ zAxis = (c, g, k)
 		</code>
 		</p>
 
-		<h3>[method:Matrix4 extractRotation]( [param:Matrix4 m] )</h3>
+		<h3>[method:this extractRotation]( [param:Matrix4 m] )</h3>
 		<p>
 		Extracts the rotation component of the supplied matrix [page:Matrix4 m] into this matrix's
 		rotation component.
 		</p>
 
-		<h3>[method:Matrix4 fromArray]( [param:Array array], [param:Integer offset] )</h3>
+		<h3>[method:this fromArray]( [param:Array array], [param:Integer offset] )</h3>
 		<p>
 		[page:Array array] - the array to read the elements from.<br />
 		[page:Integer offset] - ( optional ) offset into the array. Default is 0.<br /><br />
@@ -187,7 +187,7 @@ zAxis = (c, g, k)
 		[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major] format.
 		</p>
 
-		<h3>[method:Matrix4 getInverse]( [param:Matrix4 m], [param:Boolean throwOnDegenerate] )</h3>
+		<h3>[method:this getInverse]( [param:Matrix4 m], [param:Boolean throwOnDegenerate] )</h3>
 		<p>
 		[page:Matrix4 m] - the matrix to take the inverse of.<br />
 		[page:Boolean throwOnDegenerate] - (optional) If true, throw an error if the matrix is degenerate (not invertible).<br /><br />
@@ -202,16 +202,16 @@ zAxis = (c, g, k)
 		<h3>[method:Float getMaxScaleOnAxis]()</h3>
 		<p>Gets the maximum scale value of the 3 axes.</p>
 
-		<h3>[method:Matrix4 identity]()</h3>
+		<h3>[method:this identity]()</h3>
 		<p>Resets this matrix to the [link:https://en.wikipedia.org/wiki/Identity_matrix identity matrix].</p>
 
-		<h3>[method:Matrix4 lookAt]( [param:Vector3 eye], [param:Vector3 center], [param:Vector3 up], )</h3>
+		<h3>[method:this lookAt]( [param:Vector3 eye], [param:Vector3 center], [param:Vector3 up], )</h3>
 		<p>
 			Constructs a rotation matrix, looking from [page:Vector3 eye] towards [page:Vector3 center]
 			oriented by the [page:Vector3 up] vector.
 		</p>
 
-		<h3>[method:Matrix4 makeRotationAxis]( [param:Vector3 axis], [param:Float theta] )</h3>
+		<h3>[method:this makeRotationAxis]( [param:Vector3 axis], [param:Float theta] )</h3>
 		<p>
 		[page:Vector3 axis] — Rotation axis, should be normalized.<br />
 		[page:Float theta] — Rotation angle in radians.<br /><br />
@@ -222,7 +222,7 @@ zAxis = (c, g, k)
 		See the discussion [link:http://www.gamedev.net/reference/articles/article1199.asp here].
 		</p>
 
-		<h3>[method:Matrix4 makeBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
+		<h3>[method:this makeBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
 		<p>
 		Set this to the [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis] matrix consisting
 		of the three provided basis vectors:
@@ -234,26 +234,26 @@ xAxis.z, yAxis.z, zAxis.z, 0,
 		</code>
 		</p>
 
-		<h3>[method:Matrix4 makePerspective]( [param:Float left], [param:Float right], [param:Float top], [param:Float bottom], [param:Float near], [param:Float far] )</h3>
+		<h3>[method:this makePerspective]( [param:Float left], [param:Float right], [param:Float top], [param:Float bottom], [param:Float near], [param:Float far] )</h3>
 		<p>
 			Creates a [link:https://en.wikipedia.org/wiki/3D_projection#Perspective_projection perspective projection] matrix.
 			This is used internally by [page:PerspectiveCamera.updateProjectionMatrix]()
 		</p>
 
-		<h3>[method:Matrix4 makeOrthographic]( [param:Float left], [param:Float right], [param:Float top], [param:Float bottom], [param:Float near], [param:Float far] )</h3>
+		<h3>[method:this makeOrthographic]( [param:Float left], [param:Float right], [param:Float top], [param:Float bottom], [param:Float near], [param:Float far] )</h3>
 		<p>
 		Creates an [link:https://en.wikipedia.org/wiki/Orthographic_projection orthographic projection] matrix.
 		This is used internally by [page:OrthographicCamera.updateProjectionMatrix]().
 		</p>
 
-		<h3>[method:Matrix4 makeRotationFromEuler]( [param:Euler euler] )</h3>
+		<h3>[method:this makeRotationFromEuler]( [param:Euler euler] )</h3>
 		<p>
 		Sets the rotation component (the upper left 3x3 matrix) of this matrix to the rotation specified by the given [page:Euler Euler Angle].
 		The rest of the matrix is set to the identity. Depending on the [page:Euler.order order] of the [page:Euler euler], there are six possible outcomes.
 		See [link:https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix this page] for a complete list.
 		</p>
 
-		<h3>[method:Matrix4 makeRotationFromQuaternion]( [param:Quaternion q] )</h3>
+		<h3>[method:this makeRotationFromQuaternion]( [param:Quaternion q] )</h3>
 		<p>
 		Sets the rotation component of this matrix to the rotation specified by [page:Quaternion q], as outlined
 		[link:https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion here].
@@ -266,7 +266,7 @@ xAxis.z, yAxis.z, zAxis.z, 0,
 		</code>
 		</p>
 
-		<h3>[method:Matrix4 makeRotationX]( [param:Float theta] )</h3>
+		<h3>[method:this makeRotationX]( [param:Float theta] )</h3>
 		<p>
 		[page:Float theta] — Rotation angle in radians.<br /><br />
 
@@ -280,7 +280,7 @@ xAxis.z, yAxis.z, zAxis.z, 0,
 		</code>
 		</p>
 
-		<h3>[method:Matrix4 makeRotationY]( [param:Float theta] )</h3>
+		<h3>[method:this makeRotationY]( [param:Float theta] )</h3>
 		<p>
 		[page:Float theta] — Rotation angle in radians.<br /><br />
 
@@ -294,7 +294,7 @@ cos(&theta;)  0 sin(&theta;) 0
 		</code>
 		</p>
 
-		<h3>[method:Matrix4 makeRotationZ]( [param:Float theta] )</h3>
+		<h3>[method:this makeRotationZ]( [param:Float theta] )</h3>
 		<p>
 		[page:Float theta] — Rotation angle in radians.<br /><br />
 
@@ -308,7 +308,7 @@ sin(&theta;) cos(&theta;)  0 0
 		</code>
 		</p>
 
-		<h3>[method:Matrix4 makeScale]( [param:Float x], [param:Float y], [param:Float z] )</h3>
+		<h3>[method:this makeScale]( [param:Float x], [param:Float y], [param:Float z] )</h3>
 		<p>
 			[page:Float x] - the amount to scale in the X axis.<br />
 			[page:Float y] - the amount to scale in the Y axis.<br />
@@ -323,7 +323,7 @@ x, 0, 0, 0,
 			</code>
 		</p>
 
-		<h3>[method:Matrix4 makeShear]( [param:Float x], [param:Float y], [param:Float z] )</h3>
+		<h3>[method:this makeShear]( [param:Float x], [param:Float y], [param:Float z] )</h3>
 		<p>
 		[page:Float x] - the amount to shear in the X axis.<br />
 		[page:Float y] - the amount to shear in the Y axis.<br />
@@ -338,7 +338,7 @@ x, y, 1, 0,
 </code>
 		</p>
 
-		<h3>[method:Matrix4 makeTranslation]( [param:Float x], [param:Float y], [param:Float z] )</h3>
+		<h3>[method:this makeTranslation]( [param:Float x], [param:Float y], [param:Float z] )</h3>
 		<p>
 			[page:Float x] - the amount to translate in the X axis.<br />
 			[page:Float y] - the amount to translate in the Y axis.<br />
@@ -353,22 +353,22 @@ x, y, 1, 0,
 		</code>
 		</p>
 
-		<h3>[method:Matrix4 multiply]( [param:Matrix4 m] )</h3>
+		<h3>[method:this multiply]( [param:Matrix4 m] )</h3>
 		<p>Post-multiplies this matrix by [page:Matrix4 m].</p>
 
-		<h3>[method:Matrix4 multiplyMatrices]( [param:Matrix4 a], [param:Matrix4 b] )</h3>
+		<h3>[method:this multiplyMatrices]( [param:Matrix4 a], [param:Matrix4 b] )</h3>
 		<p>Sets this matrix to [page:Matrix4 a] x [page:Matrix4 b].</p>
 
-		<h3>[method:Matrix4 multiplyScalar]( [param:Float s] )</h3>
+		<h3>[method:this multiplyScalar]( [param:Float s] )</h3>
 		<p>Multiplies every component of the matrix by a scalar value [page:Float s].</p>
 
-		<h3>[method:Matrix4 premultiply]( [param:Matrix4 m] )</h3>
+		<h3>[method:this premultiply]( [param:Matrix4 m] )</h3>
 		<p>Pre-multiplies this matrix by [page:Matrix4 m].</p>
 
-		<h3>[method:Matrix4 scale]( [param:Vector3 v] )</h3>
+		<h3>[method:this scale]( [param:Vector3 v] )</h3>
 		<p>Multiplies the columns of this matrix by vector [page:Vector3 v].</p>
 
-		<h3>[method:Matrix4 set](
+		<h3>[method:this set](
 			[page:Float n11], [page:Float n12], [page:Float n13], [page:Float n14],
 			[page:Float n21], [page:Float n22], [page:Float n23], [page:Float n24],
 			[page:Float n31], [page:Float n32], [page:Float n33], [page:Float n34],
@@ -378,7 +378,7 @@ x, y, 1, 0,
 			[page:Float n12], ... [page:Float n44].
 		</p>
 
-		<h3>[method:Matrix4 setPosition]( [param:Vector3 v] )</h3>
+		<h3>[method:this setPosition]( [param:Vector3 v] )</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:
@@ -406,7 +406,7 @@ m, n, o, p
 		[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major] format.
 		</p>
 
-		<h3>[method:Matrix4 transpose]()</h3>
+		<h3>[method:this transpose]()</h3>
 		<p>[link:https://en.wikipedia.org/wiki/Transpose Transposes] this matrix.</p>
 
 		<h2>Source</h2>

+ 34 - 34
docs/api/math/Vector2.html

@@ -82,16 +82,16 @@
 
 		<h2>Methods</h2>
 
-		<h3>[method:Vector2 add]( [param:Vector2 v] )</h3>
+		<h3>[method:this add]( [param:Vector2 v] )</h3>
 		<p>Adds [page:Vector2 v] to this vector.</p>
 
-		<h3>[method:Vector2 addScalar]( [param:Float s] )</h3>
+		<h3>[method:this addScalar]( [param:Float s] )</h3>
 		<p>Adds the scalar value [page:Float s] to this vector's [page:.x x] and [page:.y y] values.</p>
 
-		<h3>[method:Vector2 addScaledVector]( [param:Vector2 v], [param:Float s] )</h3>
+		<h3>[method:this addScaledVector]( [param:Vector2 v], [param:Float s] )</h3>
 		<p>Adds the multiple of [page:Vector2 v] and [page:Float s] to this vector.</p>
 
-		<h3>[method:Vector2 addVectors]( [param:Vector2 a], [param:Vector2 b] )</h3>
+		<h3>[method:this addVectors]( [param:Vector2 a], [param:Vector2 b] )</h3>
 		<p>Sets this vector to [page:Vector2 a] + [page:Vector2 b].</p>
 
 		<h3>[method:Float angle]()</h3>
@@ -99,17 +99,17 @@
 		Computes the angle in radians of this vector with respect to the positive x-axis.
 		</p>
 
-		<h3>[method:Vector2 applyMatrix3]( [param:Matrix3 m] )</h3>
+		<h3>[method:this applyMatrix3]( [param:Matrix3 m] )</h3>
 		<p>
 		Multiplies this vector (with an implicit 1 as the 3rd component) by m.
 		</p>
 
-		<h3>[method:Vector2 ceil]()</h3>
+		<h3>[method:this ceil]()</h3>
 		<p>
 		The [page:.x x] and [page:.y y] components of the vector are rounded up to the nearest integer value.
 		</p>
 
-		<h3>[method:Vector2 clamp]( [param:Vector2 min], [param:Vector2 max] )</h3>
+		<h3>[method:this clamp]( [param:Vector2 min], [param:Vector2 max] )</h3>
 		<p>
 		[page:Vector2 min] - the minimum x and y values.<br />
 		[page:Vector2 max] - the maximum x and y values in the desired range<br /><br />
@@ -118,7 +118,7 @@
 		If this vector's x or y value is less than the min vector's x or y value, it is replaced by the corresponding value.
 		</p>
 
-		<h3>[method:Vector2 clampLength]( [param:Float min], [param:Float max] )</h3>
+		<h3>[method:this clampLength]( [param:Float min], [param:Float max] )</h3>
 		<p>
 		[page:Float min] - the minimum value the length will be clamped to <br />
 		[page:Float max] - the maximum value the length will be clamped to<br /><br />
@@ -127,7 +127,7 @@
 		If this vector's length is less than the min value, it is replaced by the min value.
 		</p>
 
-		<h3>[method:Vector2 clampScalar]( [param:Float min], [param:Float max] )</h3>
+		<h3>[method:this clampScalar]( [param:Float min], [param:Float max] )</h3>
 		<p>
 		[page:Float min] - the minimum value the components will be clamped to <br />
 		[page:Float max] - the maximum value the components will be clamped to<br /><br />
@@ -141,7 +141,7 @@
 		Returns a new Vector2 with the same [page:.x x] and [page:.y y] values as this one.
 		</p>
 
-		<h3>[method:Vector2 copy]( [param:Vector2 v] )</h3>
+		<h3>[method:this copy]( [param:Vector2 v] )</h3>
 		<p>
 			Copies the values of the passed Vector2's [page:.x x] and [page:.y y]
 			properties to this Vector2.
@@ -162,10 +162,10 @@
 		as it is slightly more efficient to calculate.
 		</p>
 
-		<h3>[method:Vector2 divide]( [param:Vector2 v] )</h3>
+		<h3>[method:this divide]( [param:Vector2 v] )</h3>
 		<p>Divides this vector by [page:Vector2 v].</p>
 
-		<h3>[method:Vector2 divideScalar]( [param:Float s] )</h3>
+		<h3>[method:this divideScalar]( [param:Float s] )</h3>
 		<p>
 		Divides this vector by scalar [page:Float s].<br />
 		Sets vector to *( 0, 0 )* if [page:Float s] = 0.
@@ -180,10 +180,10 @@
 		<h3>[method:Boolean equals]( [param:Vector2 v] )</h3>
 		<p>Checks for strict equality of this vector and [page:Vector2 v].</p>
 
-		<h3>[method:Vector2 floor]()</h3>
+		<h3>[method:this floor]()</h3>
 		<p>The components of the vector are rounded down to the nearest integer value.</p>
 
-		<h3>[method:Vector2 fromArray]( [param:Array array], [param:Integer offset] )</h3>
+		<h3>[method:this fromArray]( [param:Array array], [param:Integer offset] )</h3>
 		<p>
 		[page:Array array] - the source array.<br />
 		[page:Integer offset] - (optional) offset into the array. Default is 0.<br /><br />
@@ -191,7 +191,7 @@
 		Sets this vector's [page:.x x] value to be array[ offset ] and [page:.y y] value to be array[ offset + 1 ].
 		</p>
 
-		<h3>[method:Vector2 fromBufferAttribute]( [param:BufferAttribute attribute], [param:Integer index] )</h3>
+		<h3>[method:this fromBufferAttribute]( [param:BufferAttribute attribute], [param:Integer index] )</h3>
 		<p>
 		[page:BufferAttribute attribute] - the source attribute.<br />
 		[page:Integer index] - index in the attribute.<br /><br />
@@ -223,7 +223,7 @@
 		vectors, you should compare the length squared instead as it is slightly more efficient to calculate.
 		</p>
 
-		<h3>[method:Vector2 lerp]( [param:Vector2 v], [param:Float alpha] )</h3>
+		<h3>[method:this lerp]( [param:Vector2 v], [param:Float alpha] )</h3>
 		<p>
 		[page:Vector2 v] - [page:Vector2] to interpolate towards.<br />
 		alpha - interpolation factor in the closed interval [0, 1].<br /><br />
@@ -232,7 +232,7 @@
 		distance along the line - alpha = 0 will be this vector, and alpha = 1 will be [page:Vector2 v].
 		</p>
 
-		<h3>[method:Vector2 lerpVectors]( [param:Vector2 v1], [param:Vector2 v2], [param:Float alpha] )</h3>
+		<h3>[method:this lerpVectors]( [param:Vector2 v1], [param:Vector2 v2], [param:Float alpha] )</h3>
 		<p>
 		[page:Vector2 v1] - the starting [page:Vector2].<br />
 		[page:Vector2 v2] - [page:Vector2] to interpolate towards.<br />
@@ -243,35 +243,35 @@
 		- alpha = 0 will be [page:Vector2 v1], and alpha = 1 will be [page:Vector2 v2].
 		</p>
 
-		<h3>[method:Vector2 negate]()</h3>
+		<h3>[method:this negate]()</h3>
 		<p>Inverts this vector - i.e. sets x = -x and y = -y.</p>
 
-		<h3>[method:Vector2 normalize]()</h3>
+		<h3>[method:this normalize]()</h3>
 		<p>
 		Converts this vector to a [link:https://en.wikipedia.org/wiki/Unit_vector unit vector] - that is, sets it equal to the vector with the same direction
 		as this one, but [page:.length length] 1.
 		</p>
 
-		<h3>[method:Vector2 max]( [param:Vector2 v] )</h3>
+		<h3>[method:this max]( [param:Vector2 v] )</h3>
 		<p>
 		If this vector's x or y value is less than [page:Vector2 v]'s x or y value, replace
 		that value with the corresponding max value.
 		</p>
 
-		<h3>[method:Vector2 min]( [param:Vector2 v] )</h3>
+		<h3>[method:this min]( [param:Vector2 v] )</h3>
 		<p>
 		If this vector's x or y value is greater than [page:Vector2 v]'s x or y value, replace
 		that value with the corresponding min value.
 		</p>
 
-		<h3>[method:Vector2 multiply]( [param:Vector2 v] )</h3>
+		<h3>[method:this multiply]( [param:Vector2 v] )</h3>
 		<p>Multiplies this vector by [page:Vector2 v].</p>
 
 
-		<h3>[method:Vector2 multiplyScalar]( [param:Float s] )</h3>
+		<h3>[method:this multiplyScalar]( [param:Float s] )</h3>
 		<p>Multiplies this vector by scalar [page:Float s].</p>
 
-		<h3>[method:Vector2 rotateAround]( [param:Vector2 center], [param:float angle] )</h3>
+		<h3>[method:this rotateAround]( [param:Vector2 center], [param:float angle] )</h3>
 		<p>
 			[page:Vector2 center] - the point around which to rotate.<br />
 			[page:float angle] - the angle to rotate, in radians.<br /><br />
@@ -279,15 +279,15 @@
 			Rotates the vector around [page:Vector2 center] by [page:float angle] radians.
 		</p>
 
-		<h3>[method:Vector2 round]()</h3>
+		<h3>[method:this round]()</h3>
 		<p>The components of the vector are rounded to the nearest integer value.</p>
 
-		<h3>[method:Vector2 roundToZero]()</h3>
+		<h3>[method:this roundToZero]()</h3>
 		<p>
 		The components of the vector are rounded towards zero (up if negative, down if positive) to an integer value.
 		</p>
 
-		<h3>[method:Vector2 set]( [param:Float x], [param:Float y] )</h3>
+		<h3>[method:this set]( [param:Float x], [param:Float y] )</h3>
 		<p>Sets the [page:.x x] and [page:.y y] components of this vector.</p>
 
 		<h3>[method:null setComponent]( [param:Integer index], [param:Float value] )</h3>
@@ -299,30 +299,30 @@
 		If index equals 1 set [page:.y y] to [page:Float value]
 		</p>
 
-		<h3>[method:Vector2 setLength]( [param:Float l] )</h3>
+		<h3>[method:this setLength]( [param:Float l] )</h3>
 		<p>
 		Sets this vector to the vector with the same direction as this one, but [page:.length length]
 		[page:Float l].
 		</p>
 
-		<h3>[method:Vector2 setScalar]( [param:Float scalar] )</h3>
+		<h3>[method:this setScalar]( [param:Float scalar] )</h3>
 		<p>
 		Sets the [page:.x x] and [page:.y y] values of this vector both equal to [page:Float scalar].
 		</p>
 
-		<h3>[method:Vector2 setX]( [param:Float x] )</h3>
+		<h3>[method:this setX]( [param:Float x] )</h3>
 		<p>Replaces this vector's [page:.x x] value with [page:Float x].</p>
 
-		<h3>[method:Vector2 setY]( [param:Float y] )</h3>
+		<h3>[method:this setY]( [param:Float y] )</h3>
 		<p>Replaces this vector's [page:.y y] value with [page:Float y].</p>
 
-		<h3>[method:Vector2 sub]( [param:Vector2 v] )</h3>
+		<h3>[method:this sub]( [param:Vector2 v] )</h3>
 		<p>Subtracts [page:Vector2 v] from this vector.</p>
 
-		<h3>[method:Vector2 subScalar]( [param:Float s] )</h3>
+		<h3>[method:this subScalar]( [param:Float s] )</h3>
 		<p>Subtracts [page:Float s]  from this vector's [page:.x x] and [page:.y y] components.</p>
 
-		<h3>[method:Vector2 subVectors]( [param:Vector2 a], [param:Vector2 b] )</h3>
+		<h3>[method:this subVectors]( [param:Vector2 a], [param:Vector2 b] )</h3>
 		<p>Sets this vector to [page:Vector2 a] - [page:Vector2 b].</p>
 
 		<h3>[method:Array toArray]( [param:Array array], [param:Integer offset] )</h3>

+ 52 - 52
docs/api/math/Vector3.html

@@ -79,19 +79,19 @@ var d = a.distanceTo( b );
 
 		<h2>Methods</h2>
 
-		<h3>[method:Vector3 add]( [param:Vector3 v] )</h3>
+		<h3>[method:this add]( [param:Vector3 v] )</h3>
 		<p>Adds [page:Vector3 v] to this vector.</p>
 
-		<h3>[method:Vector3 addScalar]( [param:Float s] )</h3>
+		<h3>[method:this addScalar]( [param:Float s] )</h3>
 		<p>Adds the scalar value s to this vector's [page:.x x], [page:.y y] and [page:.z z] values.</p>
 
-		<h3>[method:Vector3 addScaledVector]( [param:Vector3 v], [param:Float s] )</h3>
+		<h3>[method:this addScaledVector]( [param:Vector3 v], [param:Float s] )</h3>
 		<p>Adds the multiple of [page:Vector3 v] and [page:Float s] to this vector.</p>
 
-		<h3>[method:Vector3 addVectors]( [param:Vector3 a], [param:Vector3 b] )</h3>
+		<h3>[method:this addVectors]( [param:Vector3 a], [param:Vector3 b] )</h3>
 		<p>Sets this vector to [page:Vector3 a] + [page:Vector3 b].</p>
 
-		<h3>[method:Vector3 applyAxisAngle]( [param:Vector3 axis], [param:Float angle] )</h3>
+		<h3>[method:this applyAxisAngle]( [param:Vector3 axis], [param:Float angle] )</h3>
 		<p>
 		[page:Vector3 axis] - A normalized [page:Vector3].<br />
 		[page:Float angle] - An angle in radians.<br /><br />
@@ -99,21 +99,21 @@ var d = a.distanceTo( b );
 		Applies a rotation specified by an axis and an angle to this vector.
 		</p>
 
-		<h3>[method:Vector3 applyEuler]( [param:Euler euler] )</h3>
+		<h3>[method:this applyEuler]( [param:Euler euler] )</h3>
 		<p>
 		Applies euler transform to this vector by converting the [page:Euler] object to a
 		[page:Quaternion] and applying.
 		</p>
 
-		<h3>[method:Vector3 applyMatrix3]( [param:Matrix3 m] )</h3>
+		<h3>[method:this applyMatrix3]( [param:Matrix3 m] )</h3>
 		<p>Multiplies this vector by [page:Matrix3 m]</p>
 
-		<h3>[method:Vector3 applyMatrix4]( [param:Matrix4 m] )</h3>
+		<h3>[method:this applyMatrix4]( [param:Matrix4 m] )</h3>
 		<p>
 		Multiplies this vector (with an implicit 1 in the 4th dimension) and m, and divides by perspective.
 		</p>
 
-		<h3>[method:Vector3 applyQuaternion]( [param:Quaternion quaternion] )</h3>
+		<h3>[method:this applyQuaternion]( [param:Quaternion quaternion] )</h3>
 		<p>
 		Applies a [page:Quaternion] transform to this vector.
 		</p>
@@ -124,12 +124,12 @@ var d = a.distanceTo( b );
 		Returns the angle between this vector and vector [page:Vector3 v] in radians.
 		</p>
 
-		<h3>[method:Vector3 ceil]()</h3>
+		<h3>[method:this ceil]()</h3>
 		<p>
 		The [page:.x x], [page:.y y] and [page:.z z] components of the vector are rounded up to the nearest integer value.
 		</p>
 
-		<h3>[method:Vector3 clamp]( [param:Vector3 min], [param:Vector3 max] )</h3>
+		<h3>[method:this clamp]( [param:Vector3 min], [param:Vector3 max] )</h3>
 		<p>
 		[page:Vector3 min] - the minimum [page:.x x], [page:.y y] and [page:.z z] values.<br />
 		[page:Vector3 max] - the maximum [page:.x x], [page:.y y] and [page:.z z] values in the desired range<br /><br />
@@ -138,7 +138,7 @@ var d = a.distanceTo( b );
 		If this vector's x, y or z value is less than the min vector's x, y or z value, it is replaced by the corresponding value.
 		</p>
 
-		<h3>[method:Vector3 clampLength]( [param:Float min], [param:Float max] )</h3>
+		<h3>[method:this clampLength]( [param:Float min], [param:Float max] )</h3>
 		<p>
 		[page:Float min] - the minimum value the length will be clamped to <br />
 		[page:Float max] - the maximum value the length will be clamped to<br /><br />
@@ -147,7 +147,7 @@ var d = a.distanceTo( b );
 		If this vector's length is less than the min value, it is replaced by the min value.
 		</p>
 
-		<h3>[method:Vector3 clampScalar]( [param:Float min], [param:Float max] )</h3>
+		<h3>[method:this clampScalar]( [param:Float min], [param:Float max] )</h3>
 		<p>
 		[page:Float min] - the minimum value the components will be clamped to <br />
 		[page:Float max] - the maximum value the components will be clamped to<br /><br />
@@ -161,18 +161,18 @@ var d = a.distanceTo( b );
 		Returns a new vector3 with the same [page:.x x], [page:.y y] and [page:.z z] values as this one.
 		</p>
 
-		<h3>[method:Vector3 copy]( [param:Vector3 v] )</h3>
+		<h3>[method:this copy]( [param:Vector3 v] )</h3>
 		<p>
 			Copies the values of the passed vector3's [page:.x x], [page:.y y] and [page:.z z]
 			properties to this vector3.
 		</p>
 
-		<h3>[method:Vector3 cross]( [param:Vector3 v] )</h3>
+		<h3>[method:this cross]( [param:Vector3 v] )</h3>
 		<p>
 		Sets this vector to [link:https://en.wikipedia.org/wiki/Cross_product cross product] of itself and [page:Vector3 v].
 		</p>
 
-		<h3>[method:Vector3 crossVectors]( [param:Vector3 a], [param:Vector3 b] )</h3>
+		<h3>[method:this crossVectors]( [param:Vector3 a], [param:Vector3 b] )</h3>
 		<p>
 		Sets this vector to [link:https://en.wikipedia.org/wiki/Cross_product cross product] of [page:Vector3 a] and [page:Vector3 b].
 		</p>
@@ -192,10 +192,10 @@ var d = a.distanceTo( b );
 		as it is slightly more efficient to calculate.
 		</p>
 
-		<h3>[method:Vector3 divide]( [param:Vector3 v] )</h3>
+		<h3>[method:this divide]( [param:Vector3 v] )</h3>
 		<p>Divides this vector by [page:Vector3 v].</p>
 
-		<h3>[method:Vector3 divideScalar]( [param:Float s] )</h3>
+		<h3>[method:this divideScalar]( [param:Float s] )</h3>
 		<p>
 		Divides this vector by scalar [page:Float s].<br />
 		Sets vector to *( 0, 0, 0 )* if *[page:Float s] = 0*.
@@ -210,10 +210,10 @@ var d = a.distanceTo( b );
 		<h3>[method:Boolean equals]( [param:Vector3 v] )</h3>
 		<p>Checks for strict equality of this vector and [page:Vector3 v].</p>
 
-		<h3>[method:Vector3 floor]()</h3>
+		<h3>[method:this floor]()</h3>
 		<p>The components of the vector are rounded down to the nearest integer value.</p>
 
-		<h3>[method:Vector3 fromArray]( [param:Array array], [param:Integer offset] )</h3>
+		<h3>[method:this fromArray]( [param:Array array], [param:Integer offset] )</h3>
 		<p>
 		[page:Array array] - the source array.<br />
 		[page:Integer offset] - ( optional) offset into the array. Default is 0.<br /><br />
@@ -222,7 +222,7 @@ var d = a.distanceTo( b );
 		and [page:.z z] value to be array[ offset + 2 ].
 		</p>
 
-		<h3>[method:Vector3 fromBufferAttribute]( [param:BufferAttribute attribute], [param:Integer index] )</h3>
+		<h3>[method:this fromBufferAttribute]( [param:BufferAttribute attribute], [param:Integer index] )</h3>
 		<p>
 		[page:BufferAttribute attribute] - the source attribute.<br />
 		[page:Integer index] - index in the attribute.<br /><br />
@@ -255,7 +255,7 @@ var d = a.distanceTo( b );
 		vectors, you should compare the length squared instead as it is slightly more efficient to calculate.
 		</p>
 
-		<h3>[method:Vector3 lerp]( [param:Vector3 v], [param:Float alpha] )</h3>
+		<h3>[method:this lerp]( [param:Vector3 v], [param:Float alpha] )</h3>
 		<p>
 		[page:Vector3 v] - [page:Vector3] to interpolate towards.<br />
 		alpha - interpolation factor in the closed interval [0, 1].<br /><br />
@@ -264,7 +264,7 @@ var d = a.distanceTo( b );
 		distance along the line - alpha = 0 will be this vector, and alpha = 1 will be [page:Vector3 v].
 		</p>
 
-		<h3>[method:Vector3 lerpVectors]( [param:Vector3 v1], [param:Vector3 v2], [param:Float alpha] )</h3>
+		<h3>[method:this lerpVectors]( [param:Vector3 v1], [param:Vector3 v2], [param:Float alpha] )</h3>
 		<p>
 		[page:Vector3 v1] - the starting [page:Vector3].<br />
 		[page:Vector3 v2] - [page:Vector3] to interpolate towards.<br />
@@ -275,44 +275,44 @@ var d = a.distanceTo( b );
 		- alpha = 0 will be [page:Vector3 v1], and alpha = 1 will be [page:Vector3 v2].
 		</p>
 
-		<h3>[method:Vector3 max]( [param:Vector3 v] )</h3>
+		<h3>[method:this max]( [param:Vector3 v] )</h3>
 		<p>
 		If this vector's x, y or z value is less than [page:Vector3 v]'s x, y or z value, replace
 		that value with the corresponding max value.
 		</p>
 
-		<h3>[method:Vector3 min]( [param:Vector3 v] )</h3>
+		<h3>[method:this min]( [param:Vector3 v] )</h3>
 		<p>
 		If this vector's x, y or z value is greater than [page:Vector3 v]'s x, y or z value, replace
 		that value with the corresponding min value.
 		</p>
 
-		<h3>[method:Vector3 multiply]( [param:Vector3 v] )</h3>
+		<h3>[method:this multiply]( [param:Vector3 v] )</h3>
 		<p>Multiplies this vector by [page:Vector3 v].</p>
 
-		<h3>[method:Vector3 multiplyScalar]( [param:Float s] )</h3>
+		<h3>[method:this multiplyScalar]( [param:Float s] )</h3>
 		<p>Multiplies this vector by scalar [page:Float s].</p>
 
-		<h3>[method:Vector3 multiplyVectors]( [param:Vector3 a], [param:Vector3 b] )</h3>
+		<h3>[method:this multiplyVectors]( [param:Vector3 a], [param:Vector3 b] )</h3>
 		<p>Sets this vector equal to [page:Vector3 a] * [page:Vector3 b], component-wise.</p>
 
-		<h3>[method:Vector3 negate]()</h3>
+		<h3>[method:this negate]()</h3>
 		<p>Inverts this vector - i.e. sets x = -x, y = -y and z = -z.</p>
 
-		<h3>[method:Vector3 normalize]()</h3>
+		<h3>[method:this normalize]()</h3>
 		<p>
 		Convert this vector to a [link:https://en.wikipedia.org/wiki/Unit_vector unit vector] - that is, sets it equal to the vector with the same direction
 		as this one, but [page:.length length] 1.
 		</p>
 
-		<h3>[method:Vector3 project]( [param:Camera camera] )</h3>
+		<h3>[method:this project]( [param:Camera camera] )</h3>
 		<p>
 		[page:Camera camera] — camera to use in the projection.<br /><br />
 
 		[link:https://en.wikipedia.org/wiki/Vector_projection Projects] the vector with the camera.
 		</p>
 
-		<h3>[method:Vector3 projectOnPlane]( [param:Vector3 planeNormal] )</h3>
+		<h3>[method:this projectOnPlane]( [param:Vector3 planeNormal] )</h3>
 		<p>
 		[page:Vector3 planeNormal] - A vector representing a plane normal.<br /><br />
 
@@ -320,10 +320,10 @@ var d = a.distanceTo( b );
 		normal from this vector.
 		</p>
 
-		<h3>[method:Vector3 projectOnVector]( [param:Vector3] )</h3>
+		<h3>[method:this projectOnVector]( [param:Vector3] )</h3>
 		<p>[link:https://en.wikipedia.org/wiki/Vector_projection Projects] this vector onto another vector.</p>
 
-		<h3>[method:Vector3 reflect]( [param:Vector3 normal] )</h3>
+		<h3>[method:this reflect]( [param:Vector3 normal] )</h3>
 		<p>
 		[page:Vector3 normal] - the normal to the reflecting plane<br /><br />
 
@@ -331,15 +331,15 @@ var d = a.distanceTo( b );
 		have unit length.
 		</p>
 
-		<h3>[method:Vector3 round]()</h3>
+		<h3>[method:this round]()</h3>
 		<p>The components of the vector are rounded to the nearest integer value.</p>
 
-		<h3>[method:Vector3 roundToZero]()</h3>
+		<h3>[method:this roundToZero]()</h3>
 		<p>
 		The components of the vector are rounded towards zero (up if negative, down if positive) to an integer value.
 		</p>
 
-		<h3>[method:Vector3 set]( [param:Float x], [param:Float y], [param:Float z] )</h3>
+		<h3>[method:this set]( [param:Float x], [param:Float y], [param:Float z] )</h3>
 		<p>Sets the [page:.x x], [page:.y y] and [page:.z z] components of this vector.</p>
 
 		<h3>[method:null setComponent]( [param:Integer index], [param:Float value] )</h3>
@@ -352,61 +352,61 @@ var d = a.distanceTo( b );
 		If index equals 2 set [page:.z z] to [page:Float value]
 		</p>
 
-		<h3>[method:Vector3 setFromCylindrical]( [param:Cylindrical c] )</h3>
+		<h3>[method:this setFromCylindrical]( [param:Cylindrical c] )</h3>
 		<p>
 		Sets this vector from the cylindrical coordinates [page:Cylindrical c].
 		</p>
 
-		<h3>[method:Vector3 setFromMatrixColumn]( [param:Matrix4 matrix], [param:Integer index] )</h3>
+		<h3>[method:this setFromMatrixColumn]( [param:Matrix4 matrix], [param:Integer index] )</h3>
 		<p>
 		Sets this vector's [page:.x x], [page:.y y] and [page:.z z] equal to the column of
 		the [page:Matrix4 matrix] specified by the [page:Integer index].
 		</p>
 
-		<h3>[method:Vector3 setFromMatrixPosition]( [param:Matrix4 m] )</h3>
+		<h3>[method:this setFromMatrixPosition]( [param:Matrix4 m] )</h3>
 		<p>
 		Sets this vector to the position elements of the
 		[link:https://en.wikipedia.org/wiki/Transformation_matrix transformation matrix] [page:Matrix4 m].
 		</p>
 
-		<h3>[method:Vector3 setFromMatrixScale]( [param:Matrix4 m] )</h3>
+		<h3>[method:this setFromMatrixScale]( [param:Matrix4 m] )</h3>
 		<p>
 		Sets this vector to the scale elements of the
 		[link:https://en.wikipedia.org/wiki/Transformation_matrix transformation matrix] [page:Matrix4 m].
 		</p>
 
-		<h3>[method:Vector3 setFromSpherical]( [param:Spherical s] )</h3>
+		<h3>[method:this setFromSpherical]( [param:Spherical s] )</h3>
 		<p>
 		Sets this vector from the spherical coordinates [page:Spherical s].
 		</p>
 
-		<h3>[method:Vector3 setLength]( [param:Float l] )</h3>
+		<h3>[method:this setLength]( [param:Float l] )</h3>
 		<p>
 		Set this vector to the vector with the same direction as this one, but [page:.length length]
 		[page:Float l].
 		</p>
 
-		<h3>[method:Vector3 setScalar]( [param:Float scalar] )</h3>
+		<h3>[method:this setScalar]( [param:Float scalar] )</h3>
 		<p>
 		Set the [page:.x x], [page:.y y] and [page:.z z] values of this vector both equal to [page:Float scalar].
 		</p>
 
-		<h3>[method:Vector3 setX]( [param:Float x] )</h3>
+		<h3>[method:this setX]( [param:Float x] )</h3>
 		<p>Replace this vector's [page:.x x] value with [page:Float x].</p>
 
-		<h3>[method:Vector3 setY]( [param:Float y] )</h3>
+		<h3>[method:this setY]( [param:Float y] )</h3>
 		<p>Replace this vector's [page:.y y] value with [page:Float y].</p>
 
-		<h3>[method:Vector3 setZ]( [param:Float z] )</h3>
+		<h3>[method:this setZ]( [param:Float z] )</h3>
 		<p>Replace this vector's [page:.z z] value with [page:Float z].</p>
 
-		<h3>[method:Vector3 sub]( [param:Vector3 v] )</h3>
+		<h3>[method:this sub]( [param:Vector3 v] )</h3>
 		<p>Subtracts [page:Vector3 v] from this vector.</p>
 
-		<h3>[method:Vector3 subScalar]( [param:Float s] )</h3>
+		<h3>[method:this subScalar]( [param:Float s] )</h3>
 		<p>Subtracts [page:Float s]  from this vector's [page:.x x], [page:.y y] and [page:.z z] compnents.</p>
 
-		<h3>[method:Vector3 subVectors]( [param:Vector3 a], [param:Vector3 b] )</h3>
+		<h3>[method:this subVectors]( [param:Vector3 a], [param:Vector3 b] )</h3>
 		<p>Sets this vector to [page:Vector3 a] - [page:Vector3 b].</p>
 
 		<h3>[method:Array toArray]( [param:Array array], [param:Integer offset] )</h3>
@@ -418,13 +418,13 @@ var d = a.distanceTo( b );
 		Returns an array [x, y, z], or copies x, y and z into the provided [page:Array array].
 		</p>
 
-		<h3>[method:Vector3 transformDirection]( [param:Matrix4 m] )</h3>
+		<h3>[method:this transformDirection]( [param:Matrix4 m] )</h3>
 		<p>
 		Transforms the direction of this vector by a matrix (the upper left 3 x 3 subset of a [page:Matrix4 m])
 		and then [page:.normalize normalizes] the result.
 		</p>
 
-		<h3>[method:Vector3 unproject]( [param:Camera camera] )</h3>
+		<h3>[method:this unproject]( [param:Camera camera] )</h3>
 		<p>
 		[page:Camera camera] — camera to use in the projection.<br /><br />
 

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

@@ -81,29 +81,29 @@ var d = a.dot( b );
 
 		<h2>Methods</h2>
 
-		<h3>[method:Vector4 add]( [param:Vector4 v] )</h3>
+		<h3>[method:this add]( [param:Vector4 v] )</h3>
 		<p>Adds [page:Vector4 v] to this vector.</p>
 
-		<h3>[method:Vector4 addScalar]( [param:Float s] )</h3>
+		<h3>[method:this addScalar]( [param:Float s] )</h3>
 		<p>Adds the scalar value s to this vector's [page:.x x], [page:.y y], [page:.z z] and [page:.w w] values.</p>
 
-		<h3>[method:Vector4 addScaledVector]( [param:Vector4 v], [param:Float s] )</h3>
+		<h3>[method:this addScaledVector]( [param:Vector4 v], [param:Float s] )</h3>
 		<p>Adds the multiple of [page:Vector4 v] and [page:Float s] to this vector.</p>
 
-		<h3>[method:Vector4 addVectors]( [param:Vector4 a], [param:Vector4 b] )</h3>
+		<h3>[method:this addVectors]( [param:Vector4 a], [param:Vector4 b] )</h3>
 		<p>Sets this vector to [page:Vector4 a] + [page:Vector4 b].</p>
 
-		<h3>[method:Vector4 applyMatrix4]( [param:Matrix4 m] )</h3>
+		<h3>[method:this applyMatrix4]( [param:Matrix4 m] )</h3>
 		<p>
 		Multiplies this vector by 4 x 4 [page:Matrix4 m].
 		</p>
 
-		<h3>[method:Vector4 ceil]()</h3>
+		<h3>[method:this ceil]()</h3>
 		<p>
 		The [page:.x x], [page:.y y], [page:.z z] and [page:.w w] components of the vector are rounded up to the nearest integer value.
 		</p>
 
-		<h3>[method:Vector4 clamp]( [param:Vector4 min], [param:Vector4 max] )</h3>
+		<h3>[method:this clamp]( [param:Vector4 min], [param:Vector4 max] )</h3>
 		<p>
 		[page:Vector4 min] - the minimum [page:.x x], [page:.y y], [page:.z z] and [page:.w w] values.<br />
 		[page:Vector4 max] - the maximum [page:.x x], [page:.y y], [page:.z z] and [page:.w w] values in the desired range<br /><br />
@@ -112,7 +112,7 @@ var d = a.dot( b );
 		If this vector's x, y, z or w value is less than the min vector's x, y, z or w value, it is replaced by the corresponding value.
 		</p>
 
-		<h3>[method:Vector4 clampLength]( [param:Float min], [param:Float max] )</h3>
+		<h3>[method:this clampLength]( [param:Float min], [param:Float max] )</h3>
 		<p>
 		[page:Float min] - the minimum value the length will be clamped to <br />
 		[page:Float max] - the maximum value the length will be clamped to<br /><br />
@@ -121,7 +121,7 @@ var d = a.dot( b );
 		If this vector's length is less than the min value, it is replaced by the min value.
 		</p>
 
-		<h3>[method:Vector4 clampScalar]( [param:Float min], [param:Float max] )</h3>
+		<h3>[method:this clampScalar]( [param:Float min], [param:Float max] )</h3>
 		<p>
 		[page:Float min] - the minimum value the components will be clamped to <br />
 		[page:Float max] - the maximum value the components will be clamped to<br /><br />
@@ -135,13 +135,13 @@ var d = a.dot( b );
 		Returns a new Vector4 with the same [page:.x x], [page:.y y], [page:.z z] and [page:.w w] values as this one.
 		</p>
 
-		<h3>[method:Vector4 copy]( [param:Vector4 v] )</h3>
+		<h3>[method:this copy]( [param:Vector4 v] )</h3>
 		<p>
 			Copies the values of the passed Vector4's [page:.x x], [page:.y y], [page:.z z] and [page:.w w]
 			properties to this Vector4.
 		</p>
 
-		<h3>[method:Vector4 divideScalar]( [param:Float s] )</h3>
+		<h3>[method:this divideScalar]( [param:Float s] )</h3>
 		<p>
 		Divides this vector by scalar [page:Float s].<br />
 		Sets vector to *( 0, 0, 0, 0 )* if *[page:Float s] = 0*.
@@ -156,10 +156,10 @@ var d = a.dot( b );
 		<h3>[method:Boolean equals]( [param:Vector4 v] )</h3>
 		<p>Checks for strict equality of this vector and [page:Vector4 v].</p>
 
-		<h3>[method:Vector4 floor]()</h3>
+		<h3>[method:this floor]()</h3>
 		<p>The components of the vector are rounded down to the nearest integer value.</p>
 
-		<h3>[method:Vector4 fromArray]( [param:Array array], [param:Integer offset] )</h3>
+		<h3>[method:this fromArray]( [param:Array array], [param:Integer offset] )</h3>
 		<p>
 		[page:Array array] - the source array.<br />
 		[page:Integer offset] - (optional) offset into the array. Default is 0.<br /><br />
@@ -168,7 +168,7 @@ var d = a.dot( b );
 		[page:.z z] value to be array[ offset + 2 ] and [page:.w w ] value to be array[ offset + 3 ].
 		</p>
 
-		<h3>[method:Vector4 fromBufferAttribute]( [param:BufferAttribute attribute], [param:Integer index] )</h3>
+		<h3>[method:this fromBufferAttribute]( [param:BufferAttribute attribute], [param:Integer index] )</h3>
 		<p>
 		[page:BufferAttribute attribute] - the source attribute.<br />
 		[page:Integer index] - index in the attribute.<br /><br />
@@ -202,7 +202,7 @@ var d = a.dot( b );
 		vectors, you should compare the length squared instead as it is slightly more efficient to calculate.
 		</p>
 
-		<h3>[method:Vector4 lerp]( [param:Vector4 v], [param:Float alpha] )</h3>
+		<h3>[method:this lerp]( [param:Vector4 v], [param:Float alpha] )</h3>
 		<p>
 		[page:Vector4 v] - [page:Vector4] to interpolate towards.<br />
 		alpha - interpolation factor in the closed interval [0, 1].<br /><br />
@@ -211,7 +211,7 @@ var d = a.dot( b );
 		distance along the line - alpha = 0 will be this vector, and alpha = 1 will be [page:Vector4 v].
 		</p>
 
-		<h3>[method:Vector4 lerpVectors]( [param:Vector4 v1], [param:Vector4 v2], [param:Float alpha] )</h3>
+		<h3>[method:this lerpVectors]( [param:Vector4 v1], [param:Vector4 v2], [param:Float alpha] )</h3>
 		<p>
 		[page:Vector4 v1] - the starting [page:Vector4].<br />
 		[page:Vector4 v2] - [page:Vector4] to interpolate towards.<br />
@@ -222,42 +222,42 @@ var d = a.dot( b );
 		- alpha = 0 will be [page:Vector4 v1], and alpha = 1 will be [page:Vector4 v2].
 		</p>
 
-		<h3>[method:Vector4 negate]()</h3>
+		<h3>[method:this negate]()</h3>
 		<p>Inverts this vector - i.e. sets x = -x, y = -y, z = -z and w = -w.</p>
 
-		<h3>[method:Vector4 normalize]()</h3>
+		<h3>[method:this normalize]()</h3>
 		<p>
 		Converts this vector to a [link:https://en.wikipedia.org/wiki/Unit_vector unit vector] - that is, sets it equal to the vector with the same direction
 		as this one, but [page:.length length] 1.
 		</p>
 
-		<h3>[method:Vector4 max]( [param:Vector4 v] )</h3>
+		<h3>[method:this max]( [param:Vector4 v] )</h3>
 		<p>
 		If this vector's x, y, z or w value is less than [page:Vector4 v]'s x, y, z or w value, replace
 		that value with the corresponding max value.
 		</p>
 
-		<h3>[method:Vector4 min]( [param:Vector4 v] )</h3>
+		<h3>[method:this min]( [param:Vector4 v] )</h3>
 		<p>
 		If this vector's x, y, z or w value is greater than [page:Vector4 v]'s x, y, z or w value, replace
 		that value with the corresponding min value.
 		</p>
 
-		<h3>[method:Vector4 multiplyScalar]( [param:Float s] )</h3>
+		<h3>[method:this multiplyScalar]( [param:Float s] )</h3>
 		<p>Multiplies this vector by scalar [page:Float s].</p>
 
-		<h3>[method:Vector4 round]()</h3>
+		<h3>[method:this round]()</h3>
 		<p>The components of the vector are rounded to the nearest integer value.</p>
 
-		<h3>[method:Vector4 roundToZero]()</h3>
+		<h3>[method:this roundToZero]()</h3>
 		<p>
 		The components of the vector are rounded towards zero (up if negative, down if positive) to an integer value.
 		</p>
 
-		<h3>[method:Vector4 set]( [param:Float x], [param:Float y], [param:Float z], [param:Float w] )</h3>
+		<h3>[method:this set]( [param:Float x], [param:Float y], [param:Float z], [param:Float w] )</h3>
 		<p>Sets the [page:.x x], [page:.y y], [page:.z z] and [page:.w w] components of this vector.</p>
 
-		<h3>[method:Vector4 setAxisAngleFromQuaternion]( [param:Quaterion q] )</h3>
+		<h3>[method:this setAxisAngleFromQuaternion]( [param:Quaterion q] )</h3>
 		<p>
 			[page:Quaterion q] - a normalized [page:Quaterion]<br /><br />
 
@@ -265,7 +265,7 @@ var d = a.dot( b );
 			quaternion's axis and [page:.w w] to the angle.
 		</p>
 
-		<h3>[method:Vector4 setAxisAngleFromRotationMatrix]( [param:Matrix4 m] )</h3>
+		<h3>[method:this setAxisAngleFromRotationMatrix]( [param:Matrix4 m] )</h3>
 		<p>
 			 [page:Matrix4 m] - a [page:Matrix4] of which the upper left 3x3 matrix is a pure rotation matrix.<br /><br />
 
@@ -284,36 +284,36 @@ var d = a.dot( b );
 		</p>
 
 
-		<h3>[method:Vector4 setLength]( [param:Float l] )</h3>
+		<h3>[method:this setLength]( [param:Float l] )</h3>
 		<p>
 		Sets this vector to the vector with the same direction as this one, but [page:.length length]
 		[page:Float l].
 		</p>
 
-		<h3>[method:Vector4 setScalar]( [param:Float scalar] )</h3>
+		<h3>[method:this setScalar]( [param:Float scalar] )</h3>
 		<p>
 		Sets the [page:.x x], [page:.y y], [page:.z z] and [page:.w w] values of this vector both equal to [page:Float scalar].
 		</p>
 
-		<h3>[method:Vector4 setX]( [param:Float x] )</h3>
+		<h3>[method:this setX]( [param:Float x] )</h3>
 		<p>Replaces this vector's [page:.x x] value with [page:Float x].</p>
 
-		<h3>[method:Vector4 setY]( [param:Float y] )</h3>
+		<h3>[method:this setY]( [param:Float y] )</h3>
 		<p>Replaces this vector's [page:.y y] value with [page:Float y].</p>
 
-		<h3>[method:Vector4 setZ]( [param:Float z] )</h3>
+		<h3>[method:this setZ]( [param:Float z] )</h3>
 		<p>Replaces this vector's [page:.z z] value with [page:Float z].</p>
 
-		<h3>[method:Vector4 setW]( [param:Float w] )</h3>
+		<h3>[method:this setW]( [param:Float w] )</h3>
 		<p>Replaces this vector's [page:.w w] value with [page:Float w].</p>
 
-		<h3>[method:Vector4 sub]( [param:Vector4 v] )</h3>
+		<h3>[method:this sub]( [param:Vector4 v] )</h3>
 		<p>Subtracts [page:Vector4 v] from this vector.</p>
 
-		<h3>[method:Vector4 subScalar]( [param:Float s] )</h3>
+		<h3>[method:this subScalar]( [param:Float s] )</h3>
 		<p>Subtracts [page:Float s]  from this vector's [page:.x x], [page:.y y], [page:.z z] and [page:.w w] compnents.</p>
 
-		<h3>[method:Vector4 subVectors]( [param:Vector4 a], [param:Vector4 b] )</h3>
+		<h3>[method:this subVectors]( [param:Vector4 a], [param:Vector4 b] )</h3>
 		<p>Sets this vector to [page:Vector4 a] - [page:Vector4 b].</p>
 
 		<h3>[method:Array toArray]( [param:Array array], [param:Integer offset] )</h3>

+ 1 - 1
docs/api/objects/Line.html

@@ -79,7 +79,7 @@
 		Computes an array of distance values which are necessary for [page:LineDashedMaterial]. For each vertex in the geometry, the method calculates the cumulative length from the current point to the very beginning of the line.
 		</p>
 
-		<h3>[method:Array raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
+		<h3>[method:null raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
 		<p>
 		Get intersections between a casted [page:Ray] and this Line.
 		[page:Raycaster.intersectObject] will call this method.

+ 1 - 1
docs/api/objects/Mesh.html

@@ -92,7 +92,7 @@
 		<h3>[method:Mesh clone]()</h3>
 		<p>Returns a clone of this [name] object and its descendants.</p>
 
-		<h3>[method:Array raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
+		<h3>[method:null raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
 		<p>
 		Get intersections between a casted ray and this mesh.
 		[page:Raycaster.intersectObject] will call this method.

+ 1 - 1
docs/api/objects/Points.html

@@ -58,7 +58,7 @@
 		<h2>Methods</h2>
 		<p>See the base [page:Object3D] class for common methods.</p>
 
-		<h3>[method:Array raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
+		<h3>[method:null raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
 		<p>
 		Get intersections between a casted ray and this Points.
 		[page:Raycaster.intersectObject] will call this method.

+ 4 - 1
docs/api/objects/SkinnedMesh.html

@@ -12,7 +12,10 @@
 
 		<h1>[name]</h1>
 
-		<p class="desc">A mesh that has a [page:Skeleton] with [page:Bone bones] that can then be used to animate the vertices of the geometry.</p>
+		<p class="desc">
+			A mesh that has a [page:Skeleton] with [page:Bone bones] that can then be used to animate the vertices of the geometry.
+			The material must support skinning and have skinning enabled - see [page:MeshStandardMaterial.skinning].
+		</p>
 
 		<iframe id="scene" src="scenes/bones-browser.html"></iframe>
 

+ 1 - 1
docs/api/objects/Sprite.html

@@ -76,7 +76,7 @@ scene.add( sprite );
 		Copies the properties of the passed sprite to this one.
 		</p>
 
-		<h3>[method:Array raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
+		<h3>[method:null raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
 		<p>
 		Get intersections between a casted ray and this sprite.
 		[page:Raycaster.intersectObject] will call this method.

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

@@ -286,10 +286,6 @@
 		See [page:WebGLRenderer.capabilities capabilities.maxTextures].
 		</p>
 
-		<h3>[method:null animate]( [param:Function callback] )</h3>
-		<p>[page:Function callback] — The function will be called every available frame. If `null` is passed it will stop any already ongoing animation.</p>
-		<p>A build in function that can be used instead of [link:https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame requestAnimationFrame]. For WebVR projects this function must be used.</p>
-
 		<h3>[method:null clear]( [param:Boolean color], [param:Boolean depth], [param:Boolean stencil] )</h3>
 		<p>
 		Tells the renderer to clear its color, depth or stencil drawing buffer(s).
@@ -407,6 +403,10 @@
 		Render an immediate buffer. Gets called by renderImmediateObject.
 		</p>
 
+		<h3>[method:null setAnimationLoop]( [param:Function callback] )</h3>
+		<p>[page:Function callback] — The function will be called every available frame. If `null` is passed it will stop any already ongoing animation.</p>
+		<p>A build in function that can be used instead of [link:https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame requestAnimationFrame]. For WebVR projects this function must be used.</p>
+
 		<h3>[method:null setClearAlpha]( [param:Float alpha] )</h3>
 		<p>Sets the clear alpha. Valid input is a float between *0.0* and *1.0*.</p>
 

+ 1 - 0
docs/api/textures/DataTexture.html

@@ -57,6 +57,7 @@
 		// used the buffer to create a [name]
 
 		var texture = new THREE.DataTexture( data, width, height, THREE.RGBFormat );
+		texture.needsUpdate = true
 		</code>
 
 		<h2>Properties</h2>

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

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

+ 1 - 1
docs/examples/exporters/GLTFExporter.html

@@ -25,7 +25,7 @@
 
 		<code>
 		// Instantiate a exporter
-		var exporter = new THREE.GLTFExporter( defaultOptions );
+		var exporter = new THREE.GLTFExporter();
 
 		// Parse the input and generate the glTF output
 		exporter.parse( scene, function ( gltf ) {

+ 62 - 0
docs/examples/exporters/PLYExporter.html

@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		<h1>[name]</h1>
+
+		<p class="desc">
+		An exporter for *PLY*.
+		<br /><br />
+		<a href="https://www.khronos.org/gltf">PLY</a> (Polygon or Stanford Triangle Format) is a
+		file format for efficient delivery and loading of simple, static 3D content in a dense format.
+		Both binary and ascii formats are supported. PLY can store vertex positions, colors, normals and
+		uv coordinates. No textures or texture references are saved.
+		</p>
+
+		<h2>Example</h2>
+
+		<code>
+		// Instantiate an exporter
+		var exporter = new THREE.PLYExporter();
+
+		// Parse the input and generate the ply output
+		var data = exporter.parse( scene, options );
+		downloadFile(data);
+		</code>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]()</h3>
+		<p>
+		</p>
+		<p>
+		Creates a new [name].
+		</p>
+
+		<h2>Methods</h2>
+
+		<h3>[method:null parse]( [param:Object3D input], [param:Object options] )</h3>
+		<p>
+		[page:Object input] — Object3D<br />
+		[page:Options options] — Export options<br />
+		<ul>
+			<li>excludeAttributes - array. Which properties to explicitly exclude from the exported PLY file. Valid values are 'color', 'normal', 'uv', and 'index'. If triangle indices are excluded, then a point cloud is exported. Default is an empty array.</li>
+			<li>binary - bool. Export in binary format, returning an ArrayBuffer. Default is false.</li>
+		</ul>
+		</p>
+		<p>
+		Generates ply file data as string or ArrayBuffer (ascii or binary) output from the input object.
+		If the object is composed of multiple children and geometry, they are merged into a single mesh in the file.
+		</p>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/exporters/PLYExporter.js examples/js/exporters/PLYExporter.js]
+	</body>
+</html>

+ 1 - 1
docs/examples/loaders/MMDLoader.html

@@ -13,7 +13,7 @@
 
 		<p class="desc"> A loader for <a href="http://www.geocities.jp/higuchuu4/index_e.htm"><em>MMD</em></a> resources. <br /><br />
 		[name] creates Three.js Objects from MMD resources as PMD, PMX, VMD, and VPD files.
-		You can easily handle MMD special features, as IK, Grant, and Physics, with [page:MMDAnimationHelper].<br /><br />
+		See [page:MMDAnimationHelper] for MMD animation handling as IK, Grant, and Physics.<br /><br />
 
 		If you want raw content of MMD resources, use .loadPMD/PMX/VMD/VPD methods.
 

+ 2 - 2
docs/examples/quickhull/QuickHull.html

@@ -72,13 +72,13 @@
 		<p>Makes this convex hull empty.</p>
 
 		<h3>[method:QuickHull addVertexToFace]( [param:VertexNode vertex], [param:Face face]	)</h3>
-		[page:VertexNodeNode vertex] - The vetex to add.<br /><br />
+		[page:VertexNodeNode vertex] - The vertex to add.<br /><br />
 		[page:Face face] - The target face.<br /><br />
 
 		<p>Adds a vertex to the 'assigned' list of vertices and assigns it to the given face.</p>
 
 		<h3>[method:QuickHull removeVertexFromFace]( [param:VertexNode vertex], [param:Face face]	)</h3>
-		[page:VertexNode vertex] - The vetex to remove.<br /><br />
+		[page:VertexNode vertex] - The vertex to remove.<br /><br />
 		[page:Face face] - The target face.<br /><br />
 
 		<p>Removes a vertex from the 'assigned' list of vertices and from the given face. It also makes sure that the link from 'face' to the first vertex it sees in 'assigned' is linked correctly after the removal.</p>

+ 1 - 0
docs/examples/renderers/CSS2DRenderer.html

@@ -33,6 +33,7 @@
 		<h2>Examples</h2>
 
 		<p>
+			[example:css2d_label]<br>
 			[example:webgl_loader_pdb molecules]
 		</p>
 

+ 3 - 1
docs/list.js

@@ -10,6 +10,7 @@ var list = {
 			"How to run things locally": "manual/introduction/How-to-run-things-locally",
 			"Drawing Lines": "manual/introduction/Drawing-lines",
 			"Creating Text": "manual/introduction/Creating-text",
+			"Loading 3D Models": "manual/introduction/Loading-3D-models",
 			"Migration Guide": "manual/introduction/Migration-guide",
 			"Code Style Guide": "manual/introduction/Code-style-guide",
 			"FAQ": "manual/introduction/FAQ",
@@ -373,7 +374,8 @@ var list = {
 		},
 
 		"Exporters": {
-			"GLTFExporter": "examples/exporters/GLTFExporter"
+			"GLTFExporter": "examples/exporters/GLTFExporter",
+			"PLYExporter": "examples/exporters/PLYExporter"
 		},
 
 		"Plugins": {

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

@@ -35,11 +35,11 @@
 		<p class="desc">
 
 			If you have successfully imported an animated 3D object (it doesn't matter if it has
-			bones or morph targets or both) - for example exporting it from Blender with the
-			[link:https://github.com/mrdoob/three.js/tree/master/utils/exporters/blender/addons/io_three Blender exporter] and
-			loading it into a three.js scene using [page:JSONLoader] -, one of the geometry's
-			properties of the loaded mesh should be an array named "animations", containing the
-			[page:AnimationClip AnimationClips] for this model (see a list of possible loaders below).<br /><br />
+			bones or morph targets or both)  for example exporting it from Blender with the
+			[link:https://github.com/KhronosGroup/glTF-Blender-Exporter glTF Blender exporter] and
+			loading it into a three.js scene using [page:GLTFLoader] — one of the response fields
+			should be an array named "animations", containing the [page:AnimationClip AnimationClips]
+			for this model (see a list of possible loaders below).<br /><br />
 
 			Each *AnimationClip* usually holds the data for a certain activity of the object. If the
 			mesh is a character, for example, there may be one AnimationClip for a walkcycle, a second

+ 4 - 4
docs/manual/introduction/Creating-a-scene.html

@@ -14,7 +14,7 @@
 
 		<h2>Before we start</h2>
 
-		<p>Before you can use three.js, you need somewhere to display it. Save the following HTML to a file on your computer, along with a copy of <a href="http://threejs.org/build/three.js">three.js</a> in the js/ directory, and open it in your browser.</p>
+		<p>Before you can use three.js, you need somewhere to display it. Save the following HTML to a file on your computer, along with a copy of [link:https://threejs.org/build/three.js three.js] in the js/ directory, and open it in your browser.</p>
 
 		<code>
 		&lt;!DOCTYPE html&gt;
@@ -109,8 +109,8 @@
 		<p>Add the following right above the <strong>renderer.render</strong> call in your <strong>animate</strong> function:</p>
 
 		<code>
-		cube.rotation.x += 0.1;
-		cube.rotation.y += 0.1;
+		cube.rotation.x += 0.01;
+		cube.rotation.y += 0.01;
 		</code>
 
 		<p>This will be run every frame (normally 60 times per second), and give the cube a nice rotation animation. Basically, anything you want to move or change while the app is running has to go through the animate loop. You can of course call other functions from there, so that you don't end up with a <strong>animate</strong> function that's hundreds of p.
@@ -153,7 +153,7 @@
 						cube.rotation.x += 0.1;
 						cube.rotation.y += 0.1;
 
-						renderer.render(scene, camera);
+						renderer.render( scene, camera );
 					};
 
 					animate();

+ 3 - 3
docs/manual/introduction/FAQ.html

@@ -16,7 +16,7 @@
 				The recommended format for importing and exporting assets is glTF (GL Transmission Format). Because glTF is focused on runtime asset delivery, it is compact to transmit and fast to load.
 			</p>
 			<p>
-				three.js provides loaders for many other popular formats like FBX, Collada or OBJ as well. Nevertheless, you should always try to establish a glTF based workflow in your projects first.
+				three.js provides loaders for many other popular formats like FBX, Collada or OBJ as well. Nevertheless, you should always try to establish a glTF based workflow in your projects first. For more information, see [link:#manual/introduction/Loading-3D-models loading 3D models].
 			</p>
 		</div>
 
@@ -26,9 +26,9 @@
 
 				<p>These tags control viewport size and scale for mobile browsers (where page content may be rendered at different size than visible viewport).</p>
 
-				<p><a href="https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html">Safari: Using the Viewport</a></p>
+				<p>[link:https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html Safari: Using the Viewport]</p>
 
-				<p><a href="https://developer.mozilla.org/en/Mobile/Viewport_meta_tag">MDN: Using the viewport meta tag</a></p>
+				<p>[link:https://developer.mozilla.org/en/Mobile/Viewport_meta_tag MDN: Using the viewport meta tag]</p>
 		</div>
 
 		<h2>How can scene scale be preserved on resize?</h2>

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

@@ -23,11 +23,11 @@
 
 		<h2>Installation via npm</h2>
 
-		<p>Three.js is published as an npm module, see: <a href="https://www.npmjs.com/package/three" target="_blank">npm</a>. This means all you need to do to include three.js into your project is run "npm install three"</p>
+		<p>Three.js is published as an npm module, see: [link:https://www.npmjs.com/package/three npm]. This means all you need to do to include three.js into your project is run "npm install three"</p>
 
 		<h2>Importing the module</h2>
 
-		<p>Assuming that you're bundling your files with a tool such as <a href="https://webpack.github.io/" target="_blank">Webpack</a> or <a href="https://github.com/substack/node-browserify" target="_blank">Browserify</a>, 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.
@@ -41,7 +41,7 @@
 		</code>
 
 		<p>
-			You're also able to leverage <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import" target="_blank">ES6 import syntax</a>:
+			You're also able to leverage [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import ES6 import syntax]:
 		</p>
 
 		<code>

+ 129 - 0
docs/manual/introduction/Loading-3D-models.html

@@ -0,0 +1,129 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+  <meta charset="utf-8">
+  <base href="../../" />
+  <script src="list.js"></script>
+  <script src="page.js"></script>
+  <link type="text/css" rel="stylesheet" href="page.css" />
+</head>
+
+<body>
+  <h1>[name]</h1>
+  <br />
+
+  <p>
+    3D models are available in hundreds of file formats, each with different
+    purposes, assorted features, and varying complexity. Although
+    <a href="https://github.com/mrdoob/three.js/tree/dev/examples/js/loaders" target="_blank" rel="noopener">
+    three.js provides many loaders</a>, choosing the right format and
+    workflow will save time and frustration later on. Some formats are
+    difficult to work with, inefficient for realtime experiences, or simply not
+    fully supported at this time.
+  </p>
+
+  <p>
+    This guide provides a workflow recommended for most users, and suggestions
+    for what to try if things don't go as expected.
+  </p>
+
+  <h2>Before we start</h2>
+
+  <p>
+    If you're new to running a local server, begin with
+    [link:#manual/introduction/How-to-run-things-locally how to run things locally]
+    first. Many common errors viewing 3D models can be avoided by hosting files
+    correctly.
+  </p>
+
+  <h2>Recommended workflow</h2>
+
+  <p>
+    Where possible, we recommend using glTF (GL Transmission Format). Both
+    <small>.GLB</small> and <small>.GLTF</small> versions of the format are
+    well supported. Because glTF is focused on runtime asset delivery, it is
+    compact to transmit and fast to load. Features include meshes, materials,
+    textures, skins, skeletons, morph targets, animations, lights, and
+    cameras.
+  </p>
+
+  <p>
+    Public-domain glTF files are available on sites like
+    <a href="https://sketchfab.com/models?features=downloadable&sort_by=-likeCount&type=models" target="_blank" rel="noopener">
+    Sketchfab</a>, or various tools include glTF export:
+  </p>
+
+  <ul>
+    <li><a href="https://github.com/KhronosGroup/glTF-Blender-Exporter" target="_blank" rel="noopener">glTF-Blender-Exporter</a> by the Khronos Group</li>
+    <li><a href="https://github.com/KhronosGroup/COLLADA2GLTF" target="_blank" rel="noopener">COLLADA2GLTF</a> by the Khronos Group</li>
+    <li><a href="https://github.com/facebookincubator/FBX2glTF" target="_blank" rel="noopener">FBX2GLTF</a> by Facebook</li>
+    <li><a href="https://github.com/AnalyticalGraphicsInc/obj2gltf" target="_blank" rel="noopener">OBJ2GLTF</a> by Analytical Graphics Inc</li>
+    <li><a href="https://www.allegorithmic.com/products/substance-painter" target="_blank" rel="noopener">Substance Painter</a> by Allegorithmic</li>
+    <li><a href="https://www.foundry.com/products/modo" target="_blank" rel="noopener">Modo</a> by Foundry</li>
+    <li><a href="https://www.marmoset.co/toolbag/" target="_blank" rel="noopener">Toolbag</a> by Marmoset</li>
+    <li>&hellip;and <a href="https://github.com/khronosgroup/gltf#gltf-tools" target="_blank" rel="noopener">many more</a></li>
+  </ul>
+
+  <p>
+    If your preferred tools do not support glTF, consider requesting glTF
+    export from the authors, or posting on
+    <a href="https://github.com/KhronosGroup/glTF/issues/1051" target="_blank" rel="noopener">the glTF roadmap thread</a>.
+  </p>
+
+  <p>
+    When glTF is not an option, popular formats such as FBX, OBJ, or COLLADA
+    are also available and regularly maintained.
+  </p>
+
+  <h2>Troubleshooting</h2>
+
+  <p>
+    You've spent hours modeling an artisanal masterpiece, you load it into
+    the webpage, and — oh no! 😭 It's distorted, miscolored, or missing entirely.
+    Start with these troubleshooting steps:
+  </p>
+
+  <ol>
+    <li>
+      Check the JavaScript console for errors, and make sure you've used an
+      <em>onError</em> callback when calling <em>.load()</em> to log the result.
+    </li>
+    <li>
+      View the model in another application. For glTF, drag-and-drop viewers
+      are available for
+      <a href="https://gltf-viewer.donmccurdy.com/" target="_blank" rel="noopener">three.js</a> and
+      <a href="http://sandbox.babylonjs.com/" target="_blank" rel="noopener">babylon.js</a>. If the model
+      appears correctly in one or more applications,
+      <a href="https://github.com/mrdoob/three.js/issues/new" target="_blank" rel="noopener">file a bug against three.js</a>.
+      If the model cannot be shown in any application, we strongly encourage
+      filing a bug with the application used to create the model.
+    </li>
+    <li>
+      Try scaling the model up or down by a factor of 1000. Many models are
+      scaled differently, and large models may not appear if the camera is
+      inside the model.
+    </li>
+    <li>
+      Look for failed texture requests in the network tab, like
+      <em>C:\\Path\To\Model\texture.jpg</em>. Use paths relative to your
+      model instead, such as <em>images/texture.jpg</em> — this may require
+      editing the model file in a text editor.
+    </li>
+  </ol>
+
+  <h2>Asking for help</h2>
+
+  <p>
+    If you've gone through the troubleshooting process above and your model
+    still isn't working, the right approach to asking for help will get you to
+    a solution faster. Post a question on the
+    <a href="https://discourse.threejs.org/" target="_blank" rel="noopener">three.js forum</a> and, whenever possible,
+    include your model (or a simpler model with the same problem) in any formats
+    you have available. Include enough information for someone else to reproduce
+    the issue quickly — ideally, a live demo.
+  </p>
+
+</body>
+
+</html>

+ 7 - 0
docs/manual/introduction/Useful-links.html

@@ -126,6 +126,13 @@
 			[link:http://idflood.github.io/ThreeNodes.js/ ThreeNodes.js].
 		</li>
 	 </ul>
+		
+	<h2>WebGL References</h2>
+	 <ul>
+		 <li>
+			[link:https://www.khronos.org/files/webgl/webgl-reference-card-1_0.pdf] - Reference of all WebGL and GLSL keywords, terminology, syntex and definations.
+		 </li>
+	 </ul>
 
 	 <h2>Old Links</h2>
 	 <p>

+ 1 - 1
docs/page.js

@@ -70,7 +70,7 @@ function onDocumentLoad( event ) {
 	text = text.replace( /\[example:([\w\_]+)\]/gi, "[example:$1 $1]" ); // [example:name] to [example:name title]
 	text = text.replace( /\[example:([\w\_]+) ([\w\:\/\.\-\_ \s]+)\]/gi, "<a href=\"../examples/#$1\"  target=\"_blank\">$2</a>" ); // [example:name title]
 
-	text = text.replace( /<a class="param" onclick="window.parent.setUrlFragment\('\w+'\)">(null|Boolean|Object|Array|Number|String|Integer|Float|TypedArray|ArrayBuffer)<\/a>/gi, '<span class="param">$1</span>' ); // remove links to primitive types
+	text = text.replace( /<a class="param" onclick="window.parent.setUrlFragment\('\w+'\)">(null|this|Boolean|Object|Array|Number|String|Integer|Float|TypedArray|ArrayBuffer)<\/a>/gi, '<span class="param">$1</span>' ); // remove links to primitive types
 
 	document.body.innerHTML = text;
 

+ 11 - 27
docs/scenes/geometry-browser.html

@@ -72,36 +72,20 @@
 			scene.add( lights[ 1 ] );
 			scene.add( lights[ 2 ] );
 
-			var mesh = new THREE.Object3D();
+			var group = new THREE.Group();
 
-			mesh.add( new THREE.LineSegments(
+			var geometry = new THREE.BufferGeometry();
+			geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( [], 3 ) );
 
-				new THREE.Geometry(),
+			var lineMaterial = new THREE.LineBasicMaterial( { color: 0xffffff, transparent: true, opacity: 0.5 } );
+			var meshMaterial = new THREE.MeshPhongMaterial( { color: 0x156289, emissive: 0x072534, side: THREE.DoubleSide, flatShading: true } );
 
-				new THREE.LineBasicMaterial( {
-					color: 0xffffff,
-					transparent: true,
-					opacity: 0.5
-				} )
+			group.add( new THREE.LineSegments( geometry, lineMaterial ) );
+			group.add( new THREE.Mesh( geometry, meshMaterial ) );
 
-			) );
+			var options = chooseFromHash( group );
 
-			mesh.add( new THREE.Mesh(
-
-				new THREE.Geometry(),
-
-				new THREE.MeshPhongMaterial( {
-					color: 0x156289,
-					emissive: 0x072534,
-					side: THREE.DoubleSide,
-					flatShading: true
-				} )
-
-			) );
-
-			var options = chooseFromHash( mesh );
-
-			scene.add( mesh );
+			scene.add( group );
 
 			var prevFog = false;
 
@@ -111,8 +95,8 @@
 
 				if ( ! options.fixed ) {
 
-					mesh.rotation.x += 0.005;
-					mesh.rotation.y += 0.005;
+					group.rotation.x += 0.005;
+					group.rotation.y += 0.005;
 
 				}
 

+ 4 - 4
editor/index.html

@@ -6,10 +6,10 @@
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<!-- Origin Trial Token, feature = WebVR (For Chrome M62+), origin = https://threejs.org, expires = 2018-06-19 -->
 		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M62+)" data-expires="2018-06-19" content="Alxt96tYGgIr9l6EXU0eeI360zcmzOY6Kuo3kcTfBGIRDOQbgFIZKRQ1joExQ74WZr1einsE+cUMHgSclNHCQQ4AAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMU02MiIsImV4cGlyeSI6MTUyOTM5NzgyOH0=">
-		<!-- Origin Trial Token, feature = WebXR Device API, origin = https://threejs.org, expires = 2018-06-15 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Device API" data-expires="2018-06-15" content="AtJH9g6nn0B87bnjJt+9m1joZXEYDmLSlRvtMr5qJD52hMcm3S86S7jg5I7y2I5cgQglE0rzsXzti5DECQLb8QkAAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZSIsImV4cGlyeSI6MTUyOTA4NDY2OH0=">
-		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2018-06-15 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2018-06-15" content="Aihhr0yXkVlCKF0DIpTbH8WX7ZmEexUhI/95+t8aoLfvBkePMiZ/iOoDPU3xefyfuczkDahH1L6eiPvRsuzITAAAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTI5MDg0NjY4fQ==">
+		<!-- Origin Trial Token, feature = WebXR Device API, origin = https://threejs.org, expires = 2018-07-21 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Device API" data-expires="2018-07-21" content="Anlf1R/bCOUxOEgGI/9TWuzHHNxBMfZSTUMDCN7cLwDj2gpLwgA1K0DPwOzO/O0Jwaur5bsHo7k9KXx+6g+82wIAAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZSIsImV4cGlyeSI6MTUzMjE2NjIyNX0=">
+		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2018-07-21 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2018-07-21" content="ArDsXbwATKHPmvQiPlEIWNCt4DlEjB7bLj9vOgoNmL8r38U+wQNYZyUvjQIqqzgACciUUuAnxluTIL7nNkI89gcAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTMyMTY2MjI1fQ==">
 	</head>
 	<body ontouchstart="">
 		<link href="css/main.css" rel="stylesheet" />

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

@@ -190,7 +190,7 @@ var APP = {
 
 			dispatch( events.start, arguments );
 
-			renderer.animate( animate );
+			renderer.setAnimationLoop( animate );
 
 		};
 
@@ -207,7 +207,7 @@ var APP = {
 
 			dispatch( events.stop, arguments );
 
-			renderer.animate( null );
+			renderer.setAnimationLoop( null );
 
 		};
 

+ 2 - 2
examples/canvas_lines_colors.html

@@ -85,7 +85,7 @@
 					points = hilbert2D( new THREE.Vector3( 0, 0, 0 ), 400, 4 ),
 					colors2 = [];
 
-				for ( i = 0; i < points.length; i ++ ) {
+				for ( var i = 0; i < points.length; i ++ ) {
 
 					geometry2.vertices.push( points[ i ] );
 
@@ -102,7 +102,7 @@
 					points = hilbert3D( new THREE.Vector3( 0, 0, 0 ), 200, 2, 0, 1, 2, 3, 4, 5, 6, 7 ),
 					colors3 = [];
 
-				for ( i = 0; i < points.length; i ++ ) {
+				for ( var i = 0; i < points.length; i ++ ) {
 
 					geometry3.vertices.push( points[ i ] );
 

+ 150 - 0
examples/css2d_label.html

@@ -0,0 +1,150 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<title>three.js css2d - label</title>
+		<style>
+			body {
+				background-color: #000;
+				margin: 0;
+				overflow: hidden;
+			}
+			#info {
+				position: absolute;
+				top: 0px;
+				width: 100%;
+				color: #FFF;
+				padding: 5px;
+				font-family: Monospace;
+				font-size: 13px;
+				text-align: center;
+				z-index: 1;
+			}
+
+			.label{
+				color: #FFF;
+				font-family: sans-serif;
+				padding: 2px;
+				background: rgba( 0, 0, 0, .6 );
+			}
+
+			a {
+				color: #000000;
+			}
+
+		</style>
+	</head>
+	<body>
+		<div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - three.js css2d - label</div>
+
+		<script src="../build/three.js"></script>
+
+		<script src="js/controls/OrbitControls.js"></script>
+
+		<script src="js/renderers/CSS2DRenderer.js"></script>
+
+		<script>
+
+			var camera, scene, renderer, labelRenderer;
+			var controls;
+			var clock = new THREE.Clock();
+			var textureLoader = new THREE.TextureLoader();
+
+			var earth, moon;
+
+			init();
+			animate();
+
+			function init() {
+
+				var EARTH_RADIUS = 1;
+				var MOON_RADIUS = 0.27;
+
+				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
+				camera.position.set( 10, 5, 20 );
+
+				controls = new THREE.OrbitControls( camera );
+
+				scene = new THREE.Scene();
+
+				scene2 = new THREE.Scene();
+
+				var dirLight = new THREE.DirectionalLight( 0xffffff );
+				dirLight.position.set( 0, 0, 1 );
+				scene.add( dirLight );
+
+				var axesHelper = new THREE.AxesHelper( 5 );
+				scene.add( axesHelper );
+
+				//
+
+				var earthGeometry = new THREE.SphereBufferGeometry( EARTH_RADIUS, 16, 16 );
+				var earthMaterial = new THREE.MeshPhongMaterial( {
+					specular: 0x333333,
+					shininess: 5,
+					map: textureLoader.load( 'textures/planets/earth_atmos_2048.jpg' ),
+					specularMap: textureLoader.load( 'textures/planets/earth_specular_2048.jpg' ),
+					normalMap: textureLoader.load( 'textures/planets/earth_normal_2048.jpg' ),
+					normalScale: new THREE.Vector2( 0.85, 0.85 )
+				} );
+				earth = new THREE.Mesh( earthGeometry, earthMaterial );
+				scene.add( earth );
+
+				var moonGeometry = new THREE.SphereBufferGeometry( MOON_RADIUS, 16, 16 );
+				var moonMaterial = new THREE.MeshPhongMaterial( {
+					shininess: 5,
+					map: textureLoader.load( 'textures/planets/moon_1024.jpg' )
+				} );
+				moon = new THREE.Mesh( moonGeometry, moonMaterial );
+				scene.add( moon );
+
+				//
+
+				var earthDiv = document.createElement( 'div' );
+				earthDiv.className = 'label';
+				earthDiv.textContent = 'Earth';
+				earthDiv.style.marginTop = '-1em';
+				var earthLabel = new THREE.CSS2DObject( earthDiv );
+				earthLabel.position.set( 0, EARTH_RADIUS, 0 );
+				earth.add( earthLabel );
+
+				var moonDiv = document.createElement( 'div' );
+				moonDiv.className = 'label';
+				moonDiv.textContent = 'Moon';
+				moonDiv.style.marginTop = '-1em';
+				var moonLabel = new THREE.CSS2DObject( moonDiv );
+				moonLabel.position.set( 0, MOON_RADIUS, 0 );
+				moon.add( moonLabel );
+
+				//
+
+				renderer = new THREE.WebGLRenderer();
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				document.body.appendChild( renderer.domElement );
+
+				labelRenderer = new THREE.CSS2DRenderer();
+				labelRenderer.setSize( window.innerWidth, window.innerHeight );
+				labelRenderer.domElement.style.position = 'absolute';
+				labelRenderer.domElement.style.top = 0;
+				document.body.appendChild( labelRenderer.domElement );
+
+			}
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				var elapsed = clock.getElapsedTime();
+
+				moon.position.set( Math.sin( elapsed ) * 5, 0, Math.cos( elapsed ) * 5 );
+
+				renderer.render( scene, camera );
+				labelRenderer.render( scene, camera );
+
+			}
+
+		</script>
+	</body>
+</html>

+ 6 - 2
examples/files.js

@@ -22,7 +22,7 @@ var files = {
 		"webgl_geometries",
 		"webgl_geometries_parametric",
 		"webgl_geometry_colors",
-		"webgl_geometry_colors_blender",
+		"webgl_geometry_colors_json",
 		"webgl_geometry_colors_lookuptable",
 		"webgl_geometry_convex",
 		"webgl_geometry_cube",
@@ -93,7 +93,7 @@ var files = {
 		"webgl_loader_gltf",
 		"webgl_loader_gltf_extensions",
 		"webgl_loader_imagebitmap",
-		"webgl_loader_json_blender",
+		"webgl_loader_json",
 		"webgl_loader_json_claraio",
 		"webgl_loader_json_objconverter",
 		"webgl_loader_kmz",
@@ -342,6 +342,7 @@ var files = {
 		"misc_controls_transform",
 		"misc_exporter_gltf",
 		"misc_exporter_obj",
+		"misc_exporter_stl",
 		"misc_fps",
 		"misc_lights_test",
 		"misc_lookat",
@@ -359,6 +360,9 @@ var files = {
 		"css3d_sprites",
 		"css3d_youtube"
 	],
+	"css2d": [
+		"css2d_label"
+	],
 	"canvas": [
 		"canvas_ascii_effect",
 		"canvas_camera_orthographic",

+ 2 - 7
examples/js/BufferGeometryUtils.js

@@ -236,13 +236,8 @@ THREE.BufferGeometryUtils = {
 
 			// gather .userData
 
-			if ( geometry.userData !== undefined ) {
-
-				mergedGeometry.userData = mergedGeometry.userData || {};
-				mergedGeometry.userData.mergedUserData = mergedGeometry.userData.mergedUserData || [];
-				mergedGeometry.userData.mergedUserData.push( geometry.userData );
-
-			}
+			mergedGeometry.userData.mergedUserData = mergedGeometry.userData.mergedUserData || [];
+			mergedGeometry.userData.mergedUserData.push( geometry.userData );
 
 			if ( useGroups ) {
 

+ 14 - 10
examples/js/Cloth.js

@@ -46,15 +46,13 @@ var lastTime;
 
 function plane( width, height ) {
 
-	return function ( u, v, optionalTarget ) {
-
-		var result = optionalTarget || new THREE.Vector3();
+	return function ( u, v, target ) {
 
 		var x = ( u - 0.5 ) * width;
 		var y = ( v + 0.5 ) * height;
 		var z = 0;
 
-		return result.set( x, y, z );
+		target.set( x, y, z );
 
 	};
 
@@ -62,20 +60,26 @@ function plane( width, height ) {
 
 function Particle( x, y, z, mass ) {
 
-	this.position = clothFunction( x, y ); // position
-	this.previous = clothFunction( x, y ); // previous
-	this.original = clothFunction( x, y );
+	this.position = new THREE.Vector3();
+	this.previous = new THREE.Vector3();
+	this.original = new THREE.Vector3();
 	this.a = new THREE.Vector3( 0, 0, 0 ); // acceleration
 	this.mass = mass;
 	this.invMass = 1 / mass;
 	this.tmp = new THREE.Vector3();
 	this.tmp2 = new THREE.Vector3();
 
+	// init
+
+	clothFunction( x, y, this.position ); // position
+	clothFunction( x, y, this.previous ); // previous
+	clothFunction( x, y, this.original );
+
 }
 
 // Force -> Acceleration
 
-Particle.prototype.addForce = function( force ) {
+Particle.prototype.addForce = function ( force ) {
 
 	this.a.add(
 		this.tmp2.copy( force ).multiplyScalar( this.invMass )
@@ -86,7 +90,7 @@ Particle.prototype.addForce = function( force ) {
 
 // Performs Verlet integration
 
-Particle.prototype.integrate = function( timesq ) {
+Particle.prototype.integrate = function ( timesq ) {
 
 	var newPos = this.tmp.subVectors( this.position, this.previous );
 	newPos.multiplyScalar( DRAG ).add( this.position );
@@ -280,7 +284,7 @@ function simulate( time ) {
 
 	// Ball Constraints
 
-	ballPosition.z = - Math.sin( Date.now() / 600 ) * 90 ; //+ 40;
+	ballPosition.z = - Math.sin( Date.now() / 600 ) * 90; //+ 40;
 	ballPosition.x = Math.cos( Date.now() / 400 ) * 70;
 
 	if ( sphere.visible ) {

+ 77 - 67
examples/js/ConvexObjectBreaker.js

@@ -25,10 +25,10 @@
  *
  * @param {double} minSizeForBreak Min size a debris can have to break.
  * @param {double} smallDelta Max distance to consider that a point belongs to a plane.
- * 
+ *
   */
 
-THREE.ConvexObjectBreaker = function( minSizeForBreak, smallDelta ) {
+THREE.ConvexObjectBreaker = function ( minSizeForBreak, smallDelta ) {
 
 	this.minSizeForBreak = minSizeForBreak || 1.4;
 	this.smallDelta = smallDelta || 0.0001;
@@ -45,9 +45,7 @@ THREE.ConvexObjectBreaker = function( minSizeForBreak, smallDelta ) {
 
 	this.segments = [];
 	var n = 30 * 30;
-	for ( var i = 0; i < n; i++ ) {
-		this.segments[ i ] = false;
-	}
+	for ( var i = 0; i < n; i ++ ) this.segments[ i ] = false;
 
 };
 
@@ -55,7 +53,7 @@ THREE.ConvexObjectBreaker.prototype = {
 
 	constructor: THREE.ConvexObjectBreaker,
 
-	prepareBreakableObject: function( object, mass, velocity, angularVelocity, breakable ) {
+	prepareBreakableObject: function ( object, mass, velocity, angularVelocity, breakable ) {
 
 		// object is a THREE.Object3d (normally a Mesh), must have a Geometry, and it must be convex.
 		// Its material property is propagated to its children (sub-pieces)
@@ -63,9 +61,7 @@ THREE.ConvexObjectBreaker.prototype = {
 
 		// Create vertices mark
 		var vertices = object.geometry.vertices;
-		for ( var i = 0, il = vertices.length; i < il; i++ ) {
-			vertices[ i ].mark = 0;
-		}
+		for ( var i = 0, il = vertices.length; i < il; i ++ ) vertices[ i ].mark = 0;
 
 		var userData = object.userData;
 		userData.mass = mass;
@@ -78,11 +74,10 @@ THREE.ConvexObjectBreaker.prototype = {
 	/*
 	 * @param {int} maxRadialIterations Iterations for radial cuts.
 	 * @param {int} maxRandomIterations Max random iterations for not-radial cuts
-	 * @param {double} minSizeForRadialSubdivision Min size a debris can have to break in radial subdivision.
 	 *
 	 * Returns the array of pieces
 	 */
-	subdivideByImpact: function( object, pointOfImpact, normal, maxRadialIterations, maxRandomIterations, minSizeForRadialSubdivision ) {
+	subdivideByImpact: function ( object, pointOfImpact, normal, maxRadialIterations, maxRandomIterations ) {
 
 		var debris = [];
 
@@ -103,9 +98,9 @@ THREE.ConvexObjectBreaker.prototype = {
 				debris.push( subObject );
 
 				return;
-				
+
 			}
-			
+
 			var angle = Math.PI;
 
 			if ( numIterations === 0 ) {
@@ -113,19 +108,17 @@ THREE.ConvexObjectBreaker.prototype = {
 				tempPlane2.normal.copy( tempPlane1.normal );
 				tempPlane2.constant = tempPlane1.constant;
 
-			}
-			else {
+			} else {
 
 				if ( numIterations <= maxRadialIterations ) {
-					
+
 					angle = ( endAngle - startAngle ) * ( 0.2 + 0.6 * Math.random() ) + startAngle;
 
 					// Rotate tempPlane2 at impact point around normal axis and the angle
 					scope.tempVector3_2.copy( object.position ).sub( pointOfImpact ).applyAxisAngle( normal, angle ).add( pointOfImpact );
 					tempPlane2.setFromCoplanarPoints( pointOfImpact, scope.tempVector3, scope.tempVector3_2 );
 
-				}
-				else {
+				} else {
 
 					angle = ( ( 0.5 * ( numIterations & 1 ) ) + 0.2 * ( 2 - Math.random() ) ) * Math.PI;
 
@@ -164,7 +157,7 @@ THREE.ConvexObjectBreaker.prototype = {
 
 	},
 
-	cutByPlane: function( object, plane, output ) {
+	cutByPlane: function ( object, plane, output ) {
 
 		// Returns breakable objects in output.object1 and output.object2 members, the resulting 2 pieces of the cut.
 		// object2 can be null if the plane doesn't cut the object.
@@ -183,22 +176,18 @@ THREE.ConvexObjectBreaker.prototype = {
 		var delta = this.smallDelta;
 
 		// Reset vertices mark
-		for ( var i = 0; i < numPoints; i++ ) {
-			points[ i ].mark = 0;
-		}
+		for ( var i = 0; i < numPoints; i ++ ) points[ i ].mark = 0;
 
 		// Reset segments mark
 		var numPointPairs = numPoints * numPoints;
-		for ( var i = 0; i < numPointPairs; i++ ) {
-			this.segments[ i ] = false;
-		}
+		for ( var i = 0; i < numPointPairs; i ++ ) this.segments[ i ] = false;
 
 		// Iterate through the faces to mark edges shared by coplanar faces
-		for ( var i = 0, il = faces.length - 1; i < il; i++ ) {
+		for ( var i = 0, il = faces.length - 1; i < il; i ++ ) {
 
 			var face1 = faces[ i ];
 
-			for ( var j = i + 1, jl = faces.length; j < jl; j++ ) {
+			for ( var j = i + 1, jl = faces.length; j < jl; j ++ ) {
 
 				var face2 = faces[ j ];
 
@@ -215,18 +204,24 @@ THREE.ConvexObjectBreaker.prototype = {
 
 
 					if ( a1 === a2 || a1 === b2 || a1 === c2 ) {
+
 						if ( b1 === a2 || b1 === b2 || b1 === c2 ) {
+
 							this.segments[ a1 * numPoints + b1 ] = true;
 							this.segments[ b1 * numPoints + a1 ] = true;
-						}
-						else {
+
+						}	else {
+
 							this.segments[ c1 * numPoints + a1 ] = true;
 							this.segments[ a1 * numPoints + c1 ] = true;
+
 						}
-					}
-					else if ( b1 === a2 || b1 === b2 || b1 === c2 ) {
+
+					}	else if ( b1 === a2 || b1 === b2 || b1 === c2 ) {
+
 						this.segments[ c1 * numPoints + b1 ] = true;
 						this.segments[ b1 * numPoints + c1 ] = true;
+
 					}
 
 				}
@@ -245,17 +240,14 @@ THREE.ConvexObjectBreaker.prototype = {
 
 			var face = faces[ i ];
 
-			for ( var segment = 0; segment < 3; segment++ ) {
+			for ( var segment = 0; segment < 3; segment ++ ) {
 
 				var i0 = segment === 0 ? face.a : ( segment === 1 ? face.b : face.c );
 				var i1 = segment === 0 ? face.b : ( segment === 1 ? face.c : face.a );
 
 				var segmentState = this.segments[ i0 * numPoints + i1 ];
 
-				if ( segmentState ) {
-					// The segment already has been processed in another face
-					continue;
-				}
+				if ( segmentState ) continue; // The segment already has been processed in another face
 
 				// Mark segment as processed (also inverted segment)
 				this.segments[ i0 * numPoints + i1 ] = true;
@@ -270,19 +262,23 @@ THREE.ConvexObjectBreaker.prototype = {
 
 					// mark: 1 for negative side, 2 for positive side, 3 for coplanar point
 					if ( d > delta ) {
+
 						p0.mark = 2;
 						points2.push( p0 );
-					}
-					else if ( d < - delta ) {
+
+					} else if ( d < - delta ) {
+
 						p0.mark = 1;
 						points1.push( p0 );
-					}
-					else {
+
+					} else {
+
 						p0.mark = 3;
 						points1.push( p0 );
 						var p0_2 = p0.clone();
 						p0_2.mark = 3;
 						points2.push( p0_2 );
+
 					}
 
 				}
@@ -293,19 +289,23 @@ THREE.ConvexObjectBreaker.prototype = {
 
 					// mark: 1 for negative side, 2 for positive side, 3 for coplanar point
 					if ( d > delta ) {
+
 						p1.mark = 2;
 						points2.push( p1 );
-					}
-					else if ( d < - delta ) {
+
+					} else if ( d < - delta ) {
+
 						p1.mark = 1;
 						points1.push( p1 );
-					}
-					else {
+
+					}	else {
+
 						p1.mark = 3;
 						points1.push( p1 );
 						var p1_2 = p1.clone();
 						p1_2.mark = 3;
 						points2.push( p1_2 );
+
 					}
 
 				}
@@ -319,13 +319,18 @@ THREE.ConvexObjectBreaker.prototype = {
 
 					this.tempLine1.start.copy( p0 );
 					this.tempLine1.end.copy( p1 );
-					var intersection = localPlane.intersectLine( this.tempLine1 );
+
+					var intersection = new THREE.Vector3();
+					intersection = localPlane.intersectLine( this.tempLine1, intersection );
+
 					if ( intersection === undefined ) {
+
 						// Shouldn't happen
 						console.error( "Internal error: segment does not intersect plane." );
 						output.segmentedObject1 = null;
 						output.segmentedObject2 = null;
 						return 0;
+
 					}
 
 					intersection.mark = 1;
@@ -347,33 +352,40 @@ THREE.ConvexObjectBreaker.prototype = {
 		this.tempCM1.set( 0, 0, 0 );
 		var radius1 = 0;
 		var numPoints1 = points1.length;
+
 		if ( numPoints1 > 0 ) {
-			for ( var i = 0; i < numPoints1; i++ ) {
-				this.tempCM1.add( points1[ i ] );
-			}
+
+			for ( var i = 0; i < numPoints1; i ++ ) this.tempCM1.add( points1[ i ] );
+
 			this.tempCM1.divideScalar( numPoints1 );
-			for ( var i = 0; i < numPoints1; i++ ) {
+			for ( var i = 0; i < numPoints1; i ++ ) {
+
 				var p = points1[ i ];
 				p.sub( this.tempCM1 );
 				radius1 = Math.max( radius1, p.x, p.y, p.z );
+
 			}
 			this.tempCM1.add( object.position );
+
 		}
 
 		this.tempCM2.set( 0, 0, 0 );
 		var radius2 = 0;
 		var numPoints2 = points2.length;
 		if ( numPoints2 > 0 ) {
-			for ( var i = 0; i < numPoints2; i++ ) {
-				this.tempCM2.add( points2[ i ] );
-			}
+
+			for ( var i = 0; i < numPoints2; i ++ ) this.tempCM2.add( points2[ i ] );
+
 			this.tempCM2.divideScalar( numPoints2 );
-			for ( var i = 0; i < numPoints2; i++ ) {
+			for ( var i = 0; i < numPoints2; i ++ ) {
+
 				var p = points2[ i ];
 				p.sub( this.tempCM2 );
 				radius2 = Math.max( radius2, p.x, p.y, p.z );
+
 			}
 			this.tempCM2.add( object.position );
+
 		}
 
 		var object1 = null;
@@ -389,7 +401,7 @@ THREE.ConvexObjectBreaker.prototype = {
 
 			this.prepareBreakableObject( object1, newMass, object.userData.velocity, object.userData.angularVelocity, 2 * radius1 > this.minSizeForBreak );
 
-			numObjects++;
+			numObjects ++;
 
 		}
 
@@ -401,11 +413,10 @@ THREE.ConvexObjectBreaker.prototype = {
 
 			this.prepareBreakableObject( object2, newMass, object.userData.velocity, object.userData.angularVelocity, 2 * radius2 > this.minSizeForBreak );
 
-			numObjects++;
+			numObjects ++;
 
 		}
 
-
 		output.object1 = object1;
 		output.object2 = object2;
 
@@ -415,7 +426,7 @@ THREE.ConvexObjectBreaker.prototype = {
 
 };
 
-THREE.ConvexObjectBreaker.transformFreeVector = function( v, m ) {
+THREE.ConvexObjectBreaker.transformFreeVector = function ( v, m ) {
 
 	// input:
 	// vector interpreted as a free vector
@@ -424,15 +435,15 @@ THREE.ConvexObjectBreaker.transformFreeVector = function( v, m ) {
 	var x = v.x, y = v.y, z = v.z;
 	var e = m.elements;
 
-	v.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ]  * z;
-	v.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ]  * z;
+	v.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;
+	v.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;
 	v.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;
 
 	return v;
 
 };
 
-THREE.ConvexObjectBreaker.transformFreeVectorInverse = function( v, m ) {
+THREE.ConvexObjectBreaker.transformFreeVectorInverse = function ( v, m ) {
 
 	// input:
 	// vector interpreted as a free vector
@@ -441,15 +452,15 @@ THREE.ConvexObjectBreaker.transformFreeVectorInverse = function( v, m ) {
 	var x = v.x, y = v.y, z = v.z;
 	var e = m.elements;
 
-	v.x = e[ 0 ] * x + e[ 1 ] * y + e[ 2 ]  * z;
-	v.y = e[ 4 ] * x + e[ 5 ] * y + e[ 6 ]  * z;
+	v.x = e[ 0 ] * x + e[ 1 ] * y + e[ 2 ] * z;
+	v.y = e[ 4 ] * x + e[ 5 ] * y + e[ 6 ] * z;
 	v.z = e[ 8 ] * x + e[ 9 ] * y + e[ 10 ] * z;
 
 	return v;
 
 };
 
-THREE.ConvexObjectBreaker.transformTiedVectorInverse = function( v, m ) {
+THREE.ConvexObjectBreaker.transformTiedVectorInverse = function ( v, m ) {
 
 	// input:
 	// vector interpreted as a tied (ordinary) vector
@@ -458,18 +469,17 @@ THREE.ConvexObjectBreaker.transformTiedVectorInverse = function( v, m ) {
 	var x = v.x, y = v.y, z = v.z;
 	var e = m.elements;
 
-	v.x = e[ 0 ] * x + e[ 1 ] * y + e[ 2 ]  * z - e[ 12 ];
-	v.y = e[ 4 ] * x + e[ 5 ] * y + e[ 6 ]  * z - e[ 13 ];
+	v.x = e[ 0 ] * x + e[ 1 ] * y + e[ 2 ] * z - e[ 12 ];
+	v.y = e[ 4 ] * x + e[ 5 ] * y + e[ 6 ] * z - e[ 13 ];
 	v.z = e[ 8 ] * x + e[ 9 ] * y + e[ 10 ] * z - e[ 14 ];
 
 	return v;
 
 };
 
-THREE.ConvexObjectBreaker.transformPlaneToLocalSpace = function() {
+THREE.ConvexObjectBreaker.transformPlaneToLocalSpace = function () {
 
 	var v1 = new THREE.Vector3();
-	var m1 = new THREE.Matrix3();
 
 	return function transformPlaneToLocalSpace( plane, m, resultPlane ) {
 

+ 9 - 8
examples/js/MorphBlendMesh.js

@@ -12,9 +12,9 @@ THREE.MorphBlendMesh = function ( geometry, material ) {
 	// prepare default animation
 	// (all frames played together in 1 second)
 
-	var numFrames = this.geometry.morphTargets.length;
+	var numFrames = Object.keys( this.morphTargetDictionary ).length;
 
-	var name = "__default";
+	var name = '__default';
 
 	var startFrame = 0;
 	var endFrame = numFrames - 1;
@@ -24,7 +24,7 @@ THREE.MorphBlendMesh = function ( geometry, material ) {
 	this.createAnimation( name, startFrame, endFrame, fps );
 	this.setAnimationWeight( name, 1 );
 
-}
+};
 
 THREE.MorphBlendMesh.prototype = Object.assign( Object.create( THREE.Mesh.prototype ), {
 
@@ -61,18 +61,17 @@ THREE.MorphBlendMesh.prototype = Object.assign( Object.create( THREE.Mesh.protot
 
 	},
 
-		autoCreateAnimations: function ( fps ) {
+	autoCreateAnimations: function ( fps ) {
 
 		var pattern = /([a-z]+)_?(\d+)/i;
 
 		var firstAnimation, frameRanges = {};
 
-		var geometry = this.geometry;
+		var i = 0;
 
-		for ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {
+		for ( var key in this.morphTargetDictionary ) {
 
-			var morph = geometry.morphTargets[ i ];
-			var chunks = morph.name.match( pattern );
+			var chunks = key.match( pattern );
 
 			if ( chunks && chunks.length > 1 ) {
 
@@ -89,6 +88,8 @@ THREE.MorphBlendMesh.prototype = Object.assign( Object.create( THREE.Mesh.protot
 
 			}
 
+			i ++;
+
 		}
 
 		for ( var name in frameRanges ) {

+ 14 - 28
examples/js/ParametricGeometries.js

@@ -7,9 +7,7 @@
 
 THREE.ParametricGeometries = {
 
-	klein: function ( v, u, optionalTarget ) {
-
-		var result = optionalTarget || new THREE.Vector3();
+	klein: function ( v, u, target ) {
 
 		u *= Math.PI;
 		v *= 2 * Math.PI;
@@ -30,29 +28,25 @@ THREE.ParametricGeometries = {
 
 		y = - 2 * ( 1 - Math.cos( u ) / 2 ) * Math.sin( v );
 
-		return result.set( x, y, z );
+		target.set( x, y, z );
 
 	},
 
 	plane: function ( width, height ) {
 
-		return function ( u, v, optionalTarget ) {
-
-			var result = optionalTarget || new THREE.Vector3();
+		return function ( u, v, target ) {
 
 			var x = u * width;
 			var y = 0;
 			var z = v * height;
 
-			return result.set( x, y, z );
+			target.set( x, y, z );
 
 		};
 
 	},
 
-	mobius: function ( u, t, optionalTarget ) {
-
-		var result = optionalTarget || new THREE.Vector3();
+	mobius: function ( u, t, target ) {
 
 		// flat mobius strip
 		// http://www.wolframalpha.com/input/?i=M%C3%B6bius+strip+parametric+equations&lk=1&a=ClashPrefs_*Surface.MoebiusStrip.SurfaceProperty.ParametricEquations-
@@ -67,13 +61,11 @@ THREE.ParametricGeometries = {
 		y = Math.sin( v ) * ( a + u * Math.cos( v / 2 ) );
 		z = u * Math.sin( v / 2 );
 
-		return result.set( x, y, z );
+		target.set( x, y, z );
 
 	},
 
-	mobius3d: function ( u, t, optionalTarget ) {
-
-		var result = optionalTarget || new THREE.Vector3();
+	mobius3d: function ( u, t, target ) {
 
 		// volumetric mobius strip
 
@@ -91,7 +83,7 @@ THREE.ParametricGeometries = {
 		y = ( major + x ) * Math.sin( u );
 		x = ( major + x ) * Math.cos( u );
 
-		return result.set( x, y, z );
+		target.set( x, y, z );
 
 	}
 
@@ -126,9 +118,7 @@ THREE.ParametricGeometries.TubeGeometry = function ( path, segments, radius, seg
 	this.normals = normals;
 	this.binormals = binormals;
 
-	var ParametricTube = function ( u, v, optionalTarget ) {
-
-		var result = optionalTarget || new THREE.Vector3();
+	var ParametricTube = function ( u, v, target ) {
 
 		v *= 2 * Math.PI;
 
@@ -156,7 +146,7 @@ THREE.ParametricGeometries.TubeGeometry = function ( path, segments, radius, seg
 		pos.y += cx * normal.y + cy * binormal.y;
 		pos.z += cx * normal.z + cy * binormal.z;
 
-		return result.copy( pos );
+		target.copy( pos );
 
 	};
 
@@ -226,9 +216,7 @@ THREE.ParametricGeometries.TorusKnotGeometry.prototype.constructor = THREE.Param
   *********************************************/
 THREE.ParametricGeometries.SphereGeometry = function ( size, u, v ) {
 
-	function sphere( u, v, optionalTarget ) {
-
-		var result = optionalTarget || new THREE.Vector3();
+	function sphere( u, v, target ) {
 
 		u *= Math.PI;
 		v *= 2 * Math.PI;
@@ -237,7 +225,7 @@ THREE.ParametricGeometries.SphereGeometry = function ( size, u, v ) {
 		var y = size * Math.sin( u ) * Math.sin( v );
 		var z = size * Math.cos( u );
 
-		return result.set( x, y, z );
+		target.set( x, y, z );
 
 	}
 
@@ -257,15 +245,13 @@ THREE.ParametricGeometries.SphereGeometry.prototype.constructor = THREE.Parametr
 
 THREE.ParametricGeometries.PlaneGeometry = function ( width, depth, segmentsWidth, segmentsDepth ) {
 
-	function plane( u, v, optionalTarget ) {
-
-		var result = optionalTarget || new THREE.Vector3();
+	function plane( u, v, target ) {
 
 		var x = u * width;
 		var y = 0;
 		var z = v * depth;
 
-		return result.set( x, y, z );
+		target.set( x, y, z );
 
 	}
 

+ 1 - 1
examples/js/animation/CCDIKSolver.js

@@ -203,7 +203,7 @@ THREE.CCDIKSolver = ( function () {
 		 */
 		createHelper: function () {
 
-			return new CCDIKHelper( this.mesh, this.mesh.geometry.iks );
+			return new CCDIKHelper( this.mesh, this.mesh.geometry.userData.MMD.iks );
 
 		},
 

+ 8 - 5
examples/js/animation/MMDAnimationHelper.js

@@ -275,7 +275,7 @@ THREE.MMDAnimationHelper = ( function () {
 		 */
 		createGrantSolver: function ( mesh ) {
 
-			return new GrantSolver( mesh, mesh.geometry.grants );
+			return new GrantSolver( mesh, mesh.geometry.userData.MMD.grants );
 
 		},
 
@@ -581,8 +581,8 @@ THREE.MMDAnimationHelper = ( function () {
 
 		_optimizeIK: function ( mesh, physicsEnabled ) {
 
-			var iks = mesh.geometry.iks;
-			var bones = mesh.geometry.bones;
+			var iks = mesh.geometry.userData.MMD.iks;
+			var bones = mesh.geometry.userData.MMD.bones;
 
 			for ( var i = 0, il = iks.length; i < il; i ++ ) {
 
@@ -619,7 +619,7 @@ THREE.MMDAnimationHelper = ( function () {
 
 			}
 
-			return new THREE.CCDIKSolver( mesh, mesh.geometry.iks );
+			return new THREE.CCDIKSolver( mesh, mesh.geometry.userData.MMD.iks );
 
 		},
 
@@ -632,7 +632,10 @@ THREE.MMDAnimationHelper = ( function () {
 			}
 
 			return new THREE.MMDPhysics(
-				mesh, mesh.geometry.rigidBodies, mesh.geometry.constraints, params );
+				mesh,
+				mesh.geometry.userData.MMD.rigidBodies,
+				mesh.geometry.userData.MMD.constraints,
+				params );
 
 		},
 

+ 14 - 6
examples/js/cameras/CinematicCamera.js

@@ -5,20 +5,28 @@
  * @author kaypiKun
  */
 
-THREE.CinematicCamera = function( fov, aspect, near, far ) {
+THREE.CinematicCamera = function ( fov, aspect, near, far ) {
 
 	THREE.PerspectiveCamera.call( this, fov, aspect, near, far );
 
-	this.type = "CinematicCamera";
+	this.type = 'CinematicCamera';
 
-	this.postprocessing = { enabled	: true };
+	this.postprocessing = { enabled: true };
 	this.shaderSettings = {
 		rings: 3,
 		samples: 4
 	};
 
-	this.material_depth = new THREE.MeshDepthMaterial();
-	this.material_depth.depthPacking = THREE.RGBADepthPacking;
+	var depthShader = THREE.BokehDepthShader;
+
+	this.materialDepth = new THREE.ShaderMaterial( {
+		uniforms: depthShader.uniforms,
+		vertexShader: depthShader.vertexShader,
+		fragmentShader: depthShader.fragmentShader
+	} );
+
+	this.materialDepth.uniforms[ 'mNear' ].value = near;
+	this.materialDepth.uniforms[ 'mFar' ].value = far;
 
 	// In case of cinematicCamera, having a default lens set is important
 	this.setLens();
@@ -178,7 +186,7 @@ THREE.CinematicCamera.prototype.renderCinematic = function ( scene, renderer ) {
 
 		// Render depth into texture
 
-		scene.overrideMaterial = this.material_depth;
+		scene.overrideMaterial = this.materialDepth;
 		renderer.render( scene, camera, this.postprocessing.rtTextureDepth, true );
 
 		// Render bokeh composite

+ 0 - 149
examples/js/controls/VRControls.js

@@ -1,149 +0,0 @@
-/**
- * @author dmarcos / https://github.com/dmarcos
- * @author mrdoob / http://mrdoob.com
- */
-
-THREE.VRControls = function ( object, onError ) {
-
-	var scope = this;
-
-	var vrDisplay, vrDisplays;
-
-	var standingMatrix = new THREE.Matrix4();
-
-	var frameData = null;
-
-	if ( 'VRFrameData' in window ) {
-
-		frameData = new VRFrameData();
-
-	}
-
-	function gotVRDisplays( displays ) {
-
-		vrDisplays = displays;
-
-		if ( displays.length > 0 ) {
-
-			vrDisplay = displays[ 0 ];
-
-		} else {
-
-			if ( onError ) onError( 'VR input not available.' );
-
-		}
-
-	}
-
-	if ( navigator.getVRDisplays ) {
-
-		navigator.getVRDisplays().then( gotVRDisplays ).catch( function () {
-
-			console.warn( 'THREE.VRControls: Unable to get VR Displays' );
-
-		} );
-
-	}
-
-	// the Rift SDK returns the position in meters
-	// this scale factor allows the user to define how meters
-	// are converted to scene units.
-
-	this.scale = 1;
-
-	// If true will use "standing space" coordinate system where y=0 is the
-	// floor and x=0, z=0 is the center of the room.
-	this.standing = false;
-
-	// Distance from the users eyes to the floor in meters. Used when
-	// standing=true but the VRDisplay doesn't provide stageParameters.
-	this.userHeight = 1.6;
-
-	this.getVRDisplay = function () {
-
-		return vrDisplay;
-
-	};
-
-	this.setVRDisplay = function ( value ) {
-
-		vrDisplay = value;
-
-	};
-
-	this.getVRDisplays = function () {
-
-		console.warn( 'THREE.VRControls: getVRDisplays() is being deprecated.' );
-		return vrDisplays;
-
-	};
-
-	this.getStandingMatrix = function () {
-
-		return standingMatrix;
-
-	};
-
-	this.update = function () {
-
-		if ( vrDisplay ) {
-
-			var pose;
-
-			if ( vrDisplay.getFrameData ) {
-
-				vrDisplay.getFrameData( frameData );
-				pose = frameData.pose;
-
-			} else if ( vrDisplay.getPose ) {
-
-				pose = vrDisplay.getPose();
-
-			}
-
-			if ( pose.orientation !== null ) {
-
-				object.quaternion.fromArray( pose.orientation );
-
-			}
-
-			if ( pose.position !== null ) {
-
-				object.position.fromArray( pose.position );
-
-			} else {
-
-				object.position.set( 0, 0, 0 );
-
-			}
-
-			if ( this.standing ) {
-
-				if ( vrDisplay.stageParameters ) {
-
-					object.updateMatrix();
-
-					standingMatrix.fromArray( vrDisplay.stageParameters.sittingToStandingTransform );
-					object.applyMatrix( standingMatrix );
-
-				} else {
-
-					object.position.setY( object.position.y + this.userHeight );
-
-				}
-
-			}
-
-			object.position.multiplyScalar( scope.scale );
-
-		}
-
-	};
-
-	this.dispose = function () {
-
-		vrDisplay = null;
-
-	};
-
-};

+ 2 - 4
examples/js/curves/NURBSSurface.js

@@ -42,14 +42,12 @@ THREE.NURBSSurface.prototype = {
 
 	constructor: THREE.NURBSSurface,
 
-	getPoint: function ( t1, t2 ) {
+	getPoint: function ( t1, t2, target ) {
 
 		var u = this.knots1[ 0 ] + t1 * ( this.knots1[ this.knots1.length - 1 ] - this.knots1[ 0 ] ); // linear mapping t1->u
 		var v = this.knots2[ 0 ] + t2 * ( this.knots2[ this.knots2.length - 1 ] - this.knots2[ 0 ] ); // linear mapping t2->u
 
-		return THREE.NURBSUtils.calcSurfacePoint( this.degree1, this.degree2, this.knots1, this.knots2, this.controlPoints, u, v );
+		THREE.NURBSUtils.calcSurfacePoint( this.degree1, this.degree2, this.knots1, this.knots2, this.controlPoints, u, v, target );
 
 	}
 };
-
-

+ 11 - 14
examples/js/curves/NURBSUtils.js

@@ -19,7 +19,7 @@ THREE.NURBSUtils = {
 	p : degree
 	u : parametric value
 	U : knot vector
-	
+
 	returns the span
 	*/
 	findSpan: function( p,  u,  U ) {
@@ -43,7 +43,7 @@ THREE.NURBSUtils = {
 		var mid = Math.floor( ( low + high ) / 2 );
 
 		while ( u < U[ mid ] || u >= U[ mid + 1 ] ) {
-		  
+
 			if ( u < U[ mid ] ) {
 
 				high = mid;
@@ -61,16 +61,16 @@ THREE.NURBSUtils = {
 		return mid;
 
 	},
-    
-		
+
+
 	/*
 	Calculate basis functions. See The NURBS Book, page 70, algorithm A2.2
-   
+
 	span : span in which u lies
 	u    : parametric point
 	p    : degree
 	U    : knot vector
-	
+
 	returns array[p+1] with basis functions values.
 	*/
 	calcBasisFunctions: function( span, u, p, U ) {
@@ -81,7 +81,7 @@ THREE.NURBSUtils = {
 		N[ 0 ] = 1.0;
 
 		for ( var j = 1; j <= p; ++ j ) {
-	   
+
 			left[ j ] = u - U[ span + 1 - j ];
 			right[ j ] = U[ span + j ] - u;
 
@@ -108,7 +108,7 @@ THREE.NURBSUtils = {
 
 	/*
 	Calculate B-Spline curve points. See The NURBS Book, page 82, algorithm A3.1.
- 
+
 	p : degree of B-Spline
 	U : knot vector
 	P : control points (x, y, z, w)
@@ -422,7 +422,7 @@ THREE.NURBSUtils = {
 
 	/*
 	Calculate rational B-Spline surface point. See The NURBS Book, page 134, algorithm A4.3.
- 
+
 	p1, p2 : degrees of B-Spline surface
 	U1, U2 : knot vectors
 	P      : control points (x, y, z, w)
@@ -430,7 +430,7 @@ THREE.NURBSUtils = {
 
 	returns point for given (u, v)
 	*/
-	calcSurfacePoint: function( p, q, U, V, P, u, v ) {
+	calcSurfacePoint: function ( p, q, U, V, P, u, v, target ) {
 
 		var uspan = this.findSpan( p, u, U );
 		var vspan = this.findSpan( q, v, V );
@@ -462,11 +462,8 @@ THREE.NURBSUtils = {
 		}
 
 		Sw.divideScalar( Sw.w );
-		return new THREE.Vector3( Sw.x, Sw.y, Sw.z );
+		target.set( Sw.x, Sw.y, Sw.z );
 
 	}
 
 };
-
-
-

+ 1 - 1
examples/js/effects/OutlineEffect.js

@@ -448,7 +448,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 	 * The following property copies and wrapper methods enable
 	 * THREE.OutlineEffect to be called from other *Effect, like
 	 *
-	 * effect = new THREE.VREffect( new THREE.OutlineEffect( renderer ) );
+	 * effect = new THREE.StereoEffect( new THREE.OutlineEffect( renderer ) );
 	 *
 	 * function render () {
 	 *

+ 0 - 533
examples/js/effects/VREffect.js

@@ -1,533 +0,0 @@
-/**
- * @author dmarcos / https://github.com/dmarcos
- * @author mrdoob / http://mrdoob.com
- *
- * WebVR Spec: http://mozvr.github.io/webvr-spec/webvr.html
- *
- * Firefox: http://mozvr.com/downloads/
- * Chromium: https://webvr.info/get-chrome
- */
-
-THREE.VREffect = function ( renderer, onError ) {
-
-	var vrDisplay, vrDisplays;
-	var eyeTranslationL = new THREE.Vector3();
-	var eyeTranslationR = new THREE.Vector3();
-	var renderRectL, renderRectR;
-	var headMatrix = new THREE.Matrix4();
-	var eyeMatrixL = new THREE.Matrix4();
-	var eyeMatrixR = new THREE.Matrix4();
-
-	var frameData = null;
-
-	if ( 'VRFrameData' in window ) {
-
-		frameData = new window.VRFrameData();
-
-	}
-
-	function gotVRDisplays( displays ) {
-
-		vrDisplays = displays;
-
-		if ( displays.length > 0 ) {
-
-			vrDisplay = displays[ 0 ];
-
-		} else {
-
-			if ( onError ) onError( 'HMD not available' );
-
-		}
-
-	}
-
-	if ( navigator.getVRDisplays ) {
-
-		navigator.getVRDisplays().then( gotVRDisplays ).catch( function () {
-
-			console.warn( 'THREE.VREffect: Unable to get VR Displays' );
-
-		} );
-
-	}
-
-	//
-
-	this.isPresenting = false;
-
-	var scope = this;
-
-	var rendererSize = renderer.getSize();
-	var rendererUpdateStyle = false;
-	var rendererPixelRatio = renderer.getPixelRatio();
-
-	this.getVRDisplay = function () {
-
-		return vrDisplay;
-
-	};
-
-	this.setVRDisplay = function ( value ) {
-
-		vrDisplay = value;
-
-	};
-
-	this.getVRDisplays = function () {
-
-		console.warn( 'THREE.VREffect: getVRDisplays() is being deprecated.' );
-		return vrDisplays;
-
-	};
-
-	this.setSize = function ( width, height, updateStyle ) {
-
-		rendererSize = { width: width, height: height };
-		rendererUpdateStyle = updateStyle;
-
-		if ( scope.isPresenting ) {
-
-			var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
-			renderer.setPixelRatio( 1 );
-			renderer.setSize( eyeParamsL.renderWidth * 2, eyeParamsL.renderHeight, false );
-
-		} else {
-
-			renderer.setPixelRatio( rendererPixelRatio );
-			renderer.setSize( width, height, updateStyle );
-
-		}
-
-	};
-
-	// VR presentation
-
-	var canvas = renderer.domElement;
-	var defaultLeftBounds = [ 0.0, 0.0, 0.5, 1.0 ];
-	var defaultRightBounds = [ 0.5, 0.0, 0.5, 1.0 ];
-
-	function onVRDisplayPresentChange() {
-
-		var wasPresenting = scope.isPresenting;
-		scope.isPresenting = vrDisplay !== undefined && vrDisplay.isPresenting;
-
-		if ( scope.isPresenting ) {
-
-			var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
-			var eyeWidth = eyeParamsL.renderWidth;
-			var eyeHeight = eyeParamsL.renderHeight;
-
-			if ( ! wasPresenting ) {
-
-				rendererPixelRatio = renderer.getPixelRatio();
-				rendererSize = renderer.getSize();
-
-				renderer.setPixelRatio( 1 );
-				renderer.setSize( eyeWidth * 2, eyeHeight, false );
-
-			}
-
-		} else if ( wasPresenting ) {
-
-			renderer.setPixelRatio( rendererPixelRatio );
-			renderer.setSize( rendererSize.width, rendererSize.height, rendererUpdateStyle );
-
-		}
-
-	}
-
-	window.addEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false );
-
-	this.setFullScreen = function ( boolean ) {
-
-		return new Promise( function ( resolve, reject ) {
-
-			if ( vrDisplay === undefined ) {
-
-				reject( new Error( 'No VR hardware found.' ) );
-				return;
-
-			}
-
-			if ( scope.isPresenting === boolean ) {
-
-				resolve();
-				return;
-
-			}
-
-			if ( boolean ) {
-
-				resolve( vrDisplay.requestPresent( [ { source: canvas } ] ) );
-
-			} else {
-
-				resolve( vrDisplay.exitPresent() );
-
-			}
-
-		} );
-
-	};
-
-	this.requestPresent = function () {
-
-		return this.setFullScreen( true );
-
-	};
-
-	this.exitPresent = function () {
-
-		return this.setFullScreen( false );
-
-	};
-
-	this.requestAnimationFrame = function ( f ) {
-
-		if ( vrDisplay !== undefined ) {
-
-			return vrDisplay.requestAnimationFrame( f );
-
-		} else {
-
-			return window.requestAnimationFrame( f );
-
-		}
-
-	};
-
-	this.cancelAnimationFrame = function ( h ) {
-
-		if ( vrDisplay !== undefined ) {
-
-			vrDisplay.cancelAnimationFrame( h );
-
-		} else {
-
-			window.cancelAnimationFrame( h );
-
-		}
-
-	};
-
-	this.submitFrame = function () {
-
-		if ( vrDisplay !== undefined && scope.isPresenting ) {
-
-			vrDisplay.submitFrame();
-
-		}
-
-	};
-
-	this.autoSubmitFrame = true;
-
-	// render
-
-	var cameraL = new THREE.PerspectiveCamera();
-	cameraL.layers.enable( 1 );
-
-	var cameraR = new THREE.PerspectiveCamera();
-	cameraR.layers.enable( 2 );
-
-	this.render = function ( scene, camera, renderTarget, forceClear ) {
-
-		if ( vrDisplay && scope.isPresenting ) {
-
-			var autoUpdate = scene.autoUpdate;
-
-			if ( autoUpdate ) {
-
-				scene.updateMatrixWorld();
-				scene.autoUpdate = false;
-
-			}
-
-			if ( Array.isArray( scene ) ) {
-
-				console.warn( 'THREE.VREffect.render() no longer supports arrays. Use object.layers instead.' );
-				scene = scene[ 0 ];
-
-			}
-
-			// When rendering we don't care what the recommended size is, only what the actual size
-			// of the backbuffer is.
-			var size = renderer.getSize();
-			var layers = vrDisplay.getLayers();
-			var leftBounds;
-			var rightBounds;
-
-			if ( layers.length ) {
-
-				var layer = layers[ 0 ];
-
-				leftBounds = layer.leftBounds !== null && layer.leftBounds.length === 4 ? layer.leftBounds : defaultLeftBounds;
-				rightBounds = layer.rightBounds !== null && layer.rightBounds.length === 4 ? layer.rightBounds : defaultRightBounds;
-
-			} else {
-
-				leftBounds = defaultLeftBounds;
-				rightBounds = defaultRightBounds;
-
-			}
-
-			renderRectL = {
-				x: Math.round( size.width * leftBounds[ 0 ] ),
-				y: Math.round( size.height * leftBounds[ 1 ] ),
-				width: Math.round( size.width * leftBounds[ 2 ] ),
-				height: Math.round( size.height * leftBounds[ 3 ] )
-			};
-			renderRectR = {
-				x: Math.round( size.width * rightBounds[ 0 ] ),
-				y: Math.round( size.height * rightBounds[ 1 ] ),
-				width: Math.round( size.width * rightBounds[ 2 ] ),
-				height: Math.round( size.height * rightBounds[ 3 ] )
-			};
-
-			if ( renderTarget ) {
-
-				renderer.setRenderTarget( renderTarget );
-				renderTarget.scissorTest = true;
-
-			} else {
-
-				renderer.setRenderTarget( null );
-				renderer.setScissorTest( true );
-
-			}
-
-			if ( renderer.autoClear || forceClear ) renderer.clear();
-
-			if ( camera.parent === null ) camera.updateMatrixWorld();
-
-			camera.matrixWorld.decompose( cameraL.position, cameraL.quaternion, cameraL.scale );
-
-			cameraR.position.copy( cameraL.position );
-			cameraR.quaternion.copy( cameraL.quaternion );
-			cameraR.scale.copy( cameraL.scale );
-
-			if ( vrDisplay.getFrameData ) {
-
-				vrDisplay.depthNear = camera.near;
-				vrDisplay.depthFar = camera.far;
-
-				vrDisplay.getFrameData( frameData );
-
-				cameraL.projectionMatrix.elements = frameData.leftProjectionMatrix;
-				cameraR.projectionMatrix.elements = frameData.rightProjectionMatrix;
-
-				getEyeMatrices( frameData );
-
-				cameraL.updateMatrix();
-				cameraL.matrix.multiply( eyeMatrixL );
-				cameraL.matrix.decompose( cameraL.position, cameraL.quaternion, cameraL.scale );
-
-				cameraR.updateMatrix();
-				cameraR.matrix.multiply( eyeMatrixR );
-				cameraR.matrix.decompose( cameraR.position, cameraR.quaternion, cameraR.scale );
-
-			} else {
-
-				var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
-				var eyeParamsR = vrDisplay.getEyeParameters( 'right' );
-
-				cameraL.projectionMatrix = fovToProjection( eyeParamsL.fieldOfView, true, camera.near, camera.far );
-				cameraR.projectionMatrix = fovToProjection( eyeParamsR.fieldOfView, true, camera.near, camera.far );
-
-				eyeTranslationL.fromArray( eyeParamsL.offset );
-				eyeTranslationR.fromArray( eyeParamsR.offset );
-
-				cameraL.translateOnAxis( eyeTranslationL, cameraL.scale.x );
-				cameraR.translateOnAxis( eyeTranslationR, cameraR.scale.x );
-
-			}
-
-			// render left eye
-			if ( renderTarget ) {
-
-				renderTarget.viewport.set( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
-				renderTarget.scissor.set( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
-
-			} else {
-
-				renderer.setViewport( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
-				renderer.setScissor( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
-
-			}
-			renderer.render( scene, cameraL, renderTarget, forceClear );
-
-			// render right eye
-			if ( renderTarget ) {
-
-				renderTarget.viewport.set( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
-				renderTarget.scissor.set( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
-
-			} else {
-
-				renderer.setViewport( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
-				renderer.setScissor( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
-
-			}
-			renderer.render( scene, cameraR, renderTarget, forceClear );
-
-			if ( renderTarget ) {
-
-				renderTarget.viewport.set( 0, 0, size.width, size.height );
-				renderTarget.scissor.set( 0, 0, size.width, size.height );
-				renderTarget.scissorTest = false;
-				renderer.setRenderTarget( null );
-
-			} else {
-
-				renderer.setViewport( 0, 0, size.width, size.height );
-				renderer.setScissorTest( false );
-
-			}
-
-			if ( autoUpdate ) {
-
-				scene.autoUpdate = true;
-
-			}
-
-			if ( scope.autoSubmitFrame ) {
-
-				scope.submitFrame();
-
-			}
-
-			return;
-
-		}
-
-		// Regular render mode if not HMD
-
-		renderer.render( scene, camera, renderTarget, forceClear );
-
-	};
-
-	this.dispose = function () {
-
-		window.removeEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false );
-
-	};
-
-	//
-
-	var poseOrientation = new THREE.Quaternion();
-	var posePosition = new THREE.Vector3();
-
-	// Compute model matrices of the eyes with respect to the head.
-	function getEyeMatrices( frameData ) {
-
-		// Compute the matrix for the position of the head based on the pose
-		if ( frameData.pose.orientation ) {
-
-			poseOrientation.fromArray( frameData.pose.orientation );
-			headMatrix.makeRotationFromQuaternion( poseOrientation );
-
-		}	else {
-
-			headMatrix.identity();
-
-		}
-
-		if ( frameData.pose.position ) {
-
-			posePosition.fromArray( frameData.pose.position );
-			headMatrix.setPosition( posePosition );
-
-		}
-
-		// The view matrix transforms vertices from sitting space to eye space. As such, the view matrix can be thought of as a product of two matrices:
-		// headToEyeMatrix * sittingToHeadMatrix
-
-		// The headMatrix that we've calculated above is the model matrix of the head in sitting space, which is the inverse of sittingToHeadMatrix.
-		// So when we multiply the view matrix with headMatrix, we're left with headToEyeMatrix:
-		// viewMatrix * headMatrix = headToEyeMatrix * sittingToHeadMatrix * headMatrix = headToEyeMatrix
-
-		eyeMatrixL.fromArray( frameData.leftViewMatrix );
-		eyeMatrixL.multiply( headMatrix );
-		eyeMatrixR.fromArray( frameData.rightViewMatrix );
-		eyeMatrixR.multiply( headMatrix );
-
-		// The eye's model matrix in head space is the inverse of headToEyeMatrix we calculated above.
-
-		eyeMatrixL.getInverse( eyeMatrixL );
-		eyeMatrixR.getInverse( eyeMatrixR );
-
-	}
-
-	function fovToNDCScaleOffset( fov ) {
-
-		var pxscale = 2.0 / ( fov.leftTan + fov.rightTan );
-		var pxoffset = ( fov.leftTan - fov.rightTan ) * pxscale * 0.5;
-		var pyscale = 2.0 / ( fov.upTan + fov.downTan );
-		var pyoffset = ( fov.upTan - fov.downTan ) * pyscale * 0.5;
-		return { scale: [ pxscale, pyscale ], offset: [ pxoffset, pyoffset ] };
-
-	}
-
-	function fovPortToProjection( fov, rightHanded, zNear, zFar ) {
-
-		rightHanded = rightHanded === undefined ? true : rightHanded;
-		zNear = zNear === undefined ? 0.01 : zNear;
-		zFar = zFar === undefined ? 10000.0 : zFar;
-
-		var handednessScale = rightHanded ? - 1.0 : 1.0;
-
-		// start with an identity matrix
-		var mobj = new THREE.Matrix4();
-		var m = mobj.elements;
-
-		// and with scale/offset info for normalized device coords
-		var scaleAndOffset = fovToNDCScaleOffset( fov );
-
-		// X result, map clip edges to [-w,+w]
-		m[ 0 * 4 + 0 ] = scaleAndOffset.scale[ 0 ];
-		m[ 0 * 4 + 1 ] = 0.0;
-		m[ 0 * 4 + 2 ] = scaleAndOffset.offset[ 0 ] * handednessScale;
-		m[ 0 * 4 + 3 ] = 0.0;
-
-		// Y result, map clip edges to [-w,+w]
-		// Y offset is negated because this proj matrix transforms from world coords with Y=up,
-		// but the NDC scaling has Y=down (thanks D3D?)
-		m[ 1 * 4 + 0 ] = 0.0;
-		m[ 1 * 4 + 1 ] = scaleAndOffset.scale[ 1 ];
-		m[ 1 * 4 + 2 ] = - scaleAndOffset.offset[ 1 ] * handednessScale;
-		m[ 1 * 4 + 3 ] = 0.0;
-
-		// Z result (up to the app)
-		m[ 2 * 4 + 0 ] = 0.0;
-		m[ 2 * 4 + 1 ] = 0.0;
-		m[ 2 * 4 + 2 ] = zFar / ( zNear - zFar ) * - handednessScale;
-		m[ 2 * 4 + 3 ] = ( zFar * zNear ) / ( zNear - zFar );
-
-		// W result (= Z in)
-		m[ 3 * 4 + 0 ] = 0.0;
-		m[ 3 * 4 + 1 ] = 0.0;
-		m[ 3 * 4 + 2 ] = handednessScale;
-		m[ 3 * 4 + 3 ] = 0.0;
-
-		mobj.transpose();
-		return mobj;
-
-	}
-
-	function fovToProjection( fov, rightHanded, zNear, zFar ) {
-
-		var DEG2RAD = Math.PI / 180.0;
-
-		var fovPort = {
-			upTan: Math.tan( fov.upDegrees * DEG2RAD ),
-			downTan: Math.tan( fov.downDegrees * DEG2RAD ),
-			leftTan: Math.tan( fov.leftDegrees * DEG2RAD ),
-			rightTan: Math.tan( fov.rightDegrees * DEG2RAD )
-		};
-
-		return fovPortToProjection( fovPort, rightHanded, zNear, zFar );
-
-	}
-
-};

+ 68 - 23
examples/js/exporters/GLTFExporter.js

@@ -66,6 +66,7 @@ THREE.GLTFExporter.prototype = {
 	parse: function ( input, onDone, options ) {
 
 		var DEFAULT_OPTIONS = {
+			binary: false,
 			trs: false,
 			onlyVisible: true,
 			truncateDrawRange: true,
@@ -105,7 +106,8 @@ THREE.GLTFExporter.prototype = {
 
 			attributes: new Map(),
 			materials: new Map(),
-			textures: new Map()
+			textures: new Map(),
+			images: new Map()
 
 		};
 
@@ -325,6 +327,29 @@ THREE.GLTFExporter.prototype = {
 
 		}
 
+		/**
+		 * Serializes a userData.
+		 *
+		 * @param {THREE.Object3D|THREE.Material} object
+		 * @returns {Object}
+		 */
+		function serializeUserData( object ) {
+
+			try {
+
+				return JSON.parse( JSON.stringify( object.userData ) );
+
+			} catch ( error ) {
+
+				console.warn( 'THREE.GLTFExporter: userData of \'' + object.name + '\' ' +
+					'won\'t be serialized because of JSON.stringify error - ' + error.message );
+
+				return {};
+
+			}
+
+		}
+
 		/**
 		 * Process a buffer to append to the default one.
 		 * @param  {ArrayBuffer} buffer
@@ -598,12 +623,28 @@ THREE.GLTFExporter.prototype = {
 
 		/**
 		 * Process image
-		 * @param  {Texture} map Texture to process
+		 * @param  {Image} image to process
+		 * @param  {Integer} format of the image (e.g. THREE.RGBFormat, THREE.RGBAFormat etc)
+		 * @param  {Boolean} flipY before writing out the image
 		 * @return {Integer}     Index of the processed texture in the "images" array
 		 */
-		function processImage( map ) {
+		function processImage( image, format, flipY ) {
+
+			if ( ! cachedData.images.has( image ) ) {
+
+				cachedData.images.set( image, {} );
+
+			}
 
-			// @TODO Cache
+			var cachedImages = cachedData.images.get( image );
+			var mimeType = format === THREE.RGBAFormat ? 'image/png' : 'image/jpeg';
+			var key = mimeType + ":flipY/" + flipY.toString();
+
+			if ( cachedImages[ key ] !== undefined ) {
+
+				return cachedImages[ key ];
+
+			}
 
 			if ( ! outputJSON.images ) {
 
@@ -611,19 +652,18 @@ THREE.GLTFExporter.prototype = {
 
 			}
 
-			var mimeType = map.format === THREE.RGBAFormat ? 'image/png' : 'image/jpeg';
 			var gltfImage = { mimeType: mimeType };
 
 			if ( options.embedImages ) {
 
 				var canvas = cachedCanvas = cachedCanvas || document.createElement( 'canvas' );
 
-				canvas.width = map.image.width;
-				canvas.height = map.image.height;
+				canvas.width = image.width;
+				canvas.height = image.height;
 
-				if ( options.forcePowerOfTwoTextures && ! isPowerOfTwo( map.image ) ) {
+				if ( options.forcePowerOfTwoTextures && ! isPowerOfTwo( image ) ) {
 
-					console.warn( 'GLTFExporter: Resized non-power-of-two image.', map.image );
+					console.warn( 'GLTFExporter: Resized non-power-of-two image.', image );
 
 					canvas.width = THREE.Math.floorPowerOfTwo( canvas.width );
 					canvas.height = THREE.Math.floorPowerOfTwo( canvas.height );
@@ -632,14 +672,14 @@ THREE.GLTFExporter.prototype = {
 
 				var ctx = canvas.getContext( '2d' );
 
-				if ( map.flipY === true ) {
+				if ( flipY === true ) {
 
 					ctx.translate( 0, canvas.height );
 					ctx.scale( 1, - 1 );
 
 				}
 
-				ctx.drawImage( map.image, 0, 0, canvas.width, canvas.height );
+				ctx.drawImage( image, 0, 0, canvas.width, canvas.height );
 
 				if ( options.binary === true ) {
 
@@ -667,13 +707,16 @@ THREE.GLTFExporter.prototype = {
 
 			} else {
 
-				gltfImage.uri = map.image.src;
+				gltfImage.uri = image.src;
 
 			}
 
 			outputJSON.images.push( gltfImage );
 
-			return outputJSON.images.length - 1;
+			var index = outputJSON.images.length - 1;
+			cachedImages[ key ] = index;
+
+			return index;
 
 		}
 
@@ -727,7 +770,7 @@ THREE.GLTFExporter.prototype = {
 			var gltfTexture = {
 
 				sampler: processSampler( map ),
-				source: processImage( map )
+				source: processImage( map.image, map.format, map.flipY  )
 
 			};
 
@@ -936,6 +979,12 @@ THREE.GLTFExporter.prototype = {
 
 			}
 
+			if ( Object.keys( material.userData ).length > 0 ) {
+
+				gltfMaterial.extras = serializeUserData( material );
+
+			}
+
 			outputJSON.materials.push( gltfMaterial );
 
 			var index = outputJSON.materials.length - 1;
@@ -1152,6 +1201,8 @@ THREE.GLTFExporter.prototype = {
 
 			}
 
+			var extras = ( Object.keys( geometry.userData ).length > 0 ) ? serializeUserData( geometry ) : undefined;
+
 			var forceIndices = options.forceIndices;
 			var isMultiMaterial = Array.isArray( mesh.material );
 
@@ -1193,6 +1244,8 @@ THREE.GLTFExporter.prototype = {
 					attributes: attributes,
 				};
 
+				if ( extras ) primitive.extras = extras;
+
 				if ( targets.length > 0 ) primitive.targets = targets;
 
 				if ( geometry.index !== null ) {
@@ -1512,15 +1565,7 @@ THREE.GLTFExporter.prototype = {
 
 			if ( object.userData && Object.keys( object.userData ).length > 0 ) {
 
-				try {
-
-					gltfNode.extras = JSON.parse( JSON.stringify( object.userData ) );
-
-				} catch ( e ) {
-
-					throw new Error( 'THREE.GLTFExporter: userData can\'t be serialized' );
-
-				}
+				gltfNode.extras = serializeUserData( object );
 
 			}
 

+ 417 - 112
examples/js/exporters/PLYExporter.js

@@ -5,9 +5,8 @@
  * Usage:
  *  var exporter = new THREE.PLYExporter();
  *
- *  // second argument is an array of attributes to
- *  // exclude from the format ('color', 'uv', 'normal')
- *  var data = exporter.parse(mesh, [ 'color' ]);
+ *  // second argument is a list of options
+ *  var data = exporter.parse( mesh, { binary: true, excludeAttributes: [ 'color' ] } );
  *
  * Format Definition:
  *  http://paulbourke.net/dataformats/ply/
@@ -19,40 +18,75 @@ THREE.PLYExporter.prototype = {
 
 	constructor: THREE.PLYExporter,
 
-	parse: function ( object, excludeProperties ) {
+	parse: function ( object, options ) {
 
-		if ( Array.isArray( excludeProperties ) !== true ) {
+		// Iterate over the valid meshes in the object
+		function traverseMeshes( cb ) {
 
-			excludeProperties = [];
+			object.traverse( function ( child ) {
+
+				if ( child.isMesh === true ) {
+
+					var mesh = child;
+					var geometry = mesh.geometry;
+
+					if ( geometry.isGeometry === true ) {
+
+						geometry = geomToBufferGeom.get( geometry );
+
+					}
+
+					if ( geometry.isBufferGeometry === true ) {
+
+						if ( geometry.getAttribute( 'position' ) !== undefined ) {
+
+							cb( mesh, geometry );
+
+						}
+
+					}
+
+				}
+
+			} );
 
 		}
 
-		var includeNormals = excludeProperties.indexOf( 'normal' ) === - 1;
-		var includeColors = excludeProperties.indexOf( 'color' ) === - 1;
-		var includeUVs = excludeProperties.indexOf( 'uv' ) === - 1;
+		// Default options
+		var defaultOptions = {
+			binary: false,
+			excludeAttributes: [] // normal, uv, color, index
+		};
+
+		options = Object.assign( defaultOptions, options );
 
-		// count the number of vertices
+		var excludeAttributes = options.excludeAttributes;
+		var geomToBufferGeom = new WeakMap();
+		var includeNormals = false;
+		var includeColors = false;
+		var includeUVs = false;
+		var includeIndices = true;
+
+		// count the vertices, check which properties are used,
+		// and cache the BufferGeometry
 		var vertexCount = 0;
 		var faceCount = 0;
-		var vertexList = '';
-		var faceList = '';
-
-		var vertex = new THREE.Vector3();
-		var normalMatrixWorld = new THREE.Matrix3();
 		object.traverse( function ( child ) {
 
-			if ( child instanceof THREE.Mesh ) {
+			if ( child.isMesh === true ) {
 
 				var mesh = child;
 				var geometry = mesh.geometry;
 
-				if ( geometry instanceof THREE.Geometry ) {
+				if ( geometry.isGeometry === true ) {
 
-					geometry = new THREE.BufferGeometry().setFromObject( mesh );
+					var bufferGeometry = geomToBufferGeom.get( geometry ) || new THREE.BufferGeometry().setFromObject( mesh );
+					geomToBufferGeom.set( geometry, bufferGeometry );
+					geometry = bufferGeometry;
 
 				}
 
-				if ( geometry instanceof THREE.BufferGeometry ) {
+				if ( geometry.isBufferGeometry === true ) {
 
 					var vertices = geometry.getAttribute( 'position' );
 					var normals = geometry.getAttribute( 'normal' );
@@ -60,102 +94,279 @@ THREE.PLYExporter.prototype = {
 					var colors = geometry.getAttribute( 'color' );
 					var indices = geometry.getIndex();
 
-					normalMatrixWorld.getNormalMatrix( mesh.matrixWorld );
-
 					if ( vertices === undefined ) {
 
 						return;
 
 					}
 
-					// form each line
-					for ( var i = 0, l = vertices.count; i < l; i ++ ) {
+					vertexCount += vertices.count;
+					faceCount += indices ? indices.count / 3 : vertices.count / 3;
+
+					if ( normals !== undefined ) includeNormals = true;
+
+					if ( uvs !== undefined ) includeUVs = true;
 
-						vertex.x = vertices.getX( i );
-						vertex.y = vertices.getY( i );
-						vertex.z = vertices.getZ( i );
+					if ( colors !== undefined ) includeColors = true;
 
-						vertex.applyMatrix4( mesh.matrixWorld );
+				}
 
+			}
 
-						// Position information
-						var line =
-							vertex.x + ' ' +
-							vertex.y + ' ' +
-							vertex.z;
+		} );
 
-						// Normal information
-						if ( includeNormals === true ) {
+		includeNormals = includeNormals && excludeAttributes.indexOf( 'normal' ) === - 1;
+		includeColors = includeColors && excludeAttributes.indexOf( 'color' ) === - 1;
+		includeUVs = includeUVs && excludeAttributes.indexOf( 'uv' ) === - 1;
+		includeIndices = includeIndices && excludeAttributes.indexOf( 'index' ) === - 1;
 
-							if ( normals !== undefined ) {
 
-								vertex.x = normals.getX( i );
-								vertex.y = normals.getY( i );
-								vertex.z = normals.getZ( i );
+		if ( includeIndices && faceCount !== Math.floor( faceCount ) ) {
 
-								vertex.applyMatrix3( normalMatrixWorld );
+			// point cloud meshes will not have an index array and may not have a
+			// number of vertices that is divisble by 3 (and therefore representable
+			// as triangles)
+			console.error(
 
-								line += ' ' +
-									vertex.x + ' ' +
-									vertex.y + ' ' +
-									vertex.z;
+				'PLYExporter: Failed to generate a valid PLY file with triangle indices because the ' +
+				'number of indices is not divisible by 3.'
 
-							} else {
+			);
 
-								line += ' 0 0 0';
+			return null;
 
-							}
+		}
 
-						}
+		// get how many bytes will be needed to save out the faces
+		// so we can use a minimal amount of memory / data
+		var indexByteCount = 1;
+
+		if ( vertexCount > 256 ) { // 2^8 bits
+
+			indexByteCount = 2;
+
+		}
+
+		if ( vertexCount > 65536 ) { // 2^16 bits
+
+			indexByteCount = 4;
+
+		}
+
+
+		var header =
+			'ply\n' +
+			`format ${ options.binary ? 'binary_big_endian' : 'ascii' } 1.0\n` +
+			`element vertex ${vertexCount}\n` +
+
+			// position
+			'property float x\n' +
+			'property float y\n' +
+			'property float z\n';
+
+		if ( includeNormals === true ) {
+
+			// normal
+			header +=
+				'property float nx\n' +
+				'property float ny\n' +
+				'property float nz\n';
+
+		}
+
+		if ( includeUVs === true ) {
+
+			// uvs
+			header +=
+				'property float s\n' +
+				'property float t\n';
+
+		}
+
+		if ( includeColors === true ) {
+
+			// colors
+			header +=
+				'property uchar red\n' +
+				'property uchar green\n' +
+				'property uchar blue\n';
+
+		}
+
+		if ( includeIndices === true ) {
+
+			// faces
+			header +=
+				`element face ${faceCount}\n` +
+				`property list uchar uint${ indexByteCount * 8 } vertex_index\n`;
+
+		}
 
-						// UV information
-						if ( includeUVs === true ) {
+		header += 'end_header\n';
 
-							if ( uvs !== undefined ) {
 
-								line += ' ' +
-									uvs.getX( i ) + ' ' +
-									uvs.getY( i );
+		// Generate attribute data
+		var vertex = new THREE.Vector3();
+		var normalMatrixWorld = new THREE.Matrix3();
+
+		if ( options.binary === true ) {
+
+			// Binary File Generation
+			var headerBin = new TextEncoder().encode( header );
+
+			// 3 position values at 4 bytes
+			// 3 normal values at 4 bytes
+			// 3 color channels with 1 byte
+			// 2 uv values at 4 bytes
+			var vertexListLength = vertexCount * ( 4 * 3 + ( includeNormals ? 4 * 3 : 0 ) + ( includeColors ? 3 : 0 ) + ( includeUVs ? 4 * 2 : 0 ) );
+
+			// 1 byte shape desciptor
+			// 3 vertex indices at ${indexByteCount} bytes
+			var faceListLength = includeIndices ? faceCount * ( indexByteCount * 3 + 1 ) : 0;
+			var output = new DataView( new ArrayBuffer( headerBin.length + vertexListLength + faceListLength ) );
+			new Uint8Array( output.buffer ).set( headerBin, 0 );
+
+
+			var vOffset = headerBin.length;
+			var fOffset = headerBin.length + vertexListLength;
+			var writtenVertices = 0;
+			traverseMeshes( function ( mesh, geometry ) {
+
+				var vertices = geometry.getAttribute( 'position' );
+				var normals = geometry.getAttribute( 'normal' );
+				var uvs = geometry.getAttribute( 'uv' );
+				var colors = geometry.getAttribute( 'color' );
+				var indices = geometry.getIndex();
+
+				normalMatrixWorld.getNormalMatrix( mesh.matrixWorld );
+
+				for ( var i = 0, l = vertices.count; i < l; i ++ ) {
+
+					vertex.x = vertices.getX( i );
+					vertex.y = vertices.getY( i );
+					vertex.z = vertices.getZ( i );
+
+					vertex.applyMatrix4( mesh.matrixWorld );
 
-							} else if ( includeUVs !== false ) {
 
-								line += ' 0 0';
+					// Position information
+					output.setFloat32( vOffset, vertex.x );
+					vOffset += 4;
 
-							}
+					output.setFloat32( vOffset, vertex.y );
+					vOffset += 4;
+
+					output.setFloat32( vOffset, vertex.z );
+					vOffset += 4;
+
+					// Normal information
+					if ( includeNormals === true ) {
+
+						if ( normals != null ) {
+
+							vertex.x = normals.getX( i );
+							vertex.y = normals.getY( i );
+							vertex.z = normals.getZ( i );
+
+							vertex.applyMatrix3( normalMatrixWorld );
+
+							output.setFloat32( vOffset, vertex.x );
+							vOffset += 4;
+
+							output.setFloat32( vOffset, vertex.y );
+							vOffset += 4;
+
+							output.setFloat32( vOffset, vertex.z );
+							vOffset += 4;
+
+						} else {
+
+							output.setFloat32( vOffset, 0 );
+							vOffset += 4;
+
+							output.setFloat32( vOffset, 0 );
+							vOffset += 4;
+
+							output.setFloat32( vOffset, 0 );
+							vOffset += 4;
 
 						}
 
-						// Color information
-						if ( includeColors === true ) {
+					}
 
-							if ( colors !== undefined ) {
+					// UV information
+					if ( includeUVs === true ) {
 
-								line += ' ' +
-									Math.floor( colors.getX( i ) ) + ' ' +
-									Math.floor( colors.getY( i ) ) + ' ' +
-									Math.floor( colors.getZ( i ) );
+						if ( uvs != null ) {
 
-							} else {
+							output.setFloat32( vOffset, uvs.getX( i ) );
+							vOffset += 4;
 
-								line += ' 255 255 255';
+							output.setFloat32( vOffset, uvs.getY( i ) );
+							vOffset += 4;
 
-							}
+						} else if ( includeUVs !== false ) {
+
+							output.setFloat32( vOffset, 0 );
+							vOffset += 4;
+
+							output.setFloat32( vOffset, 0 );
+							vOffset += 4;
 
 						}
 
-						vertexList += line + '\n';
+					}
+
+					// Color information
+					if ( includeColors === true ) {
+
+						if ( colors != null ) {
+
+							output.setUint8( vOffset, Math.floor( colors.getX( i ) * 255 ) );
+							vOffset += 1;
+
+							output.setUint8( vOffset, Math.floor( colors.getY( i ) * 255 ) );
+							vOffset += 1;
+
+							output.setUint8( vOffset, Math.floor( colors.getZ( i ) * 255 ) );
+							vOffset += 1;
+
+						} else {
+
+							output.setUint8( vOffset, 255 );
+							vOffset += 1;
+
+							output.setUint8( vOffset, 255 );
+							vOffset += 1;
+
+							output.setUint8( vOffset, 255 );
+							vOffset += 1;
+
+						}
 
 					}
 
+				}
+
+				if ( includeIndices === true ) {
 
 					// Create the face list
+					var faceIndexFunc = `setUint${indexByteCount * 8}`;
 					if ( indices !== null ) {
 
-						for ( i = 0, l = indices.count; i < l; i += 3 ) {
+						for ( var i = 0, l = indices.count; i < l; i += 3 ) {
+
+							output.setUint8( fOffset, 3 );
+							fOffset += 1;
 
-							faceList += `3 ${ indices.getX( i + 0 ) + vertexCount }`;
-							faceList += ` ${ indices.getX( i + 1 ) + vertexCount }`;
-							faceList += ` ${ indices.getX( i + 2 ) + vertexCount }\n`;
+							output[ faceIndexFunc ]( fOffset, indices.getX( i + 0 ) + writtenVertices );
+							fOffset += indexByteCount;
+
+							output[ faceIndexFunc ]( fOffset, indices.getX( i + 1 ) + writtenVertices );
+							fOffset += indexByteCount;
+
+							output[ faceIndexFunc ]( fOffset, indices.getX( i + 2 ) + writtenVertices );
+							fOffset += indexByteCount;
 
 						}
 
@@ -163,70 +374,164 @@ THREE.PLYExporter.prototype = {
 
 						for ( var i = 0, l = vertices.count; i < l; i += 3 ) {
 
-							faceList += `3 ${ vertexCount + i } ${ vertexCount + i + 1 } ${ vertexCount + i + 2 }\n`;
+							output.setUint8( fOffset, 3 );
+							fOffset += 1;
+
+							output[ faceIndexFunc ]( fOffset, writtenVertices + i );
+							fOffset += indexByteCount;
+
+							output[ faceIndexFunc ]( fOffset, writtenVertices + i + 1 );
+							fOffset += indexByteCount;
+
+							output[ faceIndexFunc ]( fOffset, writtenVertices + i + 2 );
+							fOffset += indexByteCount;
 
 						}
 
 					}
 
-					vertexCount += vertices.count;
-					faceCount += indices ? indices.count / 3 : vertices.count / 3;
+				}
+
+
+				// Save the amount of verts we've already written so we can offset
+				// the face index on the next mesh
+				writtenVertices += vertices.count;
+
+			} );
+
+			return output;
+
+		} else {
+
+			// Ascii File Generation
+			// count the number of vertices
+			var writtenVertices = 0;
+			var vertexList = '';
+			var faceList = '';
+
+			traverseMeshes( function ( mesh, geometry ) {
+
+				var vertices = geometry.getAttribute( 'position' );
+				var normals = geometry.getAttribute( 'normal' );
+				var uvs = geometry.getAttribute( 'uv' );
+				var colors = geometry.getAttribute( 'color' );
+				var indices = geometry.getIndex();
+
+				normalMatrixWorld.getNormalMatrix( mesh.matrixWorld );
+
+				// form each line
+				for ( var i = 0, l = vertices.count; i < l; i ++ ) {
+
+					vertex.x = vertices.getX( i );
+					vertex.y = vertices.getY( i );
+					vertex.z = vertices.getZ( i );
+
+					vertex.applyMatrix4( mesh.matrixWorld );
+
+
+					// Position information
+					var line =
+						vertex.x + ' ' +
+						vertex.y + ' ' +
+						vertex.z;
+
+					// Normal information
+					if ( includeNormals === true ) {
+
+						if ( normals != null ) {
+
+							vertex.x = normals.getX( i );
+							vertex.y = normals.getY( i );
+							vertex.z = normals.getZ( i );
+
+							vertex.applyMatrix3( normalMatrixWorld );
+
+							line += ' ' +
+								vertex.x + ' ' +
+								vertex.y + ' ' +
+								vertex.z;
+
+						} else {
+
+							line += ' 0 0 0';
+
+						}
+
+					}
+
+					// UV information
+					if ( includeUVs === true ) {
+
+						if ( uvs != null ) {
+
+							line += ' ' +
+								uvs.getX( i ) + ' ' +
+								uvs.getY( i );
+
+						} else if ( includeUVs !== false ) {
+
+							line += ' 0 0';
+
+						}
+
+					}
+
+					// Color information
+					if ( includeColors === true ) {
+
+						if ( colors != null ) {
+
+							line += ' ' +
+								Math.floor( colors.getX( i ) * 255 ) + ' ' +
+								Math.floor( colors.getY( i ) * 255 ) + ' ' +
+								Math.floor( colors.getZ( i ) * 255 );
+
+						} else {
+
+							line += ' 255 255 255';
+
+						}
+
+					}
+
+					vertexList += line + '\n';
 
 				}
 
-			}
+				// Create the face list
+				if ( includeIndices === true ) {
 
-		} );
+					if ( indices !== null ) {
 
-		var output =
-			'ply\n' +
-			'format ascii 1.0\n' +
-			`element vertex ${vertexCount}\n` +
+						for ( var i = 0, l = indices.count; i < l; i += 3 ) {
 
-			// position
-			'property float x\n' +
-			'property float y\n' +
-			'property float z\n';
+							faceList += `3 ${ indices.getX( i + 0 ) + writtenVertices }`;
+							faceList += ` ${ indices.getX( i + 1 ) + writtenVertices }`;
+							faceList += ` ${ indices.getX( i + 2 ) + writtenVertices }\n`;
 
-		if ( includeNormals === true ) {
+						}
 
-			// normal
-			output +=
-				'property float nx\n' +
-				'property float ny\n' +
-				'property float nz\n';
+					} else {
 
-		}
+						for ( var i = 0, l = vertices.count; i < l; i += 3 ) {
 
-		if ( includeUVs === true ) {
+							faceList += `3 ${ writtenVertices + i } ${ writtenVertices + i + 1 } ${ writtenVertices + i + 2 }\n`;
 
-			// uvs
-			output +=
-				'property float s\n' +
-				'property float t\n';
+						}
 
-		}
+					}
 
-		if ( includeColors === true ) {
+					faceCount += indices ? indices.count / 3 : vertices.count / 3;
 
-			// colors
-			output +=
-				'property uchar red\n' +
-				'property uchar green\n' +
-				'property uchar blue\n';
+				}
 
-		}
+				writtenVertices += vertices.count;
 
-		// faces
-		output +=
-			`element face ${faceCount}\n` +
-			'property list uchar int vertex_index\n' +
-			'end_header\n' +
+			} );
 
-			`${vertexList}\n` +
-			`${faceList}\n`;
+			return `${ header }${vertexList}\n${ includeIndices ? `${faceList}\n` : '' }`;
 
-		return output;
+		}
 
 	}
 

+ 0 - 94
examples/js/exporters/STLBinaryExporter.js

@@ -1,94 +0,0 @@
-/**
- * @author kovacsv / http://kovacsv.hu/
- * @author mrdoob / http://mrdoob.com/
- * @author mudcube / http://mudcu.be/
- */
-
-THREE.STLBinaryExporter = function () {};
-
-THREE.STLBinaryExporter.prototype = {
-
-	constructor: THREE.STLBinaryExporter,
-
-	parse: ( function () {
-
-		var vector = new THREE.Vector3();
-		var normalMatrixWorld = new THREE.Matrix3();
-
-		return function parse( scene ) {
-
-			// We collect objects first, as we may need to convert from BufferGeometry to Geometry
-			var objects = [];
-			var triangles = 0;
-			scene.traverse( function ( object ) {
-
-				if ( ! ( object instanceof THREE.Mesh ) ) return;
-
-				var geometry = object.geometry;
-				if ( geometry instanceof THREE.BufferGeometry ) {
-
-					geometry = new THREE.Geometry().fromBufferGeometry( geometry );
-
-				}
-
-				if ( ! ( geometry instanceof THREE.Geometry ) ) return;
-				triangles += geometry.faces.length;
-
-				objects.push( {
-
-					geometry: geometry,
-					matrix: object.matrixWorld
-
-				} );
-
-			} );
-
-			var offset = 80; // skip header
-			var bufferLength = triangles * 2 + triangles * 3 * 4 * 4 + 80 + 4;
-			var arrayBuffer = new ArrayBuffer( bufferLength );
-			var output = new DataView( arrayBuffer );
-			output.setUint32( offset, triangles, true ); offset += 4;
-
-			// Traversing our collected objects
-			objects.forEach( function ( object ) {
-
-				var vertices = object.geometry.vertices;
-				var faces = object.geometry.faces;
-
-				normalMatrixWorld.getNormalMatrix( object.matrix );
-
-				for ( var i = 0, l = faces.length; i < l; i ++ ) {
-
-					var face = faces[ i ];
-
-					vector.copy( face.normal ).applyMatrix3( normalMatrixWorld ).normalize();
-
-					output.setFloat32( offset, vector.x, true ); offset += 4; // normal
-					output.setFloat32( offset, vector.y, true ); offset += 4;
-					output.setFloat32( offset, vector.z, true ); offset += 4;
-
-					var indices = [ face.a, face.b, face.c ];
-
-					for ( var j = 0; j < 3; j ++ ) {
-
-						vector.copy( vertices[ indices[ j ] ] ).applyMatrix4( object.matrix );
-
-						output.setFloat32( offset, vector.x, true ); offset += 4; // vertices
-						output.setFloat32( offset, vector.y, true ); offset += 4;
-						output.setFloat32( offset, vector.z, true ); offset += 4;
-
-					}
-
-					output.setUint16( offset, 0, true ); offset += 2; // attribute byte count
-
-				}
-
-			} );
-
-			return output;
-
-		};
-
-	}() )
-
-};

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