浏览代码

added touch support for transform controls
improved touch support for editor controls

Aleksandar Rodic 12 年之前
父节点
当前提交
3eff5909d8
共有 3 个文件被更改,包括 220 次插入196 次删除
  1. 4 11
      editor/js/Viewport.js
  2. 42 18
      examples/js/controls/EditorControls.js
  3. 174 167
      examples/js/controls/TransformControls.js

+ 4 - 11
editor/js/Viewport.js

@@ -43,8 +43,9 @@ var Viewport = function ( editor ) {
 	var transformControls = new THREE.TransformControls( camera, container.dom );
 	transformControls.addEventListener( 'change', function () {
 
-		// TODO: Differentiate from transform hovers change and object transform change
-
+        controls.enabled = true;
+        if ( transformControls.axis ) controls.enabled = false;
+        
 		if (editor.selected) signals.objectChanged.dispatch( editor.selected );
 
 	} );
@@ -98,12 +99,7 @@ var Viewport = function ( editor ) {
 	    y = (event.clientY - rect.top) / rect.height;
 		onMouseDownPosition.set( x, y );
 
-		if ( transformControls.hovered === false ) {
-
-			controls.enabled = true;
-			document.addEventListener( 'mouseup', onMouseUp, false );
-
-		}
+		document.addEventListener( 'mouseup', onMouseUp, false );
 
 	};
 
@@ -144,8 +140,6 @@ var Viewport = function ( editor ) {
 
 		}
 
-		controls.enabled = false;
-
 		document.removeEventListener( 'mouseup', onMouseUp );
 
 	};
@@ -175,7 +169,6 @@ var Viewport = function ( editor ) {
 		signals.objectChanged.dispatch( camera );
 
 	} );
-	controls.enabled = false;
 
 	// signals
 

+ 42 - 18
examples/js/controls/EditorControls.js

