Browse Source

Updated examples builds.

Mr.doob 3 years ago
parent
commit
4f94d21351

+ 116 - 121
examples/js/controls/ArcballControls.js

@@ -39,26 +39,12 @@
 	};
 	const _endEvent = {
 		type: 'end'
-	}; //global objects that are used in some operations to avoid creating new objects every time (e.g. every time cursor moves)
-
-	const _v2_1 = new THREE.Vector2();
-
-	const _v3_1 = new THREE.Vector3();
-
-	const _v3_2 = new THREE.Vector3();
-
-	const _m4_1 = new THREE.Matrix4();
-
-	const _m4_2 = new THREE.Matrix4();
-
-	const _quat = new THREE.Quaternion();
+	};
 
 	const _raycaster = new THREE.Raycaster();
 
 	const _offset = new THREE.Vector3();
 
-	const _movement = new THREE.Vector3();
-
 	const _gizmoMatrixStateTemp = new THREE.Matrix4();
 
 	const _cameraMatrixStateTemp = new THREE.Matrix4();
@@ -538,9 +524,9 @@
 
 									}
 
-									_v3_1.setFromMatrixPosition( this._cameraMatrixState );
+									this._v3_1.setFromMatrixPosition( this._cameraMatrixState );
 
-									const x = _v3_1.distanceTo( this._gizmos.position );
+									const x = this._v3_1.distanceTo( this._gizmos.position );
 
 									let xNew = x / size; //distance between camera and gizmos if scale(size, scalepoint) would be performed
 									//check min and max distance
@@ -859,9 +845,9 @@
 
 									}
 
-									_v3_1.setFromMatrixPosition( this._gizmoMatrixState );
+									this._v3_1.setFromMatrixPosition( this._gizmoMatrixState );
 
-									this.applyTransformMatrix( this.scale( size, _v3_1 ) );
+									this.applyTransformMatrix( this.scale( size, this._v3_1 ) );
 
 								}
 
@@ -911,9 +897,9 @@
 
 									}
 
-									_v3_1.setFromMatrixPosition( this._cameraMatrixState );
+									this._v3_1.setFromMatrixPosition( this._cameraMatrixState );
 
-									const x = _v3_1.distanceTo( this._gizmos.position );
+									const x = this._v3_1.distanceTo( this._gizmos.position );
 
 									let xNew = x / size; //distance between camera and gizmos if scale(size, scalepoint) would be performed
 									//check min and max distance
@@ -927,14 +913,14 @@
 									const newDistance = y / Math.tan( THREE.MathUtils.DEG2RAD * ( newFov / 2 ) );
 									size = x / newDistance;
 
-									_v3_2.setFromMatrixPosition( this._gizmoMatrixState );
+									this._v3_2.setFromMatrixPosition( this._gizmoMatrixState );
 
 									this.setFov( newFov );
-									this.applyTransformMatrix( this.scale( size, _v3_2, false ) ); //adjusting distance
+									this.applyTransformMatrix( this.scale( size, this._v3_2, false ) ); //adjusting distance
 
 									_offset.copy( this._gizmos.position ).sub( this.camera.position ).normalize().multiplyScalar( newDistance / x );
 
-									_m4_1.makeTranslation( _offset.x, _offset.y, _offset.z );
+									this._m4_1.makeTranslation( _offset.x, _offset.y, _offset.z );
 
 								}
 
@@ -1146,9 +1132,9 @@
 
 					} else {
 
-						_v3_2.setFromMatrixPosition( this._gizmoMatrixState );
+						this._v3_2.setFromMatrixPosition( this._gizmoMatrixState );
 
-						rotationPoint = this.unprojectOnTbPlane( this.camera, _center.x, _center.y, this.domElement ).applyQuaternion( this.camera.quaternion ).multiplyScalar( 1 / this.camera.zoom ).add( _v3_2 );
+						rotationPoint = this.unprojectOnTbPlane( this.camera, _center.x, _center.y, this.domElement ).applyQuaternion( this.camera.quaternion ).multiplyScalar( 1 / this.camera.zoom ).add( this._v3_2 );
 
 					}
 
@@ -1303,9 +1289,9 @@
 
 					}
 
-					_v3_1.setFromMatrixPosition( this._cameraMatrixState );
+					this._v3_1.setFromMatrixPosition( this._cameraMatrixState );
 
