using UnityEngine;

namespace RebootKit.Engine.Foundation {
    public static class MathUtility {

        // Spring math
        // Source: https://allenchou.net/2015/04/game-math-precise-control-over-numeric-springing/
        public static void Spring(ref float current,
                                  ref float velocity,
                                  float target,
                                  float halfLife,
                                  float frequency,
                                  float timeStep) {
            float dampingRatio = -Mathf.Log(0.5f) / (frequency * halfLife);
            float f = 1.0f + 2.0f * timeStep * dampingRatio * frequency;
            float oo = frequency * frequency;
            float hoo = timeStep * oo;
            float hhoo = timeStep * hoo;
            float detInv = 1.0f / (f + hhoo);
            float detX = f * current + timeStep * velocity + hhoo * target;
            float detV = velocity + hoo * (target - current);
            current = detX * detInv;
            velocity = detV * detInv;
        }

        public static void Spring(ref Vector3 current,
                                  ref Vector3 velocity,
                                  Vector3 target,
                                  float halfLife,
                                  float frequency,
                                  float timeStep) {
            float dampingRatio = -Mathf.Log(0.5f) / (frequency * halfLife);
            float f = 1.0f + 2.0f * timeStep * dampingRatio * frequency;
            float oo = frequency * frequency;
            float hoo = timeStep * oo;
            float hhoo = timeStep * hoo;
            float detInv = 1.0f / (f + hhoo);
            Vector3 detX = f * current + timeStep * velocity + hhoo * target;
            Vector3 detV = velocity + hoo * (target - current);
            current = detX * detInv;
            velocity = detV * detInv;
        }
    }
}