import { mat4 , vec2 , vec3 } from 'gl-matrix' ; import { m4 , v3 } from './gl-matrix-extensions' ; import { CameraModifier } from './cameramodifier' ; /**
 * Math for camera modification based on the first person metaphor.
 */ export class FirstPersonModifier extends CameraModifier { protected static readonly DEFAULT_SENSITIVITY = 0.0008 ; /**
     * Current rotation matrix.
     */ protected _rotation : mat4 = mat4 . create ( ) ; see sensitivity protected _sensitivity : number = FirstPersonModifier . DEFAULT_SENSITIVITY ; param point initiate ( point ) { Object . assign ( this . _reference , this . _camera ) ; this . _initialPoint = point ; } param point process ( point , movement ? ) { this . _currentPoint = point ; const magnitudes = vec2 . create ( ) ; if ( movement === undefined ) { vec2 . subtract ( magnitudes , this . _initialPoint , this . _currentPoint ) ; } else { vec2 . copy ( magnitudes , movement ) ; } vec2 . scale ( magnitudes , magnitudes , window . devicePixelRatio * this . _sensitivity ) ; vec2 . copy ( this . _initialPoint , this . _currentPoint ) ; const centerToEye = vec3 . sub ( v3 ( ) , this . _reference . eye , this . _reference . center ) ; vec3 . normalize ( centerToEye , centerToEye ) ; const strafe = vec3 . cross ( v3 ( ) , centerToEye , this . _reference . up ) ; const yaw = mat4 . fromRotation ( m4 ( ) , - magnitudes [ 0 ] , this . _reference . up ) ; const pitch = mat4 . fromRotation ( m4 ( ) , magnitudes [ 1 ] , strafe ) ; mat4 . mul ( this . _rotation , pitch , yaw ) ; this . update ( ) ; } /**
     * Actually applies the trackball rotation to the given camera.
     */ update ( ) { if ( this . _camera === undefined ) { return ; } const T = mat4 . fromTranslation ( m4 ( ) , this . _reference . eye ) ; mat4 . multiply ( T , T , this . _rotation ) ; mat4 . translate ( T , T , vec3 . negate ( v3 ( ) , this . _reference . eye ) ) ; const center = vec3 . transformMat4 ( v3 ( ) , this . _reference . center , T ) ; this . _camera . center = center ; Object . assign ( this . _reference , this . _camera ) ; } /**
     * Rotational sensitivity.
     */ set sensitivity ( sensitivity ) { this . _sensitivity = sensitivity ; } get sensitivity ( ) : number { return this . _sensitivity ; } }