Beispiel #1
0
        public static List<double> RayMeshIntersections(Point3D orig, Vector3D dir, MeshGeometry3D mesh, bool frontFacesOnly)
        {
            List<double> result = new List<double>();

            if (mesh == null || !dir.IsValid())
                return result;

            double epsilon = 1E-9;
            Int32Collection indices = mesh.TriangleIndices;
            Point3DCollection positions = mesh.Positions;

            for (int i = 0; i < indices.Count; i += 3)
            {
                Point3D vert0 = positions[indices[i]];
                Point3D vert1 = positions[indices[i + 1]];
                Point3D vert2 = positions[indices[i + 2]];

                //--- find vectors for two edges sharing vert0
                Vector3D edge1 = vert1 - vert0;
                Vector3D edge2 = vert2 - vert0;

                //--- begin calculating determinant  also used to calculate U parameter
                Vector3D pvec = dir.Cross(edge2);

                //--- if determinant is near zero ray lies in plane of triangle
                double det = edge1.Dot(pvec);
                if (det < epsilon)
                {
                    if (frontFacesOnly)
                        continue;

                    else if (det > -epsilon)
                        continue;
                }
                double inv_det = 1.0 / det;

                //--- calculate distance from vert0 to ray origin
                Vector3D tvec = orig - vert0;

                //--- calculate U parameter and test bounds
                double u = tvec.Dot(pvec) * inv_det;
                if (u < 0.0 || u > 1.0)
                    continue;

                //--- prepare to test V parameter
                Vector3D qvec = tvec.Cross(edge1);

                //--- calculate V parameter and test bounds
                double v = dir.Dot(qvec) * inv_det;
                if (v < 0.0 || u + v > 1.0)
                    continue;

                //--- calculate t scale parameters, ray intersects triangle
                double t = edge2.Dot(qvec) * inv_det;

                result.Add(t);
            }

            return result;
        }