#if BURST_PRESENT using Unity.Burst; #endif using Unity.Mathematics; namespace UnityEngine.XR.Interaction.Toolkit.Utilities { /// /// Provides utility methods for various types of interpolations. /// #if BURST_PRESENT [BurstCompile] #endif public static class BurstLerpUtility { /// /// Performs a quadratic Bezier interpolation between two Vector3 values. /// This method uses the BezierLerp function for float3 types to perform the interpolation, /// allowing the method to be Burst-compiled for performance. /// /// Starting Vector3 value. /// Ending Vector3 value. /// Interpolation factor. /// Offset factor for the control point from the midpoint. Defaults to 0.5f. /// The interpolated Vector3 result. public static Vector3 BezierLerp(in Vector3 start, in Vector3 end, float t, float controlHeightFactor = 0.5f) { BezierLerp(start, end, t, out float3 result, controlHeightFactor); return result; } /// /// Performs a quadratic Bezier interpolation between two float3 values using a single interpolation factor. /// Outputs the result in an out parameter. /// /// Starting float3 value. /// Ending float3 value. /// Interpolation factor. /// Offset factor for the control point from the midpoint. Defaults to 0.5f. /// Output interpolated float3 result. #if BURST_PRESENT [BurstCompile] #endif public static void BezierLerp(in float3 start, in float3 end, float t, out float3 result, float controlHeightFactor = 0.5f) { result = math.lerp(start, end, BezierLerp(0f, 1f, t, controlHeightFactor)); } /// /// Performs a quadratic Bezier interpolation between two float values. /// This method calculates a control point as an offset from the midpoint between the start and end values, creating a curved path. /// /// Starting float value. /// Ending float value. /// Interpolation factor. /// Offset factor for the control point from the midpoint. Defaults to 0.5f. /// The interpolated float result. #if BURST_PRESENT [BurstCompile] #endif public static float BezierLerp(float start, float end, float t, float controlHeightFactor = 0.5f) { float midPoint = (start + end) / 2; float control = midPoint + controlHeightFactor * (end - start); float oneMinusT = 1 - t; return oneMinusT * (oneMinusT * start + t * control) + t * (oneMinusT * control + t * end); } /// /// Performs a bounce-out interpolation between two Vector3 values. The interpolation creates a bounce effect towards the end. /// /// Starting Vector3 value. /// Ending Vector3 value. /// Interpolation factor, typically between 0 and 1. /// Speed factor of the bounce effect. Default is 1. /// The interpolated Vector3 result. public static Vector3 BounceOutLerp(Vector3 start, Vector3 end, float t, float speed = 1f) { BounceOutLerp(start, end, t, out var result, speed); return result; } /// /// Performs a bounce-out interpolation between two float3 values. The interpolation creates a bounce effect towards the end. /// /// Starting float3 value. /// Ending float3 value. /// Interpolation factor, typically between 0 and 1. /// The interpolated float3 result. /// Speed factor of the bounce effect. Default is 1. #if BURST_PRESENT [BurstCompile] #endif public static void BounceOutLerp(in float3 start, in float3 end, float t, out float3 result, float speed = 1f) { result = math.lerp(start, end, EaseOutBounce(t, speed)); } /// /// Performs a bounce-out interpolation between two float values. The interpolation creates a bounce effect towards the end. /// /// Starting float value. /// Ending float value. /// Interpolation factor, typically between 0 and 1. /// Speed factor of the bounce effect. Default is 1. /// The interpolated float result. #if BURST_PRESENT [BurstCompile] #endif public static float BounceOutLerp(float start, float end, float t, float speed = 1f) { return math.lerp(start, end, EaseOutBounce(t, speed)); } static float EaseOutBounce(float t, float speed = 1f) { const float n1 = 7.5625f; const float d1 = 2.75f; // Adjust t based on intensity t = Mathf.Clamp01(t * speed); if (t < 1 / d1) { return n1 * t * t; } else if (t < 2 / d1) { t -= 1.5f / d1; return n1 * t * t + 0.75f; } else if (t < 2.5 / d1) { t -= 2.25f / d1; return n1 * t * t + 0.9375f; } else { t -= 2.625f / d1; return n1 * t * t + 0.984375f; } } /// /// Performs a single bounce-out interpolation between two Vector3 values. /// The interpolation creates a bounce effect towards the end. /// /// Starting Vector3 value. /// Ending Vector3 value. /// Interpolation factor, typically between 0 and 1. /// Speed factor of the bounce effect. Default is 1. /// The interpolated Vector3 result. public static Vector3 SingleBounceOutLerp(Vector3 start, Vector3 end, float t, float speed = 1f) { BounceOutLerp(start, end, t, out float3 result, speed); return result; } /// /// Performs a single bounce-out interpolation between two float3 values. /// The interpolation creates a bounce effect towards the end. /// /// Starting float3 value. /// Ending float3 value. /// Interpolation factor, typically between 0 and 1. /// The interpolated float3 result. /// Speed factor of the bounce effect. Default is 1. #if BURST_PRESENT [BurstCompile] #endif public static void SingleBounceOutLerp(in float3 start, in float3 end, float t, out float3 result, float speed = 1f) { result = math.lerp(start, end, EaseOutBounceSingle(t, speed)); } /// /// Performs a single bounce-out interpolation between two float values. /// The interpolation creates a bounce effect towards the end. /// /// Starting float value. /// Ending float value. /// Interpolation factor, typically between 0 and 1. /// Speed factor of the bounce effect. Default is 1. /// The interpolated float result. #if BURST_PRESENT [BurstCompile] #endif public static float SingleBounceOutLerp(float start, float end, float t, float speed = 1f) { return math.lerp(start, end, EaseOutBounceSingle(t, speed)); } static float EaseOutBounceSingle(float t, float speed = 1f) { const float n1 = 7.5625f; const float d1 = 2.75f; t = Mathf.Clamp01(t * speed); if (t < 1 / d1) { return n1 * t * t; } else if (t < 2 / d1) { t -= 1.5f / d1; return n1 * t * t + 0.75f; } else { t -= 2.25f / d1; return n1 * t * t + 0.9375f; } } } }