int BVHModel<BV>::recursiveBuildTree(int bv_id, int first_primitive, int num_primitives) { BVHModelType type = getModelType(); BVNode<BV>* bvnode = bvs + bv_id; unsigned int* cur_primitive_indices = primitive_indices + first_primitive; // constructing BV BV bv = bv_fitter.fit(cur_primitive_indices, num_primitives); bv_splitter.computeRule(bv, cur_primitive_indices, num_primitives); bvnode->bv = bv; bvnode->first_primitive = first_primitive; bvnode->num_primitives = num_primitives; if(num_primitives == 1) { bvnode->first_child = -((*cur_primitive_indices) + 1); } else { bvnode->first_child = num_bvs; num_bvs += 2; int c1 = 0; for(int i = 0; i < num_primitives; ++i) { Vec3f p; if(type == BVH_MODEL_POINTCLOUD) p = vertices[cur_primitive_indices[i]]; else if(type == BVH_MODEL_TRIANGLES) { const Triangle& t = tri_indices[cur_primitive_indices[i]]; const Vec3f& p1 = vertices[t[0]]; const Vec3f& p2 = vertices[t[1]]; const Vec3f& p3 = vertices[t[2]]; BVH_REAL x = (p1[0] + p2[0] + p3[0]) / 3; BVH_REAL y = (p1[1] + p2[1] + p3[1]) / 3; BVH_REAL z = (p1[2] + p2[2] + p3[2]) / 3; p = Vec3f(x, y, z); } else { std::cerr << "BVH Error: Model type not supported!" << std::endl; return BVH_ERR_UNSUPPORTED_FUNCTION; } // loop invariant: up to (but not including) index c1 in group 1, // then up to (but not including) index i in group 2 // // [1] [1] [1] [1] [2] [2] [2] [x] [x] ... [x] // c1 i // if(bv_splitter(p)) // in the right side { // do nothing } else { unsigned int temp = cur_primitive_indices[i]; cur_primitive_indices[i] = cur_primitive_indices[c1]; cur_primitive_indices[c1] = temp; c1++; } } if((c1 == 0) || (c1 == num_primitives)) c1 = num_primitives / 2; int num_first_half = c1; recursiveBuildTree(bvnode->leftChild(), first_primitive, num_first_half); recursiveBuildTree(bvnode->rightChild(), first_primitive + num_first_half, num_primitives - num_first_half); } return BVH_OK; }
int BVHModel<BV>::recursiveRefitTree_bottomup(int bv_id) { BVNode<BV>* bvnode = bvs + bv_id; if(bvnode->isLeaf()) { BVHModelType type = getModelType(); int primitive_id = -(bvnode->first_child + 1); if(type == BVH_MODEL_POINTCLOUD) { BV bv; if(prev_vertices) { Vec3f v[2]; v[0] = prev_vertices[primitive_id]; v[1] = vertices[primitive_id]; fit(v, 2, bv); } else fit(vertices + primitive_id, 1, bv); bvnode->bv = bv; } else if(type == BVH_MODEL_TRIANGLES) { BV bv; const Triangle& triangle = tri_indices[primitive_id]; if(prev_vertices) { Vec3f v[6]; for(int i = 0; i < 3; ++i) { v[i] = prev_vertices[triangle[i]]; v[i + 3] = vertices[triangle[i]]; } fit(v, 6, bv); } else { Vec3f v[3]; for(int i = 0; i < 3; ++i) { v[i] = vertices[triangle[i]]; } fit(v, 3, bv); } bvnode->bv = bv; } else { std::cerr << "BVH Error: Model type not supported!" << std::endl; return BVH_ERR_UNSUPPORTED_FUNCTION; } } else { recursiveRefitTree_bottomup(bvnode->leftChild()); recursiveRefitTree_bottomup(bvnode->rightChild()); bvnode->bv = bvs[bvnode->leftChild()].bv + bvs[bvnode->rightChild()].bv; } return BVH_OK; }