diff --git a/index.html b/index.html
index 257717d..ffe8e4a 100644
--- a/index.html
+++ b/index.html
@@ -1063,6 +1063,20 @@
_bindEventTarget('xr');
} else if (target === 'xr') {
console.log('xr click');
+ if(fakeXrDisplay){
+ _endFakeVrDisplay()
+ .then(() => _startVrDisplay())
+ .catch(err => {
+ console.warn(err.stack);
+ });
+ } else if(display){
+ _endVrDisplay()
+ .then(() => _startFakeVrDisplay())
+ .catch(err => {
+ console.warn(err.stack);
+ });
+ }
+
} else if (target === 'transform') {
console.log('transform click');
}
@@ -1280,13 +1294,13 @@
const maxX = viewport.x + viewport.z;
const maxY = viewport.y + viewport.w;
const shouldOrbit = x >= minX && x < maxX && y >= minY && y < maxY && !menuOpen;
- if (shouldOrbit && !orbitControls) {
+ if (shouldOrbit && !orbitControls && fakeXrDisplay) {
_addOrbitControls();
} else if (!shouldOrbit && orbitControls) {
_removeOrbitControls();
}
- if (orbitControls) {
+ if (orbitControls && fakeXrDisplay) {
const localCamera = camera;
localCamera.matrixWorldInverse.fromArray(fakeXrDisplay.viewMatrix);
localCamera.matrixWorld.getInverse(localCamera.matrixWorldInverse);
@@ -3291,7 +3305,14 @@
gl.uniform1i(gl.uiTexLocation, 0);
gl.activeTexture(gl.TEXTURE1);
- gl.bindTexture(gl.TEXTURE_2D, fakeXrDisplay.texture);
+ if(fakeXrDisplay){
+ gl.bindTexture(gl.TEXTURE_2D, fakeXrDisplay.texture);
+ } else if (display) {
+ // xxx
+ gl.bindTexture(gl.TEXTURE_2D, display.texture);
+ } else {
+ gl.bindTexture(gl.TEXTURE_2D, 0);
+ }
gl.uniform1i(gl.viewportTexLocation, 1);
gl.uniform4f(gl.viewportLocation, viewport.x, viewport.y, viewport.z, viewport.w);
@@ -3304,25 +3325,103 @@
animateComposeContext(time, frame);
}
-// bootstrap
+// bootstrap Xr
+const _startVrDisplay = async () => {
+ if (navigator.xr) {
+ const session = await navigator.xr.requestSession({
+ exclusive: true,
+ });
+
+ display = session;
+
+ const _end = () => {
+ renderer.vr.enabled = false;
+ renderer.vr.setSession(null);
+ renderer.vr.setAnimationLoop(null);
+
+ session.removeEventListener('end', _end);
+ };
+ session.addEventListener('end', _end);
+
+ await new Promise((accept, reject) => {
+ session.requestAnimationFrame((timestamp, frame) => {
+ session.layers = layers;
+
+ renderer.vr.setSession(session, {
+ frameOfReferenceType: 'stage',
+ });
+
+ const {views} = frame.getViewerPose();
+ const viewport = session.baseLayer.getViewport(views[0]);
+ const width = viewport.width;
+ const height = viewport.height;
+ // console.log("session.isPresenting = " + session.isPresenting());
+ // renderer.setSize(width * 2, height);
+
+ renderer.setAnimationLoop(null);
+
+ renderer.vr.enabled = true;
+ renderer.vr.setSession(session, {
+ frameOfReferenceType: 'stage',
+ });
+ renderer.vr.setAnimationLoop(animate);
+
+ console.log('entered xr');
+
+ accept();
+ });
+ });
+ } else { // WebVR
+ console.log('request device');
+ const displays = await navigator.getVRDisplays();
+ display = displays[0];
+
+ if (display) {
+ console.log('request present vr');
+ await display.requestPresent([{
+ source: renderer.domElement,
+ }]);
+ const {renderWidth: width, renderHeight: height} = display.getEyeParameters('left');
+ renderer.setSize(width * 2, height);
+
+ renderer.setAnimationLoop(null);
+ renderer.vr.enabled = true;
+ renderer.vr.setAnimationLoop(animate);
+
+ console.log('entered vr');
+ } else {
+ console.log('no vr displays');
+ renderer.setAnimationLoop(animate);
+ }
+ }
+};
+const _endVrDisplay = async () => {
+ if (display) {
+ await display.end();
+ // await display.exitPresent();
+ }
+
+ display = null;
+ // renderer.domElement.framebuffer = null; // XXX destroy this framebuffer
+};
+
+// bootstrap fakeXr
const _emitLayersVrDisplayActivate = () => {
for (let i = 0; i < layers.length; i++) {
const layer = layers[i];
-
if (layer.tagName === 'IFRAME' && layer.d === 3) {
- layer.contentWindow.runAsync('vrdisplayactivate');
+ // layer.contentWindow.runAsync('vrdisplayactivate');
}
}
};
const _emitLayersExitPresent = () => {
for (let i = 0; i < layers.length; i++) {
const layer = layers[i];
-
if (layer.tagName === 'IFRAME' && layer.d === 3) {
- layer.contentWindow.runAsync('exitPresent');
+ // layer.contentWindow.runAsync('exitPresent');
}
- }
+}
};
const _startFakeVrDisplay = async (width, height) => {
fakeXrDisplay = new FakeXRDisplay();
@@ -3346,7 +3445,7 @@
renderer.vr.setSession(null);
renderer.vr.setAnimationLoop(null);
- _emitLayersExitPresent();
+ _emitLayersExitPresent();
session.removeEventListener('end', _end);
};
@@ -3362,14 +3461,14 @@
});
renderer.vr.setAnimationLoop(animate);
- _emitLayersVrDisplayActivate();
+ _emitLayersVrDisplayActivate();
accept();
});
});
} else {
const displays = await navigator.getVRDisplays();
- const display = displays[0];
+ const fakeDisplay = displays[0];
await display.requestPresent([{
source: renderer.domElement,
}]);
@@ -3377,7 +3476,7 @@
fakeXrDisplay.display = display;
const _vrdisplaypresentchange = () => {
- _emitLayersExitPresent();
+ _emitLayersExitPresent();
display.removeEventListener('vrdisplaypresentchange', _vrdisplaypresentchange);
};