{"version":3,"file":"FirstPersonControls.cjs","sources":["../../src/controls/FirstPersonControls.ts"],"sourcesContent":["import { MathUtils, Spherical, Vector3, Camera } from 'three'\nimport { EventDispatcher } from './EventDispatcher'\nimport { StandardControlsEventMap } from './StandardControlsEventMap'\n\nconst targetPosition = /* @__PURE__ */ new Vector3()\n\nexport class FirstPersonControls extends EventDispatcher<{}> {\n  public object: Camera\n  public domElement?: HTMLElement | null\n\n  public enabled = true\n\n  public movementSpeed = 1.0\n  public lookSpeed = 0.005\n\n  public lookVertical = true\n  public autoForward = false\n\n  public activeLook = true\n\n  public heightSpeed = false\n  public heightCoef = 1.0\n  public heightMin = 0.0\n  public heightMax = 1.0\n\n  public constrainVertical = false\n  public verticalMin = 0\n  public verticalMax = Math.PI\n\n  public mouseDragOn = false\n\n  // internals\n\n  private autoSpeedFactor = 0.0\n\n  private mouseX = 0\n  private mouseY = 0\n\n  private moveForward = false\n  private moveBackward = false\n  private moveLeft = false\n  private moveRight = false\n  private moveUp = false\n  private moveDown = false\n\n  private viewHalfX = 0\n  private viewHalfY = 0\n\n  private lat = 0\n  private lon = 0\n\n  private lookDirection = new Vector3()\n  private spherical = new Spherical()\n  readonly target = new Vector3()\n\n  constructor(object: Camera, domElement?: HTMLElement | null) {\n    super()\n\n    this.object = object\n    this.domElement = domElement\n\n    this.setOrientation()\n\n    if (domElement) this.connect(domElement)\n  }\n\n  public connect = (domElement: HTMLElement): void => {\n    domElement.setAttribute('tabindex', '-1')\n\n    domElement.style.touchAction = 'none'\n\n    domElement.addEventListener('contextmenu', this.contextmenu)\n    domElement.addEventListener('mousemove', this.onMouseMove)\n    domElement.addEventListener('mousedown', this.onMouseDown)\n    domElement.addEventListener('mouseup', this.onMouseUp)\n\n    this.domElement = domElement\n\n    window.addEventListener('keydown', this.onKeyDown)\n    window.addEventListener('keyup', this.onKeyUp)\n\n    this.handleResize()\n  }\n\n  public dispose = (): void => {\n    this.domElement?.removeEventListener('contextmenu', this.contextmenu)\n    this.domElement?.removeEventListener('mousedown', this.onMouseDown)\n    this.domElement?.removeEventListener('mousemove', this.onMouseMove)\n    this.domElement?.removeEventListener('mouseup', this.onMouseUp)\n\n    window.removeEventListener('keydown', this.onKeyDown)\n    window.removeEventListener('keyup', this.onKeyUp)\n  }\n\n  public handleResize = (): void => {\n    if (this.domElement) {\n      this.viewHalfX = this.domElement.offsetWidth / 2\n      this.viewHalfY = this.domElement.offsetHeight / 2\n    }\n  }\n\n  private onMouseDown = (event: MouseEvent): void => {\n    this.domElement?.focus()\n\n    if (this.activeLook) {\n      switch (event.button) {\n        case 0:\n          this.moveForward = true\n          break\n        case 2:\n          this.moveBackward = true\n          break\n      }\n    }\n\n    this.mouseDragOn = true\n  }\n\n  private onMouseUp = (event: MouseEvent): void => {\n    if (this.activeLook) {\n      switch (event.button) {\n        case 0:\n          this.moveForward = false\n          break\n        case 2:\n          this.moveBackward = false\n          break\n      }\n    }\n\n    this.mouseDragOn = false\n  }\n\n  private onMouseMove = (event: MouseEvent): void => {\n    if (this.domElement) {\n      this.mouseX = event.pageX - this.domElement.offsetLeft - this.viewHalfX\n      this.mouseY = event.pageY - this.domElement.offsetTop - this.viewHalfY\n    }\n  }\n\n  private onKeyDown = (event: KeyboardEvent): void => {\n    switch (event.code) {\n      case 'ArrowUp':\n      case 'KeyW':\n        this.moveForward = true\n        break\n\n      case 'ArrowLeft':\n      case 'KeyA':\n        this.moveLeft = true\n        break\n\n      case 'ArrowDown':\n      case 'KeyS':\n        this.moveBackward = true\n        break\n\n      case 'ArrowRight':\n      case 'KeyD':\n        this.moveRight = true\n        break\n\n      case 'KeyR':\n        this.moveUp = true\n        break\n      case 'KeyF':\n        this.moveDown = true\n        break\n    }\n  }\n\n  private onKeyUp = (event: KeyboardEvent): void => {\n    switch (event.code) {\n      case 'ArrowUp':\n      case 'KeyW':\n        this.moveForward = false\n        break\n\n      case 'ArrowLeft':\n      case 'KeyA':\n        this.moveLeft = false\n        break\n\n      case 'ArrowDown':\n      case 'KeyS':\n        this.moveBackward = false\n        break\n\n      case 'ArrowRight':\n      case 'KeyD':\n        this.moveRight = false\n        break\n\n      case 'KeyR':\n        this.moveUp = false\n        break\n      case 'KeyF':\n        this.moveDown = false\n        break\n    }\n  }\n\n  public lookAt = (x: Vector3 | number, y?: number, z?: number): this => {\n    if (x instanceof Vector3) {\n      this.target.copy(x)\n    } else if (y && z) {\n      this.target.set(x, y, z)\n    }\n\n    this.object.lookAt(this.target)\n\n    this.setOrientation()\n\n    return this\n  }\n\n  public update = (delta: number): void => {\n    if (!this.enabled) return\n\n    if (this.heightSpeed) {\n      const y = MathUtils.clamp(this.object.position.y, this.heightMin, this.heightMax)\n      const heightDelta = y - this.heightMin\n\n      this.autoSpeedFactor = delta * (heightDelta * this.heightCoef)\n    } else {\n      this.autoSpeedFactor = 0.0\n    }\n\n    const actualMoveSpeed = delta * this.movementSpeed\n\n    if (this.moveForward || (this.autoForward && !this.moveBackward)) {\n      this.object.translateZ(-(actualMoveSpeed + this.autoSpeedFactor))\n    }\n    if (this.moveBackward) this.object.translateZ(actualMoveSpeed)\n\n    if (this.moveLeft) this.object.translateX(-actualMoveSpeed)\n    if (this.moveRight) this.object.translateX(actualMoveSpeed)\n\n    if (this.moveUp) this.object.translateY(actualMoveSpeed)\n    if (this.moveDown) this.object.translateY(-actualMoveSpeed)\n\n    let actualLookSpeed = delta * this.lookSpeed\n\n    if (!this.activeLook) {\n      actualLookSpeed = 0\n    }\n\n    let verticalLookRatio = 1\n\n    if (this.constrainVertical) {\n      verticalLookRatio = Math.PI / (this.verticalMax - this.verticalMin)\n    }\n\n    this.lon -= this.mouseX * actualLookSpeed\n    if (this.lookVertical) this.lat -= this.mouseY * actualLookSpeed * verticalLookRatio\n\n    this.lat = Math.max(-85, Math.min(85, this.lat))\n\n    let phi = MathUtils.degToRad(90 - this.lat)\n    const theta = MathUtils.degToRad(this.lon)\n\n    if (this.constrainVertical) {\n      phi = MathUtils.mapLinear(phi, 0, Math.PI, this.verticalMin, this.verticalMax)\n    }\n\n    const position = this.object.position\n\n    targetPosition.setFromSphericalCoords(1, phi, theta).add(position)\n\n    this.object.lookAt(targetPosition)\n  }\n\n  private contextmenu = (event: Event): void => event.preventDefault()\n\n  private setOrientation = (): void => {\n    this.lookDirection.set(0, 0, -1).applyQuaternion(this.object.quaternion)\n    this.spherical.setFromVector3(this.lookDirection)\n    this.lat = 90 - MathUtils.radToDeg(this.spherical.phi)\n    this.lon = MathUtils.radToDeg(this.spherical.theta)\n  }\n}\n"],"names":["Vector3","EventDispatcher","Spherical","MathUtils"],"mappings":"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"}