-					const x = _v3_1.distanceTo( this._gizmos.position );
+					const x = this._v3_1.distanceTo( this._gizmos.position );
 
 					let xNew = x / size; //distance between camera and gizmos if scale(size, scalepoint) would be performed
 					//check min and max distance
@@ -1319,14 +1305,14 @@
 					const newDistance = y / Math.tan( THREE.MathUtils.DEG2RAD * ( newFov / 2 ) );
 					size = x / newDistance;
 
-					_v3_2.setFromMatrixPosition( this._gizmoMatrixState );
+					this._v3_2.setFromMatrixPosition( this._gizmoMatrixState );
 
 					this.setFov( newFov );
-					this.applyTransformMatrix( this.scale( size, _v3_2, false ) ); //adjusting distance
+					this.applyTransformMatrix( this.scale( size, this._v3_2, false ) ); //adjusting distance
 
 					_offset.copy( this._gizmos.position ).sub( this.camera.position ).normalize().multiplyScalar( newDistance / x );
 
-					_m4_1.makeTranslation( _offset.x, _offset.y, _offset.z );
+					this._m4_1.makeTranslation( _offset.x, _offset.y, _offset.z );
 
 					this.dispatchEvent( _changeEvent );
 
@@ -1586,11 +1572,11 @@
 
 				this._rotationMatrix.extractRotation( this._cameraMatrixState );
 
-				_quat.setFromRotationMatrix( this._rotationMatrix );
+				this._quat.setFromRotationMatrix( this._rotationMatrix );
 
-				this._rotationAxis.crossVectors( vec1, vec2 ).applyQuaternion( _quat );
+				this._rotationAxis.crossVectors( vec1, vec2 ).applyQuaternion( this._quat );
 
-				return this._rotationAxis.normalize();
+				return this._rotationAxis.normalize().clone();
 
 			};
 
@@ -1770,21 +1756,21 @@
 
 				const canvasRect = canvas.getBoundingClientRect();
 
-				_v2_1.setX( ( cursorX - canvasRect.left ) / canvasRect.width * 2 - 1 );
+				this._v2_1.setX( ( cursorX - canvasRect.left ) / canvasRect.width * 2 - 1 );
 
-				_v2_1.setY( ( canvasRect.bottom - cursorY ) / canvasRect.height * 2 - 1 );
+				this._v2_1.setY( ( canvasRect.bottom - cursorY ) / canvasRect.height * 2 - 1 );
 
-				return _v2_1;
+				return this._v2_1.clone();
 
 			};
 
 			this.getCursorPosition = ( cursorX, cursorY, canvas ) => {
 
-				_v2_1.copy( this.getCursorNDC( cursorX, cursorY, canvas ) );
+				this._v2_1.copy( this.getCursorNDC( cursorX, cursorY, canvas ) );
 
-				_v2_1.x *= ( this.camera.right - this.camera.left ) * 0.5;
-				_v2_1.y *= ( this.camera.top - this.camera.bottom ) * 0.5;
-				return _v2_1;
+				this._v2_1.x *= ( this.camera.right - this.camera.left ) * 0.5;
+				this._v2_1.y *= ( this.camera.top - this.camera.bottom ) * 0.5;
+				return this._v2_1.clone();
 
 			};
 
@@ -1932,7 +1918,7 @@
 						const self = this;
 						this._animationId = window.requestAnimationFrame( function ( t ) {
 
-							self.onFocusAnim( t, point, cameraMatrix, gizmoMatrix );
+							self.onFocusAnim( t, point, cameraMatrix, gizmoMatrix.clone() );
 
 						} );
 
@@ -2007,7 +1993,7 @@
 
 			this.pan = ( p0, p1, adjust = false ) => {
 
-				const movement = _movement.copy( p0 ).sub( p1 );
+				const movement = p0.clone().sub( p1 );
 
 				if ( this.camera.isOrthographicCamera ) {
 
@@ -2017,22 +2003,22 @@
 				} else if ( this.camera.isPerspectiveCamera && adjust ) {
 
 					//adjust movement amount
-					_v3_1.setFromMatrixPosition( this._cameraMatrixState0 ); //camera's initial position
+					this._v3_1.setFromMatrixPosition( this._cameraMatrixState0 ); //camera's initial position
 
 
-					_v3_2.setFromMatrixPosition( this._gizmoMatrixState0 ); //gizmo's initial position
+					this._v3_2.setFromMatrixPosition( this._gizmoMatrixState0 ); //gizmo's initial position
 
 
-					const distanceFactor = _v3_1.distanceTo( _v3_2 ) / this.camera.position.distanceTo( this._gizmos.position );
+					const distanceFactor = this._v3_1.distanceTo( this._v3_2 ) / this.camera.position.distanceTo( this._gizmos.position );
 					movement.multiplyScalar( 1 / distanceFactor );
 
 				}
 
-				_v3_1.set( movement.x, movement.y, 0 ).applyQuaternion( this.camera.quaternion );
+				this._v3_1.set( movement.x, movement.y, 0 ).applyQuaternion( this.camera.quaternion );
 
-				_m4_1.makeTranslation( _v3_1.x, _v3_1.y, _v3_1.z );
+				this._m4_1.makeTranslation( this._v3_1.x, this._v3_1.y, this._v3_1.z );
 
-				this.setTransformationMatrices( _m4_1, _m4_1 );
+				this.setTransformationMatrices( this._m4_1, this._m4_1 );
 				return _transformation;
 
 			};
