Skip to content

Commit 8572db5

Browse files
committed
WebXR support
1 parent fa4f67f commit 8572db5

File tree

3 files changed

+64
-142
lines changed

3 files changed

+64
-142
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -805,13 +805,13 @@ The BIVROST 360WebPlayer can be optionaly made to use third party libraries:
805805
Changelog
806806
---------
807807

808-
* 2016-03-14: initial public release
808+
* 2016-03-14: initial public release (version 1.0)
809809
* 2016-09-21: WebVR 1.1 support
810810
* 2016-12-21: GearVR support, stereo UI
811811
* 2016-12-30: Documentation update
812812
* 2016-12-31: GitHub release
813813
* 2018-01-26: Move to GitLab, updated documentation
814814
* 2018-08-08: Moved back to GitHub, updated logo
815815
* 2019-04-05: Updated logo
816-
* 2020-07-16: Fixed issues with iOS 13 fullscreen and gyroscope
817-
* 2020-08-06: WebXR support, license updated
816+
* 2020-07-16: Fixed issues with iOS 13 fullscreen and gyroscope (version 1.1)
817+
* 2020-08-06: WebXR support, license updated (version 1.2)

src/bivrost-player.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -314,12 +314,19 @@
314314
vrMode=vrModes[0];
315315
log("selecting default VR mode");
316316
}
317-
// already in vr mode - toggle next available mode
317+
// already in vr mode - reset to mono
318318
else {
319-
var index=(vrModes.indexOf(this.renderer.__proto__) + 1) % vrModes.length;
320-
vrMode=vrModes[index];
321-
log("selecting next VR mode");
319+
log("back to mono");
320+
this.vrExit();
321+
return;
322322
}
323+
324+
// // already in vr mode - toggle next available mode
325+
// else {
326+
// var index=(vrModes.indexOf(this.renderer.__proto__) + 1) % vrModes.length;
327+
// vrMode=vrModes[index];
328+
// log("selecting next VR mode");
329+
// }
323330

324331
this.renderer=new vrMode(this);
325332
};

src/bivrost-renderer-webxr.js

Lines changed: 50 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,13 @@
2525
*/
2626
Bivrost.Renderer.WebXR.PLATFORM_NAME = "WebXR";
2727

28-
// /**
29-
// * Temporary handle for cleanup in destroy()
30-
// */
31-
// Bivrost.Renderer.WebXR.prototype._displayPresentChange;
32-
33-
34-
Bivrost.Renderer.WebXR.prototype.xrSession = null;
35-
Bivrost.Renderer.WebXR.prototype.xrRefSpace = null;
36-
3728

3829
Bivrost.Renderer.WebXR.prototype.init = function(player) {
3930
Bivrost.Renderer.prototype.init.call(this, player);
4031

4132
var thisRef = this;
4233
var sessionInit = { optionalFeatures: [ 'local-floor', 'bounded-floor' ] };
34+
4335
navigator.xr.requestSession('immersive-vr', sessionInit).then(function(session)
4436
{
4537
// Called either when the user has explicitly ended the session by calling
@@ -54,38 +46,14 @@
5446
// Listen for the sessions 'end' event so we can respond if the user
5547
// or UA ends the session for any reason.
5648
session.addEventListener('end', onSessionEnded);
57-
58-
// // Create a WebGL context to render with, initialized to be compatible
59-
// // with the XRDisplay we're presenting to.
60-
// var canvas = document.createElement('canvas');
61-
// var gl = canvas.getContext('webgl', { xrCompatible: true });
62-
// thisRef.vrRenderer=new THREE.WebGLRenderer({ canvas:canvas, context:gl });
63-
64-
// // Use the new WebGL context to create a XRWebGLLayer and set it as the
65-
// // sessions baseLayer. This allows any content rendered to the layer to
66-
// // be displayed on the XRDevice.
67-
// session.updateRenderState({ baseLayer: new XRWebGLLayer(session, gl) });
68-
69-
// thisRef.webvrRenderDelegate = function(time, frame) {
70-
// thisRef.renderWebXR(player.webglRenderer, player.view, frame, time);
71-
// };
72-
// // Get a reference space, which is required for querying poses. In this
73-
// // case an 'local' reference space means that all poses will be relative
74-
// // to the location where the XRDevice was first detected.
75-
// thisRef.xrSession.requestReferenceSpace('local').then(function(refSpace) {
76-
// thisRef.xrRefSpace = refSpace;
77-
78-
// // Inform the session that we're ready to begin drawing.
79-
// session.requestAnimationFrame(thisRef.webvrRenderDelegate);
80-
// });
8149

8250
player.webglRenderer.xr.setSession( session );
8351

52+
thisRef.xrSession = session;
53+
8454
log("Started WebXR");
8555

8656
});
87-
88-
this._position=new THREE.Vector3(0,0,0);
8957
};
9058

