webXRManagedOutputCanvas.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. import { Observable } from "../Misc/observable.js";
  2. import { Tools } from "../Misc/tools.js";
  3. import { WebXRWebGLLayerWrapper } from "./webXRWebGLLayer.js";
  4. /**
  5. * Configuration object for WebXR output canvas
  6. */
  7. export class WebXRManagedOutputCanvasOptions {
  8. /**
  9. * Get the default values of the configuration object
  10. * @param engine defines the engine to use (can be null)
  11. * @returns default values of this configuration object
  12. */
  13. static GetDefaults(engine) {
  14. const defaults = new WebXRManagedOutputCanvasOptions();
  15. defaults.canvasOptions = {
  16. antialias: true,
  17. depth: true,
  18. stencil: engine ? engine.isStencilEnable : true,
  19. alpha: true,
  20. framebufferScaleFactor: 1,
  21. };
  22. defaults.newCanvasCssStyle = "position:absolute; bottom:0px;right:0px;z-index:10;width:90%;height:100%;background-color: #000000;";
  23. return defaults;
  24. }
  25. }
  26. /**
  27. * Creates a canvas that is added/removed from the webpage when entering/exiting XR
  28. */
  29. export class WebXRManagedOutputCanvas {
  30. /**
  31. * Initializes the canvas to be added/removed upon entering/exiting xr
  32. * @param _xrSessionManager The XR Session manager
  33. * @param _options optional configuration for this canvas output. defaults will be used if not provided
  34. */
  35. constructor(_xrSessionManager, _options = WebXRManagedOutputCanvasOptions.GetDefaults()) {
  36. this._options = _options;
  37. this._canvas = null;
  38. this._engine = null;
  39. /**
  40. * xr layer for the canvas
  41. */
  42. this.xrLayer = null;
  43. this._xrLayerWrapper = null;
  44. /**
  45. * Observers registered here will be triggered when the xr layer was initialized
  46. */
  47. this.onXRLayerInitObservable = new Observable();
  48. this._engine = _xrSessionManager.scene.getEngine();
  49. this._engine.onDisposeObservable.addOnce(() => {
  50. this._engine = null;
  51. });
  52. if (!_options.canvasElement) {
  53. const canvas = document.createElement("canvas");
  54. canvas.style.cssText = this._options.newCanvasCssStyle || "position:absolute; bottom:0px;right:0px;";
  55. this._setManagedOutputCanvas(canvas);
  56. }
  57. else {
  58. this._setManagedOutputCanvas(_options.canvasElement);
  59. }
  60. _xrSessionManager.onXRSessionInit.add(() => {
  61. this._addCanvas();
  62. });
  63. _xrSessionManager.onXRSessionEnded.add(() => {
  64. this._removeCanvas();
  65. });
  66. }
  67. /**
  68. * Disposes of the object
  69. */
  70. dispose() {
  71. this._removeCanvas();
  72. this._setManagedOutputCanvas(null);
  73. }
  74. /**
  75. * Initializes a XRWebGLLayer to be used as the session's baseLayer.
  76. * @param xrSession xr session
  77. * @returns a promise that will resolve once the XR Layer has been created
  78. */
  79. async initializeXRLayerAsync(xrSession) {
  80. const createLayer = () => {
  81. this.xrLayer = new XRWebGLLayer(xrSession, this.canvasContext, this._options.canvasOptions);
  82. this._xrLayerWrapper = new WebXRWebGLLayerWrapper(this.xrLayer);
  83. this.onXRLayerInitObservable.notifyObservers(this.xrLayer);
  84. return this.xrLayer;
  85. };
  86. // support canvases without makeXRCompatible
  87. if (!this.canvasContext.makeXRCompatible) {
  88. return Promise.resolve(createLayer());
  89. }
  90. return this.canvasContext
  91. .makeXRCompatible()
  92. .then(
  93. // catch any error and continue. When using the emulator is throws this error for no apparent reason.
  94. () => { }, () => {
  95. // log the error, continue nonetheless!
  96. Tools.Warn("Error executing makeXRCompatible. This does not mean that the session will work incorrectly.");
  97. })
  98. .then(() => {
  99. return createLayer();
  100. });
  101. }
  102. _addCanvas() {
  103. if (this._canvas && this._engine && this._canvas !== this._engine.getRenderingCanvas()) {
  104. document.body.appendChild(this._canvas);
  105. }
  106. if (this.xrLayer) {
  107. this._setCanvasSize(true);
  108. }
  109. else {
  110. this.onXRLayerInitObservable.addOnce(() => {
  111. this._setCanvasSize(true);
  112. });
  113. }
  114. }
  115. _removeCanvas() {
  116. if (this._canvas && this._engine && document.body.contains(this._canvas) && this._canvas !== this._engine.getRenderingCanvas()) {
  117. document.body.removeChild(this._canvas);
  118. }
  119. this._setCanvasSize(false);
  120. }
  121. _setCanvasSize(init = true, xrLayer = this._xrLayerWrapper) {
  122. if (!this._canvas || !this._engine) {
  123. return;
  124. }
  125. if (init) {
  126. if (xrLayer) {
  127. if (this._canvas !== this._engine.getRenderingCanvas()) {
  128. this._canvas.style.width = xrLayer.getWidth() + "px";
  129. this._canvas.style.height = xrLayer.getHeight() + "px";
  130. }
  131. else {
  132. this._engine.setSize(xrLayer.getWidth(), xrLayer.getHeight());
  133. }
  134. }
  135. }
  136. else {
  137. if (this._originalCanvasSize) {
  138. if (this._canvas !== this._engine.getRenderingCanvas()) {
  139. this._canvas.style.width = this._originalCanvasSize.width + "px";
  140. this._canvas.style.height = this._originalCanvasSize.height + "px";
  141. }
  142. else {
  143. this._engine.setSize(this._originalCanvasSize.width, this._originalCanvasSize.height);
  144. }
  145. }
  146. }
  147. }
  148. _setManagedOutputCanvas(canvas) {
  149. this._removeCanvas();
  150. if (!canvas) {
  151. this._canvas = null;
  152. this.canvasContext = null;
  153. }
  154. else {
  155. this._originalCanvasSize = {
  156. width: canvas.offsetWidth,
  157. height: canvas.offsetHeight,
  158. };
  159. this._canvas = canvas;
  160. this.canvasContext = this._canvas.getContext("webgl2");
  161. if (!this.canvasContext) {
  162. this.canvasContext = this._canvas.getContext("webgl");
  163. }
  164. }
  165. }
  166. }
  167. //# sourceMappingURL=webXRManagedOutputCanvas.js.map