/// <summary>
        /// Intersects the ray, if intersection is closer than the one inside the record,
        /// sets the records with intersection information.
        /// </summary>
        /// <param name="ray"></param>
        /// <param name="record"></param>
        /// <returns></returns>
        public override bool Intersect(Ray ray, IntersectionRecord record)
        {
            float   dist = 0f;
            Vector3 hitPt, n;

            n = mNormal;    // because ray/plane intersection may flip the normal!
            if (!RayPlaneIntersection(ray, ref n, mD, ref dist))
            {
                return(false);
            }

            /*
             * rectangle behind the ray or there are other closer intersections
             */
            if ((dist < 0) || (dist > record.HitDistance))
            {
                return(false);
            }

            hitPt = ray.Origin + (ray.Direction * dist);

            /*
             * Now need to decide inside or outside
             */
            if (!InsidePolygon(hitPt))
            {
                return(false);
            }

            record.UpdateRecord(dist, hitPt, n, ray, mMaterialIndex, GetResourceIndex());
            return(true);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Intersects the ray with the sphere. If intersection is closer than what is
        /// in the record, updates the record with new intersection information.
        /// </summary>
        /// <param name="ray"></param>
        /// <param name="record"></param>
        /// <returns></returns>
        public override bool Intersect(Ray ray, IntersectionRecord record)
        {
            Vector3 v1   = ray.Origin - mCenter;
            float   b    = 2f * Vector3.Dot(v1, ray.Direction);
            float   c    = v1.LengthSquared() - mRadiusSquared;
            float   root = b * b - 4 * c;

            if (root < 0f)
            {
                return(false);
            }

            root = (float)Math.Sqrt(root);
            float t0 = 0.5f * (-b - root);
            float t1 = 0.5f * (-b + root);

            if ((t0 < 0) && (t1 < 0))
            {
                return(false);
            }

            float dist;

            if (t0 < t1)
            {
                if (t0 > 0)
                {
                    dist = t0;
                }
                else
                {
                    dist = t1;
                }
            }
            else
            {
                if (t1 > 0)
                {
                    dist = t1;
                }
                else
                {
                    dist = t0;
                }
            }

            if (dist > record.HitDistance)
            {
                return(false);
            }

            // intersection found
            Vector3 pt = ray.Origin + dist * ray.Direction;
            Vector3 n  = pt - mCenter;

            record.UpdateRecord(dist, pt, n, ray, mMaterialIndex, GetResourceIndex());

            return(true);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Intersects the ray, if intersection is closer than the one inside the record,
        /// sets the records with intersection information.
        /// </summary>
        /// <param name="ray"></param>
        /// <param name="record"></param>
        /// <returns></returns>
        public override bool Intersect(Ray ray, IntersectionRecord record)
        {
            float   dist = 0f;
            Vector3 hitPt, n;

            n = mNormal;
            if (!RayPlaneIntersection(ray, ref n, mD, ref dist))
            {
                return(false);
            }

            /*
             * rectangle behind the ray or there are other closer intersections
             */
            if ((dist < 0) || (dist > record.HitDistance))
            {
                return(false);
            }

            hitPt = ray.Origin + (ray.Direction * dist);

            /*
             * Now need to decide inside or outside
             */
            float   u, v, w;
            Vector3 v1        = mVertices[1] - hitPt;
            Vector3 v2        = mVertices[2] - hitPt;
            float   areaPV1V2 = Vector3.Dot(mNormal, Vector3.Cross(v1, v2));

            u = areaPV1V2 * mInvArea2;
            if ((u < 0f) || (u > 1f))
            {
                return(false);
            }

            v1 = mVertices[0] - hitPt;
            float areaPV0V2 = Vector3.Dot(mNormal, Vector3.Cross(v2, v1));

            v = areaPV0V2 * mInvArea2;
            if ((v < 0f) || (v > 1f))
            {
                return(false);
            }

            w = 1 - u - v;
            if (w < 0f)
            {
                return(false);
            }

            /*
             *  An actual hit
             */
            record.UpdateBC(u, v, w);

            // now if we have per-vertex normal, use it!
            if (null != mNormalAtVertices)
            {
                n = u * mNormalAtVertices[0] + v * mNormalAtVertices[1] + w * mNormalAtVertices[2];
            }

            // flip the normal if seeing the back face
            if (Vector3.Dot(n, ray.Direction) > 0f)
            {
                n = -n;
            }

            record.UpdateRecord(dist, hitPt, n, ray, mMaterialIndex, GetResourceIndex());
            return(true);
        }
        /// <summary>
        /// Intersects the ray, if intersection is closer than the one inside the record,
        /// sets the records with intersection information.
        /// </summary>
        /// <param name="ray"></param>
        /// <param name="record"></param>
        /// <returns></returns>
        public override bool Intersect(Ray ray, IntersectionRecord record)
        {
            float dist = 0f;
            Vector3 hitPt, n;

            n = mNormal;
            if (!RayPlaneIntersection(ray, ref n, mD, ref dist))
                return false;

            /*
             * rectangle behind the ray or there are other closer intersections
             */
            if ((dist < 0) || (dist > record.HitDistance))
                return false;

            hitPt = ray.Origin + (ray.Direction * dist);

            /*
             * Now need to decide inside or outside
             */
            float u, v, w;
            Vector3 v1 = mVertices[1] - hitPt;
            Vector3 v2 = mVertices[2] - hitPt;
            float areaPV1V2 = Vector3.Dot(mNormal, Vector3.Cross(v1, v2));

            u = areaPV1V2 * mInvArea2;
            if ((u < 0f) || (u > 1f))
                return false;

            v1 = mVertices[0] - hitPt;
            float areaPV0V2 = Vector3.Dot(mNormal, Vector3.Cross(v2, v1));
            v = areaPV0V2 * mInvArea2;
            if ((v<0f) || (v>1f))
                return false;

            w = 1 - u - v;
            if (w<0f)
                return false;

            /*
             *  An actual hit
             */
            record.UpdateBC(u, v, w);

            // now if we have per-vertex normal, use it!
            if (null != mNormalAtVertices)
                n = u * mNormalAtVertices[0] + v * mNormalAtVertices[1] + w * mNormalAtVertices[2];

            // flip the normal if seeing the back face
            if (Vector3.Dot(n, ray.Direction) > 0f)
                n = -n;

            record.UpdateRecord(dist, hitPt, n, ray, mMaterialIndex, GetResourceIndex());
            return true;
        }
Exemplo n.º 5
0
        /// <summary>
        /// Intersects the ray with the sphere. If intersection is closer than what is
        /// in the record, updates the record with new intersection information.
        /// </summary>
        /// <param name="ray"></param>
        /// <param name="record"></param>
        /// <returns></returns>
        public override bool Intersect(Ray ray, IntersectionRecord record)
        {
            Vector3 v1 = ray.Origin - mCenter;
            float b = 2f * Vector3.Dot(v1, ray.Direction);
            float c = v1.LengthSquared() - mRadiusSquared;
            float root = b * b - 4 * c;

            if (root < 0f)
                return false;

            root = (float) Math.Sqrt(root);
            float t0 = 0.5f * (-b - root);
            float t1 = 0.5f * (-b + root);

            if ((t0 < 0) && (t1 < 0))
                return false;

            float dist;
            if (t0 < t1)
            {
                if (t0 > 0)
                    dist = t0;
                else
                    dist = t1;
            }
            else
            {
                if (t1 > 0)
                    dist = t1;
                else
                    dist = t0;
            }

            if (dist > record.HitDistance)
                return false;

            // intersection found
            Vector3 pt = ray.Origin + dist * ray.Direction;
            Vector3 n = pt - mCenter;
            record.UpdateRecord(dist, pt, n, ray, mMaterialIndex, GetResourceIndex());

            return true;
        }
        /// <summary>
        /// Intersects the ray, if intersection is closer than the one inside the record,
        /// sets the records with intersection information.
        /// </summary>
        /// <param name="ray"></param>
        /// <param name="record"></param>
        /// <returns></returns>
        public override bool Intersect(Ray ray, IntersectionRecord record)
        {
            float dist= 0f;
            Vector3 hitPt, n;

            n = mNormal;    // because ray/plane intersection may flip the normal!
            if (!RayPlaneIntersection(ray, ref n, mD, ref dist))
                return false;

            /*
             * rectangle behind the ray or there are other closer intersections
             */
            if ((dist < 0) || (dist > record.HitDistance))
                return false;

            hitPt = ray.Origin + (ray.Direction * dist);

            /*
             * Now need to decide inside or outside
             */
            if (!InsidePolygon(hitPt))
                return false;

            record.UpdateRecord(dist, hitPt, n, ray, mMaterialIndex, GetResourceIndex());
            return true;
        }