Garrett Johnson 4 năm trước cách đây
mục cha
commit
466d830beb
2 tập tin đã thay đổi với 68 bổ sung31 xóa
  1. 65 31
      example/FlyOrbitControls.js
  2. 3 0
      example/index.js

+ 65 - 31
example/FlyOrbitControls.js

@@ -1,15 +1,31 @@
-import { Vector3, Vector4 } from 'three';
+import { Clock, Vector3, Vector4 } from 'three';
 import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
 
+const changeEvent = { type: 'fly-change' };
+const startEvent = { type: 'fly-start' };
+const endEvent = { type: 'fly-end' };
 const tempVector = new Vector4( 0, 0, 0, 0 );
 export class FlyOrbitControls extends OrbitControls {
 
 	constructor( camera, domElement ) {
 
-		super( camera, domElement );
+		// Disable use of shift key so we can use it for acceleration
+		const disableShiftKeyCallback = e => {
+
+			if ( this.enabled ) {
+
+				Object.defineProperty( e, 'shiftKey', { get() { return false } } );
+
+			}
+
+		};
+
+		domElement.addEventListener( 'pointerdown', disableShiftKeyCallback );
 
-		domElement.tabIndex = 1;
+		super( camera, domElement );
 
+		this.enableKeys = false;
+		this.enableFlight = true;
 		this.baseSpeed = 1;
 		this.fastSpeed = 4;
 		this.forwardKey = 'w';
@@ -33,6 +49,7 @@ export class FlyOrbitControls extends OrbitControls {
 		let originalMaxDistance = 0;
 		let rafHandle = - 1;
 		const originalTarget = new Vector3();
+		const clock = new Clock();
 
 		const endFlight = () => {
 
@@ -41,23 +58,35 @@ export class FlyOrbitControls extends OrbitControls {
 				cancelAnimationFrame( rafHandle );
 				rafHandle = - 1;
 
-			}
+				this.minDistance = originalMinDistance;
+				this.maxDistance = originalMaxDistance;
 
-			this.minDistance = originalMinDistance;
-			this.maxDistance = originalMaxDistance;
+				const targetDistance = Math.min( originalDistance, camera.position.distanceTo( originalTarget ) );
+				tempVector
+					.set( 0, 0, - 1, 0 )
+					.applyMatrix4( camera.matrixWorld );
+				this
+					.target
+					.copy( camera.position )
+					.addScaledVector( tempVector, targetDistance );
 
-			const targetDistance = Math.min( originalDistance, camera.position.distanceTo( originalTarget ) );
-			this
-				.target
-				.set( 0, 0, - targetDistance )
-				.applyMatrix4( camera.matrixWorld );
+				this.dispatchEvent( endEvent );
+
+			}
 
 		};
 
 		const updateFlight = () => {
 
+			if ( ! this.enabled || ! this.enableFlight ) {
+
+				return;
+
+			}
+
 			rafHandle = requestAnimationFrame( updateFlight );
 
+			const delta = 60 * clock.getDelta();
 			const speed = fastHeld ? this.fastSpeed : this.baseSpeed;
 			tempVector.set( 0, 0, 0, 0 );
 			if ( forwardHeld ) tempVector.z -= 1;
@@ -70,10 +99,12 @@ export class FlyOrbitControls extends OrbitControls {
 			tempVector.applyMatrix4( camera.matrixWorld );
 			camera
 				.position
-				.addScaledVector( tempVector, speed );
+				.addScaledVector( tempVector, speed * delta );
 			this
 				.target
-				.addScaledVector( tempVector, speed );
+				.addScaledVector( tempVector, speed * delta );
+
+			this.dispatchEvent( changeEvent );
 
 		};
 		this.updateFlight = updateFlight;
@@ -141,6 +172,8 @@ export class FlyOrbitControls extends OrbitControls {
 
 				if ( rafHandle === - 1 ) {
 
+					this.dispatchEvent( startEvent );
+					clock.getDelta();
 					updateFlight();
 
 				}
@@ -153,6 +186,20 @@ export class FlyOrbitControls extends OrbitControls {
 
 			const key = e.key.toLowerCase();
 
+			switch ( key ) {
+
+				case this.fastKey:
+				case this.forwardKey:
+				case this.backKey:
+				case this.leftKey:
+				case this.rightKey:
+				case this.upKey:
+				case this.downKey:
+					e.stopPropagation();
+					e.preventDefault();
+
+			}
+
 			switch( key ) {
 
 				case this.forwardKey:
@@ -179,20 +226,6 @@ export class FlyOrbitControls extends OrbitControls {
 
 			}
 
-			switch ( key ) {
-
-				case this.fastKey:
-				case this.forwardKey:
-				case this.backKey:
-				case this.leftKey:
-				case this.rightKey:
-				case this.upKey:
-				case this.downKey:
-					e.stopPropagation();
-					e.preventDefault();
-
-			}
-
 			if ( ! ( forwardHeld || backHeld || leftHeld || rightHeld || upHeld || downHeld ) ) {
 
 				endFlight();
@@ -210,6 +243,7 @@ export class FlyOrbitControls extends OrbitControls {
 		this.blurCallback = blurCallback;
 		this.keyDownCallback = keyDownCallback;
 		this.keyUpCallback = keyUpCallback;
+		this.disableShiftKeyCallback = disableShiftKeyCallback;
 
 		this.domElement.addEventListener( 'blur', blurCallback );
 		this.domElement.addEventListener( 'keydown', keyDownCallback );
@@ -221,11 +255,11 @@ export class FlyOrbitControls extends OrbitControls {
 
 		super.dispose();
 
-		this.domElement.addEventListener( 'blur', this.blurCallback );
-		this.domElement.addEventListener( 'keydown', this.keyDownCallback );
-		this.domElement.addEventListener( 'keyup', this.keyUpCallback );
+		this.domElement.removeEventListener( 'blur', this.blurCallback );
+		this.domElement.removeEventListener( 'keydown', this.keyDownCallback );
+		this.domElement.removeEventListener( 'keyup', this.keyUpCallback );
+		this.domElement.removeEventListener( 'pointerdown', this.disableShiftKeyCallback );
 
 	}
 
-
 }

+ 3 - 0
example/index.js

@@ -125,6 +125,7 @@ function init() {
 	renderer.outputEncoding = sRGBEncoding;
 
 	document.body.appendChild( renderer.domElement );
+	renderer.domElement.tabIndex = 1;
 
 	camera = new PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 4000 );
 	camera.position.set( 400, 400, 400 );
@@ -151,6 +152,7 @@ function init() {
 	secondRenderer.domElement.style.right = '0';
 	secondRenderer.domElement.style.top = '0';
 	secondRenderer.domElement.style.outline = '#0f1416 solid 2px';
+	secondRenderer.domElement.tabIndex = 1;
 
 	secondControls = new FlyOrbitControls( secondCamera, secondRenderer.domElement );
 	secondControls.screenSpacePanning = false;
@@ -175,6 +177,7 @@ function init() {
 	thirdPersonRenderer.domElement.style.position = 'fixed';
 	thirdPersonRenderer.domElement.style.left = '5px';
 	thirdPersonRenderer.domElement.style.bottom = '5px';
+	thirdPersonRenderer.domElement.tabIndex = 1;
 
 	thirdPersonControls = new FlyOrbitControls( thirdPersonCamera, thirdPersonRenderer.domElement );
 	thirdPersonControls.screenSpacePanning = false;