feat(web): place full setup objects at their real transforms

Model TTSObjectTransform in shared types and convert each object's position, rotation, and scale into three.js placement, with per-class base-size corrections and a lay-flat rotation for extruded meshes.
This commit is contained in:
2026-08-08 18:41:42 +08:00
parent c3c7fe2445
commit dcba0ac4bd
4 changed files with 145 additions and 54 deletions
+17 -7
View File
@@ -23,8 +23,9 @@ user can see the entire scene at a glance.
- `@tts/extract` provides `flattenObjects(mod)` / `traverseMod` to enumerate
every object in a save.
- `@tts/mesh` provides the shape + extrusion helpers used by the viewers.
- `TTSObject` carries no position data, so exact table placement is not
recoverable — the full setup lays objects out itself.
- Every object in a save carries a `Transform` (position/rotation/scale in TTS
world units), which the proxy passes through in the raw BSON. The shared
type now models it as `TTSObjectTransform`.
## Plan
@@ -56,10 +57,15 @@ view and the full-setup view.
### 3. Layout
- Arrange objects in a grid on the "table" (fixed spacing, wrapping by row),
grouping by type so cards sit together, tiles together, etc.
- `Scene`'s `Bounds fit` already auto-fits the camera to the full layout, so no
camera work is needed.
- Place each object at its real position from the save's `Transform` instead of
a generated grid.
- `components/viewers/transform.ts` converts a TTS transform to three.js:
TTS is left-handed (Y up, +Z toward the player), three.js is right-handed,
so Z is reflected in position and rotation. Each class also gets a base-size
correction (our viewer meshes are authored for inspection, in arbitrary
units) and a "lay flat" rotation for the extruded tile/token/card meshes.
- `Scene`'s `Bounds fit` auto-fits the camera to the full layout, so no camera
work is needed.
- Non-renderable objects (bags, dice, boards without assets) are skipped and
counted, not dropped silently.
@@ -102,6 +108,9 @@ view and the full-setup view.
export object-facing mesh wrappers
- `apps/web/src/components/viewers/sharedResources.ts` — new geometry/material
caches
- `apps/web/src/components/viewers/transform.ts` — new TTS→three.js placement
conversion
- `packages/shared/src/types.ts` — add `TTSObjectTransform`
- `apps/web/src/pages/FullSetupPage.tsx` — new
- `apps/web/src/App.tsx` — route
- `apps/web/src/pages/ModPage.tsx` — nav link
@@ -110,6 +119,7 @@ view and the full-setup view.
## Open decisions (defaults in bold)
- **Layout style** — **grouped grid** vs a fan/stack for cards.
- **Layout style** — **real `Transform` placement** (was a grouped grid before
the transform data was wired in).
- **Geometry/material cache lifetime** — **session-level module cache**
(simplest, consistent with drei's global texture cache) vs dispose-on-unmount.