/** Small framerate-independent math helpers shared by the 3D scene. */

export const clamp01 = (v: number) => (v < 0 ? 0 : v > 1 ? 1 : v);

export const lerp = (a: number, b: number, t: number) => a + (b - a) * t;

/** Linear remap of `v` from [inMin,inMax] to [outMin,outMax], clamped. */
export function remap(
  v: number,
  inMin: number,
  inMax: number,
  outMin = 0,
  outMax = 1,
): number {
  const t = clamp01((v - inMin) / (inMax - inMin || 1));
  return outMin + (outMax - outMin) * t;
}

export function smoothstep(edge0: number, edge1: number, x: number): number {
  const t = clamp01((x - edge0) / (edge1 - edge0 || 1));
  return t * t * (3 - 2 * t);
}

/**
 * Exponential damp toward a target — frame-rate independent.
 * lambda ~ responsiveness (higher = snappier).
 */
export function damp(current: number, target: number, lambda: number, dt: number): number {
  return lerp(current, target, 1 - Math.exp(-lambda * dt));
}

/** Deterministic pseudo-random in [0,1) — avoids Math.random for stable SSR/scene. */
export function seeded(i: number): number {
  const x = Math.sin(i * 127.1 + 311.7) * 43758.5453;
  return x - Math.floor(x);
}
