feat(tabletop): add state, setup, mounting, and stacking
Implement the tabletop library's game state store, setup seeding with bare-type expansion, surface mount tree resolution, part placement, and the stacking positioning process with a dependency-free SVG path helper. Wire the public API and add unit plus vite integration tests.
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* `WorldSurfaceView` — mount a surface in world space.
|
||||
*
|
||||
* Renders a world mount node (a `kind: table` surface and its child surfaces)
|
||||
* at its anchor. Parts on the surface are placed via `PartPlacement` from the
|
||||
* derived render state. A disabled surface isn't part of the mount tree, so
|
||||
* it's never rendered.
|
||||
*/
|
||||
import type { Package } from '@tts/bgm';
|
||||
import { useRenderState } from '../state.js';
|
||||
import { PartPlacement } from '../placement.js';
|
||||
import type { MountNode } from '../mount.js';
|
||||
|
||||
export function WorldSurfaceView({ pkg, node }: { pkg: Package; node: MountNode }) {
|
||||
return <SurfaceNode pkg={pkg} node={node} />;
|
||||
}
|
||||
|
||||
/** Render a mount node at its anchor, placing parts and recursing into children. */
|
||||
export function SurfaceNode({ pkg, node }: { pkg: Package; node: MountNode }) {
|
||||
const placements = useRenderState(pkg);
|
||||
const own = placements.filter((p) => p.surface === node.id);
|
||||
|
||||
return (
|
||||
<group position={[node.x, 0, node.y]} rotation={[0, node.rotation, 0]}>
|
||||
{own.map((p) => (
|
||||
<PartPlacement key={`${p.surface}:${p.piece}`} pkg={pkg} placement={p} />
|
||||
))}
|
||||
{node.children.map((child) => (
|
||||
<SurfaceNode key={child.id} pkg={pkg} node={child} />
|
||||
))}
|
||||
</group>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user