123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346 |
- using System;
- using UnityEngine;
- public class MathCM
- {
- public static float calcPointLineDist(ref Vector3 p, ref MathCM.Line l, out Vector3 h, out float t)
- {
- float sqrMagnitude = l.v.sqrMagnitude;
- t = 0f;
- if (sqrMagnitude > 0f)
- {
- t = Vector3.Dot(l.v, p - l.s) / sqrMagnitude;
- }
- h = l.s + t * l.v;
- return (h - p).magnitude;
- }
- public static bool isSharpAngle(ref Vector3 p1, ref Vector3 p2, ref Vector3 p3)
- {
- return Vector3.Dot(p1 - p2, p3 - p2) >= 0f;
- }
- public static float calcPointSegmentDist(ref Vector3 p, ref MathCM.Segment seg, out Vector3 h, out float t)
- {
- Vector3 e = seg.e;
- MathCM.Line line = new MathCM.Line(seg.s, e);
- float result = MathCM.calcPointLineDist(ref p, ref line, out h, out t);
- if (!MathCM.isSharpAngle(ref p, ref seg.s, ref e))
- {
- h = seg.s;
- return (seg.s - p).magnitude;
- }
- if (!MathCM.isSharpAngle(ref p, ref e, ref seg.s))
- {
- h = e;
- return (e - p).magnitude;
- }
- return result;
- }
- public static bool isParallel(ref Vector3 v1, ref Vector3 r)
- {
- float sqrMagnitude = Vector3.Cross(v1, r).sqrMagnitude;
- return -MathCM._OX_EPSILON_ < sqrMagnitude && sqrMagnitude < MathCM._OX_EPSILON_;
- }
- public static float calcLineLineDist(MathCM.Line l1, MathCM.Line l2, out Vector3 p1, out Vector3 p2, out float t1, out float t2)
- {
- if (MathCM.isParallel(ref l1.v, ref l2.v))
- {
- float result = MathCM.calcPointLineDist(ref l1.s, ref l2, out p2, out t2);
- p1 = l1.s;
- t1 = 0f;
- return result;
- }
- float num = Vector3.Dot(l1.v, l2.v);
- float sqrMagnitude = l1.v.sqrMagnitude;
- float sqrMagnitude2 = l2.v.sqrMagnitude;
- Vector3 rhs = l1.s - l2.s;
- t1 = (num * Vector3.Dot(l2.v, rhs) - sqrMagnitude2 * Vector3.Dot(l1.v, rhs)) / (sqrMagnitude * sqrMagnitude2 - num * num);
- p1 = l1.getPoint(t1);
- t2 = Vector3.Dot(l2.v, p1 - l2.s) / sqrMagnitude2;
- p2 = l2.getPoint(t2);
- return (p2 - p1).magnitude;
- }
- public static float calcLineLineDistNoParallelCheck(ref MathCM.Segment l1, ref MathCM.Segment l2, out Vector3 p1, out Vector3 p2, out float t1, out float t2)
- {
- float num = Vector3.Dot(l1.v, l2.v);
- float sqrMagnitude = l1.v.sqrMagnitude;
- float sqrMagnitude2 = l2.v.sqrMagnitude;
- Vector3 rhs = l1.s - l2.s;
- t1 = (num * Vector3.Dot(l2.v, rhs) - sqrMagnitude2 * Vector3.Dot(l1.v, rhs)) / (sqrMagnitude * sqrMagnitude2 - num * num);
- p1 = l1.getPoint(t1);
- t2 = Vector3.Dot(l2.v, p1 - l2.s) / sqrMagnitude2;
- p2 = l2.getPoint(t2);
- return (p2 - p1).magnitude;
- }
- public static float calcSegmentSegmentDist(ref MathCM.Segment s1, ref MathCM.Segment s2, out Vector3 p1, out Vector3 p2, out float t1, out float t2)
- {
- if (s1.v.sqrMagnitude < MathCM._OX_EPSILON_)
- {
- float result;
- if (s2.v.sqrMagnitude < MathCM._OX_EPSILON_)
- {
- result = (s2.s - s1.s).magnitude;
- p1 = s1.s;
- p2 = s2.s;
- t1 = (t2 = 0f);
- return result;
- }
- result = MathCM.calcPointSegmentDist(ref s1.s, ref s2, out p2, out t2);
- p1 = s1.s;
- t1 = 0f;
- t2 = Mathf.Clamp01(t2);
- return result;
- }
- else
- {
- float result;
- if (s2.v.sqrMagnitude < MathCM._OX_EPSILON_)
- {
- result = MathCM.calcPointSegmentDist(ref s2.s, ref s1, out p1, out t1);
- p2 = s2.s;
- t1 = Mathf.Clamp01(t1);
- t2 = 0f;
- return result;
- }
- if (MathCM.isParallel(ref s1.v, ref s2.v))
- {
- t1 = 0f;
- p1 = s1.s;
- result = MathCM.calcPointSegmentDist(ref s1.s, ref s2, out p2, out t2);
- if (0f <= t2 && t2 <= 1f)
- {
- return result;
- }
- }
- else
- {
- result = MathCM.calcLineLineDistNoParallelCheck(ref s1, ref s2, out p1, out p2, out t1, out t2);
- if (0f <= t1 && t1 <= 1f && 0f <= t2 && t2 <= 1f)
- {
- return result;
- }
- }
- t1 = Mathf.Clamp01(t1);
- p1 = s1.getPoint(t1);
- result = MathCM.calcPointSegmentDist(ref p1, ref s2, out p2, out t2);
- if (0f <= t2 && t2 <= 1f)
- {
- return result;
- }
- t2 = Mathf.Clamp01(t2);
- p2 = s2.getPoint(t2);
- result = MathCM.calcPointSegmentDist(ref p2, ref s1, out p1, out t1);
- if (0f <= t1 && t1 <= 1f)
- {
- return result;
- }
- t1 = Mathf.Clamp01(t1);
- p1 = s1.getPoint(t1);
- return (p2 - p1).magnitude;
- }
- }
- public static int hittest_point_polygon_3d(Vector3 A, Vector3 B, Vector3 C, Vector3 P)
- {
- Vector3 lhs = B - A;
- Vector3 rhs = P - B;
- Vector3 lhs2 = C - B;
- Vector3 rhs2 = P - C;
- Vector3 lhs3 = A - C;
- Vector3 rhs3 = P - A;
- Vector3 lhs4 = Vector3.Cross(lhs, rhs);
- Vector3 rhs4 = Vector3.Cross(lhs2, rhs2);
- Vector3 rhs5 = Vector3.Cross(lhs3, rhs3);
- double num = (double)Vector3.Dot(lhs4, rhs4);
- double num2 = (double)Vector3.Dot(lhs4, rhs5);
- if (num > 0.0 && num2 > 0.0)
- {
- return 0;
- }
- return 1;
- }
- public static bool TriangleRayIntersect(Vector3 Orig, Vector3 dir, Vector3 v0, Vector3 v1, Vector3 v2, ref float pRetT, ref float pRetU, ref float pRetV)
- {
- Vector3 vector = v1 - v0;
- Vector3 vector2 = v2 - v0;
- Vector3 rhs = Vector3.Cross(dir, vector2);
- float num = Vector3.Dot(vector, rhs);
- float num2;
- Vector3 rhs2;
- float num3;
- if ((double)num > 0.001)
- {
- Vector3 lhs = Orig - v0;
- num2 = Vector3.Dot(lhs, rhs);
- if (num2 < 0f || num2 > num)
- {
- return false;
- }
- rhs2 = Vector3.Cross(lhs, vector);
- num3 = Vector3.Dot(dir, rhs2);
- if ((double)num3 < 0.0 || num2 + num3 > num)
- {
- return false;
- }
- }
- else
- {
- if ((double)num >= -0.001)
- {
- return false;
- }
- Vector3 lhs = Orig - v0;
- num2 = Vector3.Dot(lhs, rhs);
- if ((double)num2 > 0.0 || num2 < num)
- {
- return false;
- }
- rhs2 = Vector3.Cross(lhs, vector);
- num3 = Vector3.Dot(dir, rhs2);
- if ((double)num3 > 0.0 || num2 + num3 < num)
- {
- return false;
- }
- }
- float num4 = 1f / num;
- float num5 = Vector3.Dot(vector2, rhs2);
- num5 *= num4;
- num2 *= num4;
- num3 *= num4;
- pRetT = num5;
- pRetU = num2;
- pRetV = num3;
- return true;
- }
- public static bool TriangleRayIntersect(Vector3 tvec, Vector3 dir, Vector3 v0, Vector3 e1, Vector3 e2, ref float pRetT)
- {
- Vector3 rhs = Vector3.Cross(dir, e2);
- float num = Vector3.Dot(e1, rhs);
- Vector3 rhs2;
- if ((double)num > 0.001)
- {
- float num2 = Vector3.Dot(tvec, rhs);
- if (num2 < 0f || num2 > num)
- {
- return false;
- }
- rhs2 = Vector3.Cross(tvec, e1);
- float num3 = Vector3.Dot(dir, rhs2);
- if ((double)num3 < 0.0 || num2 + num3 > num)
- {
- return false;
- }
- }
- else
- {
- if ((double)num >= -0.001)
- {
- return false;
- }
- float num2 = Vector3.Dot(tvec, rhs);
- if ((double)num2 > 0.0 || num2 < num)
- {
- return false;
- }
- rhs2 = Vector3.Cross(tvec, e1);
- float num3 = Vector3.Dot(dir, rhs2);
- if ((double)num3 > 0.0 || num2 + num3 < num)
- {
- return false;
- }
- }
- float num4 = 1f / num;
- float num5 = Vector3.Dot(e2, rhs2);
- num5 *= num4;
- pRetT = num5;
- return true;
- }
- public static bool TriangleLineIntersect(Vector3 src, Vector3 dest, Vector3 tvec, Vector3 v0, Vector3 e1, Vector3 e2, ref float pRetT)
- {
- Vector3 vector = dest - src;
- if (MathCM.TriangleRayIntersect(tvec, vector.normalized, v0, e1, e2, ref pRetT))
- {
- float num = Mathf.Abs(pRetT);
- if (0f <= pRetT && num * num <= vector.sqrMagnitude)
- {
- return true;
- }
- }
- return false;
- }
- public static bool SphireRayIntersect(Vector3 orig, Vector3 dir, Vector3 center, float r, ref Vector3 intersect)
- {
- Vector3 vector = orig - center;
- float num = Vector3.Dot(vector, dir);
- float num2 = Vector3.Dot(vector, vector) - r * r;
- if ((double)num2 > 0.0 && (double)num > 0.0)
- {
- return false;
- }
- float num3 = num * num - num2;
- if ((double)num3 < 0.0)
- {
- return false;
- }
- float num4 = -num - Mathf.Sqrt(num3);
- if ((double)num4 < 0.0)
- {
- return false;
- }
- intersect = orig + num4 * dir;
- return true;
- }
- private static float _OX_EPSILON_ = 1E-06f;
- public struct Line
- {
- public Line(Vector3 fs, Vector3 fe)
- {
- this.s = fs;
- this.e = fe;
- this.v = fe - fs;
- }
- public Vector3 getPoint(float t)
- {
- return this.s + t * this.v;
- }
- public Vector3 s;
- public Vector3 e;
- public Vector3 v;
- }
- public struct Segment
- {
- public Segment(Vector3 fs, Vector3 fe)
- {
- this.s = fs;
- this.e = fe;
- this.v = fe - fs;
- }
- public Vector3 getPoint(float t)
- {
- return this.s + t * this.v;
- }
- public Vector3 s;
- public Vector3 e;
- public Vector3 v;
- }
- }
|