9159

@@ -95,10 +63,9 @@
9563
if(this.xrSession)
9664
this.xrSession.end();
9765

98-
// cancel frames from now on
99-
this.webvrRenderDelegate = null;
100-
101-
this.vrRenderer.dispose();
66+
this.vrScene.dispose();
67+
this.vrScene = null;
68+
this.vrCamera = null;
10269
};
10370

10471
/**
@@ -108,23 +75,56 @@
10875
* @returns {undefined}
10976
*/
11077
Bivrost.Renderer.WebXR.prototype.render = function(webglRenderer, view) {
78+
var firstFrame = false;
11179
// scene data not yet copied from normal renderer
112-
if(!this.vrLeftScene) {
113-
this.vrLeftScene=view.leftScene.clone();
114-
this.vrRightScene=view.rightScene.clone();
115-
this.vrLeftCamera=view.leftCamera.clone();
116-
this.vrRightCamera=view.rightCamera.clone();
80+
if(!this.vrScene) {
81+
firstFrame = true;
82+
this.vrScene = new THREE.Scene();
83+
this.vrSceneOrigin = new THREE.Group();
84+
this.vrScene.add(this.vrSceneOrigin);
85+
for(var i = 0; i < view.leftScene.children.length; i++)
86+
{
87+
if(view.leftScene.children[i] == view.leftCamera) continue;
88+
var mesh = view.leftScene.children[i].clone();
89+
mesh.layers.set(1);
90+
//if(!view.enablePositionalCamera) mesh.scale
91+
this.vrSceneOrigin.add(mesh);
92+
}
93+
for(var i = 0; i < view.rightScene.children.length; i++)
94+
{
95+
if(view.rightScene.children[i] == view.rightCamera) continue;
96+
var mesh = view.rightScene.children[i].clone();
97+
mesh.layers.set(2);
98+
this.vrSceneOrigin.add(mesh);
99+
}
100+
this.vrCamera = view.leftCamera.clone();
101+
this.vrCamera.layers.enable(1); // render left view when no stereo available
102+
this.vrScene.add(this.vrCamera);
103+
this.vrTranslation = new THREE.Vector3();
104+
this.vrRotation = new THREE.Quaternion();
105+
this.vrCameraPositionHelper = new THREE.Mesh();
106+
this.vrCamera.add(this.vrCameraPositionHelper);
107+
log("WebXR lazy init");
117108
}
118109

119110
// classical renderer only if WebXR has a separate screen
120111
// TODO: check for hasExternalDisplay WebVR equivalent
121-
if(this.vrLeftCamera) {
122-
view.leftCamera.rotation.copy(this.vrLeftCamera.rotation);
123-
view.leftCamera.position.copy(this.vrLeftCamera.position);
112+
if(this.vrCamera) {
113+
view.leftCamera.rotation.copy(this.vrCamera.rotation);
114+
view.leftCamera.position.copy(this.vrCamera.position);
115+
}
116+
117+
this.vrCameraPositionHelper.getWorldPosition(this.vrTranslation);
118+
this.vrCameraPositionHelper.getWorldQuaternion(this.vrRotation);
119+
120+
if(firstFrame || !view.enablePositionalCamera)
121+
{
122+
// TODO: rotation?
123+
124+
this.vrSceneOrigin.position.set(this.vrTranslation.x, this.vrTranslation.y, this.vrTranslation.z);
124125
}
125126

126-
webglRenderer.clear();
127-
webglRenderer.render(view.leftScene, view.leftCamera);
127+
webglRenderer.render(this.vrScene, this.vrCamera);
128128
};
129129

130130

@@ -133,92 +133,7 @@
133133
Bivrost.Renderer.WebXR.prototype.vrLeftScene=null;
134134
Bivrost.Renderer.WebXR.prototype.vrRightScene=null;
135135

136-
137-
/**
138-
* @type {THREE.Vector3}
139-
* @private
140-
*/
141-
Bivrost.Renderer.WebXR.prototype._position=null;
142-
143-
// /**
144-
// * Stereo renreder on the WebXR surface, on a second rendering queue
145-
// * @param {THREE.WebGLRenderer} webglRenderer
146-
// * @param {Bivrost.View} view
147-
// * @param {?} frame
148-
// * @param {?} time
149-
// * @returns {undefined}
150-
// */
151-
// Bivrost.Renderer.WebXR.prototype.renderWebXR = function(webglRenderer, view, frame, time) {
152-
// var vrRenderer=this.vrRenderer;
153-
154-
// var thisRef = this;
155-
// if(this.webvrRenderDelegate)
156-
// this.xrSession.requestAnimationFrame(this.webvrRenderDelegate);
157-
158-
// // Get the XRDevice pose relative to the Reference Space we created
159-
// // earlier. The pose may not be available for a variety of reasons, so
160-
// // we'll exit the callback early if it comes back as null.
161-
// var pose = frame.getViewerPose(this.xrRefSpace);
162-
// if (!pose) {
163-
// console.warn("No pose?");
164-
// return;
165-
// }
166-
167-
// // TODO: move these and use view params, decide on camera using eye enumeration
168-
169-
// // var orientation=view.transform.orientation;
170-
// // var q=new THREE.Quaternion(orientation[0], orientation[1], orientation[2], orientation[3]);
171-
// // this.q=q;
172-
// // this.vrLeftCamera.rotation.setFromQuaternion(q);
173-
// // this.vrRightCamera.rotation.setFromQuaternion(q);
174-
175-
// // this.vrLeftCamera.setCameraTransform(view.transform.position, view.transform.orientation);
176-
// // this.vrRightCamera.setCameraTransform(view.transform.position, view.transform.orientation);
177-
178-
179-
// // Ensure we're rendering to the layer's backbuffer.
180-
// var layer = frame.session.renderState.baseLayer;
181-
// // gl.bindFramebuffer(gl.FRAMEBUFFER, layer.framebuffer);
182-
183-
// vrRenderer.setScissorTest(true);
184-
// vrRenderer.clear();
185-
186-
// // console.log("----");
187-
// // Loop through each of the views reported by the viewer pose.
188-
// for (var i = 0; i < pose.views.length; i++) {
189-
// var view = pose.views[i];
190-
// // console.log(view);
191-
192-
// var viewport = layer.getViewport(view);
193-
// vrRenderer.setViewport(viewport.x, viewport.y, viewport.width, viewport.height);
194-
// vrRenderer.setScissor(viewport.x, viewport.y, viewport.width, viewport.height);
195-
// this.vrLeftCamera.projectionMatrix.elements = view.projectionMatrix;
196-
197-
// // var pos = view.transform.position;
198-
// // this.vrLeftCamera.position.set(pos.x, pos.y, pos.z);
199-
200-
// vrRenderer.render(this.vrLeftScene, this.vrLeftCamera);
201-
// }
202-
203-
// // if(this.player.view.enablePositionalCamera && frameData.pose && frameData.pose.position) {
204-
// // this._position.x = frameData.pose.position[0];
205-
// // this._position.y = frameData.pose.position[1];
206-
// // this._position.z = frameData.pose.position[2];
207-
// // }
208-
209-
210-
// // var euler = new THREE.Euler("yxz");
211-
// // euler.setFromQuaternion(q);
212-
// // this.onRenderMainView.publish({
213-
// // euler: euler,
214-
// // fov: this.vrRightCamera.getEffectiveFOV(),
215-
// // platform: Bivrost.Renderer.WebXR.PLATFORM_NAME
216-
// // });
217-
218-
// // TODO: does not present?
219-
// };
220-
221-
136+
222137
Bivrost.Renderer.WebXR.shouldWork = function(player) { return !!player.input.xrAvailable; };
223138

224139

0 commit comments

Comments
 (0)