void BVHSpatialSplit::split_reference(const BVHBuild& builder, BVHReference& left, BVHReference& right, const BVHReference& ref, int dim, float pos) { /* initialize boundboxes */ BoundBox left_bounds = BoundBox::empty; BoundBox right_bounds = BoundBox::empty; /* loop over vertices/edges. */ const Object *ob = builder.objects[ref.prim_object()]; const Mesh *mesh = ob->mesh; if(ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) { split_triangle_reference(ref, mesh, dim, pos, left_bounds, right_bounds); } else if(ref.prim_type() & PRIMITIVE_ALL_CURVE) { split_curve_reference(ref, mesh, dim, pos, left_bounds, right_bounds); } else { split_object_reference(ob, dim, pos, left_bounds, right_bounds); } /* intersect with original bounds. */ left_bounds.max[dim] = pos; right_bounds.min[dim] = pos; left_bounds.intersect(ref.bounds()); right_bounds.intersect(ref.bounds()); /* set references */ left = BVHReference(left_bounds, ref.prim_index(), ref.prim_object(), ref.prim_type()); right = BVHReference(right_bounds, ref.prim_index(), ref.prim_object(), ref.prim_type()); }
void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh, int i) { for(uint j = 0; j < mesh->triangles.size(); j++) { Mesh::Triangle t = mesh->triangles[j]; BoundBox bounds = BoundBox::empty; for(int k = 0; k < 3; k++) { float3 co = mesh->verts[t.v[k]]; bounds.grow(co); } if(bounds.valid()) { references.push_back(BVHReference(bounds, j, i, ~0)); root.grow(bounds); center.grow(bounds.center2()); } } for(uint j = 0; j < mesh->curves.size(); j++) { Mesh::Curve curve = mesh->curves[j]; for(int k = 0; k < curve.num_keys - 1; k++) { BoundBox bounds = BoundBox::empty; float3 co[4]; co[0] = mesh->curve_keys[max(curve.first_key + k - 1,curve.first_key)].co; co[1] = mesh->curve_keys[curve.first_key + k].co; co[2] = mesh->curve_keys[curve.first_key + k + 1].co; co[3] = mesh->curve_keys[min(curve.first_key + k + 2, curve.first_key + curve.num_keys - 1)].co; float3 lower; float3 upper; curvebounds(&lower.x, &upper.x, co, 0); curvebounds(&lower.y, &upper.y, co, 1); curvebounds(&lower.z, &upper.z, co, 2); float mr = max(mesh->curve_keys[curve.first_key + k].radius, mesh->curve_keys[curve.first_key + k + 1].radius); bounds.grow(lower, mr); bounds.grow(upper, mr); if(bounds.valid()) { references.push_back(BVHReference(bounds, j, i, k)); root.grow(bounds); center.grow(bounds.center2()); } } } }
void BVHBuild::add_reference_object(BoundBox& root, BoundBox& center, Object *ob, int i) { references.push_back(BVHReference(ob->bounds, -1, i, 0)); root.grow(ob->bounds); center.grow(ob->bounds.center2()); }
void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh, int i) { Attribute *attr_mP = NULL; if(mesh->has_motion_blur()) attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); for(uint j = 0; j < mesh->triangles.size(); j++) { Mesh::Triangle t = mesh->triangles[j]; BoundBox bounds = BoundBox::empty; PrimitiveType type = PRIMITIVE_TRIANGLE; t.bounds_grow(&mesh->verts[0], bounds); /* motion triangles */ if(attr_mP) { size_t mesh_size = mesh->verts.size(); size_t steps = mesh->motion_steps - 1; float3 *vert_steps = attr_mP->data_float3(); for(size_t i = 0; i < steps; i++) t.bounds_grow(vert_steps + i*mesh_size, bounds); type = PRIMITIVE_MOTION_TRIANGLE; } if(bounds.valid()) { references.push_back(BVHReference(bounds, j, i, type)); root.grow(bounds); center.grow(bounds.center2()); } } Attribute *curve_attr_mP = NULL; if(mesh->has_motion_blur()) curve_attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); for(uint j = 0; j < mesh->curves.size(); j++) { Mesh::Curve curve = mesh->curves[j]; PrimitiveType type = PRIMITIVE_CURVE; for(int k = 0; k < curve.num_keys - 1; k++) { BoundBox bounds = BoundBox::empty; curve.bounds_grow(k, &mesh->curve_keys[0], bounds); /* motion curve */ if(curve_attr_mP) { size_t mesh_size = mesh->curve_keys.size(); size_t steps = mesh->motion_steps - 1; float4 *key_steps = curve_attr_mP->data_float4(); for(size_t i = 0; i < steps; i++) curve.bounds_grow(k, key_steps + i*mesh_size, bounds); type = PRIMITIVE_MOTION_CURVE; } if(bounds.valid()) { int packed_type = PRIMITIVE_PACK_SEGMENT(type, k); references.push_back(BVHReference(bounds, j, i, packed_type)); root.grow(bounds); center.grow(bounds.center2()); } } } }