feat(tabletop): add tilt and zStart/zEnd stacking options

Replace the per-part lift with a local Y-axis tilt that fans the stack,
and add zStart/zEnd to ramp the stack's height across the curve so it
arches in 3D. Update the poker deck and docs accordingly.
This commit is contained in:
2026-08-09 23:36:42 +08:00
parent 2da04940c2
commit c5d6dff12d
9 changed files with 127 additions and 28 deletions
+7 -5
View File
@@ -17,20 +17,22 @@ export function PartPlacement({ pkg, placement }: { pkg: Package; placement: Pla
const part = pkg.parts.get(piece.split(':').slice(1).join(':'));
if (!part) return null;
const { x, y, rotation } = useStacking(route.stacking, index, stackSize);
const { x, y, rotation, z, tilt } = useStacking(route.stacking, index, stackSize);
// Route anchors and stacking offsets are in mm; convert to world units so
// parts land on the (world-scaled) surface.
// parts land on the (world-scaled) surface. `z` raises the part along the
// surface normal (world +Y); `tilt` fans it about its local Y (long) axis.
const anchorX = ((candidate?.x ?? route.x ?? 0) + x) * MM_TO_WORLD;
const anchorY = ((candidate?.y ?? route.y ?? 0) + y) * MM_TO_WORLD;
const anchorZ = z * MM_TO_WORLD;
const anchorRotation = (candidate?.rotation ?? route.rotation ?? 0) + rotation;
return (
<group position={[anchorX, 0, anchorY]} rotation={[0, anchorRotation, 0]}>
<group position={[anchorX, anchorZ, anchorY]} rotation={[0, anchorRotation, 0]}>
{/* The part mesh extrudes along +Z; lay it flat so its face points up. */}
<group rotation={[-Math.PI / 2, 0, 0]}>
<group rotation={[-Math.PI / 2, 0, tilt]}>
<PartView part={part} baseUrl={part.baseUrl} />
</group>
</group>
);
}
}