Mr.doob 7 years ago
parent
commit
cc2999bbba
100 changed files with 2118 additions and 2072 deletions
  1. 37 11
      build/three.js
  2. 402 398
      build/three.min.js
  3. 37 11
      build/three.module.js
  4. 15 15
      docs/api/audio/Audio.html
  5. 4 4
      docs/api/audio/AudioListener.html
  6. 13 7
      docs/api/audio/PositionalAudio.html
  7. 4 4
      docs/api/core/Object3D.html
  8. 2 2
      docs/api/deprecated/DeprecatedList.html
  9. 1 1
      docs/api/extras/ShapeUtils.html
  10. 1 2
      docs/api/extras/core/Font.html
  11. 5 2
      docs/api/geometries/BoxBufferGeometry.html
  12. 5 2
      docs/api/geometries/BoxGeometry.html
  13. 7 0
      docs/api/geometries/CircleBufferGeometry.html
  14. 7 0
      docs/api/geometries/CircleGeometry.html
  15. 2 1
      docs/api/geometries/ConeBufferGeometry.html
  16. 2 1
      docs/api/geometries/ConeGeometry.html
  17. 2 1
      docs/api/geometries/CylinderBufferGeometry.html
  18. 2 1
      docs/api/geometries/CylinderGeometry.html
  19. 1 1
      docs/api/geometries/DodecahedronBufferGeometry.html
  20. 1 1
      docs/api/geometries/DodecahedronGeometry.html
  21. 7 0
      docs/api/geometries/EdgesGeometry.html
  22. 7 0
      docs/api/geometries/ExtrudeBufferGeometry.html
  23. 7 0
      docs/api/geometries/ExtrudeGeometry.html
  24. 1 1
      docs/api/geometries/IcosahedronBufferGeometry.html
  25. 1 1
      docs/api/geometries/IcosahedronGeometry.html
  26. 7 0
      docs/api/geometries/LatheBufferGeometry.html
  27. 7 0
      docs/api/geometries/LatheGeometry.html
  28. 1 1
      docs/api/geometries/OctahedronBufferGeometry.html
  29. 1 1
      docs/api/geometries/OctahedronGeometry.html
  30. 7 0
      docs/api/geometries/ParametricBufferGeometry.html
  31. 8 0
      docs/api/geometries/ParametricGeometry.html
  32. 2 1
      docs/api/geometries/PlaneBufferGeometry.html
  33. 2 1
      docs/api/geometries/PlaneGeometry.html
  34. 1 1
      docs/api/geometries/PolyhedronBufferGeometry.html
  35. 1 1
      docs/api/geometries/PolyhedronGeometry.html
  36. 9 0
      docs/api/geometries/RingBufferGeometry.html
  37. 8 0
      docs/api/geometries/RingGeometry.html
  38. 7 0
      docs/api/geometries/ShapeBufferGeometry.html
  39. 7 0
      docs/api/geometries/ShapeGeometry.html
  40. 2 1
      docs/api/geometries/SphereBufferGeometry.html
  41. 2 1
      docs/api/geometries/SphereGeometry.html
  42. 3 1
      docs/api/geometries/TetrahedronBufferGeometry.html
  43. 1 1
      docs/api/geometries/TetrahedronGeometry.html
  44. 7 0
      docs/api/geometries/TextBufferGeometry.html
  45. 7 0
      docs/api/geometries/TextGeometry.html
  46. 2 1
      docs/api/geometries/TorusBufferGeometry.html
  47. 2 1
      docs/api/geometries/TorusGeometry.html
  48. 2 1
      docs/api/geometries/TorusKnotBufferGeometry.html
  49. 2 1
      docs/api/geometries/TorusKnotGeometry.html
  50. 1 1
      docs/api/geometries/TubeBufferGeometry.html
  51. 1 1
      docs/api/geometries/TubeGeometry.html
  52. 1 1
      docs/api/loaders/CubeTextureLoader.html
  53. 1 1
      docs/api/loaders/ImageLoader.html
  54. 13 2
      docs/api/loaders/JSONLoader.html
  55. 1 0
      docs/api/loaders/Loader.html
  56. 1 2
      docs/api/loaders/ObjectLoader.html
  57. 1 1
      docs/api/loaders/TextureLoader.html
  58. 7 0
      docs/api/materials/MeshPhongMaterial.html
  59. 7 0
      docs/api/materials/MeshStandardMaterial.html
  60. 28 4
      docs/api/math/Color.html
  61. 1 1
      docs/api/objects/Line.html
  62. 1 1
      docs/api/objects/SkinnedMesh.html
  63. 4 4
      docs/api/renderers/WebGLRenderer.html
  64. 1 1
      docs/examples/controls/OrbitControls.html
  65. 1 1
      docs/examples/loaders/GLTFLoader.html
  66. 8 7
      docs/examples/loaders/MTLLoader.html
  67. 13 0
      docs/examples/loaders/OBJLoader.html
  68. 1 1
      docs/manual/introduction/Animation-system.html
  69. 4 5
      docs/manual/introduction/Creating-a-scene.html
  70. 2 2
      docs/manual/introduction/FAQ.html
  71. 3 3
      docs/manual/introduction/Import-via-modules.html
  72. 20 23
      docs/manual/introduction/Loading-3D-models.html
  73. 11 27
      docs/scenes/geometry-browser.html
  74. 2 3
      editor/index.html
  75. 0 20
      editor/js/Loader.js
  76. 2 2
      editor/js/libs/app.js
  77. 1 1
      editor/js/libs/tern-threejs/threejs.js
  78. 2 2
      examples/canvas_lines_colors.html
  79. 1 1
      examples/css2d_label.html
  80. 8 7
      examples/files.js
  81. 25 36
      examples/js/BufferGeometryUtils.js
  82. 9 8
      examples/js/MorphBlendMesh.js
  83. 42 42
      examples/js/RollerCoaster.js
  84. 0 1
      examples/js/animation/CCDIKSolver.js
  85. 2 3
      examples/js/animation/MMDPhysics.js
  86. 3 4
      examples/js/controls/EditorControls.js
  87. 1144 0
      examples/js/controls/MapControls.js
  88. 0 149
      examples/js/controls/VRControls.js
  89. 1 1
      examples/js/effects/OutlineEffect.js
  90. 0 533
      examples/js/effects/VREffect.js
  91. 38 19
      examples/js/exporters/GLTFExporter.js
  92. 0 646
      examples/js/libs/msgpack-js.js
  93. 5 5
      examples/js/lines/LineMaterial.js
  94. 1 1
      examples/js/lines/LineSegmentsGeometry.js
  95. 4 1
      examples/js/loaders/AssimpJSONLoader.js
  96. 4 3
      examples/js/loaders/AssimpLoader.js
  97. 4 1
      examples/js/loaders/BinaryLoader.js
  98. 12 2
      examples/js/loaders/ColladaLoader.js
  99. 3 1
      examples/js/loaders/DDSLoader.js
  100. 2 10
      examples/js/loaders/DRACOLoader.js

File diff suppressed because it is too large
+ 37 - 11
build/three.js


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


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


+ 15 - 15
docs/api/audio/Audio.html

@@ -98,24 +98,24 @@
 
 		<h2>Methods</h2>
 
-		<h3>[method:null connect]()</h3>
+		<h3>[method:Audio connect]()</h3>
 		<p>
 		Connect to the [page:Audio.source]. This is used internally on initialisation and when
 		setting / removing filters.
 		</p>
 
-		<h3>[method:null disconnect]()</h3>
+		<h3>[method:Audio disconnect]()</h3>
 		<p>
 		Disconnect from the [page:Audio.source]. This is used internally when
 		setting / removing filters.
 		</p>
 
-		<h3>[method:Array getFilter]()</h3>
+		<h3>[method:BiquadFilterNode getFilter]()</h3>
 		<p>
 		Returns the first element of the [page:Audio.filters filters] array.
 		</p>
 
-		<h3>[method:null getFilters]()</h3>
+		<h3>[method:Array getFilters]()</h3>
 		<p>
 		Returns the [page:Audio.filters filters] array.
 		</p>
@@ -131,22 +131,22 @@
 		Return the [page:Audio.gain gainNode].
 		</p>
 
-		<h3>[method:Number getPlaybackRate]()</h3>
+		<h3>[method:Float getPlaybackRate]()</h3>
 		<p>
 		Return the value of [page:Audio.playbackRate playbackRate].
 		</p>
 
-		<h3>[method:Number getVolume]( value )</h3>
+		<h3>[method:Float getVolume]( value )</h3>
 		<p>
 		Return the current volume.
 		</p>
 
-		<h3>[method:null play]()</h3>
+		<h3>[method:Audio play]()</h3>
 		<p>
 		If [page:Audio.hasPlaybackControl hasPlaybackControl] is true, starts playback.
 		</p>
 
-		<h3>[method:null pause]()</h3>
+		<h3>[method:Audio pause]()</h3>
 		<p>
 		If [page:Audio.hasPlaybackControl hasPlaybackControl] is true, pauses playback.
 		</p>
@@ -162,7 +162,7 @@
 		If [page:Audio.autoplay autoplay], also starts playback.
 		</p>
 
