| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 | ( function () {	const _euler = new THREE.Euler( 0, 0, 0, 'YXZ' );	const _vector = new THREE.Vector3();	const _changeEvent = {		type: 'change'	};	const _lockEvent = {		type: 'lock'	};	const _unlockEvent = {		type: 'unlock'	};	const _PI_2 = Math.PI / 2;	class PointerLockControls extends THREE.EventDispatcher {		constructor( camera, domElement ) {			super();			if ( domElement === undefined ) {				console.warn( 'THREE.PointerLockControls: The second parameter "domElement" is now mandatory.' );				domElement = document.body;			}			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			const scope = this;			function onMouseMove( event ) {				if ( scope.isLocked === false ) return;				const movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0;				const movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0;				_euler.setFromQuaternion( camera.quaternion );				_euler.y -= movementX * 0.002;				_euler.x -= movementY * 0.002;				_euler.x = Math.max( _PI_2 - scope.maxPolarAngle, Math.min( _PI_2 - scope.minPolarAngle, _euler.x ) );				camera.quaternion.setFromEuler( _euler );				scope.dispatchEvent( _changeEvent );			}			function onPointerlockChange() {				if ( scope.domElement.ownerDocument.pointerLockElement === scope.domElement ) {					scope.dispatchEvent( _lockEvent );					scope.isLocked = true;				} else {					scope.dispatchEvent( _unlockEvent );					scope.isLocked = false;				}			}			function onPointerlockError() {				console.error( 'THREE.PointerLockControls: Unable to use Pointer Lock API' );			}			this.connect = function () {				scope.domElement.ownerDocument.addEventListener( 'mousemove', onMouseMove );				scope.domElement.ownerDocument.addEventListener( 'pointerlockchange', onPointerlockChange );				scope.domElement.ownerDocument.addEventListener( 'pointerlockerror', onPointerlockError );			};			this.disconnect = function () {				scope.domElement.ownerDocument.removeEventListener( 'mousemove', onMouseMove );				scope.domElement.ownerDocument.removeEventListener( 'pointerlockchange', onPointerlockChange );				scope.domElement.ownerDocument.removeEventListener( 'pointerlockerror', onPointerlockError );			};			this.dispose = function () {				this.disconnect();			};			this.getObject = function () {				// retaining this method for backward compatibility				return camera;			};			this.getDirection = function () {				const direction = new THREE.Vector3( 0, 0, - 1 );				return function ( v ) {					return v.copy( direction ).applyQuaternion( camera.quaternion );				};			}();			this.moveForward = function ( distance ) {				// move forward parallel to the xz-plane				// assumes camera.up is y-up				_vector.setFromMatrixColumn( camera.matrix, 0 );				_vector.crossVectors( camera.up, _vector );				camera.position.addScaledVector( _vector, distance );			};			this.moveRight = function ( distance ) {				_vector.setFromMatrixColumn( camera.matrix, 0 );				camera.position.addScaledVector( _vector, distance );			};			this.lock = function () {				this.domElement.requestPointerLock();			};			this.unlock = function () {				scope.domElement.ownerDocument.exitPointerLock();			};			this.connect();		}	}	THREE.PointerLockControls = PointerLockControls;} )();
 |