babylon.webVRCamera.ts 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. declare var HMDVRDevice;
  2. declare var VRDisplay;
  3. module BABYLON {
  4. export interface WebVROptions {
  5. trackPosition?: boolean; //update the camera's position
  6. displayName?: string; //if there are more than one VRDisplays.
  7. }
  8. export class WebVRFreeCamera extends FreeCamera {
  9. public _vrDevice = null;
  10. private _cacheState = null;
  11. private _vrEnabled = false;
  12. private _oldSize: BABYLON.Size;
  13. private _oldHardwareScaleFactor: number;
  14. private _initialQuaternion: Quaternion;
  15. private _quaternionCache: Quaternion;
  16. constructor(name: string, position: Vector3, scene: Scene, compensateDistortion = true, vrCameraMetrics: VRCameraMetrics = VRCameraMetrics.GetDefault(), private webVROptions: WebVROptions = {}) {
  17. super(name, position, scene);
  18. vrCameraMetrics.compensateDistortion = compensateDistortion;
  19. this.setCameraRigMode(Camera.RIG_MODE_VR, { vrCameraMetrics: vrCameraMetrics });
  20. //this._getWebVRDevices = this._getWebVRDevices.bind(this);
  21. if (!this.getEngine().vrDisplaysPromise) {
  22. Tools.Error("WebVR is not enabled on your browser");
  23. }
  24. this.rotationQuaternion = new Quaternion();
  25. this._quaternionCache = new Quaternion();
  26. }
  27. public _checkInputs(): void {
  28. if (this._vrEnabled) {
  29. this._cacheState = this._vrDevice.getPose();
  30. this.rotationQuaternion.copyFromFloats(this._cacheState.orientation[0], this._cacheState.orientation[1], this._cacheState.orientation[2], this._cacheState.orientation[3]);
  31. if (this.webVROptions.trackPosition) {
  32. this.position.copyFromFloats(this._cacheState.position[0], this._cacheState.position[1], -this._cacheState.position[2]);
  33. }
  34. //Flip in XY plane
  35. this.rotationQuaternion.z *= -1;
  36. this.rotationQuaternion.w *= -1;
  37. if (this._initialQuaternion) {
  38. this._quaternionCache.copyFrom(this.rotationQuaternion);
  39. this._initialQuaternion.multiplyToRef(this.rotationQuaternion, this.rotationQuaternion);
  40. }
  41. }
  42. super._checkInputs();
  43. }
  44. public attachControl(element: HTMLElement, noPreventDefault?: boolean): void {
  45. super.attachControl(element, noPreventDefault);
  46. noPreventDefault = Camera.ForceAttachControlToAlwaysPreventDefault ? false : noPreventDefault;
  47. //TODO get the metrics updated using the device's eye parameters!
  48. //sanity check. if no WebVR enabled.
  49. this.getEngine().vrDisplaysPromise && this.getEngine().vrDisplaysPromise.then((devices) => {
  50. if (devices.length > 0) {
  51. this._vrEnabled = true;
  52. if (this.webVROptions.displayName) {
  53. devices.some(device => {
  54. if (device.displayName === this.webVROptions.displayName) {
  55. this.getEngine().enableVR(device);
  56. return true;
  57. } else {
  58. return false;
  59. }
  60. })
  61. } else {
  62. //choose the first one
  63. this.getEngine().enableVR(devices[0]);
  64. }
  65. }
  66. })
  67. }
  68. public detachControl(element: HTMLElement): void {
  69. super.detachControl(element);
  70. this._vrEnabled = false;
  71. this.getEngine().disableVR();
  72. }
  73. public requestVRFullscreen(requestPointerlock: boolean) {
  74. //Backwards comp.
  75. Tools.Warn("requestVRFullscreen is deprecated. Use engine.switchFullscreen() instead")
  76. this.getEngine().switchFullscreen(requestPointerlock);
  77. }
  78. public getTypeName(): string {
  79. return "WebVRFreeCamera";
  80. }
  81. public resetToCurrentRotation(axis: BABYLON.Axis = BABYLON.Axis.Y) {
  82. //can only work if this camera has a rotation quaternion already.
  83. if (!this.rotationQuaternion) return;
  84. if (!this._initialQuaternion) {
  85. this._initialQuaternion = new BABYLON.Quaternion();
  86. }
  87. this._initialQuaternion.copyFrom(this._quaternionCache || this.rotationQuaternion);
  88. ['x', 'y', 'z'].forEach((axisName) => {
  89. if (!axis[axisName]) {
  90. this._initialQuaternion[axisName] = 0;
  91. } else {
  92. this._initialQuaternion[axisName] *= -1;
  93. }
  94. });
  95. this._initialQuaternion.normalize();
  96. }
  97. }
  98. }