# model_scene.svelte + model_viewer.svelte + model_debug.ts — 3D Model Viewer

These three files together form the 3D model display system used on the dashboard.

### model\_scene.svelte

The outer container and lifecycle manager. Handles: delayed initialisation (100ms timer to ensure the DOM is ready before the WebGL canvas is created), WebGL context loss detection, error state with a retry button, and a resize nudge that forces the canvas to reflow correctly after mount.

<span style="white-space: pre-wrap;">Uses </span>`<span class="editor-theme-code">model_debug.ts</span>`<span style="white-space: pre-wrap;"> to persist error state across the component lifecycle using </span>`<span class="editor-theme-code">localStorage</span>`<span style="white-space: pre-wrap;"> — if the model failed to load in the previous render, the error state is restored immediately on mount to avoid a flash of broken content.</span>

### model\_viewer.svelte

<span style="white-space: pre-wrap;">The inner Three.js / Threlte scene. Loads the GLB model file by calling </span>`<span class="editor-theme-code">invoke("load_model")</span>`<span style="white-space: pre-wrap;">, which returns the raw bytes of the file. The bytes are parsed directly in the browser using </span>`<span class="editor-theme-code">GLTFLoader.parse()</span>`<span style="white-space: pre-wrap;"> — no HTTP request is made.</span>

<span style="white-space: pre-wrap;">After loading, all mesh materials are replaced with a uniform </span>`<span class="editor-theme-code">MeshStandardMaterial</span>`<span style="white-space: pre-wrap;"> in the Roboteam's purple brand colour (</span>`<span class="editor-theme-code">#5A1C74</span>`). The camera is automatically fitted to the model's bounding box so any model file will be centred and fill the view regardless of its original scale.

<span style="white-space: pre-wrap;">The model auto-rotates slowly using </span>`<span class="editor-theme-code">OrbitControls</span>`<span style="white-space: pre-wrap;"> with </span>`<span class="editor-theme-code">autoRotate</span>`<span style="white-space: pre-wrap;">. User rotation, zoom, and pan are disabled — the view is fixed. A scale animation eases the model from 0 to 1 on load using Threlte's </span>`<span class="editor-theme-code">useTask</span>`.

### model\_debug.ts

<span style="white-space: pre-wrap;">A small utility module with two functions: </span>`<span class="editor-theme-code">setLoadFailed(bool)</span>`<span style="white-space: pre-wrap;"> and </span>`<span class="editor-theme-code">wasLoadFailed(): bool</span>`<span style="white-space: pre-wrap;">. These read and write a </span>`<span class="editor-theme-code">localStorage</span>`<span style="white-space: pre-wrap;"> key to persist the model error state across component re-renders.</span>