arcRotateCameraVRDeviceOrientationInput.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import { CameraInputTypes } from "../../Cameras/cameraInputsManager.js";
  2. import { ArcRotateCameraInputsManager } from "../../Cameras/arcRotateCameraInputsManager.js";
  3. import { Tools } from "../../Misc/tools.js";
  4. /**
  5. * Add orientation input support to the input manager.
  6. * @returns the current input manager
  7. */
  8. ArcRotateCameraInputsManager.prototype.addVRDeviceOrientation = function () {
  9. this.add(new ArcRotateCameraVRDeviceOrientationInput());
  10. return this;
  11. };
  12. /**
  13. * Manage the device orientation inputs (gyroscope) to control an arc rotate camera.
  14. * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs
  15. */
  16. export class ArcRotateCameraVRDeviceOrientationInput {
  17. /**
  18. * Instantiate a new ArcRotateCameraVRDeviceOrientationInput.
  19. */
  20. constructor() {
  21. /**
  22. * Defines a correction factor applied on the alpha value retrieved from the orientation events.
  23. */
  24. this.alphaCorrection = 1;
  25. /**
  26. * Defines a correction factor applied on the gamma value retrieved from the orientation events.
  27. */
  28. this.gammaCorrection = 1;
  29. this._alpha = 0;
  30. this._gamma = 0;
  31. this._dirty = false;
  32. this._deviceOrientationHandler = (evt) => this._onOrientationEvent(evt);
  33. }
  34. /**
  35. * Attach the input controls to a specific dom element to get the input from.
  36. * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
  37. */
  38. attachControl(noPreventDefault) {
  39. // eslint-disable-next-line prefer-rest-params
  40. noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);
  41. this.camera.attachControl(noPreventDefault);
  42. const hostWindow = this.camera.getScene().getEngine().getHostWindow();
  43. if (hostWindow) {
  44. // check iOS 13+ support
  45. if (typeof DeviceOrientationEvent !== "undefined" && typeof DeviceOrientationEvent.requestPermission === "function") {
  46. DeviceOrientationEvent
  47. .requestPermission()
  48. .then((response) => {
  49. if (response === "granted") {
  50. hostWindow.addEventListener("deviceorientation", this._deviceOrientationHandler);
  51. }
  52. else {
  53. Tools.Warn("Permission not granted.");
  54. }
  55. })
  56. .catch((error) => {
  57. Tools.Error(error);
  58. });
  59. }
  60. else {
  61. hostWindow.addEventListener("deviceorientation", this._deviceOrientationHandler);
  62. }
  63. }
  64. }
  65. /**
  66. * @internal
  67. */
  68. _onOrientationEvent(evt) {
  69. if (evt.alpha !== null) {
  70. this._alpha = (+evt.alpha | 0) * this.alphaCorrection;
  71. }
  72. if (evt.gamma !== null) {
  73. this._gamma = (+evt.gamma | 0) * this.gammaCorrection;
  74. }
  75. this._dirty = true;
  76. }
  77. /**
  78. * Update the current camera state depending on the inputs that have been used this frame.
  79. * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.
  80. */
  81. checkInputs() {
  82. if (this._dirty) {
  83. this._dirty = false;
  84. if (this._gamma < 0) {
  85. this._gamma = 180 + this._gamma;
  86. }
  87. this.camera.alpha = (((-this._alpha / 180.0) * Math.PI) % Math.PI) * 2;
  88. this.camera.beta = (this._gamma / 180.0) * Math.PI;
  89. }
  90. }
  91. /**
  92. * Detach the current controls from the specified dom element.
  93. */
  94. detachControl() {
  95. window.removeEventListener("deviceorientation", this._deviceOrientationHandler);
  96. }
  97. /**
  98. * Gets the class name of the current input.
  99. * @returns the class name
  100. */
  101. getClassName() {
  102. return "ArcRotateCameraVRDeviceOrientationInput";
  103. }
  104. /**
  105. * Get the friendly name associated with the input class.
  106. * @returns the input friendly name
  107. */
  108. getSimpleName() {
  109. return "VRDeviceOrientation";
  110. }
  111. }
  112. CameraInputTypes["ArcRotateCameraVRDeviceOrientationInput"] = ArcRotateCameraVRDeviceOrientationInput;
  113. //# sourceMappingURL=arcRotateCameraVRDeviceOrientationInput.js.map