Skip to content

Commit 7a09708

Browse files
committed
1 parent 5e5392a commit 7a09708

File tree

2 files changed

+54
-62
lines changed

2 files changed

+54
-62
lines changed

src/App/Ui/ErrorBoundary.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@ export class ErrorBoundary extends React.Component<{ children: any }> {
88
}
99

1010
render() {
11-
if (this.state.error) return <h1>something bad happened</h1>;
11+
if (this.state.error)
12+
return (
13+
<>
14+
<h1>something bad happened</h1>
15+
<pre>{this.state.error.message || this.state.error.name}</pre>
16+
</>
17+
);
1218
return this.props.children;
1319
}
1420
}

src/WebXRCanvas/WebXRControls.ts

Lines changed: 47 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ export const WebXRControls = ({
2626
events,
2727
} = useThree();
2828

29-
const viewRef = React.useRef<XRView>(undefined);
30-
3129
// let webXR control the render loop
3230
// ie: do nothing on react-three-fiber render loop
3331
useFrame(() => {
@@ -37,17 +35,39 @@ export const WebXRControls = ({
3735
React.useLayoutEffect(() => {
3836
const gl = renderer.getContext();
3937

38+
const originalRenderTarget = renderer.getRenderTarget();
39+
40+
//
41+
// create the XRWebGLLayer, bind three render target to it
4042
gl.makeXRCompatible()
41-
.then(() =>
42-
webXRSession.updateRenderState({
43-
baseLayer: new XRWebGLLayer(webXRSession, gl),
44-
})
45-
)
46-
.then(() => console.log("updateRenderState done"))
43+
.then(() => {
44+
const baseLayer = new XRWebGLLayer(webXRSession, gl);
45+
46+
const newRenderTarget = new THREE.WebGLRenderTarget(
47+
baseLayer.framebufferWidth,
48+
baseLayer.framebufferHeight,
49+
{
50+
format: THREE.RGBAFormat,
51+
type: THREE.UnsignedByteType,
52+
colorSpace: renderer.outputColorSpace,
53+
stencilBuffer: gl.getContextAttributes()?.stencil,
54+
}
55+
);
56+
57+
// @ts-ignore
58+
renderer.setRenderTargetFramebuffer(
59+
newRenderTarget,
60+
baseLayer.framebuffer
61+
);
62+
renderer.setRenderTarget(newRenderTarget);
63+
64+
return webXRSession.updateRenderState({ baseLayer });
65+
})
4766
.catch(setError);
4867

68+
//
69+
// ask webXR for a local reference, (which we can then use to have the camera transform)
4970
let localReference: XRReferenceSpace;
50-
5171
webXRSession
5272
.requestReferenceSpace("local-floor")
5373
.then((r) => {
@@ -62,47 +82,25 @@ export const WebXRControls = ({
6282

6383
let cancelAnimationFrame: number;
6484
let lastTimestampMs: number;
65-
let origin: THREE.Vector3 | undefined;
6685
let renderCount = 0;
86+
let poseFound = false;
6787

6888
const onXRFrame: XRFrameRequestCallback = (timestampMs, frame) => {
6989
const pose = localReference && frame.getViewerPose(localReference);
7090

7191
const view = pose?.views[0];
92+
const glLayer = webXRSession.renderState.baseLayer;
7293

73-
if (view) {
74-
if (!viewRef.current) {
75-
const glLayer = webXRSession.renderState.baseLayer!;
76-
77-
const newRenderTarget = new THREE.WebGLRenderTarget(
78-
glLayer.framebufferWidth,
79-
glLayer.framebufferHeight,
80-
{
81-
format: THREE.RGBAFormat,
82-
type: THREE.UnsignedByteType,
83-
colorSpace: renderer.outputColorSpace,
84-
stencilBuffer: gl.getContextAttributes()?.stencil,
85-
}
86-
);
87-
88-
// @ts-ignore
89-
renderer.setRenderTargetFramebuffer(
90-
newRenderTarget,
91-
glLayer.framebuffer
92-
);
93-
renderer.setRenderTarget(newRenderTarget);
94-
95-
const viewport = glLayer.getViewport(view)!;
96-
97-
renderer.setViewport(
98-
viewport.x,
99-
viewport.y,
100-
viewport.width,
101-
viewport.height
102-
);
103-
104-
viewRef.current = view;
105-
}
94+
// check view exist (ie: tracking is ready)
95+
if (view && glLayer) {
96+
const viewport = glLayer.getViewport(view)!;
97+
98+
renderer.setViewport(
99+
viewport.x,
100+
viewport.y,
101+
viewport.width,
102+
viewport.height
103+
);
106104

107105
camera.position.set(
108106
view.transform.position.x * worldSize,
@@ -122,22 +120,9 @@ export const WebXRControls = ({
122120

123121
camera.matrixWorldNeedsUpdate = true;
124122

125-
if (!origin) {
126-
// define origin,
127-
// a point on the ground
128-
const v = new THREE.Vector3(0, 0, -1);
129-
v.applyQuaternion(camera.quaternion);
130-
v.normalize();
131-
132-
const t = -camera.position.y / v.y;
133-
134-
if (t > 0) {
135-
origin = new THREE.Vector3()
136-
.copy(camera.position)
137-
.addScaledVector(v, t);
138-
139-
onPoseFound?.();
140-
}
123+
if (!poseFound) {
124+
onPoseFound?.();
125+
poseFound = true;
141126
}
142127

143128
const dt = (timestampMs - (lastTimestampMs ?? timestampMs)) / 1000;
@@ -160,11 +145,12 @@ export const WebXRControls = ({
160145
cancelAnimationFrame = webXRSession.requestAnimationFrame(onXRFrame);
161146
setFrameloop("never");
162147

163-
// the renderer.domElement is no longer receiving events
148+
// the renderer.domElement is no longer receiving events,
149+
// connect to window instead
164150
events.connect?.(window);
165151

166152
return () => {
167-
// TODO: reset the framebuffer
153+
renderer.setRenderTarget(originalRenderTarget);
168154

169155
setFrameloop("always");
170156
webXRSession.cancelAnimationFrame(cancelAnimationFrame);

0 commit comments

Comments
 (0)