Beispiel #1
0
    public BVHNode(List <IHitable> l, int n, double time0, double time1)
    {
        AABB boxLeft, boxRight;
        int  axis = 3 * (int)RandomDouble();

        if (axis == 0)
        {
            l.Sort((a, b) =>
            {
                if (!a.BoundingBox(0, 0, out boxLeft) || !b.BoundingBox(0, 0, out boxRight))
                {
                    throw new Exception();
                }
                return(boxLeft.Min.X.CompareTo(boxRight.Min.X));
            });
        }
        else if (axis == 1)
        {
            l.Sort((a, b) =>
            {
                if (!a.BoundingBox(0, 0, out boxLeft) || !b.BoundingBox(0, 0, out boxRight))
                {
                    throw new Exception();
                }
                return(boxLeft.Min.Y.CompareTo(boxRight.Min.Y));
            });
        }
        else
        {
            l.Sort((a, b) =>
            {
                if (!a.BoundingBox(0, 0, out boxLeft) || !b.BoundingBox(0, 0, out boxRight))
                {
                    throw new Exception();
                }
                return(boxLeft.Min.Z.CompareTo(boxRight.Min.Z));
            });
        }
        if (n == 1)
        {
            left = right = l[0];
        }
        else if (n == 2)
        {
            left  = l[0];
            right = l[1];
        }
        else
        {
            left  = new BVHNode(l, n / 2, time0, time1);
            right = new BVHNode(l.Skip(n / 2).ToList(), n - n / 2, time0, time1);
        }
        if (!left.BoundingBox(time0, time1, out boxLeft) ||
            !right.BoundingBox(time0, time1, out boxRight))
        {
            throw new Exception();
        }
        box = SurroundingBox(boxLeft, boxRight);
    }
 public bool BoundingBox(double t0, double t1, out AABB box)
 {
     if (_hitable.BoundingBox(t0, t1, out box))
     {
         box = new AABB(box.Min + _offset, box.Max + _offset);
         return(true);
     }
     return(false);
 }