-		<h3>[method:null setFilter]( filter )</h3>
+		<h3>[method:Audio setFilter]( filter )</h3>
 		<p>
 		Applies a single [link:https://developer.mozilla.org/en-US/docs/Web/API/BiquadFilterNode BiquadFilterNode] to the audio.
 		</p>
@@ -173,37 +173,37 @@
 		Applies an array of [link:https://developer.mozilla.org/en-US/docs/Web/API/BiquadFilterNode BiquadFilterNodes] to the audio.
 		</p>
 
-		<h3>[method:null setLoop]( [param:Boolean value] )</h3>
+		<h3>[method:Audio setLoop]( [param:Boolean value] )</h3>
 		<p>
 		Set [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loop source.loop] to *value*
 		(whether playback should loop).
 		</p>
 
-		<h3>[method:null setMediaElementSource]( mediaElement )</h3>
+		<h3>[method:Audio setMediaElementSource]( mediaElement )</h3>
 		<p>
 		Applies the given object of type [link:https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement HTMLMediaElement] as the source of this audio.<br />
 		Also sets [page:Audio.hasPlaybackControl hasPlaybackControl] to false.
 
 		</p>
 
-		<h3>[method:null setNodeSource]( audioNode )</h3>
+		<h3>[method:Audio setNodeSource]( audioNode )</h3>
 		<p>
 		Setup the [page:Audio.source source] to the audioBuffer, and sets [page:Audio.sourceType sourceType] to 'audioNode'.<br />
 		Also sets [page:Audio.hasPlaybackControl hasPlaybackControl] to false.
 
 		</p>
 
-		<h3>[method:null setPlaybackRate]( [param:Number value] )</h3>
+		<h3>[method:Audio setPlaybackRate]( [param:Float value] )</h3>
 		<p>
 		If [page:Audio.hasPlaybackControl hasPlaybackControl] is enabled, set the [page:Audio.playbackRate playbackRate] to *value*.
 		</p>
 
-		<h3>[method:null setVolume]( [param:Number value] )</h3>
+		<h3>[method:Audio setVolume]( [param:Float value] )</h3>
 		<p>
 		Set the volume.
 		</p>
 
-		<h3>[method:null stop]()</h3>
+		<h3>[method:Audio stop]()</h3>
 		<p>
 		If [page:Audio.hasPlaybackControl hasPlaybackControl] is enabled, stops playback,
 		resets [page:Audio.startTime startTime] to *0* and sets [page:Audio.isPlaying isPlaying] to false.

+ 4 - 4
docs/api/audio/AudioListener.html

@@ -76,7 +76,7 @@
 		Return the [page:AudioListener.gain gainNode].
 		</p>
 
-		<h3>[method:null removeFilter]()</h3>
+		<h3>[method:AudioListener removeFilter]()</h3>
 		<p>
 		Set the [page:AudioListener.filter filter] property to *null*.
 		</p>
@@ -86,17 +86,17 @@
 		Returns the value of the [page:AudioListener.filter filter] property.
 		</p>
 
-		<h3>[method:null setFilter]( [param:AudioNode value] )</h3>
+		<h3>[method:AudioListener setFilter]( [param:AudioNode value] )</h3>
 		<p>
 		Set the [page:AudioListener.filter filter] property to *value*.
 		</p>
 
-		<h3>[method:Number getMasterVolume]()</h3>
+		<h3>[method:Float getMasterVolume]()</h3>
 		<p>
 		Return the volume.
 		</p>
 
-		<h3>[method:null setMasterVolume]( [param:Number value] )</h3>
+		<h3>[method:AudioListener setMasterVolume]( [param:Number value] )</h3>
 		<p>
 		Set the volume.
 		</p>

+ 13 - 7
docs/api/audio/PositionalAudio.html

@@ -22,6 +22,7 @@
 		<h2>Example</h2>
 
 		<p>
+			[example:webaudio_orientation webaudio / orientation ]</br>
 			[example:webaudio_sandbox webaudio / sandbox ]</br>
 			[example:webaudio_timing webaudio / timing ]
 		</p>
@@ -82,22 +83,22 @@
 		Returns the [page:PositionalAudio.panner panner].
 		</p>
 
-		<h3>[method:Number getRefDistance]()</h3>
+		<h3>[method:Float getRefDistance]()</h3>
 		<p>
 		Returns the value of [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/refDistance panner.refDistance].
 		</p>
 
-		<h3>[method:PannerNode setRefDistance]( [param:Number value] )</h3>
+		<h3>[method:PositionalAudio setRefDistance]( [param:Float value] )</h3>
 		<p>
 		Sets the value of [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/refDistance panner.refDistance].
 		</p>
 
-		<h3>[method:PannerNode getRolloffFactor]()</h3>
+		<h3>[method:Float getRolloffFactor]()</h3>
 		<p>
 		Returns the value of [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/rolloffFactor panner.rolloffFactor].
 		</p>
 
-		<h3>[method:PannerNode setRolloffFactor]( [param:Number value] )</h3>
+		<h3>[method:PositionalAudio setRolloffFactor]( [param:Float value] )</h3>
 		<p>
 		Sets the value of [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/rolloffFactor panner.rolloffFactor].
 		</p>
@@ -107,21 +108,26 @@
 		Returns the value of [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/distanceModel panner.distanceModel].
 		</p>
 
-		<h3>[method:String setDistanceModel]( [param:String value] )</h3>
+		<h3>[method:PositionalAudio setDistanceModel]( [param:String value] )</h3>
 		<p>
 		Sets the value of [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/distanceModel panner.distanceModel].
 		</p>
 
-		<h3>[method:PannerNode getMaxDistance]()</h3>
+		<h3>[method:Float getMaxDistance]()</h3>
 		<p>
 		Returns the value of [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/maxDistance panner.maxDistance].
 		</p>
 
-		<h3>[method:PannerNode setMaxDistance]( [param:Number value] )</h3>
+		<h3>[method:PositionalAudio setMaxDistance]( [param:Float value] )</h3>
 		<p>
 		Sets the value of [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/maxDistance panner.maxDistance].
 		</p>
 
+		<h3>[method:PositionalAudio setDirectionalCone]( [param:Float coneInnerAngle], [param:Float coneOuterAngle], [param:Float coneOuterGain] )</h3>
+		<p>
+		This method can be used in order to transform an omnidirectional sound into a [link:https://developer.mozilla.org/en-US/docs/Web/API/PannerNode directional sound].
+		</p>
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 4 - 4
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 />
 
@@ -387,13 +387,13 @@
 		</p>
 
 		<h3>[method:this translateX]( [param:Float distance] )</h3>
-		<p>Translates object along x axis by *distance* units.</p>
+		<p>Translates object along x axis in object space by *distance* units.</p>
 
 		<h3>[method:this translateY]( [param:Float distance] )</h3>
-		<p>Translates object along y axis by *distance* units.</p>
+		<p>Translates object along y axis in object space by *distance* units.</p>
 
 		<h3>[method:this translateZ]( [param:Float distance] )</h3>
-		<p>Translates object along z axis by *distance* units.</p>
+		<p>Translates object along z axis in object space by *distance* units.</p>
 
 		<h3>[method:null traverse]( [param:Function callback] )</h3>
 		<p>

+ 2 - 2
docs/api/deprecated/DeprecatedList.html

@@ -522,9 +522,9 @@
 
 		<h3>[page:WebGLProgram]</h3>
 		<p>
-			WebGLProgram.uniforms is now [page:	WebGLProgram.getUniforms]().<br /><br />
+			WebGLProgram.uniforms is now [page:WebGLProgram.getUniforms]().<br /><br />
 
-			WebGLProgram.attributes is now [page:	WebGLProgram.getAttributes]().
+			WebGLProgram.attributes is now [page:WebGLProgram.getAttributes]().
 		</p>
 
 		<h3>[page:WebGLRenderer]</h3>

+ 1 - 1
docs/api/extras/ShapeUtils.html

@@ -39,7 +39,7 @@
 		[page:ExtrudeGeometry ExtrudeGeometry] and [page:ShapeGeometry ShapeGeometry].
 		</p>
 
-		<h3>[method:null triangulateShape]( contour, holes )</h3>
+		<h3>[method:Array triangulateShape]( contour, holes )</h3>
 		<p>
 		contour -- 2D polygon.<br />
 		holes -- array of holes<br /><br />

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

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

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

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

@@ -56,7 +56,7 @@ scene.background = new THREE.CubeTextureLoader()
 		<p>
 		If set, assigns the [link:https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes crossOrigin]
 	 attribute of the image to the value of *crossOrigin*,
-		prior to starting the load. Default is *undefined*.
+		prior to starting the load. Default is *"anonymous"*.
 		</p>
 
 		<h3>[property:LoadingManager manager]</h3>

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

@@ -69,7 +69,7 @@
 		<h3>[property:String crossOrigin]</h3>
 		<p>
 		If set, assigns the [link:https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes crossOrigin]
-	 attribute of the image to the value of *crossOrigin*, prior to starting the load. Default is *undefined*.
+	 attribute of the image to the value of *crossOrigin*, prior to starting the load. Default is *"anonymous"*.
 		</p>
 
 		<h3>[property:LoadingManager manager]</h3>

+ 13 - 2
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>
 
@@ -62,6 +62,12 @@
 
 		<h2>Properties</h2>
 
+		<h3>[property:String crossOrigin]</h3>
+		<p>
+		If set, assigns the [link:https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes crossOrigin]
+	 attribute of the image to the value of *crossOrigin*, prior to starting the load. Default is *"anonymous"*.
+		</p>
+
 		<h3>[property:LoadingManager manager]</h3>
 		<p>
 			The [page:LoadingManager loadingManager]  the loader is using. Default is [page:DefaultLoadingManager].
@@ -87,7 +93,12 @@
 		Begin loading from url and pass the <em>JSON</em> to onLoad.
 		</p>
 
-		<h3>[method:null setTexturePath]( [param:String texturePath] )</h3>
+		<h3>[method:JSONLoader setCrossOrigin]( [param:String value] )</h3>
+		<p>
+			Set the [page:.crossOrigin] attribute.
+		</p>
+
+		<h3>[method:JSONLoader setTexturePath]( [param:String texturePath] )</h3>
 		<p>
 			Set the base path or URL from which to load files. This can be useful if
 			you are loading many files from the same directory.

+ 1 - 0
docs/api/loaders/Loader.html

@@ -39,6 +39,7 @@
 		<h3>[property:string crossOrigin]</h3>
 		<p>
 		The crossOrigin string to implement CORS for loading the url from a different domain that allows CORS.
+		Default is *"anonymous"*.
 		</p>
 
 		<h2>Methods</h2>

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

@@ -77,8 +77,7 @@
 		<h3>[property:String crossOrigin]</h3>
 		<p>
 		If set, assigns the [link:https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes crossOrigin]
-	 attribute of the image to the value of *crossOrigin*,
-		prior to starting the load. Default is *undefined*.
+	 attribute of the image to the value of *crossOrigin*, prior to starting the load. Default is *"anonymous"*.
 		</p>
 
 		<h3>[property:LoadingManager manager]</h3>

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

@@ -72,7 +72,7 @@
 		<h3>[property:String crossOrigin]</h3>
 		<p>
 		If set, assigns the [link:https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes crossOrigin]
-	 attribute of the image to the value of *crossOrigin*, prior to starting the load. Default is *undefined*.
+	 attribute of the image to the value of *crossOrigin*, prior to starting the load. Default is *"anonymous"*.
 		</p>
 
 

+ 7 - 0
docs/api/materials/MeshPhongMaterial.html

@@ -178,6 +178,13 @@
 			the way the color is lit. Normal maps do not change the actual shape of the surface, only the lighting.
 		</p>
 
+		<h3>[property:Integer normalMapType]</h3>
+		<p>
+			The type of normal map.<br /><br />
+
+			Options are [page:constant THREE.TangentSpaceNormalMap] (default), and [page:constant THREE.ObjectSpaceNormalMap].
+		</p>
+
 		<h3>[property:Vector2 normalScale]</h3>
 		<p>
 			How much the normal map affects the material. Typical ranges are 0-1.

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

@@ -220,6 +220,13 @@
 			the way the color is lit. Normal maps do not change the actual shape of the surface, only the lighting.
 		</p>
 
+		<h3>[property:Integer normalMapType]</h3>
+		<p>
+			The type of normal map.<br /><br />
+
+			Options are [page:constant THREE.TangentSpaceNormalMap] (default), and [page:constant THREE.ObjectSpaceNormalMap].
+		</p>
+
 		<h3>[property:Vector2 normalScale]</h3>
 		<p>
 			How much the normal map affects the material. Typical ranges are 0-1.

+ 28 - 4
docs/api/math/Color.html

@@ -124,13 +124,23 @@ var color = new THREE.Color( 1, 0, 0 );
 		<h3>[method:Color convertGammaToLinear]( [param:Float gammaFactor] ) </h3>
 		<p>
 		[page:Float gammaFactor] - (optional). Default is *2.0*.<br /><br />
-		Converts this color from gamma to linear space by taking [page:.r r], [page:.g g] and [page:.b b] to the power of [page:Float gammaFactor].
+		Converts this color from gamma space to linear space by taking [page:.r r], [page:.g g] and [page:.b b] to the power of [page:Float gammaFactor].
 		</p>
 		
 		<h3>[method:Color convertLinearToGamma]( [param:Float gammaFactor] ) </h3>
 		<p>
 		[page:Float gammaFactor] - (optional). Default is *2.0*.<br /><br />
-		Converts this color from linear to gamma space by taking [page:.r r], [page:.g g] and [page:.b b] to the power of 1 / [page:Float gammaFactor].
+		Converts this color from linear space to gamma space by taking [page:.r r], [page:.g g] and [page:.b b] to the power of 1 / [page:Float gammaFactor].
+		</p>
+
+		<h3>[method:Color convertLinearToSRGB]() </h3>
+		<p>
+		Converts this color from linear space to sRGB space.
+		</p>
+
+		<h3>[method:Color convertSRGBToLinear]() </h3>
+		<p>
+		Converts this color from sRGB space to linear space.
 		</p>
 
 		<h3>[method:Color copyGammaToLinear]( [param:Color color], [param:Float gammaFactor] ) </h3>
@@ -138,7 +148,7 @@ var color = new THREE.Color( 1, 0, 0 );
 		[page:Color color] — Color to copy.<br />
 		[page:Float gammaFactor] - (optional). Default is *2.0*.<br /><br />
 
-		Copies the given color into this color while converting it from gamma to linear space
+		Copies the given color into this color, and then converts this color from gamma space to linear space
 		by taking [page:.r r], [page:.g g] and [page:.b b] to the power of [page:Float gammaFactor].
 		</p>
 
@@ -147,10 +157,24 @@ var color = new THREE.Color( 1, 0, 0 );
 		[page:Color color] — Color to copy.<br />
 		[page:Float gammaFactor] - (optional). Default is *2.0*.<br /><br />
 
-		Copies the given color into this color while converting it from linear to gamma space
+		Copies the given color into this color, and then converts this color from linear space to gamma space
 		by taking [page:.r r], [page:.g g] and [page:.b b] to the power of 1 / [page:Float gammaFactor].
 		</p>
 
+		<h3>[method:Color copyLinearToSRGB]( [param:Color color]] ) </h3>
+		<p>
+		[page:Color color] — Color to copy.<br />
+
+		Copies the given color into this color, and then converts this color from linear space to sRGB space.
+		</p>
+
+		<h3>[method:Color copySRGBToLinear]( [param:Color color] ) </h3>
+		<p>
+		[page:Color color] — Color to copy.<br />
+
+		Copies the given color into this color, and then converts this color from sRGB space to linear space.
+		</p>
+
 		<h3>[method:Boolean equals]( [param:Color color] ) </h3>
 		<p>Compares the RGB values of [page:Color color] with those of this object. Returns true if they are the same, false otherwise.</p>
 

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

@@ -46,7 +46,7 @@
 		<h3>[name]( [param:Geometry geometry], [param:Material material] )</h3>
 
 		<p>
-		[page:Geometry geometry] — vertices representing the line segment(s). Default is a new [page:new BufferGeometry].<br />
+		[page:Geometry geometry] — vertices representing the line segment(s). Default is a new [page:BufferGeometry].<br />
 		[page:Material material] — material for the line. Default is a new [page:LineBasicMaterial] with random color.<br />
 		</p>
 

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

@@ -38,7 +38,7 @@
 		<h2>Example</h2>
 
 		<code>
-		var geometry = new THREE.CylinderBufferGeometry( 5, 5, 5, 5, 15, 5, 30 );
+		var geometry = new THREE.CylinderGeometry( 5, 5, 5, 5, 15, 5, 30 );
 
 		//Create the skin indices and skin weights
 		for ( var i = 0; i < geometry.vertices.length; i ++ ) {

+ 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 - 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/loaders/GLTFLoader.html

@@ -60,7 +60,7 @@
 				gltf.asset; // Object
 
 			},
-			// called when loading is in progresses
+			// called while loading is progressing
 			function ( xhr ) {
 
 				console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );

+ 8 - 7
docs/examples/loaders/MTLLoader.html

@@ -11,7 +11,7 @@
 
 		<h1>[name]</h1>
 
-		<p class="desc">A loader for loading an <em>.mtl</em> resource, used internaly by [page:OBJLoader] and [page:UTF8Loader].<br />
+		<p class="desc">A loader for loading an <em>.mtl</em> resource, used internaly by [page:OBJLoader].<br />
 		The Material Template Library format (MTL) or .MTL File Format is a companion file format to .OBJ that describes surface shading
 		(material) properties of objects within one or more .OBJ files.
 		</p>
@@ -44,7 +44,7 @@
 		</p>
 
 
-		<h3>[method:null setPath]( [param:String path] )</h3>
+		<h3>[method:MTLLoader setPath]( [param:String path] )</h3>
 		<p>
 			[page:String path] — required<br />
 		</p>
@@ -53,7 +53,7 @@
 		</p>
 
 
-		<h3>[method:null setTexturePath]( [param:String path] )</h3>
+		<h3>[method:MTLLoader setTexturePath]( [param:String path] )</h3>
 		<p>
 			[page:String path] — required<br />
 		</p>
@@ -62,16 +62,17 @@
 		</p>
 
 
-		<h3>[method:null setCrossOrigin]( [param:boolean useCrossOrigin] )</h3>
+		<h3>[method:MTLLoader setCrossOrigin]( [param:String value] )</h3>
 		<p>
-			[page:boolean useCrossOrigin] — required<br />
+			[page:String value] — required<br />
 		</p>
 		<p>
-			Set to true if you need to load textures from a different origin.
+			If set, assigns the [link:https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes crossOrigin]
+		 attribute of the image to the value of *crossOrigin*, prior to starting the load. Default is *"anonymous"*.
 		</p>
 
 
-		<h3>[method:null setMaterialOptions]( [param:Object options] )</h3>
+		<h3>[method:MTLLoader setMaterialOptions]( [param:Object options] )</h3>
 		<p>
 			[page:Object options] — required
 			<ul>

+ 13 - 0
docs/examples/loaders/OBJLoader.html

@@ -89,6 +89,19 @@
 		If an <em>obj</em> object or group uses multiple materials while declaring faces, geometry groups and an array of materials are used.
 		</p>
 
+		<h3>[method:OBJLoader setMaterials]( [param:Array materials] )</h3>
+		<p>
+		[page:Array materials] - Array of [page:Material Materials].
+		</p>
+		<p>
+		Sets materials loaded by MTLLoader or any other supplier of an Array of [page:Material Materials].
+		</p>
+
+		<h3>[method:OBJLoader setPath]( [param:String path] )</h3>
+		<p>
+		Sets the base path or URL from which to load files. This can be useful to avoid repetition if you are calling [page:OBJLoader.load .load] multiple times on the same directory.
+		</p>
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/OBJLoader.js examples/js/loaders/OBJLoader.js]

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

@@ -35,7 +35,7 @@
 		<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
+			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]

