Skip to content
This repository has been archived by the owner on Jan 24, 2020. It is now read-only.

"Enter XR" button toggle VR entry/exiting #37

Closed
wants to merge 4 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 112 additions & 13 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -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');
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -3291,7 +3305,14 @@
gl.uniform1i(gl.uiTexLocation, 0);

gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, fakeXrDisplay.texture);
if(fakeXrDisplay){
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section will be dropped after #35.

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);
Expand All @@ -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');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If one window exits presentation, how are the other windows notified?

// layer.contentWindow.runAsync('exitPresent');
}
}
}
};
const _startFakeVrDisplay = async (width, height) => {
fakeXrDisplay = new FakeXRDisplay();
Expand All @@ -3346,7 +3445,7 @@
renderer.vr.setSession(null);
renderer.vr.setAnimationLoop(null);

_emitLayersExitPresent();
_emitLayersExitPresent();

session.removeEventListener('end', _end);
};
Expand All @@ -3362,22 +3461,22 @@
});
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,
}]);

fakeXrDisplay.display = display;

const _vrdisplaypresentchange = () => {
_emitLayersExitPresent();
_emitLayersExitPresent();

display.removeEventListener('vrdisplaypresentchange', _vrdisplaypresentchange);
};
Expand Down