chore(monorepo): import hmwebviewer history at a717900
git-subtree-dir: apps/viewer-3d git-subtree-mainline:5e10bb1be4git-subtree-split:a71790070d
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
# tools/ — Offline asset pipeline
|
||||
|
||||
Offline tooling for preparing 3D assets served by the hmwebviewer. Nothing here
|
||||
ships to the browser at runtime; these produce the optimized assets and
|
||||
pre-rendered placeholders that the viewer consumes.
|
||||
|
||||
## preprocess.mjs — Draco + KTX2 compression
|
||||
|
||||
Compresses a `.glb`/`.gltf` into a single self-contained `.optimized.glb` using
|
||||
[gltf-transform](https://gltf-transform.dev/): Draco for geometry, KTX2/Basis
|
||||
Universal for textures, in one pass. Output loads directly in the viewer's
|
||||
`GLTFLoader` (with `DRACOLoader` + `KTX2Loader` wired on the shared loader).
|
||||
|
||||
### Install (once)
|
||||
|
||||
These dev dependencies are **not** in `package.json` yet. Run before first use:
|
||||
|
||||
```bash
|
||||
npm install -D @gltf-transform/core @gltf-transform/functions \
|
||||
@gltf-transform/extensions @gltf-transform/cli
|
||||
```
|
||||
|
||||
The CLI package provides the KTX2 encoder wiring. gltf-transform fetches the
|
||||
platform basis encoder automatically on first KTX2 run (network needed once).
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
node tools/preprocess.mjs <input.glb> [output.glb] [--draco-bits N] [--ktx2|--no-ktx2]
|
||||
```
|
||||
|
||||
- Default output: `<input>.optimized.glb` (e.g. `model.glb` → `model.optimized.glb`).
|
||||
- `--draco-bits N` — position quantization bits, 8..16 (default **14**). Lower =
|
||||
smaller file, lossier geometry. Tune per asset.
|
||||
- `--ktx2` / `--no-ktx2` — texture encoding toggle (default **on**).
|
||||
|
||||
Prints before/after byte sizes and reduction %.
|
||||
|
||||
### Outputs
|
||||
|
||||
- Compressed GLBs land in [`samples/`](../samples/) (`samples/*.optimized.glb`).
|
||||
- Pre-rendered WebP placeholders land in [`public/previews/`](../public/previews/)
|
||||
(`*.webp`) — see the pre-render section below.
|
||||
|
||||
If a required package is missing at runtime, the script prints the install
|
||||
command above and exits non-zero (no silent skip).
|
||||
|
||||
## Sample assets
|
||||
|
||||
Place source `.glb` files under `samples/` (suggested split: small / medium /
|
||||
large). Compress with `preprocess.mjs` and commit the `.optimized.glb` outputs.
|
||||
Samples are not committed yet — to be added when a sample asset is available.
|
||||
|
||||
## Pre-render pipeline (360° animated WebP placeholder)
|
||||
|
||||
For Path A (server asset) the server ships a pre-rendered 360° turntable so the
|
||||
page shows motion instantly while the real model decodes in the background.
|
||||
Output: `public/previews/<asset>.webp` (animated, with alpha).
|
||||
|
||||
**Status: to be implemented when a sample asset is available.** Two options:
|
||||
|
||||
1. **Blender headless CLI (preferred).** Camera parented to an empty at the
|
||||
model origin, Z axis 0→360° keyframed over N frames. Render frames:
|
||||
```bash
|
||||
blender -b scene.blend -o //frame_### -f 1..N -F PNG
|
||||
```
|
||||
Assemble to animated WebP (alpha) or WebM VP9 via ffmpeg:
|
||||
```bash
|
||||
ffmpeg -framerate 24 -i frame_%03d.png -loop 0 -plays 0 out.webp
|
||||
```
|
||||
|
||||
2. **Puppeteer + headless three.js (fallback).** Spin a minimal three.js page,
|
||||
rotate the model, and call `page.screenshot({ type: 'webp' })` per rotation
|
||||
step. Stitch frames into an animated WebP.
|
||||
|
||||
Both options need a committed sample asset first; blocked on P4-2.
|
||||
Reference in New Issue
Block a user