ソースを参照

Merge pull request #19163 from io-gui/transformControls/gizmoScale

TransformControls normalized gizmo scale between different cameras.
Mr.doob 5 年 前
コミット
d529026643

+ 13 - 3
examples/js/controls/TransformControls.js

@@ -1165,9 +1165,19 @@ THREE.TransformControlsGizmo = function () {
 			handle.rotation.set( 0, 0, 0 );
 			handle.position.copy( this.worldPosition );
 
-			var eyeDistance = this.camera.isOrthographicCamera ? 1000 / this.camera.zoom : 
-				this.worldPosition.distanceTo( this.cameraPosition );			
-			handle.scale.set( 1, 1, 1 ).multiplyScalar( eyeDistance * this.size / 7 );
+			var factor;
+
+			if ( this.camera.isOrthographicCamera ) {
+
+				factor = ( this.camera.top - this.camera.bottom ) / this.camera.zoom;
+
+			} else {
+
+				factor = this.worldPosition.distanceTo( this.cameraPosition ) * Math.min( 1.9 * Math.tan( Math.PI * this.camera.fov / 360 ) / this.camera.zoom, 7 );
+
+			}
+
+			handle.scale.set( 1, 1, 1 ).multiplyScalar( factor * this.size / 7 );
 
 			// TODO: simplify helpers and consider decoupling from gizmo
 

+ 13 - 3
examples/jsm/controls/TransformControls.js

@@ -1188,9 +1188,19 @@ var TransformControlsGizmo = function () {
 			handle.rotation.set( 0, 0, 0 );
 			handle.position.copy( this.worldPosition );
 
-			var eyeDistance = this.camera.isOrthographicCamera ? 1000 / this.camera.zoom : 
-				this.worldPosition.distanceTo( this.cameraPosition );			
-			handle.scale.set( 1, 1, 1 ).multiplyScalar( eyeDistance * this.size / 7 );
+			var factor;
+
+			if ( this.camera.isOrthographicCamera ) {
+
+				factor = ( this.camera.top - this.camera.bottom ) / this.camera.zoom;
+
+			} else {
+
+				factor = this.worldPosition.distanceTo( this.cameraPosition ) * Math.min( 1.9 * Math.tan( Math.PI * this.camera.fov / 360 ) / this.camera.zoom, 7 );
+
+			}
+
+			handle.scale.set( 1, 1, 1 ).multiplyScalar( factor * this.size / 7 );
 
 			// TODO: simplify helpers and consider decoupling from gizmo
 

+ 50 - 13
examples/misc_controls_transform.html

@@ -9,9 +9,10 @@
 	<body>
 
 		<div id="info">
-			"W" translate | "E" rotate | "R" scale | "+" increase size | "-" decrease size<br />
-			"Q" toggle world/local space |  Hold "Shift" down to snap to grid<br />
-			"X" toggle X | "Y" toggle Y | "Z" toggle Z | "Spacebar" toggle enabled
+			"W" translate | "E" rotate | "R" scale | "+/-" adjust size<br />
+			"Q" toggle world/local space |  "Shift" snap to grid<br />
+			"X" toggle X | "Y" toggle Y | "Z" toggle Z | "Spacebar" toggle enabled<br />
+			"C" toggle camera | "V" random zoom
 		</div>
 
 		<script type="module">
@@ -21,7 +22,7 @@
 			import { OrbitControls } from './jsm/controls/OrbitControls.js';
 			import { TransformControls } from './jsm/controls/TransformControls.js';
 
-			var camera, scene, renderer, control, orbit;
+			var cameras, camera, scene, renderer, control, orbit;
 
 			init();
 			render();
@@ -33,11 +34,15 @@
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				document.body.appendChild( renderer.domElement );
 
-				//
+				const aspect = window.innerWidth / window.innerHeight;
+				camera = 'persp';
+				cameras = {
+					'persp': new THREE.PerspectiveCamera( 50, aspect, 0.01, 30000 ),
+					'ortho': new THREE.OrthographicCamera( -600 * aspect, 600 * aspect, 600, -600, 0.01, 30000 ),
+				};
 
-				camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 3000 );
-				camera.position.set( 1000, 500, 1000 );
-				camera.lookAt( 0, 200, 0 );
+				cameras[camera].position.set( 1000, 500, 1000 );
+				cameras[camera].lookAt( 0, 200, 0 );
 
 				scene = new THREE.Scene();
 				scene.add( new THREE.GridHelper( 1000, 10 ) );
@@ -52,11 +57,11 @@
 				var geometry = new THREE.BoxBufferGeometry( 200, 200, 200 );
 				var material = new THREE.MeshLambertMaterial( { map: texture, transparent: true } );
 
-				orbit = new OrbitControls( camera, renderer.domElement );
+				orbit = new OrbitControls( cameras[camera], renderer.domElement );
 				orbit.update();
 				orbit.addEventListener( 'change', render );
 
-				control = new TransformControls( camera, renderer.domElement );
+				control = new TransformControls( cameras[camera], renderer.domElement );
 				control.addEventListener( 'change', render );
 
 				control.addEventListener( 'dragging-changed', function ( event ) {
@@ -99,6 +104,32 @@
 							control.setMode( "scale" );
 							break;
 
+						case 67: // C
+							const position = cameras[camera].position.clone();
+
+							camera = camera === 'persp' ? 'ortho' : 'persp';
+							cameras[camera].position.copy(position);
+
+							orbit.object = cameras[camera];
+							control.camera = cameras[camera];
+
+							cameras[camera].lookAt( orbit.target.x, orbit.target.y, orbit.target.z );
+							onWindowResize();
+							break;
+
+						case 86: // V
+							const randomFoV = Math.random() + 0.1;
+							const randomZoom = Math.random() + 0.1;
+
+							cameras['persp'].fov = randomFoV * 160;
+							cameras['ortho'].bottom = -randomFoV * 500;
+							cameras['ortho'].top = randomFoV * 500;
+
+							cameras['persp'].zoom = randomZoom * 5;
+							cameras['ortho'].zoom = randomZoom * 5;
+							onWindowResize();
+							break;
+
 						case 187:
 						case 107: // +, =, num+
 							control.setSize( control.size + 0.1 );
@@ -147,8 +178,14 @@
 
 			function onWindowResize() {
 
-				camera.aspect = window.innerWidth / window.innerHeight;
-				camera.updateProjectionMatrix();
+				const aspect = window.innerWidth / window.innerHeight;
+
+				cameras['persp'].aspect = aspect;
+				cameras['persp'].updateProjectionMatrix();
+
+				cameras['ortho'].left = cameras['ortho'].bottom * aspect;
+				cameras['ortho'].right = cameras['ortho'].top * aspect;
+				cameras['ortho'].updateProjectionMatrix();
 
 				renderer.setSize( window.innerWidth, window.innerHeight );
 
@@ -158,7 +195,7 @@
 
 			function render() {
 
-				renderer.render( scene, camera );
+				renderer.render( scene, cameras[camera] );
 
 			}