import type { Quaternion, Vector2, Vector3, Vector4 } from "three";
import type { Vec3 } from "./engine_types.js";
declare type Vector = Vector3 | Vector4 | Vector2 | Quaternion;
/**
 * Math utility class providing common mathematical operations.
 * Access via the exported `Mathf` constant.
 *
 * @example
 * ```ts
 * import { Mathf } from "@needle-tools/engine";
 *
 * // Random number between 0 and 10
 * const rand = Mathf.random(0, 10);
 *
 * // Clamp a value
 * const clamped = Mathf.clamp(value, 0, 100);
 *
 * // Smooth interpolation
 * const smoothed = Mathf.lerp(start, end, t);
 * ```
 */
declare class MathHelper {
    /**
     * Returns a random number or element.
     * @param arr Array to pick a random element from
     * @returns Random element from array, or null if array is empty
     * @example `Mathf.random([1, 2, 3])` - returns random element
     */
    random<T>(arr: Array<T>): T | null;
    /**
     * Returns a random number between min and max (inclusive).
     * @param min Minimum value (inclusive)
     * @param max Maximum value (inclusive)
     * @returns Random number in range, or 0-1 if no args provided
     * @example `Mathf.random(0, 10)` - returns 0 to 10
     */
    random(min?: number, max?: number): number;
    /**
     * Fills a Vector3 with random values.
     * @param target Vector3 to fill with random values
     * @param min Minimum value for each component
     * @param max Maximum value for each component
     */
    randomVector3(target: Vector3, min?: number, max?: number): void;
    /**
     * Clamps a value between min and max.
     * @param value Value to clamp
     * @param min Minimum bound
     * @param max Maximum bound
     * @returns Clamped value
     */
    clamp(value: number, min: number, max: number): number;
    /**
     * Clamps a value between 0 and 1.
     * @param value Value to clamp
     * @returns Value clamped to [0, 1]
     */
    clamp01(value: number): number;
    /**
     * Linearly interpolates between two values.
     * @param value1 Start value (returned when t=0)
     * @param value2 End value (returned when t=1)
     * @param t Interpolation factor, clamped to [0, 1]
     * @returns Interpolated value
     */
    lerp(value1: number, value2: number, t: number): number;
    /**
     * Calculates the linear interpolation parameter that produces the given value.
     * Inverse of lerp: if `lerp(a, b, t) = v`, then `inverseLerp(a, b, v) = t`
     * @param value1 Start value
     * @param value2 End value
     * @param t The value to find the parameter for
     * @returns The interpolation parameter (may be outside [0,1] if t is outside [value1, value2])
     */
    inverseLerp(value1: number, value2: number, t: number): number;
    /**
     * Remaps a value from one range to another.
     * @param value The value to remap.
     * @param min1 The minimum value of the current range.
     * @param max1 The maximum value of the current range.
     * @param min2 The minimum value of the target range.
     * @param max2 The maximum value of the target range.
     */
    remap(value: number, min1: number, max1: number, min2: number, max2: number): number;
    /**
     * Moves a value towards a target by a maximum step amount.
     * Useful for smooth following or gradual value changes.
     * @param value1 Current value
     * @param value2 Target value
     * @param amount Maximum step to move (positive moves toward target)
     * @returns New value moved toward target, never overshooting
     */
    moveTowards(value1: number, value2: number, amount: number): number;
    readonly Rad2Deg: number;
    readonly Deg2Rad: number;
    readonly Epsilon = 0.00001;
    /**
     * Converts radians to degrees
     */
    toDegrees(radians: number): number;
    /**
     * Converts degrees to radians
     */
    toRadians(degrees: number): number;
    tan(radians: number): number;
    gammaToLinear(gamma: number): number;
    linearToGamma(linear: number): number;
    /**
     * Checks if two vectors are approximately equal within epsilon tolerance.
     * Works with Vector2, Vector3, Vector4, and Quaternion.
     * @param v1 First vector
     * @param v2 Second vector
     * @param epsilon Tolerance for comparison (default: Number.EPSILON)
     * @returns True if all components are within epsilon of each other
     */
    approximately(v1: Vector, v2: Vector, epsilon?: number): boolean;
    /**
     * Easing function: slow start, fast middle, slow end (cubic).
     * @param x Input value from 0 to 1
     * @returns Eased value from 0 to 1
     */
    easeInOutCubic(x: number): number;
}
export declare const Mathf: MathHelper;
declare class LowPassFilter {
    y: number | null;
    s: number | null;
    alpha: number;
    constructor(alpha: number);
    setAlpha(alpha: number): void;
    filter(value: number, alpha: number): number;
    lastValue(): number | null;
    reset(value: number): void;
}
/**
 * [OneEuroFilter](https://engine.needle.tools/docs/api/OneEuroFilter) is a low-pass filter designed to reduce jitter in noisy signals while maintaining low latency.
 * It's particularly useful for smoothing tracking data from XR controllers, hand tracking, or other input devices where the signal contains noise but responsiveness is important.
 *
 * The filter automatically adapts its smoothing strength based on the signal's velocity:
 * - When the signal moves slowly, it applies strong smoothing to reduce jitter
 * - When the signal moves quickly, it reduces smoothing to maintain responsiveness
 *
 * Based on the research paper: [1€ Filter: A Simple Speed-based Low-pass Filter for Noisy Input](http://cristal.univ-lille.fr/~casiez/1euro/)
 *
 * @example Basic usage with timestamp
 * ```ts
 * const filter = new OneEuroFilter(120, 1.0, 0.0);
 *
 * // In your update loop:
 * const smoothedValue = filter.filter(noisyValue, this.context.time.time);
 * ```
 *
 * @example Without timestamps (using frequency estimate)
 * ```ts
 * // Assuming 60 FPS update rate
 * const filter = new OneEuroFilter(60, 1.0, 0.5);
 *
 * // Call without timestamp - uses the frequency estimate
 * const smoothedValue = filter.filter(noisyValue);
 * ```
 *
 * @example Smoothing 3D positions
 * ```ts
 * const posFilter = new OneEuroFilterXYZ(90, 0.5, 0.0);
 *
 * posFilter.filter(trackedPosition, smoothedPosition, this.context.time.time);
 * ```
 *
 * @see {@link OneEuroFilterXYZ} for filtering 3D vectors
 */
