예제 #1
0
        public override bool RayCast(Ray ray, out RayCastHit hit)
        {
            ray.direction.Normalize();
            hit = null;
            float t0, t1; // solutions for t if the ray intersects

            // geometric solution
            Vector3 L   = object3D.transform.Location - ray.origin;
            float   tca = Vector3.Dot(L, ray.direction);

            if (tca < 0)
            {
                return(false);
            }
            float d2 = Vector3.Dot(L, L) - tca * tca;

            if (d2 > radius)
            {
                return(false);
            }
            float thc = (float)Math.Sqrt(radius - d2);

            t0 = tca - thc;
            t1 = tca + thc;

            if (t0 > t1)
            {
                float temp = t1;
                t1 = t0;
                t0 = temp;
            }


            if (t0 < 0)
            {
                t0 = t1; // if t0 is negative, let's use t1 instead
                if (t0 < 0)
                {
                    return(false);        // both t0 and t1 are negative
                }
            }

            hit = new RayCastHit
            {
                collider = this,
                distance = t0,
                hit      = ray.origin + t0 * ray.direction,
                normal   = ray.origin + t0 * ray.direction - object3D.transform.Location,
            };
            return(true);
        }
예제 #2
0
        public virtual bool RayCast(Ray ray, out RayCastHit hit)
        {
            Triangle3 hitTriangle = new Triangle3();
            Vector3   barycentricCoords;
            Vector3   pt;

            ray.direction.Normalize();
            for (int face = 0; face < mesh.faces.GetLength(0); face++)
            {
                //Ignore faces where ray hits from behind
                float rayNormalDot = Vector3.Dot(mesh.faceNormals[face], ray.direction);
                if (rayNormalDot >= 0)
                {
                    continue;
                }

                float planeConst = Vector3.Dot(mesh.faceNormals[face], mesh.vertices[mesh.faces[face, 0]] + object3D.transform.Location);
                float t          = -(Vector3.Dot(mesh.faceNormals[face], ray.origin) + planeConst) / Vector3.Dot(mesh.faceNormals[face], ray.direction);
                //Triangle is behind ray origin
                if (t < 0)
                {
                    continue;
                }
                pt = ray.origin + (t * ray.direction);

                hitTriangle.v0     = mesh.vertices[mesh.faces[face, 0]] + object3D.transform.Location;
                hitTriangle.v1     = mesh.vertices[mesh.faces[face, 1]] + object3D.transform.Location;
                hitTriangle.v2     = mesh.vertices[mesh.faces[face, 2]] + object3D.transform.Location;
                hitTriangle.vn0    = mesh.vertexNormalCoords[mesh.vertexNormals[face, 0]];
                hitTriangle.vn1    = mesh.vertexNormalCoords[mesh.vertexNormals[face, 1]];
                hitTriangle.vn2    = mesh.vertexNormalCoords[mesh.vertexNormals[face, 2]];
                hitTriangle.uv0    = mesh.uvcoords[mesh.uvs[face, 0]];
                hitTriangle.uv1    = mesh.uvcoords[mesh.uvs[face, 1]];
                hitTriangle.uv2    = mesh.uvcoords[mesh.uvs[face, 2]];
                hitTriangle.normal = mesh.faceNormals[face];


                barycentricCoords = hitTriangle.GetBarycentricCoordinates(pt, out bool inTri);
                if (inTri)
                {
                    hit = new RayCastHit {
                        hit = pt, barycentricCoordinates = barycentricCoords, collider = this, distance = t, normal = (smoothMesh ? hitTriangle.NormalAt(pt) : hitTriangle.normal), triangle = hitTriangle
                    };
                    return(true);
                }
            }
            hit = null;
            return(false);
        }
예제 #3
0
 public static bool RayCast(Ray ray, out RayCastHit hit)
 {
     if (RayCastAll(ray, out RayCastHit[] hits))