Skip to content

Commit

Permalink
Add an error boundary for WebGL (#942)
Browse files Browse the repository at this point in the history
  • Loading branch information
ImUrX authored Mar 13, 2024
1 parent ee7d6a8 commit 673344b
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 26 deletions.
1 change: 1 addition & 0 deletions gui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"react": "^18.0.0",
"react-dev-utils": "^12.0.0",
"react-dom": "^18.0.0",
"react-error-boundary": "^4.0.12",
"react-helmet": "^6.1.0",
"react-hook-form": "^7.29.0",
"react-modal": "^3.15.1",
Expand Down
1 change: 1 addition & 0 deletions gui/public/i18n/en/translation.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ tips-do_not_move_heels = Ensure your heels do not move during recording!
tips-file_select = Drag & drop files to use, or <u>browse</u>.
tips-tap_setup = You can slowly tap 2 times your tracker to choose it instead of selecting it from the menu.
tips-turn_on_tracker = Using official SlimeVR trackers? Remember to <b><em>turn on your tracker</em></b> after connecting it to the PC!
tips-failed_webgl = Failed to initialize WebGL.
## Body parts
body_part-NONE = Unassigned
Expand Down
21 changes: 15 additions & 6 deletions gui/src/components/widgets/IMUVisualizerWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { QuatObject } from '@/maths/quaternion';
import { useLocalization } from '@fluent/react';
import { Vector3Object } from '@/maths/vector3';
import { Gltf } from '@react-three/drei';
import { ErrorBoundary } from 'react-error-boundary';

const groundColor = '#4444aa';

Expand Down Expand Up @@ -158,13 +159,21 @@ export function IMUVisualizerWidget({ tracker }: { tracker: TrackerDataT }) {
>
{l10n.getString('widget-imu_visualizer-rotation_hide')}
</Button>
<SceneRenderer
quat={{ ...quat }}
vec={{ ...vec }}
model={
isExtension ? '/models/extension.gltf' : '/models/tracker.gltf'
<ErrorBoundary
fallback={
<Typography color="primary" textAlign="text-center">
{l10n.getString('tips-failed_webgl')}
</Typography>
}
></SceneRenderer>
>
<SceneRenderer
quat={{ ...quat }}
vec={{ ...vec }}
model={
isExtension ? '/models/extension.gltf' : '/models/tracker.gltf'
}
></SceneRenderer>
</ErrorBoundary>
</>
)}
</div>
Expand Down
52 changes: 32 additions & 20 deletions gui/src/components/widgets/SkeletonVisualizerWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import { QuaternionFromQuatT, isIdentity } from '@/maths/quaternion';
import classNames from 'classnames';
import { Button } from '@/components/commons/Button';
import { useLocalization } from '@fluent/react';
import { ErrorBoundary } from 'react-error-boundary';
import { Typography } from '@/components/commons/Typography';

extend({ BasedSkeletonHelper });

Expand Down Expand Up @@ -119,6 +121,7 @@ export function ToggleableSkeletonVisualizerWidget(
>
{l10n.getString('widget-skeleton_visualizer-hide')}
</Button>

<SkeletonVisualizerWidget {...props} />
</>
)}
Expand All @@ -132,6 +135,7 @@ export function SkeletonVisualizerWidget({
}: SkeletonVisualizerWidgetProps) {
const { bones: _bones } = useAppContext();

const { l10n } = useLocalization();
const bones = useMemo(
() => new Map(_bones.map((b) => [b.bodyPart, b])),
[JSON.stringify(_bones)]
Expand Down Expand Up @@ -194,27 +198,35 @@ export function SkeletonVisualizerWidget({
if (!skeleton.current) return <></>;
return (
<div className="bg-background-70 flex flex-col p-3 rounded-lg gap-2">
<Canvas
className={classNames('container mx-auto')}
style={{ height, background: 'transparent', maxHeight }}
<ErrorBoundary
fallback={
<Typography color="primary" textAlign="text-center">
{l10n.getString('tips-failed_webgl')}
</Typography>
}
>
<gridHelper args={[10, 50, GROUND_COLOR, GROUND_COLOR]} />
<group position={[0, heightOffset, 0]} quaternion={yawReset}>
<SkeletonHelper object={skeleton.current[0]}></SkeletonHelper>
</group>
<primitive object={skeleton.current[0]} />
<PerspectiveCamera
makeDefault
position={[3, 2.5, -3]}
fov={20}
zoom={1 / scale}
/>
<OrbitControls
target={[0, targetCamera, 0]}
maxDistance={20}
maxPolarAngle={Math.PI / 2}
/>
</Canvas>
<Canvas
className={classNames('container mx-auto')}
style={{ height, background: 'transparent', maxHeight }}
>
<gridHelper args={[10, 50, GROUND_COLOR, GROUND_COLOR]} />
<group position={[0, heightOffset, 0]} quaternion={yawReset}>
<SkeletonHelper object={skeleton.current[0]}></SkeletonHelper>
</group>
<primitive object={skeleton.current[0]} />
<PerspectiveCamera
makeDefault
position={[3, 2.5, -3]}
fov={20}
zoom={1 / scale}
/>
<OrbitControls
target={[0, targetCamera, 0]}
maxDistance={20}
maxPolarAngle={Math.PI / 2}
/>
</Canvas>
</ErrorBoundary>
</div>
);
}
12 changes: 12 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 673344b

Please sign in to comment.