Browse Source

Merge pull request #2 from mrdoob/dev

refork
Eran Geva 7 years ago
parent
commit
a229722922
86 changed files with 1403 additions and 489 deletions
  1. 5 5
      docs/api/animation/PropertyMixer.html
  2. 1 1
      docs/api/cameras/Camera.html
  3. 1 1
      docs/api/cameras/StereoCamera.html
  4. 15 15
      docs/api/core/BufferAttribute.html
  5. 2 2
      docs/api/core/DirectGeometry.html
  6. 3 3
      docs/api/core/InterleavedBuffer.html
  7. 11 11
      docs/api/core/InterleavedBufferAttribute.html
  8. 1 1
      docs/api/core/Raycaster.html
  9. 1 1
      docs/api/helpers/Box3Helper.html
  10. 1 1
      docs/api/helpers/PlaneHelper.html
  11. 0 13
      docs/api/loaders/TextureLoader.html
  12. 2 2
      docs/api/materials/LineBasicMaterial.html
  13. 2 2
      docs/api/materials/LineDashedMaterial.html
  14. 1 2
      docs/api/materials/Material.html
  15. 3 2
      docs/api/materials/MeshBasicMaterial.html
  16. 3 2
      docs/api/materials/MeshDepthMaterial.html
  17. 3 2
      docs/api/materials/MeshLambertMaterial.html
  18. 3 2
      docs/api/materials/MeshNormalMaterial.html
  19. 3 2
      docs/api/materials/MeshPhongMaterial.html
  20. 3 2
      docs/api/materials/MeshStandardMaterial.html
  21. 1 1
      docs/api/materials/PointsMaterial.html
  22. 6 4
      docs/api/materials/ShaderMaterial.html
  23. 1 1
      docs/api/materials/SpriteMaterial.html
  24. 1 1
      docs/api/math/Cylindrical.html
  25. 7 2
      docs/api/math/Euler.html
  26. 1 6
      docs/api/math/Math.html
  27. 2 11
      docs/api/math/Matrix3.html
  28. 1 5
      docs/api/math/Matrix4.html
  29. 1 11
      docs/api/math/Quaternion.html
  30. 1 1
      docs/api/objects/Mesh.html
  31. 3 3
      docs/api/textures/Texture.html
  32. 1 1
      examples/canvas_ascii_effect.html
  33. 1 1
      examples/canvas_camera_orthographic.html
  34. 1 1
      examples/canvas_geometry_earth.html
  35. 1 1
      examples/canvas_geometry_hierarchy.html
  36. 1 1
      examples/canvas_geometry_panorama.html
  37. 7 5
      examples/canvas_geometry_panorama_fisheye.html
  38. 1 1
      examples/canvas_geometry_shapes.html
  39. 1 1
      examples/canvas_geometry_text.html
  40. 1 1
      examples/canvas_interactive_cubes.html
  41. 1 1
      examples/canvas_interactive_cubes_tween.html
  42. 1 1
      examples/canvas_interactive_voxelpainter.html
  43. 42 21
      examples/canvas_lines_colors.html
  44. 25 58
      examples/canvas_lines_dashed.html
  45. 1 1
      examples/canvas_materials_video.html
  46. 1 1
      examples/canvas_performance.html
  47. 1 1
      examples/canvas_sandbox.html
  48. 171 90
      examples/js/loaders/FBXLoader.js
  49. 48 70
      examples/js/loaders/GLTFLoader.js
  50. 316 24
      examples/js/loaders/SVGLoader.js
  51. 45 9
      examples/js/renderers/Projector.js
  52. 1 1
      examples/js/renderers/WebGLDeferredRenderer.js
  53. 3 3
      examples/misc_lights_test.html
  54. 2 2
      examples/misc_ubiquity_test.html
  55. 1 1
      examples/misc_ubiquity_test2.html
  56. BIN
      examples/models/svg/tests/1.png
  57. 96 0
      examples/models/svg/tests/1.svg
  58. BIN
      examples/models/svg/tests/2.png
  59. 105 0
      examples/models/svg/tests/2.svg
  60. BIN
      examples/models/svg/tests/3.png
  61. 105 0
      examples/models/svg/tests/3.svg
  62. BIN
      examples/models/svg/tests/4.png
  63. 66 0
      examples/models/svg/tests/4.svg
  64. BIN
      examples/models/svg/tests/5.png
  65. 68 0
      examples/models/svg/tests/5.svg
  66. BIN
      examples/models/svg/tests/6.png
  67. 69 0
      examples/models/svg/tests/6.svg
  68. BIN
      examples/models/svg/tests/7.png
  69. 66 0
      examples/models/svg/tests/7.svg
  70. 1 1
      examples/software_geometry_earth.html
  71. 2 2
      examples/svg_sandbox.html
  72. 8 15
      examples/webgl_custom_attributes_lines.html
  73. 3 3
      examples/webgl_geometry_extrude_shapes.html
  74. 1 1
      examples/webgl_geometry_shapes.html
  75. 2 6
      examples/webgl_geometry_text_shapes.html
  76. 1 1
      examples/webgl_panorama_cube.html
  77. 1 1
      examples/webvr_panorama.html
  78. 10 12
      src/renderers/WebGLRenderer.js
  79. 3 3
      src/renderers/webgl/WebGLBufferRenderer.js
  80. 5 1
      src/renderers/webgl/WebGLCapabilities.js
  81. 3 3
      src/renderers/webgl/WebGLIndexedBufferRenderer.js
  82. 6 6
      src/renderers/webgl/WebGLProgram.js
  83. 1 1
      src/renderers/webgl/WebGLPrograms.js
  84. 9 9
      src/renderers/webgl/WebGLState.js
  85. 5 5
      src/renderers/webgl/WebGLTextures.js
  86. 4 4
      src/renderers/webgl/WebGLUtils.js

+ 5 - 5
docs/api/animation/PropertyMixer.html

@@ -18,7 +18,7 @@
 		<h2>Constructor</h2>
 
 
-		<h3>[name]( binding, typeName, valueSize )</h3>
+		<h3>[name]( [param:PropertyBinding binding], [param:String typeName], [param:Number valueSize] )</h3>
 		<p>
 			-- binding <br />
 			-- typeName <br />
@@ -29,12 +29,12 @@
 		<h2>Properties</h2>
 
 
-		<h3>[property:Number binding]</h3>
+		<h3>[property:PropertyBinding binding]</h3>
 		<p>
 
 		</p>
 
-		<h3>[property:Number buffer]</h3>
+		<h3>[property:TypedArray buffer]</h3>
 		<p>
 			Buffer with size [page:PropertyMixer valueSize] * 4. <br /><br />
 			This has the layout: [ incoming | accu0 | accu1 | orig ]<br /><br />
@@ -67,14 +67,14 @@
 		<h2>Methods</h2>
 
 
-		<h3>[method:null accumulate]( accuIndex, weight )</h3>
+		<h3>[method:null accumulate]( [param:Number accuIndex], [param:Number weight] )</h3>
 		<p>
 			Accumulate data in [page:PropertyMixer.buffer buffer][accuIndex] 'incoming' region into 'accu[i]'.<br />
 
 			If weight is *0* this does nothing.
 		</p>
 
-		<h3>[method:null apply]( accuIndex )</h3>
+		<h3>[method:null apply]( [param:Number accuIndex] )</h3>
 		<p>
 			Apply the state of [page:PropertyMixer.buffer buffer] 'accu[i]' to the binding when accus differ.
 		</p>

+ 1 - 1
docs/api/cameras/Camera.html

@@ -64,7 +64,7 @@
 			Return a new camera with the same properties as this one.
 		</p>
 
-		<h3>[method:Camera copy]( [param:Camera source] )</h3>
+		<h3>[method:Camera copy]( [param:Camera source], [param:Boolean recursive] )</h3>
 		<p>
 		Copy the properties from the source camera into this one.
 		</p>

+ 1 - 1
docs/api/cameras/StereoCamera.html

@@ -55,7 +55,7 @@
 
 		<h2>Methods</h2>
 
-		<h3>[method:null update]( camera )</h3>
+		<h3>[method:null update]( [param:PerspectiveCamera camera] )</h3>
 		<p>
 		Update the stereo cameras based on the camera passed in.
 		</p>

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

@@ -131,28 +131,28 @@
 		<h3>[method:null copyAt] ( [param:Integer index1], [param:BufferAttribute bufferAttribute], [param:Integer index2] ) </h3>
 		<p>Copy a vector from bufferAttribute[index2] to [page:BufferAttribute.array array][index1].</p>
 
-		<h3>[method:BufferAttribute copyColorsArray]( colors ) </h3>
+		<h3>[method:BufferAttribute copyColorsArray]( [param:Array colors] ) </h3>
 		<p>Copy an array representing RGB color values into [page:BufferAttribute.array array].</p>
 
-		<h3>[method:BufferAttribute copyVector2sArray]( vectors ) </h3>
+		<h3>[method:BufferAttribute copyVector2sArray]( [param:Array vectors] ) </h3>
 		<p>Copy an array representing [page:Vector2]s into [page:BufferAttribute.array array].</p>
 
-		<h3>[method:BufferAttribute copyVector3sArray]( vectors ) </h3>
+		<h3>[method:BufferAttribute copyVector3sArray]( [param:Array vectors] ) </h3>
 		<p>Copy an array representing [page:Vector3]s into [page:BufferAttribute.array array].</p>
 
-		<h3>[method:BufferAttribute copyVector4sArray]( vectors ) </h3>
+		<h3>[method:BufferAttribute copyVector4sArray]( [param:Array vectors] ) </h3>
 		<p>Copy an array representing [page:Vector4]s into [page:BufferAttribute.array array].</p>
 
-		<h3>[method:Number getX]( index ) </h3>
+		<h3>[method:Number getX]( [param:Integer index] ) </h3>
 		<p>Returns the x component of the vector at the given index.</p>
 
-		<h3>[method:Number getY]( index ) </h3>
+		<h3>[method:Number getY]( [param:Integer index] ) </h3>
 		<p>Returns the y component of the vector at the given index.</p>
 
-		<h3>[method:Number getZ]( index ) </h3>
+		<h3>[method:Number getZ]( [param:Integer index] ) </h3>
 		<p>Returns the z component of the vector at the given index.</p>
 
-		<h3>[method:Number getW]( index ) </h3>
+		<h3>[method:Number getW]( [param:Integer index] ) </h3>
 		<p>Returns the w component of the vector at the given index.</p>
 
 		<h3>[method:null onUpload]( [param:Function callback] ) </h3>
@@ -185,25 +185,25 @@
 		<h3>[method:BufferAttribute setDynamic] ( [param:Boolean value] ) </h3>
 		<p>Set [page:BufferAttribute.dynamic dynamic] to value.</p>
 
-		<h3>[method:BufferAttribute setX]( index, x ) </h3>
+		<h3>[method:BufferAttribute setX]( [param:Integer index], [param:Float x] ) </h3>
 		<p>Sets the x component of the vector at the given index.</p>
 
-		<h3>[method:BufferAttribute setY]( index, y ) </h3>
+		<h3>[method:BufferAttribute setY]( [param:Integer index], [param:Float y] ) </h3>
 		<p>Sets the y component of the vector at the given index.</p>
 
-		<h3>[method:BufferAttribute setZ]( index, z ) </h3>
+		<h3>[method:BufferAttribute setZ]( [param:Integer index], [param:Float z] ) </h3>
 		<p>Sets the z component of the vector at the given index.</p>
 
-		<h3>[method:BufferAttribute setW]( index, w ) </h3>
+		<h3>[method:BufferAttribute setW]( [param:Integer index], [param:Float w] ) </h3>
 		<p>Sets the w component of the vector at the given index.</p>
 
-		<h3>[method:BufferAttribute setXY]( index, x, y ) </h3>
+		<h3>[method:BufferAttribute setXY]( [param:Integer index], [param:Float x], [param:Float y] ) </h3>
 		<p>Sets the x and y components of the vector at the given index.</p>
 
-		<h3>[method:BufferAttribute setXYZ]( index, x, y, z ) </h3>
+		<h3>[method:BufferAttribute setXYZ]( [param:Integer index], [param:Float x], [param:Float y], [param:Float z] ) </h3>
 		<p>Sets the x, y and z components of the vector at the given index.</p>
 
-		<h3>[method:BufferAttribute setXYZW]( index, x, y, z, w ) </h3>
+		<h3>[method:BufferAttribute setXYZW]( [param:Integer index], [param:Float x], [param:Float y], [param:Float z], [param:Float w] ) </h3>
 		<p>Sets the x, y, z and w components of the vector at the given index.</p>
 
 

+ 2 - 2
docs/api/core/DirectGeometry.html

@@ -91,13 +91,13 @@
 
 		<h2>Methods</h2>
 
-		<h3>[property:null computeGroups]( [page:Geometry geometry] )</h3>
+		<h3>[property:null computeGroups]( [param:Geometry geometry] )</h3>
 		<p>
 			Compute the parts of the geometry that have different materialIndex.
 			See [page:BufferGeometry.groups].
 		</p>
 
-		<h3>[property:null fromGeometry]( [page:Geometry geometry] )</h3>
+		<h3>[property:null fromGeometry]( [param:Geometry geometry] )</h3>
 		<p>Pass in a [page:Geometry] instance for conversion.</p>
 
 

+ 3 - 3
docs/api/core/InterleavedBuffer.html

@@ -91,15 +91,15 @@
 			Set [page:InterleavedBuffer.dynamic dynamic] to value.
 		</p>
 
-		<h3>[method:InterleavedBuffer copy]( source ) </h3>
+		<h3>[method:InterleavedBuffer copy]( [param:InterleavedBuffer source] ) </h3>
 		<p>
 		 Copies another [name] to this [name].
 		</p>
 
-		<h3>[method:InterleavedBuffer copyAt]( index1, attribute, index2 ) </h3>
+		<h3>[method:InterleavedBuffer copyAt]( [param:Integer index1], [param:InterleavedBuffer attribute], [param:Integer index2] ) </h3>
 		<p>Copies data from attribute[index2] to [page:InterleavedBuffer.array array][index1].</p>
 
-		<h3>[method:InterleavedBuffer set]( value, offset ) </h3>
+		<h3>[method:InterleavedBuffer set]( [param:TypedArray value], [param:Integer offset] ) </h3>
 		<p>
 			value - The source (typed) array.<br/>
 			offset - The offset into the target array at which to begin writing values from the source array. Default is *0*.<br/><br />

+ 11 - 11
docs/api/core/InterleavedBufferAttribute.html

@@ -62,37 +62,37 @@
 
 		<h2>Methods</h2>
 
-		<h3>[method:Number getX]( index ) </h3>
+		<h3>[method:Number getX]( [param:Integer index] ) </h3>
 		<p>Returns the x component of the item at the given index.</p>
 
-		<h3>[method:Number getY]( index ) </h3>
+		<h3>[method:Number getY]( [param:Integer index] ) </h3>
 		<p>Returns the y component of the item at the given index.</p>
 
-		<h3>[method:Number getZ]( index ) </h3>
+		<h3>[method:Number getZ]( [param:Integer index] ) </h3>
 		<p>Returns the z component of the item at the given index.</p>
 
-		<h3>[method:Number getW]( index ) </h3>
+		<h3>[method:Number getW]( [param:Integer index] ) </h3>
 		<p>Returns the w component of the item at the given index.</p>
 
-		<h3>[method:null setX]( index, x ) </h3>
+		<h3>[method:null setX]( [param:Integer index], [param:Float x] ) </h3>
 		<p>Sets the x component of the item at the given index.</p>
 
-		<h3>[method:null setY]( index, y ) </h3>
+		<h3>[method:null setY]( [param:Integer index], [param:Float y] ) </h3>
 		<p>Sets the y component of the item at the given index.</p>
 
-		<h3>[method:null setZ]( index, z ) </h3>
+		<h3>[method:null setZ]( [param:Integer index], [param:Float z] ) </h3>
 		<p>Sets the z component of the item at the given index.</p>
 
-		<h3>[method:null setW]( index, w ) </h3>
+		<h3>[method:null setW]( [param:Integer index], [param:Float w] ) </h3>
 		<p>Sets the w component of the item at the given index.</p>
 
-		<h3>[method:null setXY]( index, x, y ) </h3>
+		<h3>[method:null setXY]( [param:Integer index], [param:Float x], [param:Float y] ) </h3>
 		<p>Sets the x and y components of the item at the given index.</p>
 
-		<h3>[method:null setXYZ]( index, x, y, z ) </h3>
+		<h3>[method:null setXYZ]( [param:Integer index], [param:Float x], [param:Float y], [param:Float z] ) </h3>
 		<p>Sets the x, y and z components of the item at the given index.</p>
 
-		<h3>[method:null setXYZW]( index, x, y, z, w ) </h3>
+		<h3>[method:null setXYZW]( [param:Integer index], [param:Float x], [param:Float y], [param:Float z], [param:Float w] ) </h3>
 		<p>Sets the x, y, z and w components of the item at the given index.</p>
 
 

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

@@ -144,7 +144,7 @@
 		Updates the ray with a new origin and direction.
 		</p>
 
