Beispiel #1
0
        public override IntersectionList LocalIntersect(Ray ray)
        {
            var sphereToRay = ray.Origin - Vector4.CreatePosition(0, 0, 0);

            var a = Vector4.Dot(ray.Direction, ray.Direction);
            var b = 2 * Vector4.Dot(ray.Direction, sphereToRay);
            var c = Vector4.Dot(sphereToRay, sphereToRay) - 1;

            var discriminant = (b * b) - (4 * a * c);

            // If the discriminant is negative, the ray misses
            // and there are no intersections.
            if (discriminant < 0)
            {
                return(IntersectionList.Empty());
            }

            // Otherwise, we have two intersections which we can
            // solve for t using the quadratic formula.
            var t1 = (-b - Math.Sqrt(discriminant)) / (2 * a);
            var t2 = (-b + Math.Sqrt(discriminant)) / (2 * a);
            var xs = new[]
            {
                new Intersection(t1, this),
                new Intersection(t2, this),
            };

            return(IntersectionList.Create(xs));
        }
Beispiel #2
0
        public IntersectionList FilterIntersections(IntersectionList xs)
        {
            var inl    = false;
            var inr    = false;
            var result = new List <Intersection>();

            foreach (var i in xs)
            {
                var lhit = this.Left.Includes(i.Object);
                if (IntersectionAllowed(this.Operation, lhit, inl, inr))
                {
                    result.Add(i);
                }

                if (lhit)
                {
                    inl = !inl;
                }
                else
                {
                    inr = !inr;
                }
            }

            return(IntersectionList.Create(result.ToArray()));
        }
Beispiel #3
0
        public override IntersectionList LocalIntersect(Ray ray)
        {
            var dirCrossE2 = ray.Direction.Cross3(this.E2);
            var det        = this.E1.Dot(dirCrossE2);

            if (Math.Abs(det) < Epsilon)
            {
                return(IntersectionList.Empty());
            }

            var f          = 1.0 / det;
            var p1ToOrigin = ray.Origin - this.P1;
            var u          = f * p1ToOrigin.Dot(dirCrossE2);

            if (u < 0 || u > 1)
            {
                return(IntersectionList.Empty());
            }

            var originCrossE1 = p1ToOrigin.Cross3(this.E1);
            var v             = f * ray.Direction.Dot(originCrossE1);

            if (v < 0 || (u + v) > 1)
            {
                return(IntersectionList.Empty());
            }

            var t = f * this.E2.Dot(originCrossE1);

            return(IntersectionList.Create(
                       new Intersection(t, this)));
        }
Beispiel #4
0
        /// <summary>
        /// Intersect with a predicate to select a subset
        /// of shapes from the world.
        /// </summary>
        public IntersectionList Intersect(Ray ray, Func <Shape, bool> predicate)
        {
            Interlocked.Increment(ref Stats.Tests);
            var xs = this.Objects
                     .Where(predicate)
                     .SelectMany(x => x.Intersect(ray))
                     .ToArray();

            return(IntersectionList.Create(xs));
        }
Beispiel #5
0
        public override IntersectionList LocalIntersect(Ray ray)
        {
            var a = Math.Pow(ray.Direction.X, 2) + Math.Pow(ray.Direction.Z, 2);

            // ray is parallel to the y-axis
            if (Math.Abs(a) < Epsilon)
            {
                var caps = new List <Intersection>();
                this.IntersectCaps(ray, caps);
                return(IntersectionList.Create(caps.ToArray()));
            }

            var b =
                2 * ray.Origin.X * ray.Direction.X +
                2 * ray.Origin.Z * ray.Direction.Z;

            var c = Math.Pow(ray.Origin.X, 2) + Math.Pow(ray.Origin.Z, 2) - 1;

            var disc = b * b - 4 * a * c;

            if (disc < 0)
            {
                return(IntersectionList.Empty());
            }

            var t0 = (-b - Math.Sqrt(disc)) / (2 * a);
            var t1 = (-b + Math.Sqrt(disc)) / (2 * a);

            if (t0 > t1)
            {
                var tmp = t0;
                t0 = t1;
                t1 = tmp;
            }

            var xs = new List <Intersection>();

            var y0 = ray.Origin.Y + t0 * ray.Direction.Y;

            if (this.Minimum < y0 && y0 < this.Maximum)
            {
                xs.Add(new Intersection(t0, this));
            }

            var y1 = ray.Origin.Y + t1 * ray.Direction.Y;

            if (this.Minimum < y1 && y1 < this.Maximum)
            {
                xs.Add(new Intersection(t1, this));
            }

            this.IntersectCaps(ray, xs);

            return(IntersectionList.Create(xs.ToArray()));
        }
Beispiel #6
0
        public override IntersectionList LocalIntersect(Ray ray)
        {
            if (Math.Abs(ray.Direction.Y) < Epsilon)
            {
                return(IntersectionList.Empty());
            }

            var t = -ray.Origin.Y / ray.Direction.Y;
            var i = new Intersection(t, this);

            return(IntersectionList.Create(i));
        }
