using UnityEngine; /// /// 一个点和一个方向可以确定一条射线 /// public struct Ray3D { public Vector3 position; public Vector3 direction; public Ray3D(Vector3 p, Vector3 d) { position = p; direction = d; } public static bool IsRayIntersectionPlane(Ray3D ray, Plane3D plane, ref float t) { float _a = plane.normal.x * plane.point.x + plane.normal.y * plane.point.y + plane.normal.z * plane.point.z; float _b = plane.normal.x * ray.position.x + plane.normal.y * ray.position.y + plane.normal.z * ray.position.z; float _c = plane.normal.x * ray.direction.x + plane.normal.y * ray.direction.y + plane.normal.z * ray.direction.z; t = (_a - _b) / _c; return t >= 0; } public static bool IsRayIntersectQuadrAngle(Ray3D ray, QuadrAngle3D quadrAngle, ref float t, ref float u, ref float v) { for (int i = 0; i < quadrAngle.triangles.Length; ++i) { if (IsRayIntersectTriangle(ray, quadrAngle.triangles[i], ref t, ref u, ref v)) { return true; } } return false; } public static bool IsRayIntersectTriangle(Ray3D ray, Vector3 p1, Vector3 p2, Vector3 p3, ref float t, ref float u, ref float v) { Vector3 _e1 = p2 - p1; Vector3 _e2 = p3 - p1; Vector3 _p = Vector3.Cross(ray.direction, _e2); float _determinant = Vector3.Dot(_e1, _p); Vector3 _T; if (_determinant > 0) { _T = ray.position - p1; } else { _T = p1 - ray.position; _determinant = -_determinant; } if (_determinant < 0.0001f) { return false; } u = Vector3.Dot(_T, _p); if (u < 0 || u > _determinant) { return false; } Vector3 _q = Vector3.Cross(_T, _e1); v = Vector3.Dot(ray.direction, _q); if (v < 0 || u + v > _determinant) { return false; } t = Vector3.Dot(_e2, _q); float _fInvDet = 1.0f / _determinant; t *= _fInvDet; u *= _fInvDet; v *= _fInvDet; return true; } public static bool IsRayIntersectTriangle(Ray3D ray, Triangle3D triangle, ref float t, ref float u, ref float v) { return IsRayIntersectTriangle(ray, triangle.point1, triangle.point2, triangle.point3, ref t, ref u, ref v); } }