diff --git a/Runtime/mathx.Mathf.translations.cs b/Runtime/mathx.Mathf.translations.cs index e1a2281..86e5e07 100644 --- a/Runtime/mathx.Mathf.translations.cs +++ b/Runtime/mathx.Mathf.translations.cs @@ -11,16 +11,39 @@ namespace Unity.Mathematics public static partial class mathx { + #region pingpong /// PingPongs the value t, so that it is never larger than length and never smaller than 0. - public static float pingpong(float x, float length) => length - math.abs(x.repeat(length * 2) - length); - public static float2 pingpong(float2 x, float length) => length - math.abs(x.repeat(length * 2) - length); - public static float3 pingpong(float3 x, float length) => length - math.abs(x.repeat(length * 2) - length); + public static float4 pingpong(float4 x, float4 length) => length - math.abs(x.repeat(length * 2) - length); public static float4 pingpong(float4 x, float length) => length - math.abs(x.repeat(length * 2) - length); - - public static double pingpong(double x, double length) => length - math.abs(x.repeat(length * 2) - length); - public static double2 pingpong(double2 x, double length) => length - math.abs(x.repeat(length * 2) - length); - public static double3 pingpong(double3 x, double length) => length - math.abs(x.repeat(length * 2) - length); + public static float3 pingpong(float3 x, float3 length) => length - math.abs(x.repeat(length * 2) - length); + public static float3 pingpong(float3 x, float length) => length - math.abs(x.repeat(length * 2) - length); + public static float2 pingpong(float2 x, float2 length) => length - math.abs(x.repeat(length * 2) - length); + public static float2 pingpong(float2 x, float length) => length - math.abs(x.repeat(length * 2) - length); + public static float pingpong(float x, float length) => length - math.abs(x.repeat(length * 2) - length); + public static double4 pingpong(double4 x, double4 length) => length - math.abs(x.repeat(length * 2) - length); public static double4 pingpong(double4 x, double length) => length - math.abs(x.repeat(length * 2) - length); + public static double3 pingpong(double3 x, double3 length) => length - math.abs(x.repeat(length * 2) - length); + public static double3 pingpong(double3 x, double length) => length - math.abs(x.repeat(length * 2) - length); + public static double2 pingpong(double2 x, double2 length) => length - math.abs(x.repeat(length * 2) - length); + public static double2 pingpong(double2 x, double length) => length - math.abs(x.repeat(length * 2) - length); + public static double pingpong(double x, double length) => length - math.abs(x.repeat(length * 2) - length); + + // Pingpongs the value t between a and b + public static float4 pingpong(float4 a, float4 b, float4 t) => a+pingpong(t,b-a); + public static float4 pingpong(float4 a, float4 b, float t) => a+pingpong(t,b-a); + public static float3 pingpong(float3 a, float3 b, float3 t) => a+pingpong(t,b-a); + public static float3 pingpong(float3 a, float3 b, float t) => a+pingpong(t,b-a); + public static float2 pingpong(float2 a, float2 b, float2 t) => a+pingpong(t,b-a); + public static float2 pingpong(float2 a, float2 b, float t) => a+pingpong(t,b-a); + public static float pingpong(float a, float b, float t) => a+pingpong(t,b-a); + public static double4 pingpong(double4 a, double4 b, double4 t) => a+pingpong(t,b-a); + public static double4 pingpong(double4 a, double4 b, double t) => a+pingpong(t,b-a); + public static double3 pingpong(double3 a, double3 b, double3 t) => a+pingpong(t,b-a); + public static double3 pingpong(double3 a, double3 b, double t) => a+pingpong(t,b-a); + public static double2 pingpong(double2 a, double2 b, double2 t) => a+pingpong(t,b-a); + public static double2 pingpong(double2 a, double2 b, double t) => a+pingpong(t,b-a); + public static double pingpong(double a, double b, double t) => a+pingpong(t,b-a); + #endregion /// Sample a parabola trajectory diff --git a/Runtime/mathx.Mathf.translations.movetowards.cs b/Runtime/mathx.Mathf.translations.movetowards.cs index b62b5e2..133b665 100644 --- a/Runtime/mathx.Mathf.translations.movetowards.cs +++ b/Runtime/mathx.Mathf.translations.movetowards.cs @@ -1,4 +1,4 @@ -#region Header +#region Header // ** Copyright (C) 2023 Nicolas Reinhard, @LTMX. All rights reserved. // ** Github Profile: https://github.com/LTMX // ** Repository : https://github.com/LTMX/Unity.Mathematics-Extensions @@ -11,69 +11,69 @@ namespace Unity.Mathematics public partial class mathx { /// Calculate a position between the points specified by current and target, moving no farther than the distance specified by maxDistanceDelta + public static float4 movetowards(this float4 current, float4 target, float4 maxDistanceDelta) + { + var delta = target - current; + return math.mad(min(abs(delta),maxDistanceDelta),sign(delta),current); + } + /// public static float4 movetowards(this float4 current, float4 target, float maxDistanceDelta) { var delta = target - current; - var deltaLength = delta.lengthsq(); - if (deltaLength == 0 || maxDistanceDelta >= 0 && deltaLength <= maxDistanceDelta.sq()) - return target; - return (current + delta) / deltaLength.sqrt() * maxDistanceDelta; + var deltaLength = delta.length(); + return math.mad(min(deltaLength,maxDistanceDelta),sign(delta),current); } /// - public static float3 movetowards(this float3 current, float3 target, float maxDistanceDelta) + public static float4 movetowards(this Vector4 current, float4 target, float maxDistanceDelta) { - var delta = target - current; - var deltaLength = delta.lengthsq(); - if (deltaLength == 0 || maxDistanceDelta >= 0 && deltaLength <= maxDistanceDelta.sq()) - return target; - return (current + delta) / deltaLength.sqrt() * maxDistanceDelta; + return movetowards(current.asfloat(),target,maxDistanceDelta); } /// - public static float2 movetowards(this float2 current, float2 target, float maxDistanceDelta) + public static float3 movetowards(this float3 current, float3 target, float3 maxDistanceDelta) { var delta = target - current; - var deltaLength = delta.lengthsq(); - if (deltaLength == 0 || maxDistanceDelta >= 0 && deltaLength <= maxDistanceDelta.sq()) - return target; - return (current + delta) / deltaLength.sqrt() * maxDistanceDelta; + return math.mad(min(abs(delta),maxDistanceDelta),sign(delta),current); } /// - public static float movetowards(this float current, float target, float maxDistanceDelta) + public static float3 movetowards(this float3 current, float3 target, float maxDistanceDelta) { - var delta = target - current; - var deltaLength = delta.sq(); - if (deltaLength == 0 || maxDistanceDelta >= 0 && deltaLength <= maxDistanceDelta.sq()) - return target; - return (current + delta) / deltaLength.sqrt() * maxDistanceDelta; + return movetowards(current.asfloat(), target, maxDistanceDelta); } - - /// - public static float4 movetowards(this Vector4 current, float4 target, float maxDistanceDelta) + public static float2 movetowards(this float2 current, float2 target, float2 maxDistanceDelta) { - var delta = target - current.asfloat(); - var deltaLength = delta.lengthsq(); - if (deltaLength == 0 || maxDistanceDelta >= 0 && deltaLength <= maxDistanceDelta.sq()) - return target; - return (current.asfloat() + delta) / deltaLength.sqrt() * maxDistanceDelta; + var delta = target - current; + var deltaLength = delta.length(); + return math.mad(min(deltaLength,maxDistanceDelta),sign(delta),current); } /// public static float3 movetowards(this Vector3 current, float3 target, float maxDistanceDelta) { - var delta = target - current.asfloat(); - var deltaLength = delta.lengthsq(); - if (deltaLength == 0 || maxDistanceDelta >= 0 && deltaLength <= maxDistanceDelta.sq()) - return target; - return (current.asfloat() + delta) / deltaLength.sqrt() * maxDistanceDelta; + return movetowards(current.asfloat(), target, maxDistanceDelta); + } + /// + public static float2 movetowards(this float2 current, float2 target, float2 maxDistanceDelta) + { + var delta = target - current; + return math.mad(min(abs(delta),maxDistanceDelta),sign(delta),current); + } + /// + public static float2 movetowards(this float2 current, float2 target, float maxDistanceDelta) + { + var delta = target - current; + var deltaLength = delta.length(); + return math.mad(min(deltaLength,maxDistanceDelta),sign(delta),current); } /// public static float2 movetowards(this Vector2 current, float2 target, float maxDistanceDelta) { - var delta = target - current.asfloat(); - var deltaLength = delta.lengthsq(); - if (deltaLength == 0 || maxDistanceDelta >= 0 && deltaLength <= maxDistanceDelta.sq()) - return target; - return (current.asfloat() + delta) / deltaLength.sqrt() * maxDistanceDelta; + return movetowards(current.asfloat(), target, maxDistanceDelta); + } + /// + public static float movetowards(this float current, float target, float maxDistanceDelta) + { + var delta = target - current; + return math.mad(min(abs(delta),maxDistanceDelta),sign(delta),current); } } } \ No newline at end of file diff --git a/Runtime/mathx.common.float.cs b/Runtime/mathx.common.float.cs index 3908f73..b124782 100644 --- a/Runtime/mathx.common.float.cs +++ b/Runtime/mathx.common.float.cs @@ -235,7 +235,118 @@ public static partial class mathx [MethodImpl(IL)] public static float pow5(this float f) => f.sq().sq() * f; #endregion - + + #region arc + /// Returns the absolute version of sin(x) + [MethodImpl(IL)] public static float4 arc(this float4 x) => abs(sine(x)); + /// + [MethodImpl(IL)] public static float3 arc(this float3 x) => abs(sine(x)); + /// + [MethodImpl(IL)] public static float2 arc(this float2 x) => abs(sine(x)); + /// + [MethodImpl(IL)] public static float arc(this float x) => abs(sine(x)); + #endregion + + #region arch2 + /// Returns x multiplied by inv(x) + [MethodImpl(IL)] public static float4 arch2(float4 x) => x * inv(x); + /// + [MethodImpl(IL)] public static float3 arch2(float3 x) => x * inv(x); + /// + [MethodImpl(IL)] public static float2 arch2(float2 x) => x * inv(x); + /// + [MethodImpl(IL)] public static float arch2(float x) => x * inv(x); + #endregion + + #region clamp01 + /// Clamps a value between zero and one. + [MethodImpl(IL)] public static float4 clamp01(float4 value) => clamp(value,0,1); + /// + [MethodImpl(IL)] public static float3 clamp01(float3 value) => clamp(value,0,1); + /// + [MethodImpl(IL)] public static float2 clamp01(float2 value) => clamp(value,0,1); + /// + [MethodImpl(IL)] public static float clamp01(float value) => clamp(value,0,1); + #endregion + + #region normal + /// Remaps and clamps a value between zero and one. + [MethodImpl(IL)] public static float4 normal(float4 value, float4 zero, float4 one) => clamp01(math.unlerp(zero, one, value)); + /// + [MethodImpl(IL)] public static float4 normal(float4 value, float4 zero, float one) => clamp01(math.unlerp(zero, one, value)); + /// + [MethodImpl(IL)] public static float4 normal(float4 value, float zero, float4 one) => clamp01(math.unlerp(zero, one, value)); + /// + [MethodImpl(IL)] public static float4 normal(float4 value, float zero, float one) => clamp01(math.unlerp(zero, one, value)); + /// + [MethodImpl(IL)] public static float3 normal(float3 value, float3 zero, float3 one) => clamp01(math.unlerp(zero, one, value)); + /// + [MethodImpl(IL)] public static float3 normal(float3 value, float3 zero, float one) => clamp01(math.unlerp(zero, one, value)); + /// + [MethodImpl(IL)] public static float3 normal(float3 value, float zero, float3 one) => clamp01(math.unlerp(zero, one, value)); + /// + [MethodImpl(IL)] public static float3 normal(float3 value, float zero, float one) => clamp01(math.unlerp(zero, one, value)); + /// + [MethodImpl(IL)] public static float2 normal(float2 value, float2 zero, float2 one) => clamp01(math.unlerp(zero, one, value)); + /// + [MethodImpl(IL)] public static float2 normal(float2 value, float2 zero, float one) => clamp01(math.unlerp(zero, one, value)); + /// + [MethodImpl(IL)] public static float2 normal(float2 value, float zero, float2 one) => clamp01(math.unlerp(zero, one, value)); + /// + [MethodImpl(IL)] public static float2 normal(float2 value, float zero, float one) => clamp01(math.unlerp(zero, one, value)); + /// + [MethodImpl(IL)] public static float normal(float value, float zero, float one) => clamp01(math.unlerp(zero, one, value)); + #endregion + + #region sine + /// Returns the sin of x multiplied by PI. + [MethodImpl(IL)] public static float4 sine(float4 x) => sin(x*PI); + /// + [MethodImpl(IL)] public static float3 sine(float3 x) => sin(x*PI); + /// + [MethodImpl(IL)] public static float2 sine(float2 x) => sin(x*PI); + /// + [MethodImpl(IL)] public static float sine(float x) => sin(x*PI); + #endregion + + #region snap + /// Rounds a value to the closest multiplier of snap. + [MethodImpl(IL)] public static float4 snap(float4 x, float4 snap) => round(x / snap) * snap; + /// + [MethodImpl(IL)] public static float4 snap(float4 x, float snap) => round(x / snap) * snap; + /// + [MethodImpl(IL)] public static float3 snap(float3 x, float3 snap) => round(x / snap) * snap; + /// + [MethodImpl(IL)] public static float3 snap(float3 x, float snap) => round(x / snap) * snap; + /// + [MethodImpl(IL)] public static float2 snap(float2 x, float2 snap) => round(x / snap) * snap; + /// + [MethodImpl(IL)] public static float2 snap(float2 x, float snap) => round(x / snap) * snap; + /// + [MethodImpl(IL)] public static float snap(float x, float snap) => round(x / snap) * snap; + #endregion + + #region bitwave + /// Samples a square wave that goes between 0 and 1. + [MethodImpl(IL)] public static float4 bitwave(float4 x) => floor(math.fmod(x, 2)); + /// + [MethodImpl(IL)] public static float3 bitwave(float3 x) => floor(math.fmod(x, 2)); + /// + [MethodImpl(IL)] public static float2 bitwave(float2 x) => floor(math.fmod(x, 2)); + /// + [MethodImpl(IL)] public static float bitwave(float x) => floor(math.fmod(x, 2)); + #endregion + + #region triwave + /// Samples a triangle wave between +0.5f and -0.5f. + [MethodImpl(IL)] public static float4 triwave(float4 x) => abs(frac(x) - 0.5f); + /// + [MethodImpl(IL)] public static float3 triwave(float3 x) => abs(frac(x) - 0.5f); + /// + [MethodImpl(IL)] public static float2 triwave(float2 x) => abs(frac(x) - 0.5f); + /// + [MethodImpl(IL)] public static float triwave(float x) => abs(frac(x) - 0.5f); + #endregion #region Component-wise Math diff --git a/Runtime/mathx.interpolation.common.cs b/Runtime/mathx.interpolation.common.cs index 474db33..5333fdf 100644 --- a/Runtime/mathx.interpolation.common.cs +++ b/Runtime/mathx.interpolation.common.cs @@ -1,4 +1,4 @@ -#region Header +#region Header // ** Copyright (C) 2023 Nicolas Reinhard, @LTMX. All rights reserved. // ** Github Profile: https://github.com/LTMX @@ -382,5 +382,72 @@ public static partial class mathx public static float3 smin_N_factor(this float3 t, float3 a, float3 b, float3 n, out float3 factor) => f3(t.x.smin_N_factor(a.x, b.x, n.x, out factor.x), t.y.smin_N_factor(a.y, b.y, n.y, out factor.y), t.z.smin_N_factor(a.z, b.z, n.z, out factor.z)); public static float4 smin_N_factor(this float4 t, float4 a, float4 b, float4 n, out float4 factor) => f4(t.x.smin_N_factor(a.x, b.x, n.x, out factor.x), t.y.smin_N_factor(a.y, b.y, n.y, out factor.y), t.z.smin_N_factor(a.z, b.z, n.z, out factor.z), t.w.smin_N_factor(a.w, b.w, n.w, out factor.w)); + #region mix + // Returns (1-weightB)*a + weightB*b. + [MethodImpl(IL)] public static float4 mix(float4 a, float4 b, float4 weightB, float4 t) => math.mad(weightB,b,math.mad(-weightB,a,a)); + /// + [MethodImpl(IL)] public static float4 mix(float4 a, float4 b, float4 weightB, float t) => math.mad(weightB,b,math.mad(-weightB,a,a)); + /// + [MethodImpl(IL)] public static float4 mix(float4 a, float4 b, float weightB, float4 t) => math.mad(weightB,b,math.mad(-weightB,a,a)); + /// + [MethodImpl(IL)] public static float4 mix(float4 a, float4 b, float weightB, float t) => math.mad(weightB,b,math.mad(-weightB,a,a)); + /// + [MethodImpl(IL)] public static float3 mix(float3 a, float3 b, float3 weightB, float3 t) => math.mad(weightB,b,math.mad(-weightB,a,a)); + /// + [MethodImpl(IL)] public static float3 mix(float3 a, float3 b, float3 weightB, float t) => math.mad(weightB,b,math.mad(-weightB,a,a)); + /// + [MethodImpl(IL)] public static float3 mix(float3 a, float3 b, float weightB, float3 t) => math.mad(weightB,b,math.mad(-weightB,a,a)); + /// + [MethodImpl(IL)] public static float3 mix(float3 a, float3 b, float weightB, float t) => math.mad(weightB,b,math.mad(-weightB,a,a)); + /// + [MethodImpl(IL)] public static float2 mix(float2 a, float2 b, float2 weightB, float2 t) => math.mad(weightB,b,math.mad(-weightB,a,a)); + /// + [MethodImpl(IL)] public static float2 mix(float2 a, float2 b, float2 weightB, float t) => math.mad(weightB,b,math.mad(-weightB,a,a)); + /// + [MethodImpl(IL)] public static float2 mix(float2 a, float2 b, float weightB, float2 t) => math.mad(weightB,b,math.mad(-weightB,a,a)); + /// + [MethodImpl(IL)] public static float2 mix(float2 a, float2 b, float weightB, float t) => math.mad(weightB,b,math.mad(-weightB,a,a)); + /// + [MethodImpl(IL)] public static float mix(float a, float b, float weightB, float t) => math.mad(weightB,b,math.mad(-weightB,a,a)); + #endregion + + #region smoothstart + // Returns a smoother version of the value at the start. + [MethodImpl(IL)] public static float4 smoothstart(float4 t, int n) => pow(t,n); + /// + [MethodImpl(IL)] public static float3 smoothstart(float3 t, int n) => pow(t,n); + /// + [MethodImpl(IL)] public static float2 smoothstart(float2 t, int n) => pow(t,n); + /// + [MethodImpl(IL)] public static float smoothstart(float t, int n) => pow(t,n); + #endregion + + #region smoothstop + // Returns a smoother version of the value at the end. + [MethodImpl(IL)] public static float4 smoothstop(float4 t, int n) => inv(pow(inv(t), n)); + /// + [MethodImpl(IL)] public static float3 smoothstop(float3 t, int n) => inv(pow(inv(t), n)); + /// + [MethodImpl(IL)] public static float2 smoothstop(float2 t, int n) => inv(pow(inv(t), n)); + /// + [MethodImpl(IL)] public static float smoothstop(float t, int n) => inv(pow(inv(t), n)); + #endregion + + #region xfade (crossfade) + // Fades between values a and b. + [MethodImpl(IL)] public static float4 xfade(float4 a, float4 b, float4 t) => math.mad(b-a,t,a); + /// + [MethodImpl(IL)] public static float4 xfade(float4 a, float4 b, float t) => math.mad(b-a,t,a); + /// + [MethodImpl(IL)] public static float3 xfade(float3 a, float3 b, float3 t) => math.mad(b-a,t,a); + /// + [MethodImpl(IL)] public static float3 xfade(float3 a, float3 b, float t) => math.mad(b-a,t,a); + /// + [MethodImpl(IL)] public static float2 xfade(float2 a, float2 b, float2 t) => math.mad(b-a,t,a); + /// + [MethodImpl(IL)] public static float2 xfade(float2 a, float2 b, float t) => math.mad(b-a,t,a); + /// + [MethodImpl(IL)] public static float xfade(float a, float b, float t) => math.mad(b-a,t,a); + #endregion } } \ No newline at end of file diff --git a/Runtime/mathx.logic.bool.cs b/Runtime/mathx.logic.bool.cs index 58f3f42..06b5591 100644 --- a/Runtime/mathx.logic.bool.cs +++ b/Runtime/mathx.logic.bool.cs @@ -87,10 +87,12 @@ public static partial class mathx [MethodImpl(INLINE)] public static bool approx(this float a, float b) => (b - a).abs() < (1E-06f * a.abs().max(b.abs())).max(EPSILON * 8); /// Compares two floating point values and returns true if they are similar. [MethodImpl(INLINE)] public static bool approx(this double a, double b) => (b - a).abs() < (1E-06f * a.abs().max(b.abs())).max(EPSILON_DBL * 8); + /// Compares two floating point values and returns true if they are within a certain distance of each other (tolerance) + [MethodImpl(INLINE)] public static bool approx(this float a, float b, float tolerance) => abs(a - b) <= abs(tolerance); + /// Compares two floating point values and returns true if they are within a certain distance of each other (tolerance) + [MethodImpl(INLINE)] public static bool approx(this double a, double b, double tolerance) => abs(a - b) <= abs(tolerance); // Odd & Even ---------------------------------------------- - - } }