import { VecN } from '@holotope/core'; import { type XpbdPointN, type XpbdScalarConstraintN, type XpbdSolveResultN } from './xpbd-constraint.js'; export interface XpbdParticleNOptions { readonly id: string; readonly position: VecN | ArrayLike; readonly velocity?: VecN | ArrayLike; /** Zero fixes the point; default one. */ readonly inverseMass?: number; /** Multiplier on world gravity; default one. */ readonly gravityScale?: number; } /** Mutable RN point mass consumed by `XpbdWorldN`. */ export declare class XpbdParticleN implements XpbdPointN { readonly id: string; readonly dimension: number; readonly position: VecN; readonly velocity: VecN; readonly force: VecN; readonly inverseMass: number; gravityScale: number; constructor(options: XpbdParticleNOptions); applyForce(force: VecN | ArrayLike): this; clearForce(): this; kineticEnergy(): number; } export interface XpbdWorldNOptions { readonly dimension: number; /** Default is zero in every coordinate. */ readonly gravity?: VecN | ArrayLike; readonly solverIterations?: number; readonly responseEpsilon?: number; } /** Pure state-dependent forces evaluated at the current particle positions. */ export interface XpbdForceProviderEvaluationN { /** One force per provider particle, in the same order. */ readonly forces: readonly VecN[]; /** Optional conservative potential-energy evidence. */ readonly potentialEnergy?: number; } /** A renderer-neutral RN force source reevaluated before every substep. */ export interface XpbdForceProviderN { readonly id: string; readonly dimension: number; readonly particles: readonly XpbdParticleN[]; evaluate(): XpbdForceProviderEvaluationN; } /** Candidate-position lookup used by pure conservative evaluations. */ export type XpbdParticlePositionQueryN = (particle: XpbdParticleN) => VecN; /** A force evaluation with the conservative potential made mandatory. */ export interface XpbdConservativeForceProviderEvaluationN extends XpbdForceProviderEvaluationN { readonly potentialEnergy: number; } /** Conservative RN force source that can inspect a trial state without mutation. */ export interface XpbdConservativeForceProviderN extends XpbdForceProviderN { evaluate(): XpbdConservativeForceProviderEvaluationN; evaluateAt(positionOf: XpbdParticlePositionQueryN): XpbdConservativeForceProviderEvaluationN; } export interface XpbdWorldForceProviderResultN { readonly provider: XpbdForceProviderN; readonly evaluation: XpbdForceProviderEvaluationN; } /** Evidence returned by one post-projection velocity response. */ export interface XpbdVelocityResponseEvaluationN { /** Optional total kinetic-energy change caused by this response. */ readonly kineticEnergyChange?: number; } export interface XpbdVelocityResponseContextN { readonly deltaTime: number; readonly substepIndex: number; /** Position-level solve whose reconstructed velocities are now available. */ readonly solve: XpbdSolveResultN; } /** Ordered RN velocity policy applied after XPBD velocity reconstruction. */ export interface XpbdVelocityResponseN { readonly id: string; readonly dimension: number; /** Exact registered particles whose velocities this policy may mutate. */ readonly particles: readonly XpbdParticleN[]; apply(context: XpbdVelocityResponseContextN): XpbdVelocityResponseEvaluationN; } export interface XpbdWorldVelocityResponseResultN { readonly response: XpbdVelocityResponseN; readonly evaluation: XpbdVelocityResponseEvaluationN; } /** Read-only evidence deciding whether one completed RN substep is admissible. */ export interface XpbdStateGuardEvaluationN { readonly accepted: boolean; /** Optional signed distance from the guard boundary; positive is admissible. */ readonly margin?: number; readonly reason?: string; } export interface XpbdStateGuardContextN { readonly deltaTime: number; readonly substepIndex: number; /** Exact position at the beginning of this substep, returned as a defensive copy. */ readonly positionBeforeSubstep: (particle: XpbdParticleN) => VecN; readonly forceProviders: readonly XpbdWorldForceProviderResultN[]; readonly solve: XpbdSolveResultN; readonly velocityResponses: readonly XpbdWorldVelocityResponseResultN[]; } /** Pure accepted-state policy evaluated after a complete RN substep. */ export interface XpbdStateGuardN { readonly id: string; readonly dimension: number; /** Exact registered particles observed by this guard. */ readonly particles: readonly XpbdParticleN[]; evaluate(context: XpbdStateGuardContextN): XpbdStateGuardEvaluationN; } export interface XpbdWorldStateGuardResultN { readonly guard: XpbdStateGuardN; readonly evaluation: XpbdStateGuardEvaluationN; } /** Typed signal that a well-formed completed substep was not admissible. */ export declare class XpbdStateGuardRejectionErrorN extends Error { readonly guard: XpbdStateGuardN; readonly evaluation: XpbdStateGuardEvaluationN; readonly substepIndex: number; constructor(guard: XpbdStateGuardN, evaluation: XpbdStateGuardEvaluationN, substepIndex: number); } export interface XpbdAdaptiveStepOptionsN { /** First deterministic subdivision count. Default one. */ readonly initialSubsteps?: number; /** Hard retry ceiling. Default 64. */ readonly maximumSubsteps?: number; /** Integer multiplier applied after rejection. Default two. */ readonly growthFactor?: number; } export interface XpbdAdaptiveStepAttemptN { readonly substeps: number; readonly status: 'accepted' | 'rejected'; readonly rejectedGuardId?: string; readonly rejectedSubstepIndex?: number; readonly rejection?: XpbdStateGuardEvaluationN; } export interface XpbdWorldAdaptiveStepResultN { readonly result: XpbdWorldStepResultN; readonly attempts: readonly XpbdAdaptiveStepAttemptN[]; } /** Typed exhaustion result; the world has already restored its initial state. */ export declare class XpbdAdaptiveStepFailureErrorN extends Error { readonly deltaTime: number; readonly attempts: readonly XpbdAdaptiveStepAttemptN[]; readonly lastRejection: XpbdStateGuardRejectionErrorN; constructor(deltaTime: number, attempts: readonly XpbdAdaptiveStepAttemptN[], lastRejection: XpbdStateGuardRejectionErrorN); } export interface XpbdWorldSubstepResultN { readonly index: number; readonly deltaTime: number; /** Provider evaluations at the configuration preceding this substep. */ readonly forceProviders: readonly XpbdWorldForceProviderResultN[]; readonly solve: XpbdSolveResultN; /** Ordered policies applied after velocity reconstruction. */ readonly velocityResponses: readonly XpbdWorldVelocityResponseResultN[]; /** Ordered read-only acceptance checks for the completed substep. */ readonly stateGuards: readonly XpbdWorldStateGuardResultN[]; } export interface XpbdWorldStepResultN { readonly dimension: number; readonly deltaTime: number; readonly substeps: number; readonly constraintSolves: readonly XpbdWorldSubstepResultN[]; readonly maxAbsConstraintValue: number; readonly maxAbsCompliantResidual: number; readonly maxAbsProjectedKktResidual: number; } /** * Renderer-neutral RN point-mass integration around the XPBD golden kernel. * * This world is intentionally separate from `PhysicsWorld4`: point positions * and R4 rigid transforms are different generalized-coordinate systems. */ export declare class XpbdWorldN { readonly dimension: number; readonly gravity: VecN; private readonly solver; private readonly registeredParticles; private readonly registeredConstraints; private readonly registeredForceProviders; private readonly registeredVelocityResponses; private readonly registeredStateGuards; constructor(options: XpbdWorldNOptions); get particles(): readonly XpbdParticleN[]; get constraints(): readonly XpbdScalarConstraintN[]; get forceProviders(): readonly XpbdForceProviderN[]; get velocityResponses(): readonly XpbdVelocityResponseN[]; get stateGuards(): readonly XpbdStateGuardN[]; addParticle(particle: XpbdParticleN): this; removeParticle(particle: XpbdParticleN): this; addConstraint(constraint: XpbdScalarConstraintN): this; removeConstraint(constraint: XpbdScalarConstraintN): this; addForceProvider(provider: XpbdForceProviderN): this; removeForceProvider(provider: XpbdForceProviderN): this; addVelocityResponse(response: XpbdVelocityResponseN): this; removeVelocityResponse(response: XpbdVelocityResponseN): this; addStateGuard(guard: XpbdStateGuardN): this; removeStateGuard(guard: XpbdStateGuardN): this; /** * Predicts, projects, reconstructs velocity, and applies ordered responses * for one complete step. * External forces remain constant across substeps and clear after successful * return. State-dependent providers are reevaluated before every substep. */ step(deltaTime: number, substeps?: number): XpbdWorldStepResultN; /** * Retries typed accepted-state rejections with deterministic subdivision. * Every attempt advances the same `deltaTime`; unrelated errors are not retried. */ stepAdaptive(deltaTime: number, options?: XpbdAdaptiveStepOptionsN): XpbdWorldAdaptiveStepResultN; private validateCurrentState; private validateConstraintOwnership; private validateForceProviderOwnership; private validateVelocityResponseOwnership; private validateStateGuardOwnership; private evaluateStateGuards; private applyVelocityResponses; private evaluateForceProviders; private predict; private reconstructVelocities; } //# sourceMappingURL=xpbd-world.d.ts.map