@@ -2081,13 +2067,13 @@
 				this._rotationMatrix.makeRotationAxis( axis, - angle ); //rotate camera
 
 
-				_m4_1.makeTranslation( point.x, point.y, point.z );
+				this._m4_1.makeTranslation( point.x, point.y, point.z );
 
-				_m4_1.multiply( this._rotationMatrix );
+				this._m4_1.multiply( this._rotationMatrix );
 
-				_m4_1.multiply( this._translationMatrix );
+				this._m4_1.multiply( this._translationMatrix );
 
-				this.setTransformationMatrices( _m4_1 );
+				this.setTransformationMatrices( this._m4_1 );
 				return _transformation;
 
 			};
@@ -2186,38 +2172,40 @@
 
 					this.camera.updateProjectionMatrix();
 
-					_v3_1.setFromMatrixPosition( this._gizmoMatrixState ); //gizmos position
+					this._v3_1.setFromMatrixPosition( this._gizmoMatrixState ); //gizmos position
 					//scale gizmos so they appear in the same spot having the same dimension
 
 
 					this._scaleMatrix.makeScale( sizeInverse, sizeInverse, sizeInverse );
 
-					this._translationMatrix.makeTranslation( - _v3_1.x, - _v3_1.y, - _v3_1.z );
+					this._translationMatrix.makeTranslation( - this._v3_1.x, - this._v3_1.y, - this._v3_1.z );
 
-					_m4_2.makeTranslation( _v3_1.x, _v3_1.y, _v3_1.z ).multiply( this._scaleMatrix );
+					this._m4_2.makeTranslation( this._v3_1.x, this._v3_1.y, this._v3_1.z ).multiply( this._scaleMatrix );
 
-					_m4_2.multiply( this._translationMatrix ); //move camera and gizmos to obtain pinch effect
+					this._m4_2.multiply( this._translationMatrix ); //move camera and gizmos to obtain pinch effect
 
 
-					_scalePointTemp.sub( _v3_1 );
+					_scalePointTemp.sub( this._v3_1 );
 
-					_scalePointTemp.multiplyScalar( 1 - sizeInverse );
+					const amount = _scalePointTemp.clone().multiplyScalar( sizeInverse );
 
-					_m4_1.makeTranslation( _scalePointTemp.x, _scalePointTemp.y, _scalePointTemp.z );
+					_scalePointTemp.sub( amount );
 
-					_m4_2.premultiply( _m4_1 );
+					this._m4_1.makeTranslation( _scalePointTemp.x, _scalePointTemp.y, _scalePointTemp.z );
 
-					this.setTransformationMatrices( _m4_1, _m4_2 );
+					this._m4_2.premultiply( this._m4_1 );
+
+					this.setTransformationMatrices( this._m4_1, this._m4_2 );
 					return _transformation;
 
 				} else if ( this.camera.isPerspectiveCamera ) {
 
-					_v3_1.setFromMatrixPosition( this._cameraMatrixState );
+					this._v3_1.setFromMatrixPosition( this._cameraMatrixState );
 
-					_v3_2.setFromMatrixPosition( this._gizmoMatrixState ); //move camera
+					this._v3_2.setFromMatrixPosition( this._gizmoMatrixState ); //move camera
 
 
-					let distance = _v3_1.distanceTo( _scalePointTemp );
+					let distance = this._v3_1.distanceTo( _scalePointTemp );
 
 					let amount = distance - distance * sizeInverse; //check min and max distance
 
@@ -2235,36 +2223,36 @@
 
 					}
 
