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
@@ -0,0 +1,22 @@
import { lazy } from 'react';
import { registerViewer } from '../viewers';
// Register 3D viewers for the object classes that carry renderable assets.
// Importing this module has the side effect of populating the viewer registry.
// The viewers are lazy-loaded so the three.js stack is code-split out of the
// main bundle and only fetched when a 3D-capable object is actually selected.
const TileViewer = lazy(() => import('./TileViewer'));
const TokenViewer = lazy(() => import('./TokenViewer'));
const CardViewer = lazy(() => import('./CardViewer'));
const CustomModelViewer = lazy(() => import('./CustomModelViewer'));
registerViewer('Tile', TileViewer);
registerViewer('Custom_Tile', TileViewer);
registerViewer('Custom_Token', TokenViewer);
registerViewer('Card', CardViewer);
registerViewer('Deck', CardViewer);
registerViewer('DeckCustom', CardViewer);
registerViewer('Custom_Deck', CardViewer);
registerViewer('Custom_Model', CustomModelViewer);
registerViewer('Custom_Model_Bag', CustomModelViewer);
registerViewer('Custom_Model_Infinite_Bag', CustomModelViewer);