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); } }
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; } }