/** * Camera-fit policy: pick a target / distance / view direction appropriate * to the scene's bounding-box shape. * * Compact models (typical buildings, aspect <= LINEAR_ASPECT_THRESHOLD) keep * the historical south-east isometric pose with `maxSize * 2` distance — the * established BIM convention and the only thing the existing test suite has * pinned. Long-thin models (railway alignments, road corridors, anything * with bbox aspect > 50:1) get a "linear" policy: camera positioned at the * bbox centre, looking down-and-along the longest axis, distance chosen so * sub-metre features (signals, referents, kerbs) project to several pixels * rather than vanishing into a single pixel of the auto-fit frustum. * * The module is intentionally pure (no GPU / Camera / Renderer dependency) * so it can be unit-tested for every aspect ratio that matters and reused * by both the post-load auto-fit and the Home-view button without * duplicating the heuristic at each call site. * * iTwin.js civil viewers solve this same problem with a stationing * navigation mode that tracks the alignment direction. We approximate the * starting pose iTwin uses for the first frame. */ import type { Vec3 } from './raycaster.js'; export interface Bounds3 { min: Vec3; max: Vec3; } export type FitPolicyKind = 'compact' | 'linear'; export interface FitPolicy { /** Which heuristic produced this pose — for telemetry / UI hints. */ kind: FitPolicyKind; /** Bbox aspect ratio (longest / shortest, clamped). Surfaced for tests. */ aspect: number; /** Where the camera should look. */ target: Vec3; /** Where the camera should sit. */ position: Vec3; /** World up vector. Always (0, 1, 0) — both policies are Y-up. */ up: Vec3; /** Distance from position to target. Convenience copy for callers. */ distance: number; } export interface PickFitPolicyOptions { /** Vertical field-of-view in radians. */ fovY: number; /** Shortest viewport dimension in pixels (height for landscape). */ viewportShortPx?: number; /** * Override the linear-detection threshold. Production should leave this * at the default; exposed for tests that pin the threshold behaviour. */ linearAspectThreshold?: number; /** * Override the minimum longest-axis extent (world units) at/above which the * linear policy is allowed to apply. Production should leave this at the * default; exposed for tests that pin the size-floor behaviour. */ linearMinLongest?: number; } /** * Compute the fit pose for a scene's bounding box. Pure function — no * side-effects; returns the pose the caller should apply to the camera. * * The compact branch reproduces the legacy `fitToBounds()` pose exactly * (south-east isometric at `maxSize * 2`) so a model that scored "compact" * frames identically to today's build. The linear branch only kicks in * once the bbox aspect ratio crosses the threshold, so building / room / * piece geometry never sees a behaviour change. */ export declare function pickFitPolicy(bounds: Bounds3, options: PickFitPolicyOptions): FitPolicy; //# sourceMappingURL=camera-fit-policy.d.ts.map