feat: add facing orientation to parts
Replace the face/back boolean with a three-state facing (face, back, standing) seeded from setup placements. Parts now orient about the anchor at the resting face/edge, so back-down parts sit on the table instead of below it and standing parts rest on their bottom edge.
This commit is contained in:
@@ -9,10 +9,10 @@ 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, DEG_TO_RAD } from './part.js';
|
||||
import { MM_TO_WORLD, DEG_TO_RAD, facingTransform, partDimensions } from './part.js';
|
||||
|
||||
export function PartPlacement({ pkg, placement }: { pkg: Package; placement: Placement }) {
|
||||
const { route, candidate, piece, index, stackSize, face } = placement;
|
||||
const { route, candidate, piece, index, stackSize, facing } = 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;
|
||||
@@ -34,12 +34,16 @@ export function PartPlacement({ pkg, placement }: { pkg: Package; placement: Pla
|
||||
const anchorRotation =
|
||||
((candidate?.rotation ?? route.rotation ?? 0) - rotation) * DEG_TO_RAD;
|
||||
|
||||
// The facing pivot is the center of the face/edge that rests on the table
|
||||
// and should land at the anchor. Translate the mesh by the pivot, then apply
|
||||
// the facing rotation and tilt about it, so the part sits on the table.
|
||||
const { width, height, depth } = partDimensions(part);
|
||||
const { pivot, xRotation } = facingTransform(facing, { height, depth });
|
||||
|
||||
return (
|
||||
<group position={[anchorX, anchorZ, anchorY]} rotation={[0, anchorRotation, 0]}>
|
||||
{/* 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]}>
|
||||
<group rotation={!face ? [Math.PI, 0, 0] : [0, 0, 0]}>
|
||||
<group position={[-pivot[0], -pivot[1], -pivot[2]]}>
|
||||
<group rotation={[xRotation, tilt * DEG_TO_RAD, 0]}>
|
||||
<PartView part={part} baseUrl={part.baseUrl} />
|
||||
</group>
|
||||
</group>
|
||||
|
||||
Reference in New Issue
Block a user