@@ -193,29 +193,37 @@ THREE.EditorControls = function ( object, domElement ) {
 	// touch
 
 	var touch = new THREE.Vector3();
-	var prevTouch = new THREE.Vector3();
+
+	var touches = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
+	var prevTouches = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
+
 	var prevDistance = null;
 
 	function touchStart( event ) {
 
 		if ( scope.enabled === false ) return;
 
-		var touches = event.touches;
+		switch ( event.touches.length ) {
 
-		switch ( touches.length ) {
+			case 1:
+				touches[ 0 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 );
+				touches[ 1 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 );
+				break;
 
 			case 2:
-				var dx = touches[ 0 ].pageX - touches[ 1 ].pageX;
-				var dy = touches[ 0 ].pageY - touches[ 1 ].pageY;
-				prevDistance = Math.sqrt( dx * dx + dy * dy );
+				touches[ 0 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 );
+				touches[ 1 ].set( event.touches[ 1 ].pageX, event.touches[ 1 ].pageY, 0 );
+				prevDistance = touches[ 0 ].distanceTo( touches[ 1 ] );
 				break;
 
 		}
 
-		prevTouch.set( touches[ 0 ].pageX, touches[ 0 ].pageY, 0 );
+		prevTouches[ 0 ].copy( touches[ 0 ] );
+		prevTouches[ 1 ].copy( touches[ 1 ] );
 
 	}
 
+
 	function touchMove( event ) {
 
 		if ( scope.enabled === false ) return;
@@ -223,31 +231,47 @@ THREE.EditorControls = function ( object, domElement ) {
 		event.preventDefault();
 		event.stopPropagation();
 
-		var touches = event.touches;
+		var getClosest = function( touch, touches ) {
+
+			var closest = touches[ 0 ];
 
-		touch.set( touches[ 0 ].pageX, touches[ 0 ].pageY, 0 );
+			for ( var i in touches ) {
+				if ( closest.distanceTo(touch) > touches[ i ].distanceTo(touch) ) closest = touches[ i ];
+			}
 
-		switch ( touches.length ) {
+			return closest;
+
+		}
+
+		switch ( event.touches.length ) {
 
 			case 1:
-				scope.rotate( touch.sub( prevTouch ).multiplyScalar( - 0.005 ) );
+				touches[ 0 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 );
+				touches[ 1 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 );
+				scope.rotate( touches[ 0 ].sub( getClosest( touches[ 0 ] ,prevTouches ) ).multiplyScalar( - 0.005 ) );
 				break;
 
 			case 2:
-				var dx = touches[ 0 ].pageX - touches[ 1 ].pageX;
-				var dy = touches[ 0 ].pageY - touches[ 1 ].pageY;
-				var distance = Math.sqrt( dx * dx + dy * dy );
+				touches[ 0 ].set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, 0 );
+				touches[ 1 ].set( event.touches[ 1 ].pageX, event.touches[ 1 ].pageY, 0 );
+				distance = touches[ 0 ].distanceTo( touches[ 1 ] );
 				scope.zoom( new THREE.Vector3( 0, 0, prevDistance - distance ) );
 				prevDistance = distance;
-				break;
 
-			case 3:
-				scope.pan( touch.sub( prevTouch ).setX( - touch.x ) );
+
+				var offset0 = touches[ 0 ].clone().sub( getClosest( touches[ 0 ] ,prevTouches ) );
+				var offset1 = touches[ 1 ].clone().sub( getClosest( touches[ 1 ] ,prevTouches ) );
+				offset0.x = -offset0.x;
+				offset1.x = -offset1.x;
+
+				scope.pan( offset0.add( offset1 ).multiplyScalar( 0.5 ) );
+
 				break;
 
 		}
 
-		prevTouch.set( touches[ 0 ].pageX, touches[ 0 ].pageY, 0 );
+		prevTouches[ 0 ].copy( touches[ 0 ] );
+		prevTouches[ 1 ].copy( touches[ 1 ] );
 
 	}
 

+ 174 - 167
examples/js/controls/TransformControls.js

@@ -165,7 +165,7 @@ THREE.TransformGizmo = function () {
 
 		}
 
-		if ( axis ) {
+		if ( this.handleGizmos[ axis ] ) {
 		
 			handle = this.handleGizmos[ axis ][0];
 
@@ -253,7 +253,7 @@ THREE.TransformGizmoTranslate = function () {
 		XZ: [
 			new THREE.Mesh( new THREE.PlaneGeometry( 0.29, 0.29 ), new THREE.TransformGizmoMaterial( { color: "magenta", opacity: 0.25 } ) ),
 			new THREE.Vector3( 0.15, 0, 0.15 ),
-			new THREE.Vector3( Math.PI/2, 0, 0 )
+			new THREE.Vector3( -Math.PI/2, 0, 0 )
 		]
 
 	}
@@ -556,16 +556,15 @@ THREE.TransformControls = function ( camera, domElement ) {
 	this.gizmo["rotate"].hide();
 	this.gizmo["scale"].hide();
 
-	this.hovered = false;
+	this.object = false;
 	this.snap = false;
 	this.space = "world";
 	this.size = 1;
+	this.axis = false;
 
 	var scope = this;
 	
-	var _object = null;
-
-	var _axis = false;
+	var _dragging = false;
 	var _mode = "translate";
 	var _plane = "XY";
 
@@ -611,9 +610,24 @@ THREE.TransformControls = function ( camera, domElement ) {
 	var camPosition = new THREE.Vector3();
 	var camRotation = new THREE.Euler();
 
+	domElement.addEventListener( "mousedown", onPointerDown, false );
+	domElement.addEventListener( "touchstart", onPointerDown, false );
+
+	domElement.addEventListener( "mousemove", onPointerHover, false );
+	domElement.addEventListener( "touchmove", onPointerHover, false );
+
+	domElement.addEventListener( "mousemove", onPointerMove, false );
+	domElement.addEventListener( "touchmove", onPointerMove, false );
+
+	domElement.addEventListener( "mouseup", onPointerUp, false );
+	domElement.addEventListener( "mouseout", onPointerUp, false );
+	domElement.addEventListener( "touchend", onPointerUp, false );
+	domElement.addEventListener( "touchcancel", onPointerUp, false );
+	domElement.addEventListener( "touchleave", onPointerUp, false );
+
 	this.attach = function ( object ) {
 
-		_object = object;
+		scope.object = object;
 
 	 	this.gizmo["translate"].hide();
 	 	this.gizmo["rotate"].hide();
@@ -621,24 +635,19 @@ THREE.TransformControls = function ( camera, domElement ) {
 	 	this.gizmo[_mode].show();
 
 	 	scope.dispatchEvent( changeEvent );
-
-		domElement.addEventListener( "mousedown", onMouseDown, false );
-		domElement.addEventListener( "mousemove", onMouseHover, false );
+	 	scope.update();
 
 	}
 
 	this.detach = function ( object ) {
 
-		_object = null;
-		this.hovered = false;
+		scope.object = false;
+		this.axis = false;
 
 	 	this.gizmo["translate"].hide();
 	 	this.gizmo["rotate"].hide();
 	 	this.gizmo["scale"].hide();
 
-		domElement.removeEventListener( "mousedown", onMouseDown, false );
-		domElement.removeEventListener( "mousemove", onMouseHover, false );
-
 	}
 
 	this.setMode = function ( mode ) {
@@ -652,8 +661,8 @@ THREE.TransformControls = function ( camera, domElement ) {
 	 	this.gizmo["scale"].hide();	
 	 	this.gizmo[_mode].show();
 
-		this.update();
 	 	scope.dispatchEvent( changeEvent );
+		this.update();
 
 	}
 
@@ -666,8 +675,8 @@ THREE.TransformControls = function ( camera, domElement ) {
 	this.setSize = function ( size ) {
 
 		scope.size = size;
-		this.update();
 	 	scope.dispatchEvent( changeEvent );
+		this.update();
 	 	
 	}
 
@@ -675,18 +684,18 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 		scope.space = space;
 
-		this.update();
 	 	scope.dispatchEvent( changeEvent );
+		this.update();
 
 	}
 
 	this.update = function () {
 
-		if ( _object === null ) return;
+		if ( !scope.object ) return;
 
-		_object.updateMatrixWorld();
-		worldPosition.getPositionFromMatrix( _object.matrixWorld );
-		worldRotation.setFromRotationMatrix( tempMatrix.extractRotation( _object.matrixWorld ) );
+		scope.object.updateMatrixWorld();
+		worldPosition.getPositionFromMatrix( scope.object.matrixWorld );
+		worldRotation.setFromRotationMatrix( tempMatrix.extractRotation( scope.object.matrixWorld ) );
 
 		camera.updateMatrixWorld();
 		camPosition.getPositionFromMatrix( camera.matrixWorld );
@@ -704,74 +713,72 @@ THREE.TransformControls = function ( camera, domElement ) {
 		else if ( scope.space == "world" )
 			this.gizmo[_mode].update( new THREE.Euler(), eye );
 
-		
+		this.gizmo[_mode].highlight( scope.axis );
 
 	}
 
-	function onMouseHover( event ) {
-
-		event.preventDefault();
-
-		if ( _axis === false ) {
-
-			var intersect = intersectObjects( event, scope.gizmo[_mode].pickers.children );
-
-			if ( intersect ) {
-
-				if ( scope.hovered !== intersect.object ) {
-
-					scope.hovered = intersect.object;
+	function onPointerHover( event ) {
 
-					scope.gizmo[_mode].highlight( scope.hovered.name );
+		if ( !scope.object || _dragging ) return;
 
-					scope.dispatchEvent( changeEvent );
+		event.preventDefault();
+		event.stopPropagation();
 
-				}
+		var pointer = event.touches? event.touches[0] : event;
 
-			} else if ( scope.hovered !== false ) {
+		var intersect = intersectObjects( pointer, scope.gizmo[_mode].pickers.children );
 
-				scope.hovered = false;
+		if ( intersect ) {
 
-				scope.gizmo[_mode].highlight();
+			scope.axis = intersect.object.name;
+			scope.dispatchEvent( changeEvent );
+			scope.update();
 
-				scope.dispatchEvent( changeEvent );
+		} else {
 
-			}
+			scope.axis = false;
+			scope.dispatchEvent( changeEvent );
+			scope.update();
 
 		}
 
 	};
 
-	function onMouseDown( event ) {
+	function onPointerDown( event ) {
+
+		if ( !scope.object || _dragging ) return;
 
 		event.preventDefault();
+		event.stopPropagation();
+
+		var pointer = event.touches? event.touches[0] : event;
 
-		if ( event.button === 0 ) {
+		if ( pointer.button === 0 || pointer.button == undefined ) {
 
-			var intersect = intersectObjects( event, scope.gizmo[_mode].pickers.children );
+			var intersect = intersectObjects( pointer, scope.gizmo[_mode].pickers.children );
 
 			if ( intersect ) {
 
-				_axis = intersect.object.name;
+				scope.axis = intersect.object.name;
 
 				scope.update();
 
 				eye.copy( camPosition ).sub( worldPosition ).normalize();
 
-				scope.gizmo[_mode].setActivePlane( _axis, eye );
+				scope.gizmo[_mode].setActivePlane( scope.axis, eye );
 
-				var planeIntersect = intersectObjects( event, [scope.gizmo[_mode].activePlane] );
+				var planeIntersect = intersectObjects( pointer, [scope.gizmo[_mode].activePlane] );
 
 				if ( planeIntersect ) {
 
-					oldPosition.copy( _object.position );
-					oldScale.copy( _object.scale );
+					oldPosition.copy( scope.object.position );
+					oldScale.copy( scope.object.scale );
 
-					oldRotationMatrix.extractRotation( _object.matrix );
-					worldRotationMatrix.extractRotation( _object.matrixWorld );
+					oldRotationMatrix.extractRotation( scope.object.matrix );
+					worldRotationMatrix.extractRotation( scope.object.matrixWorld );
 
-					parentRotationMatrix.extractRotation( _object.parent.matrixWorld );
-					parentScale.getScaleFromMatrix( tempMatrix.getInverse( _object.parent.matrixWorld ) );
+					parentRotationMatrix.extractRotation( scope.object.parent.matrixWorld );
+					parentScale.getScaleFromMatrix( tempMatrix.getInverse( scope.object.parent.matrixWorld ) );
 
 					offset.copy( planeIntersect.point );
 
@@ -781,196 +788,196 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 		}
 
-		domElement.addEventListener( "mousemove", onMouseMove, false );
-		domElement.addEventListener( "mouseup", onMouseUp, false );
-		domElement.addEventListener( "mouseout", onMouseUp, false );
+		_dragging = true;
 
 	};
 
-	function onMouseMove( event ) {
+	function onPointerMove( event ) {
 
-		if ( _axis ) {
+		if ( !scope.object || !scope.axis || !_dragging ) return;
 
-			var planeIntersect = intersectObjects( event, [scope.gizmo[_mode].activePlane] );
+		event.preventDefault();
+		event.stopPropagation();
 
-			if ( planeIntersect ) {
+		var pointer = event.touches? event.touches[0] : event;
 
-				point.copy( planeIntersect.point );
+		var planeIntersect = intersectObjects( pointer, [scope.gizmo[_mode].activePlane] );
 
-				if ( _mode == "translate" ) {
+		if ( planeIntersect ) {
 
-					point.sub( offset );
-					point.multiply(parentScale);
+			point.copy( planeIntersect.point );
 
-					if ( scope.space == "local" ) {
+			if ( _mode == "translate" ) {
 
-						point.applyMatrix4( tempMatrix.getInverse( worldRotationMatrix ) );
+				point.sub( offset );
+				point.multiply(parentScale);
+
+				if ( scope.space == "local" ) {
 
-						if ( _axis.search("X") == -1 ) point.x = 0;
-						if ( _axis.search("Y") == -1 ) point.y = 0;
-						if ( _axis.search("Z") == -1 ) point.z = 0;
+					point.applyMatrix4( tempMatrix.getInverse( worldRotationMatrix ) );
 
-						point.applyMatrix4( oldRotationMatrix );
+					if ( scope.axis.search("X") == -1 ) point.x = 0;
+					if ( scope.axis.search("Y") == -1 ) point.y = 0;
+					if ( scope.axis.search("Z") == -1 ) point.z = 0;
 
-						_object.position.copy( oldPosition );
-						_object.position.add( point );
+					point.applyMatrix4( oldRotationMatrix );
 
-					} 
+					scope.object.position.copy( oldPosition );
+					scope.object.position.add( point );
 
-					if ( scope.space == "world" || _axis.search("XYZ") != -1 ) {
+				} 
 
-						if ( _axis.search("X") == -1 ) point.x = 0;
-						if ( _axis.search("Y") == -1 ) point.y = 0;
-						if ( _axis.search("Z") == -1 ) point.z = 0;
+				if ( scope.space == "world" || scope.axis.search("XYZ") != -1 ) {
 
-						point.applyMatrix4( tempMatrix.getInverse( parentRotationMatrix ) );
+					if ( scope.axis.search("X") == -1 ) point.x = 0;
+					if ( scope.axis.search("Y") == -1 ) point.y = 0;
+					if ( scope.axis.search("Z") == -1 ) point.z = 0;
 
-						_object.position.copy( oldPosition );
-						_object.position.add( point );
+					point.applyMatrix4( tempMatrix.getInverse( parentRotationMatrix ) );
 
-						if ( scope.snap ) {
+					scope.object.position.copy( oldPosition );
+					scope.object.position.add( point );
 
-							if ( _axis.search("X") != -1 ) _object.position.x = Math.round( _object.position.x / scope.snap ) * scope.snap;
-							if ( _axis.search("Y") != -1 ) _object.position.y = Math.round( _object.position.y / scope.snap ) * scope.snap;
-							if ( _axis.search("Z") != -1 ) _object.position.z = Math.round( _object.position.z / scope.snap ) * scope.snap;
-						
-						}
+					if ( scope.snap ) {
 
+						if ( scope.axis.search("X") != -1 ) scope.object.position.x = Math.round( scope.object.position.x / scope.snap ) * scope.snap;
+						if ( scope.axis.search("Y") != -1 ) scope.object.position.y = Math.round( scope.object.position.y / scope.snap ) * scope.snap;
+						if ( scope.axis.search("Z") != -1 ) scope.object.position.z = Math.round( scope.object.position.z / scope.snap ) * scope.snap;
+					
 					}
 
-				} else if ( _mode == "scale" ) {
+				}
 
-					point.sub( offset );
-					point.multiply(parentScale);
+			} else if ( _mode == "scale" ) {
 
-					if ( scope.space == "local" ) {
+				point.sub( offset );
+				point.multiply(parentScale);
 
-						if ( _axis == "XYZ") {
+				if ( scope.space == "local" ) {
 
-							scale = 1 + ( ( point.y ) / 50 );
+					if ( scope.axis == "XYZ") {
 
-							_object.scale.x = oldScale.x * scale;
-							_object.scale.y = oldScale.y * scale;
-							_object.scale.z = oldScale.z * scale;
+						scale = 1 + ( ( point.y ) / 50 );
 
-						} else {
+						scope.object.scale.x = oldScale.x * scale;
+						scope.object.scale.y = oldScale.y * scale;
+						scope.object.scale.z = oldScale.z * scale;
 
-							point.applyMatrix4( tempMatrix.getInverse( worldRotationMatrix ) );
+					} else {
 
-							if ( _axis == "X" ) _object.scale.x = oldScale.x * ( 1 + point.x / 50 );
-							if ( _axis == "Y" ) _object.scale.y = oldScale.y * ( 1 + point.y / 50 );
-							if ( _axis == "Z" ) _object.scale.z = oldScale.z * ( 1 + point.z / 50 );
+						point.applyMatrix4( tempMatrix.getInverse( worldRotationMatrix ) );
 
-						}
+						if ( scope.axis == "X" ) scope.object.scale.x = oldScale.x * ( 1 + point.x / 50 );
+						if ( scope.axis == "Y" ) scope.object.scale.y = oldScale.y * ( 1 + point.y / 50 );
+						if ( scope.axis == "Z" ) scope.object.scale.z = oldScale.z * ( 1 + point.z / 50 );
 
 					}
 
-				} else if ( _mode == "rotate" ) {
+				}
 
-					point.sub( worldPosition );
-					point.multiply(parentScale);
-					tempVector.copy(offset).sub( worldPosition );
-					tempVector.multiply(parentScale);
+			} else if ( _mode == "rotate" ) {
 
-					if ( _axis == "E" ) {
+				point.sub( worldPosition );
+				point.multiply(parentScale);
+				tempVector.copy(offset).sub( worldPosition );
+				tempVector.multiply(parentScale);
 
-						point.applyMatrix4( tempMatrix.getInverse( lookAtMatrix ) );
-						tempVector.applyMatrix4( tempMatrix.getInverse( lookAtMatrix ) );
+				if ( scope.axis == "E" ) {
 
-						rotation.set( Math.atan2( point.z, point.y ), Math.atan2( point.x, point.z ), Math.atan2( point.y, point.x ) );
-						offsetRotation.set( Math.atan2( tempVector.z, tempVector.y ), Math.atan2( tempVector.x, tempVector.z ), Math.atan2( tempVector.y, tempVector.x ) );
+					point.applyMatrix4( tempMatrix.getInverse( lookAtMatrix ) );
+					tempVector.applyMatrix4( tempMatrix.getInverse( lookAtMatrix ) );
 
-						tempQuaternion.setFromRotationMatrix( tempMatrix.getInverse( parentRotationMatrix ) );
+					rotation.set( Math.atan2( point.z, point.y ), Math.atan2( point.x, point.z ), Math.atan2( point.y, point.x ) );
+					offsetRotation.set( Math.atan2( tempVector.z, tempVector.y ), Math.atan2( tempVector.x, tempVector.z ), Math.atan2( tempVector.y, tempVector.x ) );
 
-						quaternionE.setFromAxisAngle( eye, rotation.z - offsetRotation.z );
-						quaternionXYZ.setFromRotationMatrix( worldRotationMatrix );
+					tempQuaternion.setFromRotationMatrix( tempMatrix.getInverse( parentRotationMatrix ) );
 
-						tempQuaternion.multiplyQuaternions( tempQuaternion, quaternionE );
-						tempQuaternion.multiplyQuaternions( tempQuaternion, quaternionXYZ );
+					quaternionE.setFromAxisAngle( eye, rotation.z - offsetRotation.z );
+					quaternionXYZ.setFromRotationMatrix( worldRotationMatrix );
 
-						_object.quaternion.copy( tempQuaternion );
+					tempQuaternion.multiplyQuaternions( tempQuaternion, quaternionE );
+					tempQuaternion.multiplyQuaternions( tempQuaternion, quaternionXYZ );
 
-					} else if ( _axis == "XYZE" ) {
+					scope.object.quaternion.copy( tempQuaternion );
 
-						quaternionE.setFromEuler( point.clone().cross(tempVector).normalize() ); // rotation axis
+				} else if ( scope.axis == "XYZE" ) {
 
-						tempQuaternion.setFromRotationMatrix( tempMatrix.getInverse( parentRotationMatrix ) );
-						quaternionX.setFromAxisAngle( quaternionE, - point.clone().angleTo(tempVector) );
-						quaternionXYZ.setFromRotationMatrix( worldRotationMatrix );
+					quaternionE.setFromEuler( point.clone().cross(tempVector).normalize() ); // rotation axis
 
-						tempQuaternion.multiplyQuaternions( tempQuaternion, quaternionX );
-						tempQuaternion.multiplyQuaternions( tempQuaternion, quaternionXYZ );
+					tempQuaternion.setFromRotationMatrix( tempMatrix.getInverse( parentRotationMatrix ) );
+					quaternionX.setFromAxisAngle( quaternionE, - point.clone().angleTo(tempVector) );
+					quaternionXYZ.setFromRotationMatrix( worldRotationMatrix );
 
-						_object.quaternion.copy( tempQuaternion );
+					tempQuaternion.multiplyQuaternions( tempQuaternion, quaternionX );
+					tempQuaternion.multiplyQuaternions( tempQuaternion, quaternionXYZ );
 
-					} else if ( scope.space == "local" ) {
+					scope.object.quaternion.copy( tempQuaternion );
 
-						point.applyMatrix4( tempMatrix.getInverse( worldRotationMatrix ) );
+				} else if ( scope.space == "local" ) {
 
-						tempVector.applyMatrix4( tempMatrix.getInverse( worldRotationMatrix ) );
+					point.applyMatrix4( tempMatrix.getInverse( worldRotationMatrix ) );
 
-						rotation.set( Math.atan2( point.z, point.y ), Math.atan2( point.x, point.z ), Math.atan2( point.y, point.x ) );
-						offsetRotation.set( Math.atan2( tempVector.z, tempVector.y ), Math.atan2( tempVector.x, tempVector.z ), Math.atan2( tempVector.y, tempVector.x ) );
+					tempVector.applyMatrix4( tempMatrix.getInverse( worldRotationMatrix ) );
 
-						quaternionXYZ.setFromRotationMatrix( oldRotationMatrix );
-						quaternionX.setFromAxisAngle( unitX, rotation.x - offsetRotation.x );
-						quaternionY.setFromAxisAngle( unitY, rotation.y - offsetRotation.y );
-						quaternionZ.setFromAxisAngle( unitZ, rotation.z - offsetRotation.z );
+					rotation.set( Math.atan2( point.z, point.y ), Math.atan2( point.x, point.z ), Math.atan2( point.y, point.x ) );
+					offsetRotation.set( Math.atan2( tempVector.z, tempVector.y ), Math.atan2( tempVector.x, tempVector.z ), Math.atan2( tempVector.y, tempVector.x ) );
 
-						if ( _axis == "X" ) quaternionXYZ.multiplyQuaternions( quaternionXYZ, quaternionX );
-						if ( _axis == "Y" ) quaternionXYZ.multiplyQuaternions( quaternionXYZ, quaternionY );
-						if ( _axis == "Z" ) quaternionXYZ.multiplyQuaternions( quaternionXYZ, quaternionZ );
+					quaternionXYZ.setFromRotationMatrix( oldRotationMatrix );
+					quaternionX.setFromAxisAngle( unitX, rotation.x - offsetRotation.x );
+					quaternionY.setFromAxisAngle( unitY, rotation.y - offsetRotation.y );
+					quaternionZ.setFromAxisAngle( unitZ, rotation.z - offsetRotation.z );
 
-						_object.quaternion.copy( quaternionXYZ );
+					if ( scope.axis == "X" ) quaternionXYZ.multiplyQuaternions( quaternionXYZ, quaternionX );
+					if ( scope.axis == "Y" ) quaternionXYZ.multiplyQuaternions( quaternionXYZ, quaternionY );
+					if ( scope.axis == "Z" ) quaternionXYZ.multiplyQuaternions( quaternionXYZ, quaternionZ );
 
-					} else if ( scope.space == "world" ) {
+					scope.object.quaternion.copy( quaternionXYZ );
 
-						rotation.set( Math.atan2( point.z, point.y ), Math.atan2( point.x, point.z ), Math.atan2( point.y, point.x ) );
-						offsetRotation.set( Math.atan2( tempVector.z, tempVector.y ), Math.atan2( tempVector.x, tempVector.z ), Math.atan2( tempVector.y, tempVector.x ) );
+				} else if ( scope.space == "world" ) {
 
-						tempQuaternion.setFromRotationMatrix( tempMatrix.getInverse( parentRotationMatrix ) );
+					rotation.set( Math.atan2( point.z, point.y ), Math.atan2( point.x, point.z ), Math.atan2( point.y, point.x ) );
+					offsetRotation.set( Math.atan2( tempVector.z, tempVector.y ), Math.atan2( tempVector.x, tempVector.z ), Math.atan2( tempVector.y, tempVector.x ) );
 
-						quaternionX.setFromAxisAngle( unitX, rotation.x - offsetRotation.x );
-						quaternionY.setFromAxisAngle( unitY, rotation.y - offsetRotation.y );
-						quaternionZ.setFromAxisAngle( unitZ, rotation.z - offsetRotation.z );
-						quaternionXYZ.setFromRotationMatrix( worldRotationMatrix );
+					tempQuaternion.setFromRotationMatrix( tempMatrix.getInverse( parentRotationMatrix ) );
 
-						if ( _axis == "X" ) tempQuaternion.multiplyQuaternions( tempQuaternion, quaternionX );
-						if ( _axis == "Y" ) tempQuaternion.multiplyQuaternions( tempQuaternion, quaternionY );
-						if ( _axis == "Z" ) tempQuaternion.multiplyQuaternions( tempQuaternion, quaternionZ );
+					quaternionX.setFromAxisAngle( unitX, rotation.x - offsetRotation.x );
+					quaternionY.setFromAxisAngle( unitY, rotation.y - offsetRotation.y );
+					quaternionZ.setFromAxisAngle( unitZ, rotation.z - offsetRotation.z );
+					quaternionXYZ.setFromRotationMatrix( worldRotationMatrix );
 
-						tempQuaternion.multiplyQuaternions( tempQuaternion, quaternionXYZ );
+					if ( scope.axis == "X" ) tempQuaternion.multiplyQuaternions( tempQuaternion, quaternionX );
+					if ( scope.axis == "Y" ) tempQuaternion.multiplyQuaternions( tempQuaternion, quaternionY );
+					if ( scope.axis == "Z" ) tempQuaternion.multiplyQuaternions( tempQuaternion, quaternionZ );
 
-						_object.quaternion.copy( tempQuaternion );
+					tempQuaternion.multiplyQuaternions( tempQuaternion, quaternionXYZ );
 
-					}
+					scope.object.quaternion.copy( tempQuaternion );
 
 				}
 
 			}
 
-			scope.update();
-			scope.dispatchEvent( changeEvent );
-
 		}
 
-	}
+		scope.dispatchEvent( changeEvent );
+		scope.update();
 
-	function onMouseUp( event ) {
+	}
 
-		_axis = false;
+	function onPointerUp( event ) {
 
-		domElement.removeEventListener( "mousemove", onMouseMove, false );
-		domElement.removeEventListener( "mouseup", onMouseUp, false );
-		domElement.removeEventListener( "mouseout", onMouseUp, false );
+		scope.axis = false;
+		_dragging = false;
+		scope.dispatchEvent( changeEvent );
+		scope.update();
 
 	}
 
-	function intersectObjects( event, objects ) {
+	function intersectObjects( pointer, objects ) {
 
 	    var rect = domElement.getBoundingClientRect();
-	    var x = (event.clientX - rect.left) / rect.width;
-	    var y = (event.clientY - rect.top) / rect.height;
+	    var x = (pointer.clientX - rect.left) / rect.width;
+	    var y = (pointer.clientY - rect.top) / rect.height;
 		pointerVector.set( ( x ) * 2 - 1, - ( y ) * 2 + 1, 0.5 );
 
 		projector.unprojectVector( pointerVector, camera );