/* get cost of sah(surface area heuristic) method for certain plane */ double get_sah_cost(double plane, aabb &voxel, int num_left, int num_right) { aabb voxel_left, voxel_right; voxel.split_aabb(dim, plane, voxel_left, voxel_right); double sa_left = voxel_left.get_surface_area(); double sa_right = voxel_right.get_surface_area(); double sa_union = voxel.get_surface_area(); return get_cost(sa_left / sa_union, sa_right / sa_union, num_left, num_right); }
/* build kd-tree */ kdtree::kdtree(aabb &voxel, vector<primitive*> &pris, int depth, kdtree* parent) { parent_kdtree = parent; left_kdtree = right_kdtree = NULL; bbox = voxel; /* end criteria; make this leaf */ if (depth > maximum_depth || pris.size() < 1) { primitives = pris; } /* general case: determine whether and how to devide current voxel */ else { double cost_asleaf = cost_i * pris.size(); cost_min = 1E100; for (dim = 0; dim < 3; dim++) { get_best_plane(pris, voxel); } /* internal node; divide further */ if (cost_min < cost_asleaf) { vector<primitive*> left_pris, right_pris; classify_primitives(pris, best_plane, left_pris, right_pris); aabb left_voxel, right_voxel; voxel.split_aabb(best_dim, best_plane, left_voxel, right_voxel); left_kdtree = new kdtree(left_voxel, left_pris, depth + 1, this); right_kdtree = new kdtree(right_voxel, right_pris, depth + 1, this); } /* leaf; division end */ else { primitives = pris; } } }