#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;
}
}
}
}