Parcourir la source

Merge pull request #15544 from arodic/fix/15521_transform_controls

TransformControls: Fixed problem with transformed parents.
Mr.doob il y a 6 ans
Parent
commit
0f6051f79a
1 fichiers modifiés avec 51 ajouts et 49 suppressions
  1. 51 49
      examples/js/controls/TransformControls.js

+ 51 - 49
examples/js/controls/TransformControls.js

@@ -58,7 +58,10 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 	var pointStart = new THREE.Vector3();
 	var pointEnd = new THREE.Vector3();
+	var offset = new THREE.Vector3();
 	var rotationAxis = new THREE.Vector3();
+	var startNorm = new THREE.Vector3();
+	var endNorm = new THREE.Vector3();
 	var rotationAngle = 0;
 
 	var cameraPosition = new THREE.Vector3();
@@ -67,6 +70,7 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 	var parentPosition = new THREE.Vector3();
 	var parentQuaternion = new THREE.Quaternion();
+	var parentQuaternionInv = new THREE.Quaternion();
 	var parentScale = new THREE.Vector3();
 
 	var worldPositionStart = new THREE.Vector3();
@@ -75,17 +79,17 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 	var worldPosition = new THREE.Vector3();
 	var worldQuaternion = new THREE.Quaternion();
+	var worldQuaternionInv = new THREE.Quaternion();
 	var worldScale = new THREE.Vector3();
 
 	var eye = new THREE.Vector3();
 
-	var _positionStart = new THREE.Vector3();
-	var _quaternionStart = new THREE.Quaternion();
-	var _scaleStart = new THREE.Vector3();
+	var positionStart = new THREE.Vector3();
+	var quaternionStart = new THREE.Quaternion();
+	var scaleStart = new THREE.Vector3();
 
 	// TODO: remove properties unused in plane and gizmo
 
-	defineProperty( "parentQuaternion", parentQuaternion );
 	defineProperty( "worldPosition", worldPosition );
 	defineProperty( "worldPositionStart", worldPositionStart );
 	defineProperty( "worldQuaternion", worldQuaternion );
@@ -190,6 +194,9 @@ THREE.TransformControls = function ( camera, domElement ) {
 			this.object.parent.matrixWorld.decompose( parentPosition, parentQuaternion, parentScale );
 			this.object.matrixWorld.decompose( worldPosition, worldQuaternion, worldScale );
 
+			parentQuaternionInv.copy( parentQuaternion ).inverse();
+			worldQuaternionInv.copy( worldQuaternion ).inverse();
+
 		}
 
 		this.camera.updateMatrixWorld();
@@ -266,16 +273,14 @@ THREE.TransformControls = function ( camera, domElement ) {
 				this.object.updateMatrixWorld();
 				this.object.parent.updateMatrixWorld();
 
-				_positionStart.copy( this.object.position );
-				_quaternionStart.copy( this.object.quaternion );
-				_scaleStart.copy( this.object.scale );
+				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 );
 
-				if ( space === 'local' ) pointStart.applyQuaternion( worldQuaternionStart.clone().inverse() );
-
 			}
 
 			this.dragging = true;
@@ -313,29 +318,27 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 		pointEnd.copy( planeIntersect.point ).sub( worldPositionStart );
 