-					_offset.copy( _scalePointTemp ).sub( _v3_1 ).normalize().multiplyScalar( amount );
+					_offset.copy( _scalePointTemp ).sub( this._v3_1 ).normalize().multiplyScalar( amount );
 
-					_m4_1.makeTranslation( _offset.x, _offset.y, _offset.z );
+					this._m4_1.makeTranslation( _offset.x, _offset.y, _offset.z );
 
 					if ( scaleGizmos ) {
 
 						//scale gizmos so they appear in the same spot having the same dimension
-						const pos = _v3_2;
+						const pos = this._v3_2;
 						distance = pos.distanceTo( _scalePointTemp );
 						amount = distance - distance * sizeInverse;
 
-						_offset.copy( _scalePointTemp ).sub( _v3_2 ).normalize().multiplyScalar( amount );
+						_offset.copy( _scalePointTemp ).sub( this._v3_2 ).normalize().multiplyScalar( amount );
 
 						this._translationMatrix.makeTranslation( pos.x, pos.y, pos.z );
 
 						this._scaleMatrix.makeScale( sizeInverse, sizeInverse, sizeInverse );
 
-						_m4_2.makeTranslation( _offset.x, _offset.y, _offset.z ).multiply( this._translationMatrix );
+						this._m4_2.makeTranslation( _offset.x, _offset.y, _offset.z ).multiply( this._translationMatrix );
 
-						_m4_2.multiply( this._scaleMatrix );
+						this._m4_2.multiply( this._scaleMatrix );
 
 						this._translationMatrix.makeTranslation( - pos.x, - pos.y, - pos.z );
 
-						_m4_2.multiply( this._translationMatrix );
+						this._m4_2.multiply( this._translationMatrix );
 
-						this.setTransformationMatrices( _m4_1, _m4_2 );
+						this.setTransformationMatrices( this._m4_1, this._m4_2 );
 
 					} else {
 
-						this.setTransformationMatrices( _m4_1 );
+						this.setTransformationMatrices( this._m4_1 );
 
 					}
 
@@ -2291,23 +2279,23 @@
 
 				this._translationMatrix.makeTranslation( - point.x, - point.y, - point.z );
 
-				_m4_1.makeTranslation( point.x, point.y, point.z );
+				this._m4_1.makeTranslation( point.x, point.y, point.z );
 
-				_m4_1.multiply( this._rotationMatrix );
+				this._m4_1.multiply( this._rotationMatrix );
 
-				_m4_1.multiply( this._translationMatrix );
+				this._m4_1.multiply( this._translationMatrix );
 
-				_v3_1.setFromMatrixPosition( this._gizmoMatrixState ).sub( point ); //vector from rotation center to gizmos position
+				this._v3_1.setFromMatrixPosition( this._gizmoMatrixState ).sub( point ); //vector from rotation center to gizmos position
 
 
-				_v3_2.copy( _v3_1 ).applyAxisAngle( this._rotationAxis, angle ); //apply rotation
+				this._v3_2.copy( this._v3_1 ).applyAxisAngle( this._rotationAxis, angle ); //apply rotation
 
 
-				_v3_2.sub( _v3_1 );
+				this._v3_2.sub( this._v3_1 );
 
-				_m4_2.makeTranslation( _v3_2.x, _v3_2.y, _v3_2.z );
+				this._m4_2.makeTranslation( this._v3_2.x, this._v3_2.y, this._v3_2.z );
 
-				this.setTransformationMatrices( _m4_1, _m4_2 );
+				this.setTransformationMatrices( this._m4_1, this._m4_2 );
 				return _transformation;
 
 			};
@@ -2324,7 +2312,7 @@
 
 					if ( intersect[ i ].object.uuid != this._gizmos.uuid && intersect[ i ].face != null ) {
 
-						return intersect[ i ].point;
+						return intersect[ i ].point.clone();
 
 					}
 
