Model part face in tabletop state

Replace the path->part-list store with a per-part map keyed by part id, so each placed part carries its path, stack index, and face. Derive each path's ordered children for stacking, and flip face-down parts in PartPlacement.
This commit is contained in:
2026-08-10 11:10:16 +08:00
parent 6502fdae4f
commit bc418b2c73
8 changed files with 170 additions and 69 deletions
+6 -3
View File
@@ -12,7 +12,7 @@ import { PartView } from './partView.js';
import { MM_TO_WORLD, DEG_TO_RAD } from './part.js';
export function PartPlacement({ pkg, placement }: { pkg: Package; placement: Placement }) {
const { route, candidate, piece, index, stackSize } = placement;
const { route, candidate, piece, index, stackSize, face } = placement;
// `piece` is `package:type#id`; the parts map is keyed by `type#id`.
const part = pkg.parts.get(piece.split(':').slice(1).join(':'));
if (!part) return null;
@@ -36,9 +36,12 @@ export function PartPlacement({ pkg, placement }: { pkg: Package; placement: Pla
return (
<group position={[anchorX, anchorZ, anchorY]} rotation={[0, anchorRotation, 0]}>
{/* The part mesh extrudes along +Z; lay it flat so its face points up. */}
{/* The part mesh extrudes along +Z; lay it flat so its face points up.
A face-down part is flipped over about its local X axis. */}
<group rotation={[-Math.PI / 2, tilt * DEG_TO_RAD, 0]}>
<PartView part={part} baseUrl={part.baseUrl} />
<group rotation={!face ? [Math.PI, 0, 0] : [0, 0, 0]}>
<PartView part={part} baseUrl={part.baseUrl} />
</group>
</group>
</group>
);