163 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			163 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								import {
							 | 
						||
| 
								 | 
							
									Euler,
							 | 
						||
| 
								 | 
							
									EventDispatcher,
							 | 
						||
| 
								 | 
							
									Vector3
							 | 
						||
| 
								 | 
							
								} from 'three';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const _euler = new Euler( 0, 0, 0, 'YXZ' );
							 | 
						||
| 
								 | 
							
								const _vector = new Vector3();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const _changeEvent = { type: 'change' };
							 | 
						||
| 
								 | 
							
								const _lockEvent = { type: 'lock' };
							 | 
						||
| 
								 | 
							
								const _unlockEvent = { type: 'unlock' };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const _PI_2 = Math.PI / 2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class PointerLockControls extends EventDispatcher {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									constructor( camera, domElement ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										super();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.camera = camera;
							 | 
						||
| 
								 | 
							
										this.domElement = domElement;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.isLocked = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// Set to constrain the pitch of the camera
							 | 
						||
| 
								 | 
							
										// Range is 0 to Math.PI radians
							 | 
						||
| 
								 | 
							
										this.minPolarAngle = 0; // radians
							 | 
						||
| 
								 | 
							
										this.maxPolarAngle = Math.PI; // radians
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.pointerSpeed = 1.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this._onMouseMove = onMouseMove.bind( this );
							 | 
						||
| 
								 | 
							
										this._onPointerlockChange = onPointerlockChange.bind( this );
							 | 
						||
| 
								 | 
							
										this._onPointerlockError = onPointerlockError.bind( this );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.connect();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									connect() {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.domElement.ownerDocument.addEventListener( 'mousemove', this._onMouseMove );
							 | 
						||
| 
								 | 
							
										this.domElement.ownerDocument.addEventListener( 'pointerlockchange', this._onPointerlockChange );
							 | 
						||
| 
								 | 
							
										this.domElement.ownerDocument.addEventListener( 'pointerlockerror', this._onPointerlockError );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									disconnect() {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.domElement.ownerDocument.removeEventListener( 'mousemove', this._onMouseMove );
							 | 
						||
| 
								 | 
							
										this.domElement.ownerDocument.removeEventListener( 'pointerlockchange', this._onPointerlockChange );
							 | 
						||
| 
								 | 
							
										this.domElement.ownerDocument.removeEventListener( 'pointerlockerror', this._onPointerlockError );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									dispose() {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.disconnect();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									getObject() { // retaining this method for backward compatibility
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return this.camera;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									getDirection( v ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return v.set( 0, 0, - 1 ).applyQuaternion( this.camera.quaternion );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									moveForward( distance ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// move forward parallel to the xz-plane
							 | 
						||
| 
								 | 
							
										// assumes camera.up is y-up
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										const camera = this.camera;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										_vector.setFromMatrixColumn( camera.matrix, 0 );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										_vector.crossVectors( camera.up, _vector );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										camera.position.addScaledVector( _vector, distance );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									moveRight( distance ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										const camera = this.camera;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										_vector.setFromMatrixColumn( camera.matrix, 0 );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										camera.position.addScaledVector( _vector, distance );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									lock() {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.domElement.requestPointerLock();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									unlock() {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.domElement.ownerDocument.exitPointerLock();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// event listeners
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function onMouseMove( event ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( this.isLocked === false ) return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									const movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0;
							 | 
						||
| 
								 | 
							
									const movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									const camera = this.camera;
							 | 
						||
| 
								 | 
							
									_euler.setFromQuaternion( camera.quaternion );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									_euler.y -= movementX * 0.002 * this.pointerSpeed;
							 | 
						||
| 
								 | 
							
									_euler.x -= movementY * 0.002 * this.pointerSpeed;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									_euler.x = Math.max( _PI_2 - this.maxPolarAngle, Math.min( _PI_2 - this.minPolarAngle, _euler.x ) );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									camera.quaternion.setFromEuler( _euler );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									this.dispatchEvent( _changeEvent );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function onPointerlockChange() {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if ( this.domElement.ownerDocument.pointerLockElement === this.domElement ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.dispatchEvent( _lockEvent );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.isLocked = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									} else {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.dispatchEvent( _unlockEvent );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.isLocked = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function onPointerlockError() {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									console.error( 'THREE.PointerLockControls: Unable to use Pointer Lock API' );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export { PointerLockControls };
							 |