export declare class OneEuroFilter {
    /**
     * An estimate of the frequency in Hz of the signal (> 0), if timestamps are not available.
     */
    freq: number;
    /**
     * Min cutoff frequency in Hz (> 0). Lower values allow to remove more jitter.
     */
    minCutOff: number;
    /**
     * Parameter to reduce latency (> 0). Higher values make the filter react faster to changes.
     */
    beta: number;
    /**
     * Used to filter the derivates. 1 Hz by default. Change this parameter if you know what you are doing.
     */
    dCutOff: number;
    /**
     * The low-pass filter for the signal.
     */
    x: LowPassFilter;
    /**
     * The low-pass filter for the derivates.
     */
    dx: LowPassFilter;
    /**
     * The last time the filter was called.
     */
    lasttime: number | null;
    /** Create a new OneEuroFilter
     * @param freq - An estimate of the frequency in Hz of the signal (> 0), if timestamps are not available.
     * @param minCutOff - Min cutoff frequency in Hz (> 0). Lower values allow to remove more jitter.
     * @param beta - Parameter to reduce latency (> 0). Higher values make the filter react faster to changes.
     * @param dCutOff - Used to filter the derivates. 1 Hz by default. Change this parameter if you know what you are doing.
     */
    constructor(freq: number, minCutOff?: number, beta?: number, dCutOff?: number);
    alpha(cutOff: number): number;
    /** Filter your value: call with your value and the current timestamp (e.g. from this.context.time.time) */
    filter(x: number, time?: number | null): number;
    reset(x?: number): void;
}
export declare class OneEuroFilterXYZ {
    readonly x: OneEuroFilter;
    readonly y: OneEuroFilter;
    readonly z: OneEuroFilter;
    /** Create a new OneEuroFilter
     * @param freq - An estimate of the frequency in Hz of the signal (> 0), if timestamps are not available.
     * @param minCutOff - Min cutoff frequency in Hz (> 0). Lower values allow to remove more jitter.
     * @param beta - Parameter to reduce latency (> 0). Higher values make the filter react faster to changes.
     * @param dCutOff - Used to filter the derivates. 1 Hz by default. Change this parameter if you know what you are doing.
     */
    constructor(freq: number, minCutOff?: number, beta?: number, dCutOff?: number);
    filter(value: Vec3, target: Vec3, time?: number | null): void;
    reset(value?: Vec3): void;
}
export {};
