webXRDefaultExperience.ts 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. import { WebXRExperienceHelper } from "./webXRExperienceHelper";
  2. import { Scene } from '../scene';
  3. import { WebXRInput, IWebXRInputOptions } from './webXRInput';
  4. import { WebXRControllerPointerSelection, IWebXRControllerPointerSelectionOptions } from './features/WebXRControllerPointerSelection';
  5. import { WebXRRenderTarget } from './webXRTypes';
  6. import { WebXREnterExitUI, WebXREnterExitUIOptions } from './webXREnterExitUI';
  7. import { AbstractMesh } from '../Meshes/abstractMesh';
  8. import { WebXRManagedOutputCanvasOptions } from './webXRManagedOutputCanvas';
  9. import { WebXRMotionControllerTeleportation, IWebXRTeleportationOptions } from './features/WebXRControllerTeleportation';
  10. import { Logger } from '../Misc/logger';
  11. /**
  12. * Options for the default xr helper
  13. */
  14. export class WebXRDefaultExperienceOptions {
  15. /**
  16. * Enable or disable default UI to enter XR
  17. */
  18. public disableDefaultUI?: boolean;
  19. /**
  20. * Should teleportation not initialize. defaults to false.
  21. */
  22. public disableTeleportation?: boolean;
  23. /**
  24. * Floor meshes that will be used for teleport
  25. */
  26. public floorMeshes?: Array<AbstractMesh>;
  27. /**
  28. * If set to true, the first frame will not be used to reset position
  29. * The first frame is mainly used when copying transformation from the old camera
  30. * Mainly used in AR
  31. */
  32. public ignoreNativeCameraTransformation?: boolean;
  33. /**
  34. * Disable the controller mesh-loading. Can be used if you want to load your own meshes
  35. */
  36. public inputOptions?: IWebXRInputOptions;
  37. /**
  38. * optional configuration for the output canvas
  39. */
  40. public outputCanvasOptions?: WebXRManagedOutputCanvasOptions;
  41. /**
  42. * optional UI options. This can be used among other to change session mode and reference space type
  43. */
  44. public uiOptions?: WebXREnterExitUIOptions;
  45. /**
  46. * When loading teleportation and pointer select, use stable versions instead of latest.
  47. */
  48. public useStablePlugins?: boolean;
  49. /**
  50. * An optional rendering group id that will be set globally for teleportation, pointer selection and default controller meshes
  51. */
  52. public renderingGroupId?: number;
  53. }
  54. /**
  55. * Default experience which provides a similar setup to the previous webVRExperience
  56. */
  57. export class WebXRDefaultExperience {
  58. /**
  59. * Base experience
  60. */
  61. public baseExperience: WebXRExperienceHelper;
  62. /**
  63. * Enables ui for entering/exiting xr
  64. */
  65. public enterExitUI: WebXREnterExitUI;
  66. /**
  67. * Input experience extension
  68. */
  69. public input: WebXRInput;
  70. /**
  71. * Enables laser pointer and selection
  72. */
  73. public pointerSelection: WebXRControllerPointerSelection;
  74. /**
  75. * Default target xr should render to
  76. */
  77. public renderTarget: WebXRRenderTarget;
  78. /**
  79. * Enables teleportation
  80. */
  81. public teleportation: WebXRMotionControllerTeleportation;
  82. private constructor() {
  83. }
  84. /**
  85. * Creates the default xr experience
  86. * @param scene scene
  87. * @param options options for basic configuration
  88. * @returns resulting WebXRDefaultExperience
  89. */
  90. public static CreateAsync(scene: Scene, options: WebXRDefaultExperienceOptions = {}) {
  91. var result = new WebXRDefaultExperience();
  92. // Create base experience
  93. return WebXRExperienceHelper.CreateAsync(scene).then((xrHelper) => {
  94. result.baseExperience = xrHelper;
  95. if (options.ignoreNativeCameraTransformation) {
  96. result.baseExperience.camera.compensateOnFirstFrame = false;
  97. }
  98. // Add controller support
  99. result.input = new WebXRInput(xrHelper.sessionManager, xrHelper.camera, {
  100. controllerOptions: {
  101. renderingGroupId: options.renderingGroupId
  102. },
  103. ...(options.inputOptions || {})
  104. });
  105. result.pointerSelection = <WebXRControllerPointerSelection>result.baseExperience.featuresManager.enableFeature(WebXRControllerPointerSelection.Name, options.useStablePlugins ? "stable" : "latest",
  106. <IWebXRControllerPointerSelectionOptions>{
  107. xrInput: result.input,
  108. renderingGroupId: options.renderingGroupId
  109. });
  110. // Add default teleportation, including rotation
  111. if (!options.disableTeleportation) {
  112. result.teleportation = <WebXRMotionControllerTeleportation>result.baseExperience.featuresManager.enableFeature(WebXRMotionControllerTeleportation.Name, options.useStablePlugins ? "stable" : "latest",
  113. <IWebXRTeleportationOptions>{
  114. floorMeshes: options.floorMeshes,
  115. xrInput: result.input,
  116. renderingGroupId: options.renderingGroupId
  117. });
  118. result.teleportation.setSelectionFeature(result.pointerSelection);
  119. }
  120. // Create the WebXR output target
  121. result.renderTarget = result.baseExperience.sessionManager.getWebXRRenderTarget(options.outputCanvasOptions);
  122. if (!options.disableDefaultUI) {
  123. if (options.uiOptions) {
  124. options.uiOptions.renderTarget = options.uiOptions.renderTarget || result.renderTarget;
  125. }
  126. // Create ui for entering/exiting xr
  127. return WebXREnterExitUI.CreateAsync(scene, result.baseExperience, options.uiOptions || { renderTarget: result.renderTarget }).then((ui) => {
  128. result.enterExitUI = ui;
  129. });
  130. } else {
  131. return;
  132. }
  133. }).then(() => {
  134. return result;
  135. }).catch((error) => {
  136. Logger.Error("Error initializing XR");
  137. Logger.Error(error);
  138. return result;
  139. });
  140. }
  141. /**
  142. * DIsposes of the experience helper
  143. */
  144. public dispose() {
  145. if (this.baseExperience) {
  146. this.baseExperience.dispose();
  147. }
  148. if (this.input) {
  149. this.input.dispose();
  150. }
  151. if (this.enterExitUI) {
  152. this.enterExitUI.dispose();
  153. }
  154. if (this.renderTarget) {
  155. this.renderTarget.dispose();
  156. }
  157. }
  158. }