# Asset pipeline and loading guide Mechanica supports procedural React Three Fiber models and GLB/GLTF assets. Production assets should be optimized for fast streaming, stable part selection, and predictable rendering on mobile GPUs. ## Asset goals | Asset type | Preferred budget | | --- | ---: | | Catalogue thumbnail | < 120 KB AVIF/WebP/SVG | | Small machine GLB | < 1.5 MB compressed | | Complex machine GLB | < 4 MB compressed | | Environment HDR/EXR | < 1 MB compressed or use procedural environment | | Texture set per machine | < 2 MB total KTX2 | | Draw calls per machine | < 250 desktop, < 140 mobile | | Triangles per machine | < 250k desktop, < 120k mobile | Budgets are guidelines. A machine can exceed a single budget only if profiling confirms the interaction remains smooth. ## Recommended folder layout ```text public/ ├── basis/ │ ├── basis_transcoder.js │ └── basis_transcoder.wasm ├── draco/ │ ├── draco_decoder.js │ ├── draco_decoder.wasm │ └── draco_wasm_wrapper.js src/assets/ ├── thumbnails/ └── machines/ └── / ├── source-notes.md ├── .glb └── preview.webp ``` Large source files such as `.blend`, `.fbx`, or CAD exports should be stored outside the application bundle or tracked through Git LFS if the project policy allows it. ## Blender export checklist Before exporting: - Apply transforms where appropriate. - Set origin points for rotating components such as shafts, gears, rotors, flywheels, and valves. - Name meshes with stable semantic names. - Keep part boundaries separate when users need visibility or opacity controls. - Remove hidden construction geometry. - Use real-world proportions, then scale uniformly for viewer framing. - Assign material names that describe engineering purpose. - Prefer a small number of shared PBR materials over many unique materials. - Avoid unapplied modifiers that create excessive geometry on export. Export as GLB unless an external `.bin` is required for a specific pipeline. ## Optimization workflow Use glTF Transform through `npx` so the CLI version is resolved explicitly when run: ```bash npx @gltf-transform/cli inspect input.glb npx @gltf-transform/cli optimize input.glb output.optimized.glb --compress draco --texture-compress webp ``` For KTX2 texture compression: ```bash npx @gltf-transform/cli etc1s input.glb output.ktx2.glb ``` For higher-quality normal maps or technical labels, use UASTC: ```bash npx @gltf-transform/cli uastc input.glb output.uastc.glb ``` Inspect after every optimization pass: ```bash npx @gltf-transform/cli inspect output.ktx2.glb ``` ## Draco guidance Draco is effective for high-poly static meshes. Use it for: - housings - cases - brackets - impellers - turbine blades - complex cast geometry Avoid Draco when: - the mesh is tiny and decoder overhead dominates - geometry is frequently morphed - mesh identity needs direct node manipulation that the optimization pass would merge away If meshes are merged during optimization, preserve names or rebuild `partMeshMap` after the final optimized file is produced. ## KTX2 guidance KTX2 reduces GPU memory and download size for texture-heavy assets. Use it for: - baked ambient occlusion - normal maps - roughness/metalness maps - technical labels baked into mesh surfaces Prefer simple material colors for procedural educational models. Many Mechanica systems are diagrammatic and do not need heavy texture sets. ## Decoder files The app configuration points loaders at: ```text VITE_DRACO_DECODER_PATH=/draco/ VITE_KTX2_TRANSCODER_PATH=/basis/ ``` Copy decoder files from the installed Three.js package that matches the application’s resolved version. Common source paths are under: ```text node_modules/three/examples/jsm/libs/draco/ node_modules/three/examples/jsm/libs/basis/ ``` Three.js package layout can change, so verify the exact source path after `npm install`. ## Loading strategy Production machine loading should follow this sequence: 1. Load registry metadata immediately; it is small and powers the catalogue. 2. Lazy-load machine scene module only when the viewer route opens. 3. Show stable skeleton panels and a viewer progress bar. 4. Initialize GLTFLoader with DracoLoader and KTX2Loader when compressed assets are used. 5. Use `LoadingManager` progress events for visible progress. 6. Cache loaded assets by URL. 7. Dispose cloned runtime materials/geometries when leaving a machine. 8. Keep decoder/transcoder paths same-origin for CSP and caching simplicity. ## React Three Fiber recommendations - Use `` around machine scene modules. - Use Drei’s `useGLTF.preload(url)` for likely next machines. - Use instancing for repeated parts such as bearing balls, roller elements, bolts, fan blades, and compressor stages. - Set `frustumCulled=true` unless an animation moves bounding volumes unpredictably. - Use shared materials and memoized geometry for procedural shapes. - Prefer baked or environment lighting over many real-time lights. - Clamp device pixel ratio on mobile. ## Material conventions Recommended material categories: | Category | Visual treatment | | --- | --- | | Housing/case | darker metal, lower opacity in x-ray/cutaway modes | | Motion transfer | accent blue or graphite metal | | Energy event | warm amber highlight | | Fluid/air flow | translucent blue/cyan ribbons or particles | | Seals/gaskets | dark rubber | | Bearings/contact | polished metal with clear labels | ## Validation before commit For every asset: 1. Open in a GLB viewer and confirm scale/orientation. 2. Run glTF Transform `inspect`. 3. Confirm mesh names match `partMeshMap`. 4. Test solid, wireframe, exploded, and cross-section modes. 5. Confirm selected-part highlight works. 6. Test on a mobile viewport with throttled CPU. 7. Compare final file size against the budget table. 8. Confirm no console warnings from GLTFLoader, DRACOLoader, or KTX2Loader.