@@ -2338,38 +2326,38 @@
 
 				if ( camera.type == 'OrthographicCamera' ) {
 
-					_v2_1.copy( this.getCursorPosition( cursorX, cursorY, canvas ) );
+					this._v2_1.copy( this.getCursorPosition( cursorX, cursorY, canvas ) );
 
-					_v3_1.set( _v2_1.x, _v2_1.y, 0 );
+					this._v3_1.set( this._v2_1.x, this._v2_1.y, 0 );
 
-					const x2 = Math.pow( _v2_1.x, 2 );
-					const y2 = Math.pow( _v2_1.y, 2 );
+					const x2 = Math.pow( this._v2_1.x, 2 );
+					const y2 = Math.pow( this._v2_1.y, 2 );
 					const r2 = Math.pow( this._tbRadius, 2 );
 
 					if ( x2 + y2 <= r2 * 0.5 ) {
 
 						//intersection with sphere
-						_v3_1.setZ( Math.sqrt( r2 - ( x2 + y2 ) ) );
+						this._v3_1.setZ( Math.sqrt( r2 - ( x2 + y2 ) ) );
 
 					} else {
 
 						//intersection with hyperboloid
-						_v3_1.setZ( r2 * 0.5 / Math.sqrt( x2 + y2 ) );
+						this._v3_1.setZ( r2 * 0.5 / Math.sqrt( x2 + y2 ) );
 
 					}
 
-					return _v3_1;
+					return this._v3_1;
 
 				} else if ( camera.type == 'PerspectiveCamera' ) {
 
 					//unproject cursor on the near plane
-					_v2_1.copy( this.getCursorNDC( cursorX, cursorY, canvas ) );
+					this._v2_1.copy( this.getCursorNDC( cursorX, cursorY, canvas ) );
 
-					_v3_1.set( _v2_1.x, _v2_1.y, - 1 );
+					this._v3_1.set( this._v2_1.x, this._v2_1.y, - 1 );
 
-					_v3_1.applyMatrix4( camera.projectionMatrixInverse );
+					this._v3_1.applyMatrix4( camera.projectionMatrixInverse );
 
-					const rayDir = _v3_2.copy( _v3_1 ).normalize(); //unprojected ray direction
+					const rayDir = this._v3_1.clone().normalize(); //unprojected ray direction
 
 
 					const cameraGizmoDistance = camera.position.distanceTo( this._gizmos.position );
@@ -2383,13 +2371,13 @@
 					//	_ _ | _ _ _\ _ _  near plane
 					//			l
 
-					const h = _v3_1.z;
-					const l = Math.sqrt( Math.pow( _v3_1.x, 2 ) + Math.pow( _v3_1.y, 2 ) );
+					const h = this._v3_1.z;
+					const l = Math.sqrt( Math.pow( this._v3_1.x, 2 ) + Math.pow( this._v3_1.y, 2 ) );
 
 					if ( l == 0 ) {
 
 						//ray aligned with camera
-						rayDir.set( _v3_1.x, _v3_1.y, tbRadius );
+						rayDir.set( this._v3_1.x, this._v3_1.y, tbRadius );
 						return rayDir;
 
 					}
@@ -2412,17 +2400,17 @@
 					if ( delta >= 0 ) {
 
 						//intersection with sphere
-						_v2_1.setX( ( - b - Math.sqrt( delta ) ) / ( 2 * a ) );
+						this._v2_1.setX( ( - b - Math.sqrt( delta ) ) / ( 2 * a ) );
 
-						_v2_1.setY( m * _v2_1.x + q );
+						this._v2_1.setY( m * this._v2_1.x + q );
 
-						const angle = THREE.MathUtils.RAD2DEG * _v2_1.angle();
+						const angle = THREE.MathUtils.RAD2DEG * this._v2_1.angle();
 
 						if ( angle >= 45 ) {
 
 							//if angle between intersection point and X' axis is >= 45°, return that point
 							//otherwise, calculate intersection point with hyperboloid
-							const rayLength = Math.sqrt( Math.pow( _v2_1.x, 2 ) + Math.pow( cameraGizmoDistance - _v2_1.y, 2 ) );
+							const rayLength = Math.sqrt( Math.pow( this._v2_1.x, 2 ) + Math.pow( cameraGizmoDistance - this._v2_1.y, 2 ) );
 							rayDir.multiplyScalar( rayLength );
 							rayDir.z += cameraGizmoDistance;
 							return rayDir;
@@ -2444,11 +2432,11 @@
 					c = - radius2 * 0.5;
 					delta = Math.pow( b, 2 ) - 4 * a * c;
 
-					_v2_1.setX( ( - b - Math.sqrt( delta ) ) / ( 2 * a ) );
+					this._v2_1.setX( ( - b - Math.sqrt( delta ) ) / ( 2 * a ) );
 
-					_v2_1.setY( m * _v2_1.x + q );
+					this._v2_1.setY( m * this._v2_1.x + q );
 
-					const rayLength = Math.sqrt( Math.pow( _v2_1.x, 2 ) + Math.pow( cameraGizmoDistance - _v2_1.y, 2 ) );
+					const rayLength = Math.sqrt( Math.pow( this._v2_1.x, 2 ) + Math.pow( cameraGizmoDistance - this._v2_1.y, 2 ) );
 					rayDir.multiplyScalar( rayLength );
 					rayDir.z += cameraGizmoDistance;
 					return rayDir;
@@ -2461,22 +2449,22 @@
 
 				if ( camera.type == 'OrthographicCamera' ) {
 
-					_v2_1.copy( this.getCursorPosition( cursorX, cursorY, canvas ) );
+					this._v2_1.copy( this.getCursorPosition( cursorX, cursorY, canvas ) );
 
-					_v3_1.set( _v2_1.x, _v2_1.y, 0 );
+					this._v3_1.set( this._v2_1.x, this._v2_1.y, 0 );
 
-					return _v3_1;
+					return this._v3_1.clone();
 
 				} else if ( camera.type == 'PerspectiveCamera' ) {
 
-					_v2_1.copy( this.getCursorNDC( cursorX, cursorY, canvas ) ); //unproject cursor on the near plane
+					this._v2_1.copy( this.getCursorNDC( cursorX, cursorY, canvas ) ); //unproject cursor on the near plane
 
 
-					_v3_1.set( _v2_1.x, _v2_1.y, - 1 );
+					this._v3_1.set( this._v2_1.x, this._v2_1.y, - 1 );
 
-					_v3_1.applyMatrix4( camera.projectionMatrixInverse );
+					this._v3_1.applyMatrix4( camera.projectionMatrixInverse );
 
-					const rayDir = _v3_2.copy( _v3_1 ).normalize(); //unprojected ray direction
+					const rayDir = this._v3_1.clone().normalize(); //unprojected ray direction
 					//	  camera
 					//		|\
 					//		| \
@@ -2488,13 +2476,13 @@
 					//			l
 
 
-					const h = _v3_1.z;
-					const l = Math.sqrt( Math.pow( _v3_1.x, 2 ) + Math.pow( _v3_1.y, 2 ) );
+					const h = this._v3_1.z;
+					const l = Math.sqrt( Math.pow( this._v3_1.x, 2 ) + Math.pow( this._v3_1.y, 2 ) );
 					let cameraGizmoDistance;
 
 					if ( initialDistance ) {
 
-						cameraGizmoDistance = _v3_1.setFromMatrixPosition( this._cameraMatrixState0 ).distanceTo( _v3_2.setFromMatrixPosition( this._gizmoMatrixState0 ) );
+						cameraGizmoDistance = this._v3_1.setFromMatrixPosition( this._cameraMatrixState0 ).distanceTo( this._v3_2.setFromMatrixPosition( this._gizmoMatrixState0 ) );
 
 					} else {
 
@@ -2688,7 +2676,14 @@
 			this._currentTarget = new THREE.Vector3();
 			this.radiusFactor = 0.67;
 			this.mouseActions = [];
-			this._mouseOp = null; //transformation matrices
+			this._mouseOp = null; //global vectors and matrices that are used in some operations to avoid creating new objects every time (e.g. every time cursor moves)
+
+			this._v2_1 = new THREE.Vector2();
+			this._v3_1 = new THREE.Vector3();
+			this._v3_2 = new THREE.Vector3();
+			this._m4_1 = new THREE.Matrix4();
+			this._m4_2 = new THREE.Matrix4();
+			this._quat = new THREE.Quaternion(); //transformation matrices
 
 			this._translationMatrix = new THREE.Matrix4(); //matrix for translation operation
 
@@ -2834,9 +2829,9 @@
 
 			if ( transformation.camera != null ) {
 
-				_m4_1.copy( this._cameraMatrixState ).premultiply( transformation.camera );
+				this._m4_1.copy( this._cameraMatrixState ).premultiply( transformation.camera );
 
-				_m4_1.decompose( this.camera.position, this.camera.quaternion, this.camera.scale );
+				this._m4_1.decompose( this.camera.position, this.camera.quaternion, this.camera.scale );
 
 				this.camera.updateMatrix(); //update camera up vector
 
@@ -2850,9 +2845,9 @@
 
 			if ( transformation.gizmos != null ) {
 
-				_m4_1.copy( this._gizmoMatrixState ).premultiply( transformation.gizmos );
+				this._m4_1.copy( this._gizmoMatrixState ).premultiply( transformation.gizmos );
 
-				_m4_1.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale );
+				this._m4_1.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale );
 
 				this._gizmos.updateMatrix();
 
@@ -2972,7 +2967,7 @@
 
 				} else {
 
-					_transformation.camera = camera;
+					_transformation.camera = camera.clone();
 
 				}
 
@@ -2990,7 +2985,7 @@
 
 				} else {
 
-					_transformation.gizmos = gizmos;
+					_transformation.gizmos = gizmos.clone();
 
 				}
 

+ 49 - 36
examples/js/exporters/GLTFExporter.js

@@ -185,23 +185,7 @@
 
 	function stringToArrayBuffer( text ) {
 
-		if ( window.TextEncoder !== undefined ) {
-
-			return new TextEncoder().encode( text ).buffer;
-
-		}
-
-		const array = new Uint8Array( new ArrayBuffer( text.length ) );
-
-		for ( let i = 0, il = text.length; i < il; i ++ ) {
-
-			const value = text.charCodeAt( i ); // Replacing multi-byte character with space(0x20).
-
-			array[ i ] = value > 0xFF ? 0x20 : value;
-
-		}
-
-		return array.buffer;
+		return new TextEncoder().encode( text ).buffer;
 
 	}
 	/**
@@ -312,10 +296,33 @@
 	}
 
 	let cachedCanvas = null;
+
+	function getCanvas() {
+
+		if ( cachedCanvas ) {
+
+			return cachedCanvas;
+
+		}
+
+		if ( typeof OffscreenCanvas !== 'undefined' ) {
+
+			cachedCanvas = new OffscreenCanvas( 1, 1 );
+
+		} else {
+
+			cachedCanvas = document.createElement( 'canvas' );
+
+		}
+
+		return cachedCanvas;
+
+	}
 	/**
  * Writer
  */
 
+
 	class GLTFWriter {
 
 		constructor() {
@@ -402,7 +409,7 @@
 			if ( options.binary === true ) {
 
 				// https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-file-format-specification
-				const reader = new window.FileReader();
+				const reader = new FileReader();
 				reader.readAsArrayBuffer( blob );
 
 				reader.onloadend = function () {
@@ -427,7 +434,7 @@
 					const glbBlob = new Blob( [ header, jsonChunkPrefix, jsonChunk, binaryChunkPrefix, binaryChunk ], {
 						type: 'application/octet-stream'
 					} );
-					const glbReader = new window.FileReader();
+					const glbReader = new FileReader();
 					glbReader.readAsArrayBuffer( glbBlob );
 
 					glbReader.onloadend = function () {
@@ -442,7 +449,7 @@
 
 				if ( json.buffers && json.buffers.length > 0 ) {
 
-					const reader = new window.FileReader();
+					const reader = new FileReader();
 					reader.readAsDataURL( blob );
 
 					reader.onloadend = function () {
@@ -634,7 +641,7 @@
 			const roughness = roughnessMap?.image;
 			const width = Math.max( metalness?.width || 0, roughness?.width || 0 );
 			const height = Math.max( metalness?.height || 0, roughness?.height || 0 );
-			const canvas = document.createElement( 'canvas' );
+			const canvas = getCanvas();
 			canvas.width = width;
 			canvas.height = height;
 			const context = canvas.getContext( '2d' );
@@ -810,7 +817,7 @@
 			if ( ! json.bufferViews ) json.bufferViews = [];
 			return new Promise( function ( resolve ) {
 
-				const reader = new window.FileReader();
+				const reader = new FileReader();
 				reader.readAsArrayBuffer( blob );
 
 				reader.onloadend = function () {
@@ -942,7 +949,7 @@
 
 			if ( options.embedImages ) {
 
-				const canvas = cachedCanvas = cachedCanvas || document.createElement( 'canvas' );
+				const canvas = getCanvas();
 				canvas.width = Math.min( image.width, options.maxTextureSize );
 				canvas.height = Math.min( image.height, options.maxTextureSize );
 				const ctx = canvas.getContext( '2d' );
@@ -954,12 +961,9 @@
 
 				}
 
-				if ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof OffscreenCanvas !== 'undefined' && image instanceof OffscreenCanvas || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) {
-
-					ctx.drawImage( image, 0, 0, canvas.width, canvas.height );
-
-				} else {
+				if ( image.data !== undefined ) {
 
+					// THREE.DataTexture
 					if ( format !== THREE.RGBAFormat ) {
 
 						console.error( 'GLTFExporter: Only THREE.RGBAFormat is supported.' );
@@ -985,24 +989,33 @@
 
 					ctx.putImageData( new ImageData( data, image.width, image.height ), 0, 0 );
 
+				} else {
+
+					ctx.drawImage( image, 0, 0, canvas.width, canvas.height );
+
 				}
 
 				if ( options.binary === true ) {
 
-					pending.push( new Promise( function ( resolve ) {
+					let toBlobPromise;
 
-						canvas.toBlob( function ( blob ) {
+					if ( canvas.toBlob !== undefined ) {
 
-							writer.processBufferViewImage( blob ).then( function ( bufferViewIndex ) {
+						toBlobPromise = new Promise( resolve => canvas.toBlob( resolve, mimeType ) );
 
-								imageDef.bufferView = bufferViewIndex;
-								resolve();
+					} else {
+
+						toBlobPromise = canvas.convertToBlob( {
+							type: mimeType
+						} );
+
+					}
 
-							} );
+					pending.push( toBlobPromise.then( blob => writer.processBufferViewImage( blob ).then( bufferViewIndex => {
 
-						}, mimeType );
+						imageDef.bufferView = bufferViewIndex;
 
-					} ) );
+					} ) ) );
 
 				} else {
 

+ 47 - 1
examples/js/loaders/GLTFLoader.js

@@ -43,6 +43,11 @@
 
 				return new GLTFMaterialsIorExtension( parser );
 
+			} );
+			this.register( function ( parser ) {
+
+				return new GLTFMaterialsEmissiveStrengthExtension( parser );
+
 			} );
 			this.register( function ( parser ) {
 
@@ -360,6 +365,7 @@
 		KHR_TEXTURE_BASISU: 'KHR_texture_basisu',
 		KHR_TEXTURE_TRANSFORM: 'KHR_texture_transform',
 		KHR_MESH_QUANTIZATION: 'KHR_mesh_quantization',
+		KHR_MATERIALS_EMISSIVE_STRENGTH: 'KHR_materials_emissive_strength',
 		EXT_TEXTURE_WEBP: 'EXT_texture_webp',
 		EXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression'
 	};
@@ -528,6 +534,46 @@
 
 		}
 
+	}
+	/**
+ * Materials Emissive Strength Extension
+ *
+ * Specification: https://github.com/KhronosGroup/glTF/blob/5768b3ce0ef32bc39cdf1bef10b948586635ead3/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md
+ */
+
+
+	class GLTFMaterialsEmissiveStrengthExtension {
+
+		constructor( parser ) {
+
+			this.parser = parser;
+			this.name = EXTENSIONS.KHR_MATERIALS_EMISSIVE_STRENGTH;
+
+		}
+
+		extendMaterialParams( materialIndex, materialParams ) {
+
+			const parser = this.parser;
+			const materialDef = parser.json.materials[ materialIndex ];
+
+			if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
+
+				return Promise.resolve();
+
+			}
+
+			const emissiveStrength = materialDef.extensions[ this.name ].emissiveStrength;
+
+			if ( emissiveStrength !== undefined ) {
+
+				materialParams.emissiveIntensity = emissiveStrength;
+
+			}
+
+			return Promise.resolve();
+
+		}
+
 	}
 	/**
  * Clearcoat Materials Extension
@@ -1521,7 +1567,7 @@
 			material.aoMap = materialParams.aoMap === undefined ? null : materialParams.aoMap;
 			material.aoMapIntensity = 1.0;
 			material.emissive = materialParams.emissive;
-			material.emissiveIntensity = 1.0;
+			material.emissiveIntensity = materialParams.emissiveIntensity === undefined ? 1.0 : materialParams.emissiveIntensity;
 			material.emissiveMap = materialParams.emissiveMap === undefined ? null : materialParams.emissiveMap;
 			material.bumpMap = materialParams.bumpMap === undefined ? null : materialParams.bumpMap;
 			material.bumpScale = 1;

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

@@ -196,6 +196,8 @@
 			vec4 base = texture2DProj( tDiffuse, vUv );
 			gl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 );
 
+			#include <encodings_fragment>
+
 		}`
 	};
 

+ 2 - 0
examples/js/objects/Refractor.js

@@ -244,6 +244,8 @@
 			vec4 base = texture2DProj( tDiffuse, vUv );
 			gl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 );
 
+			#include <encodings_fragment>
+
 		}`
 	};