import { TransformN, VecN } from '@holotope/core'; import { type BroadphaseCandidateProviderN, type BroadphaseDiagnosticsN } from './broadphase.js'; import type { RigidMotion4 } from './contact-kinematics4.js'; import type { ContactMaterial4 } from './contact-material4.js'; import { HyperboxCollider4 } from './hyperbox-contact-pipeline4.js'; import type { HyperboxContactOptions4, HyperboxContactPatch4 } from './hyperbox-contact4.js'; import { HyperplaneColliderN } from './hyperplane-collider.js'; import { type ConvexLinearCastOptionsN, type ConvexLinearCastResultN, type HyperplaneLinearCastResultN } from './linear-cast.js'; import { type ConvexRigidCastResult4, type HyperplaneRigidCastResult4 } from './rigid-cast4.js'; import type { HyperboxHyperplaneContactPatch4, MixedAnalyticContactOptions4 } from './mixed-contact4.js'; import { NarrowphaseDispatcherN, type NarrowphaseDispatchResultN } from './narrowphase-dispatcher.js'; import { ContactSolver4, type ContactParticipant4, type ContactSolveResult4, type ContactSolver4Options } from './normal-contact-solver4.js'; import type { PolytopeContactPatch4 } from './polytope-contact4.js'; import type { PolytopeContactOptions4 } from './polytope-contact4.js'; import type { PolytopeHyperplaneContactOptions4, PolytopeHyperplaneContactPatch4 } from './polytope-plane-contact4.js'; import { type ConvexPolytopeTopologyN, type ConvexPolytopeTopologyOptionsN } from './polytope-topology.js'; import { GlomeSupportShapeN, TransformedSupportShapeN, type SupportShapeN } from './support-shape.js'; import type { SmoothContactOptionsN, SmoothPointContactPatchN } from './smooth-contact.js'; import type { PhysicsWorld4 } from './world4.js'; /** * The response settings a collider contributes to a contact, separate from * its geometry. Two colliders meeting supply one of these each, and the * pipeline combines them into the material of the contact between them. */ export interface ContactColliderPolicy4 { /** Stable identity, used to match a contact to its predecessor across steps. */ readonly id: string; /** Whether the collider is dynamic, kinematic, or static in a pair. */ readonly participant: ContactParticipant4; /** Coulomb coefficient contributed to the combined friction of a pair. */ friction: number; /** Restitution contributed to the combined bounce of a pair. */ restitution: number; /** Bits identifying which layers this collider belongs to. */ collisionGroup: number; /** Bits identifying which layers it will collide against; a pair is * considered only when each side's group intersects the other's mask. */ collisionMask: number; /** When false the collider is skipped entirely, keeping its identity and * warm-start state for when it is re-enabled. */ enabled: boolean; /** Republishes the collider's derived state after its shape or pose is * changed directly. */ sync(): this; } export interface GlomeCollider4Options { readonly id: string; readonly radius: number; /** Dynamic body, pose-owning kinematic body, velocity-only motion, or null. */ readonly participant?: ContactParticipant4; /** Explicit world center for fixed or velocity-only participants. */ readonly center?: VecN | ArrayLike; /** Body-local center for a dynamic or pose-owning kinematic participant. */ readonly localCenter?: VecN | ArrayLike; readonly material?: ContactMaterial4; readonly collisionGroup?: number; readonly collisionMask?: number; readonly enabled?: boolean; } /** Finite R4 glome collider whose center can follow a rigid body. */ export declare class GlomeCollider4 implements ContactColliderPolicy4 { readonly id: string; readonly shape: GlomeSupportShapeN; readonly localCenter: VecN; friction: number; restitution: number; collisionGroup: number; collisionMask: number; enabled: boolean; private _participant; private manualCenter; constructor(options: GlomeCollider4Options); get participant(): ContactParticipant4; setParticipant(participant: ContactParticipant4): this; setCenter(center: VecN | ArrayLike): this; setRadius(radius: number): this; sync(): this; } export interface PolytopeCollider4Options { readonly id: string; /** Full-dimensional local R4 support shape with stable vertex enumeration. */ readonly source: SupportShapeN; /** Dynamic body, pose-owning kinematic body, velocity-only motion, or null. */ readonly participant?: ContactParticipant4; /** Manual world pose for fixed/velocity-only colliders. Pose owners reject it. */ readonly transform?: TransformN; /** Collider pose relative to a dynamic or kinematic body's root frame. */ readonly localTransform?: TransformN; /** Reusable source incidence. Compiled once from `source` when omitted. */ readonly topology?: ConvexPolytopeTopologyN; readonly topologyOptions?: ConvexPolytopeTopologyOptionsN; readonly material?: ContactMaterial4; readonly collisionGroup?: number; readonly collisionMask?: number; readonly enabled?: boolean; } /** Vertex-enumerable convex R4 polytope with explicit pose and response policy. */ export declare class PolytopeCollider4 implements ContactColliderPolicy4 { readonly id: string; readonly source: SupportShapeN; readonly shape: TransformedSupportShapeN; readonly topology: ConvexPolytopeTopologyN; readonly localTransform: TransformN; friction: number; restitution: number; collisionGroup: number; collisionMask: number; enabled: boolean; private _participant; private manualTransform; constructor(options: PolytopeCollider4Options); get participant(): ContactParticipant4; setParticipant(participant: ContactParticipant4): this; setTransform(transform: TransformN): this; sync(): this; } export interface HyperplaneContactCollider4Options { readonly id: string; readonly normal: VecN | ArrayLike; readonly offset?: number; /** Prescribed motion supplies velocity only; geometry remains explicit. */ readonly participant?: RigidMotion4 | null; readonly material?: ContactMaterial4; readonly collisionGroup?: number; readonly collisionMask?: number; readonly enabled?: boolean; } /** Infinite R4 contact boundary kept outside compact-support broadphase. */ export declare class HyperplaneContactCollider4 implements ContactColliderPolicy4 { readonly id: string; private _shape; friction: number; restitution: number; collisionGroup: number; collisionMask: number; enabled: boolean; private _participant; constructor(options: HyperplaneContactCollider4Options); get participant(): RigidMotion4 | null; get shape(): HyperplaneColliderN; setParticipant(participant: RigidMotion4 | null): this; setPlane(normal: VecN | ArrayLike, offset?: number): this; sync(): this; } export type CompactContactCollider4 = HyperboxCollider4 | GlomeCollider4 | PolytopeCollider4; export type ContactCollider4 = CompactContactCollider4 | HyperplaneContactCollider4; /** * One pair the pipeline examined in a step, and what came of it. * * Detection and response are separate facts. `patch` says the two shapes * touch; `responded` says the solver was given something to do about it, and * a pair can be the first without being the second — two static colliders * meet and there is nothing to push apart. Counting contacts by `responded` * therefore undercounts, and counting collisions by `patch` overcounts the * work done. * * The friction and restitution here are the pair's, combined from what each * collider's policy contributed, rather than either collider's own. */ export interface ContactPipelinePair4 { /** Identity of the ordered pair, stable across steps for warm-starting. */ readonly id: string; /** The first collider, in the order the pair was formed. */ readonly colliderA: ContactCollider4; /** The second. */ readonly colliderB: ContactCollider4; /** What the narrowphase established, including which capability answered. */ readonly narrowphase: NarrowphaseDispatchResultN; /** The contact region, whose type follows from the pair of shapes; * `null` when they do not touch. */ readonly patch: HyperboxContactPatch4 | PolytopeContactPatch4 | PolytopeHyperplaneContactPatch4 | HyperboxHyperplaneContactPatch4 | SmoothPointContactPatchN | null; /** Coulomb coefficient for this pair, combined from both policies. */ readonly friction: number; /** Restitution for this pair, likewise combined. */ readonly restitution: number; /** Constraints this pair contributed, by id, for matching them next step. */ readonly constraintIds: readonly string[]; /** Whether it contributed any — equivalently, whether `constraintIds` is * non-empty. */ readonly responded: boolean; } export interface ContactPipelineResult4 { readonly pairs: readonly ContactPipelinePair4[]; readonly response: ContactSolveResult4; readonly colliderCount: number; readonly compactColliderCount: number; readonly hyperplaneColliderCount: number; /** Compact/compact plus compact/hyperplane pairs; plane/plane is excluded. */ readonly possiblePairs: number; /** Compact candidates retained by broadphase plus every compact/plane pair. */ readonly candidatePairs: number; readonly compactCandidatePairs: number; readonly hyperplaneCandidatePairs: number; readonly broadphaseRejectedPairs: number; /** Diagnostics cover only the finite compact-collider lane. */ readonly broadphase: BroadphaseDiagnosticsN; readonly filteredPairs: number; readonly narrowphasePairs: number; readonly distancePairs: number; readonly unsupportedPairs: number; readonly contactPairs: number; readonly respondingPairs: number; readonly constraintCount: number; readonly retiredNarrowphasePairIds: readonly string[]; } export interface ContactPipelineWorldStep4 { readonly substeps: readonly ContactPipelineResult4[]; readonly final: ContactPipelineResult4; } export interface ContactPipelineContinuousOptions4 { /** Maximum impact events resolved inside one substep. Default 8. */ readonly maxEventsPerSubstep?: number; /** Smallest remaining/advanced time represented explicitly. Default 1e-12 s. */ readonly timeTolerance?: number; /** Zero band for externally prescribed kinematic velocity. Default 1e-12. */ readonly angularVelocityTolerance?: number; /** Conservative-advancement policy for compact/compact casts. */ readonly castOptions?: ConvexLinearCastOptionsN; } export type ContactPipelineContinuousStatus4 = 'complete' | 'partial' | 'event-limit'; export interface ContactPipelineContinuousEvent4 { readonly pairId: string; /** Time from the beginning of this substep. */ readonly time: number; /** Cast fraction of the remaining interval immediately before this event. */ readonly remainingFraction: number; readonly cast: ContactPipelineContinuousCast4; readonly solve: ContactPipelineResult4; } export type ContactPipelineContinuousCast4 = ConvexLinearCastResultN | HyperplaneLinearCastResultN | ConvexRigidCastResult4 | HyperplaneRigidCastResult4; export interface ContactPipelineContinuousSubstep4 { readonly status: ContactPipelineContinuousStatus4; readonly requestedDt: number; readonly advancedDt: number; readonly remainingDt: number; readonly initial: ContactPipelineResult4; readonly events: readonly ContactPipelineContinuousEvent4[]; readonly final: ContactPipelineResult4; readonly castPairs: number; /** One compact-collider swept-broadphase record per impact scan. */ readonly sweptBroadphase: readonly BroadphaseDiagnosticsN[]; /** Reserved for dynamic angular trajectories unsupported by a collider type. */ readonly angularFallbackPairIds: readonly string[]; readonly kinematicFallbackPairIds: readonly string[]; readonly indeterminatePairIds: readonly string[]; } export interface ContactPipelineContinuousWorldStep4 { readonly status: ContactPipelineContinuousStatus4; readonly substeps: readonly ContactPipelineContinuousSubstep4[]; readonly final: ContactPipelineResult4; } export interface ContactPipeline4Options { readonly solver?: ContactSolver4; readonly solverOptions?: ContactSolver4Options; readonly candidateProvider?: BroadphaseCandidateProviderN; readonly narrowphaseDispatcher?: NarrowphaseDispatcherN; readonly hyperboxContactOptions?: HyperboxContactOptions4; readonly smoothContactOptions?: SmoothContactOptionsN; readonly mixedContactOptions?: MixedAnalyticContactOptions4; readonly polytopeContactOptions?: Omit; readonly polytopeHyperplaneContactOptions?: Omit; /** Extra compact AABB expansion beyond query tolerances. Default 0. */ readonly broadphasePadding?: number; readonly mixFriction?: (frictionA: number, frictionB: number) => number; readonly mixRestitution?: (restitutionA: number, restitutionB: number) => number; readonly pairFilter?: (colliderA: ContactCollider4, colliderB: ContactCollider4) => boolean; } /** * Deterministic mixed-shape R4 contact orchestration. * * Finite hyperboxes, vertex polytopes, and glomes share the configured N-D * broadphase. Infinite hyperplanes use a separate exhaustive compact/plane * lane. The capability dispatcher decides whether each admitted pair yields * distance, exact deep contact, or an explicit unsupported result. */ export declare class ContactPipeline4 { readonly solver: ContactSolver4; readonly candidateProvider: BroadphaseCandidateProviderN; readonly narrowphaseDispatcher: NarrowphaseDispatcherN; readonly hyperboxContactOptions: HyperboxContactOptions4; readonly smoothContactOptions: SmoothContactOptionsN; readonly mixedContactOptions: MixedAnalyticContactOptions4; readonly polytopeContactOptions: Omit; readonly polytopeHyperplaneContactOptions: Omit; readonly broadphasePadding: number; private readonly colliders; private readonly mixFriction; private readonly mixRestitution; private readonly pairFilter; constructor(options?: ContactPipeline4Options); get size(): number; addCollider(collider: ContactCollider4): this; removeCollider(colliderOrId: ContactCollider4 | string): this; getCollider(id: string): ContactCollider4 | undefined; sync(): this; solve(dt: number): ContactPipelineResult4; stepWorld(world: PhysicsWorld4, dt: number, substeps?: number): ContactPipelineWorldStep4; /** * Opt-in event-driven rigid CCD followed by the existing discrete solver. * * Every scan and pose advance shares one frozen trajectory per dynamic or * pose-owning kinematic body. Centered glomes retain the exact linear fast * path; velocity-only prescribed motion remains a `partial` fallback. */ stepWorldContinuous(world: PhysicsWorld4, dt: number, substeps?: number, options?: ContactPipelineContinuousOptions4): ContactPipelineContinuousWorldStep4; private scanContinuousImpacts; reset(): void; } /** Stable, delimiter-safe ID for any canonically ordered R4 collider pair. */ export declare function contactPairId4(colliderIdA: string, colliderIdB: string): string; //# sourceMappingURL=contact-pipeline4.d.ts.map