+ 4 - 5
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;
@@ -113,8 +113,7 @@
 		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.
-		</div>
+		<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 lines.</p>
 
 		<h2>The result</h2>
 		<p>Congratulations! You have now completed your first three.js application. It's simple, you have to start somewhere.</p>
@@ -150,8 +149,8 @@
 					var animate = function () {
 						requestAnimationFrame( animate );
 
-						cube.rotation.x += 0.1;
-						cube.rotation.y += 0.1;
+						cube.rotation.x += 0.01;
+						cube.rotation.y += 0.01;
 
 						renderer.render( scene, camera );
 					};

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

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

+ 20 - 23
docs/manual/introduction/Loading-3D-models.html

@@ -16,7 +16,7 @@
   <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">
+    <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
@@ -50,25 +50,25 @@
 
   <p>
     Public-domain glTF files are available on sites like
-    <a href="https://sketchfab.com/models?features=downloadable&sort_by=-likeCount&type=models">
+    <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">glTF-Blender-Exporter</a> by the Khronos Group</li>
-    <li><a href="https://github.com/KhronosGroup/COLLADA2GLTF">COLLADA2GLTF</a> by the Khronos Group</li>
-    <li><a href="https://github.com/facebookincubator/FBX2glTF">FBX2GLTF</a> by Facebook</li>
-    <li><a href="https://github.com/AnalyticalGraphicsInc/obj2gltf">OBJ2GLTF</a> by Analytical Graphics Inc</li>
-    <li><a href="https://www.allegorithmic.com/products/substance-painter">Substance Painter</a> by Allegorithmic</li>
-    <li><a href="https://www.foundry.com/products/modo">Modo</a> by Foundry</li>
-    <li><a href="https://www.marmoset.co/toolbag/">Toolbag</a> by Marmoset</li>
-    <li>&hellip;and <a href="https://github.com/khronosgroup/gltf#gltf-tools">many more</a></li>
+    <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">the glTF roadmap thread</a>.
+    <a href="https://github.com/KhronosGroup/glTF/issues/1051" target="_blank" rel="noopener">the glTF roadmap thread</a>.
   </p>
 
   <p>
@@ -92,10 +92,10 @@
     <li>
       View the model in another application. For glTF, drag-and-drop viewers
       are available for
-      <a href="https://gltf-viewer.donmccurdy.com/">three.js</a> and
-      <a href="http://sandbox.babylonjs.com/">babylon.js</a>. If the model
+      <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">file a bug against three.js</a>.
+      <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>
@@ -117,16 +117,13 @@
   <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. 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.
+    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>
 
-  <p>
-    TODO: Do we recommend model-related questions go to GitHub, Stack Overflow,
-    or the Discourse forum?
-  </p>
 </body>
 
-</html>
+</html>

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

+ 2 - 3
editor/index.html

@@ -4,8 +4,8 @@
 		<title>three.js / editor</title>
 		<meta charset="utf-8">
 		<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 = WebVR (For Chrome M62+), origin = https://threejs.org, expires = 2018-07-25 -->
+		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M62+)" data-expires="2018-07-25" content="AtW06hJFoVWUJTZf5gqymMIlrR60JJi5MsSe44qsHjrCmzDUNmvaTtAVg+K9O9jFpjJtn/W9jvG//hHHaq5HcQoAAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMU02MiIsImV4cGlyeSI6MTUzMjUyNjI5OH0=">
 		<!-- 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 -->
@@ -55,7 +55,6 @@
 		<script src="../examples/js/loaders/SVGLoader.js"></script>
 		<script src="../examples/js/loaders/TGALoader.js"></script>
 		<script src="../examples/js/loaders/TDSLoader.js"></script>
-		<script src="../examples/js/loaders/UTF8Loader.js"></script>
 		<script src="../examples/js/loaders/VRMLLoader.js"></script>
 		<script src="../examples/js/loaders/VTKLoader.js"></script>
 		<script src="../examples/js/loaders/ctm/lzma.js"></script>

+ 0 - 20
editor/js/Loader.js

@@ -427,26 +427,6 @@ var Loader = function ( editor ) {
 
 				break;
 
-			/*
-			case 'utf8':
-
-				reader.addEventListener( 'load', function ( event ) {
-
-					var contents = event.target.result;
-
-					var geometry = new THREE.UTF8Loader().parse( contents );
-					var material = new THREE.MeshLambertMaterial();
-
-					var mesh = new THREE.Mesh( geometry, material );
-
-					editor.execute( new AddObjectCommand( mesh ) );
-
-				}, false );
-				reader.readAsBinaryString( file );
-
-				break;
-			*/
-
 			case 'vtk':
 
 				reader.addEventListener( 'load', function ( event ) {

+ 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 );
 
 		};
 

+ 1 - 1
editor/js/libs/tern-threejs/threejs.js

@@ -1836,7 +1836,7 @@
           "!doc": "Parse a <em>mtl</em> text structure and return a [page:MTLLoaderMaterialCreator] instance.<br>"
         }
       },
-      "!doc": "A loader for loading an <em>.mtl</em> resource, used internaly by [page:OBJMTLLoader] and [page:UTF8Loader].",
+      "!doc": "A loader for loading an <em>.mtl</em> resource, used internaly by [page:OBJLoader].",
       "!type": "fn(baseUrl: string, options: object, crossOrigin: string)"
     },
     "MaterialLoader": {

+ 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 ] );
 

+ 1 - 1
examples/css2d_label.html

@@ -70,7 +70,7 @@
 
 				scene2 = new THREE.Scene();
 
-				dirLight = new THREE.DirectionalLight( 0xffffff );
+				var dirLight = new THREE.DirectionalLight( 0xffffff );
 				dirLight.position.set( 0, 0, 1 );
 				scene.add( dirLight );
 

