@onerjs/core 8.42.5 → 8.42.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cameras/arcRotateCamera.js +9 -9
- package/Cameras/arcRotateCamera.js.map +1 -1
- package/Materials/vertexPullingHelper.functions.d.ts +4 -0
- package/Materials/vertexPullingHelper.functions.js +4 -2
- package/Materials/vertexPullingHelper.functions.js.map +1 -1
- package/ShadersWGSL/iblVoxelGrid.vertex.js +51 -42
- package/ShadersWGSL/iblVoxelGrid.vertex.js.map +1 -1
- package/XR/features/WebXRControllerTeleportation.js +1 -2
- package/XR/features/WebXRControllerTeleportation.js.map +1 -1
- package/XR/features/WebXRDepthSensing.js +1 -0
- package/XR/features/WebXRDepthSensing.js.map +1 -1
- package/XR/features/WebXRHandTracking.js +2 -2
- package/XR/features/WebXRHandTracking.js.map +1 -1
- package/XR/features/WebXRWalkingLocomotion.js +1 -1
- package/XR/features/WebXRWalkingLocomotion.js.map +1 -1
- package/XR/motionController/webXRMicrosoftMixedRealityController.js +1 -1
- package/XR/motionController/webXRMicrosoftMixedRealityController.js.map +1 -1
- package/XR/motionController/webXRMotionControllerManager.js +2 -2
- package/XR/motionController/webXRMotionControllerManager.js.map +1 -1
- package/XR/webXRCamera.d.ts +1 -0
- package/XR/webXRCamera.js +9 -7
- package/XR/webXRCamera.js.map +1 -1
- package/XR/webXRExperienceHelper.d.ts +4 -0
- package/XR/webXRExperienceHelper.js +25 -5
- package/XR/webXRExperienceHelper.js.map +1 -1
- package/XR/webXRInput.d.ts +1 -0
- package/XR/webXRInput.js +6 -0
- package/XR/webXRInput.js.map +1 -1
- package/XR/webXRSessionManager.js +5 -4
- package/XR/webXRSessionManager.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webXRExperienceHelper.js","sourceRoot":"","sources":["../../../../dev/core/src/XR/webXRExperienceHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Nullable } from \"../types\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport type { IDisposable, Scene } from \"../scene\";\r\nimport type { Camera } from \"../Cameras/camera\";\r\nimport { WebXRSessionManager } from \"./webXRSessionManager\";\r\nimport { WebXRCamera } from \"./webXRCamera\";\r\nimport type { WebXRRenderTarget } from \"./webXRTypes\";\r\nimport { WebXRState } from \"./webXRTypes\";\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"./webXRFeaturesManager\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { UniversalCamera } from \"../Cameras/universalCamera\";\r\nimport { Quaternion, Vector3 } from \"../Maths/math.vector\";\r\nimport type { ThinEngine } from \"../Engines/thinEngine\";\r\nimport { AbstractEngine } from \"core/Engines/abstractEngine\";\r\n\r\n/**\r\n * Options for setting up XR spectator camera.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface WebXRSpectatorModeOption {\r\n /**\r\n * Expected refresh rate (frames per sec) for a spectator camera.\r\n */\r\n fps?: number;\r\n /**\r\n * The index of rigCameras array in a WebXR camera.\r\n */\r\n preferredCameraIndex?: number;\r\n}\r\n\r\n/**\r\n * Base set of functionality needed to create an XR experience (WebXRSessionManager, Camera, StateManagement, etc.)\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/webXR/webXRExperienceHelpers\r\n */\r\nexport class WebXRExperienceHelper implements IDisposable {\r\n private _nonVRCamera: Nullable<Camera> = null;\r\n private _attachedToElement: boolean = false;\r\n private _spectatorCamera: Nullable<UniversalCamera> = null;\r\n private _originalSceneAutoClear = true;\r\n private _supported = false;\r\n private _spectatorMode = false;\r\n private _lastTimestamp = 0;\r\n\r\n /**\r\n * Camera used to render xr content\r\n */\r\n public camera: WebXRCamera;\r\n /** A features manager for this xr session */\r\n public featuresManager: WebXRFeaturesManager;\r\n /**\r\n * Observers registered here will be triggered after the camera's initial transformation is set\r\n * This can be used to set a different ground level or an extra rotation.\r\n *\r\n * Note that ground level is considered to be at 0. The height defined by the XR camera will be added\r\n * to the position set after this observable is done executing.\r\n */\r\n public onInitialXRPoseSetObservable = new Observable<WebXRCamera>();\r\n /**\r\n * Fires when the state of the experience helper has changed\r\n */\r\n public onStateChangedObservable = new Observable<WebXRState>();\r\n /** Session manager used to keep track of xr session */\r\n public sessionManager: WebXRSessionManager;\r\n /**\r\n * The current state of the XR experience (eg. transitioning, in XR or not in XR)\r\n */\r\n public state: WebXRState = WebXRState.NOT_IN_XR;\r\n\r\n /**\r\n * Creates a WebXRExperienceHelper\r\n * @param _scene The scene the helper should be created in\r\n */\r\n private constructor(private _scene: Scene) {\r\n this.sessionManager = new WebXRSessionManager(_scene);\r\n this.camera = new WebXRCamera(\"webxr\", _scene, this.sessionManager);\r\n this.featuresManager = new WebXRFeaturesManager(this.sessionManager);\r\n\r\n _scene.onDisposeObservable.addOnce(() => {\r\n this.dispose();\r\n });\r\n }\r\n\r\n /**\r\n * Creates the experience helper\r\n * @param scene the scene to attach the experience helper to\r\n * @returns a promise for the experience helper\r\n */\r\n public static async CreateAsync(scene: Scene): Promise<WebXRExperienceHelper> {\r\n const helper = new WebXRExperienceHelper(scene);\r\n return await helper.sessionManager\r\n .initializeAsync()\r\n // eslint-disable-next-line github/no-then\r\n .then(() => {\r\n helper._supported = true;\r\n return helper;\r\n })\r\n // eslint-disable-next-line github/no-then\r\n .catch((e) => {\r\n helper._setState(WebXRState.NOT_IN_XR);\r\n helper.dispose();\r\n throw e;\r\n });\r\n }\r\n\r\n /**\r\n * Disposes of the experience helper\r\n */\r\n public dispose() {\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.exitXRAsync();\r\n this.camera.dispose();\r\n this.onStateChangedObservable.clear();\r\n this.onInitialXRPoseSetObservable.clear();\r\n this.sessionManager.dispose();\r\n this._spectatorCamera?.dispose();\r\n if (this._nonVRCamera) {\r\n this._scene.activeCamera = this._nonVRCamera;\r\n }\r\n }\r\n\r\n /**\r\n * Enters XR mode (This must be done within a user interaction in most browsers eg. button click)\r\n * @param sessionMode options for the XR session\r\n * @param referenceSpaceType frame of reference of the XR session\r\n * @param renderTarget the output canvas that will be used to enter XR mode\r\n * @param sessionCreationOptions optional XRSessionInit object to init the session with\r\n * @returns promise that resolves after xr mode has entered\r\n */\r\n public async enterXRAsync(\r\n sessionMode: XRSessionMode,\r\n referenceSpaceType: XRReferenceSpaceType,\r\n renderTarget: WebXRRenderTarget = this.sessionManager.getWebXRRenderTarget(),\r\n sessionCreationOptions: XRSessionInit = {}\r\n ): Promise<WebXRSessionManager> {\r\n if (!this._supported) {\r\n // eslint-disable-next-line no-throw-literal\r\n throw \"WebXR not supported in this browser or environment\";\r\n }\r\n this._setState(WebXRState.ENTERING_XR);\r\n if (referenceSpaceType !== \"viewer\" && referenceSpaceType !== \"local\") {\r\n sessionCreationOptions.optionalFeatures = sessionCreationOptions.optionalFeatures || [];\r\n sessionCreationOptions.optionalFeatures.push(referenceSpaceType);\r\n }\r\n sessionCreationOptions = await this.featuresManager._extendXRSessionInitObject(sessionCreationOptions);\r\n // we currently recommend \"unbounded\" space in AR (#7959)\r\n if (sessionMode === \"immersive-ar\" && referenceSpaceType !== \"unbounded\") {\r\n Logger.Warn(\"We recommend using 'unbounded' reference space type when using 'immersive-ar' session mode\");\r\n }\r\n // make sure that the session mode is supported\r\n try {\r\n await this.sessionManager.initializeSessionAsync(sessionMode, sessionCreationOptions);\r\n await this.sessionManager.setReferenceSpaceTypeAsync(referenceSpaceType);\r\n\r\n const xrRenderState: XRRenderStateInit = {\r\n // if maxZ is 0 it should be \"Infinity\", but it doesn't work with the WebXR API. Setting to a large number.\r\n depthFar: this.camera.maxZ || 10000,\r\n depthNear: this.camera.minZ,\r\n };\r\n\r\n // The layers feature will have already initialized the xr session's layers on session init.\r\n if (!this.featuresManager.getEnabledFeature(WebXRFeatureName.LAYERS)) {\r\n const baseLayer = await renderTarget.initializeXRLayerAsync(this.sessionManager.session);\r\n xrRenderState.baseLayer = baseLayer;\r\n }\r\n\r\n this.sessionManager.updateRenderState(xrRenderState);\r\n // run the render loop\r\n this.sessionManager.runXRRenderLoop();\r\n // Cache pre xr scene settings\r\n this._originalSceneAutoClear = this._scene.autoClear;\r\n this._nonVRCamera = this._scene.activeCamera;\r\n this._attachedToElement = !!this._nonVRCamera?.inputs?.attachedToElement;\r\n this._nonVRCamera?.detachControl();\r\n\r\n this._scene.activeCamera = this.camera;\r\n // do not compensate when AR session is used\r\n if (sessionMode !== \"immersive-ar\") {\r\n this._nonXRToXRCamera();\r\n } else {\r\n // Kept here, TODO - check if needed\r\n this._scene.autoClear = false;\r\n this.camera.compensateOnFirstFrame = false;\r\n // reset the camera's position to the origin\r\n this.camera.position.set(0, 0, 0);\r\n this.camera.rotationQuaternion.set(0, 0, 0, 1);\r\n this.onInitialXRPoseSetObservable.notifyObservers(this.camera);\r\n }\r\n\r\n // Vision Pro suspends the audio context when entering XR, so we resume it here if needed.\r\n AbstractEngine.audioEngine?._resumeAudioContextOnStateChange();\r\n\r\n this.sessionManager.onXRSessionEnded.addOnce(() => {\r\n // when using the back button and not the exit button (default on mobile), the session is ending but the EXITING state was not set\r\n if (this.state !== WebXRState.EXITING_XR) {\r\n this._setState(WebXRState.EXITING_XR);\r\n }\r\n // Reset camera rigs output render target to ensure sessions render target is not drawn after it ends\r\n for (const c of this.camera.rigCameras) {\r\n c.outputRenderTarget = null;\r\n }\r\n\r\n // Restore scene settings\r\n this._scene.autoClear = this._originalSceneAutoClear;\r\n this._scene.activeCamera = this._nonVRCamera;\r\n if (this._attachedToElement && this._nonVRCamera) {\r\n this._nonVRCamera.attachControl(!!this._nonVRCamera.inputs.noPreventDefault);\r\n }\r\n if (sessionMode !== \"immersive-ar\" && this.camera.compensateOnFirstFrame) {\r\n if ((<any>this._nonVRCamera).setPosition) {\r\n (<any>this._nonVRCamera).setPosition(this.camera.position);\r\n } else {\r\n this._nonVRCamera!.position.copyFrom(this.camera.position);\r\n }\r\n }\r\n\r\n this._setState(WebXRState.NOT_IN_XR);\r\n });\r\n\r\n // Wait until the first frame arrives before setting state to in xr\r\n this.sessionManager.onXRFrameObservable.addOnce(() => {\r\n this._setState(WebXRState.IN_XR);\r\n });\r\n return this.sessionManager;\r\n } catch (e) {\r\n Logger.Log(e);\r\n Logger.Log(e.message);\r\n this._setState(WebXRState.NOT_IN_XR);\r\n throw e;\r\n }\r\n }\r\n\r\n /**\r\n * Exits XR mode and returns the scene to its original state\r\n * @returns promise that resolves after xr mode has exited\r\n */\r\n public async exitXRAsync() {\r\n // only exit if state is IN_XR\r\n if (this.state !== WebXRState.IN_XR) {\r\n return;\r\n }\r\n this._setState(WebXRState.EXITING_XR);\r\n return await this.sessionManager.exitXRAsync();\r\n }\r\n\r\n /**\r\n * Enable spectator mode for desktop VR experiences.\r\n * When spectator mode is enabled a camera will be attached to the desktop canvas and will\r\n * display the first rig camera's view on the desktop canvas.\r\n * Please note that this will degrade performance, as it requires another camera render.\r\n * It is also not recommended to enable this in devices like the quest, as it brings no benefit there.\r\n * @param options giving WebXRSpectatorModeOption for specutator camera to setup when the spectator mode is enabled.\r\n */\r\n public enableSpectatorMode(options?: WebXRSpectatorModeOption): void {\r\n if (!this._spectatorMode) {\r\n this._spectatorMode = true;\r\n this._switchSpectatorMode(options);\r\n }\r\n }\r\n\r\n /**\r\n * Disable spectator mode for desktop VR experiences.\r\n */\r\n public disableSpecatatorMode(): void {\r\n if (this._spectatorMode) {\r\n this._spectatorMode = false;\r\n this._switchSpectatorMode();\r\n }\r\n }\r\n\r\n private _switchSpectatorMode(options?: WebXRSpectatorModeOption): void {\r\n const fps = options?.fps ? options.fps : 1000.0;\r\n const refreshRate = (1.0 / fps) * 1000.0;\r\n const cameraIndex = options?.preferredCameraIndex ? options?.preferredCameraIndex : 0;\r\n\r\n const updateSpectatorCamera = () => {\r\n if (this._spectatorCamera) {\r\n const delta = this.sessionManager.currentTimestamp - this._lastTimestamp;\r\n if (delta >= refreshRate) {\r\n this._lastTimestamp = this.sessionManager.currentTimestamp;\r\n this._spectatorCamera.position.copyFrom(this.camera.rigCameras[cameraIndex].globalPosition);\r\n this._spectatorCamera.rotationQuaternion?.copyFrom(this.camera.rigCameras[cameraIndex].absoluteRotation);\r\n }\r\n }\r\n };\r\n if (this._spectatorMode) {\r\n if (cameraIndex >= this.camera.rigCameras.length) {\r\n throw new Error(\"the preferred camera index is beyond the length of rig camera array.\");\r\n }\r\n const onStateChanged = () => {\r\n if (this.state === WebXRState.IN_XR) {\r\n this._spectatorCamera = new UniversalCamera(\"webxr-spectator\", Vector3.Zero(), this._scene);\r\n this._spectatorCamera.rotationQuaternion = new Quaternion();\r\n this._scene.activeCameras = [this.camera, this._spectatorCamera];\r\n this.sessionManager.onXRFrameObservable.add(updateSpectatorCamera);\r\n this._scene.onAfterRenderCameraObservable.add((camera) => {\r\n if (camera === this.camera) {\r\n // reset the dimensions object for correct resizing\r\n (this._scene.getEngine() as ThinEngine).framebufferDimensionsObject = null;\r\n }\r\n });\r\n } else if (this.state === WebXRState.EXITING_XR) {\r\n this.sessionManager.onXRFrameObservable.removeCallback(updateSpectatorCamera);\r\n this._scene.activeCameras = null;\r\n }\r\n };\r\n this.onStateChangedObservable.add(onStateChanged);\r\n onStateChanged();\r\n } else {\r\n this.sessionManager.onXRFrameObservable.removeCallback(updateSpectatorCamera);\r\n this._scene.activeCameras = [this.camera];\r\n }\r\n }\r\n\r\n private _nonXRToXRCamera() {\r\n this.camera.setTransformationFromNonVRCamera(this._nonVRCamera!);\r\n this.onInitialXRPoseSetObservable.notifyObservers(this.camera);\r\n }\r\n\r\n private _setState(val: WebXRState) {\r\n if (this.state === val) {\r\n return;\r\n }\r\n this.state = val;\r\n this.onStateChangedObservable.notifyObservers(this.state);\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"webXRExperienceHelper.js","sourceRoot":"","sources":["../../../../dev/core/src/XR/webXRExperienceHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Nullable } from \"../types\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport type { Observer } from \"../Misc/observable\";\r\nimport type { IDisposable, Scene } from \"../scene\";\r\nimport type { Camera } from \"../Cameras/camera\";\r\nimport { WebXRSessionManager } from \"./webXRSessionManager\";\r\nimport { WebXRCamera } from \"./webXRCamera\";\r\nimport type { WebXRRenderTarget } from \"./webXRTypes\";\r\nimport { WebXRState } from \"./webXRTypes\";\r\nimport { WebXRFeatureName, WebXRFeaturesManager } from \"./webXRFeaturesManager\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { UniversalCamera } from \"../Cameras/universalCamera\";\r\nimport { Quaternion, Vector3 } from \"../Maths/math.vector\";\r\nimport type { ThinEngine } from \"../Engines/thinEngine\";\r\nimport { AbstractEngine } from \"core/Engines/abstractEngine\";\r\n\r\n/**\r\n * Options for setting up XR spectator camera.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface WebXRSpectatorModeOption {\r\n /**\r\n * Expected refresh rate (frames per sec) for a spectator camera.\r\n */\r\n fps?: number;\r\n /**\r\n * The index of rigCameras array in a WebXR camera.\r\n */\r\n preferredCameraIndex?: number;\r\n}\r\n\r\n/**\r\n * Base set of functionality needed to create an XR experience (WebXRSessionManager, Camera, StateManagement, etc.)\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/webXR/webXRExperienceHelpers\r\n */\r\nexport class WebXRExperienceHelper implements IDisposable {\r\n private _nonVRCamera: Nullable<Camera> = null;\r\n private _attachedToElement: boolean = false;\r\n private _spectatorCamera: Nullable<UniversalCamera> = null;\r\n private _originalSceneAutoClear = true;\r\n private _supported = false;\r\n private _spectatorMode = false;\r\n private _lastTimestamp = 0;\r\n private _spectatorStateChangedObserver: Nullable<Observer<WebXRState>> = null;\r\n private _spectatorXRFrameObserver: Nullable<Observer<XRFrame>> = null;\r\n private _spectatorAfterRenderObserver: Nullable<Observer<Camera>> = null;\r\n\r\n /**\r\n * Camera used to render xr content\r\n */\r\n public camera: WebXRCamera;\r\n /** A features manager for this xr session */\r\n public featuresManager: WebXRFeaturesManager;\r\n /**\r\n * Observers registered here will be triggered after the camera's initial transformation is set\r\n * This can be used to set a different ground level or an extra rotation.\r\n *\r\n * Note that ground level is considered to be at 0. The height defined by the XR camera will be added\r\n * to the position set after this observable is done executing.\r\n */\r\n public onInitialXRPoseSetObservable = new Observable<WebXRCamera>();\r\n /**\r\n * Fires when the state of the experience helper has changed\r\n */\r\n public onStateChangedObservable = new Observable<WebXRState>();\r\n /** Session manager used to keep track of xr session */\r\n public sessionManager: WebXRSessionManager;\r\n /**\r\n * The current state of the XR experience (eg. transitioning, in XR or not in XR)\r\n */\r\n public state: WebXRState = WebXRState.NOT_IN_XR;\r\n\r\n /**\r\n * Creates a WebXRExperienceHelper\r\n * @param _scene The scene the helper should be created in\r\n */\r\n private constructor(private _scene: Scene) {\r\n this.sessionManager = new WebXRSessionManager(_scene);\r\n this.camera = new WebXRCamera(\"webxr\", _scene, this.sessionManager);\r\n this.featuresManager = new WebXRFeaturesManager(this.sessionManager);\r\n\r\n _scene.onDisposeObservable.addOnce(() => {\r\n this.dispose();\r\n });\r\n }\r\n\r\n /**\r\n * Creates the experience helper\r\n * @param scene the scene to attach the experience helper to\r\n * @returns a promise for the experience helper\r\n */\r\n public static async CreateAsync(scene: Scene): Promise<WebXRExperienceHelper> {\r\n const helper = new WebXRExperienceHelper(scene);\r\n return await helper.sessionManager\r\n .initializeAsync()\r\n // eslint-disable-next-line github/no-then\r\n .then(() => {\r\n helper._supported = true;\r\n return helper;\r\n })\r\n // eslint-disable-next-line github/no-then\r\n .catch((e) => {\r\n helper._setState(WebXRState.NOT_IN_XR);\r\n helper.dispose();\r\n throw e;\r\n });\r\n }\r\n\r\n /**\r\n * Disposes of the experience helper\r\n */\r\n public dispose() {\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.exitXRAsync();\r\n this._clearSpectatorObservers();\r\n this.camera.dispose();\r\n this.onStateChangedObservable.clear();\r\n this.onInitialXRPoseSetObservable.clear();\r\n this.sessionManager.dispose();\r\n this._spectatorCamera?.dispose();\r\n if (this._nonVRCamera) {\r\n this._scene.activeCamera = this._nonVRCamera;\r\n }\r\n }\r\n\r\n /**\r\n * Enters XR mode (This must be done within a user interaction in most browsers eg. button click)\r\n * @param sessionMode options for the XR session\r\n * @param referenceSpaceType frame of reference of the XR session\r\n * @param renderTarget the output canvas that will be used to enter XR mode\r\n * @param sessionCreationOptions optional XRSessionInit object to init the session with\r\n * @returns promise that resolves after xr mode has entered\r\n */\r\n public async enterXRAsync(\r\n sessionMode: XRSessionMode,\r\n referenceSpaceType: XRReferenceSpaceType,\r\n renderTarget: WebXRRenderTarget = this.sessionManager.getWebXRRenderTarget(),\r\n sessionCreationOptions: XRSessionInit = {}\r\n ): Promise<WebXRSessionManager> {\r\n if (!this._supported) {\r\n // eslint-disable-next-line no-throw-literal\r\n throw \"WebXR not supported in this browser or environment\";\r\n }\r\n this._setState(WebXRState.ENTERING_XR);\r\n if (referenceSpaceType !== \"viewer\" && referenceSpaceType !== \"local\") {\r\n sessionCreationOptions.optionalFeatures = sessionCreationOptions.optionalFeatures || [];\r\n sessionCreationOptions.optionalFeatures.push(referenceSpaceType);\r\n }\r\n sessionCreationOptions = await this.featuresManager._extendXRSessionInitObject(sessionCreationOptions);\r\n // we currently recommend \"unbounded\" space in AR (#7959)\r\n if (sessionMode === \"immersive-ar\" && referenceSpaceType !== \"unbounded\") {\r\n Logger.Warn(\"We recommend using 'unbounded' reference space type when using 'immersive-ar' session mode\");\r\n }\r\n // make sure that the session mode is supported\r\n try {\r\n await this.sessionManager.initializeSessionAsync(sessionMode, sessionCreationOptions);\r\n await this.sessionManager.setReferenceSpaceTypeAsync(referenceSpaceType);\r\n\r\n const xrRenderState: XRRenderStateInit = {\r\n // if maxZ is 0 it should be \"Infinity\", but it doesn't work with the WebXR API. Setting to a large number.\r\n depthFar: this.camera.maxZ || 10000,\r\n depthNear: this.camera.minZ,\r\n };\r\n\r\n // The layers feature will have already initialized the xr session's layers on session init.\r\n if (!this.featuresManager.getEnabledFeature(WebXRFeatureName.LAYERS)) {\r\n const baseLayer = await renderTarget.initializeXRLayerAsync(this.sessionManager.session);\r\n xrRenderState.baseLayer = baseLayer;\r\n }\r\n\r\n this.sessionManager.updateRenderState(xrRenderState);\r\n // run the render loop\r\n this.sessionManager.runXRRenderLoop();\r\n // Cache pre xr scene settings\r\n this._originalSceneAutoClear = this._scene.autoClear;\r\n this._nonVRCamera = this._scene.activeCamera;\r\n this._attachedToElement = !!this._nonVRCamera?.inputs?.attachedToElement;\r\n this._nonVRCamera?.detachControl();\r\n\r\n this._scene.activeCamera = this.camera;\r\n // do not compensate when AR session is used\r\n if (sessionMode !== \"immersive-ar\") {\r\n this._nonXRToXRCamera();\r\n } else {\r\n // Kept here, TODO - check if needed\r\n this._scene.autoClear = false;\r\n this.camera.compensateOnFirstFrame = false;\r\n // reset the camera's position to the origin\r\n this.camera.position.set(0, 0, 0);\r\n this.camera.rotationQuaternion.set(0, 0, 0, 1);\r\n this.onInitialXRPoseSetObservable.notifyObservers(this.camera);\r\n }\r\n\r\n // Vision Pro suspends the audio context when entering XR, so we resume it here if needed.\r\n AbstractEngine.audioEngine?._resumeAudioContextOnStateChange();\r\n\r\n this.sessionManager.onXRSessionEnded.addOnce(() => {\r\n // when using the back button and not the exit button (default on mobile), the session is ending but the EXITING state was not set\r\n if (this.state !== WebXRState.EXITING_XR) {\r\n this._setState(WebXRState.EXITING_XR);\r\n }\r\n // Reset camera rigs output render target to ensure sessions render target is not drawn after it ends\r\n for (const c of this.camera.rigCameras) {\r\n c.outputRenderTarget = null;\r\n }\r\n\r\n // Restore scene settings\r\n this._scene.autoClear = this._originalSceneAutoClear;\r\n this._scene.activeCamera = this._nonVRCamera;\r\n if (this._attachedToElement && this._nonVRCamera) {\r\n this._nonVRCamera.attachControl(!!this._nonVRCamera.inputs.noPreventDefault);\r\n }\r\n if (sessionMode !== \"immersive-ar\" && this.camera.compensateOnFirstFrame) {\r\n if ((<any>this._nonVRCamera).setPosition) {\r\n (<any>this._nonVRCamera).setPosition(this.camera.position);\r\n } else {\r\n this._nonVRCamera!.position.copyFrom(this.camera.position);\r\n }\r\n }\r\n\r\n this._setState(WebXRState.NOT_IN_XR);\r\n });\r\n\r\n // Wait until the first frame arrives before setting state to in xr\r\n this.sessionManager.onXRFrameObservable.addOnce(() => {\r\n this._setState(WebXRState.IN_XR);\r\n });\r\n return this.sessionManager;\r\n } catch (e) {\r\n Logger.Log(e);\r\n Logger.Log(e.message);\r\n this._setState(WebXRState.NOT_IN_XR);\r\n throw e;\r\n }\r\n }\r\n\r\n /**\r\n * Exits XR mode and returns the scene to its original state\r\n * @returns promise that resolves after xr mode has exited\r\n */\r\n public async exitXRAsync() {\r\n // only exit if state is IN_XR\r\n if (this.state !== WebXRState.IN_XR) {\r\n return;\r\n }\r\n this._setState(WebXRState.EXITING_XR);\r\n return await this.sessionManager.exitXRAsync();\r\n }\r\n\r\n /**\r\n * Enable spectator mode for desktop VR experiences.\r\n * When spectator mode is enabled a camera will be attached to the desktop canvas and will\r\n * display the first rig camera's view on the desktop canvas.\r\n * Please note that this will degrade performance, as it requires another camera render.\r\n * It is also not recommended to enable this in devices like the quest, as it brings no benefit there.\r\n * @param options giving WebXRSpectatorModeOption for specutator camera to setup when the spectator mode is enabled.\r\n */\r\n public enableSpectatorMode(options?: WebXRSpectatorModeOption): void {\r\n if (!this._spectatorMode) {\r\n this._spectatorMode = true;\r\n this._switchSpectatorMode(options);\r\n }\r\n }\r\n\r\n /**\r\n * Disable spectator mode for desktop VR experiences.\r\n */\r\n public disableSpecatatorMode(): void {\r\n if (this._spectatorMode) {\r\n this._spectatorMode = false;\r\n this._switchSpectatorMode();\r\n }\r\n }\r\n\r\n private _clearSpectatorObservers() {\r\n this.sessionManager.onXRFrameObservable.remove(this._spectatorXRFrameObserver);\r\n this._spectatorXRFrameObserver = null;\r\n this._scene.onAfterRenderCameraObservable.remove(this._spectatorAfterRenderObserver);\r\n this._spectatorAfterRenderObserver = null;\r\n this.onStateChangedObservable.remove(this._spectatorStateChangedObserver);\r\n this._spectatorStateChangedObserver = null;\r\n }\r\n\r\n private _switchSpectatorMode(options?: WebXRSpectatorModeOption): void {\r\n this._clearSpectatorObservers();\r\n\r\n const fps = options?.fps ? options.fps : 1000.0;\r\n const refreshRate = (1.0 / fps) * 1000.0;\r\n const cameraIndex = options?.preferredCameraIndex ? options?.preferredCameraIndex : 0;\r\n\r\n const updateSpectatorCamera = () => {\r\n if (this._spectatorCamera) {\r\n const delta = this.sessionManager.currentTimestamp - this._lastTimestamp;\r\n if (delta >= refreshRate) {\r\n this._lastTimestamp = this.sessionManager.currentTimestamp;\r\n this._spectatorCamera.position.copyFrom(this.camera.rigCameras[cameraIndex].globalPosition);\r\n this._spectatorCamera.rotationQuaternion?.copyFrom(this.camera.rigCameras[cameraIndex].absoluteRotation);\r\n }\r\n }\r\n };\r\n if (this._spectatorMode) {\r\n if (cameraIndex >= this.camera.rigCameras.length) {\r\n throw new Error(\"the preferred camera index is beyond the length of rig camera array.\");\r\n }\r\n const onStateChanged = () => {\r\n if (this.state === WebXRState.IN_XR) {\r\n this._spectatorCamera?.dispose();\r\n this._spectatorCamera = new UniversalCamera(\"webxr-spectator\", Vector3.Zero(), this._scene);\r\n this._spectatorCamera.rotationQuaternion = new Quaternion();\r\n this._scene.activeCameras = [this.camera, this._spectatorCamera];\r\n this._spectatorXRFrameObserver = this.sessionManager.onXRFrameObservable.add(updateSpectatorCamera);\r\n this._spectatorAfterRenderObserver = this._scene.onAfterRenderCameraObservable.add((camera) => {\r\n if (camera === this.camera) {\r\n // reset the dimensions object for correct resizing\r\n (this._scene.getEngine() as ThinEngine).framebufferDimensionsObject = null;\r\n }\r\n });\r\n } else if (this.state === WebXRState.EXITING_XR) {\r\n this.sessionManager.onXRFrameObservable.remove(this._spectatorXRFrameObserver);\r\n this._spectatorXRFrameObserver = null;\r\n\r\n this._scene.onAfterRenderCameraObservable.remove(this._spectatorAfterRenderObserver);\r\n this._spectatorAfterRenderObserver = null;\r\n this._spectatorCamera?.dispose();\r\n this._spectatorCamera = null;\r\n this._scene.activeCameras = null;\r\n }\r\n };\r\n this._spectatorStateChangedObserver = this.onStateChangedObservable.add(onStateChanged);\r\n onStateChanged();\r\n } else {\r\n this._spectatorCamera?.dispose();\r\n this._spectatorCamera = null;\r\n this._scene.activeCameras = [this.camera];\r\n }\r\n }\r\n\r\n private _nonXRToXRCamera() {\r\n this.camera.setTransformationFromNonVRCamera(this._nonVRCamera!);\r\n this.onInitialXRPoseSetObservable.notifyObservers(this.camera);\r\n }\r\n\r\n private _setState(val: WebXRState) {\r\n if (this.state === val) {\r\n return;\r\n }\r\n this.state = val;\r\n this.onStateChangedObservable.notifyObservers(this.state);\r\n }\r\n}\r\n"]}
|
package/XR/webXRInput.d.ts
CHANGED
package/XR/webXRInput.js
CHANGED
|
@@ -27,6 +27,7 @@ export class WebXRInput {
|
|
|
27
27
|
* XR controllers being tracked
|
|
28
28
|
*/
|
|
29
29
|
this.controllers = [];
|
|
30
|
+
this._currentXRSession = null;
|
|
30
31
|
/**
|
|
31
32
|
* Event when a controller has been connected/added
|
|
32
33
|
*/
|
|
@@ -40,11 +41,14 @@ export class WebXRInput {
|
|
|
40
41
|
};
|
|
41
42
|
// Remove controllers when exiting XR
|
|
42
43
|
this._sessionEndedObserver = this.xrSessionManager.onXRSessionEnded.add(() => {
|
|
44
|
+
this._currentXRSession?.removeEventListener("inputsourceschange", this._onInputSourcesChange);
|
|
45
|
+
this._currentXRSession = null;
|
|
43
46
|
this._addAndRemoveControllers([], this.controllers.map((c) => {
|
|
44
47
|
return c.inputSource;
|
|
45
48
|
}));
|
|
46
49
|
});
|
|
47
50
|
this._sessionInitObserver = this.xrSessionManager.onXRSessionInit.add((session) => {
|
|
51
|
+
this._currentXRSession = session;
|
|
48
52
|
session.addEventListener("inputsourceschange", this._onInputSourcesChange);
|
|
49
53
|
});
|
|
50
54
|
this._frameObserver = this.xrSessionManager.onXRFrameObservable.add((frame) => {
|
|
@@ -108,6 +112,8 @@ export class WebXRInput {
|
|
|
108
112
|
* Disposes of the object
|
|
109
113
|
*/
|
|
110
114
|
dispose() {
|
|
115
|
+
this._currentXRSession?.removeEventListener("inputsourceschange", this._onInputSourcesChange);
|
|
116
|
+
this._currentXRSession = null;
|
|
111
117
|
for (const c of this.controllers) {
|
|
112
118
|
c.dispose();
|
|
113
119
|
}
|
package/XR/webXRInput.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webXRInput.js","sourceRoot":"","sources":["../../../../dev/core/src/XR/webXRInput.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Nullable } from \"../types\";\r\nimport type { Observer } from \"../Misc/observable\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport type { IDisposable } from \"../scene\";\r\nimport type { IWebXRControllerOptions } from \"./webXRInputSource\";\r\nimport { WebXRInputSource } from \"./webXRInputSource\";\r\nimport type { WebXRSessionManager } from \"./webXRSessionManager\";\r\nimport type { WebXRCamera } from \"./webXRCamera\";\r\nimport { WebXRMotionControllerManager } from \"./motionController/webXRMotionControllerManager\";\r\n\r\n/**\r\n * The schema for initialization options of the XR Input class\r\n */\r\nexport interface IWebXRInputOptions {\r\n /**\r\n * If set to true no model will be automatically loaded\r\n */\r\n doNotLoadControllerMeshes?: boolean;\r\n\r\n /**\r\n * If set, this profile will be used for all controllers loaded (for example \"microsoft-mixed-reality\")\r\n * If not found, the xr input profile data will be used.\r\n * Profiles are defined here - https://github.com/immersive-web/webxr-input-profiles/\r\n */\r\n forceInputProfile?: string;\r\n\r\n /**\r\n * Do not send a request to the controller repository to load the profile.\r\n *\r\n * Instead, use the controllers available in babylon itself.\r\n */\r\n disableOnlineControllerRepository?: boolean;\r\n\r\n /**\r\n * A custom URL for the controllers repository\r\n */\r\n customControllersRepositoryURL?: string;\r\n\r\n /**\r\n * Should the controller model's components not move according to the user input\r\n */\r\n disableControllerAnimation?: boolean;\r\n\r\n /**\r\n * Optional options to pass to the controller. Will be overridden by the Input options where applicable\r\n */\r\n controllerOptions?: IWebXRControllerOptions;\r\n}\r\n/**\r\n * XR input used to track XR inputs such as controllers/rays\r\n */\r\nexport class WebXRInput implements IDisposable {\r\n /**\r\n * XR controllers being tracked\r\n */\r\n public controllers: Array<WebXRInputSource> = [];\r\n private _frameObserver: Nullable<Observer<any>>;\r\n private _sessionEndedObserver: Nullable<Observer<any>>;\r\n private _sessionInitObserver: Nullable<Observer<any>>;\r\n /**\r\n * Event when a controller has been connected/added\r\n */\r\n public onControllerAddedObservable = new Observable<WebXRInputSource>();\r\n /**\r\n * Event when a controller has been removed/disconnected\r\n */\r\n public onControllerRemovedObservable = new Observable<WebXRInputSource>();\r\n\r\n /**\r\n * Initializes the WebXRInput\r\n * @param xrSessionManager the xr session manager for this session\r\n * @param xrCamera the WebXR camera for this session. Mainly used for teleportation\r\n * @param _options = initialization options for this xr input\r\n */\r\n public constructor(\r\n /**\r\n * the xr session manager for this session\r\n */\r\n public xrSessionManager: WebXRSessionManager,\r\n /**\r\n * the WebXR camera for this session. Mainly used for teleportation\r\n */\r\n public xrCamera: WebXRCamera,\r\n private readonly _options: IWebXRInputOptions = {}\r\n ) {\r\n // Remove controllers when exiting XR\r\n this._sessionEndedObserver = this.xrSessionManager.onXRSessionEnded.add(() => {\r\n this._addAndRemoveControllers(\r\n [],\r\n this.controllers.map((c) => {\r\n return c.inputSource;\r\n })\r\n );\r\n });\r\n\r\n this._sessionInitObserver = this.xrSessionManager.onXRSessionInit.add((session) => {\r\n session.addEventListener(\"inputsourceschange\", this._onInputSourcesChange);\r\n });\r\n\r\n this._frameObserver = this.xrSessionManager.onXRFrameObservable.add((frame) => {\r\n // Update controller pose info\r\n for (const controller of this.controllers) {\r\n controller.updateFromXRFrame(frame, this.xrSessionManager.referenceSpace, this.xrCamera, this.xrSessionManager);\r\n }\r\n });\r\n\r\n if (this._options.customControllersRepositoryURL) {\r\n WebXRMotionControllerManager.BaseRepositoryUrl = this._options.customControllersRepositoryURL;\r\n }\r\n\r\n WebXRMotionControllerManager.UseOnlineRepository = !this._options.disableOnlineControllerRepository;\r\n if (WebXRMotionControllerManager.UseOnlineRepository) {\r\n // pre-load the profiles list to load the controllers quicker afterwards\r\n try {\r\n // eslint-disable-next-line github/no-then\r\n WebXRMotionControllerManager.UpdateProfilesList().catch(() => {\r\n WebXRMotionControllerManager.UseOnlineRepository = false;\r\n });\r\n } catch (e) {\r\n WebXRMotionControllerManager.UseOnlineRepository = false;\r\n }\r\n }\r\n }\r\n\r\n private _onInputSourcesChange = (event: XRInputSourceChangeEvent) => {\r\n this._addAndRemoveControllers(event.added, event.removed);\r\n };\r\n\r\n private _addAndRemoveControllers(addInputs: readonly XRInputSource[], removeInputs: readonly XRInputSource[]) {\r\n // Add controllers if they don't already exist\r\n const sources = this.controllers.map((c) => {\r\n return c.inputSource;\r\n });\r\n for (const input of addInputs) {\r\n if (sources.indexOf(input) === -1) {\r\n const controller = new WebXRInputSource(this.xrSessionManager.scene, input, {\r\n ...(this._options.controllerOptions || {}),\r\n forceControllerProfile: this._options.forceInputProfile,\r\n doNotLoadControllerMesh: this._options.doNotLoadControllerMeshes,\r\n disableMotionControllerAnimation: this._options.disableControllerAnimation,\r\n });\r\n this.controllers.push(controller);\r\n this.onControllerAddedObservable.notifyObservers(controller);\r\n }\r\n }\r\n\r\n // Remove and dispose of controllers to be disposed\r\n const keepControllers: Array<WebXRInputSource> = [];\r\n const removedControllers: Array<WebXRInputSource> = [];\r\n for (const c of this.controllers) {\r\n if (removeInputs.indexOf(c.inputSource) === -1) {\r\n keepControllers.push(c);\r\n } else {\r\n removedControllers.push(c);\r\n }\r\n }\r\n this.controllers = keepControllers;\r\n for (const c of removedControllers) {\r\n this.onControllerRemovedObservable.notifyObservers(c);\r\n c.dispose();\r\n }\r\n }\r\n\r\n /**\r\n * Disposes of the object\r\n */\r\n public dispose() {\r\n for (const c of this.controllers) {\r\n c.dispose();\r\n }\r\n this.xrSessionManager.onXRFrameObservable.remove(this._frameObserver);\r\n this.xrSessionManager.onXRSessionInit.remove(this._sessionInitObserver);\r\n this.xrSessionManager.onXRSessionEnded.remove(this._sessionEndedObserver);\r\n this.onControllerAddedObservable.clear();\r\n this.onControllerRemovedObservable.clear();\r\n\r\n // clear the controller cache\r\n WebXRMotionControllerManager.ClearControllerCache();\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"webXRInput.js","sourceRoot":"","sources":["../../../../dev/core/src/XR/webXRInput.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Nullable } from \"../types\";\r\nimport type { Observer } from \"../Misc/observable\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport type { IDisposable } from \"../scene\";\r\nimport type { IWebXRControllerOptions } from \"./webXRInputSource\";\r\nimport { WebXRInputSource } from \"./webXRInputSource\";\r\nimport type { WebXRSessionManager } from \"./webXRSessionManager\";\r\nimport type { WebXRCamera } from \"./webXRCamera\";\r\nimport { WebXRMotionControllerManager } from \"./motionController/webXRMotionControllerManager\";\r\n\r\n/**\r\n * The schema for initialization options of the XR Input class\r\n */\r\nexport interface IWebXRInputOptions {\r\n /**\r\n * If set to true no model will be automatically loaded\r\n */\r\n doNotLoadControllerMeshes?: boolean;\r\n\r\n /**\r\n * If set, this profile will be used for all controllers loaded (for example \"microsoft-mixed-reality\")\r\n * If not found, the xr input profile data will be used.\r\n * Profiles are defined here - https://github.com/immersive-web/webxr-input-profiles/\r\n */\r\n forceInputProfile?: string;\r\n\r\n /**\r\n * Do not send a request to the controller repository to load the profile.\r\n *\r\n * Instead, use the controllers available in babylon itself.\r\n */\r\n disableOnlineControllerRepository?: boolean;\r\n\r\n /**\r\n * A custom URL for the controllers repository\r\n */\r\n customControllersRepositoryURL?: string;\r\n\r\n /**\r\n * Should the controller model's components not move according to the user input\r\n */\r\n disableControllerAnimation?: boolean;\r\n\r\n /**\r\n * Optional options to pass to the controller. Will be overridden by the Input options where applicable\r\n */\r\n controllerOptions?: IWebXRControllerOptions;\r\n}\r\n/**\r\n * XR input used to track XR inputs such as controllers/rays\r\n */\r\nexport class WebXRInput implements IDisposable {\r\n /**\r\n * XR controllers being tracked\r\n */\r\n public controllers: Array<WebXRInputSource> = [];\r\n private _frameObserver: Nullable<Observer<any>>;\r\n private _sessionEndedObserver: Nullable<Observer<any>>;\r\n private _sessionInitObserver: Nullable<Observer<any>>;\r\n private _currentXRSession: Nullable<XRSession> = null;\r\n /**\r\n * Event when a controller has been connected/added\r\n */\r\n public onControllerAddedObservable = new Observable<WebXRInputSource>();\r\n /**\r\n * Event when a controller has been removed/disconnected\r\n */\r\n public onControllerRemovedObservable = new Observable<WebXRInputSource>();\r\n\r\n /**\r\n * Initializes the WebXRInput\r\n * @param xrSessionManager the xr session manager for this session\r\n * @param xrCamera the WebXR camera for this session. Mainly used for teleportation\r\n * @param _options = initialization options for this xr input\r\n */\r\n public constructor(\r\n /**\r\n * the xr session manager for this session\r\n */\r\n public xrSessionManager: WebXRSessionManager,\r\n /**\r\n * the WebXR camera for this session. Mainly used for teleportation\r\n */\r\n public xrCamera: WebXRCamera,\r\n private readonly _options: IWebXRInputOptions = {}\r\n ) {\r\n // Remove controllers when exiting XR\r\n this._sessionEndedObserver = this.xrSessionManager.onXRSessionEnded.add(() => {\r\n this._currentXRSession?.removeEventListener(\"inputsourceschange\", this._onInputSourcesChange);\r\n this._currentXRSession = null;\r\n this._addAndRemoveControllers(\r\n [],\r\n this.controllers.map((c) => {\r\n return c.inputSource;\r\n })\r\n );\r\n });\r\n\r\n this._sessionInitObserver = this.xrSessionManager.onXRSessionInit.add((session) => {\r\n this._currentXRSession = session;\r\n session.addEventListener(\"inputsourceschange\", this._onInputSourcesChange);\r\n });\r\n\r\n this._frameObserver = this.xrSessionManager.onXRFrameObservable.add((frame) => {\r\n // Update controller pose info\r\n for (const controller of this.controllers) {\r\n controller.updateFromXRFrame(frame, this.xrSessionManager.referenceSpace, this.xrCamera, this.xrSessionManager);\r\n }\r\n });\r\n\r\n if (this._options.customControllersRepositoryURL) {\r\n WebXRMotionControllerManager.BaseRepositoryUrl = this._options.customControllersRepositoryURL;\r\n }\r\n\r\n WebXRMotionControllerManager.UseOnlineRepository = !this._options.disableOnlineControllerRepository;\r\n if (WebXRMotionControllerManager.UseOnlineRepository) {\r\n // pre-load the profiles list to load the controllers quicker afterwards\r\n try {\r\n // eslint-disable-next-line github/no-then\r\n WebXRMotionControllerManager.UpdateProfilesList().catch(() => {\r\n WebXRMotionControllerManager.UseOnlineRepository = false;\r\n });\r\n } catch (e) {\r\n WebXRMotionControllerManager.UseOnlineRepository = false;\r\n }\r\n }\r\n }\r\n\r\n private _onInputSourcesChange = (event: XRInputSourceChangeEvent) => {\r\n this._addAndRemoveControllers(event.added, event.removed);\r\n };\r\n\r\n private _addAndRemoveControllers(addInputs: readonly XRInputSource[], removeInputs: readonly XRInputSource[]) {\r\n // Add controllers if they don't already exist\r\n const sources = this.controllers.map((c) => {\r\n return c.inputSource;\r\n });\r\n for (const input of addInputs) {\r\n if (sources.indexOf(input) === -1) {\r\n const controller = new WebXRInputSource(this.xrSessionManager.scene, input, {\r\n ...(this._options.controllerOptions || {}),\r\n forceControllerProfile: this._options.forceInputProfile,\r\n doNotLoadControllerMesh: this._options.doNotLoadControllerMeshes,\r\n disableMotionControllerAnimation: this._options.disableControllerAnimation,\r\n });\r\n this.controllers.push(controller);\r\n this.onControllerAddedObservable.notifyObservers(controller);\r\n }\r\n }\r\n\r\n // Remove and dispose of controllers to be disposed\r\n const keepControllers: Array<WebXRInputSource> = [];\r\n const removedControllers: Array<WebXRInputSource> = [];\r\n for (const c of this.controllers) {\r\n if (removeInputs.indexOf(c.inputSource) === -1) {\r\n keepControllers.push(c);\r\n } else {\r\n removedControllers.push(c);\r\n }\r\n }\r\n this.controllers = keepControllers;\r\n for (const c of removedControllers) {\r\n this.onControllerRemovedObservable.notifyObservers(c);\r\n c.dispose();\r\n }\r\n }\r\n\r\n /**\r\n * Disposes of the object\r\n */\r\n public dispose() {\r\n this._currentXRSession?.removeEventListener(\"inputsourceschange\", this._onInputSourcesChange);\r\n this._currentXRSession = null;\r\n for (const c of this.controllers) {\r\n c.dispose();\r\n }\r\n this.xrSessionManager.onXRFrameObservable.remove(this._frameObserver);\r\n this.xrSessionManager.onXRSessionInit.remove(this._sessionInitObserver);\r\n this.xrSessionManager.onXRSessionEnded.remove(this._sessionEndedObserver);\r\n this.onControllerAddedObservable.clear();\r\n this.onControllerRemovedObservable.clear();\r\n\r\n // clear the controller cache\r\n WebXRMotionControllerManager.ClearControllerCache();\r\n }\r\n}\r\n"]}
|
|
@@ -120,6 +120,7 @@ export class WebXRSessionManager {
|
|
|
120
120
|
this.onXRFrameObservable.clear();
|
|
121
121
|
this.onXRSessionEnded.clear();
|
|
122
122
|
this.onXRReferenceSpaceChanged.clear();
|
|
123
|
+
this.onXRReferenceSpaceInitialized.clear();
|
|
123
124
|
this.onXRSessionInit.clear();
|
|
124
125
|
this.onWorldScaleFactorChangedObservable.clear();
|
|
125
126
|
this._engine?.onDisposeObservable.remove(this._onEngineDisposedObserver);
|
|
@@ -292,6 +293,7 @@ export class WebXRSessionManager {
|
|
|
292
293
|
*/
|
|
293
294
|
async setReferenceSpaceTypeAsync(referenceSpaceType = "local-floor") {
|
|
294
295
|
let referenceSpace;
|
|
296
|
+
let viewerReferenceSpace = null;
|
|
295
297
|
try {
|
|
296
298
|
referenceSpace = await this.session.requestReferenceSpace(referenceSpaceType);
|
|
297
299
|
}
|
|
@@ -300,9 +302,9 @@ export class WebXRSessionManager {
|
|
|
300
302
|
Logger.Error(rejectionReason);
|
|
301
303
|
Logger.Log('Defaulting to universally-supported "viewer" reference space type.');
|
|
302
304
|
try {
|
|
303
|
-
|
|
305
|
+
viewerReferenceSpace = (await this.session.requestReferenceSpace("viewer"));
|
|
304
306
|
const heightCompensation = new XRRigidTransform({ x: 0, y: -this.defaultHeightCompensation, z: 0 });
|
|
305
|
-
|
|
307
|
+
referenceSpace = viewerReferenceSpace.getOffsetReferenceSpace(heightCompensation);
|
|
306
308
|
}
|
|
307
309
|
catch (rejectionReason) {
|
|
308
310
|
Logger.Error(rejectionReason);
|
|
@@ -311,8 +313,7 @@ export class WebXRSessionManager {
|
|
|
311
313
|
}
|
|
312
314
|
}
|
|
313
315
|
// create viewer reference space before setting the first reference space
|
|
314
|
-
|
|
315
|
-
this.viewerReferenceSpace = viewerReferenceSpace;
|
|
316
|
+
this.viewerReferenceSpace = viewerReferenceSpace ?? (await this.session.requestReferenceSpace("viewer"));
|
|
316
317
|
// initialize the base and offset (currently the same)
|
|
317
318
|
this.referenceSpace = this.baseReferenceSpace = referenceSpace;
|
|
318
319
|
this.onXRReferenceSpaceInitialized.notifyObservers(referenceSpace);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webXRSessionManager.js","sourceRoot":"","sources":["../../../../dev/core/src/XR/webXRSessionManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { Logger } from \"../Misc/logger\";\r\nimport type { Observer } from \"../Misc/observable\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport type { Nullable } from \"../types\";\r\nimport type { IDisposable, Scene } from \"../scene\";\r\nimport type { RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture\";\r\nimport type { WebXRRenderTarget } from \"./webXRTypes\";\r\nimport { WebXRManagedOutputCanvas, WebXRManagedOutputCanvasOptions } from \"./webXRManagedOutputCanvas\";\r\nimport type { Engine } from \"../Engines/engine\";\r\nimport type { IWebXRRenderTargetTextureProvider, WebXRLayerRenderTargetTextureProvider } from \"./webXRRenderTargetTextureProvider\";\r\nimport type { Viewport } from \"../Maths/math.viewport\";\r\nimport type { WebXRLayerWrapper } from \"./webXRLayerWrapper\";\r\nimport { NativeXRLayerWrapper, NativeXRRenderTarget } from \"./native/nativeXRRenderTarget\";\r\nimport { WebXRWebGLLayerWrapper } from \"./webXRWebGLLayer\";\r\nimport type { AbstractEngine } from \"../Engines/abstractEngine\";\r\n\r\n/**\r\n * Manages an XRSession to work with Babylon's engine\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/webXR/webXRSessionManagers\r\n */\r\nexport class WebXRSessionManager implements IDisposable, IWebXRRenderTargetTextureProvider {\r\n private _engine: Nullable<Engine>;\r\n private _referenceSpace: XRReferenceSpace;\r\n private _baseLayerWrapper: Nullable<WebXRLayerWrapper>;\r\n private _baseLayerRTTProvider: Nullable<WebXRLayerRenderTargetTextureProvider>;\r\n private _xrNavigator: any;\r\n private _sessionMode: XRSessionMode;\r\n private _onEngineDisposedObserver: Nullable<Observer<AbstractEngine>>;\r\n\r\n /**\r\n * The base reference space from which the session started. good if you want to reset your\r\n * reference space\r\n */\r\n public baseReferenceSpace: XRReferenceSpace;\r\n /**\r\n * Current XR frame\r\n */\r\n public currentFrame: Nullable<XRFrame>;\r\n /** WebXR timestamp updated every frame */\r\n public currentTimestamp: number = -1;\r\n /**\r\n * Used just in case of a failure to initialize an immersive session.\r\n * The viewer reference space is compensated using this height, creating a kind of \"viewer-floor\" reference space\r\n */\r\n public defaultHeightCompensation = 1.7;\r\n /**\r\n * Fires every time a new xrFrame arrives which can be used to update the camera\r\n */\r\n public onXRFrameObservable: Observable<XRFrame> = new Observable<XRFrame>();\r\n /**\r\n * Fires when the reference space changed\r\n */\r\n public onXRReferenceSpaceChanged: Observable<XRReferenceSpace> = new Observable();\r\n /**\r\n * Fires when the xr session is ended either by the device or manually done\r\n */\r\n public onXRSessionEnded: Observable<any> = new Observable<any>();\r\n /**\r\n * Fires when the xr session is initialized: right after requestSession was called and returned with a successful result\r\n */\r\n public onXRSessionInit: Observable<XRSession> = new Observable<XRSession>();\r\n\r\n /**\r\n * Fires when the xr reference space has been initialized\r\n */\r\n public onXRReferenceSpaceInitialized: Observable<XRReferenceSpace> = new Observable<XRReferenceSpace>();\r\n\r\n /**\r\n * Fires when the session manager is rendering the first frame\r\n */\r\n public onXRReady: Observable<WebXRSessionManager> = new Observable<WebXRSessionManager>();\r\n /**\r\n * Underlying xr session\r\n */\r\n public session: XRSession;\r\n /**\r\n * The viewer (head position) reference space. This can be used to get the XR world coordinates\r\n * or get the offset the player is currently at.\r\n */\r\n public viewerReferenceSpace: XRReferenceSpace;\r\n /**\r\n * Are we currently in the XR loop?\r\n */\r\n public inXRFrameLoop: boolean = false;\r\n /**\r\n * Are we in an XR session?\r\n */\r\n public inXRSession: boolean = false;\r\n\r\n private _worldScalingFactor: number = 1;\r\n\r\n /**\r\n * Observable raised when the world scale has changed\r\n */\r\n public onWorldScaleFactorChangedObservable: Observable<{\r\n previousScaleFactor: number;\r\n newScaleFactor: number;\r\n }> = new Observable(undefined, true);\r\n\r\n /**\r\n * Scale factor to apply to all XR-related elements (camera, controllers)\r\n */\r\n public get worldScalingFactor(): number {\r\n return this._worldScalingFactor;\r\n }\r\n\r\n public set worldScalingFactor(value: number) {\r\n const oldValue = this._worldScalingFactor;\r\n this._worldScalingFactor = value;\r\n this.onWorldScaleFactorChangedObservable.notifyObservers({\r\n previousScaleFactor: oldValue,\r\n newScaleFactor: value,\r\n });\r\n }\r\n\r\n /**\r\n * Constructs a WebXRSessionManager, this must be initialized within a user action before usage\r\n * @param scene The scene which the session should be created for\r\n */\r\n constructor(\r\n /** The scene which the session should be created for */\r\n public scene: Scene\r\n ) {\r\n this._engine = scene.getEngine() as Engine;\r\n this._onEngineDisposedObserver = this._engine.onDisposeObservable.addOnce(() => {\r\n this._engine = null;\r\n });\r\n scene.onDisposeObservable.addOnce(() => {\r\n this.dispose();\r\n });\r\n\r\n this.onXRSessionEnded.add(() => {\r\n // Set the scene's pointer camera to null to stop the XR camera being used for picking.\r\n scene.cameraToUseForPointers = null;\r\n });\r\n }\r\n\r\n /**\r\n * The current reference space used in this session. This reference space can constantly change!\r\n * It is mainly used to offset the camera's position.\r\n */\r\n public get referenceSpace(): XRReferenceSpace {\r\n return this._referenceSpace;\r\n }\r\n\r\n /**\r\n * Set a new reference space and triggers the observable\r\n */\r\n public set referenceSpace(newReferenceSpace: XRReferenceSpace) {\r\n this._referenceSpace = newReferenceSpace;\r\n this.onXRReferenceSpaceChanged.notifyObservers(this._referenceSpace);\r\n }\r\n\r\n /**\r\n * The mode for the managed XR session\r\n */\r\n public get sessionMode(): XRSessionMode {\r\n return this._sessionMode;\r\n }\r\n\r\n /**\r\n * Disposes of the session manager\r\n * This should be called explicitly by the dev, if required.\r\n */\r\n public dispose() {\r\n // disposing without leaving XR? Exit XR first\r\n if (this.inXRSession) {\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.exitXRAsync();\r\n }\r\n this.onXRReady.clear();\r\n this.onXRFrameObservable.clear();\r\n this.onXRSessionEnded.clear();\r\n this.onXRReferenceSpaceChanged.clear();\r\n this.onXRSessionInit.clear();\r\n this.onWorldScaleFactorChangedObservable.clear();\r\n this._engine?.onDisposeObservable.remove(this._onEngineDisposedObserver);\r\n this._engine = null;\r\n }\r\n\r\n /**\r\n * Stops the xrSession and restores the render loop\r\n * @returns Promise which resolves after it exits XR\r\n */\r\n public async exitXRAsync() {\r\n if (this.session && this.inXRSession) {\r\n this.inXRSession = false;\r\n try {\r\n return await this.session.end();\r\n } catch {\r\n Logger.Warn(\"Could not end XR session.\");\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Attempts to set the framebuffer-size-normalized viewport to be rendered this frame for this view.\r\n * In the event of a failure, the supplied viewport is not updated.\r\n * @param viewport the viewport to which the view will be rendered\r\n * @param view the view for which to set the viewport\r\n * @returns whether the operation was successful\r\n */\r\n public trySetViewportForView(viewport: Viewport, view: XRView): boolean {\r\n return this._baseLayerRTTProvider?.trySetViewportForView(viewport, view) || false;\r\n }\r\n\r\n /**\r\n * Gets the correct render target texture to be rendered this frame for this eye\r\n * @param eye the eye for which to get the render target\r\n * @returns the render target for the specified eye or null if not available\r\n */\r\n public getRenderTargetTextureForEye(eye: XREye): Nullable<RenderTargetTexture> {\r\n return this._baseLayerRTTProvider?.getRenderTargetTextureForEye(eye) || null;\r\n }\r\n\r\n /**\r\n * Gets the correct render target texture to be rendered this frame for this view\r\n * @param view the view for which to get the render target\r\n * @returns the render target for the specified view or null if not available\r\n */\r\n public getRenderTargetTextureForView(view: XRView): Nullable<RenderTargetTexture> {\r\n return this._baseLayerRTTProvider?.getRenderTargetTextureForView(view) || null;\r\n }\r\n\r\n /**\r\n * Creates a WebXRRenderTarget object for the XR session\r\n * @param options optional options to provide when creating a new render target\r\n * @returns a WebXR render target to which the session can render\r\n */\r\n public getWebXRRenderTarget(options?: WebXRManagedOutputCanvasOptions): WebXRRenderTarget {\r\n const engine = this.scene.getEngine();\r\n if (this._xrNavigator.xr.native) {\r\n return new NativeXRRenderTarget(this);\r\n } else {\r\n options = options || WebXRManagedOutputCanvasOptions.GetDefaults(engine);\r\n options.canvasElement = options.canvasElement || engine.getRenderingCanvas() || undefined;\r\n return new WebXRManagedOutputCanvas(this, options);\r\n }\r\n }\r\n\r\n /**\r\n * Initializes the manager\r\n * After initialization enterXR can be called to start an XR session\r\n * @returns Promise which resolves after it is initialized\r\n */\r\n public async initializeAsync(): Promise<void> {\r\n // Check if the browser supports webXR\r\n this._xrNavigator = navigator;\r\n if (!this._xrNavigator.xr) {\r\n throw new Error(\"WebXR not supported on this browser.\");\r\n }\r\n }\r\n\r\n /**\r\n * Initializes an xr session\r\n * @param xrSessionMode mode to initialize\r\n * @param xrSessionInit defines optional and required values to pass to the session builder\r\n * @returns a promise which will resolve once the session has been initialized\r\n */\r\n public async initializeSessionAsync(xrSessionMode: XRSessionMode = \"immersive-vr\", xrSessionInit: XRSessionInit = {}): Promise<XRSession> {\r\n const session = await this._xrNavigator.xr.requestSession(xrSessionMode, xrSessionInit);\r\n\r\n this.session = session;\r\n this._sessionMode = xrSessionMode;\r\n this.inXRSession = true;\r\n this.onXRSessionInit.notifyObservers(session);\r\n\r\n // handle when the session is ended (By calling session.end or device ends its own session eg. pressing home button on phone)\r\n this.session.addEventListener(\r\n \"end\",\r\n () => {\r\n this.inXRSession = false;\r\n\r\n // Notify frame observers\r\n this.onXRSessionEnded.notifyObservers(null);\r\n\r\n if (this._engine) {\r\n // make sure dimensions object is restored\r\n this._engine.framebufferDimensionsObject = null;\r\n\r\n // Restore frame buffer to avoid clear on xr framebuffer after session end\r\n this._engine.restoreDefaultFramebuffer();\r\n\r\n // Need to restart render loop as after the session is ended the last request for new frame will never call callback\r\n this._engine.customAnimationFrameRequester = null;\r\n this._engine._renderLoop();\r\n }\r\n\r\n // Dispose render target textures.\r\n // Only dispose on native because we can't destroy opaque textures on browser.\r\n if (this.isNative) {\r\n this._baseLayerRTTProvider?.dispose();\r\n }\r\n this._baseLayerRTTProvider = null;\r\n this._baseLayerWrapper = null;\r\n },\r\n { once: true }\r\n );\r\n\r\n return this.session;\r\n }\r\n\r\n /**\r\n * Checks if a session would be supported for the creation options specified\r\n * @param sessionMode session mode to check if supported eg. immersive-vr\r\n * @returns A Promise that resolves to true if supported and false if not\r\n */\r\n public async isSessionSupportedAsync(sessionMode: XRSessionMode): Promise<boolean> {\r\n return await WebXRSessionManager.IsSessionSupportedAsync(sessionMode);\r\n }\r\n\r\n /**\r\n * Resets the reference space to the one started the session\r\n */\r\n public resetReferenceSpace() {\r\n this.referenceSpace = this.baseReferenceSpace;\r\n }\r\n\r\n /**\r\n * Starts rendering to the xr layer\r\n */\r\n public runXRRenderLoop() {\r\n if (!this.inXRSession || !this._engine) {\r\n return;\r\n }\r\n\r\n // Tell the engine's render loop to be driven by the xr session's refresh rate and provide xr pose information\r\n this._engine.customAnimationFrameRequester = {\r\n requestAnimationFrame: (callback: FrameRequestCallback) => this.session.requestAnimationFrame(callback),\r\n renderFunction: (timestamp: number, xrFrame: Nullable<XRFrame>) => {\r\n if (!this.inXRSession || !this._engine) {\r\n return;\r\n }\r\n // Store the XR frame and timestamp in the session manager\r\n this.currentFrame = xrFrame;\r\n this.currentTimestamp = timestamp;\r\n if (xrFrame) {\r\n this.inXRFrameLoop = true;\r\n const framebufferDimensionsObject = this._baseLayerRTTProvider?.getFramebufferDimensions() || null;\r\n // equality can be tested as it should be the same object\r\n if (this._engine.framebufferDimensionsObject !== framebufferDimensionsObject) {\r\n this._engine.framebufferDimensionsObject = framebufferDimensionsObject;\r\n }\r\n this.onXRFrameObservable.notifyObservers(xrFrame);\r\n this._engine._renderLoop();\r\n this._engine.framebufferDimensionsObject = null;\r\n this.inXRFrameLoop = false;\r\n }\r\n },\r\n };\r\n\r\n this._engine.framebufferDimensionsObject = this._baseLayerRTTProvider?.getFramebufferDimensions() || null;\r\n this.onXRFrameObservable.addOnce(() => {\r\n this.onXRReady.notifyObservers(this);\r\n });\r\n\r\n // Stop window's animation frame and trigger sessions animation frame\r\n if (typeof window !== \"undefined\" && window.cancelAnimationFrame) {\r\n window.cancelAnimationFrame(this._engine._frameHandler);\r\n }\r\n this._engine._renderLoop();\r\n }\r\n\r\n /**\r\n * Sets the reference space on the xr session\r\n * @param referenceSpaceType space to set\r\n * @returns a promise that will resolve once the reference space has been set\r\n */\r\n public async setReferenceSpaceTypeAsync(referenceSpaceType: XRReferenceSpaceType = \"local-floor\"): Promise<XRReferenceSpace> {\r\n let referenceSpace: XRReferenceSpace;\r\n try {\r\n referenceSpace = await this.session.requestReferenceSpace(referenceSpaceType);\r\n } catch (rejectionReason) {\r\n Logger.Error(\"XR.requestReferenceSpace failed for the following reason: \");\r\n Logger.Error(rejectionReason);\r\n Logger.Log('Defaulting to universally-supported \"viewer\" reference space type.');\r\n\r\n try {\r\n const referenceSpace = await this.session.requestReferenceSpace(\"viewer\");\r\n const heightCompensation = new XRRigidTransform({ x: 0, y: -this.defaultHeightCompensation, z: 0 });\r\n return (referenceSpace as XRReferenceSpace).getOffsetReferenceSpace(heightCompensation);\r\n } catch (rejectionReason) {\r\n Logger.Error(rejectionReason);\r\n // eslint-disable-next-line no-throw-literal\r\n throw 'XR initialization failed: required \"viewer\" reference space type not supported.';\r\n }\r\n }\r\n // create viewer reference space before setting the first reference space\r\n const viewerReferenceSpace = await this.session.requestReferenceSpace(\"viewer\");\r\n this.viewerReferenceSpace = viewerReferenceSpace as XRReferenceSpace;\r\n // initialize the base and offset (currently the same)\r\n this.referenceSpace = this.baseReferenceSpace = referenceSpace;\r\n this.onXRReferenceSpaceInitialized.notifyObservers(referenceSpace);\r\n return this.referenceSpace;\r\n }\r\n\r\n /**\r\n * Updates the render state of the session.\r\n * Note that this is deprecated in favor of WebXRSessionManager.updateRenderState().\r\n * @param state state to set\r\n * @returns a promise that resolves once the render state has been updated\r\n * @deprecated Use updateRenderState() instead.\r\n */\r\n public async updateRenderStateAsync(state: XRRenderState): Promise<void> {\r\n return await this.session.updateRenderState(state);\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _setBaseLayerWrapper(baseLayerWrapper: Nullable<WebXRLayerWrapper>): void {\r\n if (this.isNative) {\r\n this._baseLayerRTTProvider?.dispose();\r\n }\r\n this._baseLayerWrapper = baseLayerWrapper;\r\n this._baseLayerRTTProvider = this._baseLayerWrapper?.createRenderTargetTextureProvider(this) || null;\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _getBaseLayerWrapper(): Nullable<WebXRLayerWrapper> {\r\n return this._baseLayerWrapper;\r\n }\r\n\r\n /**\r\n * Updates the render state of the session\r\n * @param state state to set\r\n */\r\n public updateRenderState(state: XRRenderStateInit): void {\r\n if (state.baseLayer) {\r\n this._setBaseLayerWrapper(this.isNative ? new NativeXRLayerWrapper(state.baseLayer) : new WebXRWebGLLayerWrapper(state.baseLayer));\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.session.updateRenderState(state);\r\n }\r\n\r\n /**\r\n * Returns a promise that resolves with a boolean indicating if the provided session mode is supported by this browser\r\n * @param sessionMode defines the session to test\r\n * @returns a promise with boolean as final value\r\n */\r\n public static async IsSessionSupportedAsync(sessionMode: XRSessionMode): Promise<boolean> {\r\n if (!(navigator as any).xr) {\r\n return false;\r\n }\r\n // When the specs are final, remove supportsSession!\r\n const functionToUse = (navigator as any).xr.isSessionSupported || (navigator as any).xr.supportsSession;\r\n if (!functionToUse) {\r\n return false;\r\n } else {\r\n try {\r\n const result = functionToUse.call((navigator as any).xr, sessionMode);\r\n const returnValue = typeof result === \"undefined\" ? true : result;\r\n return returnValue;\r\n } catch (e: any) {\r\n Logger.Warn(e);\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Returns true if Babylon.js is using the BabylonNative backend, otherwise false\r\n */\r\n public get isNative(): boolean {\r\n return this._xrNavigator.xr.native ?? false;\r\n }\r\n\r\n /**\r\n * The current frame rate as reported by the device\r\n */\r\n public get currentFrameRate(): number | undefined {\r\n return this.session?.frameRate;\r\n }\r\n\r\n /**\r\n * A list of supported frame rates (only available in-session!\r\n */\r\n public get supportedFrameRates(): Float32Array | undefined {\r\n return this.session?.supportedFrameRates;\r\n }\r\n\r\n /**\r\n * Set the framerate of the session.\r\n * @param rate the new framerate. This value needs to be in the supportedFrameRates array\r\n * @returns a promise that resolves once the framerate has been set\r\n */\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n public async updateTargetFrameRate(rate: number): Promise<void> {\r\n return await this.session.updateTargetFrameRate(rate);\r\n }\r\n\r\n /**\r\n * Run a callback in the xr render loop\r\n * @param callback the callback to call when in XR Frame\r\n * @param ignoreIfNotInSession if no session is currently running, run it first thing on the next session\r\n */\r\n public runInXRFrame(callback: () => void, ignoreIfNotInSession = true): void {\r\n if (this.inXRFrameLoop) {\r\n callback();\r\n } else if (this.inXRSession || !ignoreIfNotInSession) {\r\n this.onXRFrameObservable.addOnce(callback);\r\n }\r\n }\r\n\r\n /**\r\n * Check if fixed foveation is supported on this device\r\n */\r\n public get isFixedFoveationSupported(): boolean {\r\n return this._baseLayerWrapper?.isFixedFoveationSupported || false;\r\n }\r\n\r\n /**\r\n * Get the fixed foveation currently set, as specified by the webxr specs\r\n * If this returns null, then fixed foveation is not supported\r\n */\r\n public get fixedFoveation(): Nullable<number> {\r\n return this._baseLayerWrapper?.fixedFoveation || null;\r\n }\r\n\r\n /**\r\n * Set the fixed foveation to the specified value, as specified by the webxr specs\r\n * This value will be normalized to be between 0 and 1, 1 being max foveation, 0 being no foveation\r\n */\r\n public set fixedFoveation(value: Nullable<number>) {\r\n const val = Math.max(0, Math.min(1, value || 0));\r\n if (this._baseLayerWrapper) {\r\n this._baseLayerWrapper.fixedFoveation = val;\r\n }\r\n }\r\n\r\n /**\r\n * Get the features enabled on the current session\r\n * This is only available in-session!\r\n * @see https://www.w3.org/TR/webxr/#dom-xrsession-enabledfeatures\r\n */\r\n public get enabledFeatures(): Nullable<string[]> {\r\n return this.session?.enabledFeatures ?? null;\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"webXRSessionManager.js","sourceRoot":"","sources":["../../../../dev/core/src/XR/webXRSessionManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { Logger } from \"../Misc/logger\";\r\nimport type { Observer } from \"../Misc/observable\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport type { Nullable } from \"../types\";\r\nimport type { IDisposable, Scene } from \"../scene\";\r\nimport type { RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture\";\r\nimport type { WebXRRenderTarget } from \"./webXRTypes\";\r\nimport { WebXRManagedOutputCanvas, WebXRManagedOutputCanvasOptions } from \"./webXRManagedOutputCanvas\";\r\nimport type { Engine } from \"../Engines/engine\";\r\nimport type { IWebXRRenderTargetTextureProvider, WebXRLayerRenderTargetTextureProvider } from \"./webXRRenderTargetTextureProvider\";\r\nimport type { Viewport } from \"../Maths/math.viewport\";\r\nimport type { WebXRLayerWrapper } from \"./webXRLayerWrapper\";\r\nimport { NativeXRLayerWrapper, NativeXRRenderTarget } from \"./native/nativeXRRenderTarget\";\r\nimport { WebXRWebGLLayerWrapper } from \"./webXRWebGLLayer\";\r\nimport type { AbstractEngine } from \"../Engines/abstractEngine\";\r\n\r\n/**\r\n * Manages an XRSession to work with Babylon's engine\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/webXR/webXRSessionManagers\r\n */\r\nexport class WebXRSessionManager implements IDisposable, IWebXRRenderTargetTextureProvider {\r\n private _engine: Nullable<Engine>;\r\n private _referenceSpace: XRReferenceSpace;\r\n private _baseLayerWrapper: Nullable<WebXRLayerWrapper>;\r\n private _baseLayerRTTProvider: Nullable<WebXRLayerRenderTargetTextureProvider>;\r\n private _xrNavigator: any;\r\n private _sessionMode: XRSessionMode;\r\n private _onEngineDisposedObserver: Nullable<Observer<AbstractEngine>>;\r\n\r\n /**\r\n * The base reference space from which the session started. good if you want to reset your\r\n * reference space\r\n */\r\n public baseReferenceSpace: XRReferenceSpace;\r\n /**\r\n * Current XR frame\r\n */\r\n public currentFrame: Nullable<XRFrame>;\r\n /** WebXR timestamp updated every frame */\r\n public currentTimestamp: number = -1;\r\n /**\r\n * Used just in case of a failure to initialize an immersive session.\r\n * The viewer reference space is compensated using this height, creating a kind of \"viewer-floor\" reference space\r\n */\r\n public defaultHeightCompensation = 1.7;\r\n /**\r\n * Fires every time a new xrFrame arrives which can be used to update the camera\r\n */\r\n public onXRFrameObservable: Observable<XRFrame> = new Observable<XRFrame>();\r\n /**\r\n * Fires when the reference space changed\r\n */\r\n public onXRReferenceSpaceChanged: Observable<XRReferenceSpace> = new Observable();\r\n /**\r\n * Fires when the xr session is ended either by the device or manually done\r\n */\r\n public onXRSessionEnded: Observable<any> = new Observable<any>();\r\n /**\r\n * Fires when the xr session is initialized: right after requestSession was called and returned with a successful result\r\n */\r\n public onXRSessionInit: Observable<XRSession> = new Observable<XRSession>();\r\n\r\n /**\r\n * Fires when the xr reference space has been initialized\r\n */\r\n public onXRReferenceSpaceInitialized: Observable<XRReferenceSpace> = new Observable<XRReferenceSpace>();\r\n\r\n /**\r\n * Fires when the session manager is rendering the first frame\r\n */\r\n public onXRReady: Observable<WebXRSessionManager> = new Observable<WebXRSessionManager>();\r\n /**\r\n * Underlying xr session\r\n */\r\n public session: XRSession;\r\n /**\r\n * The viewer (head position) reference space. This can be used to get the XR world coordinates\r\n * or get the offset the player is currently at.\r\n */\r\n public viewerReferenceSpace: XRReferenceSpace;\r\n /**\r\n * Are we currently in the XR loop?\r\n */\r\n public inXRFrameLoop: boolean = false;\r\n /**\r\n * Are we in an XR session?\r\n */\r\n public inXRSession: boolean = false;\r\n\r\n private _worldScalingFactor: number = 1;\r\n\r\n /**\r\n * Observable raised when the world scale has changed\r\n */\r\n public onWorldScaleFactorChangedObservable: Observable<{\r\n previousScaleFactor: number;\r\n newScaleFactor: number;\r\n }> = new Observable(undefined, true);\r\n\r\n /**\r\n * Scale factor to apply to all XR-related elements (camera, controllers)\r\n */\r\n public get worldScalingFactor(): number {\r\n return this._worldScalingFactor;\r\n }\r\n\r\n public set worldScalingFactor(value: number) {\r\n const oldValue = this._worldScalingFactor;\r\n this._worldScalingFactor = value;\r\n this.onWorldScaleFactorChangedObservable.notifyObservers({\r\n previousScaleFactor: oldValue,\r\n newScaleFactor: value,\r\n });\r\n }\r\n\r\n /**\r\n * Constructs a WebXRSessionManager, this must be initialized within a user action before usage\r\n * @param scene The scene which the session should be created for\r\n */\r\n constructor(\r\n /** The scene which the session should be created for */\r\n public scene: Scene\r\n ) {\r\n this._engine = scene.getEngine() as Engine;\r\n this._onEngineDisposedObserver = this._engine.onDisposeObservable.addOnce(() => {\r\n this._engine = null;\r\n });\r\n scene.onDisposeObservable.addOnce(() => {\r\n this.dispose();\r\n });\r\n\r\n this.onXRSessionEnded.add(() => {\r\n // Set the scene's pointer camera to null to stop the XR camera being used for picking.\r\n scene.cameraToUseForPointers = null;\r\n });\r\n }\r\n\r\n /**\r\n * The current reference space used in this session. This reference space can constantly change!\r\n * It is mainly used to offset the camera's position.\r\n */\r\n public get referenceSpace(): XRReferenceSpace {\r\n return this._referenceSpace;\r\n }\r\n\r\n /**\r\n * Set a new reference space and triggers the observable\r\n */\r\n public set referenceSpace(newReferenceSpace: XRReferenceSpace) {\r\n this._referenceSpace = newReferenceSpace;\r\n this.onXRReferenceSpaceChanged.notifyObservers(this._referenceSpace);\r\n }\r\n\r\n /**\r\n * The mode for the managed XR session\r\n */\r\n public get sessionMode(): XRSessionMode {\r\n return this._sessionMode;\r\n }\r\n\r\n /**\r\n * Disposes of the session manager\r\n * This should be called explicitly by the dev, if required.\r\n */\r\n public dispose() {\r\n // disposing without leaving XR? Exit XR first\r\n if (this.inXRSession) {\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.exitXRAsync();\r\n }\r\n this.onXRReady.clear();\r\n this.onXRFrameObservable.clear();\r\n this.onXRSessionEnded.clear();\r\n this.onXRReferenceSpaceChanged.clear();\r\n this.onXRReferenceSpaceInitialized.clear();\r\n this.onXRSessionInit.clear();\r\n this.onWorldScaleFactorChangedObservable.clear();\r\n this._engine?.onDisposeObservable.remove(this._onEngineDisposedObserver);\r\n this._engine = null;\r\n }\r\n\r\n /**\r\n * Stops the xrSession and restores the render loop\r\n * @returns Promise which resolves after it exits XR\r\n */\r\n public async exitXRAsync() {\r\n if (this.session && this.inXRSession) {\r\n this.inXRSession = false;\r\n try {\r\n return await this.session.end();\r\n } catch {\r\n Logger.Warn(\"Could not end XR session.\");\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Attempts to set the framebuffer-size-normalized viewport to be rendered this frame for this view.\r\n * In the event of a failure, the supplied viewport is not updated.\r\n * @param viewport the viewport to which the view will be rendered\r\n * @param view the view for which to set the viewport\r\n * @returns whether the operation was successful\r\n */\r\n public trySetViewportForView(viewport: Viewport, view: XRView): boolean {\r\n return this._baseLayerRTTProvider?.trySetViewportForView(viewport, view) || false;\r\n }\r\n\r\n /**\r\n * Gets the correct render target texture to be rendered this frame for this eye\r\n * @param eye the eye for which to get the render target\r\n * @returns the render target for the specified eye or null if not available\r\n */\r\n public getRenderTargetTextureForEye(eye: XREye): Nullable<RenderTargetTexture> {\r\n return this._baseLayerRTTProvider?.getRenderTargetTextureForEye(eye) || null;\r\n }\r\n\r\n /**\r\n * Gets the correct render target texture to be rendered this frame for this view\r\n * @param view the view for which to get the render target\r\n * @returns the render target for the specified view or null if not available\r\n */\r\n public getRenderTargetTextureForView(view: XRView): Nullable<RenderTargetTexture> {\r\n return this._baseLayerRTTProvider?.getRenderTargetTextureForView(view) || null;\r\n }\r\n\r\n /**\r\n * Creates a WebXRRenderTarget object for the XR session\r\n * @param options optional options to provide when creating a new render target\r\n * @returns a WebXR render target to which the session can render\r\n */\r\n public getWebXRRenderTarget(options?: WebXRManagedOutputCanvasOptions): WebXRRenderTarget {\r\n const engine = this.scene.getEngine();\r\n if (this._xrNavigator.xr.native) {\r\n return new NativeXRRenderTarget(this);\r\n } else {\r\n options = options || WebXRManagedOutputCanvasOptions.GetDefaults(engine);\r\n options.canvasElement = options.canvasElement || engine.getRenderingCanvas() || undefined;\r\n return new WebXRManagedOutputCanvas(this, options);\r\n }\r\n }\r\n\r\n /**\r\n * Initializes the manager\r\n * After initialization enterXR can be called to start an XR session\r\n * @returns Promise which resolves after it is initialized\r\n */\r\n public async initializeAsync(): Promise<void> {\r\n // Check if the browser supports webXR\r\n this._xrNavigator = navigator;\r\n if (!this._xrNavigator.xr) {\r\n throw new Error(\"WebXR not supported on this browser.\");\r\n }\r\n }\r\n\r\n /**\r\n * Initializes an xr session\r\n * @param xrSessionMode mode to initialize\r\n * @param xrSessionInit defines optional and required values to pass to the session builder\r\n * @returns a promise which will resolve once the session has been initialized\r\n */\r\n public async initializeSessionAsync(xrSessionMode: XRSessionMode = \"immersive-vr\", xrSessionInit: XRSessionInit = {}): Promise<XRSession> {\r\n const session = await this._xrNavigator.xr.requestSession(xrSessionMode, xrSessionInit);\r\n\r\n this.session = session;\r\n this._sessionMode = xrSessionMode;\r\n this.inXRSession = true;\r\n this.onXRSessionInit.notifyObservers(session);\r\n\r\n // handle when the session is ended (By calling session.end or device ends its own session eg. pressing home button on phone)\r\n this.session.addEventListener(\r\n \"end\",\r\n () => {\r\n this.inXRSession = false;\r\n\r\n // Notify frame observers\r\n this.onXRSessionEnded.notifyObservers(null);\r\n\r\n if (this._engine) {\r\n // make sure dimensions object is restored\r\n this._engine.framebufferDimensionsObject = null;\r\n\r\n // Restore frame buffer to avoid clear on xr framebuffer after session end\r\n this._engine.restoreDefaultFramebuffer();\r\n\r\n // Need to restart render loop as after the session is ended the last request for new frame will never call callback\r\n this._engine.customAnimationFrameRequester = null;\r\n this._engine._renderLoop();\r\n }\r\n\r\n // Dispose render target textures.\r\n // Only dispose on native because we can't destroy opaque textures on browser.\r\n if (this.isNative) {\r\n this._baseLayerRTTProvider?.dispose();\r\n }\r\n this._baseLayerRTTProvider = null;\r\n this._baseLayerWrapper = null;\r\n },\r\n { once: true }\r\n );\r\n\r\n return this.session;\r\n }\r\n\r\n /**\r\n * Checks if a session would be supported for the creation options specified\r\n * @param sessionMode session mode to check if supported eg. immersive-vr\r\n * @returns A Promise that resolves to true if supported and false if not\r\n */\r\n public async isSessionSupportedAsync(sessionMode: XRSessionMode): Promise<boolean> {\r\n return await WebXRSessionManager.IsSessionSupportedAsync(sessionMode);\r\n }\r\n\r\n /**\r\n * Resets the reference space to the one started the session\r\n */\r\n public resetReferenceSpace() {\r\n this.referenceSpace = this.baseReferenceSpace;\r\n }\r\n\r\n /**\r\n * Starts rendering to the xr layer\r\n */\r\n public runXRRenderLoop() {\r\n if (!this.inXRSession || !this._engine) {\r\n return;\r\n }\r\n\r\n // Tell the engine's render loop to be driven by the xr session's refresh rate and provide xr pose information\r\n this._engine.customAnimationFrameRequester = {\r\n requestAnimationFrame: (callback: FrameRequestCallback) => this.session.requestAnimationFrame(callback),\r\n renderFunction: (timestamp: number, xrFrame: Nullable<XRFrame>) => {\r\n if (!this.inXRSession || !this._engine) {\r\n return;\r\n }\r\n // Store the XR frame and timestamp in the session manager\r\n this.currentFrame = xrFrame;\r\n this.currentTimestamp = timestamp;\r\n if (xrFrame) {\r\n this.inXRFrameLoop = true;\r\n const framebufferDimensionsObject = this._baseLayerRTTProvider?.getFramebufferDimensions() || null;\r\n // equality can be tested as it should be the same object\r\n if (this._engine.framebufferDimensionsObject !== framebufferDimensionsObject) {\r\n this._engine.framebufferDimensionsObject = framebufferDimensionsObject;\r\n }\r\n this.onXRFrameObservable.notifyObservers(xrFrame);\r\n this._engine._renderLoop();\r\n this._engine.framebufferDimensionsObject = null;\r\n this.inXRFrameLoop = false;\r\n }\r\n },\r\n };\r\n\r\n this._engine.framebufferDimensionsObject = this._baseLayerRTTProvider?.getFramebufferDimensions() || null;\r\n this.onXRFrameObservable.addOnce(() => {\r\n this.onXRReady.notifyObservers(this);\r\n });\r\n\r\n // Stop window's animation frame and trigger sessions animation frame\r\n if (typeof window !== \"undefined\" && window.cancelAnimationFrame) {\r\n window.cancelAnimationFrame(this._engine._frameHandler);\r\n }\r\n this._engine._renderLoop();\r\n }\r\n\r\n /**\r\n * Sets the reference space on the xr session\r\n * @param referenceSpaceType space to set\r\n * @returns a promise that will resolve once the reference space has been set\r\n */\r\n public async setReferenceSpaceTypeAsync(referenceSpaceType: XRReferenceSpaceType = \"local-floor\"): Promise<XRReferenceSpace> {\r\n let referenceSpace: XRReferenceSpace;\r\n let viewerReferenceSpace: Nullable<XRReferenceSpace> = null;\r\n try {\r\n referenceSpace = await this.session.requestReferenceSpace(referenceSpaceType);\r\n } catch (rejectionReason) {\r\n Logger.Error(\"XR.requestReferenceSpace failed for the following reason: \");\r\n Logger.Error(rejectionReason);\r\n Logger.Log('Defaulting to universally-supported \"viewer\" reference space type.');\r\n\r\n try {\r\n viewerReferenceSpace = (await this.session.requestReferenceSpace(\"viewer\")) as XRReferenceSpace;\r\n const heightCompensation = new XRRigidTransform({ x: 0, y: -this.defaultHeightCompensation, z: 0 });\r\n referenceSpace = viewerReferenceSpace.getOffsetReferenceSpace(heightCompensation);\r\n } catch (rejectionReason) {\r\n Logger.Error(rejectionReason);\r\n // eslint-disable-next-line no-throw-literal\r\n throw 'XR initialization failed: required \"viewer\" reference space type not supported.';\r\n }\r\n }\r\n // create viewer reference space before setting the first reference space\r\n this.viewerReferenceSpace = viewerReferenceSpace ?? ((await this.session.requestReferenceSpace(\"viewer\")) as XRReferenceSpace);\r\n // initialize the base and offset (currently the same)\r\n this.referenceSpace = this.baseReferenceSpace = referenceSpace;\r\n this.onXRReferenceSpaceInitialized.notifyObservers(referenceSpace);\r\n return this.referenceSpace;\r\n }\r\n\r\n /**\r\n * Updates the render state of the session.\r\n * Note that this is deprecated in favor of WebXRSessionManager.updateRenderState().\r\n * @param state state to set\r\n * @returns a promise that resolves once the render state has been updated\r\n * @deprecated Use updateRenderState() instead.\r\n */\r\n public async updateRenderStateAsync(state: XRRenderState): Promise<void> {\r\n return await this.session.updateRenderState(state);\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _setBaseLayerWrapper(baseLayerWrapper: Nullable<WebXRLayerWrapper>): void {\r\n if (this.isNative) {\r\n this._baseLayerRTTProvider?.dispose();\r\n }\r\n this._baseLayerWrapper = baseLayerWrapper;\r\n this._baseLayerRTTProvider = this._baseLayerWrapper?.createRenderTargetTextureProvider(this) || null;\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _getBaseLayerWrapper(): Nullable<WebXRLayerWrapper> {\r\n return this._baseLayerWrapper;\r\n }\r\n\r\n /**\r\n * Updates the render state of the session\r\n * @param state state to set\r\n */\r\n public updateRenderState(state: XRRenderStateInit): void {\r\n if (state.baseLayer) {\r\n this._setBaseLayerWrapper(this.isNative ? new NativeXRLayerWrapper(state.baseLayer) : new WebXRWebGLLayerWrapper(state.baseLayer));\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.session.updateRenderState(state);\r\n }\r\n\r\n /**\r\n * Returns a promise that resolves with a boolean indicating if the provided session mode is supported by this browser\r\n * @param sessionMode defines the session to test\r\n * @returns a promise with boolean as final value\r\n */\r\n public static async IsSessionSupportedAsync(sessionMode: XRSessionMode): Promise<boolean> {\r\n if (!(navigator as any).xr) {\r\n return false;\r\n }\r\n // When the specs are final, remove supportsSession!\r\n const functionToUse = (navigator as any).xr.isSessionSupported || (navigator as any).xr.supportsSession;\r\n if (!functionToUse) {\r\n return false;\r\n } else {\r\n try {\r\n const result = functionToUse.call((navigator as any).xr, sessionMode);\r\n const returnValue = typeof result === \"undefined\" ? true : result;\r\n return returnValue;\r\n } catch (e: any) {\r\n Logger.Warn(e);\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Returns true if Babylon.js is using the BabylonNative backend, otherwise false\r\n */\r\n public get isNative(): boolean {\r\n return this._xrNavigator.xr.native ?? false;\r\n }\r\n\r\n /**\r\n * The current frame rate as reported by the device\r\n */\r\n public get currentFrameRate(): number | undefined {\r\n return this.session?.frameRate;\r\n }\r\n\r\n /**\r\n * A list of supported frame rates (only available in-session!\r\n */\r\n public get supportedFrameRates(): Float32Array | undefined {\r\n return this.session?.supportedFrameRates;\r\n }\r\n\r\n /**\r\n * Set the framerate of the session.\r\n * @param rate the new framerate. This value needs to be in the supportedFrameRates array\r\n * @returns a promise that resolves once the framerate has been set\r\n */\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n public async updateTargetFrameRate(rate: number): Promise<void> {\r\n return await this.session.updateTargetFrameRate(rate);\r\n }\r\n\r\n /**\r\n * Run a callback in the xr render loop\r\n * @param callback the callback to call when in XR Frame\r\n * @param ignoreIfNotInSession if no session is currently running, run it first thing on the next session\r\n */\r\n public runInXRFrame(callback: () => void, ignoreIfNotInSession = true): void {\r\n if (this.inXRFrameLoop) {\r\n callback();\r\n } else if (this.inXRSession || !ignoreIfNotInSession) {\r\n this.onXRFrameObservable.addOnce(callback);\r\n }\r\n }\r\n\r\n /**\r\n * Check if fixed foveation is supported on this device\r\n */\r\n public get isFixedFoveationSupported(): boolean {\r\n return this._baseLayerWrapper?.isFixedFoveationSupported || false;\r\n }\r\n\r\n /**\r\n * Get the fixed foveation currently set, as specified by the webxr specs\r\n * If this returns null, then fixed foveation is not supported\r\n */\r\n public get fixedFoveation(): Nullable<number> {\r\n return this._baseLayerWrapper?.fixedFoveation || null;\r\n }\r\n\r\n /**\r\n * Set the fixed foveation to the specified value, as specified by the webxr specs\r\n * This value will be normalized to be between 0 and 1, 1 being max foveation, 0 being no foveation\r\n */\r\n public set fixedFoveation(value: Nullable<number>) {\r\n const val = Math.max(0, Math.min(1, value || 0));\r\n if (this._baseLayerWrapper) {\r\n this._baseLayerWrapper.fixedFoveation = val;\r\n }\r\n }\r\n\r\n /**\r\n * Get the features enabled on the current session\r\n * This is only available in-session!\r\n * @see https://www.w3.org/TR/webxr/#dom-xrsession-enabledfeatures\r\n */\r\n public get enabledFeatures(): Nullable<string[]> {\r\n return this.session?.enabledFeatures ?? null;\r\n }\r\n}\r\n"]}
|