static void blob_merge(struct blob* b1, struct blob* b2) // merge b2 into b1, does not deal with sibs { b1->center_x = ((b1->center_x * b1->size) + (b2->center_x * b2->size)) / (b1->size + b2->size); b1->center_y = ((b1->center_y * b1->size) + (b2->center_y * b2->size)) / (b1->size + b2->size); b1->size += b2->size; bbox_update(b1, b2->bb_x1, b2->bb_x2, b2->bb_y1, b2->bb_y2); }
// Build a BVH for the triangles in the scene void bvh_build(void) { boundingbox bbox; int estimated_num_leafs; // Compute the bounding box of all the triangles. // This equals the bounding box of all the vertices (assuming // all vertices are actually used) bbox = bbox_create(); for (int i = 0; i < scene_num_vertices; i++) bbox_update(&bbox, scene_vertices[i]); printf("bvh_build():\n"); printf("... scene bounding box:\n"); printf("... (min) %.3f, %.3f, %.3f\n", bbox.min.x, bbox.min.y, bbox.min.z); printf("... (max) %.3f, %.3f, %.3f\n", bbox.max.x, bbox.max.y, bbox.max.z); num_leafs = 0; num_inner_nodes = 0; max_leaf_size = 0; // A balanced BVH built fully to depth D wil have // 2^(D-1)-1 inner nodes // and // 2^(D-1) leaf nodes // Divide the total number of triangles to store by acceptable_leaf_size // to get an estimate of the number of leaf nodes needed. Then, set // the maximum depth to a value that will allow that number of // leafs to be reached. // As the tree in reality will almost always not be balanced, this // does not guarantee that there won't be instances in which the // maximum depth is reached and a leaf needs to be created. So we // add 10 more levels just to be sure :) estimated_num_leafs = (int)(1.0 * scene_num_triangles / acceptable_leaf_size + 0.5); printf("... Estimated number of leaf nodes needed = %d\n", estimated_num_leafs); max_depth = 10 + ceil(1 + log10(estimated_num_leafs) / log10(2.0)); printf("... Setting max_depth to %d\n", max_depth); // Build the BVH bvh_root = bvh_build_recursive(1, bbox, scene_triangles, scene_num_triangles); // Done printf("Done building BVH for %d scene triangles\n", scene_num_triangles); printf("... tree has %d leaf nodes, %d inner nodes\n", num_leafs, num_inner_nodes); printf("... maximum leaf size %d\n", max_leaf_size); }
static void blob_update(struct blob* b, int x1, int x2, int y) { int s2; s2 = 1 + x2 - x1; b->x1 = x1; b->x2 = x2; b->y = y; b->center_x = ((b->center_x * b->size) + (x1+x2)*s2/2)/(b->size + s2); b->center_y = ((b->center_y * b->size) + (y * s2))/(b->size + s2); b->size += s2; bbox_update(b, x1, x2, y, y); }
// Determine the bounding box that encloses the given triangles static boundingbox bound_triangles(triangle *triangles, int num_triangles) { int t, i; boundingbox bbox; bbox = bbox_create(); // Iterate over all triangles for (t = 0; t < num_triangles; t++) { // Iterate over this triangle's vertices for (i = 0; i < 3; i++) bbox_update(&bbox, scene_vertices[triangles[t].v[i]]); } return bbox; }