You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

163 lines
4.5 KiB
C#

/******************************************************************************/
/*
Project - MudBun
Publisher - Long Bunny Labs
http://LongBunnyLabs.com
Author - Ming-Lun "Allen" Chou
http://AllenChou.net
*/
/******************************************************************************/
#if MUDBUN_BURST
using Unity.Burst;
#endif
using UnityEngine;
namespace MudBun
{
public static class VectorUtil
{
private static Vector3 s_invalid = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
public static Vector3 Invalid => s_invalid;
public static bool IsValid(Vector3 v) { return (v - s_invalid).sqrMagnitude > MathUtil.Epsilon; }
public static Vector3 Saturate(Vector3 v)
{
return new Vector3(MathUtil.Saturate(v.x), MathUtil.Saturate(v.y), MathUtil.Saturate(v.z));
}
public static Vector3 CompMul(Vector3 a, Vector3 b)
{
return new Vector3(a.x * b.x, a.y * b.y, a.z * b.z);
}
public static Vector3 CompDiv(Vector3 a, Vector3 b)
{
return new Vector3(a.x / b.x, a.y / b.y, a.z / b.z);
}
public static float MinComp(Vector3 v)
{
return Mathf.Min(v.x, Mathf.Min(v.y, v.z));
}
public static float MaxComp(Vector3 v)
{
return Mathf.Max(v.x, Mathf.Max(v.y, v.z));
}
public static Vector3 Rotate2D(Vector3 v, float deg)
{
Vector3 results = v;
float cos = Mathf.Cos(MathUtil.Deg2Rad * deg);
float sin = Mathf.Sin(MathUtil.Deg2Rad * deg);
results.x = cos * v.x - sin * v.y;
results.y = sin * v.x + cos * v.y;
return results;
}
public static Vector3 NormalizeSafe(Vector3 v, Vector3 fallback, float epsilon = 1e-9f)
{
return
v.sqrMagnitude > epsilon
? v.normalized
: fallback;
}
// Returns a vector orthogonal to given vector.
// If the given vector is a unit vector, the returned vector will also be a unit vector.
public static Vector3 FindOrthogonal(Vector3 v)
{
if (v.x >= MathUtil.Sqrt3Inv)
return new Vector3(v.y, -v.x, 0.0f);
else
return new Vector3(0.0f, v.z, -v.y);
}
// Yields two extra vectors that form an orthogonal basis with the given vector.
// If the given vector is a unit vector, the returned vectors will also be unit vectors.
public static void FormOrthonormalBasis(Vector3 v, out Vector3 a, out Vector3 b)
{
a = FindOrthogonal(v).normalized;
b = Vector3.Cross(v, a);
}
public static Vector3 ClampLength(Vector3 v, float minLen, float maxLen)
{
float lenSqr = v.sqrMagnitude;
if (lenSqr < MathUtil.Epsilon)
return v;
float len = Mathf.Sqrt(lenSqr);
return v * (Mathf.Clamp(len, minLen, maxLen) / len);
}
// Both vectors must be unit vectors.
public static Vector3 Slerp(Vector3 a, Vector3 b, float t)
{
float dot = Vector3.Dot(a, b);
if (dot > 0.99999f)
{
// singularity: two vectors point in the same direction
return Vector3.Lerp(a, b, t);
}
else if (dot < -0.99999f)
{
// singularity: two vectors point in the opposite direction
Vector3 axis = FindOrthogonal(a);
return Quaternion.AngleAxis(180.0f * t, axis) * a;
}
float rad = MathUtil.AcosSafe(dot);
return (Mathf.Sin((1.0f - t) * rad) * a + Mathf.Sin(t * rad) * b) / Mathf.Sin(rad);
}
public static Vector3 BezierQuad(Vector3 a, Vector3 b, Vector3 controlPoint, float t)
{
return Vector3.Lerp(Vector3.Lerp(a, controlPoint, t), Vector3.Lerp(controlPoint, b, t), t);
}
public static Vector3 CatmullRom(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
{
float tt = t * t;
return
0.5f
* ((2.0f * p1)
+ (-p0 + p2) * t
+ (2.0f * p0 - 5.0f * p1 + 4.0f * p2 - p3) * tt
+ (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * tt * t
);
}
public static Vector3 Abs(Vector3 v)
{
return new Vector3(Mathf.Abs(v.x), Mathf.Abs(v.y), Mathf.Abs(v.z));
}
public static Vector3 Min(Vector3 a, Vector3 b)
{
return new Vector3(Mathf.Min(a.x, b.x), Mathf.Min(a.y, b.y), Mathf.Min(a.z, b.z));
}
public static Vector3 Max(Vector3 a, Vector3 b)
{
return new Vector3(Mathf.Max(a.x, b.x), Mathf.Max(a.y, b.y), Mathf.Max(a.z, b.z));
}
public static float GetComopnent(Vector3 v, int i)
{
switch (i)
{
case 0: return v.x;
case 1: return v.y;
case 2: return v.z;
}
return float.MinValue;
}
}
}