예제 #1
0
        // dot(rayDir, rayDir) * t^2 + 2*t*dot(rayDir, rayOrig-center) + dot(rayOrig-center, rayOrig-center) - R*R=0
        public bool Hit(Ray ray, float tMin, float tMax, ref HitRecord record)
        {
            float a    = ray.Direction.LengthSquared; // dot(rayDir, rayDir)
            Vec3  temp = new Vec3();

            Vec3.Subtract(ray.Origin, this.Center, temp);
            float b = 2 * ray.Direction.Dot(temp);                    //2*dot(rayDir, rayOrig-center)
            float c = temp.LengthSquared - this.Radius * this.Radius; //dot(rayOrig-center, rayOrig-center) - R*R

            if (!PolyUtils.HasRealRoot(a, b, c))
            {
                // No hit
                return(false);
            }
            // Check first root for hit
            float firstRoot = PolyUtils.FirstRoot(a, b, c);

            if (firstRoot > tMin && firstRoot < tMax)
            {
                record.T     = firstRoot;
                record.Point = ray.PointAt(firstRoot);
                Vec3.Subtract(record.Point, this.Center, temp);
                record.Normal   = temp / this.Radius;
                record.Material = this.Material;
                return(true);
            }
            // Check second root for hit
            float secondRoot = PolyUtils.SecondRoot(a, b, c);

            if (secondRoot > tMin && secondRoot < tMax)
            {
                record.T     = secondRoot;
                record.Point = ray.PointAt(secondRoot);
                Vec3.Subtract(record.Point, this.Center, temp);
                record.Normal   = temp / this.Radius;
                record.Material = this.Material;
                return(true);
            }

            return(false);
        }
예제 #2
0
        public bool Hit(Ray ray, float tMin, float tMax, ref HitRecord record)
        {
            var originRecBase = TransformUtils.OrthogonalBaseChange(ray.Origin, this.u, this.v, this.normal);
            var dirRecBase    = TransformUtils.OrthogonalBaseChange(ray.Direction, this.u, this.v, this.normal);

            float t = (this.z - originRecBase.Z) / dirRecBase.Z;

            if (t < tMin || t > tMax)
            {
                return(false);
            }
            float x = originRecBase.X + t * dirRecBase.X;
            float y = originRecBase.Y + t * dirRecBase.Y;

            if (x < this.x0 || x > this.x1 || y < this.y0 || y > this.y1)
            {
                return(false);
            }
            record.T        = t;
            record.Material = this.Material;
            record.Point    = ray.PointAt(t);
            record.Normal   = this.normal;
            return(true);
        }