Add 3D object viewers with r3f stack

Add per-class 3D viewers for tiles, tokens, cards, and custom models
using React Three Fiber, drei, and postprocessing. Viewers are
lazy-loaded and registered through the existing viewer registry, with a
shared scene wrapper for lighting, orbit controls, and subtle effects.

Add a CORS-safe /asset proxy route so three.js loaders can fetch
Workshop-hosted textures and models, and extend TTSObject with the
CustomMesh and CustomTile/CustomToken fields the viewers read.
This commit is contained in:
2026-08-08 12:56:46 +08:00
parent f390f170da
commit 001d5eeb54
18 changed files with 1037 additions and 14 deletions
+7 -3
View File
@@ -45,8 +45,8 @@ apps/web ──► apps/proxy ──► packages/tts ──► packages/shared
### Edges
- **`apps/web``apps/proxy`** — calls `/search`, `/items/:id`, and
`/items/:id/file` over HTTP.
- **`apps/web``apps/proxy`** — calls `/search`, `/items/:id`,
`/items/:id/file`, and `/asset` (CORS-safe asset proxy) over HTTP.
- **`apps/web``packages/extract`** — uses `buildTree` / `collectRefs`
to analyze a loaded `TTSMod` in the browser (tree sidebar + asset refs).
- **`apps/proxy``packages/tts`** — calls `fetchMod` / `getFileName` to serve
@@ -82,6 +82,10 @@ apps/web ──► apps/proxy ──► packages/tts ──► packages/shared
| `bson` | BSON deserialization of TTS save files | `packages/tts` |
| `cheerio` | Workshop browse page scraping | `apps/proxy` |
| `zod` | Runtime validation | `apps/proxy`, `packages/shared` |
| `three` | 3D rendering | `apps/web` |
| `@react-three/fiber` | React renderer for three.js | `apps/web` |
| `@react-three/drei` | three.js helpers (controls, textures) | `apps/web` |
| `@react-three/postprocessing` | Post-processing effects | `apps/web` |
### Runtime constraints
@@ -103,7 +107,7 @@ apps/web ──► apps/proxy ──► packages/tts ──► packages/shared
- The proxy runs as a single Node process via `@hono/node-server`.
- `apps/web` is a static Vite build served separately; during development it
proxies `/search`, `/items`, and `/health` to the proxy.
proxies `/search`, `/items`, `/health`, and `/asset` to the proxy.
- `packages/extract` is published/consumed as a plain ESM module usable from a
browser bundle or Node.
- No shared state between requests; each request fetches fresh.