import { GfxSwapChain } from "./gfx/platform/GfxPlatform" ; export class WebXRContext { public xrSession : XRSession | null = null ; public xrViewerSpace : XRReferenceSpace ; public xrLocalSpace : XRReferenceSpace ; public views : XRView [ ] ; public onframe : ( ( time : number ) => void ) | null = null ; public onsupportedchanged : ( ( ) => void ) | null = null ; public onstart : ( ( ) => void ) | null = null ; public onend : ( ( ) => void ) | null = null ; public currentFrame : XRFrame ; public isSupported = false ; constructor ( private swapChain ) { this . checkIsSupported ( ) ; } private async checkIsSupported ( ) { const navigator = window . navigator as any ; if ( navigator . xr === undefined ) return ; const isSupported = await navigator . xr . isSessionSupported ( 'immersive-vr' ) ; if ( this . isSupported !== isSupported ) { this . isSupported = isSupported ; if ( this . onsupportedchanged !== null ) this . onsupportedchanged ( ) ; } } public async start ( ) { const xr = ( window . navigator as any ) . xr as XRSystem ; this . xrSession = await xr . requestSession ( 'immersive-vr' , { requiredFeatures : [ ] , optionalFeatures : [ 'viewer' , 'local' ] , } ) ; this . xrSession . onend = ( ) => { this . sessionEnded ( ) ; } ; [ this . xrViewerSpace , this . xrLocalSpace ] = await Promise . all ( [ this . xrSession . requestReferenceSpace ( 'viewer' ) , this . xrSession . requestReferenceSpace ( 'local' ) , ] ) ; const layer = this . swapChain . createWebXRLayer ( this . xrSession ) ; this . xrSession . updateRenderState ( { baseLayer : layer , depthNear : 5 , depthFar : 1000000.0 } ) ; if ( this . onstart !== null ) this . onstart ( ) ; this . xrSession . requestAnimationFrame ( this . _onRequestAnimationFrame ) ; } private sessionEnded ( ) { this . xrSession = null ; if ( this . onend !== null ) this . onend ( ) ; } public end ( ) { if ( this . xrSession !== null ) this . xrSession . end ( ) ; } private _onRequestAnimationFrame = ( time , frame ) : void => { const session = frame . session ; const pose = frame . getViewerPose ( this . xrLocalSpace ) ; this . currentFrame = frame ; if ( pose ) this . views = pose . views ; if ( this . onframe !== null ) this . onframe ( time ) ; session . requestAnimationFrame ( this . _onRequestAnimationFrame ) ; } ; }