feat(tabletop): show surface bounds and lay parts flat
Add a toggleable surface plane, bounds outline, and constant-size HTML label. Scale placement and mount anchors to world units so parts land on the surface, and rotate parts to face up.
This commit is contained in:
@@ -9,6 +9,7 @@ import type { Package } from '@tts/bgm';
|
||||
import { useStacking } from './stacking.js';
|
||||
import type { Placement } from './state.js';
|
||||
import { PartView } from './partView.js';
|
||||
import { MM_TO_WORLD } from './part.js';
|
||||
|
||||
export function PartPlacement({ pkg, placement }: { pkg: Package; placement: Placement }) {
|
||||
const { route, candidate, piece, index, stackSize } = placement;
|
||||
@@ -18,13 +19,18 @@ export function PartPlacement({ pkg, placement }: { pkg: Package; placement: Pla
|
||||
|
||||
const { x, y, rotation } = useStacking(route.stacking, index, stackSize);
|
||||
|
||||
const anchorX = (candidate?.x ?? route.x ?? 0) + x;
|
||||
const anchorY = (candidate?.y ?? route.y ?? 0) + y;
|
||||
// Route anchors and stacking offsets are in mm; convert to world units so
|
||||
// parts land on the (world-scaled) surface.
|
||||
const anchorX = ((candidate?.x ?? route.x ?? 0) + x) * MM_TO_WORLD;
|
||||
const anchorY = ((candidate?.y ?? route.y ?? 0) + y) * MM_TO_WORLD;
|
||||
const anchorRotation = (candidate?.rotation ?? route.rotation ?? 0) + rotation;
|
||||
|
||||
return (
|
||||
<group position={[anchorX, 0, anchorY]} rotation={[0, anchorRotation, 0]}>
|
||||
<PartView part={part} baseUrl={part.baseUrl} />
|
||||
{/* The part mesh extrudes along +Z; lay it flat so its face points up. */}
|
||||
<group rotation={[-Math.PI / 2, 0, 0]}>
|
||||
<PartView part={part} baseUrl={part.baseUrl} />
|
||||
</group>
|
||||
</group>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user