|
25 | 25 | */ |
26 | 26 | Bivrost.Renderer.WebXR.PLATFORM_NAME = "WebXR"; |
27 | 27 |
|
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 | | - |
37 | 28 |
|
38 | 29 | Bivrost.Renderer.WebXR.prototype.init = function(player) { |
39 | 30 | Bivrost.Renderer.prototype.init.call(this, player); |
40 | 31 |
|
41 | 32 | var thisRef = this; |
42 | 33 | var sessionInit = { optionalFeatures: [ 'local-floor', 'bounded-floor' ] }; |
| 34 | + |
43 | 35 | navigator.xr.requestSession('immersive-vr', sessionInit).then(function(session) |
44 | 36 | { |
45 | 37 | // Called either when the user has explicitly ended the session by calling |
|
54 | 46 | // Listen for the sessions 'end' event so we can respond if the user |
55 | 47 | // or UA ends the session for any reason. |
56 | 48 | 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 | | - // }); |
81 | 49 |
|
82 | 50 | player.webglRenderer.xr.setSession( session ); |
83 | 51 |
|
| 52 | + thisRef.xrSession = session; |
| 53 | + |
84 | 54 | log("Started WebXR"); |
85 | 55 |
|
86 | 56 | }); |
87 | | - |
88 | | - this._position=new THREE.Vector3(0,0,0); |
89 | 57 | }; |
90 | 58 |
|
91 | 59 |
|
|
95 | 63 | if(this.xrSession) |
96 | 64 | this.xrSession.end(); |
97 | 65 |
|
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; |
102 | 69 | }; |
103 | 70 |
|
104 | 71 | /** |
|
108 | 75 | * @returns {undefined} |
109 | 76 | */ |
110 | 77 | Bivrost.Renderer.WebXR.prototype.render = function(webglRenderer, view) { |
| 78 | + var firstFrame = false; |
111 | 79 | // 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"); |
117 | 108 | } |
118 | 109 |
|
119 | 110 | // classical renderer only if WebXR has a separate screen |
120 | 111 | // 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); |
124 | 125 | } |
125 | 126 |
|
126 | | - webglRenderer.clear(); |
127 | | - webglRenderer.render(view.leftScene, view.leftCamera); |
| 127 | + webglRenderer.render(this.vrScene, this.vrCamera); |
128 | 128 | }; |
129 | 129 |
|
130 | 130 |
|
|
133 | 133 | Bivrost.Renderer.WebXR.prototype.vrLeftScene=null; |
134 | 134 | Bivrost.Renderer.WebXR.prototype.vrRightScene=null; |
135 | 135 |
|
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 | + |
222 | 137 | Bivrost.Renderer.WebXR.shouldWork = function(player) { return !!player.input.xrAvailable; }; |
223 | 138 |
|
224 | 139 |
|
|
0 commit comments