Beispiel #3
0
 public bool BoundingBox(double t0, double t1, out AABB box)
 {
     if (ptr.BoundingBox(t0, t1, out box))
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
Beispiel #4
0
 public bool BoundingBox(double t0, double t1, out AABB box)
 {
     if (ptr.BoundingBox(t0, t1, out box))
     {
         box = new AABB(box.Min + offset, box.Max + offset);
         return(true);
     }
     else
     {
         return(false);
     }
 }
Beispiel #5
0
        private static int BoxXCompare(IHitable a, IHitable b)
        {
            if (!a.BoundingBox(0, 0, out AABB boxLeft) || !b.BoundingBox(0, 0, out AABB boxRight))
            {
                throw new Exception("No bounding box in BVHNode");
            }

            if (boxLeft.Min.X - boxRight.Min.X < 0)
            {
                return(-1);
            }

            return(1);
        }
Beispiel #6
0
        public BVHNode(List <IHitable> hitables, float time0, float time1)
        {
            var axis = (int)(Rand.Float * 3);

            switch (axis)
            {
            case 0:
                // sort x
                hitables.Sort(BVHNode.BoxXCompare);
                break;

            case 1:
                // sort y
                hitables.Sort(BVHNode.BoxYCompare);
                break;

            default:
                // sprt z
                hitables.Sort(BVHNode.BoxZCompare);
                break;
            }

            switch (hitables.Count)
            {
            case 1:
                Left = Right = hitables[0];
                break;

            case 2:
                Left  = hitables[0];
                Right = hitables[1];
                break;

            default:
                Left  = new BVHNode(hitables.Take(hitables.Count / 2).ToList(), time0, time1);
                Right = new BVHNode(hitables.Skip(hitables.Count / 2).ToList(), time0, time1);
                break;
            }

            if (!Left.BoundingBox(time0, time1, out AABB boxLeft) ||
                !Right.BoundingBox(time0, time1, out AABB boxRight))
            {
                throw new Exception("No bounding box in BVHNode");
            }

            Box = AABB.SurroundingBox(boxRight, boxLeft);
        }
        public RotateY(IHitable hitable, double angle)
        {
            _hitable = hitable;
            AABB box;

            _has_box = _hitable.BoundingBox(0, 1, out box);
            var radians = angle * Math.PI / 180;

            _sin_theta = Math.Sin(radians);
            _cos_theta = Math.Cos(radians);
            var rmin = Rotate(box.Min);

            _aabb = new AABB(rmin, rmin);
            _aabb = _aabb | Rotate(box.Max);
            _aabb = _aabb | Rotate(Vec3.Create(box.Min.X, box.Min.Y, box.Max.Z));
            _aabb = _aabb | Rotate(Vec3.Create(box.Max.X, box.Max.Y, box.Min.Z));
        }
Beispiel #8
0
    public RotateY(IHitable p, double angle)
    {
        ptr = p;
        double radians = (Math.PI / 180) * angle;

        sinTheta = Math.Sin(radians);
        cosTheta = Math.Cos(radians);
        hasBox   = ptr.BoundingBox(0, 1, out bBox);
        Vector3D min = new Vector3D(double.MaxValue, double.MaxValue, double.MaxValue);
        Vector3D max = new Vector3D(-double.MaxValue, -double.MaxValue, -double.MaxValue);

        for (int i = 0; i < 2; i++)
        {
            for (int j = 0; j < 2; j++)
            {
                for (int k = 0; k < 2; k++)
                {
                    double   x      = i * bBox.Max.X + (1 - i) * bBox.Min.X;
                    double   y      = j * bBox.Max.Y + (1 - j) * bBox.Min.Y;
                    double   z      = k * bBox.Max.Z + (1 - k) * bBox.Min.Z;
                    double   newx   = cosTheta * x + sinTheta * z;
                    double   newz   = -sinTheta * x + cosTheta * z;
                    Vector3D tester = new Vector3D(newx, y, newz);
                    for (int c = 0; c < 3; c++)
                    {
                        if (tester[c] > max[c])
                        {
                            max[c] = tester[c];
                        }
                        if (tester[c] < min[c])
                        {
                            min[c] = tester[c];
                        }
                    }
                }
            }
        }
        bBox = new AABB(min, max);
    }
Beispiel #9
0
        public BVHNode(List <IHitable> world, int start, int length)
        {
            this.start  = start;
            this.length = length;

            Random rng  = new Random();
            int    axis = rng.Next() % 3;

            IComparer <IHitable> sorter;

            switch (axis)
            {
            case 0: sorter = new SortByX(); break;

            case 1: sorter = new SortByY(); break;

            default: sorter = new SortByZ(); break;
            }

            world.Sort(start, length, sorter);

            if (length == 1)
            {
                left = right = world[start];
            }
            else if (length == 2)
            {
                left  = world[start];
                right = world[start + 1];
            }
            else
            {
                left  = new BVHNode(world, start, length / 2);
                right = new BVHNode(world, start + length / 2, length - length / 2);
            }

            box = AABB.CalculateSurroundBox(left.BoundingBox(), right.BoundingBox());
        }
Beispiel #10
0
        public BVHNode(IHitable[] hitables, double time0, double time1)
        {
            if (hitables.Length == 1)
            {
                _left  = hitables[0];
                _right = null;
                _left.BoundingBox(time0, time1, out _box);
                return;
            }

            int             axis = _sampler.Next(0, 3);
            List <IHitable> list = new List <IHitable>(hitables);

            list.Sort((IHitable a, IHitable b) =>
            {
                AABB sort_box_left, sort_box_right;
                if (!a.BoundingBox(time0, time1, out sort_box_left) || !b.BoundingBox(time0, time1, out sort_box_right))
                {
                    throw new InvalidOperationException("error computing AABB");
                }
                return(sort_box_left.Min[axis] < sort_box_right.Min[axis] ? -1 : 1);
            });

            int half = list.Count - list.Count / 2;

            _left  = half == 1 ? list[0] : new BVHNode(list.GetRange(0, half).ToArray(), time0, time1);
            _right = half == list.Count - 1 ? list[list.Count - 1] : new BVHNode(list.GetRange(half, list.Count - half).ToArray(), time0, time1);

            AABB box_left, box_right;

            if (!_left.BoundingBox(time0, time1, out box_left) || !_right.BoundingBox(time0, time1, out box_right))
            {
                throw new InvalidOperationException("error computing AABB");
            }
            _box = box_left | box_right;
        }
Beispiel #11
0
 public bool BoundingBox(double t0, double t1, out AABB box)
 {
     box = new AABB(new Vector3D(), new Vector3D());
     return(ptr.BoundingBox(t0, t1, out box));
 }
 public bool BoundingBox(double t0, double t1, out AABB box)
 {
     return(_source.BoundingBox(t0, t1, out box));
 }
 public bool BoundingBox(double t0, double t1, out AABB box)
 {
     return(_boundary.BoundingBox(t0, t1, out box));
 }
Beispiel #14
0
 public static BoundingBox GetGenericBoundingBox(this IHitable hitable)
 {
     hitable.BoundingBox(float.MinValue, float.MaxValue, out BoundingBox bb);
     return(bb);
 }