TURNCRAFT/src/fx/layout.ts
jing 5a39e3a947 TURNCRAFT: contracts, docs, and all five lane deliverables (pre-integration)
Lanes A (engine), B (player), C (worldgen), D (machines/quest),
E (audio/fx/ui) as landed, each with HANDOFF.md + update docs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 20:50:56 +10:00

50 lines
2.2 KiB
TypeScript

// TURNCRAFT — Lane E. Fixed world-space geometry the FX overlays sit on, all
// derived from `src/core/constants.ts` LAYOUT (never a magic literal that isn't
// anchored to a gear position). These are the sprite anchor points: VU towers
// on the mixer, the signal-path polyline lit on each repair, the patch bay.
import { LAYOUT, PLATTER, Y_RECORD_TOP } from '../core/constants';
export interface VuTower {
x: number; z: number; baseY: number; segments: number; segH: number;
band: 'low' | 'mid' | 'high';
}
const m = LAYOUT.mixer;
const midX = (m.minX + m.maxX) / 2;
// Two LED VU towers at the back of the mixer face, driven by different bands.
export const VU_TOWERS: VuTower[] = [
{ x: m.minX + 14, z: m.maxZ - 6, baseY: m.topY + 3, segments: 14, segH: 2.0, band: 'low' },
{ x: m.maxX - 14, z: m.maxZ - 6, baseY: m.topY + 3, segments: 14, segH: 2.0, band: 'mid' },
];
// The signal chain, as a polyline the trace sprite runs on each repair:
// cartridge -> tonearm pivot -> cable canyon -> patch bay -> mixer -> master out.
export const SIGNAL_PATH: [number, number, number][] = [
[LAYOUT.deckA.spindleX + 30, Y_RECORD_TOP + 2, LAYOUT.deckA.spindleZ - 18], // cartridge
[LAYOUT.deckA.maxX - 6, 92, LAYOUT.deckA.maxZ - 6], // tonearm pivot
[150, 96, 160], // cable canyon
[midX, (LAYOUT.patchBay.minY + LAYOUT.patchBay.maxY) / 2, LAYOUT.backWallZ], // patch bay
[midX, m.topY + 6, (m.minZ + m.maxZ) / 2], // mixer
[midX, m.topY - 8, LAYOUT.frontLipZ + 8], // master out (front)
];
export const PATCH_BAY_POS: [number, number, number] = [
midX,
(LAYOUT.patchBay.minY + LAYOUT.patchBay.maxY) / 2,
LAYOUT.backWallZ,
];
// Deck rim points for the 45-rpm sparkle.
export const DECK_RIM = {
A: { x: LAYOUT.deckA.spindleX, z: LAYOUT.deckA.spindleZ, y: Y_RECORD_TOP + 0.5, r: PLATTER.recordRadius },
B: { x: LAYOUT.deckB.spindleX, z: LAYOUT.deckB.spindleZ, y: Y_RECORD_TOP + 0.5, r: PLATTER.recordRadius },
} as const;
/** Booth-volume box the ambient dust motes drift within. */
export const DUST_BOX = {
min: [10, 42, 44] as [number, number, number],
max: [438, 128, 198] as [number, number, number],
};