Exemple #1
0
        /// <summary>
        /// Test single triangle given ray in same coordinate system as the vertices and normal.
        /// </summary>
        /// <param name="ray">Ray in same coordinate system as the vertices and normal.</param>
        /// <param name="rayLength">Length of the ray.</param>
        /// <param name="triangleIndex">Triangle index of current triangle.</param>
        /// <param name="v1">First vertex.</param>
        /// <param name="v2">Second vertex.</param>
        /// <param name="v3">Third vertex.</param>
        /// <param name="normal">Normal of the triangle.</param>
        /// <returns>Local result of test.</returns>
        public static TriangleTestResult TestTriangle(Ray ray, float rayLength, int triangleIndex, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 normal)
        {
            TriangleTestResult result = new TriangleTestResult()
            {
                Normal = normal, TriangleIndex = triangleIndex
            };

            result.Hit = IntersectRayTriangle(ray, rayLength, v1, v2, v3, normal, ref result.PointInTriangle, ref result.Time);
            return(result);
        }
Exemple #2
0
        /// <summary>
        /// Test all triangles in a mesh to find the first triangle that intersects the ray.
        /// </summary>
        /// <param name="worldRay">Ray given in world coordinates (e.g., HandleUtility.GUIPointToWorldRay( Event.current.mousePosition )).</param>
        /// <param name="rayLength">Length of the ray.</param>
        /// <param name="mesh">The mesh.</param>
        /// <param name="parent">Parent game object that transforms the mesh.</param>
        /// <returns>Result of the test.</returns>
        public static Raycast.TriangleHit TestAllTriangles(Ray worldRay, float rayLength, UnityEngine.Mesh mesh, GameObject parent)
        {
            if (mesh == null || parent == null)
            {
                return(Raycast.TriangleHit.Invalid);
            }

            // Mesh bounds are in local coordinates - transform ray to local.
            Ray localRay = new Ray(parent.transform.InverseTransformPoint(worldRay.origin), parent.transform.InverseTransformVector(worldRay.direction).normalized);

            if (!mesh.bounds.IntersectRay(localRay))
            {
                return(Raycast.TriangleHit.Invalid);
            }

            int[]              triangles  = mesh.triangles;
            Vector3[]          vertices   = mesh.vertices;
            TriangleTestResult testResult = new TriangleTestResult();

            for (int i = 0; i < triangles.Length; i += 3)
            {
                Vector3            v1     = vertices[triangles[i + 0]];
                Vector3            v2     = vertices[triangles[i + 1]];
                Vector3            v3     = vertices[triangles[i + 2]];
                Vector3            normal = Vector3.Cross(v2 - v1, v3 - v1).normalized;
                TriangleTestResult test   = TestTriangle(localRay, rayLength, i, v1, v2, v3, normal);
                if (test.Hit && test.Time < testResult.Time)
                {
                    testResult = test;
                }
            }

            if (!testResult.Hit)
            {
                return(Raycast.TriangleHit.Invalid);
            }

            Vector3 worldIntersectionPoint = parent.transform.TransformPoint(testResult.PointInTriangle);

            return(new Raycast.TriangleHit()
            {
                Target = parent,
                Vertices = new Vector3[]
                {
                    parent.transform.TransformPoint(vertices[triangles[testResult.TriangleIndex + 0]]),
                    parent.transform.TransformPoint(vertices[triangles[testResult.TriangleIndex + 1]]),
                    parent.transform.TransformPoint(vertices[triangles[testResult.TriangleIndex + 2]])
                },
                Point = worldIntersectionPoint,
                Normal = parent.transform.TransformDirection(testResult.Normal),
                Distance = Vector3.Distance(worldRay.GetPoint(0), worldIntersectionPoint)
            });
        }