arcRotateCameraVRDeviceOrientationInput.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import { Nullable } from "../../types";
  2. import { ArcRotateCamera } from "../../Cameras/arcRotateCamera";
  3. import { ICameraInput, CameraInputTypes } from "../../Cameras/cameraInputsManager";
  4. /**
  5. * Manage the device orientation inputs (gyroscope) to control an arc rotate camera.
  6. * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
  7. */
  8. export class ArcRotateCameraVRDeviceOrientationInput implements ICameraInput<ArcRotateCamera> {
  9. /**
  10. * Defines the camera the input is attached to.
  11. */
  12. public camera: ArcRotateCamera;
  13. /**
  14. * Defines a correction factor applied on the alpha value retrieved from the orientation events.
  15. */
  16. public alphaCorrection = 1;
  17. /**
  18. * Defines a correction factor applied on the gamma value retrieved from the orientation events.
  19. */
  20. public gammaCorrection = 1;
  21. private _alpha = 0;
  22. private _gamma = 0;
  23. private _dirty = false;
  24. private _deviceOrientationHandler: () => void;
  25. /**
  26. * Instantiate a new ArcRotateCameraVRDeviceOrientationInput.
  27. */
  28. constructor() {
  29. this._deviceOrientationHandler = this._onOrientationEvent.bind(this);
  30. }
  31. /**
  32. * Attach the input controls to a specific dom element to get the input from.
  33. * @param element Defines the element the controls should be listened from
  34. * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
  35. */
  36. public attachControl(element: HTMLElement, noPreventDefault?: boolean): void {
  37. this.camera.attachControl(element, noPreventDefault);
  38. window.addEventListener("deviceorientation", this._deviceOrientationHandler);
  39. }
  40. /** @hidden */
  41. public _onOrientationEvent(evt: DeviceOrientationEvent): void {
  42. if (evt.alpha !== null) {
  43. this._alpha = (+evt.alpha | 0) * this.alphaCorrection;
  44. }
  45. if (evt.gamma !== null) {
  46. this._gamma = (+evt.gamma | 0) * this.gammaCorrection;
  47. }
  48. this._dirty = true;
  49. }
  50. /**
  51. * Update the current camera state depending on the inputs that have been used this frame.
  52. * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.
  53. */
  54. public checkInputs(): void {
  55. if (this._dirty) {
  56. this._dirty = false;
  57. if (this._gamma < 0) {
  58. this._gamma = 180 + this._gamma;
  59. }
  60. this.camera.alpha = (-this._alpha / 180.0 * Math.PI) % Math.PI * 2;
  61. this.camera.beta = (this._gamma / 180.0 * Math.PI);
  62. }
  63. }
  64. /**
  65. * Detach the current controls from the specified dom element.
  66. * @param element Defines the element to stop listening the inputs from
  67. */
  68. public detachControl(element: Nullable<HTMLElement>): void {
  69. window.removeEventListener("deviceorientation", this._deviceOrientationHandler);
  70. }
  71. /**
  72. * Gets the class name of the current intput.
  73. * @returns the class name
  74. */
  75. public getClassName(): string {
  76. return "ArcRotateCameraVRDeviceOrientationInput";
  77. }
  78. /**
  79. * Get the friendly name associated with the input class.
  80. * @returns the input friendly name
  81. */
  82. public getSimpleName(): string {
  83. return "VRDeviceOrientation";
  84. }
  85. }
  86. (<any>CameraInputTypes)["ArcRotateCameraVRDeviceOrientationInput"] = ArcRotateCameraVRDeviceOrientationInput;