{"version":3,"file":"FlyControls.cjs","sources":["../../src/controls/FlyControls.ts"],"sourcesContent":["import { Camera, EventDispatcher, Quaternion, Vector3 } from 'three'\n\nfunction contextmenu(event: Event): void {\n  event.preventDefault()\n}\n\nclass FlyControls extends EventDispatcher {\n  public object: Camera\n  public domElement: HTMLElement | Document = null!\n\n  public movementSpeed = 1.0\n  public rollSpeed = 0.005\n\n  public dragToLook = false\n  public autoForward = false\n\n  private changeEvent = { type: 'change' }\n  private EPS = 0.000001\n\n  private tmpQuaternion = new Quaternion()\n\n  private mouseStatus = 0\n\n  private movementSpeedMultiplier = 1\n\n  private moveState = {\n    up: 0,\n    down: 0,\n    left: 0,\n    right: 0,\n    forward: 0,\n    back: 0,\n    pitchUp: 0,\n    pitchDown: 0,\n    yawLeft: 0,\n    yawRight: 0,\n    rollLeft: 0,\n    rollRight: 0,\n  }\n  private moveVector = new Vector3(0, 0, 0)\n  private rotationVector = new Vector3(0, 0, 0)\n\n  constructor(object: Camera, domElement?: HTMLElement | Document) {\n    super()\n\n    this.object = object\n\n    // connect events\n    if (domElement !== undefined) this.connect(domElement)\n\n    this.updateMovementVector()\n    this.updateRotationVector()\n  }\n\n  private keydown = (event: KeyboardEvent): void => {\n    if (event.altKey) {\n      return\n    }\n\n    switch (event.code) {\n      case 'ShiftLeft':\n      case 'ShiftRight':\n        this.movementSpeedMultiplier = 0.1\n        break\n\n      case 'KeyW':\n        this.moveState.forward = 1\n        break\n      case 'KeyS':\n        this.moveState.back = 1\n        break\n\n      case 'KeyA':\n        this.moveState.left = 1\n        break\n      case 'KeyD':\n        this.moveState.right = 1\n        break\n\n      case 'KeyR':\n        this.moveState.up = 1\n        break\n      case 'KeyF':\n        this.moveState.down = 1\n        break\n\n      case 'ArrowUp':\n        this.moveState.pitchUp = 1\n        break\n      case 'ArrowDown':\n        this.moveState.pitchDown = 1\n        break\n\n      case 'ArrowLeft':\n        this.moveState.yawLeft = 1\n        break\n      case 'ArrowRight':\n        this.moveState.yawRight = 1\n        break\n\n      case 'KeyQ':\n        this.moveState.rollLeft = 1\n        break\n      case 'KeyE':\n        this.moveState.rollRight = 1\n        break\n    }\n\n    this.updateMovementVector()\n    this.updateRotationVector()\n  }\n\n  private keyup = (event: KeyboardEvent): void => {\n    switch (event.code) {\n      case 'ShiftLeft':\n      case 'ShiftRight':\n        this.movementSpeedMultiplier = 1\n        break\n\n      case 'KeyW':\n        this.moveState.forward = 0\n        break\n      case 'KeyS':\n        this.moveState.back = 0\n        break\n\n      case 'KeyA':\n        this.moveState.left = 0\n        break\n      case 'KeyD':\n        this.moveState.right = 0\n        break\n\n      case 'KeyR':\n        this.moveState.up = 0\n        break\n      case 'KeyF':\n        this.moveState.down = 0\n        break\n\n      case 'ArrowUp':\n        this.moveState.pitchUp = 0\n        break\n      case 'ArrowDown':\n        this.moveState.pitchDown = 0\n        break\n\n      case 'ArrowLeft':\n        this.moveState.yawLeft = 0\n        break\n      case 'ArrowRight':\n        this.moveState.yawRight = 0\n        break\n\n      case 'KeyQ':\n        this.moveState.rollLeft = 0\n        break\n      case 'KeyE':\n        this.moveState.rollRight = 0\n        break\n    }\n\n    this.updateMovementVector()\n    this.updateRotationVector()\n  }\n\n  private pointerdown = (event: MouseEvent): void => {\n    if (this.dragToLook) {\n      this.mouseStatus++\n    } else {\n      switch (event.button) {\n        case 0:\n          this.moveState.forward = 1\n          break\n        case 2:\n          this.moveState.back = 1\n          break\n      }\n\n      this.updateMovementVector()\n    }\n  }\n\n  private pointermove = (event: MouseEvent): void => {\n    if (!this.dragToLook || this.mouseStatus > 0) {\n      const container = this.getContainerDimensions()\n      const halfWidth = container.size[0] / 2\n      const halfHeight = container.size[1] / 2\n\n      this.moveState.yawLeft = -(event.pageX - container.offset[0] - halfWidth) / halfWidth\n      this.moveState.pitchDown = (event.pageY - container.offset[1] - halfHeight) / halfHeight\n\n      this.updateRotationVector()\n    }\n  }\n\n  private pointerup = (event: MouseEvent): void => {\n    if (this.dragToLook) {\n      this.mouseStatus--\n\n      this.moveState.yawLeft = this.moveState.pitchDown = 0\n    } else {\n      switch (event.button) {\n        case 0:\n          this.moveState.forward = 0\n          break\n        case 2:\n          this.moveState.back = 0\n          break\n      }\n\n      this.updateMovementVector()\n    }\n\n    this.updateRotationVector()\n  }\n\n  private lastQuaternion = new Quaternion()\n  private lastPosition = new Vector3()\n\n  public update = (delta: number): void => {\n    const moveMult = delta * this.movementSpeed\n    const rotMult = delta * this.rollSpeed\n\n    this.object.translateX(this.moveVector.x * moveMult)\n    this.object.translateY(this.moveVector.y * moveMult)\n    this.object.translateZ(this.moveVector.z * moveMult)\n\n    this.tmpQuaternion\n      .set(this.rotationVector.x * rotMult, this.rotationVector.y * rotMult, this.rotationVector.z * rotMult, 1)\n      .normalize()\n    this.object.quaternion.multiply(this.tmpQuaternion)\n\n    if (\n      this.lastPosition.distanceToSquared(this.object.position) > this.EPS ||\n      8 * (1 - this.lastQuaternion.dot(this.object.quaternion)) > this.EPS\n    ) {\n      // @ts-ignore\n      this.dispatchEvent(this.changeEvent)\n      this.lastQuaternion.copy(this.object.quaternion)\n      this.lastPosition.copy(this.object.position)\n    }\n  }\n\n  private updateMovementVector = (): void => {\n    const forward = this.moveState.forward || (this.autoForward && !this.moveState.back) ? 1 : 0\n\n    this.moveVector.x = -this.moveState.left + this.moveState.right\n    this.moveVector.y = -this.moveState.down + this.moveState.up\n    this.moveVector.z = -forward + this.moveState.back\n  }\n\n  private updateRotationVector = (): void => {\n    this.rotationVector.x = -this.moveState.pitchDown + this.moveState.pitchUp\n    this.rotationVector.y = -this.moveState.yawRight + this.moveState.yawLeft\n    this.rotationVector.z = -this.moveState.rollRight + this.moveState.rollLeft\n  }\n\n  private getContainerDimensions = (): {\n    size: number[]\n    offset: number[]\n  } => {\n    if (this.domElement != document && !(this.domElement instanceof Document)) {\n      return {\n        size: [this.domElement.offsetWidth, this.domElement.offsetHeight],\n        offset: [this.domElement.offsetLeft, this.domElement.offsetTop],\n      }\n    } else {\n      return {\n        size: [window.innerWidth, window.innerHeight],\n        offset: [0, 0],\n      }\n    }\n  }\n\n  // https://github.com/mrdoob/three.js/issues/20575\n  public connect = (domElement: HTMLElement | Document): void => {\n    this.domElement = domElement\n\n    if (!(domElement instanceof Document)) {\n      domElement.setAttribute('tabindex', -1 as any)\n    }\n\n    this.domElement.addEventListener('contextmenu', contextmenu)\n    ;(this.domElement as HTMLElement).addEventListener('pointermove', this.pointermove)\n    ;(this.domElement as HTMLElement).addEventListener('pointerdown', this.pointerdown)\n    ;(this.domElement as HTMLElement).addEventListener('pointerup', this.pointerup)\n\n    window.addEventListener('keydown', this.keydown)\n    window.addEventListener('keyup', this.keyup)\n  }\n\n  public dispose = (): void => {\n    this.domElement.removeEventListener('contextmenu', contextmenu)\n    ;(this.domElement as HTMLElement).removeEventListener('pointermove', this.pointermove)\n    ;(this.domElement as HTMLElement).removeEventListener('pointerdown', this.pointerdown)\n    ;(this.domElement as HTMLElement).removeEventListener('pointerup', this.pointerup)\n\n    window.removeEventListener('keydown', this.keydown)\n    window.removeEventListener('keyup', this.keyup)\n  }\n}\n\nexport { FlyControls }\n"],"names":["EventDispatcher","Quaternion","Vector3"],"mappings":"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"}