瀏覽代碼

TransformControls: Separated the logic that handles mouse events from the event listeners.

Aki Rodic 7 年之前
父節點
當前提交
b86357766e
共有 1 個文件被更改,包括 110 次插入109 次删除
  1. 110 109
      examples/js/controls/TransformControls.js

+ 110 - 109
examples/js/controls/TransformControls.js

@@ -39,8 +39,7 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 	// Reusable utility variables
 
-	var _ray = new THREE.Raycaster();
-	var _pointerVector = new THREE.Vector2();
+	var ray = new THREE.Raycaster();
 
 	var _tempVector = new THREE.Vector3();
 	var _tempVector2 = new THREE.Vector3();
@@ -148,7 +147,6 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 	};
 
-
 	// Defined getter, setter and store for a property
 	function defineProperty( propName, defaultValue ) {
 
@@ -212,117 +210,89 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 	};
 
-	function onContext( event ) {
-
-		event.preventDefault();
-
-	}
+	this.pointerHover = function( pointer ) {
 
-	function onPointerHover( event ) {
+		if ( this.object === undefined || this.dragging === true || ( pointer.button !== undefined && pointer.button !== 0 ) ) return;
 
-		if ( scope.object === undefined || scope.dragging === true || ( event.button !== undefined && event.button !== 0 ) ) return;
+		ray.setFromCamera( pointer, this.camera );
 
-		var pointer = event.changedTouches ? event.changedTouches[ 0 ] : event;
-
-		var intersect = intersectObjects( pointer, _gizmo.picker[ scope.mode ].children, scope.camera );
+		var intersect = ray.intersectObjects( _gizmo.picker[ this.mode ].children, true )[ 0 ] || false;
 
 		if ( intersect ) {
 
-			scope.axis = intersect.object.name;
-
-			event.preventDefault();
+			this.axis = intersect.object.name;
 
 		} else {
 
-			scope.axis = null;
+			this.axis = null;
 
 		}
 
 	}
 
-	function onPointerDown( event ) {
-
-		if ( scope.object === undefined || scope.dragging === true || ( event.button !== undefined && event.button !== 0 ) ) return;
-
-		var pointer = event.changedTouches ? event.changedTouches[ 0 ] : event;
-
-		if ( pointer.button === 0 || pointer.button === undefined ) {
+	this.pointerDown = function( pointer ) {
 
-			var intersect = intersectObjects( pointer, _gizmo.picker[ scope.mode ].children, scope.camera );
+		if ( this.object === undefined || this.dragging === true || ( pointer.button !== undefined && pointer.button !== 0 ) ) return;
 
-			if ( intersect ) {
+		if ( ( pointer.button === 0 || pointer.button === undefined ) && this.axis !== null ) {
 
-				event.preventDefault();
-				event.stopPropagation();
+			ray.setFromCamera( pointer, this.camera );
 
-				scope.axis = intersect.object.name;
+			var planeIntersect = ray.intersectObjects( [ _plane ], true )[ 0 ] || false;
 
-				var planeIntersect = intersectObjects( pointer, [ _plane ], scope.camera );
+			if ( planeIntersect ) {
 
-				if ( planeIntersect ) {
+				var space = this.space;
 
-					var space = scope.space;
+				if ( this.mode === 'scale') {
 
-					if ( scope.mode === 'scale') {
+					space = 'local';
 
-						space = 'local';
-
-					} else if ( scope.axis === 'E' ||  scope.axis === 'XYZE' ||  scope.axis === 'XYZ' ) {
-
-						space = 'world';
-
-					}
+				} else if ( this.axis === 'E' ||  this.axis === 'XYZE' ||  this.axis === 'XYZ' ) {
 
-					if ( space === 'local' && scope.mode === 'rotate' ) {
+					space = 'world';
 
-						var snap = scope.rotationSnap;
-
-						if ( scope.axis === 'X' && snap ) scope.object.rotation.x = Math.round( scope.object.rotation.x / snap ) * snap;
-						if ( scope.axis === 'Y' && snap ) scope.object.rotation.y = Math.round( scope.object.rotation.y / snap ) * snap;
-						if ( scope.axis === 'Z' && snap ) scope.object.rotation.z = Math.round( scope.object.rotation.z / snap ) * snap;
-
-					}
-
-					scope.object.updateMatrixWorld();
-					scope.object.parent.updateMatrixWorld();
-
-					_positionStart.copy( scope.object.position );
-					_quaternionStart.copy( scope.object.quaternion );
-					_scaleStart.copy( scope.object.scale );
+				}
 
-					scope.object.matrixWorld.decompose( worldPositionStart, worldQuaternionStart, worldScaleStart );
+				if ( space === 'local' && this.mode === 'rotate' ) {
 
-					pointStart.copy( planeIntersect.point ).sub( worldPositionStart );
+					var snap = this.rotationSnap;
 
-					if ( space === 'local' ) pointStart.applyQuaternion( worldQuaternionStart.clone().inverse() );
+					if ( this.axis === 'X' && snap ) this.object.rotation.x = Math.round( this.object.rotation.x / snap ) * snap;
+					if ( this.axis === 'Y' && snap ) this.object.rotation.y = Math.round( this.object.rotation.y / snap ) * snap;
+					if ( this.axis === 'Z' && snap ) this.object.rotation.z = Math.round( this.object.rotation.z / snap ) * snap;
 
 				}
 
-			} else {
+				this.object.updateMatrixWorld();
+				this.object.parent.updateMatrixWorld();
 
-				scope.axis = null;
+				_positionStart.copy( this.object.position );
+				_quaternionStart.copy( this.object.quaternion );
+				_scaleStart.copy( this.object.scale );
 
-			}
+				this.object.matrixWorld.decompose( worldPositionStart, worldQuaternionStart, worldScaleStart );
 
-		}
+				pointStart.copy( planeIntersect.point ).sub( worldPositionStart );
 
-		scope.dragging = true;
+				if ( space === 'local' ) pointStart.applyQuaternion( worldQuaternionStart.clone().inverse() );
 
-		if ( scope.axis !== null ) {
+			}
 
-			mouseDownEvent.mode = scope.mode;
-			scope.dispatchEvent( mouseDownEvent );
+			this.dragging = true;
+			mouseDownEvent.mode = this.mode;
+			this.dispatchEvent( mouseDownEvent );
 
 		}
 
 	}
 
-	function onPointerMove( event ) {
+	this.pointerMove = function( pointer ) {
 
-		var axis = scope.axis;
-		var mode = scope.mode;
-		var object = scope.object;
-		var space = scope.space;
+		var axis = this.axis;
+		var mode = this.mode;
+		var object = this.object;
+		var space = this.space;
 
 		if ( mode === 'scale') {
 
@@ -334,17 +304,14 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 		}
 
-		if ( object === undefined || axis === null || scope.dragging === false || ( event.button !== undefined && event.button !== 0 ) ) return;
+		if ( object === undefined || axis === null || this.dragging === false || ( pointer.button !== undefined && pointer.button !== 0 ) ) return;
 
-		var pointer = event.changedTouches ? event.changedTouches[ 0 ] : event;
+		ray.setFromCamera( pointer, this.camera );
 
-		var planeIntersect = intersectObjects( pointer, [ _plane ], scope.camera );
+		var planeIntersect = ray.intersectObjects( [ _plane ], true )[ 0 ] || false;
 
 		if ( planeIntersect === false ) return;
 
-		event.preventDefault();
-		event.stopPropagation();
-
 		pointEnd.copy( planeIntersect.point ).sub( worldPositionStart );
 
 		if ( space === 'local' ) pointEnd.applyQuaternion( worldQuaternionStart.clone().inverse() );
@@ -373,22 +340,22 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 			// Apply translation snap
 
-			if ( scope.translationSnap ) {
+			if ( this.translationSnap ) {
 
 				if ( space === 'local' ) {
 
 					object.position.applyQuaternion(_tempQuaternion.copy( _quaternionStart ).inverse() );
 
 					if ( axis.search( 'X' ) !== -1 ) {
-						object.position.x = Math.round( object.position.x / scope.translationSnap ) * scope.translationSnap;
+						object.position.x = Math.round( object.position.x / this.translationSnap ) * this.translationSnap;
 					}
 
 					if ( axis.search( 'Y' ) !== -1 ) {
-						object.position.y = Math.round( object.position.y / scope.translationSnap ) * scope.translationSnap;
+						object.position.y = Math.round( object.position.y / this.translationSnap ) * this.translationSnap;
 					}
 
 					if ( axis.search( 'Z' ) !== -1 ) {
-						object.position.z = Math.round( object.position.z / scope.translationSnap ) * scope.translationSnap;
+						object.position.z = Math.round( object.position.z / this.translationSnap ) * this.translationSnap;
 					}
 
 					object.position.applyQuaternion( _quaternionStart );
@@ -402,15 +369,15 @@ THREE.TransformControls = function ( camera, domElement ) {
 					}
 
 					if ( axis.search( 'X' ) !== -1 ) {
-						object.position.x = Math.round( object.position.x / scope.translationSnap ) * scope.translationSnap;
+						object.position.x = Math.round( object.position.x / this.translationSnap ) * this.translationSnap;
 					}
 
 					if ( axis.search( 'Y' ) !== -1 ) {
-						object.position.y = Math.round( object.position.y / scope.translationSnap ) * scope.translationSnap;
+						object.position.y = Math.round( object.position.y / this.translationSnap ) * this.translationSnap;
 					}
 
 					if ( axis.search( 'Z' ) !== -1 ) {
-						object.position.z = Math.round( object.position.z / scope.translationSnap ) * scope.translationSnap;
+						object.position.z = Math.round( object.position.z / this.translationSnap ) * this.translationSnap;
 					}
 
 					if ( object.parent ) {
@@ -453,9 +420,9 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 		} else if ( mode === 'rotate' ) {
 
-			var LINEAR_ROTATION_SPEED = 10 / worldPosition.distanceTo( _tempVector.setFromMatrixPosition( scope.camera.matrixWorld ) );
+			var LINEAR_ROTATION_SPEED = 10 / worldPosition.distanceTo( _tempVector.setFromMatrixPosition( this.camera.matrixWorld ) );
 
-			var quaternion = scope.space === "local" ? worldQuaternion : _identityQuaternion;
+			var quaternion = this.space === "local" ? worldQuaternion : _identityQuaternion;
 
 			var unit = _unit[ axis ];
 
@@ -503,7 +470,7 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 			// Apply rotation snap
 
-			if ( scope.rotationSnap ) rotationAngle = Math.round( rotationAngle / scope.rotationSnap ) * scope.rotationSnap;
+			if ( this.rotationSnap ) rotationAngle = Math.round( rotationAngle / this.rotationSnap ) * this.rotationSnap;
 
 			this.rotationAngle = rotationAngle;
 
@@ -523,50 +490,84 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 		}
 
-		scope.dispatchEvent( changeEvent );
-		scope.dispatchEvent( objectChangeEvent );
+		this.dispatchEvent( changeEvent );
+		this.dispatchEvent( objectChangeEvent );
 
 	}
 
-	function onPointerUp( event ) {
-
-		event.preventDefault(); // Prevent MouseEvent on mobile
+	this.pointerUp = function( pointer ) {
 
-		if ( event.button !== undefined && event.button !== 0 ) return;
+		if ( pointer.button !== undefined && pointer.button !== 0 ) return;
 
-		if ( scope.dragging && ( scope.axis !== null ) ) {
+		if ( this.dragging && ( this.axis !== null ) ) {
 
-			mouseUpEvent.mode = scope.mode;
-			scope.dispatchEvent( mouseUpEvent );
+			mouseUpEvent.mode = this.mode;
+			this.dispatchEvent( mouseUpEvent );
 
 		}
 
-		scope.dragging = false;
+		this.dragging = false;
 
-		if ( 'TouchEvent' in window && event instanceof TouchEvent ) {
+		if ( pointer.button === undefined ) this.axis = null;
 
-			scope.axis = null; // Force "rollover"
+	}
 
-		} else {
+	// normalize mouse / touch pointer and remap {x,y} to view space.
+
+	function getPointer( event ) {
+
+		var pointer = event.changedTouches ? event.changedTouches[ 0 ] : event;
 
-			onPointerHover( event );
+		var rect = domElement.getBoundingClientRect();
 
+		return {
+			x: ( pointer.clientX - rect.left ) / rect.width * 2 - 1,
+			y: - ( pointer.clientY - rect.top ) / rect.height * 2 + 1,
+			button: event.button
 		}
 
 	}
 
-	function intersectObjects( pointer, objects, camera ) {
+	// mouse / touch event handlers
 
-		var rect = domElement.getBoundingClientRect();
-		var x = ( pointer.clientX - rect.left ) / rect.width;
-		var y = ( pointer.clientY - rect.top ) / rect.height;
+	function onContext( event ) {
 
-		_pointerVector.set( ( x * 2 ) - 1, - ( y * 2 ) + 1 );
-		_ray.setFromCamera( _pointerVector, camera );
+		event.preventDefault();
 
-		var intersections = _ray.intersectObjects( objects, true );
+	}
+
+	function onPointerHover( event ) {
+
+		// event.preventDefault();
+
+		scope.pointerHover( getPointer( event ) );
+
+	}
+
+	function onPointerDown( event ) {
+
+		event.preventDefault();
+		event.stopPropagation();
+
+		scope.pointerHover( getPointer( event ) );
+		scope.pointerDown( getPointer( event ) );
+
+	}
+
+	function onPointerMove( event ) {
+
+		event.preventDefault();
+		event.stopPropagation();
+
+		scope.pointerMove( getPointer( event ) );
+
+	}
+
+	function onPointerUp( event ) {
+
+		event.preventDefault(); // Prevent MouseEvent on mobile
 
-		return intersections[ 0 ] ? intersections[ 0 ] : false;
+		scope.pointerUp( getPointer( event ) );
 
 	}