예제 #1
0
        public RotateY(Hitable p, double angle)
        {
            Object = p;
            double radians = (Math.PI / 180f) * angle;

            sin_theta = Math.Sin(radians);
            cos_theta = Math.Cos(radians);
            hasbox    = Object.BoundingBox(0, 1, ref 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   = cos_theta * x + sin_theta * z;
                        double   newz   = -sin_theta * x + cos_theta * 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);
        }
예제 #2
0
 public ConstantMedium(Hitable b, double d, Texture a)
 {
     boundary       = b;
     density        = d;
     phase_function = new Isotropic(a);
 }
예제 #3
0
 public FilpNormals(Hitable p)
 {
     hitable = p;
 }
예제 #4
0
 public Translate(Hitable p, Vector3D displace)
 {
     offset = displace;
     Object = p;
 }
예제 #5
0
        public BVHNode(Hitable[] p, int n, double time0, double 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);
            }

            //随机一个轴,x轴:0 y轴:1 z轴:3
            int method = (int)(3 * Mathematics.Random.Get());

            //转换为List然后使用排序,最后再转换会Array
            //排序规则使用lambda表达式转向比较函数,并加入轴向参数
            List <Hitable> temp_list = p.ToList();

            temp_list.Sort((a, b) => Compare(a, b, method));
            p = temp_list.ToArray();

            //检测当前子节点数量,如果大于2则继续分割
            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);
            }
        }