-		if ( space === 'local' ) pointEnd.applyQuaternion( worldQuaternionStart.clone().inverse() );
-
 		if ( mode === 'translate' ) {
 
-			if ( axis.search( 'X' ) === -1 ) {
-				pointEnd.x = pointStart.x;
-			}
-			if ( axis.search( 'Y' ) === -1 ) {
-				pointEnd.y = pointStart.y;
-			}
-			if ( axis.search( 'Z' ) === -1 ) {
-				pointEnd.z = pointStart.z;
+			// Apply translate
+
+			offset.copy( pointEnd ).sub( pointStart );
+
+			if ( space === 'local' && axis !== 'XYZ' ) {
+				offset.applyQuaternion( worldQuaternionInv );
 			}
 
-			// Apply translate
+			if ( axis.indexOf( 'X' ) === -1 ) offset.x = 0;
+			if ( axis.indexOf( 'Y' ) === -1 ) offset.y = 0;
+			if ( axis.indexOf( 'Z' ) === -1 ) offset.z = 0;
 
-			if ( space === 'local' ) {
-				object.position.copy( pointEnd ).sub( pointStart ).applyQuaternion( _quaternionStart );
+			if ( space === 'local' && axis !== 'XYZ') {
+				offset.applyQuaternion( quaternionStart ).divide( parentScale );
 			} else {
-				object.position.copy( pointEnd ).sub( pointStart );
+				offset.applyQuaternion( parentQuaternionInv ).divide( parentScale );
 			}
 
-			object.position.add( _positionStart );
+			object.position.copy( offset ).add( positionStart );
 
 			// Apply translation snap
 
@@ -343,7 +346,7 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 				if ( space === 'local' ) {
 
-					object.position.applyQuaternion(_tempQuaternion.copy( _quaternionStart ).inverse() );
+					object.position.applyQuaternion(_tempQuaternion.copy( quaternionStart ).inverse() );
 
 					if ( axis.search( 'X' ) !== -1 ) {
 						object.position.x = Math.round( object.position.x / this.translationSnap ) * this.translationSnap;
@@ -357,7 +360,7 @@ THREE.TransformControls = function ( camera, domElement ) {
 						object.position.z = Math.round( object.position.z / this.translationSnap ) * this.translationSnap;
 					}
 
-					object.position.applyQuaternion( _quaternionStart );
+					object.position.applyQuaternion( quaternionStart );
 
 				}
 
@@ -415,41 +418,40 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 			// Apply scale
 
-			object.scale.copy( _scaleStart ).multiply( _tempVector );
+			object.scale.copy( scaleStart ).multiply( _tempVector );
 
 		} else if ( mode === 'rotate' ) {
 
-			var ROTATION_SPEED = 20 / worldPosition.distanceTo( _tempVector.setFromMatrixPosition( this.camera.matrixWorld ) );
-
-			var quaternion = this.space === "local" ? worldQuaternion : _identityQuaternion;
+			offset.copy( pointEnd ).sub( pointStart );
 
-			var unit = _unit[ axis ];
+			var ROTATION_SPEED = 20 / worldPosition.distanceTo( _tempVector.setFromMatrixPosition( this.camera.matrixWorld ) );
 
 			if ( axis === 'E' ) {
 
-				_tempVector.copy( pointEnd ).cross( pointStart );
 				rotationAxis.copy( eye );
-				rotationAngle = pointEnd.angleTo( pointStart ) * ( _tempVector.dot( eye ) < 0 ? 1 : -1 );
+				rotationAngle = pointEnd.angleTo( pointStart );
+
+				startNorm.copy( pointStart ).normalize();
+				endNorm.copy( pointEnd ).normalize();
+
+				rotationAngle *= ( endNorm.cross( startNorm ).dot( eye ) < 0 ? 1 : -1);
 
 			} else if ( axis === 'XYZE' ) {
 
-				_tempVector.copy( pointEnd ).sub( pointStart ).cross( eye ).normalize();
-				rotationAxis.copy( _tempVector );
-				rotationAngle = pointEnd.sub( pointStart ).dot( _tempVector.cross( eye ) ) * ROTATION_SPEED;
+				rotationAxis.copy( offset ).cross( eye ).normalize(  );
+				rotationAngle = offset.dot( _tempVector.copy( rotationAxis ).cross( this.eye ) ) * ROTATION_SPEED;
 
 			} else if ( axis === 'X' || axis === 'Y' || axis === 'Z' ) {
 
-				_alignVector.copy( unit ).applyQuaternion( quaternion );
+				rotationAxis.copy( _unit[ axis ] );
 
-				rotationAxis.copy( unit );
+				_tempVector.copy( _unit[ axis ] );
 
-				_tempVector = unit.clone();
-				_tempVector2 = pointEnd.clone().sub( pointStart );
 				if ( space === 'local' ) {
-					_tempVector.applyQuaternion( quaternion );
-					_tempVector2.applyQuaternion( worldQuaternionStart );
+					_tempVector.applyQuaternion( worldQuaternion );
 				}
-				rotationAngle = _tempVector2.dot( _tempVector.cross( eye ).normalize() ) * ROTATION_SPEED;
+
+				rotationAngle = offset.dot( _tempVector.cross( eye ).normalize() ) * ROTATION_SPEED;
 
 			}
 
@@ -460,16 +462,16 @@ THREE.TransformControls = function ( camera, domElement ) {
 			this.rotationAngle = rotationAngle;
 
 			// Apply rotate
+			if ( space === 'local' && axis !== 'E' && axis !== 'XYZE' ) {
 
-			if ( space === 'local' ) {
-
-				object.quaternion.copy( _quaternionStart );
-				object.quaternion.multiply( _tempQuaternion.setFromAxisAngle( rotationAxis, rotationAngle ) );
+				object.quaternion.copy( quaternionStart );
+				object.quaternion.multiply( _tempQuaternion.setFromAxisAngle( rotationAxis, rotationAngle ) ).normalize();
 
 			} else {
 
+				rotationAxis.applyQuaternion( parentQuaternionInv );
 				object.quaternion.copy( _tempQuaternion.setFromAxisAngle( rotationAxis, rotationAngle ) );
-				object.quaternion.multiply( _quaternionStart );
+				object.quaternion.multiply( quaternionStart ).normalize();
 
 			}
 
@@ -534,7 +536,7 @@ THREE.TransformControls = function ( camera, domElement ) {
 		if ( !scope.enabled ) return;
 
 		event.preventDefault();
-		
+
 		document.addEventListener( "mousemove", onPointerMove, false );
 
 		scope.pointerHover( getPointer( event ) );