Beispiel #7
0
        public override IntersectionList LocalIntersect(Ray ray)
        {
            var bounds = this.GetBounds();

            if (!bounds.Intersect(ray))
            {
                return(IntersectionList.Empty());
            }

            var xs = new List <Intersection>();

            xs.AddRange(this.Left.Intersect(ray));
            xs.AddRange(this.Right.Intersect(ray));
            return(this.FilterIntersections(
                       IntersectionList.Create(xs.ToArray())));
        }
Beispiel #8
0
        public override IntersectionList LocalIntersect(Ray ray)
        {
            CheckAxis(ray.Origin.X, ray.Direction.X, out var xtmin, out var xtmax);
            CheckAxis(ray.Origin.Y, ray.Direction.Y, out var ytmin, out var ytmax);
            CheckAxis(ray.Origin.Z, ray.Direction.Z, out var ztmin, out var ztmax);

            var tmin = Max(xtmin, ytmin, ztmin);
            var tmax = Min(xtmax, ytmax, ztmax);

            if (tmin > tmax)
            {
                return(IntersectionList.Empty());
            }

            return(IntersectionList.Create(
                       new Intersection(tmin, this),
                       new Intersection(tmax, this)));
        }
Beispiel #9
0
        private void CalculateRefraction(IntersectionList xs, out double n1, out double n2)
        {
            n1 = 0;
            n2 = 0;
            var containers = new List <Shape>();

            foreach (var i in xs)
            {
                if (i.Equals(this))
                {
                    if (containers.Count == 0)
                    {
                        n1 = 1.0;
                    }
                    else
                    {
                        n1 = containers.Last().Material.RefractiveIndex;
                    }
                }

                if (containers.Contains(i.Object))
                {
                    containers.Remove(i.Object);
                }
                else
                {
                    containers.Add(i.Object);
                }

                if (i.Equals(this))
                {
                    if (containers.Count == 0)
                    {
                        n2 = 1.0;
                    }
                    else
                    {
                        n2 = containers.Last().Material.RefractiveIndex;
                    }

                    break;
                }
            }
        }
Beispiel #10
0
        public Interaction Precompute(Ray r, IntersectionList xs)
        {
            var t       = this.T;
            var obj     = this.Object;
            var point   = r.GetPosition(t);
            var eyev    = -r.Direction;
            var normalv = obj.GetNormal(point);
            var inside  = false;

            if (normalv.Dot(eyev) < 0)
            {
                inside  = true;
                normalv = -normalv;
            }

            var overPoint  = point + normalv * Epsilon;
            var underPoint = point - normalv * Epsilon;

            var reflectv = r.Direction.Reflect(normalv);

            this.CalculateRefraction(xs, out var n1, out var n2);

            return(new Interaction
            {
                T = t,
                Object = obj,
                Point = point,
                OverPoint = overPoint,
                UnderPoint = underPoint,
                Eyev = eyev,
                Normalv = normalv,
                Reflectv = reflectv,
                Inside = inside,
                N1 = n1,
                N2 = n2,
            });
        }
Beispiel #11
0
 public Interaction Precompute(Ray r) =>
 Precompute(r, IntersectionList.Create(this));
Beispiel #12
0
        public override IntersectionList LocalIntersect(Ray ray)
        {
            List <Intersection> xs;

            var o = ray.Origin;
            var d = ray.Direction;

            var a = (d.X * d.X) - (d.Y * d.Y) + (d.Z * d.Z);
            var b = (2 * o.X * d.X) - (2 * o.Y * d.Y) + (2 * o.Z * d.Z);
            var c = (o.X * o.X) - (o.Y * o.Y) + (o.Z * o.Z);

            if (a == 0)
            {
                if (b == 0)
                {
                    return(IntersectionList.Empty());
                }

                var t = -c / (2 * b);
                xs = new List <Intersection>()
                {
                    new Intersection(t, this),
                };

                this.IntersectCaps(ray, xs);
                return(IntersectionList.Create(xs.ToArray()));
            }

            var disc = b * b - 4 * a * c;

            if (disc < 0)
            {
                return(IntersectionList.Empty());
            }

            var t0 = (-b - Math.Sqrt(disc)) / (2 * a);
            var t1 = (-b + Math.Sqrt(disc)) / (2 * a);

            if (t0 > t1)
            {
                var tmp = t0;
                t0 = t1;
                t1 = tmp;
            }

            xs = new List <Intersection>();

            var y0 = o.Y + t0 * d.Y;

            if (this.Minimum < y0 && y0 < this.Maximum)
            {
                xs.Add(new Intersection(t0, this));
            }

            var y1 = o.Y + t1 * d.Y;

            if (this.Minimum < y1 && y1 < this.Maximum)
            {
                xs.Add(new Intersection(t1, this));
            }

            this.IntersectCaps(ray, xs);
            return(IntersectionList.Create(xs.ToArray()));
        }