webxr-polyfill/polyfill/XRPolyfill.js

153 строки
5.3 KiB
JavaScript

import _XRDisplay from './XRDisplay.js'
import _XRSession from './XRSession.js'
import _XRSessionCreateParameters from './XRSessionCreateParameters.js'
import _Reality from './Reality.js'
import _XRPointCloud from './XRPointCloud.js'
import _XRLightEstimate from './XRLightEstimate.js'
import _XRAnchor from './XRAnchor.js'
import _XRPlaneAnchor from './XRPlaneAnchor.js'
import _XRFaceAnchor from './XRFaceAnchor.js'
import _XRImageAnchor from './XRImageAnchor.js'
import _XRAnchorOffset from './XRAnchorOffset.js'
import _XRStageBounds from './XRStageBounds.js'
import _XRStageBoundsPoint from './XRStageBoundsPoint.js'
import _XRPresentationFrame from './XRPresentationFrame.js'
import _XRView from './XRView.js'
import _XRViewport from './XRViewport.js'
import _XRCoordinateSystem from './XRCoordinateSystem.js'
import _XRViewPose from './XRViewPose.js'
import _XRLayer from './XRLayer.js'
import _XRWebGLLayer from './XRWebGLLayer.js'
import _XRVideoFrame from './XRVideoFrame.js'
import EventHandlerBase from './fill/EventHandlerBase.js'
import FlatDisplay from './display/FlatDisplay.js'
import HeadMountedDisplay from './display/HeadMountedDisplay.js'
import CameraReality from './reality/CameraReality.js'
/*
XRPolyfill implements the window.XR functionality as a polyfill
Code below will check for window.XR and if it doesn't exist will install this polyfill,
so you can safely include this script in any page.
*/
class XRPolyfill extends EventHandlerBase {
constructor(){
super()
window.XRDisplay = _XRDisplay
window.XRSession = _XRSession
window.XRSessionCreateParameters = _XRSessionCreateParameters
window.Reality = _Reality
window.XRPointCloud = _XRPointCloud
window.XRLightEstimate = _XRLightEstimate
window.XRAnchor = _XRAnchor
window.XRPlaneAnchor = _XRPlaneAnchor
window.XRFaceAnchor = _XRFaceAnchor
window.XRImageAnchor = _XRImageAnchor
window.XRAnchorOffset = _XRAnchorOffset
window.XRStageBounds = _XRStageBounds
window.XRStageBoundsPoint = _XRStageBoundsPoint
window.XRPresentationFrame = _XRPresentationFrame
window.XRView = _XRView
window.XRViewport = _XRViewport
window.XRCoordinateSystem = _XRCoordinateSystem
window.XRViewPose = _XRViewPose
window.XRLayer = _XRLayer
window.XRWebGLLayer = _XRWebGLLayer
window.XRVideoFrame = _XRVideoFrame
XRDisplay = window.XRDisplay
XRSession = window.XRSession
XRSessionCreateParameters = window.XRSessionCreateParameters
Reality = window.Reality
XRPointCloud = window.XRPointCloud
XRLightEstimate = window.XRLightEstimate
XRAnchor = window.XRAnchor;
XRPlaneAnchor = window.XRPlaneAnchor;
XRFaceAnchor = window.XRFaceAnchor;
XRImageAnchor = window.XRImageAnchor;
XRAnchorOffset = window.XRAnchorOffset;
XRStageBounds = window.XRStageBounds;
XRStageBoundsPoint = window.XRStageBoundsPoint;
XRPresentationFrame = window.XRPresentationFrame;
XRView = window.XRView;
XRViewport = window.XRViewport;
XRCoordinateSystem = window.XRCoordinateSystem;
XRViewPose = window.XRViewPose;
XRLayer = window.XRLayer;
XRWebGLLayer = window.XRWebGLLayer;
XRVideoFrame = window.XRVideoFrame;
this._getVRDisplaysFinished = false;
// Reality instances that may be shared by multiple XRSessions
this._sharedRealities = [new CameraReality(this)]
this._privateRealities = []
this._displays = [new FlatDisplay(this, this._sharedRealities[0])]
if(typeof navigator.getVRDisplays === 'function'){
navigator.getVRDisplays().then(displays => {
for(let display of displays){
if(display === null) continue
if(display.capabilities.canPresent){
this._displays.push(new HeadMountedDisplay(this, this._sharedRealities[0], display))
}
}
this._getVRDisplaysFinished = true;
})
} else {
// if no WebVR, we don't need to wait
this._getVRDisplaysFinished = true;
}
// These elements are at the beginning of the body and absolutely positioned to fill the entire window
// Sessions and realities add their elements to these divs so that they are in the right render order
this._sessionEls = document.createElement('div')
this._sessionEls.setAttribute('class', 'webxr-sessions')
this._realityEls = document.createElement('div')
this._realityEls.setAttribute('class', 'webxr-realities')
for(let el of [this._sessionEls, this._realityEls]){
el.style.position = 'absolute'
el.style.width = '100%'
el.style.height = '100%'
}
let prependElements = () => {
document.body.style.width = '100%';
document.body.style.height = '100%';
document.body.prepend(this._sessionEls);
document.body.prepend(this._realityEls); // realities must render behind the sessions
}
if(document.readyState !== 'loading') {
prependElements();
} else {
document.addEventListener('DOMContentLoaded', prependElements);
}
}
getDisplays(){
var self=this
var waitTillDisplaysChecked = function(resolve) {
if (!self._getVRDisplaysFinished) {
setTimeout(waitTillDisplaysChecked.bind(self, resolve), 30);
} else {
resolve(self._displays);
}
}
return new Promise((resolve, reject) => {
waitTillDisplaysChecked(resolve);
})
}
//attribute EventHandler ondisplayconnect;
//attribute EventHandler ondisplaydisconnect;
}
/* Install XRPolyfill if window.XR does not exist */
if(typeof navigator.XR === 'undefined') {
navigator.XR = new XRPolyfill()
}