diff --git a/dist/camera-controls.js b/dist/camera-controls.js index 48be980..4b205fb 100644 --- a/dist/camera-controls.js +++ b/dist/camera-controls.js @@ -817,6 +817,7 @@ const dollyX = this.dollyToCursor ? (lastDragPosition.x - this._elementRect.x) / this._elementRect.width * 2 - 1 : 0; const dollyY = this.dollyToCursor ? (lastDragPosition.y - this._elementRect.y) / this._elementRect.height * -2 + 1 : 0; this._state === ACTION.TOUCH_DOLLY || + this._state === ACTION.TOUCH_DOLLY_ROTATE || this._state === ACTION.TOUCH_DOLLY_TRUCK || this._state === ACTION.TOUCH_DOLLY_OFFSET ? this._dollyInternal(dollyDelta * TOUCH_DOLLY_FACTOR, dollyX, dollyY) : diff --git a/dist/camera-controls.min.js b/dist/camera-controls.min.js index 38d641c..e26d96d 100644 --- a/dist/camera-controls.min.js +++ b/dist/camera-controls.min.js @@ -4,4 +4,4 @@ * (c) 2017 @yomotsu * Released under the MIT License. */ -(function(global,factory){typeof exports==="object"&&typeof module!=="undefined"?module.exports=factory():typeof define==="function"&&define.amd?define(factory):(global=typeof globalThis!=="undefined"?globalThis:global||self,global.CameraControls=factory())})(this,(function(){"use strict";const MOUSE_BUTTON={LEFT:1,RIGHT:2,MIDDLE:4};const ACTION=Object.freeze({NONE:0,ROTATE:1,TRUCK:2,OFFSET:4,DOLLY:8,ZOOM:16,TOUCH_ROTATE:32,TOUCH_TRUCK:64,TOUCH_OFFSET:128,TOUCH_DOLLY:256,TOUCH_ZOOM:512,TOUCH_DOLLY_TRUCK:1024,TOUCH_DOLLY_OFFSET:2048,TOUCH_DOLLY_ROTATE:4096,TOUCH_ZOOM_TRUCK:8192,TOUCH_ZOOM_OFFSET:16384,TOUCH_ZOOM_ROTATE:32768});function isPerspectiveCamera(camera){return camera.isPerspectiveCamera}function isOrthographicCamera(camera){return camera.isOrthographicCamera}const PI_2=Math.PI*2;const PI_HALF=Math.PI/2;const EPSILON=1e-5;function approxZero(number,error=EPSILON){return Math.abs(number){out.x+=pointer.clientX;out.y+=pointer.clientY}));out.x/=pointers.length;out.y/=pointers.length}function notSupportedInOrthographicCamera(camera,message){if(isOrthographicCamera(camera)){console.warn(`${message} is not supported in OrthographicCamera`);return true}return false}function quatInvertCompat(target){if(target.invert){target.invert()}else{target.inverse()}return target}class EventDispatcher{constructor(){this._listeners={}}addEventListener(type,listener){const listeners=this._listeners;if(listeners[type]===undefined)listeners[type]=[];if(listeners[type].indexOf(listener)===-1)listeners[type].push(listener)}removeEventListener(type,listener){const listeners=this._listeners;const listenerArray=listeners[type];if(listenerArray!==undefined){const index=listenerArray.indexOf(listener);if(index!==-1)listenerArray.splice(index,1)}}removeAllEventListeners(type){if(!type){this._listeners={};return}if(Array.isArray(this._listeners[type]))this._listeners[type].length=0}dispatchEvent(event){const listeners=this._listeners;const listenerArray=listeners[event.type];if(listenerArray!==undefined){event.target=this;const array=listenerArray.slice(0);for(let i=0,l=array.length;i{};this._enabled=true;this._state=ACTION.NONE;this._viewport=null;this._dollyControlAmount=0;this._hasRested=true;this._boundaryEnclosesCamera=false;this._needsUpdate=true;this._updatedLastTime=false;this._elementRect=new DOMRect;this._activePointers=[];this._truckInternal=(deltaX,deltaY,dragToOffset)=>{if(isPerspectiveCamera(this._camera)){const offset=_v3A.copy(this._camera.position).sub(this._target);const fov=this._camera.getEffectiveFOV()*THREE.MathUtils.DEG2RAD;const targetDistance=offset.length()*Math.tan(fov*.5);const truckX=this.truckSpeed*deltaX*targetDistance/this._elementRect.height;const pedestalY=this.truckSpeed*deltaY*targetDistance/this._elementRect.height;if(this.verticalDragToForward){dragToOffset?this.setFocalOffset(this._focalOffsetEnd.x+truckX,this._focalOffsetEnd.y,this._focalOffsetEnd.z,true):this.truck(truckX,0,true);this.forward(-pedestalY,true)}else{dragToOffset?this.setFocalOffset(this._focalOffsetEnd.x+truckX,this._focalOffsetEnd.y+pedestalY,this._focalOffsetEnd.z,true):this.truck(truckX,pedestalY,true)}}else if(isOrthographicCamera(this._camera)){const camera=this._camera;const truckX=deltaX*(camera.right-camera.left)/camera.zoom/this._elementRect.width;const pedestalY=deltaY*(camera.top-camera.bottom)/camera.zoom/this._elementRect.height;dragToOffset?this.setFocalOffset(this._focalOffsetEnd.x+truckX,this._focalOffsetEnd.y+pedestalY,this._focalOffsetEnd.z,true):this.truck(truckX,pedestalY,true)}};this._rotateInternal=(deltaX,deltaY)=>{const theta=PI_2*this.azimuthRotateSpeed*deltaX/this._elementRect.height;const phi=PI_2*this.polarRotateSpeed*deltaY/this._elementRect.height;this.rotate(theta,phi,true)};this._dollyInternal=(delta,x,y)=>{const dollyScale=Math.pow(.95,-delta*this.dollySpeed);const distance=this._sphericalEnd.radius*dollyScale;const prevRadius=this._sphericalEnd.radius;const signedPrevRadius=prevRadius*(delta>=0?-1:1);this.dollyTo(distance);if(this.infinityDolly&&(distance{const zoomScale=Math.pow(.95,delta*this.dollySpeed);this.zoomTo(this._zoom*zoomScale);if(this.dollyToCursor){this._dollyControlAmount=this._zoomEnd;this._dollyControlCoord.set(x,y)}return};if(typeof THREE==="undefined"){console.error("camera-controls: `THREE` is undefined. You must first run `CameraControls.install( { THREE: THREE } )`. Check the docs for further information.")}this._camera=camera;this._yAxisUpSpace=(new THREE.Quaternion).setFromUnitVectors(this._camera.up,_AXIS_Y);this._yAxisUpSpaceInverse=quatInvertCompat(this._yAxisUpSpace.clone());this._state=ACTION.NONE;this._domElement=domElement;this._domElement.style.touchAction="none";this._domElement.style.userSelect="none";this._domElement.style.webkitUserSelect="none";this._target=new THREE.Vector3;this._targetEnd=this._target.clone();this._focalOffset=new THREE.Vector3;this._focalOffsetEnd=this._focalOffset.clone();this._spherical=(new THREE.Spherical).setFromVector3(_v3A.copy(this._camera.position).applyQuaternion(this._yAxisUpSpace));this._sphericalEnd=this._spherical.clone();this._zoom=this._camera.zoom;this._zoomEnd=this._zoom;this._nearPlaneCorners=[new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3];this._updateNearPlaneCorners();this._boundary=new THREE.Box3(new THREE.Vector3(-Infinity,-Infinity,-Infinity),new THREE.Vector3(Infinity,Infinity,Infinity));this._target0=this._target.clone();this._position0=this._camera.position.clone();this._zoom0=this._zoom;this._focalOffset0=this._focalOffset.clone();this._dollyControlAmount=0;this._dollyControlCoord=new THREE.Vector2;this.mouseButtons={left:ACTION.ROTATE,middle:ACTION.DOLLY,right:ACTION.TRUCK,wheel:isPerspectiveCamera(this._camera)?ACTION.DOLLY:isOrthographicCamera(this._camera)?ACTION.ZOOM:ACTION.NONE};this.touches={one:ACTION.TOUCH_ROTATE,two:isPerspectiveCamera(this._camera)?ACTION.TOUCH_DOLLY_TRUCK:isOrthographicCamera(this._camera)?ACTION.TOUCH_ZOOM_TRUCK:ACTION.NONE,three:ACTION.TOUCH_TRUCK};if(this._domElement){const dragStartPosition=new THREE.Vector2;const lastDragPosition=new THREE.Vector2;const dollyStart=new THREE.Vector2;const onPointerDown=event=>{if(!this._enabled)return;const pointer={pointerId:event.pointerId,clientX:event.clientX,clientY:event.clientY,deltaX:0,deltaY:0};this._activePointers.push(pointer);this._domElement.ownerDocument.removeEventListener("pointermove",onPointerMove,{passive:false});this._domElement.ownerDocument.removeEventListener("pointerup",onPointerUp);this._domElement.ownerDocument.addEventListener("pointermove",onPointerMove,{passive:false});this._domElement.ownerDocument.addEventListener("pointerup",onPointerUp);startDragging(event)};const onMouseDown=event=>{if(!this._enabled)return;const pointer={pointerId:0,clientX:event.clientX,clientY:event.clientY,deltaX:0,deltaY:0};this._activePointers.push(pointer);this._domElement.ownerDocument.removeEventListener("mousemove",onMouseMove);this._domElement.ownerDocument.removeEventListener("mouseup",onMouseUp);this._domElement.ownerDocument.addEventListener("mousemove",onMouseMove);this._domElement.ownerDocument.addEventListener("mouseup",onMouseUp);startDragging(event)};const onTouchStart=event=>{if(!this._enabled)return;event.preventDefault();Array.prototype.forEach.call(event.changedTouches,(touch=>{const pointer={pointerId:touch.identifier,clientX:touch.clientX,clientY:touch.clientY,deltaX:0,deltaY:0};this._activePointers.push(pointer)}));this._domElement.ownerDocument.removeEventListener("touchmove",onTouchMove,{passive:false});this._domElement.ownerDocument.removeEventListener("touchend",onTouchEnd);this._domElement.ownerDocument.addEventListener("touchmove",onTouchMove,{passive:false});this._domElement.ownerDocument.addEventListener("touchend",onTouchEnd);startDragging(event)};const onPointerMove=event=>{if(event.cancelable)event.preventDefault();const pointerId=event.pointerId;const pointer=this._findPointerById(pointerId);if(!pointer)return;pointer.clientX=event.clientX;pointer.clientY=event.clientY;pointer.deltaX=event.movementX;pointer.deltaY=event.movementY;if(event.pointerType==="touch"){switch(this._activePointers.length){case 1:this._state=this.touches.one;break;case 2:this._state=this.touches.two;break;case 3:this._state=this.touches.three;break}}else{this._state=0;if((event.buttons&MOUSE_BUTTON.LEFT)===MOUSE_BUTTON.LEFT){this._state=this._state|this.mouseButtons.left}if((event.buttons&MOUSE_BUTTON.MIDDLE)===MOUSE_BUTTON.MIDDLE){this._state=this._state|this.mouseButtons.middle}if((event.buttons&MOUSE_BUTTON.RIGHT)===MOUSE_BUTTON.RIGHT){this._state=this._state|this.mouseButtons.right}}dragging()};const onMouseMove=event=>{const pointer=this._findPointerById(0);if(!pointer)return;pointer.clientX=event.clientX;pointer.clientY=event.clientY;pointer.deltaX=event.movementX;pointer.deltaY=event.movementY;this._state=0;if((event.buttons&MOUSE_BUTTON.LEFT)===MOUSE_BUTTON.LEFT){this._state=this._state|this.mouseButtons.left}if((event.buttons&MOUSE_BUTTON.MIDDLE)===MOUSE_BUTTON.MIDDLE){this._state=this._state|this.mouseButtons.middle}if((event.buttons&MOUSE_BUTTON.RIGHT)===MOUSE_BUTTON.RIGHT){this._state=this._state|this.mouseButtons.right}dragging()};const onTouchMove=event=>{if(event.cancelable)event.preventDefault();Array.prototype.forEach.call(event.changedTouches,(touch=>{const pointerId=touch.identifier;const pointer=this._findPointerById(pointerId);if(!pointer)return;pointer.clientX=touch.clientX;pointer.clientY=touch.clientY}));dragging()};const onPointerUp=event=>{const pointerId=event.pointerId;const pointer=this._findPointerById(pointerId);pointer&&this._activePointers.splice(this._activePointers.indexOf(pointer),1);if(event.pointerType==="touch"){switch(this._activePointers.length){case 0:this._state=ACTION.NONE;break;case 1:this._state=this.touches.one;break;case 2:this._state=this.touches.two;break;case 3:this._state=this.touches.three;break}}else{this._state=ACTION.NONE}endDragging()};const onMouseUp=()=>{const pointer=this._findPointerById(0);pointer&&this._activePointers.splice(this._activePointers.indexOf(pointer),1);this._state=ACTION.NONE;endDragging()};const onTouchEnd=event=>{Array.prototype.forEach.call(event.changedTouches,(touch=>{const pointerId=touch.identifier;const pointer=this._findPointerById(pointerId);pointer&&this._activePointers.splice(this._activePointers.indexOf(pointer),1)}));switch(this._activePointers.length){case 0:this._state=ACTION.NONE;break;case 1:this._state=this.touches.one;break;case 2:this._state=this.touches.two;break;case 3:this._state=this.touches.three;break}endDragging()};let lastScrollTimeStamp=-1;const onMouseWheel=event=>{if(!this._enabled||this.mouseButtons.wheel===ACTION.NONE)return;event.preventDefault();if(this.dollyToCursor||this.mouseButtons.wheel===ACTION.ROTATE||this.mouseButtons.wheel===ACTION.TRUCK){const now=performance.now();if(lastScrollTimeStamp-now<1e3)this._getClientRect(this._elementRect);lastScrollTimeStamp=now}const deltaYFactor=isMac?-1:-3;const delta=event.deltaMode===1?event.deltaY/deltaYFactor:event.deltaY/(deltaYFactor*10);const x=this.dollyToCursor?(event.clientX-this._elementRect.x)/this._elementRect.width*2-1:0;const y=this.dollyToCursor?(event.clientY-this._elementRect.y)/this._elementRect.height*-2+1:0;switch(this.mouseButtons.wheel){case ACTION.ROTATE:{this._rotateInternal(event.deltaX,event.deltaY);break}case ACTION.TRUCK:{this._truckInternal(event.deltaX,event.deltaY,false);break}case ACTION.OFFSET:{this._truckInternal(event.deltaX,event.deltaY,true);break}case ACTION.DOLLY:{this._dollyInternal(-delta,x,y);break}case ACTION.ZOOM:{this._zoomInternal(-delta,x,y);break}}this.dispatchEvent({type:"control"})};const onContextMenu=event=>{if(!this._enabled)return;event.preventDefault()};const startDragging=event=>{if(!this._enabled)return;extractClientCoordFromEvent(this._activePointers,_v2);this._getClientRect(this._elementRect);dragStartPosition.copy(_v2);lastDragPosition.copy(_v2);const isMultiTouch=this._activePointers.length>=2;if(isMultiTouch){const dx=_v2.x-this._activePointers[1].clientX;const dy=_v2.y-this._activePointers[1].clientY;const distance=Math.sqrt(dx*dx+dy*dy);dollyStart.set(0,distance);const x=(this._activePointers[0].clientX+this._activePointers[1].clientX)*.5;const y=(this._activePointers[0].clientY+this._activePointers[1].clientY)*.5;lastDragPosition.set(x,y)}if("touches"in event||"pointerType"in event&&event.pointerType==="touch"){switch(this._activePointers.length){case 1:this._state=this.touches.one;break;case 2:this._state=this.touches.two;break;case 3:this._state=this.touches.three;break}}else{this._state=0;if((event.buttons&MOUSE_BUTTON.LEFT)===MOUSE_BUTTON.LEFT){this._state=this._state|this.mouseButtons.left}if((event.buttons&MOUSE_BUTTON.MIDDLE)===MOUSE_BUTTON.MIDDLE){this._state=this._state|this.mouseButtons.middle}if((event.buttons&MOUSE_BUTTON.RIGHT)===MOUSE_BUTTON.RIGHT){this._state=this._state|this.mouseButtons.right}}this.dispatchEvent({type:"controlstart"})};const dragging=()=>{if(!this._enabled)return;extractClientCoordFromEvent(this._activePointers,_v2);const isPointerLockActive=this._domElement&&document.pointerLockElement===this._domElement;const deltaX=isPointerLockActive?-this._activePointers[0].deltaX:lastDragPosition.x-_v2.x;const deltaY=isPointerLockActive?-this._activePointers[0].deltaY:lastDragPosition.y-_v2.y;lastDragPosition.copy(_v2);if((this._state&ACTION.ROTATE)===ACTION.ROTATE||(this._state&ACTION.TOUCH_ROTATE)===ACTION.TOUCH_ROTATE||(this._state&ACTION.TOUCH_DOLLY_ROTATE)===ACTION.TOUCH_DOLLY_ROTATE||(this._state&ACTION.TOUCH_ZOOM_ROTATE)===ACTION.TOUCH_ZOOM_ROTATE){this._rotateInternal(deltaX,deltaY)}if((this._state&ACTION.DOLLY)===ACTION.DOLLY||(this._state&ACTION.ZOOM)===ACTION.ZOOM){const dollyX=this.dollyToCursor?(dragStartPosition.x-this._elementRect.x)/this._elementRect.width*2-1:0;const dollyY=this.dollyToCursor?(dragStartPosition.y-this._elementRect.y)/this._elementRect.height*-2+1:0;this._state===ACTION.DOLLY?this._dollyInternal(deltaY*TOUCH_DOLLY_FACTOR,dollyX,dollyY):this._zoomInternal(deltaY*TOUCH_DOLLY_FACTOR,dollyX,dollyY)}if((this._state&ACTION.TOUCH_DOLLY)===ACTION.TOUCH_DOLLY||(this._state&ACTION.TOUCH_ZOOM)===ACTION.TOUCH_ZOOM||(this._state&ACTION.TOUCH_DOLLY_TRUCK)===ACTION.TOUCH_DOLLY_TRUCK||(this._state&ACTION.TOUCH_ZOOM_TRUCK)===ACTION.TOUCH_ZOOM_TRUCK||(this._state&ACTION.TOUCH_DOLLY_OFFSET)===ACTION.TOUCH_DOLLY_OFFSET||(this._state&ACTION.TOUCH_ZOOM_OFFSET)===ACTION.TOUCH_ZOOM_OFFSET||(this._state&ACTION.TOUCH_DOLLY_ROTATE)===ACTION.TOUCH_DOLLY_ROTATE||(this._state&ACTION.TOUCH_ZOOM_ROTATE)===ACTION.TOUCH_ZOOM_ROTATE){const dx=_v2.x-this._activePointers[1].clientX;const dy=_v2.y-this._activePointers[1].clientY;const distance=Math.sqrt(dx*dx+dy*dy);const dollyDelta=dollyStart.y-distance;dollyStart.set(0,distance);const dollyX=this.dollyToCursor?(lastDragPosition.x-this._elementRect.x)/this._elementRect.width*2-1:0;const dollyY=this.dollyToCursor?(lastDragPosition.y-this._elementRect.y)/this._elementRect.height*-2+1:0;this._state===ACTION.TOUCH_DOLLY||this._state===ACTION.TOUCH_DOLLY_TRUCK||this._state===ACTION.TOUCH_DOLLY_OFFSET?this._dollyInternal(dollyDelta*TOUCH_DOLLY_FACTOR,dollyX,dollyY):this._zoomInternal(dollyDelta*TOUCH_DOLLY_FACTOR,dollyX,dollyY)}if((this._state&ACTION.TRUCK)===ACTION.TRUCK||(this._state&ACTION.TOUCH_TRUCK)===ACTION.TOUCH_TRUCK||(this._state&ACTION.TOUCH_DOLLY_TRUCK)===ACTION.TOUCH_DOLLY_TRUCK||(this._state&ACTION.TOUCH_ZOOM_TRUCK)===ACTION.TOUCH_ZOOM_TRUCK){this._truckInternal(deltaX,deltaY,false)}if((this._state&ACTION.OFFSET)===ACTION.OFFSET||(this._state&ACTION.TOUCH_OFFSET)===ACTION.TOUCH_OFFSET||(this._state&ACTION.TOUCH_DOLLY_OFFSET)===ACTION.TOUCH_DOLLY_OFFSET||(this._state&ACTION.TOUCH_ZOOM_OFFSET)===ACTION.TOUCH_ZOOM_OFFSET){this._truckInternal(deltaX,deltaY,true)}this.dispatchEvent({type:"control"})};const endDragging=()=>{extractClientCoordFromEvent(this._activePointers,_v2);lastDragPosition.copy(_v2);if(this._activePointers.length===0){this._domElement.ownerDocument.removeEventListener("pointermove",onPointerMove,{passive:false});this._domElement.ownerDocument.removeEventListener("pointerup",onPointerUp);this._domElement.ownerDocument.removeEventListener("touchmove",onTouchMove,{passive:false});this._domElement.ownerDocument.removeEventListener("touchend",onTouchEnd);this.dispatchEvent({type:"controlend"})}};this._domElement.addEventListener("pointerdown",onPointerDown);isPointerEventsNotSupported&&this._domElement.addEventListener("mousedown",onMouseDown);isPointerEventsNotSupported&&this._domElement.addEventListener("touchstart",onTouchStart);this._domElement.addEventListener("pointercancel",onPointerUp);this._domElement.addEventListener("wheel",onMouseWheel,{passive:false});this._domElement.addEventListener("contextmenu",onContextMenu);this._removeAllEventListeners=()=>{this._domElement.removeEventListener("pointerdown",onPointerDown);this._domElement.removeEventListener("mousedown",onMouseDown);this._domElement.removeEventListener("touchstart",onTouchStart);this._domElement.removeEventListener("pointercancel",onPointerUp);this._domElement.removeEventListener("wheel",onMouseWheel,{passive:false});this._domElement.removeEventListener("contextmenu",onContextMenu);this._domElement.ownerDocument.removeEventListener("pointermove",onPointerMove,{passive:false});this._domElement.ownerDocument.removeEventListener("mousemove",onMouseMove);this._domElement.ownerDocument.removeEventListener("touchmove",onTouchMove,{passive:false});this._domElement.ownerDocument.removeEventListener("pointerup",onPointerUp);this._domElement.ownerDocument.removeEventListener("mouseup",onMouseUp);this._domElement.ownerDocument.removeEventListener("touchend",onTouchEnd)};this.cancel=()=>{if(this._state===ACTION.NONE)return;this._state=ACTION.NONE;this._activePointers.length=0;endDragging()}}this.update(0)}static install(libs){THREE=libs.THREE;_ORIGIN=Object.freeze(new THREE.Vector3(0,0,0));_AXIS_Y=Object.freeze(new THREE.Vector3(0,1,0));_AXIS_Z=Object.freeze(new THREE.Vector3(0,0,1));_v2=new THREE.Vector2;_v3A=new THREE.Vector3;_v3B=new THREE.Vector3;_v3C=new THREE.Vector3;_xColumn=new THREE.Vector3;_yColumn=new THREE.Vector3;_zColumn=new THREE.Vector3;_deltaTarget=new THREE.Vector3;_deltaOffset=new THREE.Vector3;_sphericalA=new THREE.Spherical;_sphericalB=new THREE.Spherical;_box3A=new THREE.Box3;_box3B=new THREE.Box3;_sphere=new THREE.Sphere;_quaternionA=new THREE.Quaternion;_quaternionB=new THREE.Quaternion;_rotationMatrix=new THREE.Matrix4;_raycaster=new THREE.Raycaster}static get ACTION(){return ACTION}get camera(){return this._camera}set camera(camera){this._camera=camera;this.updateCameraUp();this._camera.updateProjectionMatrix();this._updateNearPlaneCorners();this._needsUpdate=true}get enabled(){return this._enabled}set enabled(enabled){this._enabled=enabled;if(enabled){this._domElement.style.touchAction="none";this._domElement.style.userSelect="none";this._domElement.style.webkitUserSelect="none"}else{this.cancel();this._domElement.style.touchAction="";this._domElement.style.userSelect="";this._domElement.style.webkitUserSelect=""}}get active(){return!this._hasRested}get currentAction(){return this._state}get distance(){return this._spherical.radius}set distance(distance){if(this._spherical.radius===distance&&this._sphericalEnd.radius===distance)return;this._spherical.radius=distance;this._sphericalEnd.radius=distance;this._needsUpdate=true}get azimuthAngle(){return this._spherical.theta}set azimuthAngle(azimuthAngle){if(this._spherical.theta===azimuthAngle&&this._sphericalEnd.theta===azimuthAngle)return;this._spherical.theta=azimuthAngle;this._sphericalEnd.theta=azimuthAngle;this._needsUpdate=true}get polarAngle(){return this._spherical.phi}set polarAngle(polarAngle){if(this._spherical.phi===polarAngle&&this._sphericalEnd.phi===polarAngle)return;this._spherical.phi=polarAngle;this._sphericalEnd.phi=polarAngle;this._needsUpdate=true}get boundaryEnclosesCamera(){return this._boundaryEnclosesCamera}set boundaryEnclosesCamera(boundaryEnclosesCamera){this._boundaryEnclosesCamera=boundaryEnclosesCamera;this._needsUpdate=true}addEventListener(type,listener){super.addEventListener(type,listener)}removeEventListener(type,listener){super.removeEventListener(type,listener)}rotate(azimuthAngle,polarAngle,enableTransition=false){return this.rotateTo(this._sphericalEnd.theta+azimuthAngle,this._sphericalEnd.phi+polarAngle,enableTransition)}rotateAzimuthTo(azimuthAngle,enableTransition=false){return this.rotateTo(azimuthAngle,this._sphericalEnd.phi,enableTransition)}rotatePolarTo(polarAngle,enableTransition=false){return this.rotateTo(this._sphericalEnd.theta,polarAngle,enableTransition)}rotateTo(azimuthAngle,polarAngle,enableTransition=false){const theta=THREE.MathUtils.clamp(azimuthAngle,this.minAzimuthAngle,this.maxAzimuthAngle);const phi=THREE.MathUtils.clamp(polarAngle,this.minPolarAngle,this.maxPolarAngle);this._sphericalEnd.theta=theta;this._sphericalEnd.phi=phi;this._sphericalEnd.makeSafe();this._needsUpdate=true;if(!enableTransition){this._spherical.theta=this._sphericalEnd.theta;this._spherical.phi=this._sphericalEnd.phi}const resolveImmediately=!enableTransition||approxEquals(this._spherical.theta,this._sphericalEnd.theta,this.restThreshold)&&approxEquals(this._spherical.phi,this._sphericalEnd.phi,this.restThreshold);return this._createOnRestPromise(resolveImmediately)}dolly(distance,enableTransition=false){return this.dollyTo(this._sphericalEnd.radius-distance,enableTransition)}dollyTo(distance,enableTransition=false){const lastRadius=this._sphericalEnd.radius;const newRadius=THREE.MathUtils.clamp(distance,this.minDistance,this.maxDistance);const hasCollider=this.colliderMeshes.length>=1;if(hasCollider){const maxDistanceByCollisionTest=this._collisionTest();const isCollided=approxEquals(maxDistanceByCollisionTest,this._spherical.radius);const isDollyIn=lastRadius>newRadius;if(!isDollyIn&&isCollided)return Promise.resolve();this._sphericalEnd.radius=Math.min(newRadius,maxDistanceByCollisionTest)}else{this._sphericalEnd.radius=newRadius}this._needsUpdate=true;if(!enableTransition){this._spherical.radius=this._sphericalEnd.radius}const resolveImmediately=!enableTransition||approxEquals(this._spherical.radius,this._sphericalEnd.radius,this.restThreshold);return this._createOnRestPromise(resolveImmediately)}zoom(zoomStep,enableTransition=false){return this.zoomTo(this._zoomEnd+zoomStep,enableTransition)}zoomTo(zoom,enableTransition=false){this._zoomEnd=THREE.MathUtils.clamp(zoom,this.minZoom,this.maxZoom);this._needsUpdate=true;if(!enableTransition){this._zoom=this._zoomEnd}const resolveImmediately=!enableTransition||approxEquals(this._zoom,this._zoomEnd,this.restThreshold);return this._createOnRestPromise(resolveImmediately)}pan(x,y,enableTransition=false){console.warn("`pan` has been renamed to `truck`");return this.truck(x,y,enableTransition)}truck(x,y,enableTransition=false){this._camera.updateMatrix();_xColumn.setFromMatrixColumn(this._camera.matrix,0);_yColumn.setFromMatrixColumn(this._camera.matrix,1);_xColumn.multiplyScalar(x);_yColumn.multiplyScalar(-y);const offset=_v3A.copy(_xColumn).add(_yColumn);const to=_v3B.copy(this._targetEnd).add(offset);return this.moveTo(to.x,to.y,to.z,enableTransition)}forward(distance,enableTransition=false){_v3A.setFromMatrixColumn(this._camera.matrix,0);_v3A.crossVectors(this._camera.up,_v3A);_v3A.multiplyScalar(distance);const to=_v3B.copy(this._targetEnd).add(_v3A);return this.moveTo(to.x,to.y,to.z,enableTransition)}moveTo(x,y,z,enableTransition=false){const offset=_v3A.set(x,y,z).sub(this._targetEnd);this._encloseToBoundary(this._targetEnd,offset,this.boundaryFriction);this._needsUpdate=true;if(!enableTransition){this._target.copy(this._targetEnd)}const resolveImmediately=!enableTransition||approxEquals(this._target.x,this._targetEnd.x,this.restThreshold)&&approxEquals(this._target.y,this._targetEnd.y,this.restThreshold)&&approxEquals(this._target.z,this._targetEnd.z,this.restThreshold);return this._createOnRestPromise(resolveImmediately)}fitToBox(box3OrObject,enableTransition,{cover:cover=false,paddingLeft:paddingLeft=0,paddingRight:paddingRight=0,paddingBottom:paddingBottom=0,paddingTop:paddingTop=0}={}){const promises=[];const aabb=box3OrObject.isBox3?_box3A.copy(box3OrObject):_box3A.setFromObject(box3OrObject);if(aabb.isEmpty()){console.warn("camera-controls: fitTo() cannot be used with an empty box. Aborting");Promise.resolve()}const theta=roundToStep(this._sphericalEnd.theta,PI_HALF);const phi=roundToStep(this._sphericalEnd.phi,PI_HALF);promises.push(this.rotateTo(theta,phi,enableTransition));const normal=_v3A.setFromSpherical(this._sphericalEnd).normalize();const rotation=_quaternionA.setFromUnitVectors(normal,_AXIS_Z);const viewFromPolar=approxEquals(Math.abs(normal.y),1);if(viewFromPolar){rotation.multiply(_quaternionB.setFromAxisAngle(_AXIS_Y,theta))}rotation.multiply(this._yAxisUpSpaceInverse);const bb=_box3B.makeEmpty();_v3B.copy(aabb.min).applyQuaternion(rotation);bb.expandByPoint(_v3B);_v3B.copy(aabb.min).setX(aabb.max.x).applyQuaternion(rotation);bb.expandByPoint(_v3B);_v3B.copy(aabb.min).setY(aabb.max.y).applyQuaternion(rotation);bb.expandByPoint(_v3B);_v3B.copy(aabb.max).setZ(aabb.min.z).applyQuaternion(rotation);bb.expandByPoint(_v3B);_v3B.copy(aabb.min).setZ(aabb.max.z).applyQuaternion(rotation);bb.expandByPoint(_v3B);_v3B.copy(aabb.max).setY(aabb.min.y).applyQuaternion(rotation);bb.expandByPoint(_v3B);_v3B.copy(aabb.max).setX(aabb.min.x).applyQuaternion(rotation);bb.expandByPoint(_v3B);_v3B.copy(aabb.max).applyQuaternion(rotation);bb.expandByPoint(_v3B);bb.min.x-=paddingLeft;bb.min.y-=paddingBottom;bb.max.x+=paddingRight;bb.max.y+=paddingTop;rotation.setFromUnitVectors(_AXIS_Z,normal);if(viewFromPolar){rotation.premultiply(_quaternionB.invert())}rotation.premultiply(this._yAxisUpSpace);const bbSize=bb.getSize(_v3A);const center=bb.getCenter(_v3B).applyQuaternion(rotation);if(isPerspectiveCamera(this._camera)){const distance=this.getDistanceToFitBox(bbSize.x,bbSize.y,bbSize.z,cover);promises.push(this.moveTo(center.x,center.y,center.z,enableTransition));promises.push(this.dollyTo(distance,enableTransition));promises.push(this.setFocalOffset(0,0,0,enableTransition))}else if(isOrthographicCamera(this._camera)){const camera=this._camera;const width=camera.right-camera.left;const height=camera.top-camera.bottom;const zoom=cover?Math.max(width/bbSize.x,height/bbSize.y):Math.min(width/bbSize.x,height/bbSize.y);promises.push(this.moveTo(center.x,center.y,center.z,enableTransition));promises.push(this.zoomTo(zoom,enableTransition));promises.push(this.setFocalOffset(0,0,0,enableTransition))}return Promise.all(promises)}fitToSphere(sphereOrMesh,enableTransition){const promises=[];const isSphere=sphereOrMesh instanceof THREE.Sphere;const boundingSphere=isSphere?_sphere.copy(sphereOrMesh):createBoundingSphere(sphereOrMesh,_sphere);promises.push(this.moveTo(boundingSphere.center.x,boundingSphere.center.y,boundingSphere.center.z,enableTransition));if(isPerspectiveCamera(this._camera)){const distanceToFit=this.getDistanceToFitSphere(boundingSphere.radius);promises.push(this.dollyTo(distanceToFit,enableTransition))}else if(isOrthographicCamera(this._camera)){const width=this._camera.right-this._camera.left;const height=this._camera.top-this._camera.bottom;const diameter=2*boundingSphere.radius;const zoom=Math.min(width/diameter,height/diameter);promises.push(this.zoomTo(zoom,enableTransition))}promises.push(this.setFocalOffset(0,0,0,enableTransition));return Promise.all(promises)}setLookAt(positionX,positionY,positionZ,targetX,targetY,targetZ,enableTransition=false){const target=_v3B.set(targetX,targetY,targetZ);const position=_v3A.set(positionX,positionY,positionZ);this._targetEnd.copy(target);this._sphericalEnd.setFromVector3(position.sub(target).applyQuaternion(this._yAxisUpSpace));this.normalizeRotations();this._needsUpdate=true;if(!enableTransition){this._target.copy(this._targetEnd);this._spherical.copy(this._sphericalEnd)}const resolveImmediately=!enableTransition||approxEquals(this._target.x,this._targetEnd.x,this.restThreshold)&&approxEquals(this._target.y,this._targetEnd.y,this.restThreshold)&&approxEquals(this._target.z,this._targetEnd.z,this.restThreshold)&&approxEquals(this._spherical.theta,this._sphericalEnd.theta,this.restThreshold)&&approxEquals(this._spherical.phi,this._sphericalEnd.phi,this.restThreshold)&&approxEquals(this._spherical.radius,this._sphericalEnd.radius,this.restThreshold);return this._createOnRestPromise(resolveImmediately)}lerpLookAt(positionAX,positionAY,positionAZ,targetAX,targetAY,targetAZ,positionBX,positionBY,positionBZ,targetBX,targetBY,targetBZ,t,enableTransition=false){const targetA=_v3A.set(targetAX,targetAY,targetAZ);const positionA=_v3B.set(positionAX,positionAY,positionAZ);_sphericalA.setFromVector3(positionA.sub(targetA).applyQuaternion(this._yAxisUpSpace));const targetB=_v3C.set(targetBX,targetBY,targetBZ);const positionB=_v3B.set(positionBX,positionBY,positionBZ);_sphericalB.setFromVector3(positionB.sub(targetB).applyQuaternion(this._yAxisUpSpace));this._targetEnd.copy(targetA.lerp(targetB,t));const deltaTheta=_sphericalB.theta-_sphericalA.theta;const deltaPhi=_sphericalB.phi-_sphericalA.phi;const deltaRadius=_sphericalB.radius-_sphericalA.radius;this._sphericalEnd.set(_sphericalA.radius+deltaRadius*t,_sphericalA.phi+deltaPhi*t,_sphericalA.theta+deltaTheta*t);this.normalizeRotations();this._needsUpdate=true;if(!enableTransition){this._target.copy(this._targetEnd);this._spherical.copy(this._sphericalEnd)}const resolveImmediately=!enableTransition||approxEquals(this._target.x,this._targetEnd.x,this.restThreshold)&&approxEquals(this._target.y,this._targetEnd.y,this.restThreshold)&&approxEquals(this._target.z,this._targetEnd.z,this.restThreshold)&&approxEquals(this._spherical.theta,this._sphericalEnd.theta,this.restThreshold)&&approxEquals(this._spherical.phi,this._sphericalEnd.phi,this.restThreshold)&&approxEquals(this._spherical.radius,this._sphericalEnd.radius,this.restThreshold);return this._createOnRestPromise(resolveImmediately)}setPosition(positionX,positionY,positionZ,enableTransition=false){return this.setLookAt(positionX,positionY,positionZ,this._targetEnd.x,this._targetEnd.y,this._targetEnd.z,enableTransition)}setTarget(targetX,targetY,targetZ,enableTransition=false){const pos=this.getPosition(_v3A);return this.setLookAt(pos.x,pos.y,pos.z,targetX,targetY,targetZ,enableTransition)}setFocalOffset(x,y,z,enableTransition=false){this._focalOffsetEnd.set(x,y,z);this._needsUpdate=true;if(!enableTransition){this._focalOffset.copy(this._focalOffsetEnd)}const resolveImmediately=!enableTransition||approxEquals(this._focalOffset.x,this._focalOffsetEnd.x,this.restThreshold)&&approxEquals(this._focalOffset.y,this._focalOffsetEnd.y,this.restThreshold)&&approxEquals(this._focalOffset.z,this._focalOffsetEnd.z,this.restThreshold);return this._createOnRestPromise(resolveImmediately)}setOrbitPoint(targetX,targetY,targetZ){_xColumn.setFromMatrixColumn(this._camera.matrixWorldInverse,0);_yColumn.setFromMatrixColumn(this._camera.matrixWorldInverse,1);_zColumn.setFromMatrixColumn(this._camera.matrixWorldInverse,2);const position=_v3A.set(targetX,targetY,targetZ);const distance=position.distanceTo(this._camera.position);const cameraToPoint=position.sub(this._camera.position);_xColumn.multiplyScalar(cameraToPoint.x);_yColumn.multiplyScalar(cameraToPoint.y);_zColumn.multiplyScalar(cameraToPoint.z);_v3A.copy(_xColumn).add(_yColumn).add(_zColumn);_v3A.z=_v3A.z+distance;this.dollyTo(distance,false);this.setFocalOffset(-_v3A.x,_v3A.y,-_v3A.z,false);this.moveTo(targetX,targetY,targetZ,false)}setBoundary(box3){if(!box3){this._boundary.min.set(-Infinity,-Infinity,-Infinity);this._boundary.max.set(Infinity,Infinity,Infinity);this._needsUpdate=true;return}this._boundary.copy(box3);this._boundary.clampPoint(this._targetEnd,this._targetEnd);this._needsUpdate=true}setViewport(viewportOrX,y,width,height){if(viewportOrX===null){this._viewport=null;return}this._viewport=this._viewport||new THREE.Vector4;if(typeof viewportOrX==="number"){this._viewport.set(viewportOrX,y,width,height)}else{this._viewport.copy(viewportOrX)}}getDistanceToFitBox(width,height,depth,cover=false){if(notSupportedInOrthographicCamera(this._camera,"getDistanceToFitBox"))return this._spherical.radius;const boundingRectAspect=width/height;const fov=this._camera.getEffectiveFOV()*THREE.MathUtils.DEG2RAD;const aspect=this._camera.aspect;const heightToFit=(cover?boundingRectAspect>aspect:boundingRectAspect{if(activePointer.pointerId===pointerId){pointer=activePointer;return true}return false}));return pointer}_encloseToBoundary(position,offset,friction){const offsetLength2=offset.lengthSq();if(offsetLength2===0){return position}const newTarget=_v3B.copy(offset).add(position);const clampedTarget=this._boundary.clampPoint(newTarget,_v3C);const deltaClampedTarget=clampedTarget.sub(newTarget);const deltaClampedTargetLength2=deltaClampedTarget.lengthSq();if(deltaClampedTargetLength2===0){return position.add(offset)}else if(deltaClampedTargetLength2===offsetLength2){return position}else if(friction===0){return position.add(offset).add(deltaClampedTarget)}else{const offsetFactor=1+friction*deltaClampedTargetLength2/offset.dot(deltaClampedTarget);return position.add(_v3B.copy(offset).multiplyScalar(offsetFactor)).add(deltaClampedTarget.multiplyScalar(1-friction))}}_updateNearPlaneCorners(){if(isPerspectiveCamera(this._camera)){const camera=this._camera;const near=camera.near;const fov=camera.getEffectiveFOV()*THREE.MathUtils.DEG2RAD;const heightHalf=Math.tan(fov*.5)*near;const widthHalf=heightHalf*camera.aspect;this._nearPlaneCorners[0].set(-widthHalf,-heightHalf,0);this._nearPlaneCorners[1].set(widthHalf,-heightHalf,0);this._nearPlaneCorners[2].set(widthHalf,heightHalf,0);this._nearPlaneCorners[3].set(-widthHalf,heightHalf,0)}else if(isOrthographicCamera(this._camera)){const camera=this._camera;const zoomInv=1/camera.zoom;const left=camera.left*zoomInv;const right=camera.right*zoomInv;const top=camera.top*zoomInv;const bottom=camera.bottom*zoomInv;this._nearPlaneCorners[0].set(left,top,0);this._nearPlaneCorners[1].set(right,top,0);this._nearPlaneCorners[2].set(right,bottom,0);this._nearPlaneCorners[3].set(left,bottom,0)}}_collisionTest(){let distance=Infinity;const hasCollider=this.colliderMeshes.length>=1;if(!hasCollider)return distance;if(notSupportedInOrthographicCamera(this._camera,"_collisionTest"))return distance;const direction=_v3A.setFromSpherical(this._spherical).divideScalar(this._spherical.radius);_rotationMatrix.lookAt(_ORIGIN,direction,this._camera.up);for(let i=0;i<4;i++){const nearPlaneCorner=_v3B.copy(this._nearPlaneCorners[i]);nearPlaneCorner.applyMatrix4(_rotationMatrix);const origin=_v3C.addVectors(this._target,nearPlaneCorner);_raycaster.set(origin,direction);_raycaster.far=this._spherical.radius+1;const intersects=_raycaster.intersectObjects(this.colliderMeshes);if(intersects.length!==0&&intersects[0].distance{const onResolve=()=>{this.removeEventListener("rest",onResolve);resolve()};this.addEventListener("rest",onResolve)}))}_removeAllEventListeners(){}}function createBoundingSphere(object3d,out){const boundingSphere=out;const center=boundingSphere.center;_box3A.makeEmpty();object3d.traverseVisible((object=>{if(!object.isMesh)return;_box3A.expandByObject(object)}));_box3A.getCenter(center);let maxRadiusSq=0;object3d.traverseVisible((object=>{if(!object.isMesh)return;const mesh=object;const geometry=mesh.geometry.clone();geometry.applyMatrix4(mesh.matrixWorld);if(geometry.isBufferGeometry){const bufferGeometry=geometry;const position=bufferGeometry.attributes.position;for(let i=0,l=position.count;i{out.x+=pointer.clientX;out.y+=pointer.clientY}));out.x/=pointers.length;out.y/=pointers.length}function notSupportedInOrthographicCamera(camera,message){if(isOrthographicCamera(camera)){console.warn(`${message} is not supported in OrthographicCamera`);return true}return false}function quatInvertCompat(target){if(target.invert){target.invert()}else{target.inverse()}return target}class EventDispatcher{constructor(){this._listeners={}}addEventListener(type,listener){const listeners=this._listeners;if(listeners[type]===undefined)listeners[type]=[];if(listeners[type].indexOf(listener)===-1)listeners[type].push(listener)}removeEventListener(type,listener){const listeners=this._listeners;const listenerArray=listeners[type];if(listenerArray!==undefined){const index=listenerArray.indexOf(listener);if(index!==-1)listenerArray.splice(index,1)}}removeAllEventListeners(type){if(!type){this._listeners={};return}if(Array.isArray(this._listeners[type]))this._listeners[type].length=0}dispatchEvent(event){const listeners=this._listeners;const listenerArray=listeners[event.type];if(listenerArray!==undefined){event.target=this;const array=listenerArray.slice(0);for(let i=0,l=array.length;i{};this._enabled=true;this._state=ACTION.NONE;this._viewport=null;this._dollyControlAmount=0;this._hasRested=true;this._boundaryEnclosesCamera=false;this._needsUpdate=true;this._updatedLastTime=false;this._elementRect=new DOMRect;this._activePointers=[];this._truckInternal=(deltaX,deltaY,dragToOffset)=>{if(isPerspectiveCamera(this._camera)){const offset=_v3A.copy(this._camera.position).sub(this._target);const fov=this._camera.getEffectiveFOV()*THREE.MathUtils.DEG2RAD;const targetDistance=offset.length()*Math.tan(fov*.5);const truckX=this.truckSpeed*deltaX*targetDistance/this._elementRect.height;const pedestalY=this.truckSpeed*deltaY*targetDistance/this._elementRect.height;if(this.verticalDragToForward){dragToOffset?this.setFocalOffset(this._focalOffsetEnd.x+truckX,this._focalOffsetEnd.y,this._focalOffsetEnd.z,true):this.truck(truckX,0,true);this.forward(-pedestalY,true)}else{dragToOffset?this.setFocalOffset(this._focalOffsetEnd.x+truckX,this._focalOffsetEnd.y+pedestalY,this._focalOffsetEnd.z,true):this.truck(truckX,pedestalY,true)}}else if(isOrthographicCamera(this._camera)){const camera=this._camera;const truckX=deltaX*(camera.right-camera.left)/camera.zoom/this._elementRect.width;const pedestalY=deltaY*(camera.top-camera.bottom)/camera.zoom/this._elementRect.height;dragToOffset?this.setFocalOffset(this._focalOffsetEnd.x+truckX,this._focalOffsetEnd.y+pedestalY,this._focalOffsetEnd.z,true):this.truck(truckX,pedestalY,true)}};this._rotateInternal=(deltaX,deltaY)=>{const theta=PI_2*this.azimuthRotateSpeed*deltaX/this._elementRect.height;const phi=PI_2*this.polarRotateSpeed*deltaY/this._elementRect.height;this.rotate(theta,phi,true)};this._dollyInternal=(delta,x,y)=>{const dollyScale=Math.pow(.95,-delta*this.dollySpeed);const distance=this._sphericalEnd.radius*dollyScale;const prevRadius=this._sphericalEnd.radius;const signedPrevRadius=prevRadius*(delta>=0?-1:1);this.dollyTo(distance);if(this.infinityDolly&&(distance{const zoomScale=Math.pow(.95,delta*this.dollySpeed);this.zoomTo(this._zoom*zoomScale);if(this.dollyToCursor){this._dollyControlAmount=this._zoomEnd;this._dollyControlCoord.set(x,y)}return};if(typeof THREE==="undefined"){console.error("camera-controls: `THREE` is undefined. You must first run `CameraControls.install( { THREE: THREE } )`. Check the docs for further information.")}this._camera=camera;this._yAxisUpSpace=(new THREE.Quaternion).setFromUnitVectors(this._camera.up,_AXIS_Y);this._yAxisUpSpaceInverse=quatInvertCompat(this._yAxisUpSpace.clone());this._state=ACTION.NONE;this._domElement=domElement;this._domElement.style.touchAction="none";this._domElement.style.userSelect="none";this._domElement.style.webkitUserSelect="none";this._target=new THREE.Vector3;this._targetEnd=this._target.clone();this._focalOffset=new THREE.Vector3;this._focalOffsetEnd=this._focalOffset.clone();this._spherical=(new THREE.Spherical).setFromVector3(_v3A.copy(this._camera.position).applyQuaternion(this._yAxisUpSpace));this._sphericalEnd=this._spherical.clone();this._zoom=this._camera.zoom;this._zoomEnd=this._zoom;this._nearPlaneCorners=[new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3];this._updateNearPlaneCorners();this._boundary=new THREE.Box3(new THREE.Vector3(-Infinity,-Infinity,-Infinity),new THREE.Vector3(Infinity,Infinity,Infinity));this._target0=this._target.clone();this._position0=this._camera.position.clone();this._zoom0=this._zoom;this._focalOffset0=this._focalOffset.clone();this._dollyControlAmount=0;this._dollyControlCoord=new THREE.Vector2;this.mouseButtons={left:ACTION.ROTATE,middle:ACTION.DOLLY,right:ACTION.TRUCK,wheel:isPerspectiveCamera(this._camera)?ACTION.DOLLY:isOrthographicCamera(this._camera)?ACTION.ZOOM:ACTION.NONE};this.touches={one:ACTION.TOUCH_ROTATE,two:isPerspectiveCamera(this._camera)?ACTION.TOUCH_DOLLY_TRUCK:isOrthographicCamera(this._camera)?ACTION.TOUCH_ZOOM_TRUCK:ACTION.NONE,three:ACTION.TOUCH_TRUCK};if(this._domElement){const dragStartPosition=new THREE.Vector2;const lastDragPosition=new THREE.Vector2;const dollyStart=new THREE.Vector2;const onPointerDown=event=>{if(!this._enabled)return;const pointer={pointerId:event.pointerId,clientX:event.clientX,clientY:event.clientY,deltaX:0,deltaY:0};this._activePointers.push(pointer);this._domElement.ownerDocument.removeEventListener("pointermove",onPointerMove,{passive:false});this._domElement.ownerDocument.removeEventListener("pointerup",onPointerUp);this._domElement.ownerDocument.addEventListener("pointermove",onPointerMove,{passive:false});this._domElement.ownerDocument.addEventListener("pointerup",onPointerUp);startDragging(event)};const onMouseDown=event=>{if(!this._enabled)return;const pointer={pointerId:0,clientX:event.clientX,clientY:event.clientY,deltaX:0,deltaY:0};this._activePointers.push(pointer);this._domElement.ownerDocument.removeEventListener("mousemove",onMouseMove);this._domElement.ownerDocument.removeEventListener("mouseup",onMouseUp);this._domElement.ownerDocument.addEventListener("mousemove",onMouseMove);this._domElement.ownerDocument.addEventListener("mouseup",onMouseUp);startDragging(event)};const onTouchStart=event=>{if(!this._enabled)return;event.preventDefault();Array.prototype.forEach.call(event.changedTouches,(touch=>{const pointer={pointerId:touch.identifier,clientX:touch.clientX,clientY:touch.clientY,deltaX:0,deltaY:0};this._activePointers.push(pointer)}));this._domElement.ownerDocument.removeEventListener("touchmove",onTouchMove,{passive:false});this._domElement.ownerDocument.removeEventListener("touchend",onTouchEnd);this._domElement.ownerDocument.addEventListener("touchmove",onTouchMove,{passive:false});this._domElement.ownerDocument.addEventListener("touchend",onTouchEnd);startDragging(event)};const onPointerMove=event=>{if(event.cancelable)event.preventDefault();const pointerId=event.pointerId;const pointer=this._findPointerById(pointerId);if(!pointer)return;pointer.clientX=event.clientX;pointer.clientY=event.clientY;pointer.deltaX=event.movementX;pointer.deltaY=event.movementY;if(event.pointerType==="touch"){switch(this._activePointers.length){case 1:this._state=this.touches.one;break;case 2:this._state=this.touches.two;break;case 3:this._state=this.touches.three;break}}else{this._state=0;if((event.buttons&MOUSE_BUTTON.LEFT)===MOUSE_BUTTON.LEFT){this._state=this._state|this.mouseButtons.left}if((event.buttons&MOUSE_BUTTON.MIDDLE)===MOUSE_BUTTON.MIDDLE){this._state=this._state|this.mouseButtons.middle}if((event.buttons&MOUSE_BUTTON.RIGHT)===MOUSE_BUTTON.RIGHT){this._state=this._state|this.mouseButtons.right}}dragging()};const onMouseMove=event=>{const pointer=this._findPointerById(0);if(!pointer)return;pointer.clientX=event.clientX;pointer.clientY=event.clientY;pointer.deltaX=event.movementX;pointer.deltaY=event.movementY;this._state=0;if((event.buttons&MOUSE_BUTTON.LEFT)===MOUSE_BUTTON.LEFT){this._state=this._state|this.mouseButtons.left}if((event.buttons&MOUSE_BUTTON.MIDDLE)===MOUSE_BUTTON.MIDDLE){this._state=this._state|this.mouseButtons.middle}if((event.buttons&MOUSE_BUTTON.RIGHT)===MOUSE_BUTTON.RIGHT){this._state=this._state|this.mouseButtons.right}dragging()};const onTouchMove=event=>{if(event.cancelable)event.preventDefault();Array.prototype.forEach.call(event.changedTouches,(touch=>{const pointerId=touch.identifier;const pointer=this._findPointerById(pointerId);if(!pointer)return;pointer.clientX=touch.clientX;pointer.clientY=touch.clientY}));dragging()};const onPointerUp=event=>{const pointerId=event.pointerId;const pointer=this._findPointerById(pointerId);pointer&&this._activePointers.splice(this._activePointers.indexOf(pointer),1);if(event.pointerType==="touch"){switch(this._activePointers.length){case 0:this._state=ACTION.NONE;break;case 1:this._state=this.touches.one;break;case 2:this._state=this.touches.two;break;case 3:this._state=this.touches.three;break}}else{this._state=ACTION.NONE}endDragging()};const onMouseUp=()=>{const pointer=this._findPointerById(0);pointer&&this._activePointers.splice(this._activePointers.indexOf(pointer),1);this._state=ACTION.NONE;endDragging()};const onTouchEnd=event=>{Array.prototype.forEach.call(event.changedTouches,(touch=>{const pointerId=touch.identifier;const pointer=this._findPointerById(pointerId);pointer&&this._activePointers.splice(this._activePointers.indexOf(pointer),1)}));switch(this._activePointers.length){case 0:this._state=ACTION.NONE;break;case 1:this._state=this.touches.one;break;case 2:this._state=this.touches.two;break;case 3:this._state=this.touches.three;break}endDragging()};let lastScrollTimeStamp=-1;const onMouseWheel=event=>{if(!this._enabled||this.mouseButtons.wheel===ACTION.NONE)return;event.preventDefault();if(this.dollyToCursor||this.mouseButtons.wheel===ACTION.ROTATE||this.mouseButtons.wheel===ACTION.TRUCK){const now=performance.now();if(lastScrollTimeStamp-now<1e3)this._getClientRect(this._elementRect);lastScrollTimeStamp=now}const deltaYFactor=isMac?-1:-3;const delta=event.deltaMode===1?event.deltaY/deltaYFactor:event.deltaY/(deltaYFactor*10);const x=this.dollyToCursor?(event.clientX-this._elementRect.x)/this._elementRect.width*2-1:0;const y=this.dollyToCursor?(event.clientY-this._elementRect.y)/this._elementRect.height*-2+1:0;switch(this.mouseButtons.wheel){case ACTION.ROTATE:{this._rotateInternal(event.deltaX,event.deltaY);break}case ACTION.TRUCK:{this._truckInternal(event.deltaX,event.deltaY,false);break}case ACTION.OFFSET:{this._truckInternal(event.deltaX,event.deltaY,true);break}case ACTION.DOLLY:{this._dollyInternal(-delta,x,y);break}case ACTION.ZOOM:{this._zoomInternal(-delta,x,y);break}}this.dispatchEvent({type:"control"})};const onContextMenu=event=>{if(!this._enabled)return;event.preventDefault()};const startDragging=event=>{if(!this._enabled)return;extractClientCoordFromEvent(this._activePointers,_v2);this._getClientRect(this._elementRect);dragStartPosition.copy(_v2);lastDragPosition.copy(_v2);const isMultiTouch=this._activePointers.length>=2;if(isMultiTouch){const dx=_v2.x-this._activePointers[1].clientX;const dy=_v2.y-this._activePointers[1].clientY;const distance=Math.sqrt(dx*dx+dy*dy);dollyStart.set(0,distance);const x=(this._activePointers[0].clientX+this._activePointers[1].clientX)*.5;const y=(this._activePointers[0].clientY+this._activePointers[1].clientY)*.5;lastDragPosition.set(x,y)}if("touches"in event||"pointerType"in event&&event.pointerType==="touch"){switch(this._activePointers.length){case 1:this._state=this.touches.one;break;case 2:this._state=this.touches.two;break;case 3:this._state=this.touches.three;break}}else{this._state=0;if((event.buttons&MOUSE_BUTTON.LEFT)===MOUSE_BUTTON.LEFT){this._state=this._state|this.mouseButtons.left}if((event.buttons&MOUSE_BUTTON.MIDDLE)===MOUSE_BUTTON.MIDDLE){this._state=this._state|this.mouseButtons.middle}if((event.buttons&MOUSE_BUTTON.RIGHT)===MOUSE_BUTTON.RIGHT){this._state=this._state|this.mouseButtons.right}}this.dispatchEvent({type:"controlstart"})};const dragging=()=>{if(!this._enabled)return;extractClientCoordFromEvent(this._activePointers,_v2);const isPointerLockActive=this._domElement&&document.pointerLockElement===this._domElement;const deltaX=isPointerLockActive?-this._activePointers[0].deltaX:lastDragPosition.x-_v2.x;const deltaY=isPointerLockActive?-this._activePointers[0].deltaY:lastDragPosition.y-_v2.y;lastDragPosition.copy(_v2);if((this._state&ACTION.ROTATE)===ACTION.ROTATE||(this._state&ACTION.TOUCH_ROTATE)===ACTION.TOUCH_ROTATE||(this._state&ACTION.TOUCH_DOLLY_ROTATE)===ACTION.TOUCH_DOLLY_ROTATE||(this._state&ACTION.TOUCH_ZOOM_ROTATE)===ACTION.TOUCH_ZOOM_ROTATE){this._rotateInternal(deltaX,deltaY)}if((this._state&ACTION.DOLLY)===ACTION.DOLLY||(this._state&ACTION.ZOOM)===ACTION.ZOOM){const dollyX=this.dollyToCursor?(dragStartPosition.x-this._elementRect.x)/this._elementRect.width*2-1:0;const dollyY=this.dollyToCursor?(dragStartPosition.y-this._elementRect.y)/this._elementRect.height*-2+1:0;this._state===ACTION.DOLLY?this._dollyInternal(deltaY*TOUCH_DOLLY_FACTOR,dollyX,dollyY):this._zoomInternal(deltaY*TOUCH_DOLLY_FACTOR,dollyX,dollyY)}if((this._state&ACTION.TOUCH_DOLLY)===ACTION.TOUCH_DOLLY||(this._state&ACTION.TOUCH_ZOOM)===ACTION.TOUCH_ZOOM||(this._state&ACTION.TOUCH_DOLLY_TRUCK)===ACTION.TOUCH_DOLLY_TRUCK||(this._state&ACTION.TOUCH_ZOOM_TRUCK)===ACTION.TOUCH_ZOOM_TRUCK||(this._state&ACTION.TOUCH_DOLLY_OFFSET)===ACTION.TOUCH_DOLLY_OFFSET||(this._state&ACTION.TOUCH_ZOOM_OFFSET)===ACTION.TOUCH_ZOOM_OFFSET||(this._state&ACTION.TOUCH_DOLLY_ROTATE)===ACTION.TOUCH_DOLLY_ROTATE||(this._state&ACTION.TOUCH_ZOOM_ROTATE)===ACTION.TOUCH_ZOOM_ROTATE){const dx=_v2.x-this._activePointers[1].clientX;const dy=_v2.y-this._activePointers[1].clientY;const distance=Math.sqrt(dx*dx+dy*dy);const dollyDelta=dollyStart.y-distance;dollyStart.set(0,distance);const dollyX=this.dollyToCursor?(lastDragPosition.x-this._elementRect.x)/this._elementRect.width*2-1:0;const dollyY=this.dollyToCursor?(lastDragPosition.y-this._elementRect.y)/this._elementRect.height*-2+1:0;this._state===ACTION.TOUCH_DOLLY||this._state===ACTION.TOUCH_DOLLY_ROTATE||this._state===ACTION.TOUCH_DOLLY_TRUCK||this._state===ACTION.TOUCH_DOLLY_OFFSET?this._dollyInternal(dollyDelta*TOUCH_DOLLY_FACTOR,dollyX,dollyY):this._zoomInternal(dollyDelta*TOUCH_DOLLY_FACTOR,dollyX,dollyY)}if((this._state&ACTION.TRUCK)===ACTION.TRUCK||(this._state&ACTION.TOUCH_TRUCK)===ACTION.TOUCH_TRUCK||(this._state&ACTION.TOUCH_DOLLY_TRUCK)===ACTION.TOUCH_DOLLY_TRUCK||(this._state&ACTION.TOUCH_ZOOM_TRUCK)===ACTION.TOUCH_ZOOM_TRUCK){this._truckInternal(deltaX,deltaY,false)}if((this._state&ACTION.OFFSET)===ACTION.OFFSET||(this._state&ACTION.TOUCH_OFFSET)===ACTION.TOUCH_OFFSET||(this._state&ACTION.TOUCH_DOLLY_OFFSET)===ACTION.TOUCH_DOLLY_OFFSET||(this._state&ACTION.TOUCH_ZOOM_OFFSET)===ACTION.TOUCH_ZOOM_OFFSET){this._truckInternal(deltaX,deltaY,true)}this.dispatchEvent({type:"control"})};const endDragging=()=>{extractClientCoordFromEvent(this._activePointers,_v2);lastDragPosition.copy(_v2);if(this._activePointers.length===0){this._domElement.ownerDocument.removeEventListener("pointermove",onPointerMove,{passive:false});this._domElement.ownerDocument.removeEventListener("pointerup",onPointerUp);this._domElement.ownerDocument.removeEventListener("touchmove",onTouchMove,{passive:false});this._domElement.ownerDocument.removeEventListener("touchend",onTouchEnd);this.dispatchEvent({type:"controlend"})}};this._domElement.addEventListener("pointerdown",onPointerDown);isPointerEventsNotSupported&&this._domElement.addEventListener("mousedown",onMouseDown);isPointerEventsNotSupported&&this._domElement.addEventListener("touchstart",onTouchStart);this._domElement.addEventListener("pointercancel",onPointerUp);this._domElement.addEventListener("wheel",onMouseWheel,{passive:false});this._domElement.addEventListener("contextmenu",onContextMenu);this._removeAllEventListeners=()=>{this._domElement.removeEventListener("pointerdown",onPointerDown);this._domElement.removeEventListener("mousedown",onMouseDown);this._domElement.removeEventListener("touchstart",onTouchStart);this._domElement.removeEventListener("pointercancel",onPointerUp);this._domElement.removeEventListener("wheel",onMouseWheel,{passive:false});this._domElement.removeEventListener("contextmenu",onContextMenu);this._domElement.ownerDocument.removeEventListener("pointermove",onPointerMove,{passive:false});this._domElement.ownerDocument.removeEventListener("mousemove",onMouseMove);this._domElement.ownerDocument.removeEventListener("touchmove",onTouchMove,{passive:false});this._domElement.ownerDocument.removeEventListener("pointerup",onPointerUp);this._domElement.ownerDocument.removeEventListener("mouseup",onMouseUp);this._domElement.ownerDocument.removeEventListener("touchend",onTouchEnd)};this.cancel=()=>{if(this._state===ACTION.NONE)return;this._state=ACTION.NONE;this._activePointers.length=0;endDragging()}}this.update(0)}static install(libs){THREE=libs.THREE;_ORIGIN=Object.freeze(new THREE.Vector3(0,0,0));_AXIS_Y=Object.freeze(new THREE.Vector3(0,1,0));_AXIS_Z=Object.freeze(new THREE.Vector3(0,0,1));_v2=new THREE.Vector2;_v3A=new THREE.Vector3;_v3B=new THREE.Vector3;_v3C=new THREE.Vector3;_xColumn=new THREE.Vector3;_yColumn=new THREE.Vector3;_zColumn=new THREE.Vector3;_deltaTarget=new THREE.Vector3;_deltaOffset=new THREE.Vector3;_sphericalA=new THREE.Spherical;_sphericalB=new THREE.Spherical;_box3A=new THREE.Box3;_box3B=new THREE.Box3;_sphere=new THREE.Sphere;_quaternionA=new THREE.Quaternion;_quaternionB=new THREE.Quaternion;_rotationMatrix=new THREE.Matrix4;_raycaster=new THREE.Raycaster}static get ACTION(){return ACTION}get camera(){return this._camera}set camera(camera){this._camera=camera;this.updateCameraUp();this._camera.updateProjectionMatrix();this._updateNearPlaneCorners();this._needsUpdate=true}get enabled(){return this._enabled}set enabled(enabled){this._enabled=enabled;if(enabled){this._domElement.style.touchAction="none";this._domElement.style.userSelect="none";this._domElement.style.webkitUserSelect="none"}else{this.cancel();this._domElement.style.touchAction="";this._domElement.style.userSelect="";this._domElement.style.webkitUserSelect=""}}get active(){return!this._hasRested}get currentAction(){return this._state}get distance(){return this._spherical.radius}set distance(distance){if(this._spherical.radius===distance&&this._sphericalEnd.radius===distance)return;this._spherical.radius=distance;this._sphericalEnd.radius=distance;this._needsUpdate=true}get azimuthAngle(){return this._spherical.theta}set azimuthAngle(azimuthAngle){if(this._spherical.theta===azimuthAngle&&this._sphericalEnd.theta===azimuthAngle)return;this._spherical.theta=azimuthAngle;this._sphericalEnd.theta=azimuthAngle;this._needsUpdate=true}get polarAngle(){return this._spherical.phi}set polarAngle(polarAngle){if(this._spherical.phi===polarAngle&&this._sphericalEnd.phi===polarAngle)return;this._spherical.phi=polarAngle;this._sphericalEnd.phi=polarAngle;this._needsUpdate=true}get boundaryEnclosesCamera(){return this._boundaryEnclosesCamera}set boundaryEnclosesCamera(boundaryEnclosesCamera){this._boundaryEnclosesCamera=boundaryEnclosesCamera;this._needsUpdate=true}addEventListener(type,listener){super.addEventListener(type,listener)}removeEventListener(type,listener){super.removeEventListener(type,listener)}rotate(azimuthAngle,polarAngle,enableTransition=false){return this.rotateTo(this._sphericalEnd.theta+azimuthAngle,this._sphericalEnd.phi+polarAngle,enableTransition)}rotateAzimuthTo(azimuthAngle,enableTransition=false){return this.rotateTo(azimuthAngle,this._sphericalEnd.phi,enableTransition)}rotatePolarTo(polarAngle,enableTransition=false){return this.rotateTo(this._sphericalEnd.theta,polarAngle,enableTransition)}rotateTo(azimuthAngle,polarAngle,enableTransition=false){const theta=THREE.MathUtils.clamp(azimuthAngle,this.minAzimuthAngle,this.maxAzimuthAngle);const phi=THREE.MathUtils.clamp(polarAngle,this.minPolarAngle,this.maxPolarAngle);this._sphericalEnd.theta=theta;this._sphericalEnd.phi=phi;this._sphericalEnd.makeSafe();this._needsUpdate=true;if(!enableTransition){this._spherical.theta=this._sphericalEnd.theta;this._spherical.phi=this._sphericalEnd.phi}const resolveImmediately=!enableTransition||approxEquals(this._spherical.theta,this._sphericalEnd.theta,this.restThreshold)&&approxEquals(this._spherical.phi,this._sphericalEnd.phi,this.restThreshold);return this._createOnRestPromise(resolveImmediately)}dolly(distance,enableTransition=false){return this.dollyTo(this._sphericalEnd.radius-distance,enableTransition)}dollyTo(distance,enableTransition=false){const lastRadius=this._sphericalEnd.radius;const newRadius=THREE.MathUtils.clamp(distance,this.minDistance,this.maxDistance);const hasCollider=this.colliderMeshes.length>=1;if(hasCollider){const maxDistanceByCollisionTest=this._collisionTest();const isCollided=approxEquals(maxDistanceByCollisionTest,this._spherical.radius);const isDollyIn=lastRadius>newRadius;if(!isDollyIn&&isCollided)return Promise.resolve();this._sphericalEnd.radius=Math.min(newRadius,maxDistanceByCollisionTest)}else{this._sphericalEnd.radius=newRadius}this._needsUpdate=true;if(!enableTransition){this._spherical.radius=this._sphericalEnd.radius}const resolveImmediately=!enableTransition||approxEquals(this._spherical.radius,this._sphericalEnd.radius,this.restThreshold);return this._createOnRestPromise(resolveImmediately)}zoom(zoomStep,enableTransition=false){return this.zoomTo(this._zoomEnd+zoomStep,enableTransition)}zoomTo(zoom,enableTransition=false){this._zoomEnd=THREE.MathUtils.clamp(zoom,this.minZoom,this.maxZoom);this._needsUpdate=true;if(!enableTransition){this._zoom=this._zoomEnd}const resolveImmediately=!enableTransition||approxEquals(this._zoom,this._zoomEnd,this.restThreshold);return this._createOnRestPromise(resolveImmediately)}pan(x,y,enableTransition=false){console.warn("`pan` has been renamed to `truck`");return this.truck(x,y,enableTransition)}truck(x,y,enableTransition=false){this._camera.updateMatrix();_xColumn.setFromMatrixColumn(this._camera.matrix,0);_yColumn.setFromMatrixColumn(this._camera.matrix,1);_xColumn.multiplyScalar(x);_yColumn.multiplyScalar(-y);const offset=_v3A.copy(_xColumn).add(_yColumn);const to=_v3B.copy(this._targetEnd).add(offset);return this.moveTo(to.x,to.y,to.z,enableTransition)}forward(distance,enableTransition=false){_v3A.setFromMatrixColumn(this._camera.matrix,0);_v3A.crossVectors(this._camera.up,_v3A);_v3A.multiplyScalar(distance);const to=_v3B.copy(this._targetEnd).add(_v3A);return this.moveTo(to.x,to.y,to.z,enableTransition)}moveTo(x,y,z,enableTransition=false){const offset=_v3A.set(x,y,z).sub(this._targetEnd);this._encloseToBoundary(this._targetEnd,offset,this.boundaryFriction);this._needsUpdate=true;if(!enableTransition){this._target.copy(this._targetEnd)}const resolveImmediately=!enableTransition||approxEquals(this._target.x,this._targetEnd.x,this.restThreshold)&&approxEquals(this._target.y,this._targetEnd.y,this.restThreshold)&&approxEquals(this._target.z,this._targetEnd.z,this.restThreshold);return this._createOnRestPromise(resolveImmediately)}fitToBox(box3OrObject,enableTransition,{cover:cover=false,paddingLeft:paddingLeft=0,paddingRight:paddingRight=0,paddingBottom:paddingBottom=0,paddingTop:paddingTop=0}={}){const promises=[];const aabb=box3OrObject.isBox3?_box3A.copy(box3OrObject):_box3A.setFromObject(box3OrObject);if(aabb.isEmpty()){console.warn("camera-controls: fitTo() cannot be used with an empty box. Aborting");Promise.resolve()}const theta=roundToStep(this._sphericalEnd.theta,PI_HALF);const phi=roundToStep(this._sphericalEnd.phi,PI_HALF);promises.push(this.rotateTo(theta,phi,enableTransition));const normal=_v3A.setFromSpherical(this._sphericalEnd).normalize();const rotation=_quaternionA.setFromUnitVectors(normal,_AXIS_Z);const viewFromPolar=approxEquals(Math.abs(normal.y),1);if(viewFromPolar){rotation.multiply(_quaternionB.setFromAxisAngle(_AXIS_Y,theta))}rotation.multiply(this._yAxisUpSpaceInverse);const bb=_box3B.makeEmpty();_v3B.copy(aabb.min).applyQuaternion(rotation);bb.expandByPoint(_v3B);_v3B.copy(aabb.min).setX(aabb.max.x).applyQuaternion(rotation);bb.expandByPoint(_v3B);_v3B.copy(aabb.min).setY(aabb.max.y).applyQuaternion(rotation);bb.expandByPoint(_v3B);_v3B.copy(aabb.max).setZ(aabb.min.z).applyQuaternion(rotation);bb.expandByPoint(_v3B);_v3B.copy(aabb.min).setZ(aabb.max.z).applyQuaternion(rotation);bb.expandByPoint(_v3B);_v3B.copy(aabb.max).setY(aabb.min.y).applyQuaternion(rotation);bb.expandByPoint(_v3B);_v3B.copy(aabb.max).setX(aabb.min.x).applyQuaternion(rotation);bb.expandByPoint(_v3B);_v3B.copy(aabb.max).applyQuaternion(rotation);bb.expandByPoint(_v3B);bb.min.x-=paddingLeft;bb.min.y-=paddingBottom;bb.max.x+=paddingRight;bb.max.y+=paddingTop;rotation.setFromUnitVectors(_AXIS_Z,normal);if(viewFromPolar){rotation.premultiply(_quaternionB.invert())}rotation.premultiply(this._yAxisUpSpace);const bbSize=bb.getSize(_v3A);const center=bb.getCenter(_v3B).applyQuaternion(rotation);if(isPerspectiveCamera(this._camera)){const distance=this.getDistanceToFitBox(bbSize.x,bbSize.y,bbSize.z,cover);promises.push(this.moveTo(center.x,center.y,center.z,enableTransition));promises.push(this.dollyTo(distance,enableTransition));promises.push(this.setFocalOffset(0,0,0,enableTransition))}else if(isOrthographicCamera(this._camera)){const camera=this._camera;const width=camera.right-camera.left;const height=camera.top-camera.bottom;const zoom=cover?Math.max(width/bbSize.x,height/bbSize.y):Math.min(width/bbSize.x,height/bbSize.y);promises.push(this.moveTo(center.x,center.y,center.z,enableTransition));promises.push(this.zoomTo(zoom,enableTransition));promises.push(this.setFocalOffset(0,0,0,enableTransition))}return Promise.all(promises)}fitToSphere(sphereOrMesh,enableTransition){const promises=[];const isSphere=sphereOrMesh instanceof THREE.Sphere;const boundingSphere=isSphere?_sphere.copy(sphereOrMesh):createBoundingSphere(sphereOrMesh,_sphere);promises.push(this.moveTo(boundingSphere.center.x,boundingSphere.center.y,boundingSphere.center.z,enableTransition));if(isPerspectiveCamera(this._camera)){const distanceToFit=this.getDistanceToFitSphere(boundingSphere.radius);promises.push(this.dollyTo(distanceToFit,enableTransition))}else if(isOrthographicCamera(this._camera)){const width=this._camera.right-this._camera.left;const height=this._camera.top-this._camera.bottom;const diameter=2*boundingSphere.radius;const zoom=Math.min(width/diameter,height/diameter);promises.push(this.zoomTo(zoom,enableTransition))}promises.push(this.setFocalOffset(0,0,0,enableTransition));return Promise.all(promises)}setLookAt(positionX,positionY,positionZ,targetX,targetY,targetZ,enableTransition=false){const target=_v3B.set(targetX,targetY,targetZ);const position=_v3A.set(positionX,positionY,positionZ);this._targetEnd.copy(target);this._sphericalEnd.setFromVector3(position.sub(target).applyQuaternion(this._yAxisUpSpace));this.normalizeRotations();this._needsUpdate=true;if(!enableTransition){this._target.copy(this._targetEnd);this._spherical.copy(this._sphericalEnd)}const resolveImmediately=!enableTransition||approxEquals(this._target.x,this._targetEnd.x,this.restThreshold)&&approxEquals(this._target.y,this._targetEnd.y,this.restThreshold)&&approxEquals(this._target.z,this._targetEnd.z,this.restThreshold)&&approxEquals(this._spherical.theta,this._sphericalEnd.theta,this.restThreshold)&&approxEquals(this._spherical.phi,this._sphericalEnd.phi,this.restThreshold)&&approxEquals(this._spherical.radius,this._sphericalEnd.radius,this.restThreshold);return this._createOnRestPromise(resolveImmediately)}lerpLookAt(positionAX,positionAY,positionAZ,targetAX,targetAY,targetAZ,positionBX,positionBY,positionBZ,targetBX,targetBY,targetBZ,t,enableTransition=false){const targetA=_v3A.set(targetAX,targetAY,targetAZ);const positionA=_v3B.set(positionAX,positionAY,positionAZ);_sphericalA.setFromVector3(positionA.sub(targetA).applyQuaternion(this._yAxisUpSpace));const targetB=_v3C.set(targetBX,targetBY,targetBZ);const positionB=_v3B.set(positionBX,positionBY,positionBZ);_sphericalB.setFromVector3(positionB.sub(targetB).applyQuaternion(this._yAxisUpSpace));this._targetEnd.copy(targetA.lerp(targetB,t));const deltaTheta=_sphericalB.theta-_sphericalA.theta;const deltaPhi=_sphericalB.phi-_sphericalA.phi;const deltaRadius=_sphericalB.radius-_sphericalA.radius;this._sphericalEnd.set(_sphericalA.radius+deltaRadius*t,_sphericalA.phi+deltaPhi*t,_sphericalA.theta+deltaTheta*t);this.normalizeRotations();this._needsUpdate=true;if(!enableTransition){this._target.copy(this._targetEnd);this._spherical.copy(this._sphericalEnd)}const resolveImmediately=!enableTransition||approxEquals(this._target.x,this._targetEnd.x,this.restThreshold)&&approxEquals(this._target.y,this._targetEnd.y,this.restThreshold)&&approxEquals(this._target.z,this._targetEnd.z,this.restThreshold)&&approxEquals(this._spherical.theta,this._sphericalEnd.theta,this.restThreshold)&&approxEquals(this._spherical.phi,this._sphericalEnd.phi,this.restThreshold)&&approxEquals(this._spherical.radius,this._sphericalEnd.radius,this.restThreshold);return this._createOnRestPromise(resolveImmediately)}setPosition(positionX,positionY,positionZ,enableTransition=false){return this.setLookAt(positionX,positionY,positionZ,this._targetEnd.x,this._targetEnd.y,this._targetEnd.z,enableTransition)}setTarget(targetX,targetY,targetZ,enableTransition=false){const pos=this.getPosition(_v3A);return this.setLookAt(pos.x,pos.y,pos.z,targetX,targetY,targetZ,enableTransition)}setFocalOffset(x,y,z,enableTransition=false){this._focalOffsetEnd.set(x,y,z);this._needsUpdate=true;if(!enableTransition){this._focalOffset.copy(this._focalOffsetEnd)}const resolveImmediately=!enableTransition||approxEquals(this._focalOffset.x,this._focalOffsetEnd.x,this.restThreshold)&&approxEquals(this._focalOffset.y,this._focalOffsetEnd.y,this.restThreshold)&&approxEquals(this._focalOffset.z,this._focalOffsetEnd.z,this.restThreshold);return this._createOnRestPromise(resolveImmediately)}setOrbitPoint(targetX,targetY,targetZ){_xColumn.setFromMatrixColumn(this._camera.matrixWorldInverse,0);_yColumn.setFromMatrixColumn(this._camera.matrixWorldInverse,1);_zColumn.setFromMatrixColumn(this._camera.matrixWorldInverse,2);const position=_v3A.set(targetX,targetY,targetZ);const distance=position.distanceTo(this._camera.position);const cameraToPoint=position.sub(this._camera.position);_xColumn.multiplyScalar(cameraToPoint.x);_yColumn.multiplyScalar(cameraToPoint.y);_zColumn.multiplyScalar(cameraToPoint.z);_v3A.copy(_xColumn).add(_yColumn).add(_zColumn);_v3A.z=_v3A.z+distance;this.dollyTo(distance,false);this.setFocalOffset(-_v3A.x,_v3A.y,-_v3A.z,false);this.moveTo(targetX,targetY,targetZ,false)}setBoundary(box3){if(!box3){this._boundary.min.set(-Infinity,-Infinity,-Infinity);this._boundary.max.set(Infinity,Infinity,Infinity);this._needsUpdate=true;return}this._boundary.copy(box3);this._boundary.clampPoint(this._targetEnd,this._targetEnd);this._needsUpdate=true}setViewport(viewportOrX,y,width,height){if(viewportOrX===null){this._viewport=null;return}this._viewport=this._viewport||new THREE.Vector4;if(typeof viewportOrX==="number"){this._viewport.set(viewportOrX,y,width,height)}else{this._viewport.copy(viewportOrX)}}getDistanceToFitBox(width,height,depth,cover=false){if(notSupportedInOrthographicCamera(this._camera,"getDistanceToFitBox"))return this._spherical.radius;const boundingRectAspect=width/height;const fov=this._camera.getEffectiveFOV()*THREE.MathUtils.DEG2RAD;const aspect=this._camera.aspect;const heightToFit=(cover?boundingRectAspect>aspect:boundingRectAspect{if(activePointer.pointerId===pointerId){pointer=activePointer;return true}return false}));return pointer}_encloseToBoundary(position,offset,friction){const offsetLength2=offset.lengthSq();if(offsetLength2===0){return position}const newTarget=_v3B.copy(offset).add(position);const clampedTarget=this._boundary.clampPoint(newTarget,_v3C);const deltaClampedTarget=clampedTarget.sub(newTarget);const deltaClampedTargetLength2=deltaClampedTarget.lengthSq();if(deltaClampedTargetLength2===0){return position.add(offset)}else if(deltaClampedTargetLength2===offsetLength2){return position}else if(friction===0){return position.add(offset).add(deltaClampedTarget)}else{const offsetFactor=1+friction*deltaClampedTargetLength2/offset.dot(deltaClampedTarget);return position.add(_v3B.copy(offset).multiplyScalar(offsetFactor)).add(deltaClampedTarget.multiplyScalar(1-friction))}}_updateNearPlaneCorners(){if(isPerspectiveCamera(this._camera)){const camera=this._camera;const near=camera.near;const fov=camera.getEffectiveFOV()*THREE.MathUtils.DEG2RAD;const heightHalf=Math.tan(fov*.5)*near;const widthHalf=heightHalf*camera.aspect;this._nearPlaneCorners[0].set(-widthHalf,-heightHalf,0);this._nearPlaneCorners[1].set(widthHalf,-heightHalf,0);this._nearPlaneCorners[2].set(widthHalf,heightHalf,0);this._nearPlaneCorners[3].set(-widthHalf,heightHalf,0)}else if(isOrthographicCamera(this._camera)){const camera=this._camera;const zoomInv=1/camera.zoom;const left=camera.left*zoomInv;const right=camera.right*zoomInv;const top=camera.top*zoomInv;const bottom=camera.bottom*zoomInv;this._nearPlaneCorners[0].set(left,top,0);this._nearPlaneCorners[1].set(right,top,0);this._nearPlaneCorners[2].set(right,bottom,0);this._nearPlaneCorners[3].set(left,bottom,0)}}_collisionTest(){let distance=Infinity;const hasCollider=this.colliderMeshes.length>=1;if(!hasCollider)return distance;if(notSupportedInOrthographicCamera(this._camera,"_collisionTest"))return distance;const direction=_v3A.setFromSpherical(this._spherical).divideScalar(this._spherical.radius);_rotationMatrix.lookAt(_ORIGIN,direction,this._camera.up);for(let i=0;i<4;i++){const nearPlaneCorner=_v3B.copy(this._nearPlaneCorners[i]);nearPlaneCorner.applyMatrix4(_rotationMatrix);const origin=_v3C.addVectors(this._target,nearPlaneCorner);_raycaster.set(origin,direction);_raycaster.far=this._spherical.radius+1;const intersects=_raycaster.intersectObjects(this.colliderMeshes);if(intersects.length!==0&&intersects[0].distance{const onResolve=()=>{this.removeEventListener("rest",onResolve);resolve()};this.addEventListener("rest",onResolve)}))}_removeAllEventListeners(){}}function createBoundingSphere(object3d,out){const boundingSphere=out;const center=boundingSphere.center;_box3A.makeEmpty();object3d.traverseVisible((object=>{if(!object.isMesh)return;_box3A.expandByObject(object)}));_box3A.getCenter(center);let maxRadiusSq=0;object3d.traverseVisible((object=>{if(!object.isMesh)return;const mesh=object;const geometry=mesh.geometry.clone();geometry.applyMatrix4(mesh.matrixWorld);if(geometry.isBufferGeometry){const bufferGeometry=geometry;const position=bufferGeometry.attributes.position;for(let i=0,l=position.count;i