浏览代码

Merge remote-tracking branch 'arodic/transformControls' into dev

Mr.doob 12 年之前
父节点
当前提交
b35b95524f
共有 2 个文件被更改,包括 142 次插入54 次删除
  1. 140 53
      examples/js/controls/TransformControls.js
  2. 2 1
      examples/misc_controls_transform.html

+ 140 - 53
examples/js/controls/TransformControls.js

@@ -6,7 +6,6 @@
 
 THREE.TransformControls = function ( camera, domElement ) {
 
-	// TODO: Choose a better fitting intersection plane when looking at grazing angles
 	// TODO: Make non-uniform scale and rotate play nice in hierarchies
 	// TODO: ADD RXYZ contol
 
@@ -15,7 +14,7 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 	this.active = false;
 	this.mode = 'translate';
-	this.space = 'world';
+	this.space = 'local';
 	this.scale = 1;
 
 	this.snapDist = null;
@@ -77,6 +76,28 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 	var object, name;
 
+	// intersection planes
+	{
+
+		var planes = new THREE.Object3D();
+		this.gizmo.add(planes);
+
+		for ( var i in intersectionPlaneList ){
+
+			intersectionPlanes[intersectionPlaneList[i]] = new THREE.Mesh( new THREE.PlaneGeometry( 500, 500 ) );
+			intersectionPlanes[intersectionPlaneList[i]].material.side = THREE.DoubleSide;
+			intersectionPlanes[intersectionPlaneList[i]].visible = false;
+			planes.add(intersectionPlanes[intersectionPlaneList[i]]);
+
+		}
+
+		intersectionPlanes['YZ'].rotation.set( 0, Math.PI/2, 0 );
+		intersectionPlanes['XZ'].rotation.set( -Math.PI/2, 0, 0 );
+		bakeTransformations(intersectionPlanes['YZ']);
+		bakeTransformations(intersectionPlanes['XZ']);
+
+	}
+
 	// gizmo geometry
 	{
 
@@ -159,17 +180,17 @@ THREE.TransformControls = function ( camera, domElement ) {
 		displayAxes['translate'].add( mesh );
 		pickerAxes['translate'].add( mesh.clone() );
 
-		geometry = new THREE.PlaneGeometry( 0.2, 0.2 );
+		geometry = new THREE.PlaneGeometry( 0.3, 0.3 );
 
 		mesh = new THREE.Mesh( geometry, HandleMaterial( yellow ) );
-		mesh.position.set( 0.1, 0.1, 0 );
+		mesh.position.set( 0.15, 0.15, 0 );
 		bakeTransformations( mesh );
 		mesh.name = 'TXY';
 		displayAxes['translate'].add( mesh );
 		pickerAxes['translate'].add( mesh.clone() );
 
 		mesh = new THREE.Mesh( geometry, HandleMaterial( cyan ) );
-		mesh.position.set( 0, 0.1, 0.1 );
+		mesh.position.set( 0, 0.15, 0.15 );
 		mesh.rotation.y = Math.PI/2;
 		bakeTransformations( mesh );
 		mesh.name = 'TYZ';
@@ -177,7 +198,7 @@ THREE.TransformControls = function ( camera, domElement ) {
 		pickerAxes['translate'].add( mesh.clone() );
 
 		mesh = new THREE.Mesh( geometry, HandleMaterial( magenta ) );
-		mesh.position.set( 0.1, 0, 0.1 );
+		mesh.position.set( 0.15, 0, 0.15 );
 		mesh.rotation.x = Math.PI/2;
 		bakeTransformations( mesh );
 		mesh.name = 'TXZ';
@@ -187,42 +208,42 @@ THREE.TransformControls = function ( camera, domElement ) {
 		geometry = new THREE.CylinderGeometry( 0, 0.05, 0.2, 4, 1, true );
 
 		mesh = new THREE.Mesh( geometry, HandleMaterial( red ) );
-		mesh.position.x = 0.9;
+		mesh.position.x = 1.1;
 		mesh.rotation.z = -Math.PI/2;
 		bakeTransformations( mesh );
 		mesh.name = 'TX';
 		displayAxes['translate'].add( mesh );
 
 		mesh = new THREE.Mesh( geometry, HandleMaterial( green ) );
-		mesh.position.y = 0.9;
+		mesh.position.y = 1.1;
 		bakeTransformations( mesh );
 		mesh.name = 'TY';
 		displayAxes['translate'].add( mesh );
 
 		mesh = new THREE.Mesh( geometry, HandleMaterial( blue ) );
-		mesh.position.z = 0.9;
+		mesh.position.z = 1.1;
 		mesh.rotation.x = Math.PI/2;
 		bakeTransformations( mesh );
 		mesh.name = 'TZ';
 		displayAxes['translate'].add( mesh );
 
-		geometry = new THREE.CylinderGeometry( 0.1, 0.1, 0.8, 4, 1, false );
+		geometry = new THREE.CylinderGeometry( 0.2, 0.1, 0.8, 4, 1, false );
 
 		mesh = new THREE.Mesh( geometry, HandleMaterial( red ) );
-		mesh.position.x = 0.6;
+		mesh.position.x = 0.7;
 		mesh.rotation.z = -Math.PI/2;
 		bakeTransformations( mesh );
 		mesh.name = 'TX';
 		pickerAxes['translate'].add( mesh );
 
 		mesh = new THREE.Mesh( geometry, HandleMaterial( green ) );
-		mesh.position.y = 0.6;
+		mesh.position.y = 0.7;
 		bakeTransformations( mesh );
 		mesh.name = 'TY';
 		pickerAxes['translate'].add( mesh );
 
 		mesh = new THREE.Mesh( geometry, HandleMaterial( blue ) );
-		mesh.position.z = 0.6;
+		mesh.position.z = 0.7;
 		mesh.rotation.x = Math.PI/2;
 		bakeTransformations( mesh );
 		mesh.name = 'TZ';
@@ -230,29 +251,29 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 		// scale manipulators
 
-		geometry = new THREE.CubeGeometry( 0.1, 0.1, 0.1 );
+		geometry = new THREE.CubeGeometry( 0.125, 0.125, 0.125 );
 
 		mesh = new THREE.Mesh( geometry, HandleMaterial( white ) );
 		mesh.name = 'SXYZ';
 		displayAxes['scale'].add( mesh );
 		pickerAxes['scale'].add( mesh.clone() );
 
-		mesh = new THREE.Mesh( geometry, HandleMaterial( red ) );
-		mesh.position.set( 1, 0, 0 );
+		mesh = new THREE.Mesh( geometry, HandleMaterial( [1,0,0,0.25] ) );
+		mesh.position.set( 1.05, 0, 0 );
 		bakeTransformations( mesh );
 		mesh.name = 'SX';
 		displayAxes['scale'].add( mesh );
 		pickerAxes['scale'].add( mesh.clone() );
 
-		mesh = new THREE.Mesh( geometry, HandleMaterial( green ) );
-		mesh.position.set( 0, 1, 0 );
+		mesh = new THREE.Mesh( geometry, HandleMaterial( [0,1,0,0.25] ) );
+		mesh.position.set( 0, 1.05, 0 );
 		bakeTransformations( mesh );
 		mesh.name = 'SY';
 		displayAxes['scale'].add( mesh );
 		pickerAxes['scale'].add( mesh.clone() );
 
-		mesh = new THREE.Mesh( geometry, HandleMaterial( blue ) );
-		mesh.position.set( 0, 0, 1 );
+		mesh = new THREE.Mesh( geometry, HandleMaterial( [0,0,1,0.25] ) );
+		mesh.position.set( 0, 0, 1.05 );
 		bakeTransformations( mesh );
 		mesh.name = 'SZ';
 		displayAxes['scale'].add( mesh );
@@ -289,11 +310,11 @@ THREE.TransformControls = function ( camera, domElement ) {
 		mesh.name = 'RXYZE';
 		displayAxes['rotate'].add( mesh );
 
-		mesh = new THREE.Line( Circle( 1.1, 'z' ), LineMaterial( [1,1,0,1] ) );
+		mesh = new THREE.Line( Circle( 1.25, 'z' ), LineMaterial( [1,1,0,0.25] ) );
 		mesh.name = 'RE';
 		displayAxes['rotate'].add( mesh );
 
-		geometry = new THREE.TorusGeometry( 1, 0.05, 4, 6, Math.PI );
+		geometry = new THREE.TorusGeometry( 1, 0.15, 4, 6, Math.PI );
 
 		mesh = new THREE.Mesh( geometry, HandleMaterial( cyan ) );
 		mesh.rotation.z = -Math.PI/2;
@@ -316,10 +337,14 @@ THREE.TransformControls = function ( camera, domElement ) {
 		pickerAxes['rotate'].add( mesh );
 
 		mesh = new THREE.Mesh( new THREE.SphereGeometry( 0.95, 12, 12 ), HandleMaterial( white ) );
-		mesh.name = 'RXYZ';
+		mesh.name = 'RXYZE';
 		pickerAxes['rotate'].add( mesh );
 
-		mesh = new THREE.Mesh( new THREE.TorusGeometry( 1.12, 0.07, 4, 12 ), HandleMaterial( yellow ) );
+		intersectionPlanes['SPHERE'] = new THREE.Mesh( new THREE.SphereGeometry( 0.95, 12, 12 ) );
+		intersectionPlanes['SPHERE'].visible = false;
+		planes.add(intersectionPlanes['SPHERE']);
+
+		mesh = new THREE.Mesh( new THREE.TorusGeometry( 1.30, 0.15, 4, 12 ), HandleMaterial( yellow ) );
 		mesh.name = 'RE';
 		pickerAxes['rotate'].add( mesh );
 
@@ -327,35 +352,13 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 	}
 
-	// intersection planes
-	{
-
-		var planes = new THREE.Object3D();
-		this.gizmo.add(planes);
-
-		for ( var i in intersectionPlaneList ){
-
-			intersectionPlanes[intersectionPlaneList[i]] = new THREE.Mesh( new THREE.PlaneGeometry( 500, 500 ) );
-			intersectionPlanes[intersectionPlaneList[i]].material.side = THREE.DoubleSide;
-			intersectionPlanes[intersectionPlaneList[i]].name = intersectionPlaneList[i];
-			intersectionPlanes[intersectionPlaneList[i]].visible = false;
-			planes.add(intersectionPlanes[intersectionPlaneList[i]]);
-
-		}
-
-		intersectionPlanes['YZ'].rotation.set( 0, Math.PI/2, 0 );
-		intersectionPlanes['XZ'].rotation.set( -Math.PI/2, 0, 0 );
-		bakeTransformations(intersectionPlanes['YZ']);
-		bakeTransformations(intersectionPlanes['XZ']);
-
-	}
-
 	this.attatch = function ( object ) {
 
 		this.object = object;
 	 	this.setMode( scope.mode );
 
 		this.domElement.addEventListener( 'mousedown', onMouseDown, false );
+		this.domElement.addEventListener( 'mousemove', onMouseHover, false );
 		document.addEventListener( 'keydown', onKeyDown, false );
 
 	}
@@ -365,6 +368,7 @@ THREE.TransformControls = function ( camera, domElement ) {
 	 	this.hide();
 
 		this.domElement.removeEventListener( 'mousedown', onMouseDown, false );
+		this.domElement.removeEventListener( 'mousemove', onMouseHover, false );
 		document.removeEventListener( 'keydown', onKeyDown, false );
 
 	}
@@ -379,7 +383,7 @@ THREE.TransformControls = function ( camera, domElement ) {
 		camPosition.getPositionFromMatrix( this.camera.matrixWorld );
 		camRotation.setEulerFromRotationMatrix( tempMatrix.extractRotation( this.camera.matrixWorld ));
 
-		scale = worldPosition.distanceTo( camPosition ) / 10 * this.scale;
+		scale = worldPosition.distanceTo( camPosition ) / 6 * this.scale;
 		this.gizmo.position.copy( worldPosition )
 		this.gizmo.scale.set( scale, scale, scale );
 
@@ -503,14 +507,43 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 	this.setIntersectionPlane = function () {
 
-		if ( isActive("X") || isActive("Y") ) {
+		eye.copy( camPosition ).sub( worldPosition ).normalize();
 
-			currentPlane = 'XY';
+		if ( this.space == 'local' ) {
+
+			eye.applyMatrix4( tempMatrix.getInverse( scope.object.matrixWorld ) );
+		
+		}
+
+		if ( isActive("X") ) {
+
+			if ( eye.y > eye.z ) currentPlane = 'XZ';
+			else currentPlane = 'XY';
+
+		}
+
+		if ( isActive("Y") ) {
+
+			if ( eye.x > eye.z ) currentPlane = 'YZ';
+			else currentPlane = 'XY';
 
 		}
 
 		if ( isActive("Z") ) {
 
+			if ( eye.x > eye.y ) currentPlane = 'YZ';
+			else currentPlane = 'XZ';
+
+		}
+
+		if ( isActive("XY") ) {
+
+			currentPlane = 'XY';
+
+		}
+
+		if ( isActive("YZ") ) {
+
 			currentPlane = 'YZ';
 
 		}
@@ -545,10 +578,54 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 		}
 
-		scope.update();
+		if ( isActive("RXYZ") ) {
+
+			currentPlane = 'SPHERE';
+
+		}
 
 	}
 
+	function onMouseHover( event ) {
+
+		event.preventDefault();
+
+		if ( event.button === 0 && !scope.active ) {
+
+			intersect = intersectObjects( event, pickerAxes[scope.mode].children );
+
+			for ( var i in displayAxes[scope.mode].children ) {
+
+	 			var axis = displayAxes[scope.mode].children[i];
+	 			
+	 			if ( intersect && axis.name == intersect.object.name ) {
+
+	 				axis.material.color.setRGB(1,1,0);
+	 				axis.material.opacity = 1;
+	 			
+	 			} else if ( axis.material.origColor ) {
+
+	 				axis.material.color.copy( axis.material.origColor );
+	 				axis.material.opacity = axis.material.origOpacity;
+	 					
+	 			} else {
+
+	 				axis.material.origColor = axis.material.color.clone();
+	 				axis.material.origOpacity = axis.material.opacity;
+
+	 			}
+
+		 	}
+
+		 	scope.dispatchEvent( changeEvent );
+
+		}
+
+		document.addEventListener( 'mousemove', onMouseMove, false );
+		document.addEventListener( 'mouseup', onMouseUp, false );
+
+	};
+
 	function onMouseDown( event ) {
 
 		event.preventDefault();
@@ -561,6 +638,7 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 				scope.active = intersect.object.name;
 
+				scope.update();
 				scope.setIntersectionPlane();
 
 				planeIntersect = intersectObjects( event, [intersectionPlanes[currentPlane]] );
@@ -695,9 +773,18 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 						scope.object.rotation.setEulerFromQuaternion( tempQuaternion );
 
-					} else if ( scope.active == "RXYZ" ) {
+					} else if ( scope.active == "RXYZE" ) {
+
+						quaternionE.setFromEuler( point.clone().cross(tempVector).normalize() ); // rotation axis
 
-						// TODO
+						tempQuaternion.setFromRotationMatrix( tempMatrix.getInverse( parentRotationMatrix ) );
+						quaternionX.setFromAxisAngle( quaternionE, - point.clone().angleTo(tempVector) );
+						quaternionXYZ.setFromRotationMatrix( worldRotationMatrix );
+
+						tempQuaternion.multiplyQuaternions( tempQuaternion, quaternionX );
+						tempQuaternion.multiplyQuaternions( tempQuaternion, quaternionXYZ );
+
+						scope.object.rotation.setEulerFromQuaternion( tempQuaternion );
 
 					} else if ( scope.space == 'local' ) {
 

+ 2 - 1
examples/misc_controls_transform.html

@@ -26,7 +26,7 @@
 
 		<div id="info">
 		"W" translate | "E" rotate | "R" scale | "+" increase size | "-" decrease size<br />
-		Press "w/E/R" twice to toggle world/local space
+		Press "W/E/R" twice to toggle world/local space
 		</div>
 
 		<script src="../build/three.min.js"></script>
@@ -73,6 +73,7 @@
 					var control = new THREE.TransformControls( camera, renderer.domElement );
 					control.addEventListener( 'change', render );
 					control.attatch( mesh );
+					control.scale = 0.65;
 					scene.add( control.gizmo );
 
 					controls.push( control );