+ 8 - 7
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",
@@ -72,6 +72,7 @@ var files = {
 		"webgl_lines_colors",
 		"webgl_lines_dashed",
 		"webgl_lines_fat",
+		"webgl_lines_fat_wireframe",
 		"webgl_lines_sphere",
 		"webgl_loader_3ds",
 		"webgl_loader_3mf",
@@ -93,7 +94,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",
@@ -102,7 +103,6 @@ var files = {
 		"webgl_loader_mmd",
 		"webgl_loader_mmd_pose",
 		"webgl_loader_mmd_audio",
-		"webgl_loader_msgpack",
 		"webgl_loader_nodes",
 		"webgl_loader_obj",
 		"webgl_loader_obj_mtl",
@@ -132,7 +132,6 @@ var files = {
 		"webgl_loader_texture_pvrtc",
 		"webgl_loader_texture_tga",
 		"webgl_loader_ttf",
-		"webgl_loader_utf8",
 		"webgl_loader_vrm",
 		"webgl_loader_vrml",
 		"webgl_loader_vtk",
@@ -313,20 +312,21 @@ var files = {
 	],
 	*/
 	"webaudio": [
+		"webaudio_orientation",
 		"webaudio_sandbox",
 		"webaudio_timing",
 		"webaudio_visualizer"
 	],
 	"webvr": [
+		"webvr_ballshooter",
 		"webvr_cubes",
-		"webvr_daydream",
-		"webvr_gearvr",
+		"webvr_dragging",
+		"webvr_lorenzattractor",
 		"webvr_panorama",
 		"webvr_rollercoaster",
 		"webvr_sandbox",
 		"webvr_video",
 		"webvr_vive",
-		"webvr_vive_dragging",
 		"webvr_vive_paint",
 		"webvr_vive_sculpt"
 	],
@@ -336,6 +336,7 @@ var files = {
 		"misc_animation_keys",
 		"misc_controls_deviceorientation",
 		"misc_controls_fly",
+		"misc_controls_map",
 		"misc_controls_orbit",
 		"misc_controls_pointerlock",
 		"misc_controls_trackball",

+ 25 - 36
examples/js/BufferGeometryUtils.js

@@ -39,10 +39,10 @@ THREE.BufferGeometryUtils = {
 
 		var tan1 = [], tan2 = [];
 
-		for ( var k = 0; k < nVertices; k ++ ) {
+		for ( var i = 0; i < nVertices; i ++ ) {
 
-			tan1[ k ] = new THREE.Vector3();
-			tan2[ k ] = new THREE.Vector3();
+			tan1[ i ] = new THREE.Vector3();
+			tan2[ i ] = new THREE.Vector3();
 
 		}
 
@@ -117,19 +117,19 @@ THREE.BufferGeometryUtils = {
 
 		}
 
-		for ( var j = 0, jl = groups.length; j < jl; ++ j ) {
+		for ( var i = 0, il = groups.length; i < il; ++ i ) {
 
-			var group = groups[ j ];
+			var group = groups[ i ];
 
 			var start = group.start;
 			var count = group.count;
 
-			for ( var i = start, il = start + count; i < il; i += 3 ) {
+			for ( var j = start, jl = start + count; j < jl; j += 3 ) {
 
 				handleTriangle(
-					indices[ i + 0 ],
-					indices[ i + 1 ],
-					indices[ i + 2 ]
+					indices[ j + 0 ],
+					indices[ j + 1 ],
+					indices[ j + 2 ]
 				);
 
 			}
@@ -165,18 +165,18 @@ THREE.BufferGeometryUtils = {
 
 		}
 
-		for ( var j = 0, jl = groups.length; j < jl; ++ j ) {
+		for ( var i = 0, il = groups.length; i < il; ++ i ) {
 
-			var group = groups[ j ];
+			var group = groups[ i ];
 
 			var start = group.start;
 			var count = group.count;
 
-			for ( var i = start, il = start + count; i < il; i += 3 ) {
+			for ( var j = start, jl = start + count; j < jl; j += 3 ) {
 
-				handleVertex( indices[ i + 0 ] );
-				handleVertex( indices[ i + 1 ] );
-				handleVertex( indices[ i + 2 ] );
+				handleVertex( indices[ j + 0 ] );
+				handleVertex( indices[ j + 1 ] );
+				handleVertex( indices[ j + 2 ] );
 
 			}
 
@@ -214,7 +214,7 @@ THREE.BufferGeometryUtils = {
 
 			for ( var name in geometry.attributes ) {
 
-				if ( !attributesUsed.has( name ) ) return null;
+				if ( ! attributesUsed.has( name ) ) return null;
 
 				if ( attributes[ name ] === undefined ) attributes[ name ] = [];
 
@@ -226,7 +226,7 @@ THREE.BufferGeometryUtils = {
 
 			for ( var name in geometry.morphAttributes ) {
 
-				if ( !morphAttributesUsed.has( name ) ) return null;
+				if ( ! morphAttributesUsed.has( name ) ) return null;
 
 				if ( morphAttributes[ name ] === undefined ) morphAttributes[ name ] = [];
 
@@ -270,34 +270,23 @@ THREE.BufferGeometryUtils = {
 		if ( isIndexed ) {
 
 			var indexOffset = 0;
-			var indexList = [];
+			var mergedIndex = [];
 
 			for ( var i = 0; i < geometries.length; ++ i ) {
 
 				var index = geometries[ i ].index;
 
-				if ( indexOffset > 0 ) {
+				for ( var j = 0; j < index.count; ++ j ) {
 
-					index = index.clone();
-
-					for ( var j = 0; j < index.count; ++ j ) {
-
-						index.setX( j, index.getX( j ) + indexOffset );
-
-					}
+					mergedIndex.push( index.getX( j ) + indexOffset );
 
 				}
 
-				indexList.push( index );
 				indexOffset += geometries[ i ].attributes.position.count;
 
 			}
 
-			var mergedIndex = this.mergeBufferAttributes( indexList );
-
-			if ( !mergedIndex ) return null;
-
-			mergedGeometry.index = mergedIndex;
+			mergedGeometry.setIndex( mergedIndex );
 
 		}
 
@@ -336,7 +325,7 @@ THREE.BufferGeometryUtils = {
 
 				var mergedMorphAttribute = this.mergeBufferAttributes( morphAttributesToMerge );
 
-				if ( !mergedMorphAttribute ) return null;
+				if ( ! mergedMorphAttribute ) return null;
 
 				mergedGeometry.morphAttributes[ name ].push( mergedMorphAttribute );
 
@@ -381,11 +370,11 @@ THREE.BufferGeometryUtils = {
 		var array = new TypedArray( arrayLength );
 		var offset = 0;
 
-		for ( var j = 0; j < attributes.length; ++ j ) {
+		for ( var i = 0; i < attributes.length; ++ i ) {
 
-			array.set( attributes[ j ].array, offset );
+			array.set( attributes[ i ].array, offset );
 
-			offset += attributes[ j ].array.length;
+			offset += attributes[ i ].array.length;
 
 		}
 

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

+ 42 - 42
examples/js/RollerCoaster.js

@@ -19,7 +19,7 @@ function RollerCoasterGeometry( curve, divisions ) {
 
 	var quaternion = new THREE.Quaternion();
 	var prevQuaternion = new THREE.Quaternion();
-	prevQuaternion.setFromAxisAngle( up , Math.PI / 2 );
+	prevQuaternion.setFromAxisAngle( up, Math.PI / 2 );
 
 	var point = new THREE.Vector3();
 	var prevPoint = new THREE.Vector3();
@@ -28,13 +28,13 @@ function RollerCoasterGeometry( curve, divisions ) {
 	// shapes
 
 	var step = [
-		new THREE.Vector3( -0.225,  0, 0 ),
-		new THREE.Vector3(  0, -0.050, 0 ),
-		new THREE.Vector3(  0, -0.175, 0 ),
+		new THREE.Vector3( - 0.225, 0, 0 ),
+		new THREE.Vector3( 0, - 0.050, 0 ),
+		new THREE.Vector3( 0, - 0.175, 0 ),
 
-		new THREE.Vector3(  0, -0.050, 0 ),
-		new THREE.Vector3(  0.225,  0, 0 ),
-		new THREE.Vector3(  0, -0.175, 0 )
+		new THREE.Vector3( 0, - 0.050, 0 ),
+		new THREE.Vector3( 0.225, 0, 0 ),
+		new THREE.Vector3( 0, - 0.175, 0 )
 	];
 
 	var PI2 = Math.PI * 2;
@@ -64,7 +64,7 @@ function RollerCoasterGeometry( curve, divisions ) {
 
 	function drawShape( shape, color ) {
 
-		normal.set( 0, 0, -1 ).applyQuaternion( quaternion );
+		normal.set( 0, 0, - 1 ).applyQuaternion( quaternion );
 
 		for ( var j = 0; j < shape.length; j ++ ) {
 
@@ -92,7 +92,7 @@ function RollerCoasterGeometry( curve, divisions ) {
 
 		}
 
-	};
+	}
 
 	var vector1 = new THREE.Vector3();
 	var vector2 = new THREE.Vector3();
@@ -171,7 +171,7 @@ function RollerCoasterGeometry( curve, divisions ) {
 
 		}
 
-	};
+	}
 
 	var offset = new THREE.Vector3();
 
@@ -195,9 +195,9 @@ function RollerCoasterGeometry( curve, divisions ) {
 
 		}
 
-		extrudeShape( tube1, offset.set(  0,  -0.125, 0 ), color2 );
-		extrudeShape( tube2, offset.set(  0.2, 0,     0 ), color1 );
-		extrudeShape( tube2, offset.set( -0.2, 0,     0 ), color1 );
+		extrudeShape( tube1, offset.set( 0, - 0.125, 0 ), color2 );
+		extrudeShape( tube2, offset.set( 0.2, 0, 0 ), color1 );
+		extrudeShape( tube2, offset.set( - 0.2, 0, 0 ), color1 );
 
 		prevPoint.copy( point );
 		prevQuaternion.copy( quaternion );
@@ -210,7 +210,7 @@ function RollerCoasterGeometry( curve, divisions ) {
 	this.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( normals ), 3 ) );
 	this.addAttribute( 'color', new THREE.BufferAttribute( new Float32Array( colors ), 3 ) );
 
-};
+}
 
 RollerCoasterGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
 
@@ -231,21 +231,21 @@ function RollerCoasterLiftersGeometry( curve, divisions ) {
 	// shapes
 
 	var tube1 = [
-		new THREE.Vector3(  0,  0.05, -0.05 ),
-		new THREE.Vector3(  0,  0.05,  0.05 ),
-		new THREE.Vector3(  0, -0.05,  0 )
+		new THREE.Vector3( 0, 0.05, - 0.05 ),
+		new THREE.Vector3( 0, 0.05, 0.05 ),
+		new THREE.Vector3( 0, - 0.05, 0 )
 	];
 
 	var tube2 = [
-		new THREE.Vector3( -0.05, 0,  0.05 ),
-		new THREE.Vector3( -0.05, 0, -0.05 ),
-		new THREE.Vector3(  0.05, 0,  0 )
+		new THREE.Vector3( - 0.05, 0, 0.05 ),
+		new THREE.Vector3( - 0.05, 0, - 0.05 ),
+		new THREE.Vector3( 0.05, 0, 0 )
 	];
 
 	var tube3 = [
-		new THREE.Vector3(  0.05, 0, -0.05 ),
-		new THREE.Vector3(  0.05, 0,  0.05 ),
-		new THREE.Vector3( -0.05, 0,  0 )
+		new THREE.Vector3( 0.05, 0, - 0.05 ),
+		new THREE.Vector3( 0.05, 0, 0.05 ),
+		new THREE.Vector3( - 0.05, 0, 0 )
 	];
 
 	var vector1 = new THREE.Vector3();
@@ -317,7 +317,7 @@ function RollerCoasterLiftersGeometry( curve, divisions ) {
 
 		}
 
-	};
+	}
 
 	var fromPoint = new THREE.Vector3();
 	var toPoint = new THREE.Vector3();
@@ -335,31 +335,31 @@ function RollerCoasterLiftersGeometry( curve, divisions ) {
 
 		if ( point.y > 10 ) {
 
-			fromPoint.set( -0.75, -0.35, 0 );
+			fromPoint.set( - 0.75, - 0.35, 0 );
 			fromPoint.applyQuaternion( quaternion );
 			fromPoint.add( point );
 
-			toPoint.set( 0.75, -0.35, 0 );
+			toPoint.set( 0.75, - 0.35, 0 );
 			toPoint.applyQuaternion( quaternion );
 			toPoint.add( point );
 
 			extrudeShape( tube1, fromPoint, toPoint );
 
-			fromPoint.set( -0.7, -0.3, 0 );
+			fromPoint.set( - 0.7, - 0.3, 0 );
 			fromPoint.applyQuaternion( quaternion );
 			fromPoint.add( point );
 
-			toPoint.set( -0.7, -point.y, 0 );
+			toPoint.set( - 0.7, - point.y, 0 );
 			toPoint.applyQuaternion( quaternion );
 			toPoint.add( point );
 
 			extrudeShape( tube2, fromPoint, toPoint );
 
-			fromPoint.set( 0.7, -0.3, 0 );
+			fromPoint.set( 0.7, - 0.3, 0 );
 			fromPoint.applyQuaternion( quaternion );
 			fromPoint.add( point );
 
-			toPoint.set( 0.7, -point.y, 0 );
+			toPoint.set( 0.7, - point.y, 0 );
 			toPoint.applyQuaternion( quaternion );
 			toPoint.add( point );
 
@@ -367,11 +367,11 @@ function RollerCoasterLiftersGeometry( curve, divisions ) {
 
 		} else {
 
-			fromPoint.set( 0, -0.2, 0 );
+			fromPoint.set( 0, - 0.2, 0 );
 			fromPoint.applyQuaternion( quaternion );
 			fromPoint.add( point );
 
-			toPoint.set( 0, -point.y, 0 );
+			toPoint.set( 0, - point.y, 0 );
 			toPoint.applyQuaternion( quaternion );
 			toPoint.add( point );
 
@@ -384,7 +384,7 @@ function RollerCoasterLiftersGeometry( curve, divisions ) {
 	this.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) );
 	this.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( normals ), 3 ) );
 
-};
+}
 
 RollerCoasterLiftersGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
 
@@ -399,7 +399,7 @@ function RollerCoasterShadowGeometry( curve, divisions ) {
 
 	var quaternion = new THREE.Quaternion();
 	var prevQuaternion = new THREE.Quaternion();
-	prevQuaternion.setFromAxisAngle( up , Math.PI / 2 );
+	prevQuaternion.setFromAxisAngle( up, Math.PI / 2 );
 
 	var point = new THREE.Vector3();
 
@@ -423,19 +423,19 @@ function RollerCoasterShadowGeometry( curve, divisions ) {
 
 		quaternion.setFromAxisAngle( up, angle );
 
-		vector1.set( -0.3, 0, 0 );
+		vector1.set( - 0.3, 0, 0 );
 		vector1.applyQuaternion( quaternion );
 		vector1.add( point );
 
-		vector2.set(  0.3, 0, 0 );
+		vector2.set( 0.3, 0, 0 );
 		vector2.applyQuaternion( quaternion );
 		vector2.add( point );
 
-		vector3.set(  0.3, 0, 0 );
+		vector3.set( 0.3, 0, 0 );
 		vector3.applyQuaternion( prevQuaternion );
 		vector3.add( prevPoint );
 
-		vector4.set( -0.3, 0, 0 );
+		vector4.set( - 0.3, 0, 0 );
 		vector4.applyQuaternion( prevQuaternion );
 		vector4.add( prevPoint );
 
@@ -454,7 +454,7 @@ function RollerCoasterShadowGeometry( curve, divisions ) {
 
 	this.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) );
 
-};
+}
 
 RollerCoasterShadowGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
 
@@ -485,7 +485,7 @@ function SkyGeometry() {
 
 	this.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) );
 
-};
+}
 
 SkyGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
 
@@ -497,7 +497,7 @@ function TreesGeometry( landscape ) {
 	var colors = [];
 
 	var raycaster = new THREE.Raycaster();
-	raycaster.ray.direction.set( 0, -1, 0 );
+	raycaster.ray.direction.set( 0, - 1, 0 );
 
 	for ( var i = 0; i < 2000; i ++ ) {
 
@@ -539,6 +539,6 @@ function TreesGeometry( landscape ) {
 	this.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) );
 	this.addAttribute( 'color', new THREE.BufferAttribute( new Float32Array( colors ), 3 ) );
 
-};
+}
 
 TreesGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );

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

@@ -393,7 +393,6 @@ THREE.CCDIKSolver = ( function () {
 		_init: function () {
 
 			var self = this;
-			var mesh = this.root;
 			var iks = this.iks;
 
 			function createLineGeometry( ik ) {

+ 2 - 3
examples/js/animation/MMDPhysics.js

@@ -746,8 +746,8 @@ THREE.MMDPhysics = ( function () {
 				s = Math.sqrt( t + 1.0 ) * 2;
 				w = 0.25 * s;
 				x = ( m[ 7 ] - m[ 5 ] ) / s;
-				y = ( m[ 2 ] - m[ 6 ] ) / s; 
-				z = ( m[ 3 ] - m[ 1 ] ) / s; 
+				y = ( m[ 2 ] - m[ 6 ] ) / s;
+				z = ( m[ 3 ] - m[ 1 ] ) / s;
 
 			} else if( ( m[ 0 ] > m[ 4 ] ) && ( m[ 0 ] > m[ 8 ] ) ) {
 
@@ -1348,7 +1348,6 @@ THREE.MMDPhysics = ( function () {
 
 		_init: function () {
 
-			var mesh = this.root;
 			var bodies = this.physics.bodies;
 
 			function createGeometry( param ) {

+ 3 - 4
examples/js/controls/EditorControls.js

@@ -14,7 +14,7 @@ THREE.EditorControls = function ( object, domElement ) {
 	this.enabled = true;
 	this.center = new THREE.Vector3();
 	this.panSpeed = 0.001;
-	this.zoomSpeed = 0.001;
+	this.zoomSpeed = 0.1;
 	this.rotationSpeed = 0.005;
 
 	// internals
@@ -187,9 +187,8 @@ THREE.EditorControls = function ( object, domElement ) {
 
 		event.preventDefault();
 
-		// if ( scope.enabled === false ) return;
-
-		scope.zoom( new THREE.Vector3( 0, 0, event.deltaY ) );
+		// Normalize deltaY due to https://bugzilla.mozilla.org/show_bug.cgi?id=1392460
+		scope.zoom( new THREE.Vector3( 0, 0, event.deltaY > 0 ? 1 : - 1 ) );
 
 	}
 

+ 1144 - 0
examples/js/controls/MapControls.js

@@ -0,0 +1,1144 @@
+/**
+ * @author qiao / https://github.com/qiao
+ * @author mrdoob / http://mrdoob.com
+ * @author alteredq / http://alteredqualia.com/
+ * @author WestLangley / http://github.com/WestLangley
+ * @author erich666 / http://erichaines.com
+ * @author moroine / https://github.com/moroine
+ */
+
+// This set of controls performs orbiting, dollying (zooming), and panning.
+// Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default).
+// This is very similar to OrbitControls, another set of touch behavior
+//
+//    Orbit - right mouse / touch: two-finger rotate
+//    Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish
+//    Pan - left mouse, or arrow keys / touch: one-finger move
+
+
+THREE.MapControls = function ( object, domElement ) {
+
+	this.object = object;
+
+	this.domElement = ( domElement !== undefined ) ? domElement : document;
+
+	// Set to false to disable this control
+	this.enabled = true;
+
+	// "target" sets the location of focus, where the object orbits around
+	this.target = new THREE.Vector3();
+
+	// How far you can dolly in and out ( PerspectiveCamera only )
+	this.minDistance = 0;
+	this.maxDistance = Infinity;
+
+	// How far you can zoom in and out ( OrthographicCamera only )
+	this.minZoom = 0;
+	this.maxZoom = Infinity;
+
+	// How far you can orbit vertically, upper and lower limits.
+	// Range is 0 to Math.PI radians.
+	this.minPolarAngle = 0; // radians
+	this.maxPolarAngle = Math.PI; // radians
+
+	// How far you can orbit horizontally, upper and lower limits.
+	// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].
+	this.minAzimuthAngle = - Infinity; // radians
+	this.maxAzimuthAngle = Infinity; // radians
+
+	// Set to true to enable damping (inertia)
+	// If damping is enabled, you must call controls.update() in your animation loop
+	this.enableDamping = false;
+	this.dampingFactor = 0.25;
+
+	// This option actually enables dollying in and out; left as "zoom" for backwards compatibility.
+	// Set to false to disable zooming
+	this.enableZoom = true;
+	this.zoomSpeed = 1.0;
+
+	// Set to false to disable rotating
+	this.enableRotate = true;
+	this.rotateSpeed = 1.0;
+
+	// Set to false to disable panning
+	this.enablePan = true;
+	this.panSpeed = 1.0;
+	this.screenSpacePanning = false; // if true, pan in screen-space
+	this.keyPanSpeed = 7.0;	// pixels moved per arrow key push
+
+	// Set to true to automatically rotate around the target
+	// If auto-rotate is enabled, you must call controls.update() in your animation loop
+	this.autoRotate = false;
+	this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60
+
+	// Set to false to disable use of the keys
+	this.enableKeys = true;
+
+	// The four arrow keys
+	this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };
+
+	// Mouse buttons
+	this.mouseButtons = { ORBIT: THREE.MOUSE.RIGHT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.LEFT };
+
+	// for reset
+	this.target0 = this.target.clone();
+	this.position0 = this.object.position.clone();
+	this.zoom0 = this.object.zoom;
+
+	//
+	// public methods
+	//
+
+	this.getPolarAngle = function () {
+
+		return spherical.phi;
+
+	};
+
+	this.getAzimuthalAngle = function () {
+
+		return spherical.theta;
+
+	};
+
+	this.saveState = function () {
+
+		scope.target0.copy( scope.target );
+		scope.position0.copy( scope.object.position );
+		scope.zoom0 = scope.object.zoom;
+
+	};
+
+	this.reset = function () {
+
+		scope.target.copy( scope.target0 );
+		scope.object.position.copy( scope.position0 );
+		scope.object.zoom = scope.zoom0;
+
+		scope.object.updateProjectionMatrix();
+		scope.dispatchEvent( changeEvent );
+
+		scope.update();
+
+		state = STATE.NONE;
+
+	};
+
+	// this method is exposed, but perhaps it would be better if we can make it private...
+	this.update = function () {
+
+		var offset = new THREE.Vector3();
+
+		// so camera.up is the orbit axis
+		var quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );
+		var quatInverse = quat.clone().inverse();
+
+		var lastPosition = new THREE.Vector3();
+		var lastQuaternion = new THREE.Quaternion();
+
+		return function update() {
+
+			var position = scope.object.position;
+
+			offset.copy( position ).sub( scope.target );
+
+			// rotate offset to "y-axis-is-up" space
+			offset.applyQuaternion( quat );
+
+			// angle from z-axis around y-axis
+			spherical.setFromVector3( offset );
+
+			if ( scope.autoRotate && state === STATE.NONE ) {
+
+				rotateLeft( getAutoRotationAngle() );
+
+			}
+
+			spherical.theta += sphericalDelta.theta;
+			spherical.phi += sphericalDelta.phi;
+
+			// restrict theta to be between desired limits
+			spherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );
+
+			// restrict phi to be between desired limits
+			spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );
+
+			spherical.makeSafe();
+
+
+			spherical.radius *= scale;
+
+			// restrict radius to be between desired limits
+			spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );
+
+			// move target to panned location
+			scope.target.add( panOffset );
+
+			offset.setFromSpherical( spherical );
+
+			// rotate offset back to "camera-up-vector-is-up" space
+			offset.applyQuaternion( quatInverse );
+
+			position.copy( scope.target ).add( offset );
+
+			scope.object.lookAt( scope.target );
+
+			if ( scope.enableDamping === true ) {
+
+				sphericalDelta.theta *= ( 1 - scope.dampingFactor );
+				sphericalDelta.phi *= ( 1 - scope.dampingFactor );
+
+				panOffset.multiplyScalar( 1 - scope.dampingFactor );
+
+			} else {
+
+				sphericalDelta.set( 0, 0, 0 );
+
+				panOffset.set( 0, 0, 0 );
+
+			}
+
+			scale = 1;
+
+			// update condition is:
+			// min(camera displacement, camera rotation in radians)^2 > EPS
+			// using small-angle approximation cos(x/2) = 1 - x^2 / 8
+
+			if ( zoomChanged ||
+				lastPosition.distanceToSquared( scope.object.position ) > EPS ||
+				8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {
+
+				scope.dispatchEvent( changeEvent );
+
+				lastPosition.copy( scope.object.position );
+				lastQuaternion.copy( scope.object.quaternion );
+				zoomChanged = false;
+
+				return true;
+
+			}
+
+			return false;
+
+		};
+
+	}();
+
+	this.dispose = function () {
+
+		scope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );
+		scope.domElement.removeEventListener( 'mousedown', onMouseDown, false );
+		scope.domElement.removeEventListener( 'wheel', onMouseWheel, false );
+
+		scope.domElement.removeEventListener( 'touchstart', onTouchStart, false );
+		scope.domElement.removeEventListener( 'touchend', onTouchEnd, false );
+		scope.domElement.removeEventListener( 'touchmove', onTouchMove, false );
+
+		document.removeEventListener( 'mousemove', onMouseMove, false );
+		document.removeEventListener( 'mouseup', onMouseUp, false );
+
+		window.removeEventListener( 'keydown', onKeyDown, false );
+
+		//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?
+
+	};
+
+	//
+	// internals
+	//
+
+	var scope = this;
+
+	var changeEvent = { type: 'change' };
+	var startEvent = { type: 'start' };
+	var endEvent = { type: 'end' };
+
+	var STATE = {
+		NONE: 0,
+		ROTATE_UP: 1,
+		ROTATE_LEFT: 2,
+		ROTATE: 3, // ROTATE_UP | ROTATE_LEFT
+		DOLLY: 4,
+		DOLLY_ROTATE: 7, // ROTATE | DOLLY
+		PAN: 8,
+		DOLLY_PAN: 12, // DOLLY | PAN
+	};
+
+	var state = STATE.NONE;
+
+	var EPS = 0.000001;
+
+	// current position in spherical coordinates
+	var spherical = new THREE.Spherical();
+	var sphericalDelta = new THREE.Spherical();
+
+	var scale = 1;
+	var panOffset = new THREE.Vector3();
+	var zoomChanged = false;
+
+	var rotateStart = new THREE.Vector2();
+	var rotateStart2 = new THREE.Vector2();
+	var rotateEnd = new THREE.Vector2();
+	var rotateEnd2 = new THREE.Vector2();
+	var rotateDelta = new THREE.Vector2();
+	var rotateDelta2 = new THREE.Vector2();
+	var rotateDeltaStartFingers = new THREE.Vector2();
+	var rotateDeltaEndFingers = new THREE.Vector2();
+
+	var panStart = new THREE.Vector2();
+	var panEnd = new THREE.Vector2();
+	var panDelta = new THREE.Vector2();
+
+	var dollyStart = new THREE.Vector2();
+	var dollyEnd = new THREE.Vector2();
+	var dollyDelta = new THREE.Vector2();
+
+	function getAutoRotationAngle() {
+
+		return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
+
+	}
+
+	function getZoomScale() {
+
+		return Math.pow( 0.95, scope.zoomSpeed );
+
+	}
+
+	function rotateLeft( angle ) {
+
+		sphericalDelta.theta -= angle;
+
+	}
+
+	function rotateUp( angle ) {
+
+		sphericalDelta.phi -= angle;
+
+	}
+
+	var panLeft = function () {
+
+		var v = new THREE.Vector3();
+
+		return function panLeft( distance, objectMatrix ) {
+
+			v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix
+			v.multiplyScalar( - distance );
+
+			panOffset.add( v );
+
+		};
+
+	}();
+
+	var panUp = function () {
+
+		var v = new THREE.Vector3();
+
+		return function panUp( distance, objectMatrix ) {
+
+			if ( scope.screenSpacePanning === true ) {
+
+				v.setFromMatrixColumn( objectMatrix, 1 );
+
+			} else {
+
+				v.setFromMatrixColumn( objectMatrix, 0 );
+				v.crossVectors( scope.object.up, v );
+
+			}
+
+			v.multiplyScalar( distance );
+
+			panOffset.add( v );
+
+		};
+
+	}();
+
+	// deltaX and deltaY are in pixels; right and down are positive
+	var pan = function () {
+
+		var offset = new THREE.Vector3();
+
+		return function pan( deltaX, deltaY ) {
+
+			var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
+
+			if ( scope.object.isPerspectiveCamera ) {
+
+				// perspective
+				var position = scope.object.position;
+				offset.copy( position ).sub( scope.target );
+				var targetDistance = offset.length();
+
+				// half of the fov is center to top of screen
+				targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );
+
+				// we use only clientHeight here so aspect ratio does not distort speed
+				panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );
+				panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );
+
+			} else if ( scope.object.isOrthographicCamera ) {
+
+				// orthographic
+				panLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );
+				panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );
+
+			} else {
+
+				// camera neither orthographic nor perspective
+				console.warn( 'WARNING: MapControls.js encountered an unknown camera type - pan disabled.' );
+				scope.enablePan = false;
+
+			}
+
+		};
+
+	}();
+
+	function dollyIn( dollyScale ) {
+
+		if ( scope.object.isPerspectiveCamera ) {
+
+			scale /= dollyScale;
+
+		} else if ( scope.object.isOrthographicCamera ) {
+
+			scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );
+			scope.object.updateProjectionMatrix();
+			zoomChanged = true;
+
+		} else {
+
+			console.warn( 'WARNING: MapControls.js encountered an unknown camera type - dolly/zoom disabled.' );
+			scope.enableZoom = false;
+
+		}
+
+	}
+
+	function dollyOut( dollyScale ) {
+
+		if ( scope.object.isPerspectiveCamera ) {
+
+			scale *= dollyScale;
+
+		} else if ( scope.object.isOrthographicCamera ) {
+
+			scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );
+			scope.object.updateProjectionMatrix();
+			zoomChanged = true;
+
+		} else {
+
+			console.warn( 'WARNING: MapControls.js encountered an unknown camera type - dolly/zoom disabled.' );
+			scope.enableZoom = false;
+
+		}
+
+	}
+
+	//
+	// event callbacks - update the object state
+	//
+
+	function handleMouseDownRotate( event ) {
+
+		//console.log( 'handleMouseDownRotate' );
+
+		rotateStart.set( event.clientX, event.clientY );
+
+	}
+
+	function handleMouseDownDolly( event ) {
+
+		//console.log( 'handleMouseDownDolly' );
+
+		dollyStart.set( event.clientX, event.clientY );
+
+	}
+
+	function handleMouseDownPan( event ) {
+
+		//console.log( 'handleMouseDownPan' );
+
+		panStart.set( event.clientX, event.clientY );
+
+	}
+
+	function handleMouseMoveRotate( event ) {
+
+		//console.log( 'handleMouseMoveRotate' );
+
+		rotateEnd.set( event.clientX, event.clientY );
+
+		rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );
+
+		var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
+
+		rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height
+
+		rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight );
+
+		rotateStart.copy( rotateEnd );
+
+		scope.update();
+
+	}
+
+	function handleMouseMoveDolly( event ) {
+
+		//console.log( 'handleMouseMoveDolly' );
+
+		dollyEnd.set( event.clientX, event.clientY );
+
+		dollyDelta.subVectors( dollyEnd, dollyStart );
+
+		if ( dollyDelta.y > 0 ) {
+
+			dollyIn( getZoomScale() );
+
+		} else if ( dollyDelta.y < 0 ) {
+
+			dollyOut( getZoomScale() );
+
+		}
+
+		dollyStart.copy( dollyEnd );
+
+		scope.update();
+
+	}
+
+	function handleMouseMovePan( event ) {
+
+		//console.log( 'handleMouseMovePan' );
+
+		panEnd.set( event.clientX, event.clientY );
+
+		panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );
+
+		pan( panDelta.x, panDelta.y );
+
+		panStart.copy( panEnd );
+
+		scope.update();
+
+	}
+
+	function handleMouseUp( event ) {
+
+		// console.log( 'handleMouseUp' );
+
+	}
+
+	function handleMouseWheel( event ) {
+
+		// console.log( 'handleMouseWheel' );
+
+		if ( event.deltaY < 0 ) {
+
+			dollyOut( getZoomScale() );
+
+		} else if ( event.deltaY > 0 ) {
+
+			dollyIn( getZoomScale() );
+
+		}
+
+		scope.update();
+
+	}
+
+	function handleKeyDown( event ) {
+
+		//console.log( 'handleKeyDown' );
+
+		switch ( event.keyCode ) {
+
+			case scope.keys.UP:
+				pan( 0, scope.keyPanSpeed );
+				scope.update();
+				break;
+
+			case scope.keys.BOTTOM:
+				pan( 0, - scope.keyPanSpeed );
+				scope.update();
+				break;
+
+			case scope.keys.LEFT:
+				pan( scope.keyPanSpeed, 0 );
+				scope.update();
+				break;
+
+			case scope.keys.RIGHT:
+				pan( - scope.keyPanSpeed, 0 );
+				scope.update();
+				break;
+
+		}
+
+	}
+
+	function handleTouchStartRotate( event ) {
+
+		// console.log( 'handleTouchStartRotate' );
+
+		// First finger
+		rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
+
+		// Second finger
+		rotateStart2.set( event.touches[ 1 ].pageX, event.touches[ 1 ].pageY );
+
+	}
+
+	function handleTouchStartDolly( event ) {
+
+		if ( scope.enableZoom ) {
+
+			// console.log( 'handleTouchStartDolly' );
+
+			var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
+			var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
+
+			var distance = Math.sqrt( dx * dx + dy * dy );
+
+			dollyStart.set( 0, distance );
+
+		}
+
+	}
+
+	function handleTouchStartPan( event ) {
+
+		if ( scope.enablePan ) {
+
+			// console.log( 'handleTouchStartPan' );
+
+			panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
+
+		}
+
+	}
+
+	function handleTouchMoveRotate( event ) {
+
+		if ( scope.enableRotate === false ) return;
+		if ( ( state & STATE.ROTATE ) === 0 ) return;
+
+		// First finger
+		rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
+
+		// Second finger
+		rotateEnd2.set( event.touches[ 1 ].pageX, event.touches[ 1 ].pageY );
+
+		rotateDelta.subVectors( rotateEnd, rotateStart );
+		rotateDelta2.subVectors( rotateEnd2, rotateStart2 );
+		rotateDeltaStartFingers.subVectors( rotateStart2, rotateStart );
+		rotateDeltaEndFingers.subVectors( rotateEnd2, rotateEnd );
+
+		if ( isRotateUp() ) {
+
+			var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
+
+			// rotating up and down along whole screen attempts to go 360, but limited to 180
+			rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight );
+
+			// Start rotateUp ==> disable all movement to prevent flickering
+			state = STATE.ROTATE_UP;
+
+		} else if ( ( state & STATE.ROTATE_LEFT ) !== 0 ) {
+
+			rotateLeft( ( rotateDeltaStartFingers.angle() - rotateDeltaEndFingers.angle() ) * scope.rotateSpeed );
+
+		}
+
+		rotateStart.copy( rotateEnd );
+		rotateStart2.copy( rotateEnd2 );
+
+	}
+
+	function isRotateUp() {
+
+		// At start, does the two fingers are aligned horizontally
+		if ( ! isHorizontal( rotateDeltaStartFingers ) ) {
+
+			return false;
+
+		}
+
+		// At end, does the two fingers are aligned horizontally
+		if ( ! isHorizontal( rotateDeltaEndFingers ) ) {
+
+			return false;
+
+		}
+
+		// does the first finger moved vertically between start and end
+		if ( ! isVertical( rotateDelta ) ) {
+
+			return false;
+
+		}
+
+		// does the second finger moved vertically between start and end
+		if ( ! isVertical( rotateDelta2 ) ) {
+
+			return false;
+
+		}
+
+		// Does the two finger moved in the same direction (prevent moving one finger vertically up while the other goes down)
+		return rotateDelta.dot( rotateDelta2 ) > 0;
+
+	}
+
+	var isHorizontal = function () {
+
+		var precision = Math.sin( Math.PI / 6 );
+
+		return function isHorizontal( vector ) {
+
+			return Math.abs( Math.sin( vector.angle() ) ) < precision;
+
+		};
+
+	}();
+
+	var isVertical = function () {
+
+		var precision = Math.cos( Math.PI / 2 - Math.PI / 6 );
+
+		return function isVertical( vector ) {
+
+			return Math.abs( Math.cos( vector.angle() ) ) < precision;
+
+		};
+
+	}();
+
+	function handleTouchMoveDolly( event ) {
+
+		if ( scope.enableZoom === false ) return;
+		if ( ( state & STATE.DOLLY ) === 0 ) return;
+
+		// console.log( 'handleTouchMoveDolly' );
+
+		var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
+		var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
+
+		var distance = Math.sqrt( dx * dx + dy * dy );
+
+		dollyEnd.set( 0, distance );
+
+		dollyDelta.set( 0, Math.pow( dollyEnd.y / dollyStart.y, scope.zoomSpeed ) );
+
+		dollyIn( dollyDelta.y );
+
+		dollyStart.copy( dollyEnd );
+
+	}
+
+	function handleTouchMovePan( event ) {
+
+		if ( scope.enablePan === false ) return;
+		if ( ( state & STATE.PAN ) === 0 ) return;
+
+		// console.log( 'handleTouchMovePan' );
+
+		panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
+
+		panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );
+
+		pan( panDelta.x, panDelta.y );
+
+		panStart.copy( panEnd );
+
+	}
+
+	function handleTouchEnd( event ) {
+
+		//console.log( 'handleTouchEnd' );
+
+	}
+
+	//
+	// event handlers - FSM: listen for events and reset state
+	//
+
+	function onMouseDown( event ) {
+
+		if ( scope.enabled === false ) return;
+
+		event.preventDefault();
+
+		switch ( event.button ) {
+
+			case scope.mouseButtons.ORBIT:
+
+				if ( scope.enableRotate === false ) return;
+
+				handleMouseDownRotate( event );
+
+				state = STATE.ROTATE;
+
+				break;
+
+			case scope.mouseButtons.ZOOM:
+
+				if ( scope.enableZoom === false ) return;
+
+				handleMouseDownDolly( event );
+
+				state = STATE.DOLLY;
+
+				break;
+
+			case scope.mouseButtons.PAN:
+
+				if ( scope.enablePan === false ) return;
+
+				handleMouseDownPan( event );
+
+				state = STATE.PAN;
+
+				break;
+
+		}
+
+		if ( state !== STATE.NONE ) {
+
+			document.addEventListener( 'mousemove', onMouseMove, false );
+			document.addEventListener( 'mouseup', onMouseUp, false );
+
+			scope.dispatchEvent( startEvent );
+
+		}
+
+	}
+
+	function onMouseMove( event ) {
+
+		if ( scope.enabled === false ) return;
+
+		event.preventDefault();
+
+		switch ( state ) {
+
+			case STATE.ROTATE:
+
+				if ( scope.enableRotate === false ) return;
+
+				handleMouseMoveRotate( event );
+
+				break;
+
+			case STATE.DOLLY:
+
+				if ( scope.enableZoom === false ) return;
+
+				handleMouseMoveDolly( event );
+
+				break;
+
+			case STATE.PAN:
+
+				if ( scope.enablePan === false ) return;
+
+				handleMouseMovePan( event );
+
+				break;
+
+		}
+
+	}
+
+	function onMouseUp( event ) {
+
+		if ( scope.enabled === false ) return;
+
+		handleMouseUp( event );
+
+		document.removeEventListener( 'mousemove', onMouseMove, false );
+		document.removeEventListener( 'mouseup', onMouseUp, false );
+
+		scope.dispatchEvent( endEvent );
+
+		state = STATE.NONE;
+
+	}
+
+	function onMouseWheel( event ) {
+
+		if ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return;
+
+		event.preventDefault();
+		event.stopPropagation();
+
+		scope.dispatchEvent( startEvent );
+
+		handleMouseWheel( event );
+
+		scope.dispatchEvent( endEvent );
+
+	}
+
+	function onKeyDown( event ) {
+
+		if ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;
+
+		handleKeyDown( event );
+
+	}
+
+	function onTouchStart( event ) {
+
+		if ( scope.enabled === false ) return;
+
+		event.preventDefault();
+
+		switch ( event.touches.length ) {
+
+			case 1:	// one-fingered touch: pan
+
+				if ( scope.enablePan === false ) return;
+
+				handleTouchStartPan( event );
+
+				state = STATE.PAN;
+
+				break;
+
+			case 2:	// two-fingered touch: rotate-dolly
+
+				if ( scope.enableZoom === false && scope.enableRotate === false ) return;
+
+				handleTouchStartRotate( event );
+				handleTouchStartDolly( event );
+
+				state = STATE.DOLLY_ROTATE;
+
+				break;
+
+			default:
+
+				state = STATE.NONE;
+
+		}
+
+		if ( state !== STATE.NONE ) {
+
+			scope.dispatchEvent( startEvent );
+
+		}
+
+	}
+
+	function onTouchMove( event ) {
+
+		if ( scope.enabled === false ) return;
+
+		event.preventDefault();
+		event.stopPropagation();
+
+		switch ( event.touches.length ) {
+
+			case 1: // one-fingered touch: pan
+
+				if ( scope.enablePan === false ) return;
+				if ( state !== STATE.PAN ) return; // is this needed?
+
+				handleTouchMovePan( event );
+
+				scope.update();
+
+				break;
+
+			case 2: // two-fingered touch: rotate-dolly
+
+				if ( scope.enableZoom === false && scope.enableRotate === false ) return;
+				if ( ( state & STATE.DOLLY_ROTATE ) === 0 ) return; // is this needed?
+
+				handleTouchMoveRotate( event );
+				handleTouchMoveDolly( event );
+
+				scope.update();
+
+				break;
+
+			default:
+
+				state = STATE.NONE;
+
+		}
+
+	}
+
+	function onTouchEnd( event ) {
+
+		if ( scope.enabled === false ) return;
+
+		handleTouchEnd( event );
+
+		scope.dispatchEvent( endEvent );
+
+		state = STATE.NONE;
+
+	}
+
+	function onContextMenu( event ) {
+
+		if ( scope.enabled === false ) return;
+
+		event.preventDefault();
+
+	}
+
+	//
+
+	scope.domElement.addEventListener( 'contextmenu', onContextMenu, false );
+
+	scope.domElement.addEventListener( 'mousedown', onMouseDown, false );
+	scope.domElement.addEventListener( 'wheel', onMouseWheel, false );
+
+	scope.domElement.addEventListener( 'touchstart', onTouchStart, false );
+	scope.domElement.addEventListener( 'touchend', onTouchEnd, false );
+	scope.domElement.addEventListener( 'touchmove', onTouchMove, false );
+
+	window.addEventListener( 'keydown', onKeyDown, false );
+
+	// force an update at start
+
+	this.update();
+
+};
+
+THREE.MapControls.prototype = Object.create( THREE.EventDispatcher.prototype );
+THREE.MapControls.prototype.constructor = THREE.MapControls;
+
+Object.defineProperties( THREE.MapControls.prototype, {
+
+	center: {
+
+		get: function () {
+
+			console.warn( 'THREE.MapControls: .center has been renamed to .target' );
+			return this.target;
+
+		}
+
+	},
+
+	// backward compatibility
+
+	noZoom: {
+
+		get: function () {
+
+			console.warn( 'THREE.MapControls: .noZoom has been deprecated. Use .enableZoom instead.' );
+			return ! this.enableZoom;
+
+		},
+
+		set: function ( value ) {
+
+			console.warn( 'THREE.MapControls: .noZoom has been deprecated. Use .enableZoom instead.' );
+			this.enableZoom = ! value;
+
+		}
+
+	},
+
+	noRotate: {
+
+		get: function () {
+
+			console.warn( 'THREE.MapControls: .noRotate has been deprecated. Use .enableRotate instead.' );
+			return ! this.enableRotate;
+
+		},
+
+		set: function ( value ) {
+
+			console.warn( 'THREE.MapControls: .noRotate has been deprecated. Use .enableRotate instead.' );
+			this.enableRotate = ! value;
+
+		}
+
+	},
+
+	noPan: {
+
+		get: function () {
+
+			console.warn( 'THREE.MapControls: .noPan has been deprecated. Use .enablePan instead.' );
+			return ! this.enablePan;
+
+		},
+
+		set: function ( value ) {
+
+			console.warn( 'THREE.MapControls: .noPan has been deprecated. Use .enablePan instead.' );
+			this.enablePan = ! value;
+
+		}
+
+	},
+
+	noKeys: {
+
+		get: function () {
+
+			console.warn( 'THREE.MapControls: .noKeys has been deprecated. Use .enableKeys instead.' );
+			return ! this.enableKeys;
+
+		},
+
+		set: function ( value ) {
+
+			console.warn( 'THREE.MapControls: .noKeys has been deprecated. Use .enableKeys instead.' );
+			this.enableKeys = ! value;
+
+		}
+
+	},
+
+	staticMoving: {
+
+		get: function () {
+
+			console.warn( 'THREE.MapControls: .staticMoving has been deprecated. Use .enableDamping instead.' );
+			return ! this.enableDamping;
+
+		},
+
+		set: function ( value ) {
+
+			console.warn( 'THREE.MapControls: .staticMoving has been deprecated. Use .enableDamping instead.' );
+			this.enableDamping = ! value;
+
+		}
+
+	},
+
+	dynamicDampingFactor: {
+
+		get: function () {
+
+			console.warn( 'THREE.MapControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );
+			return this.dampingFactor;
+
+		},
+
+		set: function ( value ) {
+
+			console.warn( 'THREE.MapControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );
+			this.dampingFactor = value;
+
+		}
+
+	}
+
+} );

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

+ 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 );
-
-	}
-
-};

+ 38 - 19
examples/js/exporters/GLTFExporter.js

@@ -106,7 +106,8 @@ THREE.GLTFExporter.prototype = {
 
 			attributes: new Map(),
 			materials: new Map(),
-			textures: new Map()
+			textures: new Map(),
+			images: new Map()
 
 		};
 
@@ -243,7 +244,7 @@ THREE.GLTFExporter.prototype = {
 
 			if ( cachedData.attributes.has( normal ) ) {
 
-				return cachedData.textures.get( normal );
+				return cachedData.attributes.get( normal );
 
 			}
 
@@ -565,8 +566,8 @@ THREE.GLTFExporter.prototype = {
 
 				var end = start + count;
 				var end2 = geometry.drawRange.count === Infinity
-						? attribute.count
-						: geometry.drawRange.start + geometry.drawRange.count;
+					? attribute.count
+					: geometry.drawRange.start + geometry.drawRange.count;
 
 				start = Math.max( start, geometry.drawRange.start );
 				count = Math.min( end, end2 ) - start;
@@ -622,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, {} );
+
+			}
+
+			var cachedImages = cachedData.images.get( image );
+			var mimeType = format === THREE.RGBAFormat ? 'image/png' : 'image/jpeg';
+			var key = mimeType + ":flipY/" + flipY.toString();
 
-			// @TODO Cache
+			if ( cachedImages[ key ] !== undefined ) {
+
+				return cachedImages[ key ];
+
+			}
 
 			if ( ! outputJSON.images ) {
 
@@ -635,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 );
@@ -656,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 ) {
 
@@ -691,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;
 
 		}
 
@@ -751,7 +770,7 @@ THREE.GLTFExporter.prototype = {
 			var gltfTexture = {
 
 				sampler: processSampler( map ),
-				source: processImage( map )
+				source: processImage( map.image, map.format, map.flipY )
 
 			};
 
@@ -1187,7 +1206,7 @@ THREE.GLTFExporter.prototype = {
 			var forceIndices = options.forceIndices;
 			var isMultiMaterial = Array.isArray( mesh.material );
 
-			if ( isMultiMaterial && mesh.geometry.groups.length === 0 ) return null;
+			if ( isMultiMaterial && geometry.groups.length === 0 ) return null;
 
 			if ( ! forceIndices && geometry.index === null && isMultiMaterial ) {
 
@@ -1216,7 +1235,7 @@ THREE.GLTFExporter.prototype = {
 			}
 
 			var materials = isMultiMaterial ? mesh.material : [ mesh.material ];
-			var groups = isMultiMaterial ? mesh.geometry.groups : [ { materialIndex: 0, start: undefined, count: undefined } ];
+			var groups = isMultiMaterial ? geometry.groups : [ { materialIndex: 0, start: undefined, count: undefined } ];
 
 			for ( var i = 0, il = groups.length; i < il; i ++ ) {
 

+ 0 - 646
examples/js/libs/msgpack-js.js

@@ -1,646 +0,0 @@
-/* jshint browser: true */
-/* global define, module */
-( // Module boilerplate to support browser globals and browserify and AMD.
-  typeof define === "function" ? function (m) { define("msgpack-js", m); } :
-  typeof exports === "object" ? function (m) { module.exports = m(); } :
-  function(m){ this.msgpack = m(); }
-)(function () {
-"use strict";
-
-var exports = {};
-
-exports.inspect = inspect;
-function inspect(buffer) {
-  if (buffer === undefined) return "undefined";
-  var view;
-  var type;
-  if (buffer instanceof ArrayBuffer) {
-    type = "ArrayBuffer";
-    view = new DataView(buffer);
-  }
-  else if (buffer instanceof DataView) {
-    type = "DataView";
-    view = buffer;
-  }
-  if (!view) return JSON.stringify(buffer);
-  var bytes = [];
-  for (var i = 0; i < buffer.byteLength; i++) {
-    if (i > 20) {
-      bytes.push("...");
-      break;
-    }
-    var byte = view.getUint8(i).toString(16);
-    if (byte.length === 1) byte = "0" + byte;
-    bytes.push(byte);
-  }
-  return "<" + type + " " + bytes.join(" ") + ">";
-}
-
-// Encode string as utf8 into dataview at offset
-exports.utf8Write = utf8Write;
-function utf8Write(view, offset, string) {
-  var byteLength = view.byteLength;
-  for(var i = 0, l = string.length; i < l; i++) {
-    var codePoint = string.charCodeAt(i);
-
-    // One byte of UTF-8
-    if (codePoint < 0x80) {
-      view.setUint8(offset++, codePoint >>> 0 & 0x7f | 0x00);
-      continue;
-    }
-
-    // Two bytes of UTF-8
-    if (codePoint < 0x800) {
-      view.setUint8(offset++, codePoint >>> 6 & 0x1f | 0xc0);
-      view.setUint8(offset++, codePoint >>> 0 & 0x3f | 0x80);
-      continue;
-    }
-
-    // Three bytes of UTF-8.
-    if (codePoint < 0x10000) {
-      view.setUint8(offset++, codePoint >>> 12 & 0x0f | 0xe0);
-      view.setUint8(offset++, codePoint >>> 6  & 0x3f | 0x80);
-      view.setUint8(offset++, codePoint >>> 0  & 0x3f | 0x80);
-      continue;
-    }
-
-    // Four bytes of UTF-8
-    if (codePoint < 0x110000) {
-      view.setUint8(offset++, codePoint >>> 18 & 0x07 | 0xf0);
-      view.setUint8(offset++, codePoint >>> 12 & 0x3f | 0x80);
-      view.setUint8(offset++, codePoint >>> 6  & 0x3f | 0x80);
-      view.setUint8(offset++, codePoint >>> 0  & 0x3f | 0x80);
-      continue;
-    }
-    throw new Error("bad codepoint " + codePoint);
-  }
-}
-
-exports.utf8Read = utf8Read;
-function utf8Read(view, offset, length) {
-  var string = "";
-  for (var i = offset, end = offset + length; i < end; i++) {
-    var byte = view.getUint8(i);
-    // One byte character
-    if ((byte & 0x80) === 0x00) {
-      string += String.fromCharCode(byte);
-      continue;
-    }
-    // Two byte character
-    if ((byte & 0xe0) === 0xc0) {
-      string += String.fromCharCode(
-        ((byte & 0x1f) << 6) |
-        (view.getUint8(++i) & 0x3f)
-      );
-      continue;
-    }
-    // Three byte character
-    if ((byte & 0xf0) === 0xe0) {
-      string += String.fromCharCode(
-        ((byte & 0x0f) << 12) |
-        ((view.getUint8(++i) & 0x3f) << 6) |
-        ((view.getUint8(++i) & 0x3f) << 0)
-      );
-      continue;
-    }
-    // Four byte character
-    if ((byte & 0xf8) === 0xf0) {
-      string += String.fromCharCode(
-        ((byte & 0x07) << 18) |
-        ((view.getUint8(++i) & 0x3f) << 12) |
-        ((view.getUint8(++i) & 0x3f) << 6) |
-        ((view.getUint8(++i) & 0x3f) << 0)
-      );
-      continue;
-    }
-    throw new Error("Invalid byte " + byte.toString(16));
-  }
-  return string;
-}
-
-exports.utf8ByteCount = utf8ByteCount;
-function utf8ByteCount(string) {
-  var count = 0;
-  for(var i = 0, l = string.length; i < l; i++) {
-    var codePoint = string.charCodeAt(i);
-    if (codePoint < 0x80) {
-      count += 1;
-      continue;
-    }
-    if (codePoint < 0x800) {
-      count += 2;
-      continue;
-    }
-    if (codePoint < 0x10000) {
-      count += 3;
-      continue;
-    }
-    if (codePoint < 0x110000) {
-      count += 4;
-      continue;
-    }
-    throw new Error("bad codepoint " + codePoint);
-  }
-  return count;
-}
-
-exports.encode = function (value) {
-  var buffer = new ArrayBuffer(encodedSize(value));
-  var view = new DataView(buffer);
-  encode(value, view, 0);
-  return buffer;
-};
-
-exports.decode = decode;
-
-// https://github.com/msgpack/msgpack/blob/master/spec.md
-// we reserve extension type 0x00 to encode javascript 'undefined'
-
-function Decoder(view, offset) {
-  this.offset = offset || 0;
-  this.view = view;
-}
-Decoder.prototype.map = function (length) {
-  var value = {};
-  for (var i = 0; i < length; i++) {
-    var key = this.parse();
-    value[key] = this.parse();
-  }
-  return value;
-};
-Decoder.prototype.bin = function (length) {
-  var value = new ArrayBuffer(length);
-  (new Uint8Array(value)).set(new Uint8Array(this.view.buffer, this.offset, length), 0);
-  this.offset += length;
-  return value;
-};
-Decoder.prototype.str = function (length) {
-  var value = utf8Read(this.view, this.offset, length);
-  this.offset += length;
-  return value;
-};
-Decoder.prototype.array = function (length) {
-  var value = new Array(length);
-  for (var i = 0; i < length; i++) {
-    value[i] = this.parse();
-  }
-  return value;
-};
-Decoder.prototype.parse = function () {
-  var type = this.view.getUint8(this.offset);
-  var value, length;
-  // FixStr
-  if ((type & 0xe0) === 0xa0) {
-    length = type & 0x1f;
-    this.offset++;
-    return this.str(length);
-  }
-  // FixMap
-  if ((type & 0xf0) === 0x80) {
-    length = type & 0x0f;
-    this.offset++;
-    return this.map(length);
-  }
-  // FixArray
-  if ((type & 0xf0) === 0x90) {
-    length = type & 0x0f;
-    this.offset++;
-    return this.array(length);
-  }
-  // Positive FixNum
-  if ((type & 0x80) === 0x00) {
-    this.offset++;
-    return type;
-  }
-  // Negative Fixnum
-  if ((type & 0xe0) === 0xe0) {
-    value = this.view.getInt8(this.offset);
-    this.offset++;
-    return value;
-  }
-  // Undefined as FixExt1
-  if (type === 0xd4 && this.view.getUint8(this.offset + 1) === 0x00) {
-    this.offset += 3;
-    return undefined;
-  }
-  switch (type) {
-  // str 8
-  case 0xd9:
-    length = this.view.getUint8(this.offset + 1);
-    this.offset += 2;
-    return this.str(length);
-  // str 16
-  case 0xda:
-    length = this.view.getUint16(this.offset + 1);
-    this.offset += 3;
-    return this.str(length);
-  // str 32
-  case 0xdb:
-    length = this.view.getUint32(this.offset + 1);
-    this.offset += 5;
-    return this.str(length);
-  // bin 8
-  case 0xc4:
-    length = this.view.getUint8(this.offset + 1);
-    this.offset += 2;
-    return this.bin(length);
-  // bin 16
-  case 0xc5:
-    length = this.view.getUint16(this.offset + 1);
-    this.offset += 3;
-    return this.bin(length);
-  // bin 32
-  case 0xc6:
-    length = this.view.getUint32(this.offset + 1);
-    this.offset += 5;
-    return this.bin(length);
-  // nil
-  case 0xc0:
-    this.offset++;
-    return null;
-  // false
-  case 0xc2:
-    this.offset++;
-    return false;
-  // true
-  case 0xc3:
-    this.offset++;
-    return true;
-  // uint8
-  case 0xcc:
-    value = this.view.getUint8(this.offset + 1);
-    this.offset += 2;
-    return value;
-  // uint 16
-  case 0xcd:
-    value = this.view.getUint16(this.offset + 1);
-    this.offset += 3;
-    return value;
-  // uint 32
-  case 0xce:
-    value = this.view.getUint32(this.offset + 1);
-    this.offset += 5;
-    return value;
-  // uint 64
-  case 0xcf:
-    var high = this.view.getUint32(this.offset + 1);
-    var low = this.view.getUint32(this.offset + 5);
-    value = high*0x100000000 + low;
-    this.offset += 9;
-    return value;
-  // int 8
-  case 0xd0:
-    value = this.view.getInt8(this.offset + 1);
-    this.offset += 2;
-    return value;
-  // int 16
-  case 0xd1:
-    value = this.view.getInt16(this.offset + 1);
-    this.offset += 3;
-    return value;
-  // int 32
-  case 0xd2:
-    value = this.view.getInt32(this.offset + 1);
-    this.offset += 5;
-    return value;
-  // int 64
-  case 0xd3:
-    var high = this.view.getInt32(this.offset + 1);
-    var low = this.view.getUint32(this.offset + 5);
-    value = high*0x100000000 + low;
-    this.offset += 9;
-    return value;
-  // map 16
-  case 0xde:
-    length = this.view.getUint16(this.offset + 1);
-    this.offset += 3;
-    return this.map(length);
-  // map 32
-  case 0xdf:
-    length = this.view.getUint32(this.offset + 1);
-    this.offset += 5;
-    return this.map(length);
-  // array 16
-  case 0xdc:
-    length = this.view.getUint16(this.offset + 1);
-    this.offset += 3;
-    return this.array(length);
-  // array 32
-  case 0xdd:
-    length = this.view.getUint32(this.offset + 1);
-    this.offset += 5;
-    return this.array(length);
-  // float
-  case 0xca:
-    value = this.view.getFloat32(this.offset + 1);
-    this.offset += 5;
-    return value;
-  // double
-  case 0xcb:
-    value = this.view.getFloat64(this.offset + 1);
-    this.offset += 9;
-    return value;
-  }
-  throw new Error("Unknown type 0x" + type.toString(16));
-};
-function decode(buffer) {
-  var view = new DataView(buffer);
-  var decoder = new Decoder(view);
-  var value = decoder.parse();
-  if (decoder.offset !== buffer.byteLength) throw new Error((buffer.byteLength - decoder.offset) + " trailing bytes");
-  return value;
-}
-
-function encode(value, view, offset) {
-  var type = typeof value;
-
-  // Strings Bytes
-  if (type === "string") {
-    var length = utf8ByteCount(value);
-    // fix str
-    if (length < 0x20) {
-      view.setUint8(offset, length | 0xa0);
-      utf8Write(view, offset + 1, value);
-      return 1 + length;
-    }
-    // str 8
-    if (length < 0x100) {
-      view.setUint8(offset, 0xd9);
-      view.setUint8(offset + 1, length);
-      utf8Write(view, offset + 2, value);
-      return 2 + length;
-    }
-    // str 16
-    if (length < 0x10000) {
-      view.setUint8(offset, 0xda);
-      view.setUint16(offset + 1, length);
-      utf8Write(view, offset + 3, value);
-      return 3 + length;
-    }
-    // str 32
-    if (length < 0x100000000) {
-      view.setUint8(offset, 0xdb);
-      view.setUint32(offset + 1, length);
-      utf8Write(view, offset + 5, value);
-      return 5 + length;
-    }
-  }
-
-  if (value instanceof ArrayBuffer) {
-    var length = value.byteLength;
-    // bin 8
-    if (length < 0x100) {
-      view.setUint8(offset, 0xc4);
-      view.setUint8(offset + 1, length);
-      (new Uint8Array(view.buffer)).set(new Uint8Array(value), offset + 2);
-      return 2 + length;
-    }
-    // bin 16
-    if (length < 0x10000) {
-      view.setUint8(offset, 0xc5);
-      view.setUint16(offset + 1, length);
-      (new Uint8Array(view.buffer)).set(new Uint8Array(value), offset + 3);
-      return 3 + length;
-    }
-    // bin 32
-    if (length < 0x100000000) {
-      view.setUint8(offset, 0xc6);
-      view.setUint32(offset + 1, length);
-      (new Uint8Array(view.buffer)).set(new Uint8Array(value), offset + 5);
-      return 5 + length;
-    }
-  }
-
-  if (type === "number") {
-    // Floating Point
-    if ((value << 0) !== value) {
-      view.setUint8(offset, 0xcb);
-      view.setFloat64(offset + 1, value);
-      return 9;
-    }
-
-    // Integers
-    if (value >=0) {
-      // positive fixnum
-      if (value < 0x80) {
-        view.setUint8(offset, value);
-        return 1;
-      }
-      // uint 8
-      if (value < 0x100) {
-        view.setUint8(offset, 0xcc);
-        view.setUint8(offset + 1, value);
-        return 2;
-      }
-      // uint 16
-      if (value < 0x10000) {
-        view.setUint8(offset, 0xcd);
-        view.setUint16(offset + 1, value);
-        return 3;
-      }
-      // uint 32
-      if (value < 0x100000000) {
-        view.setUint8(offset, 0xce);
-        view.setUint32(offset + 1, value);
-        return 5;
-      }
-      throw new Error("Number too big 0x" + value.toString(16));
-    }
-    // negative fixnum
-    if (value >= -0x20) {
-      view.setInt8(offset, value);
-      return 1;
-    }
-    // int 8
-    if (value >= -0x80) {
-      view.setUint8(offset, 0xd0);
-      view.setInt8(offset + 1, value);
-      return 2;
-    }
-    // int 16
-    if (value >= -0x8000) {
-      view.setUint8(offset, 0xd1);
-      view.setInt16(offset + 1, value);
-      return 3;
-    }
-    // int 32
-    if (value >= -0x80000000) {
-      view.setUint8(offset, 0xd2);
-      view.setInt32(offset + 1, value);
-      return 5;
-    }
-    throw new Error("Number too small -0x" + (-value).toString(16).substr(1));
-  }
-
-  // undefined
-  if (type === "undefined") {
-    view.setUint8(offset, 0xd4);  // fixext 1
-    view.setUint8(offset + 1, 0); // type (undefined)
-    view.setUint8(offset + 2, 0); // data (ignored)
-    return 3;
-  }
-
-  // null
-  if (value === null) {
-    view.setUint8(offset, 0xc0);
-    return 1;
-  }
-
-  // Boolean
-  if (type === "boolean") {
-    view.setUint8(offset, value ? 0xc3 : 0xc2);
-    return 1;
-  }
-
-  // Container Types
-  if (type === "object") {
-    var length, size = 0;
-    var isArray = Array.isArray(value);
-
-    if (isArray) {
-      length = value.length;
-    }
-    else {
-      var keys = Object.keys(value);
-      length = keys.length;
-    }
-
-    var size;
-    if (length < 0x10) {
-      view.setUint8(offset, length | (isArray ? 0x90 : 0x80));
-      size = 1;
-    }
-    else if (length < 0x10000) {
-      view.setUint8(offset, isArray ? 0xdc : 0xde);
-      view.setUint16(offset + 1, length);
-      size = 3;
-    }
-    else if (length < 0x100000000) {
-      view.setUint8(offset, isArray ? 0xdd : 0xdf);
-      view.setUint32(offset + 1, length);
-      size = 5;
-    }
-
-    if (isArray) {
-      for (var i = 0; i < length; i++) {
-        size += encode(value[i], view, offset + size);
-      }
-    }
-    else {
-      for (var i = 0; i < length; i++) {
-        var key = keys[i];
-        size += encode(key, view, offset + size);
-        size += encode(value[key], view, offset + size);
-      }
-    }
-
-    return size;
-  }
-  throw new Error("Unknown type " + type);
-}
-
-function encodedSize(value) {
-  var type = typeof value;
-
-  // Raw Bytes
-  if (type === "string") {
-    var length = utf8ByteCount(value);
-    if (length < 0x20) {
-      return 1 + length;
-    }
-    if (length < 0x100) {
-      return 2 + length;
-    }
-    if (length < 0x10000) {
-      return 3 + length;
-    }
-    if (length < 0x100000000) {
-      return 5 + length;
-    }
-  }
-
-  if (value instanceof ArrayBuffer) {
-    var length = value.byteLength;
-    if (length < 0x100) {
-      return 2 + length;
-    }
-    if (length < 0x10000) {
-      return 3 + length;
-    }
-    if (length < 0x100000000) {
-      return 5 + length;
-    }
-  }
-
-  if (type === "number") {
-    // Floating Point
-    // double
-    if (value << 0 !== value) return 9;
-
-    // Integers
-    if (value >=0) {
-      // positive fixnum
-      if (value < 0x80) return 1;
-      // uint 8
-      if (value < 0x100) return 2;
-      // uint 16
-      if (value < 0x10000) return 3;
-      // uint 32
-      if (value < 0x100000000) return 5;
-      // uint 64
-      if (value < 0x10000000000000000) return 9;
-      throw new Error("Number too big 0x" + value.toString(16));
-    }
-    // negative fixnum
-    if (value >= -0x20) return 1;
-    // int 8
-    if (value >= -0x80) return 2;
-    // int 16
-    if (value >= -0x8000) return 3;
-    // int 32
-    if (value >= -0x80000000) return 5;
-    // int 64
-    if (value >= -0x8000000000000000) return 9;
-    throw new Error("Number too small -0x" + value.toString(16).substr(1));
-  }
-
-  // undefined
-  if (type === "undefined") return 3;
-
-  // Boolean, null
-  if (type === "boolean" || value === null) return 1;
-
-  // Container Types
-  if (type === "object") {
-    var length, size = 0;
-    if (Array.isArray(value)) {
-      length = value.length;
-      for (var i = 0; i < length; i++) {
-        size += encodedSize(value[i]);
-      }
-    }
-    else {
-      var keys = Object.keys(value);
-      length = keys.length;
-      for (var i = 0; i < length; i++) {
-        var key = keys[i];
-        size += encodedSize(key) + encodedSize(value[key]);
-      }
-    }
-    if (length < 0x10) {
-      return 1 + size;
-    }
-    if (length < 0x10000) {
-      return 3 + size;
-    }
-    if (length < 0x100000000) {
-      return 5 + size;
-    }
-    throw new Error("Array or object too long 0x" + length.toString(16));
-  }
-  throw new Error("Unknown type " + type);
-}
-
-return exports;
-
-});

+ 5 - 5
examples/js/lines/LineMaterial.js

@@ -205,19 +205,19 @@ THREE.ShaderLib[ 'line' ] = {
 
 			#ifdef USE_DASH
 
-				if ( vUv.y < 0.5 || vUv.y > 0.5 ) discard; // discard endcaps
+				if ( vUv.y < - 1.0 || vUv.y > 1.0 ) discard; // discard endcaps
 
 				if ( mod( vLineDistance, dashSize + gapSize ) > dashSize ) discard; // todo - FIX
 
 			#endif
 
-			if ( vUv.y < 0.5 || vUv.y > 0.5 ) {
+			if ( abs( vUv.y ) > 1.0 ) {
 
-				float a = vUv.x - 0.5;
-				float b = vUv.y - 0.5;
+				float a = vUv.x;
+				float b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;
 				float len2 = a * a + b * b;
 
-				if ( len2 > 0.25 ) discard;
+				if ( len2 > 1.0 ) discard;
 
 			}
 

+ 1 - 1
examples/js/lines/LineSegmentsGeometry.js

@@ -12,7 +12,7 @@ THREE.LineSegmentsGeometry = function () {
 	var plane = new THREE.BufferGeometry();
 
 	var positions = [ - 1, 2, 0, 1, 2, 0, - 1, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 0, - 1, - 1, 0, 1, - 1, 0 ];
-	var uvs = [ 0, 1, 1, 1, 0, .5, 1, .5, 0, .5, 1, .5, 0, 0, 1, 0 ];
+	var uvs = [ - 1, 2, 1, 2, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 2, 1, - 2 ];
 	var index = [ 0, 2, 1, 2, 3, 1, 2, 4, 3, 4, 5, 3, 4, 6, 5, 6, 7, 5 ];
 
 	this.setIndex( index );

+ 4 - 1
examples/js/loaders/AssimpJSONLoader.js

@@ -21,7 +21,7 @@ THREE.AssimpJSONLoader.prototype = {
 
 	constructor: THREE.AssimpJSONLoader,
 
-	crossOrigin: 'Anonymous',
+	crossOrigin: 'anonymous',
 
 	load: function ( url, onLoad, onProgress, onError ) {
 
@@ -67,6 +67,7 @@ THREE.AssimpJSONLoader.prototype = {
 	setCrossOrigin: function ( value ) {
 
 		this.crossOrigin = value;
+		return this;
 
 	},
 
@@ -221,8 +222,10 @@ THREE.AssimpJSONLoader.prototype = {
 
 					case '$mat.opacity':
 						if ( value < 1 ) {
+
 							material.opacity = value;
 							material.transparent = true;
+
 						}
 						break;
 

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

@@ -12,7 +12,7 @@ THREE.AssimpLoader.prototype = {
 
 	constructor: THREE.AssimpLoader,
 
-	crossOrigin: 'Anonymous',
+	crossOrigin: 'anonymous',
 
 	load: function ( url, onLoad, onProgress, onError ) {
 
@@ -34,6 +34,7 @@ THREE.AssimpLoader.prototype = {
 	setCrossOrigin: function ( value ) {
 
 		this.crossOrigin = value;
+		return this;
 
 	},
 
@@ -1129,7 +1130,7 @@ THREE.AssimpLoader.prototype = {
 			}
 
 			if ( ! key ) {
-				
+
 				return null;
 
 			} else if ( nextKey ) {
@@ -1150,7 +1151,7 @@ THREE.AssimpLoader.prototype = {
 				var l = T / dT;
 
 				return lerp( key.mValue.toTHREE(), nextKey.mValue.toTHREE(), l );
-				
+
 			}
 
 		}

+ 4 - 1
examples/js/loaders/BinaryLoader.js

@@ -19,7 +19,7 @@ THREE.BinaryLoader.prototype = {
 
 	constructor: THREE.BinaryLoader,
 
-	crossOrigin: 'Anonymous',
+	crossOrigin: 'anonymous',
 
 	// Load models generated by slim OBJ converter with BINARY option (converter_obj_three_slim.py -t binary)
 	//  - binary models consist of two files: JS and BIN
@@ -66,18 +66,21 @@ THREE.BinaryLoader.prototype = {
 	setBinaryPath: function ( value ) {
 
 		this.binaryPath = value;
+		return this;
 
 	},
 
 	setCrossOrigin: function ( value ) {
 
 		this.crossOrigin = value;
+		return this;
 
 	},
 
 	setTexturePath: function ( value ) {
 
 		this.texturePath = value;
+		return this;
 
 	},
 

+ 12 - 2
examples/js/loaders/ColladaLoader.js

@@ -13,7 +13,7 @@ THREE.ColladaLoader.prototype = {
 
 	constructor: THREE.ColladaLoader,
 
-	crossOrigin: 'Anonymous',
+	crossOrigin: 'anonymous',
 
 	load: function ( url, onLoad, onProgress, onError ) {
 
@@ -33,6 +33,7 @@ THREE.ColladaLoader.prototype = {
 	setPath: function ( value ) {
 
 		this.path = value;
+		return this;
 
 	},
 
@@ -49,6 +50,7 @@ THREE.ColladaLoader.prototype = {
 	setCrossOrigin: function ( value ) {
 
 		this.crossOrigin = value;
+		return this;
 
 	},
 
@@ -965,7 +967,15 @@ THREE.ColladaLoader.prototype = {
 
 			// setup bind matrix
 
-			build.bindMatrix = new THREE.Matrix4().fromArray( data.bindShapeMatrix ).transpose();
+			if ( data.bindShapeMatrix ) {
+
+				build.bindMatrix = new THREE.Matrix4().fromArray( data.bindShapeMatrix ).transpose(); 
+
+			} else {
+
+				build.bindMatrix = new THREE.Matrix4().transpose(); 
+
+			}
 
 			// process bones and inverse bind matrix data
 

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

@@ -2,7 +2,9 @@
  * @author mrdoob / http://mrdoob.com/
  */
 
-THREE.DDSLoader = function () {
+THREE.DDSLoader = function ( manager ) {
+
+	THREE.CompressedTextureLoader.call( this, manager );
 
 	this._parser = THREE.DDSLoader.parse;
 

+ 2 - 10
examples/js/loaders/DRACOLoader.js

@@ -42,9 +42,6 @@ THREE.DRACOLoader.prototype = {
         var loader = new THREE.FileLoader(scope.manager);
         loader.setPath(this.path);
         loader.setResponseType('arraybuffer');
-        if (this.crossOrigin !== undefined) {
-          loader.crossOrigin = this.crossOrigin;
-        }
         loader.load(url, function(blob) {
             scope.decodeDracoFile(blob, onLoad);
         }, onProgress, onError);
@@ -55,11 +52,6 @@ THREE.DRACOLoader.prototype = {
         return this;
     },
 
-    setCrossOrigin: function(value) {
-        this.crossOrigin = value;
-        return this;
-    },
-
     setVerbosity: function(level) {
         this.verbosity = level;
         return this;
@@ -146,7 +138,7 @@ THREE.DRACOLoader.prototype = {
     },
 
     addAttributeToGeometry: function(dracoDecoder, decoder, dracoGeometry,
-                                     attributeName, attributeType, attribute, 
+                                     attributeName, attributeType, attribute,
                                      geometry, geometryBuffer) {
       if (attribute.ptr === 0) {
         var errorMsg = 'THREE.DRACOLoader: No attribute ' + attributeName;
@@ -224,7 +216,7 @@ THREE.DRACOLoader.prototype = {
           throw new Error( errorMsg );
 
       }
-      
+
       // Copy data from decoder.
       for (var i = 0; i < numValues; i++) {
         geometryBuffer[attributeName][i] = attributeData.GetValue(i);

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