import { VecN } from '@holotope/core'; import { type GjkOptions, type GjkResult } from './gjk.js'; import { HyperplaneColliderN, type HyperplaneQueryResult } from './hyperplane-collider.js'; import type { SupportFeatureId, SupportShapeN } from './support-shape.js'; export type LinearCastStatusN = 'impact' | 'initial-overlap' | 'miss' | 'indeterminate'; export type LinearCastReasonN = 'contact-band' | 'initial-overlap' | 'separating-motion' | 'past-horizon' | 'gjk-iteration-limit' | 'advancement-stalled' | 'advancement-limit'; export interface ConvexLinearCastOptionsN { /** Maximum conservative-advancement steps. Default 32. */ readonly maxIterations?: number; /** Report impact at this non-negative separation. Default 0. */ readonly targetDistance?: number; /** World-space contact band. Default 1e-12. */ readonly distanceTolerance?: number; /** Normalized sweep-fraction progress band. Default 1e-12. */ readonly timeTolerance?: number; /** Closing-speed zero band in displacement units. Default 1e-14. */ readonly speedTolerance?: number; /** GJK policy reused at every sampled pose. Warm starts are managed internally. */ readonly gjkOptions?: Omit; /** Retain one compact record per advancement step. Default false. */ readonly recordTrace?: boolean; } export interface LinearCastTraceEntryN { readonly iteration: number; readonly time: number; readonly distance: number; readonly closingSpeed: number | null; readonly advance: number | null; } export interface ConvexLinearCastResultN { readonly kind: 'convex'; readonly status: LinearCastStatusN; readonly reason: LinearCastReasonN; readonly hit: boolean | null; /** Normalized fraction in [0,1], or null when no impact is certified. */ readonly time: number | null; /** Interval [0, safeTime) is certified outside the requested contact band. */ readonly safeTime: number; readonly distance: number; /** Last separating normal from B toward A; null for an initial overlap. */ readonly normal: VecN | null; readonly pointA: VecN; readonly pointB: VecN; readonly iterations: number; readonly gjkIterations: number; readonly finalQuery: GjkResult; readonly trace?: readonly LinearCastTraceEntryN[]; } export interface HyperplaneLinearCastOptionsN { /** Report impact at this non-negative separation. Default 0. */ readonly targetDistance?: number; /** World-space contact band. Default 1e-12. */ readonly distanceTolerance?: number; /** Normalized sweep-fraction band. Default 1e-12. */ readonly timeTolerance?: number; /** Closing-speed zero band in displacement units. Default 1e-14. */ readonly speedTolerance?: number; } /** * Result of casting a convex shape against a hyperplane under translation * alone. Without rotation the closing speed is constant, so the cast is * solved rather than advanced: it always decides, and neither an * indeterminate status nor an iteration-limit reason can occur. `hit` is * therefore a plain boolean, unlike its rigid counterparts. */ export interface HyperplaneLinearCastResultN { /** Discriminant, for narrowing a union of cast results. */ readonly kind: 'hyperplane'; readonly status: Exclude; readonly reason: Exclude; /** Whether the shape reaches the plane within the cast. */ readonly hit: boolean; /** Time of impact, `null` on a miss. */ readonly time: number | null; /** Motion is proven contact-free up to here. */ readonly safeTime: number; /** Signed separation at the final query; negative once the shape crosses. */ readonly distance: number; /** The plane's unit normal. */ readonly normal: VecN; /** Deepest point of the shape toward the plane, in world coordinates. */ readonly pointOnShape: VecN; /** Its projection onto the plane. */ readonly pointOnPlane: VecN; /** Which support feature `pointOnShape` came from, for warm-starting. */ readonly featureId: SupportFeatureId; /** The support query the result was read from. */ readonly finalQuery: HyperplaneQueryResult; } /** * Dimension-independent linear shape cast for two compact convex bodies. * * The input vectors are complete displacements over one normalized interval, * not velocities. Each advancement is bounded by the current separating * plane, so no sampled step can pass through first contact. Rotation is an * explicitly separate trajectory problem and is not approximated here. */ export declare function convexLinearCastN(shapeA: SupportShapeN, displacementA: VecN | ArrayLike, shapeB: SupportShapeN, displacementB: VecN | ArrayLike, options?: ConvexLinearCastOptionsN): ConvexLinearCastResultN; /** Exact linear cast of one compact support shape against a static plane. */ export declare function supportShapeHyperplaneLinearCastN(shape: SupportShapeN, displacement: VecN | ArrayLike, plane: HyperplaneColliderN, options?: HyperplaneLinearCastOptionsN): HyperplaneLinearCastResultN; //# sourceMappingURL=linear-cast.d.ts.map