/** * SpineChain - Core physics for procedural fish animation * * Based on inverse kinematics chain simulation where: * - Each joint follows its predecessor * - Distance constraints maintain segment lengths * - Angle constraints limit bending between segments * - Swimming motion emerges from tail oscillation propagating through chain * * References: * - FABRIK algorithm: http://www.andreasaristidou.com/FABRIK.html * - argonaut procedural animation: https://github.com/argonautcode/animal-proc-anim */ export interface SpineJoint { x: number; y: number; angle: number; width: number; segmentLength: number; } export interface SpineConfig { jointCount: number; widthProfile: number[]; angleConstraint: number; segmentLength: number; } export declare class SpineChain { joints: SpineJoint[]; angleConstraint: number; constructor(config: SpineConfig, startX: number, startY: number, direction: 1 | -1); /** * Update spine positions - head moves to target, body follows * Uses forward reaching: each joint pulls toward its predecessor */ update(targetX: number, targetY: number): void; /** * Apply swimming wave through entire spine * Creates natural S-curve motion that propagates from tail to head * @param amplitude - Max swing at tail (decreases toward head) * @param phase - Current phase of oscillation (0-2PI) */ applyTailOscillation(amplitude: number, phase: number): void; /** * Get position along spine using parametric interpolation * @param t - Position from 0 (head) to 1 (tail) */ getPositionAt(t: number): { x: number; y: number; angle: number; width: number; }; /** * Get curvature at a specific joint (angle difference from previous) * Used for fin deflection */ getCurvatureAt(jointIndex: number): number; /** * Get the head position */ get head(): { x: number; y: number; }; /** * Get the tail position */ get tail(): { x: number; y: number; }; /** * Get head angle (fish's facing direction) */ get headAngle(): number; /** * Constrain an angle to be within angleConstraint of reference */ private constrainAngle; /** * Normalize angle to -PI to PI range */ private normalizeAngle; /** * Interpolate between two angles, handling wraparound */ private lerpAngle; /** * Set body widths from a profile array (for species variation) */ setWidthProfile(profile: number[], maxWidth: number): void; /** * Get total length of spine */ get totalLength(): number; } //# sourceMappingURL=SpineChain.d.ts.map