-		<h3>[method:Array intersectObject]( [page:Object3D object], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
+		<h3>[method:Array intersectObject]( [param:Object3D object], [param:Boolean recursive], [param:Array optionalTarget] )</h3>
 		<p>
 		[page:Object3D object] — The object to check for intersection with the ray.<br />
 		[page:Boolean recursive] — If true, it also checks all descendants. Otherwise it only checks intersecton with the object. Default is false.<br />

+ 1 - 1
docs/api/helpers/Box3Helper.html

@@ -50,7 +50,7 @@
 		<p>See the base [page:LineSegments] class for common methods.</p>
 
 
-		<h3>[method:void updateMatrixWorld]( force )</h3>
+		<h3>[method:void updateMatrixWorld]( [param:Boolean force] )</h3>
 		<p>
 			This overrides the method in the base [page:Object3D] class so that it
 			also updates the wireframe box to the extent of the [page:Box3Helper.box .box]

+ 1 - 1
docs/api/helpers/PlaneHelper.html

@@ -51,7 +51,7 @@
 		<h2>Methods</h2>
 		<p>See the base [page:LineSegments] class for common methods.</p>
 
-		<h3>[method:void updateMatrixWorld]( force )</h3>
+		<h3>[method:void updateMatrixWorld]( [param:Boolean force] )</h3>
 		<p>
 			This overrides the method in the base [page:Object3D] class so that it also
 			updates the helper object according to the [page:PlaneHelper.plane .plane] and

+ 0 - 13
docs/api/loaders/TextureLoader.html

@@ -85,12 +85,6 @@
 		<p>The base path from which files will be loaded. See [page:.setPath]. Default is *undefined*.</p>
 
 
-		<h3>[property:String withCredentials]</h3>
-		<p>
-			Whether the XMLHttpRequest uses credentials - see [page:.setWithCredentials].
-			Default is *undefined*.
-		</p>
-
 		<h2>Methods</h2>
 
 		<h3>[method:Texture load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )</h3>
@@ -114,13 +108,6 @@
 			you are loading many models from the same directory.
 		</p>
 
-		<h3>[method:FileLoader setWithCredentials]( [param:Boolean value] )</h3>
-		<p>
-		Whether the XMLHttpRequest uses credentials such as cookies, authorization headers or
-		TLS client certificates. See
-		[link:https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials XMLHttpRequest.withCredentials].<br />
-		Note that this has no effect if you are loading files locally or from the same domain.
-		</p>
 
 		<h2>Source</h2>
 

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

@@ -75,8 +75,8 @@ var material = new THREE.LineBasicMaterial( {
 		<p>
 			Controls line thickness. Default is *1*.<br /><br />
 
-			Due to limitations in the [link:https://code.google.com/p/angleproject ANGLE layer],
-			with the [page:WebGLRenderer WebGL] renderer on Windows platforms linewidth will
+			Due to limitations of the [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile]
+			with the [page:WebGLRenderer WebGL] renderer on most platforms linewidth will
 			always be 1 regardless of the set value.
 		</p>
 

+ 2 - 2
docs/api/materials/LineDashedMaterial.html

@@ -70,8 +70,8 @@ var material = new THREE.LineDashedMaterial( {
 		<p>
 			Controls line thickness. Default is *1*.<br /><br />
 
-			Due to limitations in the [link:https://code.google.com/p/angleproject ANGLE layer],
-			with the [page:WebGLRenderer WebGL] renderer on Windows platforms linewidth will
+			Due to limitations of the [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile]
+			with the [page:WebGLRenderer WebGL] renderer on most platforms linewidth will
 			always be 1 regardless of the set value.
 		</p>
 

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

@@ -162,8 +162,7 @@
 
 		<h3>[property:Boolean needsUpdate]</h3>
 		<p>
-		Specifies that the material needs to be updated at the WebGL level.
-		Set it to true if you made changes that need to be reflected in WebGL.<br />
+		Specifies that the material needs to be recompiled.<br />
 		This property is automatically set to *true* when instancing a new material.
 		</p>
 

+ 3 - 2
docs/api/materials/MeshBasicMaterial.html

@@ -151,8 +151,9 @@
 		<h3>[property:Float wireframeLinewidth]</h3>
 		<p>Controls wireframe thickness. Default is 1.<br /><br />
 
-		Due to limitations in the [link:https://code.google.com/p/angleproject ANGLE layer],
-		on Windows platforms linewidth will always be 1 regardless of the set value.
+		Due to limitations of the [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile]
+		with the [page:WebGLRenderer WebGL] renderer on most platforms linewidth will
+		always be 1 regardless of the set value.
 		</p>
 
 		<h2>Methods</h2>

+ 3 - 2
docs/api/materials/MeshDepthMaterial.html

@@ -107,8 +107,9 @@
 		<h3>[property:Float wireframeLinewidth]</h3>
 		<p>Controls wireframe thickness. Default is 1.<br /><br />
 
-		Due to limitations in the [link:https://code.google.com/p/angleproject ANGLE layer],
-		on Windows platforms linewidth will always be 1 regardless of the set value.
+		Due to limitations of the [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile]
+		with the [page:WebGLRenderer WebGL] renderer on most platforms linewidth will
+		always be 1 regardless of the set value.
 		</p>
 
 		<h2>Methods</h2>

+ 3 - 2
docs/api/materials/MeshLambertMaterial.html

@@ -177,8 +177,9 @@
 		<h3>[property:Float wireframeLinewidth]</h3>
 		<p>Controls wireframe thickness. Default is 1.<br /><br />
 
-		Due to limitations in the [link:https://code.google.com/p/angleproject ANGLE layer],
-		on Windows platforms linewidth will always be 1 regardless of the set value.
+		Due to limitations of the [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile]
+		with the [page:WebGLRenderer WebGL] renderer on most platforms linewidth will
+		always be 1 regardless of the set value.
 		</p>
 
 		<h2>Methods</h2>

+ 3 - 2
docs/api/materials/MeshNormalMaterial.html

@@ -68,8 +68,9 @@
 		<h3>[property:Float wireframeLinewidth]</h3>
 		<p>Controls wireframe thickness. Default is 1.<br /><br />
 
-		Due to limitations in the [link:https://code.google.com/p/angleproject ANGLE layer],
-		on Windows platforms linewidth will always be 1 regardless of the set value.
+		Due to limitations of the [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile]
+		with the [page:WebGLRenderer WebGL] renderer on most platforms linewidth will
+		always be 1 regardless of the set value.
 		</p>
 
 		<h2>Methods</h2>

+ 3 - 2
docs/api/materials/MeshPhongMaterial.html

@@ -247,8 +247,9 @@
 		<h3>[property:Float wireframeLinewidth]</h3>
 		<p>Controls wireframe thickness. Default is 1.<br /><br />
 
-		Due to limitations in the [link:https://code.google.com/p/angleproject ANGLE layer],
-		on Windows platforms linewidth will always be 1 regardless of the set value.
+		Due to limitations of the [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile]
+		with the [page:WebGLRenderer WebGL] renderer on most platforms linewidth will
+		always be 1 regardless of the set value.
 		</p>
 
 		<h2>Methods</h2>

+ 3 - 2
docs/api/materials/MeshStandardMaterial.html

@@ -274,8 +274,9 @@
 		<h3>[property:Float wireframeLinewidth]</h3>
 		<p>Controls wireframe thickness. Default is 1.<br /><br />
 
-		Due to limitations in the [link:https://code.google.com/p/angleproject ANGLE layer],
-		on Windows platforms linewidth will always be 1 regardless of the set value.
+		Due to limitations of the [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile]
+		with the [page:WebGLRenderer WebGL] renderer on most platforms linewidth will
+		always be 1 regardless of the set value.
 		</p>
 
 		<h2>Methods</h2>

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

@@ -55,7 +55,7 @@ var starField = new THREE.Points( starsGeometry, starsMaterial );
 scene.add( starField );
 		</code>
 
-		<h3>[name]( [page:Object parameters] )</h3>
+		<h3>[name]( [param:Object parameters] )</h3>
 		<p>
 			[page:Object parameters] - (optional) an object with one or more properties defining the material's appearance.
 			Any property of the material (including any property inherited from [page:Material]) can be passed in here.<br /><br />

+ 6 - 4
docs/api/materials/ShaderMaterial.html

@@ -371,8 +371,9 @@ this.extensions = {
 		<h3>[property:Float linewidth]</h3>
 		<p>Controls wireframe thickness. Default is 1.<br /><br />
 
-		Due to limitations in the [link:https://code.google.com/p/angleproject ANGLE layer],
-		on Windows platforms linewidth will always be 1 regardless of the set value.
+		Due to limitations of the [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile]
+		with the [page:WebGLRenderer WebGL] renderer on most platforms linewidth will
+		always be 1 regardless of the set value.
 		</p>
 
 
@@ -443,8 +444,9 @@ this.extensions = {
 		<h3>[property:Float wireframeLinewidth]</h3>
 		<p>Controls wireframe thickness. Default is 1.<br /><br />
 
-		Due to limitations in the [link:https://code.google.com/p/angleproject ANGLE layer],
-		on Windows platforms linewidth will always be 1 regardless of the set value.
+		Due to limitations of the [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile)
+		with the [page:WebGLRenderer WebGL] renderer on most platforms linewidth will
+		always be 1 regardless of the set value.
 		</p>
 
 

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

@@ -37,7 +37,7 @@ scene.add( sprite );
 		</code>
 
 
-		<h3>[name]( [page:Object parameters] )</h3>
+		<h3>[name]( [param:Object parameters] )</h3>
 		<p>
 			[page:Object parameters] - (optional) an object with one or more properties defining the material's appearance.
 			Any property of the material (including any property inherited from [page:Material]) can be passed in here.<br /><br />

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

@@ -50,7 +50,7 @@
 			and [page:.y y] properties to this cylindrical.
 		</p>
 
-		<h3>[method:Cylindrical set]( [param:Float radius], [param:Float phi], [param:Float theta] )</h3>
+		<h3>[method:Cylindrical set]( [param:Float radius], [param:Float theta], [param:Float y] )</h3>
 		<p>Sets values of this cylindrical's [page:.radius radius], [page:.theta theta]
 		and [page:.y y] properties.</p>
 

+ 7 - 2
docs/api/math/Euler.html

@@ -176,8 +176,13 @@
 		Returns an array of the form [[page:.x x], [page:.y y], [page:.z z], [page:.order order ]].
 		</p>
 
-		<h3>[method:Vector3 toVector3]()</h3>
-		<p>Returns the Euler's [page:.x x], [page:.y y] and [page:.z z] properties as a [page:Vector3].</p>
+		<h3>[method:Vector3 toVector3]( [param:Vector3 optionalResult] )</h3>
+		<p>
+			[page:Vector3 optionalResult] — (optional) If specified, the result will be copied into this Vector,
+			otherwise a new one will be created. <br /><br />
+
+			Returns the Euler's [page:.x x], [page:.y y] and [page:.z z] properties as a [page:Vector3].
+		</p>
 
 
 		<h2>Source</h2>

+ 1 - 6
docs/api/math/Math.html

@@ -54,12 +54,7 @@
 		and [page:Float t] = 1 will return [page:Float y].
 		</p>
 
-		<h3>[method:Float mapLinear](
-			[page:Float x],
-			[page:Float a1],
-			[page:Float a2],
-			[page:Float b1],
-			[page:Float b2] )</h3>
+		<h3>[method:Float mapLinear]( [param:Float x], [param:Float a1], [param:Float a2], [param:Float b1], [param:Float b2] )</h3>
 		<p>
 		[page:Float x] — Value to be mapped.<br />
 		[page:Float a1] — Minimum value for range A.<br />

+ 2 - 11
docs/api/math/Matrix3.html

@@ -144,12 +144,7 @@ m.elements = [ 11, 21, 31,
 		<h3>[method:this multiplyScalar]( [param:Float s] )</h3>
 		<p>Multiplies every component of the matrix by the scalar value *s*.</p>
 
-		<h3>
-			[method:this set](
-			[page:Float n11], [page:Float n12], [page:Float n13],
-			[page:Float n21], [page:Float n22], [page:Float n23],
-			[page:Float n31], [page:Float n32], [page:Float n33] )
-		</h3>
+		<h3>[method:this set]( [param:Float n11], [param:Float n12], [param:Float n13], [param:Float n21], [param:Float n22], [param:Float n23], [param:Float n31], [param:Float n32], [param:Float n33] )</h3>
 		<p>
 		[page:Float n11] - value to put in row 1, col 1.<br />
 		[page:Float n12] - value to put in row 1, col 2.<br />
@@ -169,11 +164,7 @@ m.elements = [ 11, 21, 31,
 		<h3>[method:this setFromMatrix4]( [param:Matrix4 m] )</h3>
 		<p>Set this matrx to the upper 3x3 matrix of the Matrix4 [page:Matrix4 m].</p>
 
-		<h3>
-			[method:this setUvTransform](
-			[page:Float tx], [page:Float ty], [page:Float sx], [page:Float sy],
-			[page:Float rotation], [page:Float cx], [page:Float cy] )
-		</h3>
+		<h3>[method:this setUvTransform]( [param:Float tx], [param:Float ty], [param:Float sx], [param:Float sy], [param:Float rotation], [param:Float cx], [param:Float cy] )</h3>
 		<p>
 		[page:Float tx] - offset x<br />
 		[page:Float ty] - offset y<br />

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

@@ -368,11 +368,7 @@ x, y, 1, 0,
 		<h3>[method:this scale]( [param:Vector3 v] )</h3>
 		<p>Multiplies the columns of this matrix by vector [page:Vector3 v].</p>
 
-		<h3>[method:this set](
-			[page:Float n11], [page:Float n12], [page:Float n13], [page:Float n14],
-			[page:Float n21], [page:Float n22], [page:Float n23], [page:Float n24],
-			[page:Float n31], [page:Float n32], [page:Float n33], [page:Float n34],
-			[page:Float n41], [page:Float n42], [page:Float n43], [page:Float n44] )</h3>
+		<h3>[method:this set]( [param:Float n11], [param:Float n12], [param:Float n13], [param:Float n14], [param:Float n21], [param:Float n22], [param:Float n23], [param:Float n24], [param:Float n31], [param:Float n32], [param:Float n33], [param:Float n34], [param:Float n41], [param:Float n42], [param:Float n43], [param:Float n44] )</h3>
 		<p>
 			Set the [page:.elements elements] of this matrix to the supplied row-major values [page:Float n11],
 			[page:Float n12], ... [page:Float n44].

+ 1 - 11
docs/api/math/Quaternion.html

@@ -261,17 +261,7 @@ q.slerp( qb, t )
 		</p>
 
 
-		<h3>
-		[method:null slerpFlat](
-			[page:Array dst],
-			[page:Integer dstOffset],
-			[page:Array src0],
-			[page:Integer srcOffset0],
-			[page:Array src1],
-			[page:Integer srcOffset1],
-			[page:Float t]
-		)
-		</h3>
+		<h3>[method:null slerpFlat]( [param:Array dst], [param:Integer dstOffset], [param:Array src0], [param:Integer srcOffset0], [param:Array src1], [param:Integer srcOffset1], [param:Float t] )</h3>
 		<p>
 		[page:Array dst] - The output array.<br />
 		[page:Integer dstOffset] - An offset into the output array.<br />

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

@@ -86,7 +86,7 @@
 		<h2>Methods</h2>
 		<p>See the base [page:Object3D] class for common methods.</p>
 
-		<h3>[method:null setDrawMode]()</h3>
+		<h3>[method:null setDrawMode]( [param:Integer value] )</h3>
 		<p>Set the value of [page:.drawMode drawMode].</p>
 
 		<h3>[method:Mesh clone]()</h3>

+ 3 - 3
docs/api/textures/Texture.html

@@ -234,12 +234,12 @@
 		[page:Texture.rotation .rotation], and [page:Texture.center .center].
 		</p>
 
-		<h3>[method:Texture clone]( [param:Texture texture] )</h3>
+		<h3>[method:Texture clone]()</h3>
 		<p>
 		Make copy of the texture. Note this is not a "deep copy", the image is shared.
 		</p>
 
-		<h3>[method:Texture toJSON]( meta )</h3>
+		<h3>[method:Texture toJSON]( [param:Object meta] )</h3>
 		<p>
 		meta -- optional object containing metadata.<br />
 		Convert the material to three.js JSON format.
@@ -250,7 +250,7 @@
 		Call [page:EventDispatcher EventDispatcher].dispatchEvent with a 'dispose' event type.
 		</p>
 
-		<h3>[method:null transformUv]( uv )</h3>
+		<h3>[method:null transformUv]( [param:Vector2 uv] )</h3>
 		<p>
 		Transform the uv based on the value of this texture's [page:Texture.offset .offset], [page:Texture.repeat .repeat],
 		[page:Texture.wrapS .wrapS], [page:Texture.wrapT .wrapT] and [page:Texture.flipY .flipY] properties.

+ 1 - 1
examples/canvas_ascii_effect.html

@@ -72,7 +72,7 @@
 				light.position.set( - 500, - 500, - 500 );
 				scene.add( light );
 
-				sphere = new THREE.Mesh( new THREE.SphereGeometry( 200, 20, 10 ), new THREE.MeshLambertMaterial() );
+				sphere = new THREE.Mesh( new THREE.SphereBufferGeometry( 200, 20, 10 ), new THREE.MeshLambertMaterial() );
 				scene.add( sphere );
 
 				// Plane

+ 1 - 1
examples/canvas_camera_orthographic.html

@@ -58,7 +58,7 @@
 
 				// Cubes
 
-				var geometry = new THREE.BoxGeometry( 50, 50, 50 );
+				var geometry = new THREE.BoxBufferGeometry( 50, 50, 50 );
 				var material = new THREE.MeshLambertMaterial( { color: 0xffffff, overdraw: 0.5 } );
 
 				for ( var i = 0; i < 100; i ++ ) {

+ 1 - 1
examples/canvas_geometry_earth.html

@@ -72,7 +72,7 @@
 				var loader = new THREE.TextureLoader();
 				loader.load( 'textures/land_ocean_ice_cloud_2048.jpg', function ( texture ) {
 
-					var geometry = new THREE.SphereGeometry( 200, 20, 20 );
+					var geometry = new THREE.SphereBufferGeometry( 200, 20, 20 );
 
 					var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: 0.5 } );
 					var mesh = new THREE.Mesh( geometry, material );

+ 1 - 1
examples/canvas_geometry_hierarchy.html

@@ -52,7 +52,7 @@
 				scene = new THREE.Scene();
 				scene.background = new THREE.Color( 0xffffff );
 
-				var geometry = new THREE.BoxGeometry( 100, 100, 100 );
+				var geometry = new THREE.BoxBufferGeometry( 100, 100, 100 );
 				var material = new THREE.MeshNormalMaterial( { overdraw: 0.5 } );
 
 				group = new THREE.Group();

+ 1 - 1
examples/canvas_geometry_panorama.html

@@ -81,7 +81,7 @@
 
 				];
 
-				var geometry = new THREE.BoxGeometry( 300, 300, 300, 7, 7, 7 );
+				var geometry = new THREE.BoxBufferGeometry( 300, 300, 300, 7, 7, 7 );
 				geometry.scale( - 1, 1, 1 );
 
 				mesh = new THREE.Mesh( geometry, materials );

+ 7 - 5
examples/canvas_geometry_panorama_fisheye.html

@@ -81,18 +81,20 @@
 
 				];
 
-				var geometry = new THREE.BoxGeometry( 300, 300, 300, 7, 7, 7 );
+				var geometry = new THREE.BoxBufferGeometry( 300, 300, 300, 7, 7, 7 );
 				geometry.scale( - 1, 1, 1 );
 
 				mesh = new THREE.Mesh( geometry, materials );
 				scene.add( mesh );
 
-				for ( var i = 0, l = mesh.geometry.vertices.length; i < l; i ++ ) {
+				var vec = new THREE.Vector3();
+				var positions = mesh.geometry.attributes.position;
 
-					var vertex = mesh.geometry.vertices[ i ];
+				for ( var i = 0, l = positions.count; i < l; i ++ ) {
 
-					vertex.normalize();
-					vertex.multiplyScalar( 550 );
+					vec.fromBufferAttribute( positions, i );
+					vec.setLength( 550 );
+					positions.setXYZ( i, vec.x, vec.y, vec.z );
 
 				}
 

+ 1 - 1
examples/canvas_geometry_shapes.html

@@ -71,7 +71,7 @@
 
 					// flat shape
 
-					var geometry = new THREE.ShapeGeometry( shape );
+					var geometry = new THREE.ShapeBufferGeometry( shape );
 					var material = new THREE.MeshBasicMaterial( { color: color, overdraw: 0.5 } );
 
 					var mesh = new THREE.Mesh( geometry, material );

+ 1 - 1
examples/canvas_geometry_text.html

@@ -80,7 +80,7 @@
 
 				}
 
-				var geometry = new THREE.TextGeometry( theText, {
+				var geometry = new THREE.TextBufferGeometry( theText, {
 
 					font: font,
 					size: 80,

+ 1 - 1
examples/canvas_interactive_cubes.html

@@ -55,7 +55,7 @@
 				scene = new THREE.Scene();
 				scene.background = new THREE.Color( 0xf0f0f0 );
 
-				var geometry = new THREE.BoxGeometry( 100, 100, 100 );
+				var geometry = new THREE.BoxBufferGeometry( 100, 100, 100 );
 
 				for ( var i = 0; i < 10; i ++ ) {
 

+ 1 - 1
examples/canvas_interactive_cubes_tween.html

@@ -54,7 +54,7 @@
 				scene = new THREE.Scene();
 				scene.background = new THREE.Color( 0xf0f0f0 );
 
-				var geometry = new THREE.BoxGeometry( 100, 100, 100 );
+				var geometry = new THREE.BoxBufferGeometry( 100, 100, 100 );
 
 				for ( var i = 0; i < 20; i ++ ) {
 

+ 1 - 1
examples/canvas_interactive_voxelpainter.html

@@ -28,7 +28,7 @@
 
 			var mouse, raycaster, isShiftDown = false;
 
-			var cubeGeometry = new THREE.BoxGeometry( 50, 50, 50 );
+			var cubeGeometry = new THREE.BoxBufferGeometry( 50, 50, 50 );
 			var cubeMaterial = new THREE.MeshLambertMaterial( { color: 0x00ff80, overdraw: 0.5 } );
 
 			var objects = [];

+ 42 - 21
examples/canvas_lines_colors.html

@@ -49,14 +49,11 @@
 		<script src="js/renderers/Projector.js"></script>
 		<script src="js/renderers/CanvasRenderer.js"></script>
 
-		<script src="js/Detector.js"></script>
 		<script src="js/geometries/hilbert3D.js"></script>
 		<script src="js/geometries/hilbert2D.js"></script>
 
 		<script>
 
-			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
-
 			var mouseX = 0, mouseY = 0;
 
 			var windowHalfX = window.innerWidth / 2;
@@ -81,37 +78,61 @@
 
 				// 2d lines
 
-				var geometry2 = new THREE.Geometry(),
-					points = hilbert2D( new THREE.Vector3( 0, 0, 0 ), 400, 4 ),
-					colors2 = [];
+				var vertices = hilbert2D( new THREE.Vector3( 0, 0, 0 ), 400, 4 );
+				numVertices = vertices.length;
 
-				for ( var i = 0; i < points.length; i ++ ) {
+				var geometry2 = new THREE.BufferGeometry();
 
-					geometry2.vertices.push( points[ i ] );
+				var positions = new Float32Array( numVertices * 3 );
+				var colors = new Float32Array( numVertices * 3 );
 
-					colors2[ i ] = new THREE.Color( 0xffffff );
-					colors2[ i ].setHSL( i / points.length, 1, 0.5 );
+				geometry2.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
+				geometry2.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
 
-				}
+				var color = new THREE.Color();
+
+				for ( var i = 0, index = 0, l = numVertices; i < l; i ++, index += 3 ) {
+
+					positions[ index ] = vertices[ i ].x;
+					positions[ index + 1 ] = vertices[ i ].y;
+					positions[ index + 2 ] = vertices[ i ].z;
 
-				geometry2.colors = colors2;
+					color.setHSL( i / l, 1.0, 0.5 );
+
+					colors[ index ] = color.r;
+					colors[ index + 1 ] = color.g;
+					colors[ index + 2 ] = color.b;
+
+				}
 
 				// 3d lines
 
-				var geometry3 = new THREE.Geometry(),
-					points = hilbert3D( new THREE.Vector3( 0, 0, 0 ), 200, 2, 0, 1, 2, 3, 4, 5, 6, 7 ),
-					colors3 = [];
+				var vertices = hilbert3D( new THREE.Vector3( 0, 0, 0 ), 200, 2, 0, 1, 2, 3, 4, 5, 6, 7 );
+				numVertices = vertices.length;
 
-				for ( var i = 0; i < points.length; i ++ ) {
+				var geometry3 = new THREE.BufferGeometry();
 
-					geometry3.vertices.push( points[ i ] );
+				var positions = new Float32Array( numVertices * 3 );
+				var colors = new Float32Array( numVertices * 3 );
 
-					colors3[ i ] = new THREE.Color( 0xffffff );
-					colors3[ i ].setHSL( i / points.length, 1, 0.5 );
+				geometry3.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
+				geometry3.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
 
-				}
+				var color = new THREE.Color();
+
+				for ( var i = 0, index = 0, l = numVertices; i < l; i ++, index += 3 ) {
+
+					positions[ index ] = vertices[ i ].x;
+					positions[ index + 1 ] = vertices[ i ].y;
+					positions[ index + 2 ] = vertices[ i ].z;
 
-				geometry3.colors = colors3;
+					color.setHSL( i / l, 1.0, 0.5 );
+
+					colors[ index ] = color.r;
+					colors[ index + 1 ] = color.g;
+					colors[ index + 2 ] = color.b;
+
+				}
 
 				// lines
 

+ 25 - 58
examples/canvas_lines_dashed.html

@@ -38,17 +38,13 @@
 
 		<script src="js/geometries/hilbert3D.js"></script>
 
-		<script src="js/Detector.js"></script>
 		<script src="js/libs/stats.min.js"></script>
 
 		<script>
 
-			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
-
 			var renderer, scene, camera, stats;
 			var objects = [];
 
-
 			var WIDTH = window.innerWidth, HEIGHT = window.innerHeight;
 
 			init();
@@ -62,23 +58,43 @@
 				scene = new THREE.Scene();
 				scene.background = new THREE.Color( 0x111111 );
 
-				var subdivisions = 6;
+				var subdivisions = 3;
 				var recursion = 1;
 
 				var points = hilbert3D( new THREE.Vector3( 0,0,0 ), 25.0, recursion, 0, 1, 2, 3, 4, 5, 6, 7 );
 				var spline = new THREE.CatmullRomCurve3( points );
 
 				var samples = spline.getPoints( points.length * subdivisions );
-				var geometrySpline = new THREE.Geometry().setFromPoints( samples );
+				numSamples = samples.length;
+
+				var geometrySpline = new THREE.BufferGeometry();
+
+				var positions = new Float32Array( numSamples * 3 );
+
+				geometrySpline.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
+
+				for ( var i = 0, index = 0, l = numSamples; i < l; i ++, index += 3 ) {
+
+					positions[ index ] = samples[ i ].x;
+					positions[ index + 1 ] = samples[ i ].y;
+					positions[ index + 2 ] = samples[ i ].z;
 
-				var geometryCube = cube( 50 );
+				}
+
+				var geometryCube = new THREE.EdgesGeometry( new THREE.BoxBufferGeometry( 50, 50, 50 ) );
 
-				var object = new THREE.Line( geometrySpline, new THREE.LineDashedMaterial( { color: 0xffffff, dashSize: 1, gapSize: 0.5 } ) );
+				var object = new THREE.Line(
+					geometrySpline,
+					new THREE.LineDashedMaterial( { color: 0xffffff, dashSize: 10, gapSize: 10, linewidth: 3 } )
+				);
 
 				objects.push( object );
 				scene.add( object );
 
-				var object = new THREE.LineSegments( geometryCube, new THREE.LineDashedMaterial( { color: 0xffaa00, dashSize: 30, gapSize: 10, linewidth: 2 } ) );
+				var object = new THREE.LineSegments(
+					geometryCube,
+					new THREE.LineDashedMaterial( { color: 0xffaa00, dashSize: 30, gapSize: 10, linewidth: 3 } )
+				);
 
 				objects.push( object );
 				scene.add( object );
@@ -99,55 +115,6 @@
 
 			}
 
-			function cube( size ) {
-
-				var h = size * 0.5;
-
-				var geometry = new THREE.Geometry();
-
-				geometry.vertices.push(
-					new THREE.Vector3( -h, -h, -h ),
-					new THREE.Vector3( -h, h, -h ),
-
-					new THREE.Vector3( -h, h, -h ),
-					new THREE.Vector3( h, h, -h ),
-
-					new THREE.Vector3( h, h, -h ),
-					new THREE.Vector3( h, -h, -h ),
-
-					new THREE.Vector3( h, -h, -h ),
-					new THREE.Vector3( -h, -h, -h ),
-
-
-					new THREE.Vector3( -h, -h, h ),
-					new THREE.Vector3( -h, h, h ),
-
-					new THREE.Vector3( -h, h, h ),
-					new THREE.Vector3( h, h, h ),
-
-					new THREE.Vector3( h, h, h ),
-					new THREE.Vector3( h, -h, h ),
-
-					new THREE.Vector3( h, -h, h ),
-					new THREE.Vector3( -h, -h, h ),
-
-					new THREE.Vector3( -h, -h, -h ),
-					new THREE.Vector3( -h, -h, h ),
-
-					new THREE.Vector3( -h, h, -h ),
-					new THREE.Vector3( -h, h, h ),
-
-					new THREE.Vector3( h, h, -h ),
-					new THREE.Vector3( h, h, h ),
-
-					new THREE.Vector3( h, -h, -h ),
-					new THREE.Vector3( h, -h, h )
-				 );
-
-				return geometry;
-
-			}
-
 			function onWindowResize() {
 
 				camera.aspect = window.innerWidth / window.innerHeight;

+ 1 - 1
examples/canvas_materials_video.html

@@ -103,7 +103,7 @@
 
 				//
 
-				var plane = new THREE.PlaneGeometry( 480, 204, 4, 4 );
+				var plane = new THREE.PlaneBufferGeometry( 480, 204, 4, 4 );
 
 				mesh = new THREE.Mesh( plane, material );
 				mesh.scale.x = mesh.scale.y = mesh.scale.z = 1.5;

+ 1 - 1
examples/canvas_performance.html

@@ -53,7 +53,7 @@
 
 				// Spheres
 
-				var geometry = new THREE.SphereGeometry( 100, 26, 18 );
+				var geometry = new THREE.SphereBufferGeometry( 100, 26, 18 );
 				var material = new THREE.MeshLambertMaterial( { color: 0xffffff, overdraw: 0.5 } );
 
 				for ( var i = 0; i < 20; i ++ ) {

+ 1 - 1
examples/canvas_sandbox.html

@@ -56,7 +56,7 @@
 				group = new THREE.Group();
 				scene.add( group );
 
-				var geometry = new THREE.IcosahedronGeometry( 100, 1 );
+				var geometry = new THREE.IcosahedronBufferGeometry( 100, 1 );
 
 				var envMap = new THREE.TextureLoader().load( 'textures/metal.jpg' );
 				envMap.mapping = THREE.SphericalReflectionMapping;

+ 171 - 90
examples/js/loaders/FBXLoader.js

@@ -9,9 +9,6 @@
  *
  * Needs Support:
  *  Morph normals / blend shape normals
- *  Animation tracks for morph targets
- *
- *	Euler rotation order
  *
  * FBX format references:
  * 	https://wiki.blender.org/index.php/User:Mont29/Foundation/FBX_File_Structure
@@ -817,8 +814,6 @@
 
 		}, null );
 
-		var preTransform = new THREE.Matrix4();
-
 		// TODO: if there is more than one model associated with the geometry, AND the models have
 		// different geometric transforms, then this will cause problems
 		// if ( modelNodes.length > 1 ) { }
@@ -826,28 +821,17 @@
 		// For now just assume one model and get the preRotations from that
 		var modelNode = modelNodes[ 0 ];
 
-		if ( 'GeometricRotation' in modelNode ) {
-
-			var array = modelNode.GeometricRotation.value.map( THREE.Math.degToRad );
-			array[ 3 ] = 'ZYX';
-
-			preTransform.makeRotationFromEuler( new THREE.Euler().fromArray( array ) );
-
-		}
-
-		if ( 'GeometricTranslation' in modelNode ) {
-
-			preTransform.setPosition( new THREE.Vector3().fromArray( modelNode.GeometricTranslation.value ) );
-
-		}
+		var transformData = {};
 
-		if ( 'GeometricScaling' in modelNode ) {
+		if ( 'RotationOrder' in modelNode ) transformData.eulerOrder = modelNode.RotationOrder.value;
 
-			preTransform.scale( new THREE.Vector3().fromArray( modelNode.GeometricScaling.value ) );
+		if ( 'GeometricTranslation' in modelNode ) transformData.translation = modelNode.GeometricTranslation.value;
+		if ( 'GeometricRotation' in modelNode ) transformData.rotation = modelNode.GeometricRotation.value;
+		if ( 'GeometricScaling' in modelNode ) transformData.scale = modelNode.GeometricScaling.value;
 
-		}
+		var transform = generateTransform( transformData );
 
-		return genGeometry( FBXTree, geoNode, skeleton, morphTarget, preTransform );
+		return genGeometry( FBXTree, geoNode, skeleton, morphTarget, transform );
 
 	}
 
@@ -1647,10 +1631,19 @@
 
 		bindSkeleton( FBXTree, deformers.skeletons, geometryMap, modelMap, connections );
 		addAnimations( FBXTree, connections, sceneGraph );
+
 		createAmbientLight( FBXTree, sceneGraph );
 
 		setupMorphMaterials( sceneGraph );
 
+		// if all the models where already combined in a single group, just return that
+		if ( sceneGraph.children.length === 1 && sceneGraph.children[ 0 ].isGroup ) {
+
+			sceneGraph.children[ 0 ].animations = sceneGraph.animations;
+			return sceneGraph.children[ 0 ];
+
+		}
+
 		return sceneGraph;
 
 	}
@@ -1734,7 +1727,7 @@
 
 			}
 
-			setModelTransforms( FBXTree, model, node );
+			setModelTransforms( model, node );
 			modelMap.set( id, model );
 
 		}
@@ -2147,69 +2140,25 @@
 	}
 
 	// parse the model node for transform details and apply them to the model
-	function setModelTransforms( FBXTree, model, modelNode ) {
-
-		// http://help.autodesk.com/view/FBX/2017/ENU/?guid=__cpp_ref_class_fbx_euler_html
-		if ( 'RotationOrder' in modelNode ) {
-
-			var enums = [
-				'XYZ', // default
-				'XZY',
-				'YZX',
-				'ZXY',
-				'YXZ',
-				'ZYX',
-				'SphericXYZ',
-			];
+	function setModelTransforms( model, modelNode ) {
 
-			var value = parseInt( modelNode.RotationOrder.value, 10 );
+		var transformData = {};
 
-			if ( value > 0 && value < 6 ) {
+		if ( 'RotationOrder' in modelNode ) transformData.eulerOrder = parseInt( modelNode.RotationOrder.value );
 
-				// model.rotation.order = enums[ value ];
+		if ( 'Lcl_Translation' in modelNode ) transformData.translation = modelNode.Lcl_Translation.value;
+		if ( 'RotationOffset' in modelNode ) transformData.rotationOffset = modelNode.RotationOffset.value;
 
-				// Note: Euler order other than XYZ is currently not supported, so just display a warning for now
-				console.warn( 'THREE.FBXLoader: unsupported Euler Order: %s. Currently only XYZ order is supported. Animations and rotations may be incorrect.', enums[ value ] );
+		if ( 'Lcl_Rotation' in modelNode ) transformData.rotation = modelNode.Lcl_Rotation.value;
+		if ( 'PreRotation' in modelNode ) transformData.preRotation = modelNode.PreRotation.value;
 
-			} else if ( value === 6 ) {
+		if ( 'PostRotation' in modelNode ) transformData.postRotation = modelNode.PostRotation.value;
 
-				console.warn( 'THREE.FBXLoader: unsupported Euler Order: Spherical XYZ. Animations and rotations may be incorrect.' );
+		if ( 'Lcl_Scaling' in modelNode ) transformData.scale = modelNode.Lcl_Scaling.value;
 
-			}
-
-		}
+		var transform = generateTransform( transformData );
 
-		if ( 'Lcl_Translation' in modelNode ) {
-
-			model.position.fromArray( modelNode.Lcl_Translation.value );
-
-		}
-
-		if ( 'Lcl_Rotation' in modelNode ) {
-
-			var rotation = modelNode.Lcl_Rotation.value.map( THREE.Math.degToRad );
-			rotation.push( 'ZYX' );
-			model.quaternion.setFromEuler( new THREE.Euler().fromArray( rotation ) );
-
-		}
-
-		if ( 'Lcl_Scaling' in modelNode ) {
-
-			model.scale.fromArray( modelNode.Lcl_Scaling.value );
-
-		}
-
-		if ( 'PreRotation' in modelNode ) {
-
-			var array = modelNode.PreRotation.value.map( THREE.Math.degToRad );
-			array[ 3 ] = 'ZYX';
-
-			var preRotations = new THREE.Euler().fromArray( array );
-
-			preRotations = new THREE.Quaternion().setFromEuler( preRotations );
-			model.quaternion.premultiply( preRotations );
-
-		}
+		model.applyMatrix( transform );
 
 	}
 
@@ -2297,6 +2246,7 @@
 		var curveNodesMap = parseAnimationCurveNodes( FBXTree );
 
 		parseAnimationCurves( FBXTree, connections, curveNodesMap );
+
 		var layersMap = parseAnimationLayers( FBXTree, connections, curveNodesMap );
 		var rawClips = parseAnimStacks( FBXTree, connections, layersMap );
 
@@ -2380,7 +2330,7 @@
 
 					curveNodesMap.get( animationCurveID ).curves[ 'z' ] = animationCurve;
 
-				} else if ( animationCurveRelationship.match( /d|DeformPercent/ ) ) {
+				} else if ( animationCurveRelationship.match( /d|DeformPercent/ ) && curveNodesMap.has( animationCurveID ) ) {
 
 					curveNodesMap.get( animationCurveID ).curves[ 'morph' ] = animationCurve;
 
@@ -2439,18 +2389,16 @@
 									initialPosition: [ 0, 0, 0 ],
 									initialRotation: [ 0, 0, 0 ],
 									initialScale: [ 1, 1, 1 ],
+									transform: getModelAnimTransform( rawModel ),
 
 								};
 
-								if ( 'Lcl_Translation' in rawModel ) node.initialPosition = rawModel.Lcl_Translation.value;
-
-								if ( 'Lcl_Rotation' in rawModel ) node.initialRotation = rawModel.Lcl_Rotation.value;
-
-								if ( 'Lcl_Scaling' in rawModel ) node.initialScale = rawModel.Lcl_Scaling.value;
+								node.transform = getModelAnimTransform( rawModel );
 
-								// if the animated model is pre rotated, we'll have to apply the pre rotations to every
+								// if the animated model is pre or post rotated, we'll have to apply the pre rotations to every
 								// animation value as well
 								if ( 'PreRotation' in rawModel ) node.preRotations = rawModel.PreRotation.value;
+								if ( 'PostRotation' in rawModel ) node.postRotations = rawModel.PostRotation.value;
 
 								layerCurveNodes[ i ] = node;
 
@@ -2507,6 +2455,26 @@
 
 	}
 
+	function getModelAnimTransform( modelNode ) {
+
+		var transformData = {};
+
+		if ( 'RotationOrder' in modelNode ) transformData.eulerOrder = parseInt( modelNode.RotationOrder.value );
+
+		if ( 'Lcl_Translation' in modelNode ) transformData.translation = modelNode.Lcl_Translation.value;
+		if ( 'RotationOffset' in modelNode ) transformData.rotationOffset = modelNode.RotationOffset.value;
+
+		if ( 'Lcl_Rotation' in modelNode ) transformData.rotation = modelNode.Lcl_Rotation.value;
+		if ( 'PreRotation' in modelNode ) transformData.preRotation = modelNode.PreRotation.value;
+
+		if ( 'PostRotation' in modelNode ) transformData.postRotation = modelNode.PostRotation.value;
+
+		if ( 'Lcl_Scaling' in modelNode ) transformData.scale = modelNode.Lcl_Scaling.value;
+
+		return generateTransform( transformData );
+
+	}
+
 	// parse nodes in FBXTree.Objects.AnimationStack. These are the top level node in the animation
 	// hierarchy. Each Stack node will be used to create a THREE.AnimationClip
 	function parseAnimStacks( FBXTree, connections, layersMap ) {
@@ -2582,28 +2550,39 @@
 
 		var tracks = [];
 
+		var initialPosition = new THREE.Vector3();
+		var initialRotation = new THREE.Quaternion();
+		var initialScale = new THREE.Vector3();
+
+		if ( rawTracks.transform ) rawTracks.transform.decompose( initialPosition, initialRotation, initialScale );
+
+		initialPosition = initialPosition.toArray();
+		initialRotation = new THREE.Euler().setFromQuaternion( initialRotation ).toArray(); // todo: euler order
+		initialScale = initialScale.toArray();
+
 		if ( rawTracks.T !== undefined && Object.keys( rawTracks.T.curves ).length > 0 ) {
 
-			var positionTrack = generateVectorTrack( rawTracks.modelName, rawTracks.T.curves, rawTracks.initialPosition, 'position' );
+			var positionTrack = generateVectorTrack( rawTracks.modelName, rawTracks.T.curves, initialPosition, 'position' );
 			if ( positionTrack !== undefined ) tracks.push( positionTrack );
 
 		}
 
 		if ( rawTracks.R !== undefined && Object.keys( rawTracks.R.curves ).length > 0 ) {
 
-			var rotationTrack = generateRotationTrack( rawTracks.modelName, rawTracks.R.curves, rawTracks.initialRotation, rawTracks.preRotations );
+			var rotationTrack = generateRotationTrack( rawTracks.modelName, rawTracks.R.curves, initialRotation, rawTracks.preRotations, rawTracks.postRotations );
 			if ( rotationTrack !== undefined ) tracks.push( rotationTrack );
 
 		}
 
 		if ( rawTracks.S !== undefined && Object.keys( rawTracks.S.curves ).length > 0 ) {
 
-			var scaleTrack = generateVectorTrack( rawTracks.modelName, rawTracks.S.curves, rawTracks.initialScale, 'scale' );
+			var scaleTrack = generateVectorTrack( rawTracks.modelName, rawTracks.S.curves, initialScale, 'scale' );
 			if ( scaleTrack !== undefined ) tracks.push( scaleTrack );
 
 		}
 
 		if ( rawTracks.DeformPercent !== undefined ) {
+
 			var morphTrack = generateMorphTrack( rawTracks, sceneGraph );
 			if ( morphTrack !== undefined ) tracks.push( morphTrack );
 
@@ -2622,7 +2601,7 @@
 
 	}
 
-	function generateRotationTrack( modelName, curves, initialValue, preRotations ) {
+	function generateRotationTrack( modelName, curves, initialValue, preRotations, postRotations ) {
 
 		if ( curves.x !== undefined ) {
 
@@ -2656,6 +2635,16 @@
 
 		}
 
+		if ( postRotations !== undefined ) {
+
+			postRotations = postRotations.map( THREE.Math.degToRad );
+			postRotations.push( 'ZYX' );
+
+			postRotations = new THREE.Euler().fromArray( postRotations );
+			postRotations = new THREE.Quaternion().setFromEuler( postRotations );
+
+		}
+
 		var quaternion = new THREE.Quaternion();
 		var euler = new THREE.Euler();
 
@@ -3802,6 +3791,98 @@
 
 	}
 
+	var tempMat = new THREE.Matrix4();
+	var tempEuler = new THREE.Euler();
+	var tempVec = new THREE.Vector3();
+	var translation = new THREE.Vector3();
+	var rotation = new THREE.Matrix4();
+
+	// generate transformation from FBX transform data
+	// ref: https://help.autodesk.com/view/FBX/2017/ENU/?guid=__files_GUID_10CDD63C_79C1_4F2D_BB28_AD2BE65A02ED_htm
+	// transformData = {
+	//	 eulerOrder: int,
+	//	 translation: [],
+	//   rotationOffset: [],
+	//	 preRotation
+	//	 rotation
+	//	 postRotation
+	//   scale
+	// }
+	// all entries are optional
+	function generateTransform( transformData ) {
+
+		var transform = new THREE.Matrix4();
+		translation.set( 0, 0, 0 );
+		rotation.identity();
+
+		var order = ( transformData.eulerOrder ) ? getEulerOrder( transformData.eulerOrder ) : getEulerOrder( 0 );
+
+		if ( transformData.translation ) translation.fromArray( transformData.translation );
+		if ( transformData.rotationOffset ) translation.add( tempVec.fromArray( transformData.rotationOffset ) );
+
+		if ( transformData.rotation ) {
+
+			var array = transformData.rotation.map( THREE.Math.degToRad );
+			array.push( order );
+			rotation.makeRotationFromEuler( tempEuler.fromArray( array ) );
+
+		}
+
+		if ( transformData.preRotation ) {
+
+			var array = transformData.preRotation.map( THREE.Math.degToRad );
+			array.push( order );
+			tempMat.makeRotationFromEuler( tempEuler.fromArray( array ) );
+
+			rotation.premultiply( tempMat );
+
+		}
+
+		if ( transformData.postRotation ) {
+
+			var array = transformData.postRotation.map( THREE.Math.degToRad );
+			array.push( order );
+			tempMat.makeRotationFromEuler( tempEuler.fromArray( array ) );
+
+			tempMat.getInverse( tempMat );
+
+			rotation.multiply( tempMat );
+
+		}
+
+		if ( transformData.scale ) transform.scale( tempVec.fromArray( transformData.scale ) );
+
+		transform.setPosition( translation );
+		transform.multiply( rotation );
+
+		return transform;
+
+	}
+
+	// Returns the three.js intrinsic Euler order corresponding to FBX extrinsic Euler order
+	// ref: http://help.autodesk.com/view/FBX/2017/ENU/?guid=__cpp_ref_class_fbx_euler_html
+	function getEulerOrder( order ) {
+
+		var enums = [
+			'ZYX', // -> XYZ extrinsic
+			'YZX', // -> XZY extrinsic
+			'XZY', // -> YZX extrinsic
+			'ZXY', // -> YXZ extrinsic
+			'YXZ', // -> ZXY extrinsic
+			'XYZ', // -> ZYX extrinsic
+			//'SphericXYZ', // not possible to support
+		];
+
+		if ( order === 6 ) {
+
+			console.warn( 'THREE.FBXLoader: unsupported Euler Order: Spherical XYZ. Animations and rotations may be incorrect.' );
+			return enums[ 0 ];
+
+		}
+
+		return enums[ order ];
+
+	}
 
 	// Parses comma separated list of numbers and returns them an array.
 	// Used internally by the TextParser

+ 48 - 70
examples/js/loaders/GLTFLoader.js

@@ -272,28 +272,22 @@ THREE.GLTFLoader = ( function () {
 
 		this.name = EXTENSIONS.KHR_LIGHTS_PUNCTUAL;
 
-		this.lights = {};
+		this.lights = [];
 
 		var extension = ( json.extensions && json.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ] ) || {};
-		var lights = extension.lights || {};
+		var lightDefs = extension.lights || [];
 
-		for ( var lightId in lights ) {
+		for ( var i = 0; i < lightDefs.length; i ++ ) {
 
-			var light = lights[ lightId ];
+			var lightDef = lightDefs[ i ];
 			var lightNode;
 
-			// the color default value is [1, 1, 1]
 			var color = new THREE.Color( 0xffffff );
-			if ( light.color !== undefined ) {
-				color.fromArray( light.color )
-			}
+			if ( lightDef.color !== undefined ) color.fromArray( lightDef.color );
 
-			var range = 0;
-			if ( light.range !== undefined ) {
-				range = light.range;
-			}
+			var range = lightDef.range !== undefined ? lightDef.range : 0;
 
-			switch ( light.type ) {
+			switch ( lightDef.type ) {
 
 				case 'directional':
 					lightNode = new THREE.DirectionalLight( color );
@@ -310,31 +304,27 @@ THREE.GLTFLoader = ( function () {
 					lightNode = new THREE.SpotLight( color );
 					lightNode.distance = range;
 					// Handle spotlight properties.
-					light.spot = light.spot || {};
-					light.spot.innerConeAngle = light.spot.innerConeAngle !== undefined ? light.spot.innerConeAngle : 0;
-					light.spot.outerConeAngle = light.spot.outerConeAngle !== undefined ? light.spot.outerConeAngle : Math.PI / 4.0;
-					lightNode.angle = light.spot.outerConeAngle;
-					lightNode.penumbra = 1.0 - light.spot.innerConeAngle / light.spot.outerConeAngle;
+					lightDef.spot = lightDef.spot || {};
+					lightDef.spot.innerConeAngle = lightDef.spot.innerConeAngle !== undefined ? lightDef.spot.innerConeAngle : 0;
+					lightDef.spot.outerConeAngle = lightDef.spot.outerConeAngle !== undefined ? lightDef.spot.outerConeAngle : Math.PI / 4.0;
+					lightNode.angle = lightDef.spot.outerConeAngle;
+					lightNode.penumbra = 1.0 - lightDef.spot.innerConeAngle / lightDef.spot.outerConeAngle;
 					lightNode.target.position.set( 0, 0, 1 );
 					lightNode.add( lightNode.target );
 					break;
 
-			}
-
-			if ( lightNode ) {
-
-				lightNode.decay = 2;
+				default:
+					throw new Error( 'THREE.GLTFLoader: Unexpected light type, "' + lightDef.type + '".' );
 
-				if ( light.intensity !== undefined ) {
+			}
 
-					lightNode.intensity = light.intensity;
+			lightNode.decay = 2;
 
-				}
+			if ( lightDef.intensity !== undefined ) lightNode.intensity = lightDef.intensity;
 
-				lightNode.name = light.name || ( 'light_' + lightId );
-				this.lights[ lightId ] = lightNode;
+			lightNode.name = lightDef.name || ( 'light_' + i );
 
-			}
+			this.lights.push( lightNode );
 
 		}
 
@@ -1026,21 +1016,6 @@ THREE.GLTFLoader = ( function () {
 		10497: THREE.RepeatWrapping
 	};
 
-	var WEBGL_TEXTURE_FORMATS = {
-		6406: THREE.AlphaFormat,
-		6407: THREE.RGBFormat,
-		6408: THREE.RGBAFormat,
-		6409: THREE.LuminanceFormat,
-		6410: THREE.LuminanceAlphaFormat
-	};
-
-	var WEBGL_TEXTURE_DATATYPES = {
-		5121: THREE.UnsignedByteType,
-		32819: THREE.UnsignedShort4444Type,
-		32820: THREE.UnsignedShort5551Type,
-		33635: THREE.UnsignedShort565Type
-	};
-
 	var WEBGL_SIDES = {
 		1028: THREE.BackSide, // Culling front
 		1029: THREE.FrontSide // Culling back
@@ -1195,6 +1170,28 @@ THREE.GLTFLoader = ( function () {
 
 	}
 
+	/**
+	 * @param {THREE.Object3D|THREE.Material|THREE.BufferGeometry} object
+	 * @param {GLTF.definition} def
+	 */
+	function assignExtrasToUserData( object, gltfDef ) {
+
+		if ( gltfDef.extras !== undefined ) {
+
+			if ( typeof gltfDef.extras === 'object' ) {
+
+				object.userData = gltfDef.extras;
+
+			} else {
+
+				console.warn( 'THREE.GLTFLoader: Ignoring primitive type .extras, ' + gltfDef.extras );
+
+			}
+
+		}
+
+	}
+
 	/**
 	 * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#morph-targets
 	 *
@@ -2021,22 +2018,6 @@ THREE.GLTFLoader = ( function () {
 
 			if ( textureDef.name !== undefined ) texture.name = textureDef.name;
 
-			// .format of dds texture is set in DDSLoader
-			if ( ! textureExtensions[ EXTENSIONS.MSFT_TEXTURE_DDS ] ) {
-
-				texture.format = textureDef.format !== undefined ? WEBGL_TEXTURE_FORMATS[ textureDef.format ] : THREE.RGBAFormat;
-
-			}
-
-			if ( textureDef.internalFormat !== undefined && texture.format !== WEBGL_TEXTURE_FORMATS[ textureDef.internalFormat ] ) {
-
-				console.warn( 'THREE.GLTFLoader: Three.js does not support texture internalFormat which is different from texture format. ' +
-											'internalFormat will be forced to be the same value as format.' );
-
-			}
-
-			texture.type = textureDef.type !== undefined ? WEBGL_TEXTURE_DATATYPES[ textureDef.type ] : THREE.UnsignedByteType;
-
 			var samplers = json.samplers || {};
 			var sampler = samplers[ textureDef.sampler ] || {};
 
@@ -2229,7 +2210,7 @@ THREE.GLTFLoader = ( function () {
 			if ( material.emissiveMap ) material.emissiveMap.encoding = THREE.sRGBEncoding;
 			if ( material.specularMap ) material.specularMap.encoding = THREE.sRGBEncoding;
 
-			if ( materialDef.extras ) material.userData = materialDef.extras;
+			assignExtrasToUserData( material, materialDef );
 
 			if ( materialDef.extensions ) addUnknownExtensionsToUserData( extensions, material, materialDef );
 
@@ -2273,11 +2254,7 @@ THREE.GLTFLoader = ( function () {
 
 		}
 
-		if ( primitiveDef.extras !== undefined ) {
-
-			geometry.userData = primitiveDef.extras;
-
-		}
+		assignExtrasToUserData( geometry, primitiveDef );
 
 	}
 
@@ -2546,7 +2523,7 @@ THREE.GLTFLoader = ( function () {
 
 					if ( geometries.length > 1 ) mesh.name += '_' + i;
 
-					if ( meshDef.extras !== undefined ) mesh.userData = meshDef.extras;
+					assignExtrasToUserData( mesh, meshDef );
 
 					meshes.push( mesh );
 
@@ -2714,7 +2691,8 @@ THREE.GLTFLoader = ( function () {
 		}
 
 		if ( cameraDef.name !== undefined ) camera.name = cameraDef.name;
-		if ( cameraDef.extras ) camera.userData = cameraDef.extras;
+
+		assignExtrasToUserData( camera, cameraDef );
 
 		return Promise.resolve( camera );
 
@@ -2981,7 +2959,7 @@ THREE.GLTFLoader = ( function () {
 
 			}
 
-			if ( nodeDef.extras ) node.userData = nodeDef.extras;
+			assignExtrasToUserData( node, nodeDef );
 
 			if ( nodeDef.extensions ) addUnknownExtensionsToUserData( extensions, node, nodeDef );
 
@@ -3115,7 +3093,7 @@ THREE.GLTFLoader = ( function () {
 				var scene = new THREE.Scene();
 				if ( sceneDef.name !== undefined ) scene.name = sceneDef.name;
 
-				if ( sceneDef.extras ) scene.userData = sceneDef.extras;
+				assignExtrasToUserData( scene, sceneDef );
 
 				if ( sceneDef.extensions ) addUnknownExtensionsToUserData( extensions, scene, sceneDef );
 

+ 316 - 24
examples/js/loaders/SVGLoader.js

@@ -1,6 +1,7 @@
 /**
  * @author mrdoob / http://mrdoob.com/
  * @author zz85 / http://joshuakoo.com/
+ * @author yomboprime / https://yombo.org
  */
 
 THREE.SVGLoader = function ( manager ) {
@@ -32,6 +33,10 @@ THREE.SVGLoader.prototype = {
 
 			if ( node.nodeType !== 1 ) return;
 
+			var transform = getNodeTransform( node );
+
+			var path = null;
+
 			switch ( node.nodeName ) {
 
 				case 'svg':
@@ -43,37 +48,37 @@ THREE.SVGLoader.prototype = {
 
 				case 'path':
 					style = parseStyle( node, style );
-					if ( node.hasAttribute( 'd' ) && isVisible( style ) ) paths.push( parsePathNode( node, style ) );
+					if ( node.hasAttribute( 'd' ) && isVisible( style ) ) path = parsePathNode( node, style );
 					break;
 
 				case 'rect':
 					style = parseStyle( node, style );
-					if ( isVisible( style ) ) paths.push( parseRectNode( node, style ) );
+					if ( isVisible( style ) ) path = parseRectNode( node, style );
 					break;
 
 				case 'polygon':
 					style = parseStyle( node, style );
-					if ( isVisible( style ) ) paths.push( parsePolygonNode( node, style ) );
+					if ( isVisible( style ) ) path = parsePolygonNode( node, style );
 					break;
 
 				case 'polyline':
 					style = parseStyle( node, style );
-					if ( isVisible( style ) ) paths.push( parsePolylineNode( node, style ) );
+					if ( isVisible( style ) ) path = parsePolylineNode( node, style );
 					break;
 
 				case 'circle':
 					style = parseStyle( node, style );
-					if ( isVisible( style ) ) paths.push( parseCircleNode( node, style ) );
+					if ( isVisible( style ) ) path = parseCircleNode( node, style );
 					break;
 
 				case 'ellipse':
 					style = parseStyle( node, style );
-					if ( isVisible( style ) ) paths.push( parseEllipseNode( node, style ) );
+					if ( isVisible( style ) ) path = parseEllipseNode( node, style );
 					break;
 
 				case 'line':
 					style = parseStyle( node, style );
-					if ( isVisible( style ) ) paths.push( parseLineNode( node, style ) );
+					if ( isVisible( style ) ) path = parseLineNode( node, style );
 					break;
 
 				default:
@@ -81,6 +86,14 @@ THREE.SVGLoader.prototype = {
 
 			}
 
+			if ( path ) {
+
+				transformPath( path, currentTransform );
+
+				paths.push( path );
+
+			}
+
 			var nodes = node.childNodes;
 
 			for ( var i = 0; i < nodes.length; i ++ ) {
@@ -89,6 +102,12 @@ THREE.SVGLoader.prototype = {
 
 			}
 
+			if ( transform ) {
+
+				currentTransform.copy( transformStack.pop() );
+
+			}
+
 		}
 
 		function parsePathNode( node, style ) {
@@ -99,6 +118,10 @@ THREE.SVGLoader.prototype = {
 			var point = new THREE.Vector2();
 			var control = new THREE.Vector2();
 
+			var firstPoint = new THREE.Vector2();
+			var isFirstPoint = true;
+			var doSetFirstPoint = false;
+
 			var d = node.getAttribute( 'd' );
 
 			// console.log( d );
@@ -112,6 +135,11 @@ THREE.SVGLoader.prototype = {
 				var type = command.charAt( 0 );
 				var data = command.substr( 1 ).trim();
 
+				if ( isFirstPoint ) {
+					doSetFirstPoint = true;
+				}
+				isFirstPoint = false;
+
 				switch ( type ) {
 
 					case 'M':
@@ -121,7 +149,11 @@ THREE.SVGLoader.prototype = {
 							point.y = numbers[ j + 1 ];
 							control.x = point.x;
 							control.y = point.y;
-							path.moveTo( point.x, point.y );
+							if ( j === 0 ) {
+								path.moveTo( point.x, point.y );
+							} else {
+								path.lineTo( point.x, point.y );
+							}
 						}
 						break;
 
@@ -249,7 +281,11 @@ THREE.SVGLoader.prototype = {
 							point.y += numbers[ j + 1 ];
 							control.x = point.x;
 							control.y = point.y;
-							path.moveTo( point.x, point.y );
+							if ( j === 0 ) {
+								path.moveTo( point.x, point.y );
+							} else {
+								path.lineTo( point.x, point.y );
+							}
 						}
 						break;
 
@@ -375,21 +411,9 @@ THREE.SVGLoader.prototype = {
 						path.currentPath.autoClose = true;
 						if ( path.currentPath.curves.length > 0 ) {
 							// Reset point to beginning of Path
-							var curve = path.currentPath.curves[ 0 ];
-							if ( curve.isLineCurve ) {
-								point.x = curve.v1.x;
-								point.y = curve.v1.y;
-							} else if ( curve.isEllipseCurve || curve.isArcCurve ) {
-								point.x = curve.aX;
-								point.y = curve.aY;
-							} else if ( curve.isCubicBezierCurve || curve.isQuadraticBezierCurve ) {
-								point.x = curve.v0.x;
-								point.y = curve.v0.y;
-							} else if ( curve.isSplineCurve ) {
-								point.x = curve.points[ 0 ].x;
-								point.y = curve.points[ 0 ].y;
-							}
+							point.copy( firstPoint );
 							path.currentPath.currentPoint.copy( point );
+							isFirstPoint = true;
 						}
 						break;
 
@@ -400,6 +424,13 @@ THREE.SVGLoader.prototype = {
 
 				// console.log( type, parseFloats( data ), parseFloats( data ).length  )
 
+				if ( doSetFirstPoint ) {
+
+					firstPoint.copy( point );
+
+					doSetFirstPoint = false;
+
+				}
 			}
 
 			return path;
@@ -503,7 +534,13 @@ THREE.SVGLoader.prototype = {
 			if ( rx !== 0 || ry !== 0 ) {
 
 				path.bezierCurveTo( x, y + h, x, y + h, x, y + h - 2 * ry );
-				path.lineTo( x, y + 2 * ry );
+
+			}
+
+			path.lineTo( x, y + 2 * ry );
+
+			if ( rx !== 0 || ry !== 0 ) {
+
 				path.bezierCurveTo( x, y, x, y, x + 2 * rx, y );
 
 			}
@@ -683,6 +720,252 @@ THREE.SVGLoader.prototype = {
 
 			return array;
 
+
+		}
+
+		function getNodeTransform( node ) {
+
+			if ( ! node.hasAttribute( 'transform' ) ) {
+				return null;
+			}
+
+			var transform = parseTransformNode( node );
+
+			if ( transform ) {
+
+				if ( transformStack.length > 0 ) {
+					transform.premultiply( transformStack[ transformStack.length - 1 ] );
+				}
+
+				currentTransform.copy( transform );
+				transformStack.push( transform );
+
+			}
+
+			return transform;
+
+		}
+
+		function parseTransformNode( node ) {
+
+			var transformAttr = node.getAttribute( 'transform' );
+			var transform = null;
+			var openParPos = transformAttr.indexOf( "(" );
+			var closeParPos = transformAttr.indexOf( ")" );
+
+			if ( openParPos > 0 && openParPos < closeParPos ) {
+
+				var transformType = transformAttr.substr( 0, openParPos );
+
+				var array = parseFloats( transformAttr.substr( openParPos + 1, closeParPos - openParPos - 1 ) );
+
+				switch ( transformType ) {
+
+					case "translate":
+
+						if ( array.length >= 1 ) {
+
+							transform = new THREE.Matrix3();
+
+							var tx = array[ 0 ];
+							var ty = tx;
+
+							if ( array.length >= 2 ) {
+
+								ty = array[ 1 ];
+
+							}
+
+							transform.translate( tx, ty );
+
+						}
+
+						break;
+
+					case "rotate":
+
+						if ( array.length >= 1 ) {
+
+							var angle = 0;
+							var cx = 0;
+							var cy = 0;
+
+							transform = new THREE.Matrix3();
+
+							// Angle
+							angle = - array[ 0 ] * Math.PI / 180;
+
+							if ( array.length >= 3 ) {
+
+								// Center x, y
+								cx = array[ 1 ];
+								cy = array[ 2 ];
+
+							}
+
+							// Rotate around center (cx, cy)
+							tempTransform1.identity().translate( -cx, -cy );
+							tempTransform2.identity().rotate( angle );
+							tempTransform3.multiplyMatrices( tempTransform2, tempTransform1 );
+							tempTransform1.identity().translate( cx, cy );
+							transform.multiplyMatrices( tempTransform1, tempTransform3 );
+
+						}
+
+						break;
+
+					case "scale":
+
+						if ( array.length >= 1 ) {
+
+							transform = new THREE.Matrix3();
+
+							var scaleX = array[ 0 ];
+							var scaleY = scaleX;
+
+							if ( array.length >= 2 ) {
+								scaleY = array[ 1 ];
+							}
+
+							transform.scale( scaleX, scaleY );
+
+						}
+
+						break;
+
+					case "skewX":
+
+						if ( array.length === 1 ) {
+
+							transform = new THREE.Matrix3();
+
+							transform.set(
+								1, Math.tan( array[ 0 ] * Math.PI / 180 ), 0,
+								0, 1, 0,
+								0, 0, 1
+							);
+
+						}
+
+						break;
+
+					case "skewY":
+
+						if ( array.length === 1 ) {
+
+							transform = new THREE.Matrix3();
+
+							transform.set(
+								1, 0, 0,
+								Math.tan( array[ 0 ] * Math.PI / 180 ), 1, 0,
+								0, 0, 1
+							);
+
+						}
+
+						break;
+
+					case "matrix":
+
+						if ( array.length === 6 ) {
+
+							transform = new THREE.Matrix3();
+
+							transform.set(
+								array[ 0 ], array[ 2 ], array[ 4 ],
+								array[ 1 ], array[ 3 ], array[ 5 ],
+								0, 0, 1
+							);
+
+						}
+
+						break;
+				}
+
+			}
+
+			return transform;
+
+		}
+
+		function transformPath( path, m ) {
+
+			function transfVec2( v2 ) {
+
+				tempV3.set( v2.x, v2.y, 1 ).applyMatrix3( m );
+
+				v2.set( tempV3.x, tempV3.y );
+
+			}
+
+			var isRotated = isTransformRotated( m );
+
+			var tempV2 = new THREE.Vector2();
+			var tempV3 = new THREE.Vector3();
+
+			var subPaths = path.subPaths;
+
+			for ( var i = 0, n = subPaths.length; i < n; i++ ) {
+
+				var subPath = subPaths[ i ];
+				var curves = subPath.curves;
+
+				for ( var j = 0; j < curves.length; j++ ) {
+
+					var curve = curves[ j ];
+
+					if ( curve.isLineCurve ) {
+
+						transfVec2( curve.v1 );
+						transfVec2( curve.v2 );
+
+					} else if ( curve.isCubicBezierCurve ) {
+
+						transfVec2( curve.v0 );
+						transfVec2( curve.v1 );
+						transfVec2( curve.v2 );
+						transfVec2( curve.v3 );
+
+					} else if ( curve.isQuadraticBezierCurve ) {
+
+						transfVec2( curve.v0 );
+						transfVec2( curve.v1 );
+						transfVec2( curve.v2 );
+
+					} else if ( curve.isEllipseCurve ) {
+
+						if ( isRotated ) {
+							console.warn( "SVGLoader: Elliptic arc or ellipse rotation or skewing is not implemented." );
+						}
+
+						tempV2.set( curve.aX, curve.aY );
+						transfVec2( tempV2 );
+						curve.aX = tempV2.x;
+						curve.aY = tempV2.y;
+
+						curve.xRadius *= getTransformScaleX( m );
+						curve.yRadius *= getTransformScaleY( m );
+
+					}
+
+				}
+
+			}
+
+		}
+
+		function isTransformRotated( m ) {
+			return m.elements[ 1 ] !== 0 || m.elements[ 3 ] !== 0;
+		}
+
+		function getTransformScaleX( m ) {
+			var te = m.elements;
+			return Math.sqrt( te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] )
+		}
+
+		function getTransformScaleY( m ) {
+			var te = m.elements;
+			return Math.sqrt( te[ 3 ] * te[ 3 ] + te[ 4 ] * te[ 4 ] )
 		}
 
 		//
@@ -691,6 +974,14 @@ THREE.SVGLoader.prototype = {
 
 		var paths = [];
 
+		var transformStack = [];
+
+		var tempTransform1 = new THREE.Matrix3();
+		var tempTransform2 = new THREE.Matrix3();
+		var tempTransform3 = new THREE.Matrix3();
+
+		var currentTransform = new THREE.Matrix3();
+
 		console.time( 'THREE.SVGLoader: DOMParser' );
 
 		var xml = new DOMParser().parseFromString( text, 'image/svg+xml' ); // application/xml
@@ -703,6 +994,7 @@ THREE.SVGLoader.prototype = {
 
 		// console.log( paths );
 
+
 		console.timeEnd( 'THREE.SVGLoader: Parse' );
 
 		return paths;

+ 45 - 9
examples/js/renderers/Projector.js

@@ -281,7 +281,7 @@ THREE.Projector = function () {
 
 		}
 
-		function pushTriangle( a, b, c ) {
+		function pushTriangle( a, b, c, material ) {
 
 			var v1 = _vertexPool[ a ];
 			var v2 = _vertexPool[ b ];
@@ -300,9 +300,11 @@ THREE.Projector = function () {
 				_face.z = ( v1.positionScreen.z + v2.positionScreen.z + v3.positionScreen.z ) / 3;
 				_face.renderOrder = object.renderOrder;
 
-				// use first vertex normal as face normal
-
-				_face.normalModel.fromArray( normals, a * 3 );
+				// face normal
+				_vector3.subVectors( v3.position, v2.position );
+				_vector4.subVectors( v1.position, v2.position );
+				_vector3.cross( _vector4 );
+				_face.normalModel.copy( _vector3 );
 				_face.normalModel.applyMatrix3( normalMatrix ).normalize();
 
 				for ( var i = 0; i < 3; i ++ ) {
@@ -318,7 +320,7 @@ THREE.Projector = function () {
 
 				_face.vertexNormalsLength = 3;
 
-				_face.material = object.material;
+				_face.material = material;
 
 				_renderData.elements.push( _face );
 
@@ -442,6 +444,10 @@ THREE.Projector = function () {
 
 				if ( geometry instanceof THREE.BufferGeometry ) {
 
+					var material = object.material;
+
+					var isMultiMaterial = Array.isArray( material );
+
 					var attributes = geometry.attributes;
 					var groups = geometry.groups;
 
@@ -489,9 +495,15 @@ THREE.Projector = function () {
 
 								var group = groups[ g ];
 
+								material = isMultiMaterial === true
+									 ? object.material[ group.materialIndex ]
+									 : object.material;
+
+								if ( material === undefined ) continue;
+
 								for ( var i = group.start, l = group.start + group.count; i < l; i += 3 ) {
 
-									renderList.pushTriangle( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );
+									renderList.pushTriangle( indices[ i ], indices[ i + 1 ], indices[ i + 2 ], material );
 
 								}
 
@@ -501,7 +513,7 @@ THREE.Projector = function () {
 
 							for ( var i = 0, l = indices.length; i < l; i += 3 ) {
 
-								renderList.pushTriangle( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );
+								renderList.pushTriangle( indices[ i ], indices[ i + 1 ], indices[ i + 2 ], material );
 
 							}
 
@@ -509,9 +521,33 @@ THREE.Projector = function () {
 
 					} else {
 
-						for ( var i = 0, l = positions.length / 3; i < l; i += 3 ) {
+						if ( groups.length > 0 ) {
+
+							for ( var g = 0; g < groups.length; g ++ ) {
+
+								var group = groups[ g ];
+
+								material = isMultiMaterial === true
+									 ? object.material[ group.materialIndex ]
+									 : object.material;
 
-							renderList.pushTriangle( i, i + 1, i + 2 );
+								if ( material === undefined ) continue;
+
+								for ( var i = group.start, l = group.start + group.count; i < l; i += 3 ) {
+
+									renderList.pushTriangle( i, i + 1, i + 2, material );
+
+								}
+
+							}
+
+						} else {
+
+							for ( var i = 0, l = positions.length / 3; i < l; i += 3 ) {
+
+								renderList.pushTriangle( i, i + 1, i + 2, material );
+
+							}
 
 						}
 

+ 1 - 1
examples/js/renderers/WebGLDeferredRenderer.js

@@ -797,7 +797,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 	function createDeferredPointLight( light ) {
 
-		var mesh = createDeferredLightMesh( light, new THREE.SphereGeometry( 1, 16, 8 ) );
+		var mesh = createDeferredLightMesh( light, new THREE.SphereBufferGeometry( 1, 16, 8 ) );
 		mesh.onBeforeRender = updateDeferredPointLightUniforms;
 		return mesh;
 

+ 3 - 3
examples/misc_lights_test.html

@@ -71,7 +71,7 @@
 
 				// Spheres
 
-				geometry = new THREE.SphereGeometry( 100, 16, 8 );
+				geometry = new THREE.SphereBufferGeometry( 100, 16, 8 );
 				material = new THREE.MeshPhongMaterial( { color: 0xffffff, flatShading: true, overdraw: 0.5, shininess: 0 } );
 
 				for ( var i = 0; i < 30; i ++ ) {
@@ -87,7 +87,7 @@
 
 				// Torus
 
-				geometry = new THREE.TorusGeometry( 100, 25, 15, 30 );
+				geometry = new THREE.TorusBufferGeometry( 100, 25, 15, 30 );
 				mesh = new THREE.Mesh( geometry, material );
 				scene.add( mesh );
 
@@ -108,7 +108,7 @@
 				pointLight = new THREE.PointLight( 0xffaa00 );
 				scene.add( pointLight );
 
-				geometry = new THREE.SphereGeometry( 100, 8, 4 );
+				geometry = new THREE.SphereBufferGeometry( 100, 8, 4 );
 				material = new THREE.MeshBasicMaterial( { color: 0xffaa00 } );
 				mesh = new THREE.Mesh( geometry, material );
 				mesh.scale.set( 0.05, 0.05, 0.05 );

+ 2 - 2
examples/misc_ubiquity_test.html

@@ -62,7 +62,7 @@
 
 				// CUBES
 
-				var cube = new THREE.BoxGeometry( 100, 100, 100 );
+				var cube = new THREE.BoxBufferGeometry( 100, 100, 100 );
 
 				mesh = new THREE.Mesh( cube, new THREE.MeshBasicMaterial( { color: 0x0000ff, opacity: 0.5, transparent: true } ) );
 				mesh.position.x = 500;
@@ -88,7 +88,7 @@
 
 				// CYLINDER
 
-				mesh = new THREE.Mesh( new THREE.CylinderGeometry( 20, 100, 200, 10 ), new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff } ) );
+				mesh = new THREE.Mesh( new THREE.CylinderBufferGeometry( 20, 100, 200, 10 ), new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff } ) );
 				mesh.position.x = -500;
 				mesh.rotation.x = - Math.PI / 2;
 				mesh.scale.x = mesh.scale.y = mesh.scale.z = 2;

+ 1 - 1
examples/misc_ubiquity_test2.html

@@ -56,7 +56,7 @@
 				texture.wrapS = THREE.RepeatWrapping;
 				texture.wrapT = THREE.RepeatWrapping;
 
-				var geometry = new THREE.BoxGeometry( 150, 150, 150, 4, 4, 4 );
+				var geometry = new THREE.BoxBufferGeometry( 150, 150, 150, 4, 4, 4 );
 				var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: 0.5 } );
 
 				mesh = new THREE.Mesh( geometry, material );

BIN
examples/models/svg/tests/1.png


+ 96 - 0
examples/models/svg/tests/1.svg

@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="210mm"
+   height="297mm"
+   viewBox="0 0 210 297"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="1.svg"
+   inkscape:export-filename=""
+   inkscape:export-xdpi="149.98094"
+   inkscape:export-ydpi="149.98094">
+  <defs
+     id="defs2" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.49497475"
+     inkscape:cx="-345.56008"
+     inkscape:cy="768.64217"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1920"
+     inkscape:window-height="1015"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <g
+       aria-label="Three.js"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:22.57777786px;line-height:1.25;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
+       id="text817">
+      <path
+         d="m 39.122152,29.585705 v 1.896534 H 34.200196 V 45.232105 H 32.010152 V 31.482239 h -4.921956 v -1.896534 z"
+         style="stroke-width:0.26458332"
+         id="path814" />
+      <path
+         d="M 41.277272,45.232105 V 28.072994 l 2.099733,-0.361244 v 6.005689 q 0.587022,-0.225778 1.241778,-0.338667 0.677333,-0.135467 1.332089,-0.135467 1.399822,0 2.325511,0.4064 0.925689,0.383822 1.467555,1.106311 0.564445,0.699911 0.790222,1.693334 0.225778,0.993422 0.225778,2.190044 v 6.592711 H 48.660205 V 39.09095 q 0,-1.083734 -0.158045,-1.851378 -0.135466,-0.767645 -0.474133,-1.241778 -0.338667,-0.474133 -0.903111,-0.677333 -0.564444,-0.225778 -1.399822,-0.225778 -0.338667,0 -0.699911,0.04516 -0.361245,0.04516 -0.699911,0.112888 -0.316089,0.04516 -0.587023,0.112889 -0.248355,0.06773 -0.361244,0.112889 v 9.7536 z"
+         style="stroke-width:0.26458332"
+         id="path816" />
+      <path
+         d="m 58.488594,33.243305 q 0.270934,0 0.6096,0.04516 0.361245,0.02258 0.699912,0.09031 0.338666,0.04516 0.6096,0.112889 0.293511,0.04516 0.428977,0.09031 l -0.361244,1.8288 q -0.248356,-0.09031 -0.835378,-0.2032 -0.564444,-0.135467 -1.467555,-0.135467 -0.587023,0 -1.174045,0.135467 -0.564444,0.112889 -0.745067,0.158044 v 9.866489 H 54.153661 V 33.988372 q 0.745067,-0.270933 1.851378,-0.496711 1.106311,-0.248356 2.483555,-0.248356 z"
+         style="stroke-width:0.26458332"
+         id="path818" />
+      <path
+         d="m 62.230156,39.384461 q 0,-1.557867 0.451556,-2.709334 0.451555,-1.174044 1.196622,-1.941688 0.745067,-0.767645 1.715911,-1.151467 0.970845,-0.383822 1.986845,-0.383822 2.370666,0 3.635022,1.490133 1.264355,1.467556 1.264355,4.492978 0,0.135466 0,0.361244 0,0.2032 -0.02258,0.383822 h -8.037689 q 0.135466,1.8288 1.061155,2.777067 0.925689,0.948267 2.889956,0.948267 1.106311,0 1.851378,-0.180622 0.767644,-0.2032 1.151466,-0.383823 l 0.293511,1.761067 q -0.383822,0.2032 -1.354666,0.428978 -0.948267,0.225778 -2.167467,0.225778 -1.535289,0 -2.664178,-0.451556 -1.106311,-0.474133 -1.8288,-1.286933 -0.722489,-0.8128 -1.083733,-1.919111 -0.338667,-1.128889 -0.338667,-2.460978 z m 8.060267,-1.151467 q 0.02258,-1.4224 -0.722489,-2.325511 -0.722489,-0.925689 -2.009422,-0.925689 -0.722489,0 -1.286934,0.293511 -0.541866,0.270934 -0.925688,0.722489 -0.383823,0.451556 -0.6096,1.038578 -0.2032,0.587022 -0.270934,1.196622 z"
+         style="stroke-width:0.26458332"
+         id="path820" />
+      <path
+         d="m 74.841961,39.384461 q 0,-1.557867 0.451556,-2.709334 0.451555,-1.174044 1.196622,-1.941688 0.745067,-0.767645 1.715911,-1.151467 0.970845,-0.383822 1.986845,-0.383822 2.370666,0 3.635022,1.490133 1.264355,1.467556 1.264355,4.492978 0,0.135466 0,0.361244 0,0.2032 -0.02258,0.383822 h -8.037689 q 0.135466,1.8288 1.061155,2.777067 0.925689,0.948267 2.889956,0.948267 1.106311,0 1.851378,-0.180622 0.767644,-0.2032 1.151466,-0.383823 l 0.293511,1.761067 q -0.383822,0.2032 -1.354666,0.428978 -0.948267,0.225778 -2.167467,0.225778 -1.535289,0 -2.664178,-0.451556 -1.106311,-0.474133 -1.8288,-1.286933 -0.722489,-0.8128 -1.083733,-1.919111 -0.338667,-1.128889 -0.338667,-2.460978 z m 8.060267,-1.151467 q 0.02258,-1.4224 -0.722489,-2.325511 -0.722489,-0.925689 -2.009422,-0.925689 -0.722489,0 -1.286934,0.293511 -0.541866,0.270934 -0.925688,0.722489 -0.383823,0.451556 -0.6096,1.038578 -0.2032,0.587022 -0.270934,1.196622 z"
+         style="stroke-width:0.26458332"
+         id="path822" />
+      <path
+         d="m 90.592077,44.012905 q 0,0.6096 -0.4064,1.061156 -0.4064,0.451555 -1.106311,0.451555 -0.699911,0 -1.106311,-0.451555 -0.4064,-0.451556 -0.4064,-1.061156 0,-0.6096 0.4064,-1.061155 0.4064,-0.451556 1.106311,-0.451556 0.699911,0 1.106311,0.451556 0.4064,0.451555 0.4064,1.061155 z"
+         style="stroke-width:0.26458332"
+         id="path824" />
+      <path
+         d="m 91.745662,49.45415 q -0.270933,0 -0.699911,-0.06773 -0.428978,-0.06773 -0.722489,-0.180622 l 0.270933,-1.715911 q 0.225778,0.06773 0.519289,0.112889 0.293511,0.04516 0.541867,0.04516 1.083733,0 1.535289,-0.677333 0.474133,-0.654755 0.474133,-1.941689 V 33.491661 h 2.099734 v 11.514666 q 0,2.257778 -1.038578,3.341512 -1.016,1.106311 -2.980267,1.106311 z m 2.957689,-18.0848 q -0.564444,0 -0.970844,-0.361245 -0.383823,-0.383822 -0.383823,-1.016 0,-0.632178 0.383823,-0.993422 0.4064,-0.383822 0.970844,-0.383822 0.564444,0 0.948267,0.383822 0.4064,0.361244 0.4064,0.993422 0,0.632178 -0.4064,1.016 -0.383823,0.361245 -0.948267,0.361245 z"
+         style="stroke-width:0.26458332"
+         id="path826" />
+      <path
+         d="m 102.12932,43.719394 q 1.28693,0 1.89653,-0.338667 0.63218,-0.338666 0.63218,-1.083733 0,-0.767644 -0.6096,-1.2192 -0.6096,-0.451555 -2.00942,-1.016 -0.67733,-0.270933 -1.30951,-0.541867 -0.6096,-0.293511 -1.061158,-0.677333 -0.451555,-0.383822 -0.722489,-0.925689 -0.270933,-0.541866 -0.270933,-1.332089 0,-1.557866 1.151467,-2.460977 1.151463,-0.925689 3.138313,-0.925689 0.49671,0 0.99342,0.06773 0.49671,0.04516 0.92569,0.135467 0.42898,0.06773 0.74507,0.158044 0.33866,0.09031 0.51928,0.158045 l -0.38382,1.806222 q -0.33866,-0.180622 -1.06115,-0.361245 -0.72249,-0.2032 -1.73849,-0.2032 -0.88054,0 -1.53529,0.361245 -0.65476,0.338666 -0.65476,1.083733 0,0.383822 0.13547,0.677333 0.15804,0.293512 0.45156,0.541867 0.31608,0.225778 0.76764,0.428978 0.45156,0.2032 1.08373,0.428978 0.83538,0.316089 1.49014,0.632177 0.65475,0.293512 1.10631,0.699912 0.47413,0.4064 0.72249,0.993422 0.24835,0.564444 0.24835,1.399822 0,1.6256 -1.2192,2.460978 -1.19662,0.835378 -3.43182,0.835378 -1.55787,0 -2.4384,-0.270934 -0.880533,-0.248355 -1.196622,-0.383822 l 0.383822,-1.806222 q 0.361244,0.135466 1.15147,0.4064 0.79022,0.270933 2.09973,0.270933 z"
+         style="stroke-width:0.26458332"
+         id="path828" />
+    </g>
+  </g>
+</svg>

BIN
examples/models/svg/tests/2.png


+ 105 - 0
examples/models/svg/tests/2.svg

@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="210mm"
+   height="297mm"
+   viewBox="0 0 210 297"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="2.svg"
+   inkscape:export-filename=""
+   inkscape:export-xdpi="149.98094"
+   inkscape:export-ydpi="149.98094">
+  <defs
+     id="defs2" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.49497475"
+     inkscape:cx="180.72939"
+     inkscape:cy="809.04827"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1920"
+     inkscape:window-height="1015"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <g
+       aria-label="Three.js"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:22.57777786px;line-height:1.25;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
+       id="text817"
+       transform="rotate(-30,66.934268,38.58295)">
+      <path
+         d="m 39.122152,29.585705 v 1.896534 H 34.200196 V 45.232105 H 32.010152 V 31.482239 h -4.921956 v -1.896534 z"
+         style="stroke-width:0.26458332"
+         id="path814"
+         inkscape:connector-curvature="0" />
+      <path
+         d="M 41.277272,45.232105 V 28.072994 l 2.099733,-0.361244 v 6.005689 q 0.587022,-0.225778 1.241778,-0.338667 0.677333,-0.135467 1.332089,-0.135467 1.399822,0 2.325511,0.4064 0.925689,0.383822 1.467555,1.106311 0.564445,0.699911 0.790222,1.693334 0.225778,0.993422 0.225778,2.190044 v 6.592711 H 48.660205 V 39.09095 q 0,-1.083734 -0.158045,-1.851378 -0.135466,-0.767645 -0.474133,-1.241778 -0.338667,-0.474133 -0.903111,-0.677333 -0.564444,-0.225778 -1.399822,-0.225778 -0.338667,0 -0.699911,0.04516 -0.361245,0.04516 -0.699911,0.112888 -0.316089,0.04516 -0.587023,0.112889 -0.248355,0.06773 -0.361244,0.112889 v 9.7536 z"
+         style="stroke-width:0.26458332"
+         id="path816"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 58.488594,33.243305 q 0.270934,0 0.6096,0.04516 0.361245,0.02258 0.699912,0.09031 0.338666,0.04516 0.6096,0.112889 0.293511,0.04516 0.428977,0.09031 l -0.361244,1.8288 q -0.248356,-0.09031 -0.835378,-0.2032 -0.564444,-0.135467 -1.467555,-0.135467 -0.587023,0 -1.174045,0.135467 -0.564444,0.112889 -0.745067,0.158044 v 9.866489 H 54.153661 V 33.988372 q 0.745067,-0.270933 1.851378,-0.496711 1.106311,-0.248356 2.483555,-0.248356 z"
+         style="stroke-width:0.26458332"
+         id="path818"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 62.230156,39.384461 q 0,-1.557867 0.451556,-2.709334 0.451555,-1.174044 1.196622,-1.941688 0.745067,-0.767645 1.715911,-1.151467 0.970845,-0.383822 1.986845,-0.383822 2.370666,0 3.635022,1.490133 1.264355,1.467556 1.264355,4.492978 0,0.135466 0,0.361244 0,0.2032 -0.02258,0.383822 h -8.037689 q 0.135466,1.8288 1.061155,2.777067 0.925689,0.948267 2.889956,0.948267 1.106311,0 1.851378,-0.180622 0.767644,-0.2032 1.151466,-0.383823 l 0.293511,1.761067 q -0.383822,0.2032 -1.354666,0.428978 -0.948267,0.225778 -2.167467,0.225778 -1.535289,0 -2.664178,-0.451556 -1.106311,-0.474133 -1.8288,-1.286933 -0.722489,-0.8128 -1.083733,-1.919111 -0.338667,-1.128889 -0.338667,-2.460978 z m 8.060267,-1.151467 q 0.02258,-1.4224 -0.722489,-2.325511 -0.722489,-0.925689 -2.009422,-0.925689 -0.722489,0 -1.286934,0.293511 -0.541866,0.270934 -0.925688,0.722489 -0.383823,0.451556 -0.6096,1.038578 -0.2032,0.587022 -0.270934,1.196622 z"
+         style="stroke-width:0.26458332"
+         id="path820"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 74.841961,39.384461 q 0,-1.557867 0.451556,-2.709334 0.451555,-1.174044 1.196622,-1.941688 0.745067,-0.767645 1.715911,-1.151467 0.970845,-0.383822 1.986845,-0.383822 2.370666,0 3.635022,1.490133 1.264355,1.467556 1.264355,4.492978 0,0.135466 0,0.361244 0,0.2032 -0.02258,0.383822 h -8.037689 q 0.135466,1.8288 1.061155,2.777067 0.925689,0.948267 2.889956,0.948267 1.106311,0 1.851378,-0.180622 0.767644,-0.2032 1.151466,-0.383823 l 0.293511,1.761067 q -0.383822,0.2032 -1.354666,0.428978 -0.948267,0.225778 -2.167467,0.225778 -1.535289,0 -2.664178,-0.451556 -1.106311,-0.474133 -1.8288,-1.286933 -0.722489,-0.8128 -1.083733,-1.919111 -0.338667,-1.128889 -0.338667,-2.460978 z m 8.060267,-1.151467 q 0.02258,-1.4224 -0.722489,-2.325511 -0.722489,-0.925689 -2.009422,-0.925689 -0.722489,0 -1.286934,0.293511 -0.541866,0.270934 -0.925688,0.722489 -0.383823,0.451556 -0.6096,1.038578 -0.2032,0.587022 -0.270934,1.196622 z"
+         style="stroke-width:0.26458332"
+         id="path822"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 90.592077,44.012905 q 0,0.6096 -0.4064,1.061156 -0.4064,0.451555 -1.106311,0.451555 -0.699911,0 -1.106311,-0.451555 -0.4064,-0.451556 -0.4064,-1.061156 0,-0.6096 0.4064,-1.061155 0.4064,-0.451556 1.106311,-0.451556 0.699911,0 1.106311,0.451556 0.4064,0.451555 0.4064,1.061155 z"
+         style="stroke-width:0.26458332"
+         id="path824"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 91.745662,49.45415 q -0.270933,0 -0.699911,-0.06773 -0.428978,-0.06773 -0.722489,-0.180622 l 0.270933,-1.715911 q 0.225778,0.06773 0.519289,0.112889 0.293511,0.04516 0.541867,0.04516 1.083733,0 1.535289,-0.677333 0.474133,-0.654755 0.474133,-1.941689 V 33.491661 h 2.099734 v 11.514666 q 0,2.257778 -1.038578,3.341512 -1.016,1.106311 -2.980267,1.106311 z m 2.957689,-18.0848 q -0.564444,0 -0.970844,-0.361245 -0.383823,-0.383822 -0.383823,-1.016 0,-0.632178 0.383823,-0.993422 0.4064,-0.383822 0.970844,-0.383822 0.564444,0 0.948267,0.383822 0.4064,0.361244 0.4064,0.993422 0,0.632178 -0.4064,1.016 -0.383823,0.361245 -0.948267,0.361245 z"
+         style="stroke-width:0.26458332"
+         id="path826"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 102.12932,43.719394 q 1.28693,0 1.89653,-0.338667 0.63218,-0.338666 0.63218,-1.083733 0,-0.767644 -0.6096,-1.2192 -0.6096,-0.451555 -2.00942,-1.016 -0.67733,-0.270933 -1.30951,-0.541867 -0.6096,-0.293511 -1.061158,-0.677333 -0.451555,-0.383822 -0.722489,-0.925689 -0.270933,-0.541866 -0.270933,-1.332089 0,-1.557866 1.151467,-2.460977 1.151463,-0.925689 3.138313,-0.925689 0.49671,0 0.99342,0.06773 0.49671,0.04516 0.92569,0.135467 0.42898,0.06773 0.74507,0.158044 0.33866,0.09031 0.51928,0.158045 l -0.38382,1.806222 q -0.33866,-0.180622 -1.06115,-0.361245 -0.72249,-0.2032 -1.73849,-0.2032 -0.88054,0 -1.53529,0.361245 -0.65476,0.338666 -0.65476,1.083733 0,0.383822 0.13547,0.677333 0.15804,0.293512 0.45156,0.541867 0.31608,0.225778 0.76764,0.428978 0.45156,0.2032 1.08373,0.428978 0.83538,0.316089 1.49014,0.632177 0.65475,0.293512 1.10631,0.699912 0.47413,0.4064 0.72249,0.993422 0.24835,0.564444 0.24835,1.399822 0,1.6256 -1.2192,2.460978 -1.19662,0.835378 -3.43182,0.835378 -1.55787,0 -2.4384,-0.270934 -0.880533,-0.248355 -1.196622,-0.383822 l 0.383822,-1.806222 q 0.361244,0.135466 1.15147,0.4064 0.79022,0.270933 2.09973,0.270933 z"
+         style="stroke-width:0.26458332"
+         id="path828"
+         inkscape:connector-curvature="0" />
+    </g>
+  </g>
+</svg>

BIN
examples/models/svg/tests/3.png


+ 105 - 0
examples/models/svg/tests/3.svg

@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="210mm"
+   height="297mm"
+   viewBox="0 0 210 297"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="3.svg"
+   inkscape:export-filename=""
+   inkscape:export-xdpi="149.98094"
+   inkscape:export-ydpi="149.98094">
+  <defs
+     id="defs2" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.49497475"
+     inkscape:cx="180.72939"
+     inkscape:cy="809.04827"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1920"
+     inkscape:window-height="1015"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <g
+       aria-label="Three.js"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:22.57777786px;line-height:1.25;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
+       id="text817"
+       transform="matrix(1.7884384,-0.78408147,1.0325554,1.3580689,-51.066515,52.200548)">
+      <path
+         d="m 39.122152,29.585705 v 1.896534 H 34.200196 V 45.232105 H 32.010152 V 31.482239 h -4.921956 v -1.896534 z"
+         style="stroke-width:0.26458332"
+         id="path814"
+         inkscape:connector-curvature="0" />
+      <path
+         d="M 41.277272,45.232105 V 28.072994 l 2.099733,-0.361244 v 6.005689 q 0.587022,-0.225778 1.241778,-0.338667 0.677333,-0.135467 1.332089,-0.135467 1.399822,0 2.325511,0.4064 0.925689,0.383822 1.467555,1.106311 0.564445,0.699911 0.790222,1.693334 0.225778,0.993422 0.225778,2.190044 v 6.592711 H 48.660205 V 39.09095 q 0,-1.083734 -0.158045,-1.851378 -0.135466,-0.767645 -0.474133,-1.241778 -0.338667,-0.474133 -0.903111,-0.677333 -0.564444,-0.225778 -1.399822,-0.225778 -0.338667,0 -0.699911,0.04516 -0.361245,0.04516 -0.699911,0.112888 -0.316089,0.04516 -0.587023,0.112889 -0.248355,0.06773 -0.361244,0.112889 v 9.7536 z"
+         style="stroke-width:0.26458332"
+         id="path816"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 58.488594,33.243305 q 0.270934,0 0.6096,0.04516 0.361245,0.02258 0.699912,0.09031 0.338666,0.04516 0.6096,0.112889 0.293511,0.04516 0.428977,0.09031 l -0.361244,1.8288 q -0.248356,-0.09031 -0.835378,-0.2032 -0.564444,-0.135467 -1.467555,-0.135467 -0.587023,0 -1.174045,0.135467 -0.564444,0.112889 -0.745067,0.158044 v 9.866489 H 54.153661 V 33.988372 q 0.745067,-0.270933 1.851378,-0.496711 1.106311,-0.248356 2.483555,-0.248356 z"
+         style="stroke-width:0.26458332"
+         id="path818"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 62.230156,39.384461 q 0,-1.557867 0.451556,-2.709334 0.451555,-1.174044 1.196622,-1.941688 0.745067,-0.767645 1.715911,-1.151467 0.970845,-0.383822 1.986845,-0.383822 2.370666,0 3.635022,1.490133 1.264355,1.467556 1.264355,4.492978 0,0.135466 0,0.361244 0,0.2032 -0.02258,0.383822 h -8.037689 q 0.135466,1.8288 1.061155,2.777067 0.925689,0.948267 2.889956,0.948267 1.106311,0 1.851378,-0.180622 0.767644,-0.2032 1.151466,-0.383823 l 0.293511,1.761067 q -0.383822,0.2032 -1.354666,0.428978 -0.948267,0.225778 -2.167467,0.225778 -1.535289,0 -2.664178,-0.451556 -1.106311,-0.474133 -1.8288,-1.286933 -0.722489,-0.8128 -1.083733,-1.919111 -0.338667,-1.128889 -0.338667,-2.460978 z m 8.060267,-1.151467 q 0.02258,-1.4224 -0.722489,-2.325511 -0.722489,-0.925689 -2.009422,-0.925689 -0.722489,0 -1.286934,0.293511 -0.541866,0.270934 -0.925688,0.722489 -0.383823,0.451556 -0.6096,1.038578 -0.2032,0.587022 -0.270934,1.196622 z"
+         style="stroke-width:0.26458332"
+         id="path820"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 74.841961,39.384461 q 0,-1.557867 0.451556,-2.709334 0.451555,-1.174044 1.196622,-1.941688 0.745067,-0.767645 1.715911,-1.151467 0.970845,-0.383822 1.986845,-0.383822 2.370666,0 3.635022,1.490133 1.264355,1.467556 1.264355,4.492978 0,0.135466 0,0.361244 0,0.2032 -0.02258,0.383822 h -8.037689 q 0.135466,1.8288 1.061155,2.777067 0.925689,0.948267 2.889956,0.948267 1.106311,0 1.851378,-0.180622 0.767644,-0.2032 1.151466,-0.383823 l 0.293511,1.761067 q -0.383822,0.2032 -1.354666,0.428978 -0.948267,0.225778 -2.167467,0.225778 -1.535289,0 -2.664178,-0.451556 -1.106311,-0.474133 -1.8288,-1.286933 -0.722489,-0.8128 -1.083733,-1.919111 -0.338667,-1.128889 -0.338667,-2.460978 z m 8.060267,-1.151467 q 0.02258,-1.4224 -0.722489,-2.325511 -0.722489,-0.925689 -2.009422,-0.925689 -0.722489,0 -1.286934,0.293511 -0.541866,0.270934 -0.925688,0.722489 -0.383823,0.451556 -0.6096,1.038578 -0.2032,0.587022 -0.270934,1.196622 z"
+         style="stroke-width:0.26458332"
+         id="path822"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 90.592077,44.012905 q 0,0.6096 -0.4064,1.061156 -0.4064,0.451555 -1.106311,0.451555 -0.699911,0 -1.106311,-0.451555 -0.4064,-0.451556 -0.4064,-1.061156 0,-0.6096 0.4064,-1.061155 0.4064,-0.451556 1.106311,-0.451556 0.699911,0 1.106311,0.451556 0.4064,0.451555 0.4064,1.061155 z"
+         style="stroke-width:0.26458332"
+         id="path824"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 91.745662,49.45415 q -0.270933,0 -0.699911,-0.06773 -0.428978,-0.06773 -0.722489,-0.180622 l 0.270933,-1.715911 q 0.225778,0.06773 0.519289,0.112889 0.293511,0.04516 0.541867,0.04516 1.083733,0 1.535289,-0.677333 0.474133,-0.654755 0.474133,-1.941689 V 33.491661 h 2.099734 v 11.514666 q 0,2.257778 -1.038578,3.341512 -1.016,1.106311 -2.980267,1.106311 z m 2.957689,-18.0848 q -0.564444,0 -0.970844,-0.361245 -0.383823,-0.383822 -0.383823,-1.016 0,-0.632178 0.383823,-0.993422 0.4064,-0.383822 0.970844,-0.383822 0.564444,0 0.948267,0.383822 0.4064,0.361244 0.4064,0.993422 0,0.632178 -0.4064,1.016 -0.383823,0.361245 -0.948267,0.361245 z"
+         style="stroke-width:0.26458332"
+         id="path826"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 102.12932,43.719394 q 1.28693,0 1.89653,-0.338667 0.63218,-0.338666 0.63218,-1.083733 0,-0.767644 -0.6096,-1.2192 -0.6096,-0.451555 -2.00942,-1.016 -0.67733,-0.270933 -1.30951,-0.541867 -0.6096,-0.293511 -1.061158,-0.677333 -0.451555,-0.383822 -0.722489,-0.925689 -0.270933,-0.541866 -0.270933,-1.332089 0,-1.557866 1.151467,-2.460977 1.151463,-0.925689 3.138313,-0.925689 0.49671,0 0.99342,0.06773 0.49671,0.04516 0.92569,0.135467 0.42898,0.06773 0.74507,0.158044 0.33866,0.09031 0.51928,0.158045 l -0.38382,1.806222 q -0.33866,-0.180622 -1.06115,-0.361245 -0.72249,-0.2032 -1.73849,-0.2032 -0.88054,0 -1.53529,0.361245 -0.65476,0.338666 -0.65476,1.083733 0,0.383822 0.13547,0.677333 0.15804,0.293512 0.45156,0.541867 0.31608,0.225778 0.76764,0.428978 0.45156,0.2032 1.08373,0.428978 0.83538,0.316089 1.49014,0.632177 0.65475,0.293512 1.10631,0.699912 0.47413,0.4064 0.72249,0.993422 0.24835,0.564444 0.24835,1.399822 0,1.6256 -1.2192,2.460978 -1.19662,0.835378 -3.43182,0.835378 -1.55787,0 -2.4384,-0.270934 -0.880533,-0.248355 -1.196622,-0.383822 l 0.383822,-1.806222 q 0.361244,0.135466 1.15147,0.4064 0.79022,0.270933 2.09973,0.270933 z"
+         style="stroke-width:0.26458332"
+         id="path828"
+         inkscape:connector-curvature="0" />
+    </g>
+  </g>
+</svg>

BIN
examples/models/svg/tests/4.png


+ 66 - 0
examples/models/svg/tests/4.svg

@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="210mm"
+   height="297mm"
+   viewBox="0 0 210 297"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="4.svg"
+   inkscape:export-filename=""
+   inkscape:export-xdpi="149.98094"
+   inkscape:export-ydpi="149.98094">
+  <defs
+     id="defs2" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.49497475"
+     inkscape:cx="-224.34178"
+     inkscape:cy="809.04827"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1920"
+     inkscape:window-height="1015"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.44999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect821"
+       width="107.97688"
+       height="59.868374"
+       x="18.708866"
+       y="19.039692" />
+  </g>
+</svg>

BIN
examples/models/svg/tests/5.png


+ 68 - 0
examples/models/svg/tests/5.svg

@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="210mm"
+   height="297mm"
+   viewBox="0 0 210 297"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="5.svg"
+   inkscape:export-filename=""
+   inkscape:export-xdpi="149.98094"
+   inkscape:export-ydpi="149.98094">
+  <defs
+     id="defs2" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.49497475"
+     inkscape:cx="378.71929"
+     inkscape:cy="609.03807"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1920"
+     inkscape:window-height="1015"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.44999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect821"
+       width="107.97688"
+       height="59.868374"
+       x="18.708866"
+       y="19.039692"
+       rx="10"
+       ry="10" />
+  </g>
+</svg>

BIN
examples/models/svg/tests/6.png


+ 69 - 0
examples/models/svg/tests/6.svg

@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="210mm"
+   height="297mm"
+   viewBox="0 0 210 297"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="6.svg"
+   inkscape:export-filename=""
+   inkscape:export-xdpi="149.98094"
+   inkscape:export-ydpi="149.98094">
+  <defs
+     id="defs2" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.49497475"
+     inkscape:cx="-26.351878"
+     inkscape:cy="609.03807"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1920"
+     inkscape:window-height="1015"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.44999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect821"
+       width="107.97688"
+       height="59.868374"
+       x="-69.666222"
+       y="76.970978"
+       rx="10"
+       ry="10"
+       transform="rotate(-48)" />
+  </g>
+</svg>

BIN
examples/models/svg/tests/7.png


+ 66 - 0
examples/models/svg/tests/7.svg

@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="210mm"
+   height="297mm"
+   viewBox="0 0 210 297"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="7.svg"
+   inkscape:export-filename=""
+   inkscape:export-xdpi="149.98094"
+   inkscape:export-ydpi="149.98094">
+  <defs
+     id="defs2" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.49497475"
+     inkscape:cx="258.51114"
+     inkscape:cy="677.72844"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1920"
+     inkscape:window-height="1015"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="scale(1.7,1.1)">
+    <circle
+       style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.44999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="path816"
+       cx="71.8955"
+       cy="52.715652"
+       r="27.564367" />
+  </g>
+</svg>

+ 1 - 1
examples/software_geometry_earth.html

@@ -71,7 +71,7 @@
 				var loader = new THREE.TextureLoader();
 				loader.load( 'textures/land_ocean_ice_cloud_2048.jpg', function ( texture ) {
 
-					var geometry = new THREE.SphereGeometry( 200, 20, 20 );
+					var geometry = new THREE.SphereBufferGeometry( 200, 20, 20 );
 
 					var material = new THREE.MeshLambertMaterial( { map: texture, overdraw: 0.5 } );
 					var mesh = new THREE.Mesh( geometry, material );

+ 2 - 2
examples/svg_sandbox.html

@@ -50,7 +50,7 @@
 
 				// CUBES
 
-				var cube = new THREE.BoxGeometry( 100, 100, 100 );
+				var cube = new THREE.BoxBufferGeometry( 100, 100, 100 );
 
 				mesh = new THREE.Mesh( cube, new THREE.MeshBasicMaterial( { color: 0x0000ff, opacity: 0.5, transparent: true } ) );
 				mesh.position.x = 500;
@@ -76,7 +76,7 @@
 
 				// CYLINDER
 
-				mesh = new THREE.Mesh( new THREE.CylinderGeometry( 20, 100, 200, 10 ), new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff } ) );
+				mesh = new THREE.Mesh( new THREE.CylinderBufferGeometry( 20, 100, 200, 10 ), new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff } ) );
 				mesh.position.x = -500;
 				mesh.rotation.x = - Math.PI / 2;
 				mesh.scale.x = mesh.scale.y = mesh.scale.z = 2;

+ 8 - 15
examples/webgl_custom_attributes_lines.html

@@ -101,7 +101,7 @@
 
 				amplitude: { value: 5.0 },
 				opacity:   { value: 0.3 },
-				color:     { value: new THREE.Color( 0xff0000 ) }
+				color:     { value: new THREE.Color( 0xffffff ) }
 
 			};
 
@@ -117,7 +117,7 @@
 			});
 
 
-			var geometry = new THREE.TextGeometry( 'three.js', {
+			var geometry = new THREE.TextBufferGeometry( 'three.js', {
 
 				font: font,
 
@@ -130,24 +130,17 @@
 				bevelEnabled: true,
 				bevelSegments: 10,
 
-				steps: 40
-
 			} );
 
 			geometry.center();
 
-			var vertices = geometry.vertices;
-
-			var buffergeometry = new THREE.BufferGeometry();
-
-			var position = new THREE.Float32BufferAttribute( vertices.length * 3, 3 ).copyVector3sArray( vertices );
-			buffergeometry.addAttribute( 'position', position );
+			var count = geometry.attributes.position.count;
 
-			var displacement = new THREE.Float32BufferAttribute( vertices.length * 3, 3 );
-			buffergeometry.addAttribute( 'displacement', displacement );
+			var displacement = new THREE.Float32BufferAttribute( count * 3, 3 );
+			geometry.addAttribute( 'displacement', displacement );
 
-			var customColor = new THREE.Float32BufferAttribute( vertices.length * 3, 3 );
-			buffergeometry.addAttribute( 'customColor', customColor );
+			var customColor = new THREE.Float32BufferAttribute( count * 3, 3 );
+			geometry.addAttribute( 'customColor', customColor );
 
 			var color = new THREE.Color( 0xffffff );
 
@@ -158,7 +151,7 @@
 
 			}
 
-			object = new THREE.Line( buffergeometry, shaderMaterial );
+			object = new THREE.Line( geometry, shaderMaterial );
 			object.rotation.x = 0.2;
 			scene.add( object );
 

+ 3 - 3
examples/webgl_geometry_extrude_shapes.html

@@ -98,7 +98,7 @@
 
 				var shape = new THREE.Shape( pts );
 
-				var geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );
+				var geometry = new THREE.ExtrudeBufferGeometry( shape, extrudeSettings );
 
 				var material = new THREE.MeshLambertMaterial( { color: 0xb00000, wireframe: false } );
 
@@ -143,7 +143,7 @@
 
 				var shape = new THREE.Shape( pts );
 
-				var geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );
+				var geometry = new THREE.ExtrudeBufferGeometry( shape, extrudeSettings );
 
 				var material2 = new THREE.MeshLambertMaterial( { color: 0xff8000, wireframe: false } );
 
@@ -165,7 +165,7 @@
 					bevelSegments: 1
 				};
 
-				var geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );
+				var geometry = new THREE.ExtrudeBufferGeometry( shape, extrudeSettings );
 
 				var mesh = new THREE.Mesh( geometry, materials );
 

+ 1 - 1
examples/webgl_geometry_shapes.html

@@ -97,7 +97,7 @@
 
 					// extruded shape
 
-					var geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );
+					var geometry = new THREE.ExtrudeBufferGeometry( shape, extrudeSettings );
 
 					var mesh = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial( { color: color } ) );
 					mesh.position.set( x, y, z - 75 );

+ 2 - 6
examples/webgl_geometry_text_shapes.html

@@ -51,8 +51,6 @@
 
 					var xMid, text;
 
-					var textShape = new THREE.BufferGeometry();
-
 					var color = 0x006699;
 
 					var matDark = new THREE.LineBasicMaterial( {
@@ -71,7 +69,7 @@
 
 					var shapes = font.generateShapes( message, 100 );
 
-					var geometry = new THREE.ShapeGeometry( shapes );
+					var geometry = new THREE.ShapeBufferGeometry( shapes );
 
 					geometry.computeBoundingBox();
 
@@ -81,9 +79,7 @@
 
 					// make shape ( N.B. edge view not visible )
 
-					textShape.fromGeometry( geometry );
-
-					text = new THREE.Mesh( textShape, matLite );
+					text = new THREE.Mesh( geometry, matLite );
 					text.position.z = - 150;
 					scene.add( text );
 

+ 1 - 1
examples/webgl_panorama_cube.html

@@ -76,7 +76,7 @@
 
 			}
 
-			var skyBox = new THREE.Mesh( new THREE.CubeGeometry( 1, 1, 1 ), materials );
+			var skyBox = new THREE.Mesh( new THREE.BoxBufferGeometry( 1, 1, 1 ), materials );
 			skyBox.geometry.scale( 1, 1, - 1 );
 			scene.add( skyBox );
 

+ 1 - 1
examples/webvr_panorama.html

@@ -52,7 +52,7 @@
 			camera = new THREE.PerspectiveCamera( 90, window.innerWidth / window.innerHeight, 1, 1000 );
 			camera.layers.enable( 1 );
 
-			var geometry = new THREE.CubeGeometry( 100, 100, 100 );
+			var geometry = new THREE.BoxBufferGeometry( 100, 100, 100 );
 			geometry.scale( 1, 1, - 1 );
 			var textures = getTexturesFromAtlasFile( "textures/cube/sun_temple_stripe_stereo.jpg", 12 );
 

+ 10 - 12
src/renderers/WebGLRenderer.js

@@ -209,8 +209,6 @@ function WebGLRenderer( parameters ) {
 
 		}
 
-		_gl.isWebGL2 = typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext;
-
 		// Some experimental-webgl implementations do not have getShaderPrecisionFormat
 
 		if ( _gl.getShaderPrecisionFormat === undefined ) {
@@ -241,7 +239,9 @@ function WebGLRenderer( parameters ) {
 
 		extensions = new WebGLExtensions( _gl );
 
-		if ( ! _gl.isWebGL2 ) {
+		capabilities = new WebGLCapabilities( _gl, extensions, parameters );
+
+		if ( ! capabilities.isWebGL2 ) {
 
 			extensions.get( 'WEBGL_depth_texture' );
 			extensions.get( 'OES_texture_float' );
@@ -255,11 +255,9 @@ function WebGLRenderer( parameters ) {
 
 		extensions.get( 'OES_texture_float_linear' );
 
-		utils = new WebGLUtils( _gl, extensions );
-
-		capabilities = new WebGLCapabilities( _gl, extensions, parameters );
+		utils = new WebGLUtils( _gl, extensions, capabilities );
 
-		state = new WebGLState( _gl, extensions, utils );
+		state = new WebGLState( _gl, extensions, utils, capabilities );
 		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
 		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
 
@@ -276,8 +274,8 @@ function WebGLRenderer( parameters ) {
 
 		background = new WebGLBackground( _this, state, objects, _premultipliedAlpha );
 
-		bufferRenderer = new WebGLBufferRenderer( _gl, extensions, info );
-		indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, info );
+		bufferRenderer = new WebGLBufferRenderer( _gl, extensions, info, capabilities );
+		indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, info, capabilities );
 
 		info.programs = programCache.programs;
 
@@ -814,7 +812,7 @@ function WebGLRenderer( parameters ) {
 
 	function setupVertexAttributes( material, program, geometry ) {
 
-		if ( geometry && geometry.isInstancedBufferGeometry & ! _gl.isWebGL2 ) {
+		if ( geometry && geometry.isInstancedBufferGeometry & ! capabilities.isWebGL2 ) {
 
 			if ( extensions.get( 'ANGLE_instanced_arrays' ) === null ) {
 
@@ -2525,8 +2523,8 @@ function WebGLRenderer( parameters ) {
 				}
 
 				if ( textureType !== UnsignedByteType && utils.convert( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)
-					! ( textureType === FloatType && ( _gl.isWebGL2 || extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox
-					! ( textureType === HalfFloatType && ( _gl.isWebGL2 ? extensions.get( 'EXT_color_buffer_float' ) : extensions.get( 'EXT_color_buffer_half_float' ) ) ) ) {
+					! ( textureType === FloatType && ( capabilities.isWebGL2 || extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox
+					! ( textureType === HalfFloatType && ( capabilities.isWebGL2 ? extensions.get( 'EXT_color_buffer_float' ) : extensions.get( 'EXT_color_buffer_half_float' ) ) ) ) {
 
 					console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );
 					return;

+ 3 - 3
src/renderers/webgl/WebGLBufferRenderer.js

@@ -2,7 +2,7 @@
  * @author mrdoob / http://mrdoob.com/
  */
 
-function WebGLBufferRenderer( gl, extensions, info ) {
+function WebGLBufferRenderer( gl, extensions, info, capabilities ) {
 
 	var mode;
 
@@ -24,7 +24,7 @@ function WebGLBufferRenderer( gl, extensions, info ) {
 
 		var extension;
 
-		if ( gl.isWebGL2 ) {
+		if ( capabilities.isWebGL2 ) {
 
 			extension = gl;
 
@@ -41,7 +41,7 @@ function WebGLBufferRenderer( gl, extensions, info ) {
 
 		}
 
-		extension[ gl.isWebGL2 ? 'drawArraysInstanced' : 'drawArraysInstancedANGLE' ]( mode, start, count, geometry.maxInstancedCount );
+		extension[ capabilities.isWebGL2 ? 'drawArraysInstanced' : 'drawArraysInstancedANGLE' ]( mode, start, count, geometry.maxInstancedCount );
 
 		info.update( count, mode, geometry.maxInstancedCount );
 

+ 5 - 1
src/renderers/webgl/WebGLCapabilities.js

@@ -56,6 +56,8 @@ function WebGLCapabilities( gl, extensions, parameters ) {
 
 	}
 
+	var isWebGL2 = typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext;
+
 	var precision = parameters.precision !== undefined ? parameters.precision : 'highp';
 	var maxPrecision = getMaxPrecision( precision );
 
@@ -79,11 +81,13 @@ function WebGLCapabilities( gl, extensions, parameters ) {
 	var maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );
 
 	var vertexTextures = maxVertexTextures > 0;
-	var floatFragmentTextures = gl.isWebGL2 || !! extensions.get( 'OES_texture_float' );
+	var floatFragmentTextures = isWebGL2 || !! extensions.get( 'OES_texture_float' );
 	var floatVertexTextures = vertexTextures && floatFragmentTextures;
 
 	return {
 
+		isWebGL2: isWebGL2,
+
 		getMaxAnisotropy: getMaxAnisotropy,
 		getMaxPrecision: getMaxPrecision,
 

+ 3 - 3
src/renderers/webgl/WebGLIndexedBufferRenderer.js

@@ -2,7 +2,7 @@
  * @author mrdoob / http://mrdoob.com/
  */
 
-function WebGLIndexedBufferRenderer( gl, extensions, info ) {
+function WebGLIndexedBufferRenderer( gl, extensions, info, capabilities ) {
 
 	var mode;
 
@@ -33,7 +33,7 @@ function WebGLIndexedBufferRenderer( gl, extensions, info ) {
 
 		var extension;
 
-		if ( gl.isWebGL2 ) {
+		if ( capabilities.isWebGL2 ) {
 
 			extension = gl;
 
@@ -50,7 +50,7 @@ function WebGLIndexedBufferRenderer( gl, extensions, info ) {
 
 		}
 
-		extension[ gl.isWebGL2 ? 'drawElementsInstanced' : 'drawElementsInstancedANGLE' ]( mode, count, type, start * bytesPerElement, geometry.maxInstancedCount );
+		extension[ capabilities.isWebGL2 ? 'drawElementsInstanced' : 'drawElementsInstancedANGLE' ]( mode, count, type, start * bytesPerElement, geometry.maxInstancedCount );
 
 		info.update( count, mode, geometry.maxInstancedCount );
 

+ 6 - 6
src/renderers/webgl/WebGLProgram.js

@@ -202,7 +202,7 @@ function unrollLoops( string ) {
 
 }
 
-function WebGLProgram( renderer, extensions, code, material, shader, parameters ) {
+function WebGLProgram( renderer, extensions, code, material, shader, parameters, capabilities ) {
 
 	var gl = renderer.context;
 
@@ -285,7 +285,7 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters
 
 	//
 
-	var customExtensions = gl.isWebGL2 ? '' : generateExtensions( material.extensions, parameters, extensions );
+	var customExtensions = capabilities.isWebGL2 ? '' : generateExtensions( material.extensions, parameters, extensions );
 
 	var customDefines = generateDefines( defines );
 
@@ -373,7 +373,7 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters
 			parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',
 
 			parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
-			parameters.logarithmicDepthBuffer && ( gl.isWebGL2 || extensions.get( 'EXT_frag_depth' ) ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
+			parameters.logarithmicDepthBuffer && ( capabilities.isWebGL2 || extensions.get( 'EXT_frag_depth' ) ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
 
 			'uniform mat4 modelMatrix;',
 			'uniform mat4 modelViewMatrix;',
@@ -478,9 +478,9 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters
 			parameters.physicallyCorrectLights ? '#define PHYSICALLY_CORRECT_LIGHTS' : '',
 
 			parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
-			parameters.logarithmicDepthBuffer && ( gl.isWebGL2 || extensions.get( 'EXT_frag_depth' ) ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
+			parameters.logarithmicDepthBuffer && ( capabilities.isWebGL2 || extensions.get( 'EXT_frag_depth' ) ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
 
-			parameters.envMap && ( gl.isWebGL2 || extensions.get( 'EXT_shader_texture_lod' ) ) ? '#define TEXTURE_LOD_EXT' : '',
+			parameters.envMap && ( capabilities.isWebGL2 || extensions.get( 'EXT_shader_texture_lod' ) ) ? '#define TEXTURE_LOD_EXT' : '',
 
 			'uniform mat4 viewMatrix;',
 			'uniform vec3 cameraPosition;',
@@ -516,7 +516,7 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters
 	vertexShader = unrollLoops( vertexShader );
 	fragmentShader = unrollLoops( fragmentShader );
 
-	if ( gl.isWebGL2 && ! material.isRawShaderMaterial ) {
+	if ( capabilities.isWebGL2 && ! material.isRawShaderMaterial ) {
 
 		var isGLSL3ShaderMaterial = false;
 

+ 1 - 1
src/renderers/webgl/WebGLPrograms.js

@@ -273,7 +273,7 @@ function WebGLPrograms( renderer, extensions, capabilities ) {
 
 		if ( program === undefined ) {
 
-			program = new WebGLProgram( renderer, extensions, code, material, shader, parameters );
+			program = new WebGLProgram( renderer, extensions, code, material, shader, parameters, capabilities );
 			programs.push( program );
 
 		}

+ 9 - 9
src/renderers/webgl/WebGLState.js

@@ -5,7 +5,7 @@
 import { NotEqualDepth, GreaterDepth, GreaterEqualDepth, EqualDepth, LessEqualDepth, LessDepth, AlwaysDepth, NeverDepth, CullFaceFront, CullFaceBack, CullFaceNone, CustomBlending, MultiplyBlending, SubtractiveBlending, AdditiveBlending, NoBlending, NormalBlending, DoubleSide, BackSide } from '../../constants.js';
 import { Vector4 } from '../../math/Vector4.js';
 
-function WebGLState( gl, extensions, utils ) {
+function WebGLState( gl, extensions, utils, capabilities ) {
 
 	function ColorBuffer() {
 
@@ -317,7 +317,7 @@ function WebGLState( gl, extensions, utils ) {
 	var enabledAttributes = new Uint8Array( maxVertexAttributes );
 	var attributeDivisors = new Uint8Array( maxVertexAttributes );
 
-	var capabilities = {};
+	var enabledCapabilities = {};
 
 	var compressedTextureFormats = null;
 
@@ -434,9 +434,9 @@ function WebGLState( gl, extensions, utils ) {
 
 		if ( attributeDivisors[ attribute ] !== meshPerAttribute ) {
 
-			var extension = gl.isWebGL2 ? gl : extensions.get( 'ANGLE_instanced_arrays' );
+			var extension = capabilities.isWebGL2 ? gl : extensions.get( 'ANGLE_instanced_arrays' );
 
-			extension[ gl.isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE' ]( attribute, meshPerAttribute );
+			extension[ capabilities.isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE' ]( attribute, meshPerAttribute );
 			attributeDivisors[ attribute ] = meshPerAttribute;
 
 		}
@@ -460,10 +460,10 @@ function WebGLState( gl, extensions, utils ) {
 
 	function enable( id ) {
 
-		if ( capabilities[ id ] !== true ) {
+		if ( enabledCapabilities[ id ] !== true ) {
 
 			gl.enable( id );
-			capabilities[ id ] = true;
+			enabledCapabilities[ id ] = true;
 
 		}
 
@@ -471,10 +471,10 @@ function WebGLState( gl, extensions, utils ) {
 
 	function disable( id ) {
 
-		if ( capabilities[ id ] !== false ) {
+		if ( enabledCapabilities[ id ] !== false ) {
 
 			gl.disable( id );
-			capabilities[ id ] = false;
+			enabledCapabilities[ id ] = false;
 
 		}
 
@@ -883,7 +883,7 @@ function WebGLState( gl, extensions, utils ) {
 
 		}
 
-		capabilities = {};
+		enabledCapabilities = {};
 
 		compressedTextureFormats = null;
 

+ 5 - 5
src/renderers/webgl/WebGLTextures.js

@@ -75,7 +75,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 	function textureNeedsPowerOfTwo( texture ) {
 
-		if ( _gl.isWebGL2 ) return false;
+		if ( capabilities.isWebGL2 ) return false;
 
 		return ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) ||
 			( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter );
@@ -102,7 +102,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 	function getInternalFormat( glFormat, glType ) {
 
-		if ( ! _gl.isWebGL2 ) return glFormat;
+		if ( ! capabilities.isWebGL2 ) return glFormat;
 
 		if ( glFormat === _gl.RGB ) {
 
@@ -447,7 +447,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 		if ( extension ) {
 
 			if ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;
-			if ( texture.type === HalfFloatType && ( _gl.isWebGL2 || extensions.get( 'OES_texture_half_float_linear' ) ) === null ) return;
+			if ( texture.type === HalfFloatType && ( capabilities.isWebGL2 || extensions.get( 'OES_texture_half_float_linear' ) ) === null ) return;
 
 			if ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {
 
@@ -506,10 +506,10 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 			if ( texture.type === FloatType ) {
 
-				if ( ! _gl.isWebGL2 ) throw new Error( 'Float Depth Texture only supported in WebGL2.0' );
+				if ( ! capabilities.isWebGL2 ) throw new Error( 'Float Depth Texture only supported in WebGL2.0' );
 				glInternalFormat = _gl.DEPTH_COMPONENT32F;
 
-			} else if ( _gl.isWebGL2 ) {
+			} else if ( capabilities.isWebGL2 ) {
 
 				// WebGL 2.0 requires signed internalformat for glTexImage2D
 				glInternalFormat = _gl.DEPTH_COMPONENT16;

+ 4 - 4
src/renderers/webgl/WebGLUtils.js

@@ -4,7 +4,7 @@
 
 import { MaxEquation, MinEquation, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_10x10_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGB_ETC1_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT5_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT1_Format, RGB_S3TC_DXT1_Format, SrcAlphaSaturateFactor, OneMinusDstColorFactor, DstColorFactor, OneMinusDstAlphaFactor, DstAlphaFactor, OneMinusSrcAlphaFactor, SrcAlphaFactor, OneMinusSrcColorFactor, SrcColorFactor, OneFactor, ZeroFactor, ReverseSubtractEquation, SubtractEquation, AddEquation, DepthFormat, DepthStencilFormat, LuminanceAlphaFormat, LuminanceFormat, RGBAFormat, RGBFormat, AlphaFormat, HalfFloatType, FloatType, UnsignedIntType, IntType, UnsignedShortType, ShortType, ByteType, UnsignedInt248Type, UnsignedShort565Type, UnsignedShort5551Type, UnsignedShort4444Type, UnsignedByteType, LinearMipMapLinearFilter, LinearMipMapNearestFilter, LinearFilter, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NearestFilter, MirroredRepeatWrapping, ClampToEdgeWrapping, RepeatWrapping } from '../../constants.js';
 
-function WebGLUtils( gl, extensions ) {
+function WebGLUtils( gl, extensions, capabilities ) {
 
 	function convert( p ) {
 
@@ -36,7 +36,7 @@ function WebGLUtils( gl, extensions ) {
 
 		if ( p === HalfFloatType ) {
 
-			if ( gl.isWebGL2 ) return gl.HALF_FLOAT;
+			if ( capabilities.isWebGL2 ) return gl.HALF_FLOAT;
 
 			extension = extensions.get( 'OES_texture_half_float' );
 
@@ -127,7 +127,7 @@ function WebGLUtils( gl, extensions ) {
 
 		if ( p === MinEquation || p === MaxEquation ) {
 
-			if ( gl.isWebGL2 ) {
+			if ( capabilities.isWebGL2 ) {
 
 				if ( p === MinEquation ) return gl.MIN;
 				if ( p === MaxEquation ) return gl.MAX;
@@ -147,7 +147,7 @@ function WebGLUtils( gl, extensions ) {
 
 		if ( p === UnsignedInt248Type ) {
 
-			if ( gl.isWebGL2 ) return gl.UNSIGNED_INT_24_8;
+			if ( capabilities.isWebGL2 ) return gl.UNSIGNED_INT_24_8;
 
 			extension = extensions.get( 'WEBGL_depth_texture' );