arcRotateCameraVRDeviceOrientationInput.ts 4.4 KB

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