import { Event as Event3 , EventDispatcher , Quaternion , Vector3 } from "three" ; import { MovementState } from "./MovementState" ; import { ControlMode } from "../core" ; import { Settings } from "../settings" ; import { ScalarDamper } from "../math" ; import { Updatable } from "../core" ; import { MILLISECONDS_TO_SECONDS } from "../core/time" ; import * as axes from "../core/axes" ; const v = new Vector3 ( ) ; /**
 * A translation manager.
 */ export class TranslationManager extends EventDispatcher implements Updatable { /**
     * The current position.
     */ private position : Vector3 ; /**
     * The quaternion.
     */ private quaternion : Quaternion ; /**
     * The current target.
     */ private target : Vector3 ; /**
     * The settings.
     */ private settings : Settings ; /**
     * The current movement state.
     */ private movementState : MovementState ; /**
     * The current velocity.
     */ private velocity0 : Vector3 ; /**
     * The target velocity.
     */ private velocity1 : Vector3 ; /**
     * Scalar dampers.
     */ private scalarDampers : ScalarDamper [ ] ; /**
     * A timestamp.
     */ private timestamp : number ; /**
     * A reusable update event.
     */ private updateEvent : Event3 ; param position param quaternion param target param settings constructor ( position , quaternion , target , settings ) { super ( ) ; this . position = position ; this . quaternion = quaternion ; this . target = target ; this . settings = settings ; this . movementState = new MovementState ( ) ; this . velocity0 = new Vector3 ( ) ; this . velocity1 = new Vector3 ( ) ; this . timestamp = 0 ; this . updateEvent = { type : "update" } ; this . scalarDampers = [ new ScalarDamper ( ) , new ScalarDamper ( ) , new ScalarDamper ( ) ] ; } return getMovementState ( ) { return this . movementState ; } param position return setPosition ( position ) { this . position = position ; return this ; } param quaternion return setQuaternion ( quaternion ) { this . quaternion = quaternion ; return this ; } param target return setTarget ( target ) { this . target = target ; return this ; } return resetVelocity ( ) { this . velocity0 . set ( 0 , 0 , 0 ) ; this . velocity1 . set ( 0 , 0 , 0 ) ; for ( const scalarDamper of this . scalarDampers ) { scalarDamper . resetVelocity ( ) ; } } param axis param distance private translateOnAxis ( axis , distance ) { v . copy ( axis ) . applyQuaternion ( this . quaternion ) . multiplyScalar ( distance ) ; this . position . add ( v ) ; if ( this . settings . general . getMode ( ) === ControlMode . THIRD_PERSON ) { this . target . add ( v ) ; } } param elapsed private translate ( elapsed ) { const v = this . velocity0 ; if ( v . x !== 0.0 ) { this . translateOnAxis ( axes . x , v . x * elapsed ) ; } if ( v . y !== 0.0 ) { this . translateOnAxis ( axes . y , v . y * elapsed ) ; } if ( v . z !== 0.0 ) { this . translateOnAxis ( axes . z , v . z * elapsed ) ; } this . dispatchEvent ( this . updateEvent ) ; } update ( timestamp ) { const settings = this . settings ; if ( settings . translation . isEnabled ( ) ) { const state = this . movementState ; const translation = this . settings . translation ; const boost = state . boost ? translation . getBoostMultiplier ( ) : 1.0 ; const sensitivity = translation . getSensitivity ( ) ; const scalarDampers = this . scalarDampers ; const v0 = this . velocity0 ; const v1 = this . velocity1 ; const elapsed = ( timestamp - this . timestamp ) * MILLISECONDS_TO_SECONDS ; const speed = sensitivity * boost ; v1 . setScalar ( 0.0 ) ; if ( state . active ) { if ( state . backward && state . forward ) { v1 . z = state . backwardBeforeForward ? speed : - speed ; } else if ( state . backward ) { v1 . z = speed ; } else if ( state . forward ) { v1 . z = - speed ; } if ( state . right && state . left ) { v1 . x = state . rightBeforeLeft ? speed : - speed ; } else if ( state . right ) { v1 . x = speed ; } else if ( state . left ) { v1 . x = - speed ; } if ( state . up && state . down ) { v1 . y = state . upBeforeDown ? speed : - speed ; } else if ( state . up ) { v1 . y = speed ; } else if ( state . down ) { v1 . y = - speed ; } } if ( ! v0 . equals ( v1 ) ) { if ( translation . getDamping ( ) > 0.0 ) { const damping = translation . getDamping ( ) ; const omega = ScalarDamper . calculateOmega ( damping ) ; const exp = ScalarDamper . calculateExp ( omega , elapsed ) ; v0 . x = scalarDampers [ 0 ] . interpolate ( v0 . x , v1 . x , damping , omega , exp , elapsed ) ; v0 . y = scalarDampers [ 1 ] . interpolate ( v0 . y , v1 . y , damping , omega , exp , elapsed ) ; v0 . z = scalarDampers [ 2 ] . interpolate ( v0 . z , v1 . z , damping , omega , exp , elapsed ) ; } else { v0 . copy ( v1 ) ; } } if ( v0 . x !== 0.0 || v0 . y !== 0.0 || v0 . z !== 0.0 ) { this . translate ( elapsed ) ; } } this . timestamp = timestamp ; } }