Пример #1
0
        public BvhNode(List <Hitable> list, double time0, double time1)
        {
            int axis = (int)(FastRandom.RandomDouble() * 3);

            list.Sort(compareHitable(axis));

            if (list.Count == 1)
            {
                left = right = list[0];
            }
            else if (list.Count == 2)
            {
                left  = list[0];
                right = list[1];
            }
            else
            {
                left  = new BvhNode(list.GetRange(0, list.Count / 2), time0, time1);
                right = new BvhNode(list.GetRange(list.Count / 2, list.Count - list.Count / 2), time0, time1);
            }

            AxisAlignedBoundingBox boxLeft, boxRight;

            if (!left.BoundingBox(time0, time1, out boxLeft) || !right.BoundingBox(time0, time1, out boxRight))
            {
                throw new Exception("No Bounding Box in BvhNode Constructor.");
            }

            box = AxisAlignedBoundingBox.SurroundingBox(boxLeft, boxRight);
        }
Пример #2
0
 public override bool BoundingBox(float t0, float t1, ref AABB box)
 {
     if (!Object.BoundingBox(t0, t1, ref box))
     {
         return(false);
     }
     box = new AABB(box.min + offset, box.max + offset);
     return(true);
 }
Пример #3
0
        public BVHNode(List <Hitable> scene, int n = -1)
        {
            if (n == -1)
            {
                n = scene.Count;
            }

            var axis = (int)(Random.Value * 3.0f);

            if (axis == 0)
            {
                scene.Sort(BoxXCompare);
            }
            else if (axis == 1)
            {
                scene.Sort(BoxYCompare);
            }
            else
            {
                scene.Sort(BoxZCompare);
            }

            if (n == 1)
            {
                m_Left = m_Right = scene[0];
            }
            else if (n == 2)
            {
                m_Left  = scene[0];
                m_Right = scene[1];
            }
            else
            {
                m_Left = new BVHNode(scene, n / 2);

                var list = new List <Hitable>();
                for (var i = n / 2; i < scene.Count; i++)
                {
                    list.Add(scene[i]);
                }

                m_Right = new BVHNode(list, n - n / 2);
            }

            var left  = new AABB();
            var right = new AABB();

            if (!m_Left.BoundingBox(ref left) || !m_Right.BoundingBox(ref right))
            {
                throw new System.Exception("No bounding box in bvh_node constructor");
            }

            m_BoundingBox = AABB.SurroundingBox(ref left, ref right);
        }
    public BVHNode(List <Hitable> l, int n, float time0, float time1)
    {
        int Compare(Hitable a, Hitable b, int i)
        {
            AABB boxL = new AABB();
            AABB boxR = new AABB();

            if (!a.BoundingBox(0, 0, out boxL) || !b.BoundingBox(0, 0, out boxR))
            {
                throw new Exception();
            }
            return(boxL.Min[i] - boxR.Min[i] < 0 ? -1 : 1);
        }

        List <Hitable> SplitList(List <Hitable> source, int startIndex, int endIndex)
        {
            List <Hitable> result = new List <Hitable>();

            for (int i = 0; i <= endIndex - startIndex; i++)
            {
                result.Add(source[i + startIndex]);
            }
            return(result);
        }

        int method = (int)(3 * Mathf.Randomfloat());

        l.Sort((a, b) => Compare(a, b, method));
        switch (n)
        {
        case 1:
            left = right = l[0];
            break;

        case 2:
            left  = l[0];
            right = l[1];
            break;

        default:
            left  = new BVHNode(SplitList(l, 0, n / 2 - 1), n / 2, time0, time1);
            right = new BVHNode(SplitList(l, n / 2, n - 1), n - n / 2, time0, time1);
            break;
        }
        AABB boxLeft  = new AABB();
        AABB boxRight = new AABB();

        if (!left.BoundingBox(time0, time1, out boxLeft) ||
            !right.BoundingBox(time0, time1, out boxRight))
        {
            throw new Exception();
        }
        box = SurroundingBox(boxLeft, boxRight);
    }
