2
0
Эх сурвалжийг харах

Merge branch 'master' into gimbal-lock-precision

TheophileMot 6 жил өмнө
parent
commit
c09ae2dc65
62 өөрчлөгдсөн 798 нэмэгдсэн , 890 устгасан
  1. 1 1
      README.md
  2. 92 94
      build/three.js
  3. 163 285
      build/three.min.js
  4. 92 94
      build/three.module.js
  5. 2 2
      docs/api/en/objects/Sprite.html
  6. 1 1
      docs/api/zh/core/Clock.html
  7. 4 7
      docs/manual/en/introduction/Loading-3D-models.html
  8. 15 15
      docs/manual/zh/introduction/Creating-a-scene.html
  9. 6 6
      docs/manual/zh/introduction/Import-via-modules.html
  10. 3 6
      docs/manual/zh/introduction/Loading-3D-models.html
  11. 2 0
      editor/index.html
  12. 1 1
      editor/sw.js
  13. 2 2
      examples/css3d_molecules.html
  14. 1 1
      examples/files.js
  15. 13 20
      examples/js/loaders/FBXLoader.js
  16. 59 22
      examples/js/loaders/GLTFLoader.js
  17. 1 1
      examples/js/loaders/OBJLoader.js
  18. 10 5
      examples/js/loaders/TTFLoader.js
  19. 1 0
      examples/js/misc/VolumeSlice.js
  20. 3 1
      examples/jsm/controls/OrbitControls.d.ts
  21. 14 22
      examples/jsm/loaders/FBXLoader.js
  22. 59 22
      examples/jsm/loaders/GLTFLoader.js
  23. 1 1
      examples/jsm/loaders/OBJLoader.js
  24. 10 5
      examples/jsm/loaders/TTFLoader.js
  25. 1 0
      examples/jsm/misc/VolumeSlice.js
  26. 0 1
      examples/jsm/nodes/accessors/NormalNode.d.ts
  27. 5 29
      examples/jsm/nodes/accessors/NormalNode.js
  28. 1 1
      examples/jsm/nodes/accessors/PositionNode.js
  29. 1 1
      examples/jsm/nodes/inputs/CubeTextureNode.js
  30. 1 1
      examples/jsm/nodes/inputs/TextureNode.js
  31. 2 2
      examples/webgl_buffergeometry_drawrange.html
  32. 106 136
      examples/webgl_buffergeometry_instancing_lambert.html
  33. 5 3
      examples/webgl_buffergeometry_rawshader.html
  34. 1 1
      examples/webgl_geometry_extrude_splines.html
  35. 1 2
      examples/webgl_materials_nodes.html
  36. 4 4
      examples/webgl_math_orientation_transform.html
  37. 2 0
      examples/webvr_ballshooter.html
  38. 2 0
      examples/webvr_cubes.html
  39. 2 0
      examples/webvr_dragging.html
  40. 2 0
      examples/webvr_lorenzattractor.html
  41. 2 0
      examples/webvr_paint.html
  42. 2 0
      examples/webvr_panorama.html
  43. 2 0
      examples/webvr_rollercoaster.html
  44. 2 0
      examples/webvr_sandbox.html
  45. 2 0
      examples/webvr_sculpt.html
  46. 2 0
      examples/webvr_video.html
  47. 2 0
      examples/webvr_vive_paint.html
  48. 2 0
      examples/webvr_vive_sculpt.html
  49. BIN
      icon.png
  50. 1 1
      package.json
  51. 1 1
      rollup.config.js
  52. 1 1
      src/constants.js
  53. 7 1
      src/extras/core/Font.js
  54. 0 3
      src/geometries/CircleGeometry.d.ts
  55. 2 2
      src/geometries/PolyhedronGeometry.js
  56. 12 18
      src/math/Euler.js
  57. 17 15
      src/math/Line3.js
  58. 11 0
      src/math/Matrix3.d.ts
  59. 13 15
      src/math/Matrix3.js
  60. 17 19
      src/math/Sphere.js
  61. 7 18
      src/math/Vector4.js
  62. 1 1
      utils/modularize.js

+ 1 - 1
README.md

@@ -19,7 +19,7 @@ The aim of the project is to create an easy to use, lightweight, 3D library with
 [Questions](http://stackoverflow.com/questions/tagged/three.js) —
 [Questions](http://stackoverflow.com/questions/tagged/three.js) —
 [Forum](https://discourse.threejs.org/) —
 [Forum](https://discourse.threejs.org/) —
 [Gitter](https://gitter.im/mrdoob/three.js) —
 [Gitter](https://gitter.im/mrdoob/three.js) —
-[Slack](https://threejs-slack.herokuapp.com/)
+[Slack](https://join.slack.com/t/threejs/shared_invite/enQtMzYxMzczODM2OTgxLTQ1YmY4YTQxOTFjNDAzYmQ4NjU2YzRhNzliY2RiNDEyYjU2MjhhODgyYWQ5Y2MyZTU3MWNkOGVmOGRhOTQzYTk)
 
 
 ### Usage ###
 ### Usage ###
 
 

+ 92 - 94
build/three.js

@@ -185,7 +185,7 @@
 
 
 	} );
 	} );
 
 
-	var REVISION = '107dev';
+	var REVISION = '107';
 	var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 };
 	var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 };
 	var TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 };
 	var TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 };
 	var CullFaceNone = 0;
 	var CullFaceNone = 0;
@@ -2349,6 +2349,8 @@
 	 * @author tschw
 	 * @author tschw
 	 */
 	 */
 
 
