import type { Object3D } from "three"; import { Vector3 } from "three"; /** * Distributes aim rotation across a chain of bones. * * Computes the swing rotation from `currentDirection` to `targetDirection` * and splits it across bones according to `curve` weights. * * Mutates `bone.quaternion` directly. Call after AnimationMixer update. */ export declare class AimChainIK { readonly bones: readonly Object3D[]; /** Numerical stability threshold. */ epsilon: number; /** * Global blend weight. 0 = solver has no effect, 1 = full effect. * Clamped to 0-1 internally. */ weight: number; /** * Per-bone rotation weights. Normalized internally so their sum equals 1. * * `[1, 1, 1, 1]` = uniform. `[0.2, 0.5, 0.8, 1.0]` = root gets least, tip gets most. * * Compared by reference - mutating values in-place won't trigger * renormalization. Assign a new array to update. * * Length must match bone count; mismatches throw on `solve()`. */ curve: readonly number[]; private readonly swingAxis; private readonly deltaRotation; private readonly boneWorldQuaternion; private readonly parentWorldQuaternion; private normalizedCurve; private lastCurveReference; /** * @param bones - Ordered from root to tip. Must contain at least one bone. */ constructor(bones: readonly Object3D[]); /** * Rotate the chain so that `currentDirection` aligns with `targetDirection`. * * Both vectors are in world space and are not mutated. * * Sample directions **before** calling - this method mutates bone quaternions, * so any direction derived from the chain will be stale after the call. * * @param currentDirection - Where the chain currently aims. * @param targetDirection - Where it should aim. */ solve(currentDirection: Vector3, targetDirection: Vector3): void; /** * Returns normalized curve (sums to 1). * Rebuilds only when the `curve` reference changes. */ private getNormalizedCurve; }