Пример #5
0
    public BvhNode(Hitable[] hitables, int start, int length, float time0, float time1)
    {
        // TODO recursive -> iteration loop
        IComparer <Hitable> comparer = null;

        switch ((int)(3.0f * Util.UnitRandFloat()))
        {
        case 0:
            comparer = Boundary.compareX;
            break;

        case 1:
            comparer = Boundary.compareY;
            break;

        case 2:
        default:
            comparer = Boundary.compareZ;
            break;
        }
        System.Array.Sort(hitables, start, length, comparer);
        var halfLength = length / 2;

        switch (length)
        {
        case 1:
            left_  = hitables[start];
            right_ = hitables[start];
            break;

        case 2:
            left_  = hitables[start];
            right_ = hitables[start + 1];
            break;

        default:
            left_  = new BvhNode(hitables, start, halfLength, time0, time1);
            right_ = new BvhNode(hitables, start + halfLength, length - halfLength, time0, time1);
            break;
        }
        var boxLeft = left_.BoundingBox(time0, time1);

        if (!boxLeft.IsValid())
        {
            Debug.Log("no bounding box detected.");
        }
        var boxRight = right_.BoundingBox(time0, time1);

        if (!boxRight.IsValid())
        {
            Debug.Log("no bounding box detected.");
        }
        boundary_ = Boundary.SurroundingBoundary(boxLeft, boxRight);
    }
Пример #6
0
 public override bool BoundingBox(double t0, double t1, out AABB box)
 {
     if (ptr.BoundingBox(t0, t1, out box))
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
Пример #7
0
 public override 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);
     }
 }
Пример #8
0
        private int BoxZCompare(Hitable a, Hitable b)
        {
            var left  = new AABB();
            var right = new AABB();

            if (!a.BoundingBox(ref left) || !b.BoundingBox(ref right))
            {
                throw new System.Exception("No bounding box in bvh_node constructor");
            }

            if (left.Min.Z - right.Min.Z < 0.0f)
            {
                return(-1);
            }

            return(1);
        }
Пример #9
0
        private int compareHitableForSortingZ(Hitable a, Hitable b)
        {
            AxisAlignedBoundingBox boxLeft, boxRight;

            if (!a.BoundingBox(0, 0, out boxLeft) || !b.BoundingBox(0, 0, out boxRight))
            {
                throw new Exception("No Bounding Box in BvhNode Constructor.");
            }

            if (boxLeft.Min().Z() - boxRight.Min().Z() < 0.0)
            {
                return(-1);
            }
            else
            {
                return(1);
            }
        }
Пример #10
0
        public RotateY(Hitable hitable, double angle)
        {
            _hitable = hitable;

            double radians = (Math.PI / 180.0) * angle;

            _sinTheta = Math.Sin(radians);
            _cosTheta = Math.Cos(radians);
            _hasbox   = _hitable.BoundingBox(0, 1, out _bbox);

            Vec3 min = new Vec3(double.MaxValue, double.MaxValue, double.MaxValue);
            Vec3 max = new Vec3(-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;
                        Vec3   tester = new Vec3(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 AxisAlignedBoundingBox(min, max);
        }
Пример #11
0
        public RotateY(Hitable p, float angle)
        {
            Object = p;
            var radians = (Mathf.PI / 180f) * angle;

            sin_theta = Mathf.Sin(radians);
            cos_theta = Mathf.Cos(radians);
            hasbox    = Object.BoundingBox(0, 1, ref bbox);
            var min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
            var max = new Vector3(-float.MaxValue, -float.MaxValue, -float.MaxValue);

            for (var i = 0; i < 2; i++)
            {
                for (var j = 0; j < 2; j++)
                {
                    for (var k = 0; k < 2; k++)
                    {
                        var x      = i * bbox.max.x + (1 - i) * bbox.min.x;
                        var y      = j * bbox.max.y + (1 - j) * bbox.min.y;
                        var z      = k * bbox.max.z + (1 - k) * bbox.min.z;
                        var newx   = cos_theta * x + sin_theta * z;
                        var newz   = -sin_theta * x + cos_theta * z;
                        var tester = new Vector3(newx, y, newz);
                        for (var 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);
        }
Пример #12
0
    public RotateY(Hitable 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);
    }
Пример #13
0
 public override bool BoundingBox(float t0, float t1, ref AABB box)
 {
     return(boundary.BoundingBox(t0, t1, ref box));
 }
Пример #14
0
 public override bool BoundingBox(double t0, double t1, out AABB box)
 {
     box = new AABB(new Vector3D(), new Vector3D());
     return(ptr.BoundingBox(t0, t1, out box));
 }
Пример #15
0
 public override bool BoundingBox(double t0, double t1, out AABB box)
 {
     return(boundary.BoundingBox(t0, t1, out box));
 }