+	var _vector;
+
 	function Matrix3() {
 	function Matrix3() {
 
 
 		this.elements = [
 		this.elements = [
@@ -2432,29 +2434,25 @@
 
 
 		},
 		},
 
 
-		applyToBufferAttribute: function () {
-
-			var v1 = new Vector3();
-
-			return function applyToBufferAttribute( attribute ) {
+		applyToBufferAttribute: function ( attribute ) {
 
 
-				for ( var i = 0, l = attribute.count; i < l; i ++ ) {
+			if ( _vector === undefined ) _vector = new Vector3();
 
 
-					v1.x = attribute.getX( i );
-					v1.y = attribute.getY( i );
-					v1.z = attribute.getZ( i );
+			for ( var i = 0, l = attribute.count; i < l; i ++ ) {
 
 
-					v1.applyMatrix3( this );
+				_vector.x = attribute.getX( i );
+				_vector.y = attribute.getY( i );
+				_vector.z = attribute.getZ( i );
 
 
-					attribute.setXYZ( i, v1.x, v1.y, v1.z );
+				_vector.applyMatrix3( this );
 
 
-				}
+				attribute.setXYZ( i, _vector.x, _vector.y, _vector.z );
 
 
-				return attribute;
+			}
 
 
-			};
+			return attribute;
 
 
-		}(),
+		},
 
 
 		multiply: function ( m ) {
 		multiply: function ( m ) {
 
 
@@ -3571,27 +3569,16 @@
 
 
 		},
 		},
 
 
-		clampScalar: function () {
-
-			var min, max;
-
-			return function clampScalar( minVal, maxVal ) {
-
-				if ( min === undefined ) {
-
-					min = new Vector4();
-					max = new Vector4();
-
-				}
-
-				min.set( minVal, minVal, minVal, minVal );
-				max.set( maxVal, maxVal, maxVal, maxVal );
+		clampScalar: function ( minVal, maxVal ) {
 
 
-				return this.clamp( min, max );
+			this.x = Math.max( minVal, Math.min( maxVal, this.x ) );
+			this.y = Math.max( minVal, Math.min( maxVal, this.y ) );
+			this.z = Math.max( minVal, Math.min( maxVal, this.z ) );
+			this.w = Math.max( minVal, Math.min( maxVal, this.w ) );
 
 
-			};
+			return this;
 
 
-		}(),
+		},
 
 
 		clampLength: function ( min, max ) {
 		clampLength: function ( min, max ) {
 
 
@@ -4836,6 +4823,8 @@
 	 * @author bhouston / http://clara.io
 	 * @author bhouston / http://clara.io
 	 */
 	 */
 
 
+	var _matrix, _quaternion;
+
 	function Euler( x, y, z, order ) {
 	function Euler( x, y, z, order ) {
 
 
 		this._x = x || 0;
 		this._x = x || 0;
@@ -5080,19 +5069,15 @@
 
 
 		},
 		},
 
 
-		setFromQuaternion: function () {
+		setFromQuaternion: function ( q, order, update ) {
 
 
-			var matrix = new Matrix4();
-
-			return function setFromQuaternion( q, order, update ) {
+			if ( _matrix === undefined ) _matrix = new Matrix4();
 
 
-				matrix.makeRotationFromQuaternion( q );
+			_matrix.makeRotationFromQuaternion( q );
 
 
-				return this.setFromRotationMatrix( matrix, order, update );
+			return this.setFromRotationMatrix( _matrix, order, update );
 
 
-			};
-
-		}(),
+		},
 
 
 		setFromVector3: function ( v, order ) {
 		setFromVector3: function ( v, order ) {
 
 
@@ -5100,21 +5085,17 @@
 
 
 		},
 		},
 
 
-		reorder: function () {
+		reorder: function ( newOrder ) {
 
 
 			// WARNING: this discards revolution information -bhouston
 			// WARNING: this discards revolution information -bhouston
 
 
-			var q = new Quaternion();
-
-			return function reorder( newOrder ) {
+			if ( _quaternion === undefined ) _quaternion = new Quaternion();
 
 
-				q.setFromEuler( this );
+			_quaternion.setFromEuler( this );
 
 
-				return this.setFromQuaternion( q, newOrder );
+			return this.setFromQuaternion( _quaternion, newOrder );
 
 
-			};
-
-		}(),
+		},
 
 
 		equals: function ( euler ) {
 		equals: function ( euler ) {
 
 
@@ -6818,6 +6799,8 @@
 	 * @author mrdoob / http://mrdoob.com/
 	 * @author mrdoob / http://mrdoob.com/
 	 */
 	 */
 
 
+	var _box;
+
 	function Sphere( center, radius ) {
 	function Sphere( center, radius ) {
 
 
 		this.center = ( center !== undefined ) ? center : new Vector3();
 		this.center = ( center !== undefined ) ? center : new Vector3();
@@ -6836,39 +6819,35 @@
 
 
 		},
 		},
 
 
-		setFromPoints: function () {
-
-			var box = new Box3();
-
-			return function setFromPoints( points, optionalCenter ) {
+		setFromPoints: function ( points, optionalCenter ) {
 
 
-				var center = this.center;
+			if ( _box === undefined ) _box = new Box3();
 
 
-				if ( optionalCenter !== undefined ) {
+			var center = this.center;
 
 
-					center.copy( optionalCenter );
+			if ( optionalCenter !== undefined ) {
 
 
-				} else {
+				center.copy( optionalCenter );
 
 
-					box.setFromPoints( points ).getCenter( center );
+			} else {
 
 
-				}
+				_box.setFromPoints( points ).getCenter( center );
 
 
-				var maxRadiusSq = 0;
+			}
 
 
-				for ( var i = 0, il = points.length; i < il; i ++ ) {
+			var maxRadiusSq = 0;
 
 
-					maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );
+			for ( var i = 0, il = points.length; i < il; i ++ ) {
 
 
-				}
+				maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );
 
 
-				this.radius = Math.sqrt( maxRadiusSq );
+			}
 
 
-				return this;
+			this.radius = Math.sqrt( maxRadiusSq );
 
 
-			};
+			return this;
 
 
-		}(),
+		},
 
 
 		clone: function () {
 		clone: function () {
 
 
@@ -11201,7 +11180,7 @@
 
 
 			}
 			}
 
 
-			function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, uv, a, b, c ) {
+			function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, uv, uv2, a, b, c ) {
 
 
 				vA.fromBufferAttribute( position, a );
 				vA.fromBufferAttribute( position, a );
 				vB.fromBufferAttribute( position, b );
 				vB.fromBufferAttribute( position, b );
@@ -11252,6 +11231,16 @@
 
 
 					}
 					}
 
 
+					if ( uv2 ) {
+
+						uvA.fromBufferAttribute( uv2, a );
+						uvB.fromBufferAttribute( uv2, b );
+						uvC.fromBufferAttribute( uv2, c );
+
+						intersection.uv2 = Triangle.getUV( intersectionPoint, vA, vB, vC, uvA, uvB, uvC, new Vector2() );
+
+					}
+
 					var face = new Face3( a, b, c );
 					var face = new Face3( a, b, c );
 					Triangle.getNormal( vA, vB, vC, face.normal );
 					Triangle.getNormal( vA, vB, vC, face.normal );
 
 
@@ -11302,6 +11291,7 @@
 					var position = geometry.attributes.position;
 					var position = geometry.attributes.position;
 					var morphPosition = geometry.morphAttributes.position;
 					var morphPosition = geometry.morphAttributes.position;
 					var uv = geometry.attributes.uv;
 					var uv = geometry.attributes.uv;
+					var uv2 = geometry.attributes.uv2;
 					var groups = geometry.groups;
 					var groups = geometry.groups;
 					var drawRange = geometry.drawRange;
 					var drawRange = geometry.drawRange;
 					var i, j, il, jl;
 					var i, j, il, jl;
@@ -11328,7 +11318,7 @@
 									b = index.getX( j + 1 );
 									b = index.getX( j + 1 );
 									c = index.getX( j + 2 );
 									c = index.getX( j + 2 );
 
 
-									intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, ray, position, morphPosition, uv, a, b, c );
+									intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, ray, position, morphPosition, uv, uv2, a, b, c );
 
 
 									if ( intersection ) {
 									if ( intersection ) {
 
 
@@ -11353,7 +11343,7 @@
 								b = index.getX( i + 1 );
 								b = index.getX( i + 1 );
 								c = index.getX( i + 2 );
 								c = index.getX( i + 2 );
 
 
-								intersection = checkBufferGeometryIntersection( this, material, raycaster, ray, position, morphPosition, uv, a, b, c );
+								intersection = checkBufferGeometryIntersection( this, material, raycaster, ray, position, morphPosition, uv, uv2, a, b, c );
 
 
 								if ( intersection ) {
 								if ( intersection ) {
 
 
@@ -11386,7 +11376,7 @@
 									b = j + 1;
 									b = j + 1;
 									c = j + 2;
 									c = j + 2;
 
 
-									intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, ray, position, morphPosition, uv, a, b, c );
+									intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, ray, position, morphPosition, uv, uv2, a, b, c );
 
 
 									if ( intersection ) {
 									if ( intersection ) {
 
 
@@ -11411,7 +11401,7 @@
 								b = i + 1;
 								b = i + 1;
 								c = i + 2;
 								c = i + 2;
 
 
-								intersection = checkBufferGeometryIntersection( this, material, raycaster, ray, position, morphPosition, uv, a, b, c );
+								intersection = checkBufferGeometryIntersection( this, material, raycaster, ray, position, morphPosition, uv, uv2, a, b, c );
 
 
 								if ( intersection ) {
 								if ( intersection ) {
 
 
@@ -27847,7 +27837,7 @@
 
 
 		// all vertices should lie on a conceptual sphere with a given radius
 		// all vertices should lie on a conceptual sphere with a given radius
 
 
-		appplyRadius( radius );
+		applyRadius( radius );
 
 
 		// finally, create the uv data
 		// finally, create the uv data
 
 
@@ -27960,7 +27950,7 @@
 
 
 		}
 		}
 
 
-		function appplyRadius( radius ) {
+		function applyRadius( radius ) {
 
 
 			var vertex = new Vector3();
 			var vertex = new Vector3();
 
 
@@ -40138,7 +40128,13 @@
 
 
 		var glyph = data.glyphs[ char ] || data.glyphs[ '?' ];
 		var glyph = data.glyphs[ char ] || data.glyphs[ '?' ];
 
 
-		if ( ! glyph ) return;
+		if ( ! glyph ) {
+
+			console.error( 'THREE.Font: character "' + char + '" does not exists in font family ' + data.familyName + '.' );
+
+			return;
+
+		}
 
 
 		var path = new ShapePath();
 		var path = new ShapePath();
 
 
@@ -45158,6 +45154,8 @@
 	 * @author bhouston / http://clara.io
 	 * @author bhouston / http://clara.io
 	 */
 	 */
 
 
+	var _startP, _startEnd;
+
 	function Line3( start, end ) {
 	function Line3( start, end ) {
 
 
 		this.start = ( start !== undefined ) ? start : new Vector3();
 		this.start = ( start !== undefined ) ? start : new Vector3();
@@ -45242,32 +45240,32 @@
 
 
 		},
 		},
 
 
-		closestPointToPointParameter: function () {
+		closestPointToPointParameter: function ( point, clampToLine ) {
 
 
-			var startP = new Vector3();
-			var startEnd = new Vector3();
+			if ( _startP === undefined ) {
 
 
-			return function closestPointToPointParameter( point, clampToLine ) {
+				_startP = new Vector3();
+				_startEnd = new Vector3();
 
 
-				startP.subVectors( point, this.start );
-				startEnd.subVectors( this.end, this.start );
+			}
 
 
-				var startEnd2 = startEnd.dot( startEnd );
-				var startEnd_startP = startEnd.dot( startP );
+			_startP.subVectors( point, this.start );
+			_startEnd.subVectors( this.end, this.start );
 
 
-				var t = startEnd_startP / startEnd2;
+			var startEnd2 = _startEnd.dot( _startEnd );
+			var startEnd_startP = _startEnd.dot( _startP );
 
 
-				if ( clampToLine ) {
+			var t = startEnd_startP / startEnd2;
 
 
-					t = _Math.clamp( t, 0, 1 );
+			if ( clampToLine ) {
 
 
-				}
+				t = _Math.clamp( t, 0, 1 );
 
 
-				return t;
+			}
 
 
-			};
+			return t;
 
 
-		}(),
+		},
 
 
 		closestPointToPoint: function ( point, clampToLine, target ) {
 		closestPointToPoint: function ( point, clampToLine, target ) {
 
 

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 163 - 285
build/three.min.js


+ 92 - 94
build/three.module.js

@@ -179,7 +179,7 @@ Object.assign( EventDispatcher.prototype, {
 
 
 } );
 } );
 
 
-var REVISION = '107dev';
+var REVISION = '107';
 var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 };
 var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 };
 var TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 };
 var TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 };
 var CullFaceNone = 0;
 var CullFaceNone = 0;
@@ -2343,6 +2343,8 @@ Object.assign( Vector3.prototype, {
  * @author tschw
  * @author tschw
  */
  */
 
 
+var _vector;
+
 function Matrix3() {
 function Matrix3() {
 
 
 	this.elements = [
 	this.elements = [
@@ -2426,29 +2428,25 @@ Object.assign( Matrix3.prototype, {
 
 
 	},
 	},
 
 
-	applyToBufferAttribute: function () {
-
-		var v1 = new Vector3();
-
-		return function applyToBufferAttribute( attribute ) {
+	applyToBufferAttribute: function ( attribute ) {
 
 
-			for ( var i = 0, l = attribute.count; i < l; i ++ ) {
+		if ( _vector === undefined ) _vector = new Vector3();
 
 
-				v1.x = attribute.getX( i );
-				v1.y = attribute.getY( i );
-				v1.z = attribute.getZ( i );
+		for ( var i = 0, l = attribute.count; i < l; i ++ ) {
 
 
-				v1.applyMatrix3( this );
+			_vector.x = attribute.getX( i );
+			_vector.y = attribute.getY( i );
+			_vector.z = attribute.getZ( i );
 
 
-				attribute.setXYZ( i, v1.x, v1.y, v1.z );
+			_vector.applyMatrix3( this );
 
 
-			}
+			attribute.setXYZ( i, _vector.x, _vector.y, _vector.z );
 
 
-			return attribute;
+		}
 
 
-		};
+		return attribute;
 
 
-	}(),
+	},
 
 
 	multiply: function ( m ) {
 	multiply: function ( m ) {
 
 
@@ -3565,27 +3563,16 @@ Object.assign( Vector4.prototype, {
 
 
 	},
 	},
 
 
-	clampScalar: function () {
-
-		var min, max;
-
-		return function clampScalar( minVal, maxVal ) {
-
-			if ( min === undefined ) {
-
-				min = new Vector4();
-				max = new Vector4();
-
-			}
-
-			min.set( minVal, minVal, minVal, minVal );
-			max.set( maxVal, maxVal, maxVal, maxVal );
+	clampScalar: function ( minVal, maxVal ) {
 
 
-			return this.clamp( min, max );
+		this.x = Math.max( minVal, Math.min( maxVal, this.x ) );
+		this.y = Math.max( minVal, Math.min( maxVal, this.y ) );
+		this.z = Math.max( minVal, Math.min( maxVal, this.z ) );
+		this.w = Math.max( minVal, Math.min( maxVal, this.w ) );
 
 
-		};
+		return this;
 
 
-	}(),
+	},
 
 
 	clampLength: function ( min, max ) {
 	clampLength: function ( min, max ) {
 
 
@@ -4830,6 +4817,8 @@ Object.assign( Matrix4.prototype, {
  * @author bhouston / http://clara.io
  * @author bhouston / http://clara.io
  */
  */
 
 
+var _matrix, _quaternion;
+
 function Euler( x, y, z, order ) {
 function Euler( x, y, z, order ) {
 
 
 	this._x = x || 0;
 	this._x = x || 0;
@@ -5074,19 +5063,15 @@ Object.assign( Euler.prototype, {
 
 
 	},
 	},
 
 
-	setFromQuaternion: function () {
+	setFromQuaternion: function ( q, order, update ) {
 
 
-		var matrix = new Matrix4();
-
-		return function setFromQuaternion( q, order, update ) {
+		if ( _matrix === undefined ) _matrix = new Matrix4();
 
 
-			matrix.makeRotationFromQuaternion( q );
+		_matrix.makeRotationFromQuaternion( q );
 
 
-			return this.setFromRotationMatrix( matrix, order, update );
+		return this.setFromRotationMatrix( _matrix, order, update );
 
 
-		};
-
-	}(),
+	},
 
 
 	setFromVector3: function ( v, order ) {
 	setFromVector3: function ( v, order ) {
 
 
@@ -5094,21 +5079,17 @@ Object.assign( Euler.prototype, {
 
 
 	},
 	},
 
 
-	reorder: function () {
+	reorder: function ( newOrder ) {
 
 
 		// WARNING: this discards revolution information -bhouston
 		// WARNING: this discards revolution information -bhouston
 
 
-		var q = new Quaternion();
-
-		return function reorder( newOrder ) {
+		if ( _quaternion === undefined ) _quaternion = new Quaternion();
 
 
-			q.setFromEuler( this );
+		_quaternion.setFromEuler( this );
 
 
-			return this.setFromQuaternion( q, newOrder );
+		return this.setFromQuaternion( _quaternion, newOrder );
 
 
-		};
-
-	}(),
+	},
 
 
 	equals: function ( euler ) {
 	equals: function ( euler ) {
 
 
@@ -6812,6 +6793,8 @@ Object.assign( Box3.prototype, {
  * @author mrdoob / http://mrdoob.com/
  * @author mrdoob / http://mrdoob.com/
  */
  */
 
 
+var _box;
+
 function Sphere( center, radius ) {
 function Sphere( center, radius ) {
 
 
 	this.center = ( center !== undefined ) ? center : new Vector3();
 	this.center = ( center !== undefined ) ? center : new Vector3();
@@ -6830,39 +6813,35 @@ Object.assign( Sphere.prototype, {
 
 
 	},
 	},
 
 
-	setFromPoints: function () {
-
-		var box = new Box3();
-
-		return function setFromPoints( points, optionalCenter ) {
+	setFromPoints: function ( points, optionalCenter ) {
 
 
-			var center = this.center;
+		if ( _box === undefined ) _box = new Box3();
 
 
-			if ( optionalCenter !== undefined ) {
+		var center = this.center;
 
 
-				center.copy( optionalCenter );
+		if ( optionalCenter !== undefined ) {
 
 
-			} else {
+			center.copy( optionalCenter );
 
 
-				box.setFromPoints( points ).getCenter( center );
+		} else {
 
 
-			}
+			_box.setFromPoints( points ).getCenter( center );
 
 
-			var maxRadiusSq = 0;
+		}
 
 
-			for ( var i = 0, il = points.length; i < il; i ++ ) {
+		var maxRadiusSq = 0;
 
 
-				maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );
+		for ( var i = 0, il = points.length; i < il; i ++ ) {
 
 
-			}
+			maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );
 
 
-			this.radius = Math.sqrt( maxRadiusSq );
+		}
 
 
-			return this;
+		this.radius = Math.sqrt( maxRadiusSq );
 
 
-		};
+		return this;
 
 
-	}(),
+	},
 
 
 	clone: function () {
 	clone: function () {
 
 
@@ -11195,7 +11174,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 
 		}
 		}
 
 
-		function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, uv, a, b, c ) {
+		function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, uv, uv2, a, b, c ) {
 
 
 			vA.fromBufferAttribute( position, a );
 			vA.fromBufferAttribute( position, a );
 			vB.fromBufferAttribute( position, b );
 			vB.fromBufferAttribute( position, b );
@@ -11246,6 +11225,16 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 
 				}
 				}
 
 
+				if ( uv2 ) {
+
+					uvA.fromBufferAttribute( uv2, a );
+					uvB.fromBufferAttribute( uv2, b );
+					uvC.fromBufferAttribute( uv2, c );
+
+					intersection.uv2 = Triangle.getUV( intersectionPoint, vA, vB, vC, uvA, uvB, uvC, new Vector2() );
+
+				}
+
 				var face = new Face3( a, b, c );
 				var face = new Face3( a, b, c );
 				Triangle.getNormal( vA, vB, vC, face.normal );
 				Triangle.getNormal( vA, vB, vC, face.normal );
 
 
@@ -11296,6 +11285,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
 				var position = geometry.attributes.position;
 				var position = geometry.attributes.position;
 				var morphPosition = geometry.morphAttributes.position;
 				var morphPosition = geometry.morphAttributes.position;
 				var uv = geometry.attributes.uv;
 				var uv = geometry.attributes.uv;
+				var uv2 = geometry.attributes.uv2;
 				var groups = geometry.groups;
 				var groups = geometry.groups;
 				var drawRange = geometry.drawRange;
 				var drawRange = geometry.drawRange;
 				var i, j, il, jl;
 				var i, j, il, jl;
@@ -11322,7 +11312,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
 								b = index.getX( j + 1 );
 								b = index.getX( j + 1 );
 								c = index.getX( j + 2 );
 								c = index.getX( j + 2 );
 
 
-								intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, ray, position, morphPosition, uv, a, b, c );
+								intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, ray, position, morphPosition, uv, uv2, a, b, c );
 
 
 								if ( intersection ) {
 								if ( intersection ) {
 
 
@@ -11347,7 +11337,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
 							b = index.getX( i + 1 );
 							b = index.getX( i + 1 );
 							c = index.getX( i + 2 );
 							c = index.getX( i + 2 );
 
 
-							intersection = checkBufferGeometryIntersection( this, material, raycaster, ray, position, morphPosition, uv, a, b, c );
+							intersection = checkBufferGeometryIntersection( this, material, raycaster, ray, position, morphPosition, uv, uv2, a, b, c );
 
 
 							if ( intersection ) {
 							if ( intersection ) {
 
 
@@ -11380,7 +11370,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
 								b = j + 1;
 								b = j + 1;
 								c = j + 2;
 								c = j + 2;
 
 
-								intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, ray, position, morphPosition, uv, a, b, c );
+								intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, ray, position, morphPosition, uv, uv2, a, b, c );
 
 
 								if ( intersection ) {
 								if ( intersection ) {
 
 
@@ -11405,7 +11395,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
 							b = i + 1;
 							b = i + 1;
 							c = i + 2;
 							c = i + 2;
 
 
-							intersection = checkBufferGeometryIntersection( this, material, raycaster, ray, position, morphPosition, uv, a, b, c );
+							intersection = checkBufferGeometryIntersection( this, material, raycaster, ray, position, morphPosition, uv, uv2, a, b, c );
 
 
 							if ( intersection ) {
 							if ( intersection ) {
 
 
@@ -27841,7 +27831,7 @@ function PolyhedronBufferGeometry( vertices, indices, radius, detail ) {
 
 
 	// all vertices should lie on a conceptual sphere with a given radius
 	// all vertices should lie on a conceptual sphere with a given radius
 
 
-	appplyRadius( radius );
+	applyRadius( radius );
 
 
 	// finally, create the uv data
 	// finally, create the uv data
 
 
@@ -27954,7 +27944,7 @@ function PolyhedronBufferGeometry( vertices, indices, radius, detail ) {
 
 
 	}
 	}
 
 
-	function appplyRadius( radius ) {
+	function applyRadius( radius ) {
 
 
 		var vertex = new Vector3();
 		var vertex = new Vector3();
 
 
@@ -40132,7 +40122,13 @@ function createPath( char, scale, offsetX, offsetY, data ) {
 
 
 	var glyph = data.glyphs[ char ] || data.glyphs[ '?' ];
 	var glyph = data.glyphs[ char ] || data.glyphs[ '?' ];
 
 
-	if ( ! glyph ) return;
+	if ( ! glyph ) {
+
+		console.error( 'THREE.Font: character "' + char + '" does not exists in font family ' + data.familyName + '.' );
+
+		return;
+
+	}
 
 
 	var path = new ShapePath();
 	var path = new ShapePath();
 
 
@@ -45152,6 +45148,8 @@ Object.assign( Box2.prototype, {
  * @author bhouston / http://clara.io
  * @author bhouston / http://clara.io
  */
  */
 
 
+var _startP, _startEnd;
+
 function Line3( start, end ) {
 function Line3( start, end ) {
 
 
 	this.start = ( start !== undefined ) ? start : new Vector3();
 	this.start = ( start !== undefined ) ? start : new Vector3();
@@ -45236,32 +45234,32 @@ Object.assign( Line3.prototype, {
 
 
 	},
 	},
 
 
-	closestPointToPointParameter: function () {
+	closestPointToPointParameter: function ( point, clampToLine ) {
 
 
-		var startP = new Vector3();
-		var startEnd = new Vector3();
+		if ( _startP === undefined ) {
 
 
-		return function closestPointToPointParameter( point, clampToLine ) {
+			_startP = new Vector3();
+			_startEnd = new Vector3();
 
 
-			startP.subVectors( point, this.start );
-			startEnd.subVectors( this.end, this.start );
+		}
 
 
-			var startEnd2 = startEnd.dot( startEnd );
-			var startEnd_startP = startEnd.dot( startP );
+		_startP.subVectors( point, this.start );
+		_startEnd.subVectors( this.end, this.start );
 
 
-			var t = startEnd_startP / startEnd2;
+		var startEnd2 = _startEnd.dot( _startEnd );
+		var startEnd_startP = _startEnd.dot( _startP );
 
 
-			if ( clampToLine ) {
+		var t = startEnd_startP / startEnd2;
 
 
-				t = _Math.clamp( t, 0, 1 );
+		if ( clampToLine ) {
 
 
-			}
+			t = _Math.clamp( t, 0, 1 );
 
 
-			return t;
+		}
 
 
-		};
+		return t;
 
 
-	}(),
+	},
 
 
 	closestPointToPoint: function ( point, clampToLine, target ) {
 	closestPointToPoint: function ( point, clampToLine, target ) {
 
 

+ 2 - 2
docs/api/en/objects/Sprite.html

@@ -78,8 +78,8 @@ scene.add( sprite );
 
 
 		<h3>[method:null raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
 		<h3>[method:null raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
 		<p>
 		<p>
-		Get intersections between a casted ray and this sprite.
-		[page:Raycaster.intersectObject] will call this method.
+		Get intersections between a casted ray and this sprite. [page:Raycaster.intersectObject]() will call this method.
+		The raycaster must be initialized by calling [page:Raycaster.setFromCamera]() before raycasting against sprites.
 		</p>
 		</p>
 
 
 
 

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

@@ -67,7 +67,7 @@
 
 
 		<h3>[method:Float getElapsedTime]()</h3>
 		<h3>[method:Float getElapsedTime]()</h3>
 		<p>
 		<p>
-			获取自时钟启动后的秒数,摒弃将 [page:Clock.oldTime oldTime] 设置为当前时间。<br />
+			获取自时钟启动后的秒数,同时将 [page:Clock.oldTime oldTime] 设置为当前时间。<br />
 			如果 [page:Clock.autoStart autoStart] 设置为 *true* 且时钟并未运行,则该方法同时启动时钟。
 			如果 [page:Clock.autoStart autoStart] 设置为 *true* 且时钟并未运行,则该方法同时启动时钟。
 		</p>
 		</p>
 
 

+ 4 - 7
docs/manual/en/introduction/Loading-3D-models.html

@@ -92,18 +92,15 @@
 		// commonjs
 		// commonjs
 		var THREE = window.THREE = require('three');
 		var THREE = window.THREE = require('three');
 		require('three/examples/js/loaders/GLTFLoader');
 		require('three/examples/js/loaders/GLTFLoader');
-	</code>
 
 
-	<p>
-		Currently three.js examples are not available as ES modules (import &hellip; from '&hellip;').
-		Several workarounds are discussed in
-		<a href="https://github.com/mrdoob/three.js/issues/9562" target="_blank" rel="noopener">#9562</a>.
-	</p>
+		// ES modules
+		import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
+	</code>
 
 
 	<p>
 	<p>
 		Once you've imported a loader, you're ready to add a model to your scene. Syntax varies among
 		Once you've imported a loader, you're ready to add a model to your scene. Syntax varies among
 		different loaders — when using another format, check the examples and documentation for that
 		different loaders — when using another format, check the examples and documentation for that
-		loader. For glTF, basic usage would be:
+		loader. For glTF, usage with global scripts would be:
 	</p>
 	</p>
 
 
 	<code>
 	<code>

+ 15 - 15
docs/manual/zh/introduction/Creating-a-scene.html

@@ -55,21 +55,21 @@
 
 
 		<p>three.js里有几种不同的相机,在这里,我们使用的是<strong>PerspectiveCamera</strong>(透视摄像机)。</p>
 		<p>three.js里有几种不同的相机,在这里,我们使用的是<strong>PerspectiveCamera</strong>(透视摄像机)。</p>
 
 
-		<p>第一个属性是<strong>视野角度(FOV)</strong>。视野角度就是无论在什么时候,你所能在显示器上看到的场景的范围,它的值是一个角度。</p>
+		<p>第一个参数是<strong>视野角度(FOV)</strong>。视野角度就是无论在什么时候,你所能在显示器上看到的场景的范围,它的值是角度单位。</p>
 
 
-		<p>第二个是<strong>长宽比(aspect ratio)</strong>。 也就是你用一个物体的宽除以它的高的值。比如说,当你在一个宽屏电视上播放老电影时,可以看到图像仿佛是被压扁的。</p>
+		<p>第二个参数是<strong>长宽比(aspect ratio)</strong>。 也就是你用一个物体的宽除以它的高的值。比如说,当你在一个宽屏电视上播放老电影时,可以看到图像仿佛是被压扁的。</p>
 
 
-		<p>接下来的两个值是<strong>远剪切面</strong>和<strong>近剪切面</strong>。 也就是说当物体所在的位置比摄像机的<strong>远剪切面</strong>远或者所在位置比<strong>近剪切面</strong>近的时候,该物体超出的部分将不会被渲染到场景中。现在你或许并不用担心这个值的影响,但未来为了获得更好的渲染性能,你将可以在你的应用程序里去设置它。</p>
+		<p>接下来的两个参数是<strong>近截面</strong>(near)和<strong>远截面</strong>(far)。 当物体某些部分比摄像机的<strong>远截面</strong>远或者比<strong>近截面</strong>近的时候,该这些部分将不会被渲染到场景中。你或许现在并不用担心这个值的影响,但未来为了获得更好的渲染性能,你将可以在你的应用程序里去设置它。</p>
 
 
 		<p>接下来是渲染器。这里是施展魔法的地方。除了我们在这里用到的WebGLRenderer渲染器之外,Three.js同时提供了其他几种渲染器,当用户所使用的浏览器过于老旧,或者由于其他原因不支持WebGL时,可以使用这几种渲染器进行降级。</p>
 		<p>接下来是渲染器。这里是施展魔法的地方。除了我们在这里用到的WebGLRenderer渲染器之外,Three.js同时提供了其他几种渲染器,当用户所使用的浏览器过于老旧,或者由于其他原因不支持WebGL时,可以使用这几种渲染器进行降级。</p>
 
 
-		<p>除了创建一个渲染器的实例之外,我们还需要在我们的应用程序里设置一个渲染器的大小尺寸。比如说,我们可以使用所需要的渲染区域的宽高,来让渲染器渲染出的场景填充满我们的应用程序。因此,我们可以将渲染器宽高设置为浏览器窗口宽高。对于性能比较敏感的应用程序来说,你可以<strong>setSize</strong>传入一个较小的值,例如<strong>window.innerWidth/2</strong>和<strong>window.innerHeight/2</strong>,这将使得应用程序在渲染时,以一半的长宽尺寸渲染场景。</p>
+		<p>除了创建一个渲染器的实例之外,我们还需要在我们的应用程序里设置一个渲染器的尺寸。比如说,我们可以使用所需要的渲染区域的宽高,来让渲染器渲染出的场景填充满我们的应用程序。因此,我们可以将渲染器宽高设置为浏览器窗口宽高。对于性能比较敏感的应用程序来说,你可以使用<strong>setSize</strong>传入一个较小的值,例如<strong>window.innerWidth/2</strong>和<strong>window.innerHeight/2</strong>,这将使得应用程序在渲染时,以一半的长宽尺寸渲染场景。</p>
 
 
-		<p>如果你希望保持你的应用程序的尺寸,但是以较低的分辨率来渲染,你可以在调用<strong>setSize</strong>时,给<strong>updateStyle</strong>(第三个参数)传入false。例如,假设你的&lt;canvas&gt; 标签现在已经具有了100%的宽和高,调用<strong>setSize(window.innerWidth/2, window.innerHeight/2, false)</strong>将使得你的应用程序以一半的分辨率来进行渲染。</p>
+		<p>如果你希望保持你的应用程序的尺寸,但是以较低的分辨率来渲染,你可以在调用<strong>setSize</strong>时,将<strong>updateStyle</strong>(第三个参数)设为false。例如,假设你的&lt;canvas&gt; 标签现在已经具有了100%的宽和高,调用<strong>setSize(window.innerWidth/2, window.innerHeight/2, false)</strong>将使得你的应用程序以一半的分辨率来进行渲染。</p>
 
 
-		<p>最后,我们将<strong>renderer</strong>(渲染器)这个元素添加到我们的HTML文档中,这也就是渲染器使用&lt;canvas&gt;元素来将场景展现给我们。</p>
+		<p>最后一步很重要,我们将<strong>renderer</strong>(渲染器)的dom元素(renderer.domElement)添加到我们的HTML文档中。这就是渲染器用来显示场景给我们看的&lt;canvas&gt;元素。</p>
 
 
-		<p><em>“嗯,看起来很不错,那你说的那个立方体在哪儿?”</em>接下来,我们就来对它继续进行添加。</p>
+		<p><em>“嗯,看起来很不错,那你说的那个立方体在哪儿?”</em>接下来,我们就来添加立方体。</p>
 
 
 		<code>
 		<code>
 		var geometry = new THREE.BoxGeometry( 1, 1, 1 );
 		var geometry = new THREE.BoxGeometry( 1, 1, 1 );
@@ -82,15 +82,15 @@
 
 
 		<p>要创建一个立方体,我们需要一个<strong>BoxGeometry</strong>(立方体)对象. 这个对象包含了一个立方体中所有的顶点(<strong>vertices</strong>)和面(<strong>faces</strong>)。未来我们将在这方面进行更多的探索。</p>
 		<p>要创建一个立方体,我们需要一个<strong>BoxGeometry</strong>(立方体)对象. 这个对象包含了一个立方体中所有的顶点(<strong>vertices</strong>)和面(<strong>faces</strong>)。未来我们将在这方面进行更多的探索。</p>
 
 
-		<p>接下来,对于这个立方体,我们需要给它一个材质,来让它有颜色。Three.js自带了几种材质,在这里我们使用的是<strong>MeshBasicMaterial</strong>。所有的材质是都一个将会被应用于立方体的属性对象。在这里为了简单起见,我们只设置一个color属性,值为<strong>0x00ff00</strong>,也就是绿色。这里所做的事情,就相当于是在CSS或者Photoshop中使用十六进制(<strong>hex colors</strong>)颜色格式来设置颜色。</p>
+		<p>接下来,对于这个立方体,我们需要给它一个材质,来让它有颜色。Three.js自带了几种材质,在这里我们使用的是<strong>MeshBasicMaterial</strong>。所有的材质都存有应用于他们的属性的对象。在这里为了简单起见,我们只设置一个color属性,值为<strong>0x00ff00</strong>,也就是绿色。这里所做的事情,在CSS或者Photoshop中使用十六进制(<strong>hex colors</strong>)颜色格式来设置颜色的方式一致。</p>
 
 
-		<p>第三步,我们需要一个<strong>Mesh</strong>(网格)。 网格是包含有一个几何体以及应用在在此几何体上的材质的对象,我们可以直接将网格对象放入到我们的场景中,并让它在场景中自由移动。</p>
+		<p>第三步,我们需要一个<strong>Mesh</strong>(网格)。 网格包含一个几何体以及作用在此几何体上的材质,我们可以直接将网格对象放入到我们的场景中,并让它在场景中自由移动。</p>
 
 
-		<p>默认情况下,当我们调用<strong>scene.add()</strong>的时候,物体将会被添加到坐标为<strong>(0,0,0)</strong>的位置。但这可能会使得摄像机的位置和立方体相互重叠(也就是摄像机位于立方体中)。为了防止这种情况的发生,我们只需要将摄像机稍微向外移动一些即可。</p>
+		<p>默认情况下,当我们调用<strong>scene.add()</strong>的时候,物体将会被添加到<strong>(0,0,0)</strong>坐标。但将使得摄像机和立方体彼此在一起。为了防止这种情况的发生,我们只需要将摄像机稍微向外移动一些即可。</p>
 
 
 		<h2>渲染场景</h2>
 		<h2>渲染场景</h2>
 
 
-		<p>现在,如果你已经从上面复制了我们已经写好的代码到HTML文件中,你将不会在其中看到任何东西。这是因为我们还没有对它进行真正的渲染。为此,我们需要调用一个被叫做“<strong>渲染</strong>”或者“<strong>动画循环</strong>”的东西。</p>
+		<p>现在,如果将之前写好的代码复制到HTML文件中,你不会在页面中看到任何东西。这是因为我们还没有对它进行真正的渲染。为此,我们需要使用“<strong>渲染循环</strong>”(render loop)或者“<strong>动画循环</strong>”(animate loop)的东西。</p>
 
 
 		<code>
 		<code>
 		function animate() {
 		function animate() {
@@ -100,12 +100,12 @@
 		animate();
 		animate();
 		</code>
 		</code>
 
 
-		<p>在这里我们创建了一个循环——这使得渲染器能够在每次屏幕刷新时对场景进行绘制(在大多数屏幕上,刷新率一般是60次/秒)。如果你正在浏览器里写一个游戏,你或许会说<em>“为什么我们不直接用setInterval来实现刷新的功能呢?”</em>当然啦,我们的确可以用setInterval,但是,<strong>requestAnimationFrame</strong>有很多的优点。最重要的一点或许就是当用户切换到其它的标签页时,它会暂停,因此不会浪费用户宝贵的处理器资源,以及损耗电池的使用寿命。</p>
+		<p>在将创建了一个使渲染器能够在每次屏幕刷新时对场景进行绘制的循环(在大多数屏幕上,刷新率一般是60次/秒)。如果你是一个浏览器游戏开发的新手,你或许会说<em>“为什么我们不直接用setInterval来实现刷新的功能呢?”</em>当然啦,我们的确可以用setInterval,但是,<strong>requestAnimationFrame</strong>有很多的优点。最重要的一点或许就是当用户切换到其它的标签页时,它会暂停,因此不会浪费用户宝贵的处理器资源,以及损耗电池的使用寿命。</p>
 
 
 		<h2>使立方体动起来</h2>
 		<h2>使立方体动起来</h2>
 
 
 		<p>
 		<p>
-			在开始之前,如果你已经将上面的代码写入到了你所创建的文件中,你应当已经可以看到一个绿色的立方体。让我们来做一些更加有趣的事 —— 让它旋转起来。</p>
+			在开始之前,如果你已经将上面的代码写入到了你所创建的文件中,你可以看到一个绿色的方块。让我们来做一些更加有趣的事 —— 让它旋转起来。</p>
 
 
 		<p>将下列代码添加到animate()函数中<strong>renderer.render</strong>调用的上方:</p>
 		<p>将下列代码添加到animate()函数中<strong>renderer.render</strong>调用的上方:</p>
 
 
@@ -114,12 +114,12 @@
 		cube.rotation.y += 0.01;
 		cube.rotation.y += 0.01;
 		</code>
 		</code>
 
 
-		<p>这一段代码将在每一帧时被渲染时调用(正常情况下是60次/秒),这就让立方体有了一个看起来很不错的旋转动画。基本上来说,当应用程序运行时,如果你想要移动或者改变任何场景中的东西,都必须要经过这个动画循环。当然,在这个动画循环函数里,你也可以调用别的函数,这样你在写<strong>animate</strong>函数的时候,就不用在这里以成千上万的代码来结尾了。</p>
+		<p>这段代码每帧都会执行(正常情况下是60次/秒),这就让立方体有了一个看起来很不错的旋转动画。基本上来说,当应用程序运行时,如果你想要移动或者改变任何场景中的东西,都必须要经过这个动画循环。当然,你可以在这个动画循环里调用别的函数,这样你就不会写出有上百行代码的<strong>animate</strong>函数。</p>
 
 
 		<h2>结果</h2>
 		<h2>结果</h2>
 		<p>祝贺你!你现在已经成功完成了你的第一个Three.js应用程序。虽然它很简单,但现在你已经有了一个入门的起点。</p>
 		<p>祝贺你!你现在已经成功完成了你的第一个Three.js应用程序。虽然它很简单,但现在你已经有了一个入门的起点。</p>
 
 
-		<p>下面是完整的代码,请尽情运行它或者修改它,这将可以让你对它的工作机制有更加深入的了解。</p>
+		<p>下面是完整的代码,运行或者修改代码从而有助于更好的理解它是如何工作的。</p>
 
 
 		<code>
 		<code>
 		&lt;html&gt;
 		&lt;html&gt;

+ 6 - 6
docs/manual/zh/introduction/Import-via-modules.html

@@ -11,20 +11,20 @@
 		<h1>通过模块来引入([name])</h1>
 		<h1>通过模块来引入([name])</h1>
 
 
 		<p>
 		<p>
-			虽然通过script标签来引入three.js是一个能够快速起步、快速运行的方式,但这种方式对于一些具有较长生命周期的项目来说是有一些缺点。比如
+			虽然通过script标签来引入three.js是一个能够快速起步、快速运行的方式,但这种方式对于一些具有较长生命周期的项目来说是有一些缺点。比如:
 
 
 			<ul>
 			<ul>
-				<li>你必须手动获得并在你的源代码中包含这个库的一个拷贝</li>
-				<li>更新这个库的版本是一个手动操作的过程</li>
-				<li>在检查新版本的库时,你的版本差异对比将会被许多行给弄乱。</li>
+				<li>你必须手动获得并在你的项目源代码中包含这个库的一个拷贝</li>
+				<li>更新库的版本是一个手动操作的过程</li>
+				<li>在检查新版本的库时,你的版本差异对比将会被许多行的构建文件给弄乱。</li>
 			</ul>
 			</ul>
 		</p>
 		</p>
 
 
-		<p>使用像npm这样的依赖包管理器可以很好地避免这些需要注意的问题,只需在你的电脑上下载并导入你所需要的库的版本即可。</p>
+		<p>使用像npm这样的依赖包管理器,你只需在你的机器上下载并导入你所需要的版本的库就很好地避免这些需要注意的问题。</p>
 
 
 		<h2>通过npm来安装</h2>
 		<h2>通过npm来安装</h2>
 
 
-		<p>Three.js目前已经作为一个npm来进行了发布,详情请参阅:[link:https://www.npmjs.com/package/three npm]。这意味着,在所有你需要包含three.js库的项目中,只需运行"npm install three"即可。</p>
+		<p>Three.js目前已经作为一个npm模块来进行了发布,详情请参阅:[link:https://www.npmjs.com/package/three npm]。这意味着你只需运行"npm install three"就可以使你的项目包含three.js库。</p>
 
 
 		<h2>导入这个模块</h2>
 		<h2>导入这个模块</h2>
 
 

+ 3 - 6
docs/manual/zh/introduction/Loading-3D-models.html

@@ -79,13 +79,10 @@
 		// commonjs
 		// commonjs
 		var THREE = window.THREE = require('three');
 		var THREE = window.THREE = require('three');
 		require('three/examples/js/loaders/GLTFLoader');
 		require('three/examples/js/loaders/GLTFLoader');
-	</code>
 
 
-	<p>
-		目前three.js示例不能作为ES modules (import &hellip; from '&hellip;')来使用。
-		这里讨论了一些解决方法:
-		<a href="https://github.com/mrdoob/three.js/issues/9562" target="_blank" rel="noopener">#9562</a>.
-	</p>
+		// ES modules
+		import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
+	</code>
 
 
 	<p>
 	<p>
 		一旦你引入了一个加载器,你就已经准备好为场景添加模型了。不同加载器之间可能具有不同的语法 ——
 		一旦你引入了一个加载器,你就已经准备好为场景添加模型了。不同加载器之间可能具有不同的语法 ——

+ 2 - 0
editor/index.html

@@ -7,6 +7,8 @@
 		<link rel="apple-touch-icon" href="images/icon.png">
 		<link rel="apple-touch-icon" href="images/icon.png">
 		<link rel="manifest" href="manifest.json">
 		<link rel="manifest" href="manifest.json">
 		<link rel="shortcut icon" href="../files/favicon.ico" />
 		<link rel="shortcut icon" href="../files/favicon.ico" />
+		<!-- WebXR Device API (For Chrome M76+), expires 09/09/2019 -->
+		<meta http-equiv="origin-trial" content="Ai1/G787sugfmWtk1xQExa8N6OqwDsJyNn+OwpA1J4PozR1lixRYIQ4Tmp00vrGWS8FQQ2iDyqjwaewrOfYvPAUAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU03NiIsImV4cGlyeSI6MTU2ODAyMzQ3OH0=">
 	</head>
 	</head>
 	<body ontouchstart="">
 	<body ontouchstart="">
 		<link rel="stylesheet" href="css/main.css">
 		<link rel="stylesheet" href="css/main.css">

+ 1 - 1
editor/sw.js

@@ -1,4 +1,4 @@
-// r106
+// r107
 
 
 const staticAssets = [
 const staticAssets = [
 	'./',
 	'./',

+ 2 - 2
examples/css3d_molecules.html

@@ -425,7 +425,7 @@
 
 
 						var objMatrix = new THREE.Matrix4().makeRotationAxis( axis.normalize(), radians );
 						var objMatrix = new THREE.Matrix4().makeRotationAxis( axis.normalize(), radians );
 						object.matrix = objMatrix;
 						object.matrix = objMatrix;
-						object.rotation.setFromRotationMatrix( object.matrix, object.rotation.order );
+						object.quaternion.setFromRotationMatrix( object.matrix );
 
 
 						object.matrixAutoUpdate = false;
 						object.matrixAutoUpdate = false;
 						object.updateMatrix();
 						object.updateMatrix();
@@ -445,7 +445,7 @@
 						joint.position.lerp( end, 0.5 );
 						joint.position.lerp( end, 0.5 );
 
 
 						joint.matrix.copy( objMatrix );
 						joint.matrix.copy( objMatrix );
-						joint.rotation.setFromRotationMatrix( joint.matrix, joint.rotation.order );
+						joint.quaternion.setFromRotationMatrix( joint.matrix );
 
 
 						joint.matrixAutoUpdate = false;
 						joint.matrixAutoUpdate = false;
 						joint.updateMatrix();
 						joint.updateMatrix();

+ 1 - 1
examples/files.js

@@ -282,7 +282,7 @@ var files = {
 		"webgl_buffergeometry",
 		"webgl_buffergeometry",
 		"webgl_buffergeometry_constructed_from_geometry",
 		"webgl_buffergeometry_constructed_from_geometry",
 		"webgl_buffergeometry_custom_attributes_particles",
 		"webgl_buffergeometry_custom_attributes_particles",
-		"webgl_buffergeometry_drawcalls",
+		"webgl_buffergeometry_drawrange",
 		"webgl_buffergeometry_indexed",
 		"webgl_buffergeometry_indexed",
 		"webgl_buffergeometry_instancing",
 		"webgl_buffergeometry_instancing",
 		"webgl_buffergeometry_instancing2",
 		"webgl_buffergeometry_instancing2",

+ 13 - 20
examples/js/loaders/FBXLoader.js

@@ -288,27 +288,15 @@ THREE.FBXLoader = ( function () {
 
 
 				case 'tga':
 				case 'tga':
 
 
-					if ( typeof THREE.TGALoader !== 'function' ) {
+					if ( THREE.Loader.Handlers.get( '.tga' ) === null ) {
 
 
-						console.warn( 'FBXLoader: THREE.TGALoader is required to load TGA textures' );
-						return;
-
-					} else {
-
-						if ( THREE.Loader.Handlers.get( '.tga' ) === null ) {
-
-							var tgaLoader = new THREE.TGALoader();
-							tgaLoader.setPath( this.textureLoader.path );
-
-							THREE.Loader.Handlers.add( /\.tga$/i, tgaLoader );
-
-						}
-
-						type = 'image/tga';
-						break;
+						console.warn( 'FBXLoader: TGA loader not found, skipping ', fileName );
 
 
 					}
 					}
 
 
+					type = 'image/tga';
+					break;
+
 				default:
 				default:
 
 
 					console.warn( 'FBXLoader: Image type "' + extension + '" is not supported.' );
 					console.warn( 'FBXLoader: Image type "' + extension + '" is not supported.' );
@@ -417,7 +405,7 @@ THREE.FBXLoader = ( function () {
 
 
 				if ( loader === null ) {
 				if ( loader === null ) {
 
 
-					console.warn( 'FBXLoader: TGALoader not found, creating empty placeholder texture for', fileName );
+					console.warn( 'FBXLoader: TGA loader not found, creating placeholder texture for', textureNode.RelativeFilename );
 					texture = new THREE.Texture();
 					texture = new THREE.Texture();
 
 
 				} else {
 				} else {
@@ -428,7 +416,7 @@ THREE.FBXLoader = ( function () {
 
 
 			} else if ( extension === 'psd' ) {
 			} else if ( extension === 'psd' ) {
 
 
-				console.warn( 'FBXLoader: PSD textures are not supported, creating empty placeholder texture for', fileName );
+				console.warn( 'FBXLoader: PSD textures are not supported, creating placeholder texture for', textureNode.RelativeFilename );
 				texture = new THREE.Texture();
 				texture = new THREE.Texture();
 
 
 			} else {
 			} else {
@@ -609,6 +597,7 @@ THREE.FBXLoader = ( function () {
 					case 'DiffuseColor':
 					case 'DiffuseColor':
 					case 'Maya|TEX_color_map':
 					case 'Maya|TEX_color_map':
 						parameters.map = self.getTexture( textureMap, child.ID );
 						parameters.map = self.getTexture( textureMap, child.ID );
+						parameters.map.encoding = THREE.sRGBEncoding;
 						break;
 						break;
 
 
 					case 'DisplacementColor':
 					case 'DisplacementColor':
@@ -617,6 +606,7 @@ THREE.FBXLoader = ( function () {
 
 
 					case 'EmissiveColor':
 					case 'EmissiveColor':
 						parameters.emissiveMap = self.getTexture( textureMap, child.ID );
 						parameters.emissiveMap = self.getTexture( textureMap, child.ID );
+						parameters.emissiveMap.encoding = THREE.sRGBEncoding;
 						break;
 						break;
 
 
 					case 'NormalMap':
 					case 'NormalMap':
@@ -627,10 +617,12 @@ THREE.FBXLoader = ( function () {
 					case 'ReflectionColor':
 					case 'ReflectionColor':
 						parameters.envMap = self.getTexture( textureMap, child.ID );
 						parameters.envMap = self.getTexture( textureMap, child.ID );
 						parameters.envMap.mapping = THREE.EquirectangularReflectionMapping;
 						parameters.envMap.mapping = THREE.EquirectangularReflectionMapping;
+						parameters.envMap.encoding = THREE.sRGBEncoding;
 						break;
 						break;
 
 
 					case 'SpecularColor':
 					case 'SpecularColor':
 						parameters.specularMap = self.getTexture( textureMap, child.ID );
 						parameters.specularMap = self.getTexture( textureMap, child.ID );
+						parameters.specularMap.encoding = THREE.sRGBEncoding;
 						break;
 						break;
 
 
 					case 'TransparentColor':
 					case 'TransparentColor':
@@ -1554,6 +1546,7 @@ THREE.FBXLoader = ( function () {
 
 
 		},
 		},
 
 
+
 		// Parse single node mesh geometry in FBXTree.Objects.Geometry
 		// Parse single node mesh geometry in FBXTree.Objects.Geometry
 		parseMeshGeometry: function ( relationships, geoNode, deformers ) {
 		parseMeshGeometry: function ( relationships, geoNode, deformers ) {
 
 
@@ -4133,4 +4126,4 @@ THREE.FBXLoader = ( function () {
 
 
 	return FBXLoader;
 	return FBXLoader;
 
 
-} )();
+} )();

+ 59 - 22
examples/js/loaders/GLTFLoader.js

@@ -1187,6 +1187,13 @@ THREE.GLTFLoader = ( function () {
 
 
 		// Invalid URL
 		// Invalid URL
 		if ( typeof url !== 'string' || url === '' ) return '';
 		if ( typeof url !== 'string' || url === '' ) return '';
+		
+		// Host Relative URL
+		if ( /^https?:\/\//i.test( path ) && /^\//.test( url ) ) {
+
+			path = path.replace( /(^https?:\/\/[^\/]+).*/i , '$1' );
+
+		}
 
 
 		// Absolute URL http://,https://,//
 		// Absolute URL http://,https://,//
 		if ( /^(https?:)?\/\//i.test( url ) ) return url;
 		if ( /^(https?:)?\/\//i.test( url ) ) return url;
@@ -1875,13 +1882,15 @@ THREE.GLTFLoader = ( function () {
 			// The buffer is not interleaved if the stride is the item size in bytes.
 			// The buffer is not interleaved if the stride is the item size in bytes.
 			if ( byteStride && byteStride !== itemBytes ) {
 			if ( byteStride && byteStride !== itemBytes ) {
 
 
-				var ibCacheKey = 'InterleavedBuffer:' + accessorDef.bufferView + ':' + accessorDef.componentType;
+				// Each "slice" of the buffer, as defined by 'count' elements of 'byteStride' bytes, gets its own InterleavedBuffer
+				// This makes sure that IBA.count reflects accessor.count properly
+				var ibSlice = Math.floor( byteOffset / byteStride );
+				var ibCacheKey = 'InterleavedBuffer:' + accessorDef.bufferView + ':' + accessorDef.componentType + ':' + ibSlice + ':' + accessorDef.count;
 				var ib = parser.cache.get( ibCacheKey );
 				var ib = parser.cache.get( ibCacheKey );
 
 
 				if ( ! ib ) {
 				if ( ! ib ) {
 
 
-					// Use the full buffer if it's interleaved.
-					array = new TypedArray( bufferView );
+					array = new TypedArray( bufferView, ibSlice * byteStride, accessorDef.count * byteStride / elementBytes );
 
 
 					// Integer parameters to IB/IBA are in array elements, not bytes.
 					// Integer parameters to IB/IBA are in array elements, not bytes.
 					ib = new THREE.InterleavedBuffer( array, byteStride / elementBytes );
 					ib = new THREE.InterleavedBuffer( array, byteStride / elementBytes );
@@ -1890,7 +1899,7 @@ THREE.GLTFLoader = ( function () {
 
 
 				}
 				}
 
 
-				bufferAttribute = new THREE.InterleavedBufferAttribute( ib, itemSize, byteOffset / elementBytes, normalized );
+				bufferAttribute = new THREE.InterleavedBufferAttribute( ib, itemSize, (byteOffset % byteStride) / elementBytes, normalized );
 
 
 			} else {
 			} else {
 
 
@@ -2912,14 +2921,11 @@ THREE.GLTFLoader = ( function () {
 
 
 		return ( function () {
 		return ( function () {
 
 
-			// .isBone isn't in glTF spec. See .markDefs
-			if ( nodeDef.isBone === true ) {
-
-				return Promise.resolve( new THREE.Bone() );
+			var pending = [];
 
 
-			} else if ( nodeDef.mesh !== undefined ) {
+			if ( nodeDef.mesh !== undefined ) {
 
 
-				return parser.getDependency( 'mesh', nodeDef.mesh ).then( function ( mesh ) {
+				pending.push( parser.getDependency( 'mesh', nodeDef.mesh ).then( function ( mesh ) {
 
 
 					var node;
 					var node;
 
 
@@ -2965,25 +2971,58 @@ THREE.GLTFLoader = ( function () {
 
 
 					return node;
 					return node;
 
 
-				} );
+				} ) );
 
 
-			} else if ( nodeDef.camera !== undefined ) {
+			}
+
+			if ( nodeDef.camera !== undefined ) {
 
 
-				return parser.getDependency( 'camera', nodeDef.camera );
+				pending.push( parser.getDependency( 'camera', nodeDef.camera ) );
 
 
-			} else if ( nodeDef.extensions
+			}
+
+			if ( nodeDef.extensions
 				&& nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ]
 				&& nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ]
 				&& nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].light !== undefined ) {
 				&& nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].light !== undefined ) {
 
 
-				return parser.getDependency( 'light', nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].light );
+				pending.push( parser.getDependency( 'light', nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].light ) );
+
+			}
+
+			return Promise.all( pending );
+
+		}() ).then( function ( objects ) {
+
+			var node;
+
+			// .isBone isn't in glTF spec. See .markDefs
+			if ( nodeDef.isBone === true ) {
+
+				node = new THREE.Bone();
+
+			} else if ( objects.length > 1 ) {
+
+				node = new THREE.Group();
+
+			} else if ( objects.length === 1 ) {
+
+				node = objects[ 0 ];
 
 
 			} else {
 			} else {
 
 
-				return Promise.resolve( new THREE.Object3D() );
+				node = new THREE.Object3D();
 
 
 			}
 			}
 
 
-		}() ).then( function ( node ) {
+			if ( node !== objects[ 0 ] ) {
+
+				for ( var i = 0, il = objects.length; i < il; i ++ ) {
+
+					node.add( objects[ i ] );
+
+				}
+
+			}
 
 
 			if ( nodeDef.name !== undefined ) {
 			if ( nodeDef.name !== undefined ) {
 
 
@@ -3067,11 +3106,9 @@ THREE.GLTFLoader = ( function () {
 
 
 				} ).then( function ( jointNodes ) {
 				} ).then( function ( jointNodes ) {
 
 
-					var meshes = node.isGroup === true ? node.children : [ node ];
-
-					for ( var i = 0, il = meshes.length; i < il; i ++ ) {
+					node.traverse( function ( mesh ) {
 
 
-						var mesh = meshes[ i ];
+						if ( ! mesh.isMesh ) return;
 
 
 						var bones = [];
 						var bones = [];
 						var boneInverses = [];
 						var boneInverses = [];
@@ -3104,7 +3141,7 @@ THREE.GLTFLoader = ( function () {
 
 
 						mesh.bind( new THREE.Skeleton( bones, boneInverses ), mesh.matrixWorld );
 						mesh.bind( new THREE.Skeleton( bones, boneInverses ), mesh.matrixWorld );
 
 
-					}
+					} );
 
 
 					return node;
 					return node;
 
 

+ 1 - 1
examples/js/loaders/OBJLoader.js

@@ -459,7 +459,7 @@ THREE.OBJLoader = ( function () {
 								parseFloat( data[ 2 ] ),
 								parseFloat( data[ 2 ] ),
 								parseFloat( data[ 3 ] )
 								parseFloat( data[ 3 ] )
 							);
 							);
-							if ( data.length === 8 ) {
+							if ( data.length >= 7 ) {
 
 
 								state.colors.push(
 								state.colors.push(
 									parseFloat( data[ 4 ] ),
 									parseFloat( data[ 4 ] ),

+ 10 - 5
examples/js/loaders/TTFLoader.js

@@ -1,6 +1,7 @@
 /**
 /**
  * @author gero3 / https://github.com/gero3
  * @author gero3 / https://github.com/gero3
  * @author tentone / https://github.com/tentone
  * @author tentone / https://github.com/tentone
+ * @author troy351 / https://github.com/troy351
  *
  *
  * Requires opentype.js to be included in the project.
  * Requires opentype.js to be included in the project.
  * Loads TTF files and converts them into typeface JSON that can be used directly
  * Loads TTF files and converts them into typeface JSON that can be used directly
@@ -48,12 +49,16 @@ THREE.TTFLoader.prototype = {
 
 
 			var glyphs = {};
 			var glyphs = {};
 			var scale = ( 100000 ) / ( ( font.unitsPerEm || 2048 ) * 72 );
 			var scale = ( 100000 ) / ( ( font.unitsPerEm || 2048 ) * 72 );
+			
+			var glyphIndexMap = font.encoding.cmap.glyphIndexMap;
+			var unicodes = Object.keys( glyphIndexMap );
 
 
-			for ( var i = 0; i < font.glyphs.length; i ++ ) {
+			for ( var i = 0; i < unicodes.length; i ++ ) {
 
 
-				var glyph = font.glyphs.glyphs[ i ];
+				var unicode = unicodes[ i ];
+				var glyph = font.glyphs.glyphs[ glyphIndexMap[ unicode ] ];
 
 
-				if ( glyph.unicode !== undefined ) {
+				if ( unicode !== undefined ) {
 
 
 					var token = {
 					var token = {
 						ha: round( glyph.advanceWidth * scale ),
 						ha: round( glyph.advanceWidth * scale ),
@@ -98,7 +103,7 @@ THREE.TTFLoader.prototype = {
 
 
 					} );
 					} );
 
 
-					glyphs[ String.fromCharCode( glyph.unicode ) ] = token;
+					glyphs[ String.fromCodePoint( glyph.unicode ) ] = token;
 
 
 				}
 				}
 
 
@@ -106,7 +111,7 @@ THREE.TTFLoader.prototype = {
 
 
 			return {
 			return {
 				glyphs: glyphs,
 				glyphs: glyphs,
-				familyName: font.familyName,
+				familyName: font.getEnglishName( 'fullName' ),
 				ascender: round( font.ascender * scale ),
 				ascender: round( font.ascender * scale ),
 				descender: round( font.descender * scale ),
 				descender: round( font.descender * scale ),
 				underlinePosition: font.tables.post.underlinePosition,
 				underlinePosition: font.tables.post.underlinePosition,

+ 1 - 0
examples/js/misc/VolumeSlice.js

@@ -62,6 +62,7 @@ THREE.VolumeSlice = function ( volume, index, axis ) {
 	 * @member {THREE.Mesh} mesh The mesh ready to get used in the scene
 	 * @member {THREE.Mesh} mesh The mesh ready to get used in the scene
 	 */
 	 */
 	this.mesh = new THREE.Mesh( this.geometry, material );
 	this.mesh = new THREE.Mesh( this.geometry, material );
+	this.mesh.matrixAutoUpdate = false;
 	/**
 	/**
 	 * @member {Boolean} geometryNeedsUpdate If set to true, updateGeometry will be triggered at the next repaint
 	 * @member {Boolean} geometryNeedsUpdate If set to true, updateGeometry will be triggered at the next repaint
 	 */
 	 */

+ 3 - 1
examples/jsm/controls/OrbitControls.d.ts

@@ -142,7 +142,9 @@ export class MapControls {
 
 
 	dollyOut(dollyScale: number): void;
 	dollyOut(dollyScale: number): void;
 
 
-	update(): void;
+	update(): boolean;
+
+	saveState(): void;
 
 
 	reset(): void;
 	reset(): void;
 
 

+ 14 - 22
examples/jsm/loaders/FBXLoader.js

@@ -61,10 +61,10 @@ import {
 	Vector3,
 	Vector3,
 	Vector4,
 	Vector4,
 	VectorKeyframeTrack,
 	VectorKeyframeTrack,
-	VertexColors
+	VertexColors,
+	sRGBEncoding
 } from "../../../build/three.module.js";
 } from "../../../build/three.module.js";
 import { Zlib } from "../libs/inflate.module.min.js";
 import { Zlib } from "../libs/inflate.module.min.js";
-import { TGALoader } from "../loaders/TGALoader.js";
 import { NURBSCurve } from "../curves/NURBSCurve.js";
 import { NURBSCurve } from "../curves/NURBSCurve.js";
 
 
 
 
@@ -337,27 +337,15 @@ var FBXLoader = ( function () {
 
 
 				case 'tga':
 				case 'tga':
 
 
-					if ( typeof TGALoader !== 'function' ) {
+					if ( Loader.Handlers.get( '.tga' ) === null ) {
 
 
-						console.warn( 'FBXLoader: TGALoader is required to load TGA textures' );
-						return;
-
-					} else {
-
-						if ( Loader.Handlers.get( '.tga' ) === null ) {
-
-							var tgaLoader = new TGALoader();
-							tgaLoader.setPath( this.textureLoader.path );
-
-							Loader.Handlers.add( /\.tga$/i, tgaLoader );
-
-						}
-
-						type = 'image/tga';
-						break;
+						console.warn( 'FBXLoader: TGA loader not found, skipping ', fileName );
 
 
 					}
 					}
 
 
+					type = 'image/tga';
+					break;
+
 				default:
 				default:
 
 
 					console.warn( 'FBXLoader: Image type "' + extension + '" is not supported.' );
 					console.warn( 'FBXLoader: Image type "' + extension + '" is not supported.' );
@@ -466,7 +454,7 @@ var FBXLoader = ( function () {
 
 
 				if ( loader === null ) {
 				if ( loader === null ) {
 
 
-					console.warn( 'FBXLoader: TGALoader not found, creating empty placeholder texture for', fileName );
+					console.warn( 'FBXLoader: TGA loader not found, creating placeholder texture for', textureNode.RelativeFilename );
 					texture = new Texture();
 					texture = new Texture();
 
 
 				} else {
 				} else {
@@ -477,7 +465,7 @@ var FBXLoader = ( function () {
 
 
 			} else if ( extension === 'psd' ) {
 			} else if ( extension === 'psd' ) {
 
 
-				console.warn( 'FBXLoader: PSD textures are not supported, creating empty placeholder texture for', fileName );
+				console.warn( 'FBXLoader: PSD textures are not supported, creating placeholder texture for', textureNode.RelativeFilename );
 				texture = new Texture();
 				texture = new Texture();
 
 
 			} else {
 			} else {
@@ -658,6 +646,7 @@ var FBXLoader = ( function () {
 					case 'DiffuseColor':
 					case 'DiffuseColor':
 					case 'Maya|TEX_color_map':
 					case 'Maya|TEX_color_map':
 						parameters.map = self.getTexture( textureMap, child.ID );
 						parameters.map = self.getTexture( textureMap, child.ID );
+						parameters.map.encoding = sRGBEncoding;
 						break;
 						break;
 
 
 					case 'DisplacementColor':
 					case 'DisplacementColor':
@@ -666,6 +655,7 @@ var FBXLoader = ( function () {
 
 
 					case 'EmissiveColor':
 					case 'EmissiveColor':
 						parameters.emissiveMap = self.getTexture( textureMap, child.ID );
 						parameters.emissiveMap = self.getTexture( textureMap, child.ID );
+						parameters.emissiveMap.encoding = sRGBEncoding;
 						break;
 						break;
 
 
 					case 'NormalMap':
 					case 'NormalMap':
@@ -676,10 +666,12 @@ var FBXLoader = ( function () {
 					case 'ReflectionColor':
 					case 'ReflectionColor':
 						parameters.envMap = self.getTexture( textureMap, child.ID );
 						parameters.envMap = self.getTexture( textureMap, child.ID );
 						parameters.envMap.mapping = EquirectangularReflectionMapping;
 						parameters.envMap.mapping = EquirectangularReflectionMapping;
+						parameters.envMap.encoding = sRGBEncoding;
 						break;
 						break;
 
 
 					case 'SpecularColor':
 					case 'SpecularColor':
 						parameters.specularMap = self.getTexture( textureMap, child.ID );
 						parameters.specularMap = self.getTexture( textureMap, child.ID );
+						parameters.specularMap.encoding = sRGBEncoding;
 						break;
 						break;
 
 
 					case 'TransparentColor':
 					case 'TransparentColor':
@@ -1603,6 +1595,7 @@ var FBXLoader = ( function () {
 
 
 		},
 		},
 
 
+
 		// Parse single node mesh geometry in FBXTree.Objects.Geometry
 		// Parse single node mesh geometry in FBXTree.Objects.Geometry
 		parseMeshGeometry: function ( relationships, geoNode, deformers ) {
 		parseMeshGeometry: function ( relationships, geoNode, deformers ) {
 
 
@@ -4183,5 +4176,4 @@ var FBXLoader = ( function () {
 	return FBXLoader;
 	return FBXLoader;
 
 
 } )();
 } )();
-
 export { FBXLoader };
 export { FBXLoader };

+ 59 - 22
examples/jsm/loaders/GLTFLoader.js

@@ -1252,6 +1252,13 @@ var GLTFLoader = ( function () {
 
 
 		// Invalid URL
 		// Invalid URL
 		if ( typeof url !== 'string' || url === '' ) return '';
 		if ( typeof url !== 'string' || url === '' ) return '';
+		
+		// Host Relative URL
+		if ( /^https?:\/\//i.test( path ) && /^\//.test( url ) ) {
+
+			path = path.replace( /(^https?:\/\/[^\/]+).*/i , '$1' );
+
+		}
 
 
 		// Absolute URL http://,https://,//
 		// Absolute URL http://,https://,//
 		if ( /^(https?:)?\/\//i.test( url ) ) return url;
 		if ( /^(https?:)?\/\//i.test( url ) ) return url;
@@ -1940,13 +1947,15 @@ var GLTFLoader = ( function () {
 			// The buffer is not interleaved if the stride is the item size in bytes.
 			// The buffer is not interleaved if the stride is the item size in bytes.
 			if ( byteStride && byteStride !== itemBytes ) {
 			if ( byteStride && byteStride !== itemBytes ) {
 
 
-				var ibCacheKey = 'InterleavedBuffer:' + accessorDef.bufferView + ':' + accessorDef.componentType;
+				// Each "slice" of the buffer, as defined by 'count' elements of 'byteStride' bytes, gets its own InterleavedBuffer
+				// This makes sure that IBA.count reflects accessor.count properly
+				var ibSlice = Math.floor( byteOffset / byteStride );
+				var ibCacheKey = 'InterleavedBuffer:' + accessorDef.bufferView + ':' + accessorDef.componentType + ':' + ibSlice + ':' + accessorDef.count;
 				var ib = parser.cache.get( ibCacheKey );
 				var ib = parser.cache.get( ibCacheKey );
 
 
 				if ( ! ib ) {
 				if ( ! ib ) {
 
 
-					// Use the full buffer if it's interleaved.
-					array = new TypedArray( bufferView );
+					array = new TypedArray( bufferView, ibSlice * byteStride, accessorDef.count * byteStride / elementBytes );
 
 
 					// Integer parameters to IB/IBA are in array elements, not bytes.
 					// Integer parameters to IB/IBA are in array elements, not bytes.
 					ib = new InterleavedBuffer( array, byteStride / elementBytes );
 					ib = new InterleavedBuffer( array, byteStride / elementBytes );
@@ -1955,7 +1964,7 @@ var GLTFLoader = ( function () {
 
 
 				}
 				}
 
 
-				bufferAttribute = new InterleavedBufferAttribute( ib, itemSize, byteOffset / elementBytes, normalized );
+				bufferAttribute = new InterleavedBufferAttribute( ib, itemSize, (byteOffset % byteStride) / elementBytes, normalized );
 
 
 			} else {
 			} else {
 
 
@@ -2977,14 +2986,11 @@ var GLTFLoader = ( function () {
 
 
 		return ( function () {
 		return ( function () {
 
 
-			// .isBone isn't in glTF spec. See .markDefs
-			if ( nodeDef.isBone === true ) {
-
-				return Promise.resolve( new Bone() );
+			var pending = [];
 
 
-			} else if ( nodeDef.mesh !== undefined ) {
+			if ( nodeDef.mesh !== undefined ) {
 
 
-				return parser.getDependency( 'mesh', nodeDef.mesh ).then( function ( mesh ) {
+				pending.push( parser.getDependency( 'mesh', nodeDef.mesh ).then( function ( mesh ) {
 
 
 					var node;
 					var node;
 
 
@@ -3030,25 +3036,58 @@ var GLTFLoader = ( function () {
 
 
 					return node;
 					return node;
 
 
-				} );
+				} ) );
 
 
-			} else if ( nodeDef.camera !== undefined ) {
+			}
+
+			if ( nodeDef.camera !== undefined ) {
 
 
-				return parser.getDependency( 'camera', nodeDef.camera );
+				pending.push( parser.getDependency( 'camera', nodeDef.camera ) );
 
 
-			} else if ( nodeDef.extensions
+			}
+
+			if ( nodeDef.extensions
 				&& nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ]
 				&& nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ]
 				&& nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].light !== undefined ) {
 				&& nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].light !== undefined ) {
 
 
-				return parser.getDependency( 'light', nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].light );
+				pending.push( parser.getDependency( 'light', nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].light ) );
+
+			}
+
+			return Promise.all( pending );
+
+		}() ).then( function ( objects ) {
+
+			var node;
+
+			// .isBone isn't in glTF spec. See .markDefs
+			if ( nodeDef.isBone === true ) {
+
+				node = new Bone();
+
+			} else if ( objects.length > 1 ) {
+
+				node = new Group();
+
+			} else if ( objects.length === 1 ) {
+
+				node = objects[ 0 ];
 
 
 			} else {
 			} else {
 
 
-				return Promise.resolve( new Object3D() );
+				node = new Object3D();
 
 
 			}
 			}
 
 
-		}() ).then( function ( node ) {
+			if ( node !== objects[ 0 ] ) {
+
+				for ( var i = 0, il = objects.length; i < il; i ++ ) {
+
+					node.add( objects[ i ] );
+
+				}
+
+			}
 
 
 			if ( nodeDef.name !== undefined ) {
 			if ( nodeDef.name !== undefined ) {
 
 
@@ -3132,11 +3171,9 @@ var GLTFLoader = ( function () {
 
 
 				} ).then( function ( jointNodes ) {
 				} ).then( function ( jointNodes ) {
 
 
-					var meshes = node.isGroup === true ? node.children : [ node ];
-
-					for ( var i = 0, il = meshes.length; i < il; i ++ ) {
+					node.traverse( function ( mesh ) {
 
 
-						var mesh = meshes[ i ];
+						if ( ! mesh.isMesh ) return;
 
 
 						var bones = [];
 						var bones = [];
 						var boneInverses = [];
 						var boneInverses = [];
@@ -3169,7 +3206,7 @@ var GLTFLoader = ( function () {
 
 
 						mesh.bind( new Skeleton( bones, boneInverses ), mesh.matrixWorld );
 						mesh.bind( new Skeleton( bones, boneInverses ), mesh.matrixWorld );
 
 
-					}
+					} );
 
 
 					return node;
 					return node;
 
 

+ 1 - 1
examples/jsm/loaders/OBJLoader.js

@@ -476,7 +476,7 @@ var OBJLoader = ( function () {
 								parseFloat( data[ 2 ] ),
 								parseFloat( data[ 2 ] ),
 								parseFloat( data[ 3 ] )
 								parseFloat( data[ 3 ] )
 							);
 							);
-							if ( data.length === 8 ) {
+							if ( data.length >= 7 ) {
 
 
 								state.colors.push(
 								state.colors.push(
 									parseFloat( data[ 4 ] ),
 									parseFloat( data[ 4 ] ),

+ 10 - 5
examples/jsm/loaders/TTFLoader.js

@@ -1,6 +1,7 @@
 /**
 /**
  * @author gero3 / https://github.com/gero3
  * @author gero3 / https://github.com/gero3
  * @author tentone / https://github.com/tentone
  * @author tentone / https://github.com/tentone
+ * @author troy351 / https://github.com/troy351
  *
  *
  * Requires opentype.js to be included in the project.
  * Requires opentype.js to be included in the project.
  * Loads TTF files and converts them into typeface JSON that can be used directly
  * Loads TTF files and converts them into typeface JSON that can be used directly
@@ -53,12 +54,16 @@ TTFLoader.prototype = {
 
 
 			var glyphs = {};
 			var glyphs = {};
 			var scale = ( 100000 ) / ( ( font.unitsPerEm || 2048 ) * 72 );
 			var scale = ( 100000 ) / ( ( font.unitsPerEm || 2048 ) * 72 );
+			
+			var glyphIndexMap = font.encoding.cmap.glyphIndexMap;
+			var unicodes = Object.keys( glyphIndexMap );
 
 
-			for ( var i = 0; i < font.glyphs.length; i ++ ) {
+			for ( var i = 0; i < unicodes.length; i ++ ) {
 
 
-				var glyph = font.glyphs.glyphs[ i ];
+				var unicode = unicodes[ i ];
+				var glyph = font.glyphs.glyphs[ glyphIndexMap[ unicode ] ];
 
 
-				if ( glyph.unicode !== undefined ) {
+				if ( unicode !== undefined ) {
 
 
 					var token = {
 					var token = {
 						ha: round( glyph.advanceWidth * scale ),
 						ha: round( glyph.advanceWidth * scale ),
@@ -103,7 +108,7 @@ TTFLoader.prototype = {
 
 
 					} );
 					} );
 
 
-					glyphs[ String.fromCharCode( glyph.unicode ) ] = token;
+					glyphs[ String.fromCodePoint( glyph.unicode ) ] = token;
 
 
 				}
 				}
 
 
@@ -111,7 +116,7 @@ TTFLoader.prototype = {
 
 
 			return {
 			return {
 				glyphs: glyphs,
 				glyphs: glyphs,
-				familyName: font.familyName,
+				familyName: font.getEnglishName( 'fullName' ),
 				ascender: round( font.ascender * scale ),
 				ascender: round( font.ascender * scale ),
 				descender: round( font.descender * scale ),
 				descender: round( font.descender * scale ),
 				underlinePosition: font.tables.post.underlinePosition,
 				underlinePosition: font.tables.post.underlinePosition,

+ 1 - 0
examples/jsm/misc/VolumeSlice.js

@@ -72,6 +72,7 @@ var VolumeSlice = function ( volume, index, axis ) {
 	 * @member {Mesh} mesh The mesh ready to get used in the scene
 	 * @member {Mesh} mesh The mesh ready to get used in the scene
 	 */
 	 */
 	this.mesh = new Mesh( this.geometry, material );
 	this.mesh = new Mesh( this.geometry, material );
+	this.mesh.matrixAutoUpdate = false;
 	/**
 	/**
 	 * @member {Boolean} geometryNeedsUpdate If set to true, updateGeometry will be triggered at the next repaint
 	 * @member {Boolean} geometryNeedsUpdate If set to true, updateGeometry will be triggered at the next repaint
 	 */
 	 */

+ 0 - 1
examples/jsm/nodes/accessors/NormalNode.d.ts

@@ -12,5 +12,4 @@ export class NormalNode extends TempNode {
 
 
   static LOCAL: string;
   static LOCAL: string;
   static WORLD: string;
   static WORLD: string;
-  static VIEW: string;
 }
 }

+ 5 - 29
examples/jsm/nodes/accessors/NormalNode.js

@@ -15,23 +15,16 @@ function NormalNode( scope ) {
 
 
 NormalNode.LOCAL = 'local';
 NormalNode.LOCAL = 'local';
 NormalNode.WORLD = 'world';
 NormalNode.WORLD = 'world';
-NormalNode.VIEW = 'view';
 
 
 NormalNode.prototype = Object.create( TempNode.prototype );
 NormalNode.prototype = Object.create( TempNode.prototype );
 NormalNode.prototype.constructor = NormalNode;
 NormalNode.prototype.constructor = NormalNode;
 NormalNode.prototype.nodeType = "Normal";
 NormalNode.prototype.nodeType = "Normal";
 
 
-NormalNode.prototype.getShared = function ( /* builder */ ) {
+NormalNode.prototype.getShared = function () {
 
 
-	switch ( this.scope ) {
-
-		case NormalNode.WORLD:
-
-			return true;
+	// if shared is false, TempNode will not create temp variable (for optimization)
 
 
-	}
-
-	return false;
+	return this.scope === NormalNode.WORLD;
 
 
 };
 };
 
 
@@ -43,9 +36,6 @@ NormalNode.prototype.generate = function ( builder, output ) {
 
 
 		case NormalNode.LOCAL:
 		case NormalNode.LOCAL:
 
 
-			// to use vObjectNormal as vertex normal
-			//builder.requires.normal = true;
-
 			result = 'normal';
 			result = 'normal';
 
 
 			break;
 			break;
@@ -54,24 +44,16 @@ NormalNode.prototype.generate = function ( builder, output ) {
 
 
 			if ( builder.isShader( 'vertex' ) ) {
 			if ( builder.isShader( 'vertex' ) ) {
 
 
-				return '( modelMatrix * vec4( objectNormal, 0.0 ) ).xyz';
+				result = '( modelMatrix * vec4( objectNormal, 0.0 ) ).xyz';
 
 
 			} else {
 			} else {
 
 
-				builder.requires.worldNormal = true;
-
-				result = 'vWNormal';
+				result = 'inverseTransformDirection( normal, viewMatrix )';
 
 
 			}
 			}
 
 
 			break;
 			break;
 
 
-		case NormalNode.VIEW:
-
-			result = 'vNormal';
-
-			break;
-
 	}
 	}
 
 
 	return builder.format( result, this.getType( builder ), output );
 	return builder.format( result, this.getType( builder ), output );
@@ -116,10 +98,4 @@ NodeLib.addKeyword( 'worldNormal', function () {
 
 
 } );
 } );
 
 
-NodeLib.addKeyword( 'viewNormal', function () {
-
-	return new NormalNode( NormalNode.VIEW );
-
-} );
-
 export { NormalNode };
 export { NormalNode };

+ 1 - 1
examples/jsm/nodes/accessors/PositionNode.js

@@ -148,7 +148,7 @@ NodeLib.addKeyword( 'worldPosition', function () {
 
 
 NodeLib.addKeyword( 'viewPosition', function () {
 NodeLib.addKeyword( 'viewPosition', function () {
 
 
-	return new PositionNode( NormalNode.VIEW );
+	return new PositionNode( PositionNode.VIEW );
 
 
 } );
 } );
 
 

+ 1 - 1
examples/jsm/nodes/inputs/CubeTextureNode.js

@@ -61,7 +61,7 @@ CubeTextureNode.prototype.generate = function ( builder, output ) {
 	builder.addContext( context );
 	builder.addContext( context );
 
 
 	this.colorSpace = this.colorSpace || new ColorSpaceNode( new ExpressionNode( '', outputType ) );
 	this.colorSpace = this.colorSpace || new ColorSpaceNode( new ExpressionNode( '', outputType ) );
-	this.colorSpace.fromEncoding( builder.getTextureEncodingFromMap( this.value ) );
+	this.colorSpace.fromDecoding( builder.getTextureEncodingFromMap( this.value ) );
 	this.colorSpace.input.parse( code );
 	this.colorSpace.input.parse( code );
 
 
 	code = this.colorSpace.build( builder, outputType );
 	code = this.colorSpace.build( builder, outputType );

+ 1 - 1
examples/jsm/nodes/inputs/TextureNode.js

@@ -65,7 +65,7 @@ TextureNode.prototype.generate = function ( builder, output ) {
 	builder.addContext( context );
 	builder.addContext( context );
 
 
 	this.colorSpace = this.colorSpace || new ColorSpaceNode( new ExpressionNode( '', outputType ) );
 	this.colorSpace = this.colorSpace || new ColorSpaceNode( new ExpressionNode( '', outputType ) );
-	this.colorSpace.fromEncoding( builder.getTextureEncodingFromMap( this.value ) );
+	this.colorSpace.fromDecoding( builder.getTextureEncodingFromMap( this.value ) );
 	this.colorSpace.input.parse( code );
 	this.colorSpace.input.parse( code );
 
 
 	code = this.colorSpace.build( builder, outputType );
 	code = this.colorSpace.build( builder, outputType );

+ 2 - 2
examples/webgl_buffergeometry_drawcalls.html → examples/webgl_buffergeometry_drawrange.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <!DOCTYPE html>
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
-		<title>three.js webgl - buffergeometry - lines drawcalls</title>
+		<title>three.js webgl - buffergeometry - lines drawrange</title>
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<link type="text/css" rel="stylesheet" href="main.css">
 		<link type="text/css" rel="stylesheet" href="main.css">
@@ -15,7 +15,7 @@
 
 
 		<div id="container"></div>
 		<div id="container"></div>
 		<div id="info">
 		<div id="info">
-			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - buffergeometry drawcalls<br/>
+			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - buffergeometry drawrange<br/>
 			by <a href="https://twitter.com/fernandojsg">fernandojsg</a>
 			by <a href="https://twitter.com/fernandojsg">fernandojsg</a>
 		</div>
 		</div>
 
 

+ 106 - 136
examples/webgl_buffergeometry_instancing_lambert.html

@@ -34,147 +34,120 @@
 		import { OrbitControls } from './jsm/controls/OrbitControls.js';
 		import { OrbitControls } from './jsm/controls/OrbitControls.js';
 		import { Curves } from './jsm/curves/CurveExtras.js';
 		import { Curves } from './jsm/curves/CurveExtras.js';
 
 
-		THREE.ShaderLib.customDepthRGBA = { // this is a cut-and-paste of the depth shader -- modified to accommodate instancing for this app
+		// this is a cut-and-paste of the depth shader -- modified to accommodate instancing for this app
+		var customDepthVertexShader = 
+			`
+			// instanced
+			attribute vec3 instanceOffset;
+			attribute float instanceScale;
 
 
-			uniforms: THREE.ShaderLib.depth.uniforms,
+			#include <common>
+			#include <uv_pars_vertex>
+			#include <displacementmap_pars_vertex>
+			#include <morphtarget_pars_vertex>
+			#include <skinning_pars_vertex>
+			#include <logdepthbuf_pars_vertex>
+			#include <clipping_planes_pars_vertex>
 
 
-			vertexShader:
-				`
-				// instanced
-				#ifdef INSTANCED
-
-					attribute vec3 instanceOffset;
-					attribute float instanceScale;
-
-				#endif
-
-				#include <common>
-				#include <uv_pars_vertex>
-				#include <displacementmap_pars_vertex>
-				#include <morphtarget_pars_vertex>
-				#include <skinning_pars_vertex>
-				#include <logdepthbuf_pars_vertex>
-				#include <clipping_planes_pars_vertex>
-
-				void main() {
-
-					#include <uv_vertex>
-
-					#include <skinbase_vertex>
-
-					#ifdef USE_DISPLACEMENTMAP
-
-						#include <beginnormal_vertex>
-						#include <morphnormal_vertex>
-						#include <skinnormal_vertex>
-
-					#endif
-
-					#include <begin_vertex>
-
-					// instanced
-					#ifdef INSTANCED
-
-						transformed *= instanceScale;
-						transformed = transformed + instanceOffset;
-
-					#endif
-
-					#include <morphtarget_vertex>
-					#include <skinning_vertex>
-					#include <displacementmap_vertex>
-					#include <project_vertex>
-					#include <logdepthbuf_vertex>
-					#include <clipping_planes_vertex>
-
-				}
-			`,
+			void main() {
 
 
-			fragmentShader: THREE.ShaderChunk.depth_frag
+				#include <uv_vertex>
 
 
-		};
+				#include <skinbase_vertex>
 
 
-		THREE.ShaderLib.lambert = { // this is a cut-and-paste of the lambert shader -- modified to accommodate instancing for this app
+				#ifdef USE_DISPLACEMENTMAP
 
 
-			uniforms: THREE.ShaderLib.lambert.uniforms,
-
-			vertexShader:
-				`
-				#define LAMBERT
+					#include <beginnormal_vertex>
+					#include <morphnormal_vertex>
+					#include <skinnormal_vertex>
 
 
-				#ifdef INSTANCED
-					attribute vec3 instanceOffset;
-					attribute vec3 instanceColor;
-					attribute float instanceScale;
 				#endif
 				#endif
 
 
-				varying vec3 vLightFront;
-				varying vec3 vIndirectFront;
+				#include <begin_vertex>
 
 
-				#ifdef DOUBLE_SIDED
-					varying vec3 vLightBack;
-					varying vec3 vIndirectBack;
-				#endif
-
-				#include <common>
-				#include <uv_pars_vertex>
-				#include <uv2_pars_vertex>
-				#include <envmap_pars_vertex>
-				#include <bsdfs>
-				#include <lights_pars_begin>
-				#include <color_pars_vertex>
-				#include <fog_pars_vertex>
-				#include <morphtarget_pars_vertex>
-				#include <skinning_pars_vertex>
-				#include <shadowmap_pars_vertex>
-				#include <logdepthbuf_pars_vertex>
-				#include <clipping_planes_pars_vertex>
-
-				void main() {
-
-					#include <uv_vertex>
-					#include <uv2_vertex>
-					#include <color_vertex>
-
-					// vertex colors instanced
-					#ifdef INSTANCED
-						#ifdef USE_COLOR
-							vColor.xyz = instanceColor.xyz;
-						#endif
-					#endif
+				// instanced
+				transformed *= instanceScale;
+				transformed = transformed + instanceOffset;
 
 
-					#include <beginnormal_vertex>
-					#include <morphnormal_vertex>
-					#include <skinbase_vertex>
-					#include <skinnormal_vertex>
-					#include <defaultnormal_vertex>
+				#include <morphtarget_vertex>
+				#include <skinning_vertex>
+				#include <displacementmap_vertex>
+				#include <project_vertex>
+				#include <logdepthbuf_vertex>
+				#include <clipping_planes_vertex>
 
 
-					#include <begin_vertex>
+			}
+			`;
+
+		// this is a cut-and-paste of the lambert shader -- modified to accommodate instancing for this app
+		var customLambertVertexShader =
+			`
+			#define LAMBERT
+
+			// instanced
+			attribute vec3 instanceOffset;
+			attribute vec3 instanceColor;
+			attribute float instanceScale;
+
+			varying vec3 vLightFront;
+			varying vec3 vIndirectFront;
+
+			#ifdef DOUBLE_SIDED
+				varying vec3 vLightBack;
+				varying vec3 vIndirectBack;
+			#endif
+
+			#include <common>
+			#include <uv_pars_vertex>
+			#include <uv2_pars_vertex>
+			#include <envmap_pars_vertex>
+			#include <bsdfs>
+			#include <lights_pars_begin>
+			#include <color_pars_vertex>
+			#include <fog_pars_vertex>
+			#include <morphtarget_pars_vertex>
+			#include <skinning_pars_vertex>
+			#include <shadowmap_pars_vertex>
+			#include <logdepthbuf_pars_vertex>
+			#include <clipping_planes_pars_vertex>
+
+			void main() {
+
+				#include <uv_vertex>
+				#include <uv2_vertex>
+				#include <color_vertex>
+
+				// vertex colors instanced
+				#ifdef USE_COLOR
+					vColor.xyz = instanceColor.xyz;
+				#endif
 
 
-					// position instanced
-					#ifdef INSTANCED
-						transformed *= instanceScale;
-						transformed = transformed + instanceOffset;
-					#endif
+				#include <beginnormal_vertex>
+				#include <morphnormal_vertex>
+				#include <skinbase_vertex>
+				#include <skinnormal_vertex>
+				#include <defaultnormal_vertex>
 
 
-					#include <morphtarget_vertex>
-					#include <skinning_vertex>
-					#include <project_vertex>
-					#include <logdepthbuf_vertex>
-					#include <clipping_planes_vertex>
+				#include <begin_vertex>
 
 
-					#include <worldpos_vertex>
-					#include <envmap_vertex>
-					#include <lights_lambert_vertex>
-					#include <shadowmap_vertex>
-					#include <fog_vertex>
+				// position instanced
+				transformed *= instanceScale;
+				transformed = transformed + instanceOffset;
 
 
-				}
-				`,
+				#include <morphtarget_vertex>
+				#include <skinning_vertex>
+				#include <project_vertex>
+				#include <logdepthbuf_vertex>
+				#include <clipping_planes_vertex>
 
 
-			fragmentShader: THREE.ShaderLib.lambert.fragmentShader
+				#include <worldpos_vertex>
+				#include <envmap_vertex>
+				#include <lights_lambert_vertex>
+				#include <shadowmap_vertex>
+				#include <fog_vertex>
 
 
-		};
+			}
+			`;
 
 
 
 
 		//
 		//
@@ -292,27 +265,24 @@
 
 
 			} );
 			} );
 
 
-			material.defines = material.defines || {};
-			material.defines[ 'INSTANCED' ] = "";
+			material.onBeforeCompile = function( shader ) {
+
+				shader.vertexShader = customLambertVertexShader;
+
+			};
 
 
 
 
 			// custom depth material - required for instanced shadows
 			// custom depth material - required for instanced shadows
 
 
-			var shader = THREE.ShaderLib[ 'customDepthRGBA' ];
+			var customDepthMaterial = new THREE.MeshDepthMaterial();
 
 
-			var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
+			customDepthMaterial.onBeforeCompile = function( shader ) {
 
 
-			var customDepthMaterial = new THREE.ShaderMaterial( {
+				shader.vertexShader = customDepthVertexShader;
 
 
-				defines: {
-					'INSTANCED': "",
-					'DEPTH_PACKING': THREE.RGBADepthPacking
-				},
-				uniforms: uniforms,
-				vertexShader: shader.vertexShader,
-				fragmentShader: shader.fragmentShader
+			};
 
 
-			} );
+			customDepthMaterial.depthPacking = THREE.RGBADepthPacking;
 
 
 			//
 			//
 
 

+ 5 - 3
examples/webgl_buffergeometry_rawshader.html

@@ -81,20 +81,22 @@
 				scene.background = new THREE.Color( 0x101010 );
 				scene.background = new THREE.Color( 0x101010 );
 
 
 				// geometry
 				// geometry
-
-				var triangles = 500;
+				// nr of triangles with 3 vertices per triangle
+				var vertexCount = 200 * 3;
 
 
 				var geometry = new THREE.BufferGeometry();
 				var geometry = new THREE.BufferGeometry();
 
 
 				var positions = [];
 				var positions = [];
 				var colors = [];
 				var colors = [];
 
 
-				for ( var i = 0; i < triangles; i ++ ) {
+				for ( var i = 0; i < vertexCount; i ++ ) {
 
 
+					// adding x,y,z
 					positions.push( Math.random() - 0.5 );
 					positions.push( Math.random() - 0.5 );
 					positions.push( Math.random() - 0.5 );
 					positions.push( Math.random() - 0.5 );
 					positions.push( Math.random() - 0.5 );
 					positions.push( Math.random() - 0.5 );
 
 
+					// adding r,g,b,a
 					colors.push( Math.random() * 255 );
 					colors.push( Math.random() * 255 );
 					colors.push( Math.random() * 255 );
 					colors.push( Math.random() * 255 );
 					colors.push( Math.random() * 255 );
 					colors.push( Math.random() * 255 );

+ 1 - 1
examples/webgl_geometry_extrude_splines.html

@@ -323,7 +323,7 @@
 
 
 				if ( ! params.lookAhead ) lookAt.copy( pos ).add( dir );
 				if ( ! params.lookAhead ) lookAt.copy( pos ).add( dir );
 				splineCamera.matrix.lookAt( splineCamera.position, lookAt, normal );
 				splineCamera.matrix.lookAt( splineCamera.position, lookAt, normal );
-				splineCamera.rotation.setFromRotationMatrix( splineCamera.matrix, splineCamera.rotation.order );
+				splineCamera.quaternion.setFromRotationMatrix( splineCamera.matrix );
 
 
 				cameraHelper.update();
 				cameraHelper.update();
 
 

+ 1 - 2
examples/webgl_materials_nodes.html

@@ -2280,8 +2280,7 @@
 
 
 						addGui( 'scope', {
 						addGui( 'scope', {
 							local: Nodes.NormalNode.LOCAL,
 							local: Nodes.NormalNode.LOCAL,
-							world: Nodes.NormalNode.WORLD,
-							view: Nodes.NormalNode.VIEW
+							world: Nodes.NormalNode.WORLD
 						}, function ( val ) {
 						}, function ( val ) {
 
 
 							node.scope = val;
 							node.scope = val;

+ 4 - 4
examples/webgl_math_orientation_transform.html

@@ -21,7 +21,7 @@
 
 
 			var spherical = new THREE.Spherical();
 			var spherical = new THREE.Spherical();
 			var rotationMatrix = new THREE.Matrix4();
 			var rotationMatrix = new THREE.Matrix4();
-			var targetRotation = new THREE.Quaternion();
+			var targetQuaternion = new THREE.Quaternion();
 			var clock = new THREE.Clock();
 			var clock = new THREE.Clock();
 			var speed = 2;
 			var speed = 2;
 
 
@@ -88,10 +88,10 @@
 
 
 				var delta = clock.getDelta();
 				var delta = clock.getDelta();
 
 
-				if ( ! mesh.quaternion.equals( targetRotation ) ) {
+				if ( ! mesh.quaternion.equals( targetQuaternion ) ) {
 
 
 					var step = speed * delta;
 					var step = speed * delta;
-					mesh.quaternion.rotateTowards( targetRotation, step );
+					mesh.quaternion.rotateTowards( targetQuaternion, step );
 
 
 				}
 				}
 
 
@@ -112,7 +112,7 @@
 				// compute target rotation
 				// compute target rotation
 
 
 				rotationMatrix.lookAt( target.position, mesh.position, mesh.up );
 				rotationMatrix.lookAt( target.position, mesh.position, mesh.up );
-				targetRotation.setFromRotationMatrix( rotationMatrix );
+				targetQuaternion.setFromRotationMatrix( rotationMatrix );
 
 
 				setTimeout( generateTarget, 2000 );
 				setTimeout( generateTarget, 2000 );
 
 

+ 2 - 0
examples/webvr_ballshooter.html

@@ -5,6 +5,8 @@
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<link type="text/css" rel="stylesheet" href="main.css">
 		<link type="text/css" rel="stylesheet" href="main.css">
+		<!-- WebXR Device API (For Chrome M76+), expires 09/09/2019 -->
+		<meta http-equiv="origin-trial" content="Ai1/G787sugfmWtk1xQExa8N6OqwDsJyNn+OwpA1J4PozR1lixRYIQ4Tmp00vrGWS8FQQ2iDyqjwaewrOfYvPAUAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU03NiIsImV4cGlyeSI6MTU2ODAyMzQ3OH0=">
 	</head>
 	</head>
 	<body>
 	<body>
 
 

+ 2 - 0
examples/webvr_cubes.html

@@ -5,6 +5,8 @@
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<link type="text/css" rel="stylesheet" href="main.css">
 		<link type="text/css" rel="stylesheet" href="main.css">
+		<!-- WebXR Device API (For Chrome M76+), expires 09/09/2019 -->
+		<meta http-equiv="origin-trial" content="Ai1/G787sugfmWtk1xQExa8N6OqwDsJyNn+OwpA1J4PozR1lixRYIQ4Tmp00vrGWS8FQQ2iDyqjwaewrOfYvPAUAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU03NiIsImV4cGlyeSI6MTU2ODAyMzQ3OH0=">
 	</head>
 	</head>
 	<body>
 	<body>
 
 

+ 2 - 0
examples/webvr_dragging.html

@@ -5,6 +5,8 @@
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<link type="text/css" rel="stylesheet" href="main.css">
 		<link type="text/css" rel="stylesheet" href="main.css">
+		<!-- WebXR Device API (For Chrome M76+), expires 09/09/2019 -->
+		<meta http-equiv="origin-trial" content="Ai1/G787sugfmWtk1xQExa8N6OqwDsJyNn+OwpA1J4PozR1lixRYIQ4Tmp00vrGWS8FQQ2iDyqjwaewrOfYvPAUAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU03NiIsImV4cGlyeSI6MTU2ODAyMzQ3OH0=">
 	</head>
 	</head>
 	<body>
 	<body>
 
 

+ 2 - 0
examples/webvr_lorenzattractor.html

@@ -5,6 +5,8 @@
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<link type="text/css" rel="stylesheet" href="main.css">
 		<link type="text/css" rel="stylesheet" href="main.css">
+		<!-- WebXR Device API (For Chrome M76+), expires 09/09/2019 -->
+		<meta http-equiv="origin-trial" content="Ai1/G787sugfmWtk1xQExa8N6OqwDsJyNn+OwpA1J4PozR1lixRYIQ4Tmp00vrGWS8FQQ2iDyqjwaewrOfYvPAUAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU03NiIsImV4cGlyeSI6MTU2ODAyMzQ3OH0=">
 	</head>
 	</head>
 	<body>
 	<body>
 
 

+ 2 - 0
examples/webvr_paint.html

@@ -5,6 +5,8 @@
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<link type="text/css" rel="stylesheet" href="main.css">
 		<link type="text/css" rel="stylesheet" href="main.css">
+		<!-- WebXR Device API (For Chrome M76+), expires 09/09/2019 -->
+		<meta http-equiv="origin-trial" content="Ai1/G787sugfmWtk1xQExa8N6OqwDsJyNn+OwpA1J4PozR1lixRYIQ4Tmp00vrGWS8FQQ2iDyqjwaewrOfYvPAUAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU03NiIsImV4cGlyeSI6MTU2ODAyMzQ3OH0=">
 	</head>
 	</head>
 	<body>
 	<body>
 
 

+ 2 - 0
examples/webvr_panorama.html

@@ -5,6 +5,8 @@
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<link type="text/css" rel="stylesheet" href="main.css">
 		<link type="text/css" rel="stylesheet" href="main.css">
+		<!-- WebXR Device API (For Chrome M76+), expires 09/09/2019 -->
+		<meta http-equiv="origin-trial" content="Ai1/G787sugfmWtk1xQExa8N6OqwDsJyNn+OwpA1J4PozR1lixRYIQ4Tmp00vrGWS8FQQ2iDyqjwaewrOfYvPAUAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU03NiIsImV4cGlyeSI6MTU2ODAyMzQ3OH0=">
 	</head>
 	</head>
 	<body>
 	<body>
 		<script src="js/vr/HelioWebXRPolyfill.js"></script>
 		<script src="js/vr/HelioWebXRPolyfill.js"></script>

+ 2 - 0
examples/webvr_rollercoaster.html

@@ -5,6 +5,8 @@
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<link type="text/css" rel="stylesheet" href="main.css">
 		<link type="text/css" rel="stylesheet" href="main.css">
+		<!-- WebXR Device API (For Chrome M76+), expires 09/09/2019 -->
+		<meta http-equiv="origin-trial" content="Ai1/G787sugfmWtk1xQExa8N6OqwDsJyNn+OwpA1J4PozR1lixRYIQ4Tmp00vrGWS8FQQ2iDyqjwaewrOfYvPAUAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU03NiIsImV4cGlyeSI6MTU2ODAyMzQ3OH0=">
 	</head>
 	</head>
 	<body>
 	<body>
 
 

+ 2 - 0
examples/webvr_sandbox.html

@@ -5,6 +5,8 @@
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<link type="text/css" rel="stylesheet" href="main.css">
 		<link type="text/css" rel="stylesheet" href="main.css">
+		<!-- WebXR Device API (For Chrome M76+), expires 09/09/2019 -->
+		<meta http-equiv="origin-trial" content="Ai1/G787sugfmWtk1xQExa8N6OqwDsJyNn+OwpA1J4PozR1lixRYIQ4Tmp00vrGWS8FQQ2iDyqjwaewrOfYvPAUAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU03NiIsImV4cGlyeSI6MTU2ODAyMzQ3OH0=">
 	</head>
 	</head>
 	<body>
 	<body>
 
 

+ 2 - 0
examples/webvr_sculpt.html

@@ -5,6 +5,8 @@
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<link type="text/css" rel="stylesheet" href="main.css">
 		<link type="text/css" rel="stylesheet" href="main.css">
+		<!-- WebXR Device API (For Chrome M76+), expires 09/09/2019 -->
+		<meta http-equiv="origin-trial" content="Ai1/G787sugfmWtk1xQExa8N6OqwDsJyNn+OwpA1J4PozR1lixRYIQ4Tmp00vrGWS8FQQ2iDyqjwaewrOfYvPAUAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU03NiIsImV4cGlyeSI6MTU2ODAyMzQ3OH0=">
 	</head>
 	</head>
 	<body>
 	<body>
 
 

+ 2 - 0
examples/webvr_video.html

@@ -5,6 +5,8 @@
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<link type="text/css" rel="stylesheet" href="main.css">
 		<link type="text/css" rel="stylesheet" href="main.css">
+		<!-- WebXR Device API (For Chrome M76+), expires 09/09/2019 -->
+		<meta http-equiv="origin-trial" content="Ai1/G787sugfmWtk1xQExa8N6OqwDsJyNn+OwpA1J4PozR1lixRYIQ4Tmp00vrGWS8FQQ2iDyqjwaewrOfYvPAUAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU03NiIsImV4cGlyeSI6MTU2ODAyMzQ3OH0=">
 	</head>
 	</head>
 	<body>
 	<body>
 		<div id="container"></div>
 		<div id="container"></div>

+ 2 - 0
examples/webvr_vive_paint.html

@@ -5,6 +5,8 @@
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<link type="text/css" rel="stylesheet" href="main.css">
 		<link type="text/css" rel="stylesheet" href="main.css">
+		<!-- WebXR Device API (For Chrome M76+), expires 09/09/2019 -->
+		<meta http-equiv="origin-trial" content="Ai1/G787sugfmWtk1xQExa8N6OqwDsJyNn+OwpA1J4PozR1lixRYIQ4Tmp00vrGWS8FQQ2iDyqjwaewrOfYvPAUAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU03NiIsImV4cGlyeSI6MTU2ODAyMzQ3OH0=">
 	</head>
 	</head>
 	<body>
 	<body>
 
 

+ 2 - 0
examples/webvr_vive_sculpt.html

@@ -5,6 +5,8 @@
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<link type="text/css" rel="stylesheet" href="main.css">
 		<link type="text/css" rel="stylesheet" href="main.css">
+		<!-- WebXR Device API (For Chrome M76+), expires 09/09/2019 -->
+		<meta http-equiv="origin-trial" content="Ai1/G787sugfmWtk1xQExa8N6OqwDsJyNn+OwpA1J4PozR1lixRYIQ4Tmp00vrGWS8FQQ2iDyqjwaewrOfYvPAUAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU03NiIsImV4cGlyeSI6MTU2ODAyMzQ3OH0=">
 	</head>
 	</head>
 	<body>
 	<body>
 
 

BIN
icon.png


+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "three",
   "name": "three",
-  "version": "0.106.2",
+  "version": "0.107.0",
   "description": "JavaScript 3D library",
   "description": "JavaScript 3D library",
   "main": "build/three.js",
   "main": "build/three.js",
   "repository": "mrdoob/three.js",
   "repository": "mrdoob/three.js",

+ 1 - 1
rollup.config.js

@@ -207,7 +207,7 @@ export default {
 			indent: '\t'
 			indent: '\t'
 		},
 		},
 		{
 		{
-			format: 'es',
+			format: 'esm',
 			file: 'build/three.module.js',
 			file: 'build/three.module.js',
 			indent: '\t'
 			indent: '\t'
 		}
 		}

+ 1 - 1
src/constants.js

@@ -1,4 +1,4 @@
-export var REVISION = '107dev';
+export var REVISION = '107';
 export var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 };
 export var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 };
 export var TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 };
 export var TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 };
 export var CullFaceNone = 0;
 export var CullFaceNone = 0;

+ 7 - 1
src/extras/core/Font.js

@@ -74,7 +74,13 @@ function createPath( char, scale, offsetX, offsetY, data ) {
 
 
 	var glyph = data.glyphs[ char ] || data.glyphs[ '?' ];
 	var glyph = data.glyphs[ char ] || data.glyphs[ '?' ];
 
 
-	if ( ! glyph ) return;
+	if ( ! glyph ) {
+
+		console.error( 'THREE.Font: character "' + char + '" does not exists in font family ' + data.familyName + '.' );
+
+		return;
+
+	}
 
 
 	var path = new ShapePath();
 	var path = new ShapePath();
 
 

+ 0 - 3
src/geometries/CircleGeometry.d.ts

@@ -1,9 +1,6 @@
 import { Geometry } from './../core/Geometry';
 import { Geometry } from './../core/Geometry';
 import { BufferGeometry } from '../core/BufferGeometry';
 import { BufferGeometry } from '../core/BufferGeometry';
 
 
-/**
- * @deprecated Use {@link BoxGeometry} instead.
- */
 export class CircleBufferGeometry extends BufferGeometry {
 export class CircleBufferGeometry extends BufferGeometry {
 
 
 	constructor(
 	constructor(

+ 2 - 2
src/geometries/PolyhedronGeometry.js

@@ -63,7 +63,7 @@ function PolyhedronBufferGeometry( vertices, indices, radius, detail ) {
 
 
 	// all vertices should lie on a conceptual sphere with a given radius
 	// all vertices should lie on a conceptual sphere with a given radius
 
 
-	appplyRadius( radius );
+	applyRadius( radius );
 
 
 	// finally, create the uv data
 	// finally, create the uv data
 
 
@@ -176,7 +176,7 @@ function PolyhedronBufferGeometry( vertices, indices, radius, detail ) {
 
 
 	}
 	}
 
 
-	function appplyRadius( radius ) {
+	function applyRadius( radius ) {
 
 
 		var vertex = new Vector3();
 		var vertex = new Vector3();
 
 

+ 12 - 18
src/math/Euler.js

@@ -9,6 +9,8 @@ import { _Math } from './Math.js';
  * @author bhouston / http://clara.io
  * @author bhouston / http://clara.io
  */
  */
 
 
+var _matrix, _quaternion;
+
 function Euler( x, y, z, order ) {
 function Euler( x, y, z, order ) {
 
 
 	this._x = x || 0;
 	this._x = x || 0;
@@ -253,19 +255,15 @@ Object.assign( Euler.prototype, {
 
 
 	},
 	},
 
 
-	setFromQuaternion: function () {
-
-		var matrix = new Matrix4();
+	setFromQuaternion: function ( q, order, update ) {
 
 
-		return function setFromQuaternion( q, order, update ) {
+		if ( _matrix === undefined ) _matrix = new Matrix4();
 
 
-			matrix.makeRotationFromQuaternion( q );
+		_matrix.makeRotationFromQuaternion( q );
 
 
-			return this.setFromRotationMatrix( matrix, order, update );
+		return this.setFromRotationMatrix( _matrix, order, update );
 
 
-		};
-
-	}(),
+	},
 
 
 	setFromVector3: function ( v, order ) {
 	setFromVector3: function ( v, order ) {
 
 
@@ -273,21 +271,17 @@ Object.assign( Euler.prototype, {
 
 
 	},
 	},
 
 
-	reorder: function () {
+	reorder: function ( newOrder ) {
 
 
 		// WARNING: this discards revolution information -bhouston
 		// WARNING: this discards revolution information -bhouston
 
 
-		var q = new Quaternion();
+		if ( _quaternion === undefined ) _quaternion = new Quaternion();
 
 
-		return function reorder( newOrder ) {
+		_quaternion.setFromEuler( this );
 
 
-			q.setFromEuler( this );
+		return this.setFromQuaternion( _quaternion, newOrder );
 
 
-			return this.setFromQuaternion( q, newOrder );
-
-		};
-
-	}(),
+	},
 
 
 	equals: function ( euler ) {
 	equals: function ( euler ) {
 
 

+ 17 - 15
src/math/Line3.js

@@ -5,6 +5,8 @@ import { _Math } from './Math.js';
  * @author bhouston / http://clara.io
  * @author bhouston / http://clara.io
  */
  */
 
 
+var _startP, _startEnd;
+
 function Line3( start, end ) {
 function Line3( start, end ) {
 
 
 	this.start = ( start !== undefined ) ? start : new Vector3();
 	this.start = ( start !== undefined ) ? start : new Vector3();
@@ -89,32 +91,32 @@ Object.assign( Line3.prototype, {
 
 
 	},
 	},
 
 
-	closestPointToPointParameter: function () {
+	closestPointToPointParameter: function ( point, clampToLine ) {
 
 
-		var startP = new Vector3();
-		var startEnd = new Vector3();
+		if ( _startP === undefined ) {
 
 
-		return function closestPointToPointParameter( point, clampToLine ) {
+			_startP = new Vector3();
+			_startEnd = new Vector3();
 
 
-			startP.subVectors( point, this.start );
-			startEnd.subVectors( this.end, this.start );
+		}
 
 
-			var startEnd2 = startEnd.dot( startEnd );
-			var startEnd_startP = startEnd.dot( startP );
+		_startP.subVectors( point, this.start );
+		_startEnd.subVectors( this.end, this.start );
 
 
-			var t = startEnd_startP / startEnd2;
+		var startEnd2 = _startEnd.dot( _startEnd );
+		var startEnd_startP = _startEnd.dot( _startP );
 
 
-			if ( clampToLine ) {
+		var t = startEnd_startP / startEnd2;
 
 
-				t = _Math.clamp( t, 0, 1 );
+		if ( clampToLine ) {
 
 
-			}
+			t = _Math.clamp( t, 0, 1 );
 
 
-			return t;
+		}
 
 
-		};
+		return t;
 
 
-	}(),
+	},
 
 
 	closestPointToPoint: function ( point, clampToLine, target ) {
 	closestPointToPoint: function ( point, clampToLine, target ) {
 
 

+ 11 - 0
src/math/Matrix3.d.ts

@@ -100,6 +100,17 @@ export class Matrix3 implements Matrix {
 	 * Transposes this matrix into the supplied array r, and returns itself.
 	 * Transposes this matrix into the supplied array r, and returns itself.
 	 */
 	 */
 	transposeIntoArray( r: number[] ): number[];
 	transposeIntoArray( r: number[] ): number[];
+
+	setUvTransform( tx: number, ty: number, sx: number, sy: number, rotation: number, cx: number, cy: number ): Matrix3;
+
+	scale( sx: number, sy: number ): Matrix3;
+
+	rotate( theta: number ): Matrix3;
+
+	translate( tx: number, ty: number ): Matrix3;
+
+	equals( matrix: Matrix3 ): boolean;
+
 	fromArray( array: number[], offset?: number ): Matrix3;
 	fromArray( array: number[], offset?: number ): Matrix3;
 
 
 	toArray( array?: number[], offset?: number ): number[];
 	toArray( array?: number[], offset?: number ): number[];

+ 13 - 15
src/math/Matrix3.js

@@ -7,6 +7,8 @@ import { Vector3 } from './Vector3.js';
  * @author tschw
  * @author tschw
  */
  */
 
 
+var _vector;
+
 function Matrix3() {
 function Matrix3() {
 
 
 	this.elements = [
 	this.elements = [
@@ -90,29 +92,25 @@ Object.assign( Matrix3.prototype, {
 
 
 	},
 	},
 
 
-	applyToBufferAttribute: function () {
-
-		var v1 = new Vector3();
-
-		return function applyToBufferAttribute( attribute ) {
+	applyToBufferAttribute: function ( attribute ) {
 
 
-			for ( var i = 0, l = attribute.count; i < l; i ++ ) {
+		if ( _vector === undefined ) _vector = new Vector3();
 
 
-				v1.x = attribute.getX( i );
-				v1.y = attribute.getY( i );
-				v1.z = attribute.getZ( i );
+		for ( var i = 0, l = attribute.count; i < l; i ++ ) {
 
 
-				v1.applyMatrix3( this );
+			_vector.x = attribute.getX( i );
+			_vector.y = attribute.getY( i );
+			_vector.z = attribute.getZ( i );
 
 
-				attribute.setXYZ( i, v1.x, v1.y, v1.z );
+			_vector.applyMatrix3( this );
 
 
-			}
+			attribute.setXYZ( i, _vector.x, _vector.y, _vector.z );
 
 
-			return attribute;
+		}
 
 
-		};
+		return attribute;
 
 
-	}(),
+	},
 
 
 	multiply: function ( m ) {
 	multiply: function ( m ) {
 
 

+ 17 - 19
src/math/Sphere.js

@@ -6,6 +6,8 @@ import { Vector3 } from './Vector3.js';
  * @author mrdoob / http://mrdoob.com/
  * @author mrdoob / http://mrdoob.com/
  */
  */
 
 
+var _box;
+
 function Sphere( center, radius ) {
 function Sphere( center, radius ) {
 
 
 	this.center = ( center !== undefined ) ? center : new Vector3();
 	this.center = ( center !== undefined ) ? center : new Vector3();
@@ -24,39 +26,35 @@ Object.assign( Sphere.prototype, {
 
 
 	},
 	},
 
 
-	setFromPoints: function () {
-
-		var box = new Box3();
+	setFromPoints: function ( points, optionalCenter ) {
 
 
-		return function setFromPoints( points, optionalCenter ) {
+		if ( _box === undefined ) _box = new Box3();
 
 
-			var center = this.center;
+		var center = this.center;
 
 
-			if ( optionalCenter !== undefined ) {
+		if ( optionalCenter !== undefined ) {
 
 
-				center.copy( optionalCenter );
+			center.copy( optionalCenter );
 
 
-			} else {
+		} else {
 
 
-				box.setFromPoints( points ).getCenter( center );
+			_box.setFromPoints( points ).getCenter( center );
 
 
-			}
-
-			var maxRadiusSq = 0;
+		}
 
 
-			for ( var i = 0, il = points.length; i < il; i ++ ) {
+		var maxRadiusSq = 0;
 
 
-				maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );
+		for ( var i = 0, il = points.length; i < il; i ++ ) {
 
 
-			}
+			maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );
 
 
-			this.radius = Math.sqrt( maxRadiusSq );
+		}
 
 
-			return this;
+		this.radius = Math.sqrt( maxRadiusSq );
 
 
-		};
+		return this;
 
 
-	}(),
+	},
 
 
 	clone: function () {
 	clone: function () {
 
 

+ 7 - 18
src/math/Vector4.js

@@ -471,27 +471,16 @@ Object.assign( Vector4.prototype, {
 
 
 	},
 	},
 
 
-	clampScalar: function () {
+	clampScalar: function ( minVal, maxVal ) {
 
 
-		var min, max;
+		this.x = Math.max( minVal, Math.min( maxVal, this.x ) );
+		this.y = Math.max( minVal, Math.min( maxVal, this.y ) );
+		this.z = Math.max( minVal, Math.min( maxVal, this.z ) );
+		this.w = Math.max( minVal, Math.min( maxVal, this.w ) );
 
 
-		return function clampScalar( minVal, maxVal ) {
-
-			if ( min === undefined ) {
-
-				min = new Vector4();
-				max = new Vector4();
-
-			}
-
-			min.set( minVal, minVal, minVal, minVal );
-			max.set( maxVal, maxVal, maxVal, maxVal );
-
-			return this.clamp( min, max );
-
-		};
+		return this;
 
 
-	}(),
+	},
 
 
 	clampLength: function ( min, max ) {
 	clampLength: function ( min, max ) {
 
 

+ 1 - 1
utils/modularize.js

@@ -87,7 +87,7 @@ var files = [
 	{ path: 'loaders/DRACOLoader.js', dependencies: [], ignoreList: [ 'LoadingManager' ] },
 	{ path: 'loaders/DRACOLoader.js', dependencies: [], ignoreList: [ 'LoadingManager' ] },
 	{ path: 'loaders/EXRLoader.js', dependencies: [], ignoreList: [] },
 	{ path: 'loaders/EXRLoader.js', dependencies: [], ignoreList: [] },
 	{ path: 'loaders/EquirectangularToCubeGenerator.js', dependencies: [], ignoreList: [] },
 	{ path: 'loaders/EquirectangularToCubeGenerator.js', dependencies: [], ignoreList: [] },
-	{ path: 'loaders/FBXLoader.js', dependencies: [ { name: 'Zlib', path: 'libs/inflate.module.min.js' }, { name: 'TGALoader', path: 'loaders/TGALoader.js' }, { name: 'NURBSCurve', path: 'curves/NURBSCurve.js' } ], ignoreList: [] },
+	{ path: 'loaders/FBXLoader.js', dependencies: [ { name: 'Zlib', path: 'libs/inflate.module.min.js' }, { name: 'NURBSCurve', path: 'curves/NURBSCurve.js' } ], ignoreList: [] },
 	{ path: 'loaders/GCodeLoader.js', dependencies: [], ignoreList: [] },
 	{ path: 'loaders/GCodeLoader.js', dependencies: [], ignoreList: [] },
 	{ path: 'loaders/GLTFLoader.js', dependencies: [], ignoreList: [ 'NoSide', 'Matrix2', 'Camera', 'Texture' ] },
 	{ path: 'loaders/GLTFLoader.js', dependencies: [], ignoreList: [ 'NoSide', 'Matrix2', 'Camera', 'Texture' ] },
 	{ path: 'loaders/HDRCubeTextureLoader.js', dependencies: [ { name: 'RGBELoader', path: 'loaders/RGBELoader.js' } ], ignoreList: [] },
 	{ path: 'loaders/HDRCubeTextureLoader.js', dependencies: [ { name: 'RGBELoader', path: 'loaders/RGBELoader.js' } ], ignoreList: [] },

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно