import { mat4 , vec3 } from "gl-matrix" ; import { AbstractCamera , ICameraOptions } from "./AbstractCamera" ; import * as InteractionEvents from "normalized-interaction-events" ; import * as IntertialTurntableCamera from "inertial-turntable-camera" ; export class SphericalCamera extends AbstractCamera { private _instance : any = null ; param options public constructor ( options ? ) { super ( options ) ; const instance = IntertialTurntableCamera . default ( { phi : 0.5 , theta : 1 , aspectRatio : this . getAspect ( ) , distance : 2 } ) ; { instance . params . near = 0.01 ; instance . params . far = 8192.0 ; instance . params . panDecayTime = 50 ; instance . params . zoomDecayTime = 50 ; instance . params . rotationDecayTime = 50 ; instance . params . zoomAboutCursor = false ; instance . params . rotateAboutCenter = true ; const prevYRange = instance . params . distance * Math . tan ( instance . params . fovY * 0.5 ) ; instance . params . fovY = 40 * Math . PI / 180.0 ; instance . params . distance = prevYRange / Math . tan ( instance . params . fovY * 0.5 ) ; } this . _instance = instance ; } /**
     * The instance of the spherical camera
     */ public getInstance ( ) { return this . _instance ; } param element public attachControl ( element ) { InteractionEvents . default ( element ) . on ( "wheel" , ( e ) => { this . _instance . zoom ( e . x , e . y , Math . exp ( - e . dy * 0.5 ) - 1.0 ) ; e . originalEvent . preventDefault ( ) ; } ) . on ( "mousemove" , ( e ) => { if ( ! e . active ) return ; if ( e . buttons === 2 ) { if ( e . mods . shift ) { this . _instance . pan ( e . dx , e . dy ) ; } else { this . _instance . rotate ( - e . dx * Math . PI * 0.5 , - e . dy * Math . PI * 0.5 ) ; } } else if ( e . buttons === 4 ) { this . _instance . pan ( e . dx , e . dy ) ; } e . originalEvent . preventDefault ( ) ; } ) ; { this . setWidth ( element . width ) ; this . setHeight ( element . height ) ; } } param width param height public resize ( width , height ) { this . _instance . resize ( width / height ) ; super . resize ( width , height ) ; } /**
     * Should be called every frame
     */ public update ( ) { this . getInstance ( ) . tick ( { near : this . getInstance ( ) . params . distance * 0.01 , far : ( this . getInstance ( ) . params . distance * 2 ) + 200 } ) ; const mView = this . _instance . state . view ; const mProjection = this . _instance . state . projection ; this . updateTransforms ( mView , mProjection ) ; this . updateFrustum ( ) ; this . emit ( "update" ) ; } /**
     * Destroy this Object
     */ public destroy ( ) { this . _instance = null ; super . destroy ( ) ; } param mCameraView param mCameraProjection public updateTransforms ( mCameraView , mCameraProjection ) { super . updateTransforms ( mCameraView , mCameraProjection ) ; const vTranslation = this . _instance . state . eye ; vec3 . copy ( this . getTranslation ( ) , vTranslation ) ; } }