mirror of
https://github.com/GTA-ASM/SanAndreasUnity
synced 2024-11-23 20:43:04 +00:00
159 lines
No EOL
4.8 KiB
C#
159 lines
No EOL
4.8 KiB
C#
namespace UnityEngine
|
|
{
|
|
public static class MathExtension
|
|
{
|
|
public static float SnapToCenter(this float val, float snapValue)
|
|
{
|
|
if (snapValue == 0) return val;
|
|
|
|
return Mathf.Round((val / snapValue) + 0.5f) * snapValue - 0.5f;
|
|
}
|
|
|
|
public static float SnapToEdge(this float val, float snapValue)
|
|
{
|
|
if (snapValue == 0) return val;
|
|
|
|
return Mathf.Round(val / snapValue) * snapValue;
|
|
}
|
|
|
|
public static Vector3 SnapToCenter(this Vector2 val, float snapValue)
|
|
{
|
|
return new Vector2(val.x.SnapToCenter(snapValue), val.y.SnapToCenter(snapValue));
|
|
}
|
|
|
|
public static Vector3 SnapToEdge(this Vector2 val, float snapValue)
|
|
{
|
|
return new Vector2(val.x.SnapToEdge(snapValue), val.y.SnapToEdge(snapValue));
|
|
}
|
|
|
|
public static Vector3 SnapToCenter(this Vector3 val, float snapValue)
|
|
{
|
|
return new Vector3(val.x.SnapToCenter(snapValue), val.y.SnapToCenter(snapValue), val.z.SnapToCenter(snapValue));
|
|
}
|
|
|
|
public static Vector3 SnapToEdge(this Vector3 val, float snapValue)
|
|
{
|
|
return new Vector3(val.x.SnapToEdge(snapValue), val.y.SnapToEdge(snapValue), val.z.SnapToEdge(snapValue));
|
|
}
|
|
|
|
public static Vector3 ToVector3XZ(this Vector2 val)
|
|
{
|
|
return new Vector3(val.x, 0.0f, val.y);
|
|
}
|
|
|
|
public static float ClosestPointDistance(this Ray val, Vector3 point)
|
|
{
|
|
return Vector3.Dot(point - val.origin, val.direction);
|
|
}
|
|
|
|
public static Vector3 ClosestPoint(this Ray val, Vector3 point)
|
|
{
|
|
return val.GetPoint(val.ClosestPointDistance(point));
|
|
}
|
|
|
|
public static float ClosestRayPointDistance(this Ray val, Ray ray)
|
|
{
|
|
Vector3 v0 = val.origin;
|
|
Vector3 v1 = val.direction;
|
|
Vector3 v2 = ray.origin;
|
|
Vector3 v3 = ray.direction;
|
|
Vector3 v4 = v0 - v2;
|
|
|
|
float d0 = 0.0f;
|
|
float d1 = 0.0f;
|
|
|
|
float dv4v3 = Vector3.Dot(v4, v3);
|
|
float dv3v1 = Vector3.Dot(v3, v1);
|
|
float dv3v3 = Vector3.Dot(v3, v3);
|
|
float dv4v1 = Vector3.Dot(v4, v1);
|
|
float dv1v1 = Vector3.Dot(v1, v1);
|
|
|
|
float denom = dv1v1 * dv3v3 - dv3v1 * dv3v1;
|
|
|
|
if (Mathf.Abs(denom) > Mathf.Epsilon)
|
|
{
|
|
float numer = dv4v3 * dv3v1 - dv4v1 * dv3v3;
|
|
d0 = numer / denom;
|
|
}
|
|
else
|
|
{
|
|
d0 = 0.0f;
|
|
}
|
|
|
|
d1 = (dv4v3 + d0 * dv3v1) / dv3v3;
|
|
|
|
if (d1 >= 0.0f)
|
|
{
|
|
return d0;
|
|
}
|
|
else
|
|
{
|
|
d1 = 0.0f;
|
|
|
|
return val.ClosestPointDistance(ray.origin);
|
|
}
|
|
}
|
|
|
|
public static Vector3 ClosestRayPoint(this Ray val, Ray ray)
|
|
{
|
|
return val.GetPoint(val.ClosestRayPointDistance(ray));
|
|
}
|
|
|
|
public static int Mod(this int val, int mod)
|
|
{
|
|
int r = val % mod;
|
|
|
|
return r < 0 ? val + mod : r;
|
|
}
|
|
|
|
public static bool PlaneTest(this Ray ray, Vector3 planeCenter, Quaternion planeRot, Vector2 planeSize, out Vector3 hitPosition, float gridSize = 0.0f, bool edge = true)
|
|
{
|
|
Plane plane = new Plane(planeRot * Vector3.up, planeCenter);
|
|
|
|
hitPosition = Vector3.zero;
|
|
float hitDistance = 0.0f;
|
|
|
|
if (!plane.Raycast(ray, out hitDistance))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
hitPosition = ray.origin + ray.direction * hitDistance;
|
|
|
|
Vector3 hitOffset = hitPosition - planeCenter;
|
|
|
|
float distanceLf = Vector3.Dot(hitOffset, planeRot * Vector3.left);
|
|
float distanceUp = Vector3.Dot(hitOffset, planeRot * Vector3.forward);
|
|
|
|
if (gridSize > 0.0f)
|
|
{
|
|
if (edge)
|
|
{
|
|
distanceLf = distanceLf.SnapToEdge(gridSize);
|
|
distanceUp = distanceUp.SnapToEdge(gridSize);
|
|
}
|
|
else
|
|
{
|
|
distanceLf = distanceLf.SnapToCenter(gridSize);
|
|
distanceUp = distanceUp.SnapToCenter(gridSize);
|
|
}
|
|
}
|
|
|
|
hitPosition = planeCenter;
|
|
hitPosition += (planeRot * Vector3.left) * distanceLf;
|
|
hitPosition += (planeRot * Vector3.forward) * distanceUp;
|
|
|
|
return true;
|
|
}
|
|
|
|
public static float NormalizeAngle(this float ang)
|
|
{
|
|
return ang - Mathf.Floor((ang + 180f) / 360f) * 360f;
|
|
}
|
|
|
|
public static float AngleDiff(this float ang, float other)
|
|
{
|
|
return (other - ang).NormalizeAngle();
|
|
}
|
|
}
|
|
} |