public BVHNode(Hitable[] p, int n, float time0, float time1)
        {
            int Compare(Hitable a, Hitable b, int i)
            {
                AABB l = new AABB(), r = new AABB();

                if (!a.BoundingBox(0, 0, ref l) || !b.BoundingBox(0, 0, ref r))
                {
                    throw new Exception("NULL");
                }
                return(l.min[i] - r.min[i] < 0 ? -1 : 1);
            }

            Hitable[] SplitArray(Hitable[] Source, int StartIndex, int EndIndex)
            {
                Hitable[] result = new Hitable[EndIndex - StartIndex + 1];
                for (int i = 0; i <= EndIndex - StartIndex; i++)
                {
                    result[i] = Source[i + StartIndex];
                }
                return(result);
            }

            var pl     = p.ToList();
            var method = (int)(3 * Mathematics.Random.Get());

            pl.Sort((a, b) => Compare(a, b, method));
            p = pl.ToArray();
            //Console.ReadLine();
            switch (n)
            {
            case 1:
                left = right = p[0];
                break;

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

            default:
                left  = new BVHNode(SplitArray(p, 0, n / 2 - 1), n / 2, time0, time1);
                right = new BVHNode(SplitArray(p, n / 2, n - 1), n - n / 2, time0, time1);
                break;
            }
            AABB box_left = new AABB(), box_right = new AABB();

            if (!left.BoundingBox(time0, time1, ref box_left) || !right.BoundingBox(time0, time1, ref box_right))
            {
                throw new Exception("no bounding box in bvh_node constructor");
            }
            box = GetBox(box_left, box_right);
            if (n == 6)
            {
                Console.WriteLine("结果" + this);
            }
        }
        public RotateY(Hitable p, float angle)
        {
            Object = p;
            float 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++)
                    {
                        float x      = i * bbox.max.x + (1 - i) * bbox.min.x;
                        float y      = j * bbox.max.y + (1 - j) * bbox.min.y;
                        float z      = k * bbox.max.z + (1 - k) * bbox.min.z;
                        float newx   = cos_theta * x + sin_theta * z;
                        float newz   = -sin_theta * x + cos_theta * z;
                        var   tester = new Vector3(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);
        }
Example #3
0
 public FilpNormals(Hitable p) => hitable = p;
 public ConstantMedium(Hitable b, float d, Texture a)
 {
     boundary       = b;
     density        = d;
     phase_function = new Isotropic(a);
 }
 public Translate(Hitable p, Vector3 displace)
 {
     offset = displace;
     Object = p;
 }
 public FilpNormals(Hitable p)
 {
     hitable = p;
 }