public Computation PrepareComputations(Ray ray, List <Intersection> xs = null)
        {
            if (xs == null)
            {
                xs = new List <Intersection> {
                    this
                };
            }

            var comp = new Computation
            {
                T      = this.T,
                Object = this.Object
            };

            comp.Point   = ray.Position(comp.T);
            comp.EyeV    = (-ray.Direction).ToVector();
            comp.NormalV = comp.Object.NormalAt(comp.Point);

            if (comp.NormalV.Dot(comp.EyeV) < 0)
            {
                comp.Inside  = true;
                comp.NormalV = comp.NormalV.Negate().ToVector();
            }
            else
            {
                comp.Inside = false;
            }

            comp.ReflectV   = ray.Direction.Reflect(comp.NormalV);
            comp.OverPoint  = (comp.Point + comp.NormalV * (DoubleUtils.Epsilon)).ToPoint();
            comp.UnderPoint = (comp.Point - comp.NormalV * (DoubleUtils.Epsilon)).ToPoint();


            var containers = new List <ISceneObject>();

            foreach (var intersection in xs)
            {
                if (intersection.Equals(this))
                {
                    if (!containers.Any())
                    {
                        comp.N1 = 1.0;
                    }
                    else
                    {
                        var last = containers.Last();
                        comp.N1 = last.Material.RefractiveIndex;
                    }
                }

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

                if (intersection == this)
                {
                    if (!containers.Any())
                    {
                        comp.N2 = 1.0;
                    }
                    else
                    {
                        var last = containers.Last();
                        comp.N2 = last.Material.RefractiveIndex;
                    }

                    break;
                }
            }

            return(comp);
        }
예제 #2
0
 public Tuple ReflectedColor(World w, Computation comps)
 {
     return(ReflectedColor(w, comps, defaultRemaining));
 }
        /// <summary>
        /// Given an Intersection and a Ray
        /// evaluates for eye vector, normal vector, insection point,
        /// and if ray is inside of object.
        /// This is the same as calling the Computation class constructor with Intersection and Ray parameter
        /// </summary>
        /// <param name="i"></param>
        /// <param name="r"></param>
        public static Computation PrepareComputations(Intersection i, Ray r, List <Intersection> xs = null)
        {
            Computation comp = new Computation();

            comp.t         = i.t;
            comp.rayObject = i.rayObject;
            comp.point     = r.GetPointPosition(i.t);
            comp.eyeV      = -r.direction;
            comp.normalV   = comp.rayObject.GetNormal(comp.point);

            // Checks if eye vector and normal are pointing in the same direction
            // if dot product is less than zero that point in the same direction
            if (Vector3.Dot(comp.eyeV, comp.normalV) < 0)
            {
                comp.inside  = true;
                comp.normalV = -comp.normalV;
            }
            else
            {
                comp.inside = false;
            }


            if (xs == null)
            {
                xs = new List <Intersection>()
                {
                    i
                }
            }
            ;

            // Transparency Intersections algorithm
            List <RayObject> containers = new List <RayObject>();

            foreach (Intersection intersect in xs)
            {
                // n1
                if (i == intersect)
                {
                    if (containers.Count == 0)
                    {
                        comp.n1 = 1.0f;
                    }
                    else
                    {
                        comp.n1 = containers.Last <RayObject>().material.RefractIndex;
                    }
                }

                if (containers.Contains(intersect.rayObject))
                {
                    containers.Remove(intersect.rayObject);
                    //Console.WriteLine("Object Removed: " + intersect.rayObject.ToString());
                }
                else
                {
                    containers.Add(intersect.rayObject);
                    //Console.WriteLine("Object Added: " + intersect.rayObject.ToString());
                }
                //Console.WriteLine("List Lenght: " + containers.Count);

                // n2
                if (i == intersect)
                {
                    if (containers.Count == 0)
                    {
                        comp.n2 = 1.0f;
                    }
                    else
                    {
                        comp.n2 = containers[containers.Count - 1].material.RefractIndex;
                    }
                    break;
                }
            }

            comp.reflectV   = Vector3.Reflection(r.direction, comp.normalV);
            comp.overPoint  = comp.point + comp.normalV * Utilities.OVER_POINT_EPSILON;
            comp.underPoint = comp.point - comp.normalV * Utilities.UNDER_POINT_EPSILON;

            return(comp);
        }
    }
예제 #4
0
 public Tuple ShadeHit(World w, Computation comps)
 {
     return(ShadeHit(w, comps, defaultRemaining));
 }