Example #1
0
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());
}
Example #2
0
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());
			}
		}
	}
}
Example #3
0
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());
}
Example #4
0
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());
			}
		}
	}
}