示例#1
0
        private int BoxCompare(IHittable a, IHittable b, int axis)
        {
            var boxA = a.BoundingBox();
            var boxB = b.BoundingBox();

            return(boxA.Min[axis].CompareTo(boxB.Min[axis]));
        }
示例#2
0
        private static int BoxCompare(IHittable a, IHittable b, int axis)
        {
            if (!a.BoundingBox(0, 1, out var boxA) ||
                !b.BoundingBox(0, 1, out var boxB))
            {
                throw new Exception("No bounding box found in BoxCompare!");
            }

            return(boxA.Min[axis].CompareTo(boxB.Min[axis]));
        }
示例#3
0
        public bool BoundingBox(double t0, double t1, out Aabb outputBox)
        {
            if (!Child.BoundingBox(t0, t1, out outputBox))
            {
                return(false);
            }

            outputBox = new Aabb
            {
                Min = outputBox.Min + Offset,
                Max = outputBox.Max + Offset
            };
            return(true);
        }
示例#4
0
        public RotateY(IHittable child, double angle)
        {
            Child = child;

            var radians = MathUtils.Deg2Rad(angle);

            SinTheta = Math.Sin(radians);
            CosTheta = Math.Cos(radians);
            HasBox   = Child.BoundingBox(0, 1, out var box);

            var min = new Vec3(MathUtils.Infinity, MathUtils.Infinity, MathUtils.Infinity);
            var max = new Vec3(-MathUtils.Infinity, -MathUtils.Infinity, -MathUtils.Infinity);

            for (var i = 0; i < 2; i++)
            {
                for (var j = 0; j < 2; j++)
                {
                    for (var k = 0; k < 2; k++)
                    {
                        var x = i * box.Max.x + (1 - i) * box.Min.x;
                        var y = j * box.Max.y + (1 - j) * box.Min.y;
                        var z = k * box.Max.z + (1 - k) * box.Min.z;

                        var newX = CosTheta * x + SinTheta * z;
                        var newZ = -SinTheta * x + CosTheta * z;

                        var tester = new Vec3(newX, y, newZ);

                        for (int c = 0; c < 3; c++)
                        {
                            min[c] = Math.Min(min[c], tester[c]);
                            max[c] = Math.Max(max[c], tester[c]);
                        }
                    }
                }
            }

            BBox = new Aabb
            {
                Min = min,
                Max = max
            };
        }
示例#5
0
        // https://raytracing.github.io/books/RayTracingTheNextWeek.html#boundingvolumehierarchies
        public BvhNode(List <IHittable> srcObjects, int start, int end, AbstractSampler <int> sampler = null)
        {
            sampler ??= new ThreadSafeSampler <int>(count => IntSampling.Random(count, 0, 3), SAMPLES);

            var objects = srcObjects;
            int axis    = sampler.GetSample();

            int Comparator(IHittable a, IHittable b) => BoxCompare(a, b, axis);

            int objectSpan = end - start;

            switch (objectSpan)
            {
            case 1:
                _left = _right = objects[start];
                break;

            case 2 when Comparator(objects[start], objects[start + 1]) < 0:
                _left = objects[start];

                _right = objects[start + 1];
                break;

            case 2:
                _left  = objects[start + 1];
                _right = objects[start];
                break;

            default:
                objects.Sort(start, objectSpan - 1, new FuncComparer <IHittable>(Comparator));
                int mid = start + objectSpan / 2;
                _left  = new BvhNode(objects, start, mid, sampler);
                _right = new BvhNode(objects, mid, end, sampler);
                break;
            }

            var boxLeft  = _left.BoundingBox();
            var boxRight = _right.BoundingBox();

            _box = boxLeft + boxRight;
        }
示例#6
0
        public BvhNode(List <IHittable> srcObjects, int start, int end, double t0, double t1)
        {
            var min = new Vec3(MathUtils.Infinity, MathUtils.Infinity, MathUtils.Infinity);
            var max = new Vec3(-MathUtils.Infinity, -MathUtils.Infinity, -MathUtils.Infinity);

            for (var i = start; i < end; i++)
            {
                srcObjects[i].BoundingBox(t0, t1, out var box);
                if (box.Min.x < min.x)
                {
                    min.x = box.Min.x;
                }
                if (box.Min.y < min.y)
                {
                    min.y = box.Min.y;
                }
                if (box.Min.z < min.z)
                {
                    min.z = box.Min.z;
                }
                if (box.Max.x > max.x)
                {
                    max.x = box.Max.x;
                }
                if (box.Max.y > max.y)
                {
                    max.y = box.Max.y;
                }
                if (box.Max.z > max.z)
                {
                    max.z = box.Max.z;
                }
            }

            var diffs = max - min;
            var axis  = 0;

            if (diffs.y > diffs.x && diffs.y > diffs.z)
            {
                axis = 1;
            }
            if (diffs.z > diffs.x && diffs.z > diffs.y)
            {
                axis = 2;
            }

            IComparer <IHittable> comparator;

            switch (axis)
            {
            case 0: comparator = new BoxCompareX(); break;

            case 1: comparator = new BoxCompareY(); break;

            default: comparator = new BoxCompareZ(); break;
            }

            var objSpan = end - start;

            if (objSpan == 1)
            {
                Left  = srcObjects[start];
                Right = srcObjects[start];
            }
            else if (objSpan == 2)
            {
                if (comparator.Compare(srcObjects[start], srcObjects[start + 1]) < 0)
                {
                    Left  = srcObjects[start];
                    Right = srcObjects[start + 1];
                }
                else
                {
                    Left  = srcObjects[start + 1];
                    Right = srcObjects[start];
                }
            }
            else
            {
                srcObjects.Sort(start, objSpan, comparator);
                var mid = start + objSpan / 2;
                Left  = new BvhNode(srcObjects, start, mid, t0, t1);
                Right = new BvhNode(srcObjects, mid, end, t0, t1);
            }

            if (!Left.BoundingBox(t0, t1, out var boxLeft) ||
                !Right.BoundingBox(t0, t1, out var boxRight))
            {
                throw new Exception("No bounding box in BvhNode constructor");
            }
            Box = Aabb.SurroundingBox(boxLeft, boxRight);
        }
示例#7
0
文件: ConstantMedium.cs 项目: rje/ray
 public bool BoundingBox(double t0, double t1, out Aabb outputBox)
 {
     return(Boundary.BoundingBox(t0, t1, out outputBox));
 }