예제 #1
0
 public void Init(float t_min, float t_max)
 {
     if (hitable_list.Count > 0)
     {
         root = new BVH_Node(hitable_list, 0, hitable_list.Count - 1, t_min, t_max);
     }
 }
예제 #2
0
        public BVH_Node(List <Hitable> nodes, int start_index, int end_index, float t_min, float t_max)
        {
            //这里就不做nodes为null或者长度为0的考虑了,放到外面去做
            //参考raytracingnextweek的方法.每次随机选轴然后排序,然后平分两部分.不断二分直到只剩下1-2个节点.
            int node_num = end_index - start_index + 1;

            if (node_num == 1)
            {
                left_node  = nodes[start_index];
                right_node = null;//书的话是跟left一样.其实如果是这样的话,hit和构造包围盒都需要再判断.看个人喜欢吧
            }
            else if (node_num == 2)
            {
                left_node  = nodes[start_index];
                right_node = nodes[end_index];
            }
            else
            {
                switch ((int)utils.GenerateRandomNum(0, 3))
                {
                case 0:
                case 1:
                    nodes.Sort(start_index, node_num, new CompareInAxisX());
                    break;

                case 2:
                    nodes.Sort(start_index, node_num, new CompareInAxisY());
                    break;

                case 3:
                    nodes.Sort(start_index, node_num, new CompareInAxisZ());
                    break;
                }
                int mid = (start_index + end_index) / 2;//下面递归不会报错的,因为入口的时候就已经判断好了
                left_node  = new BVH_Node(nodes, start_index, mid, t_min, t_max);
                right_node = new BVH_Node(nodes, mid + 1, end_index, t_min, t_max);
            }

            AABB left  = null;
            AABB right = null;

            if (left_node != null)
            {
                left_node.GetBoundingBox(t_min, t_max, ref left);
            }
            if (right_node != null)
            {
                right_node.GetBoundingBox(t_min, t_max, ref right);
            }
            if (left != null && right != null)
            {
                aabb = AABB.GetSurroundingBox(left, right);
            }
            else
            {
                aabb = left != null ? left : right;
            }
        }