Beispiel #1
0
/*
 * Recursively builds the BVH starting at the given node with the given
 * first and last primitive indices (in bag).
 */
size_t BVH4::recursive_build(size_t parent, size_t first_prim, size_t last_prim)
{
	// Allocate the node
	const size_t me = build_nodes.size();
	build_nodes.push_back(BuildNode());


	build_nodes[me].flags = 0;
	build_nodes[me].parent_index = parent;

	if (first_prim == last_prim) {
		// Leaf node

		build_nodes[me].flags |= IS_LEAF;
		build_nodes[me].data = prim_bag[first_prim].data;

		// Copy bounding boxes
		build_nodes[me].bbox_index = build_bboxes.size();
		build_nodes[me].ts = prim_bag[first_prim].data->bounds().size();
		for (size_t i = 0; i < build_nodes[me].ts; i++)
			build_bboxes.push_back(prim_bag[first_prim].data->bounds()[i]);
	} else {
		// Not a leaf node

		// Create child nodes
		uint32_t split_index = split_primitives(first_prim, last_prim);
		const size_t child1i = recursive_build(me, first_prim, split_index);
		const size_t child2i = recursive_build(me, split_index+1, last_prim);

		build_nodes[me].child_index = child2i;


		// Calculate bounds
		build_nodes[me].bbox_index = build_bboxes.size();
		// If both children have same number of time samples
		if (build_nodes[child1i].ts == build_nodes[child2i].ts) {
			build_nodes[me].ts = build_nodes[child1i].ts;

			// Copy merged bounding boxes
			for (size_t i = 0; i < build_nodes[me].ts; i++) {
				build_bboxes.push_back(build_bboxes[build_nodes[child1i].bbox_index+i]);
				build_bboxes.back().merge_with(build_bboxes[build_nodes[child2i].bbox_index+i]);
			}

		}
		// If children have different number of time samples
		else {
			build_nodes[me].ts = 1;

			// Merge children's bboxes to get our bbox
			build_bboxes.push_back(build_bboxes[build_nodes[child1i].bbox_index]);
			for (size_t i = 1; i < build_nodes[child1i].ts; i++)
				build_bboxes.back().merge_with(build_bboxes[build_nodes[child1i].bbox_index+i]);
			for (size_t i = 0; i < build_nodes[child2i].ts; i++)
				build_bboxes.back().merge_with(build_bboxes[build_nodes[child2i].bbox_index+i]);
		}
	}

	return me;
}
Beispiel #2
0
		result_type operator() (conditional_defn_node const& conditional)
		{
			for(auto const& comp : conditional.components_)
			{
				recursive_build(g_, comp.nd, conditional, nd_map_);
			}
			if(conditional.default_)
			{
				recursive_build(g_, conditional.default_, conditional, nd_map_);
			}
		}
Beispiel #3
0
size_t LightTree::recursive_build(std::vector<LightTree::BuildNode>::iterator start, std::vector<LightTree::BuildNode>::iterator end) {
	// Allocate the node
	const size_t me = nodes.size();
	nodes.push_back(Node());

	if ((start + 1) == end) {
		// Leaf node
		const Instance& instance = assembly->instances[start->instance_index];

		nodes[me].is_leaf = true;
		nodes[me].instance_index = start->instance_index;

		// Get bounds
		if (instance.type == Instance::OBJECT) {
			nodes[me].bounds = assembly->instance_bounds(start->instance_index);
		} else if (instance.type == Instance::ASSEMBLY) {
			const Assembly* assmb = assembly->assemblies[instance.data_index].get();
			if (instance.transform_count > 0) {
				auto xstart = assembly->xforms.cbegin() + instance.transform_index;
				auto xend = xstart + instance.transform_count;
				nodes[me].bounds = transform_from(assmb->light_accel.bounds(), xstart, xend);
			} else {
				nodes[me].bounds = assmb->light_accel.bounds();
			}
		}

		// Copy energy
		nodes[me].energy = start->energy;
	} else {
		// Not a leaf node
		nodes[me].is_leaf = false;

		// Create child nodes
		auto split_itr = split_lights(start, end);
		const size_t c1 = recursive_build(start, split_itr);
		const size_t c2 = recursive_build(split_itr, end);
		nodes[me].index1 = c1;
		nodes[me].index2 = c2;

		// Calculate bounds
		nodes[me].bounds = merge(nodes[c1].bounds, nodes[c2].bounds);

		// Calculate energy
		nodes[me].energy = nodes[c1].energy + nodes[c2].energy;
	}

	return me;
}
Beispiel #4
0
		result_type operator() (composite_defn_node const& composite)
		{
			auto children = composite.children();
			for(auto const& c_dn : children)
			{
				recursive_build(g_, c_dn.second, composite, nd_map_);
			}
		}
 bool randomize() override {
   if (!built_) {
     gen_ = std::make_shared<Generator>();
     recursive_build(*gen_);
     built_ = true;
   }
   return gen_->nextCov();
 }
Beispiel #6
0
 bool randomize_with(Exprs... exprs) {
   // TODO Generator caching
   rand_with_gen_ = std::make_shared<Generator>();
   recursive_build(*rand_with_gen_);
   expression_list list(exprs...);
   for (auto e : list) (*rand_with_gen_)(e);
   return rand_with_gen_->next();
 }
Beispiel #7
0
void LightTree::build(const Assembly& assembly_) {
	assembly = &assembly_;

	// Populate the build nodes
	for (size_t i = 0; i < assembly->instances.size(); ++i) {
		const auto& instance = assembly->instances[i]; // Shorthand

		// If it's an object
		if (instance.type == Instance::OBJECT) {
			const Object* obj = assembly->objects[instance.data_index].get(); // Shorthand

			if (obj->total_emitted_color().energy() > 0.0f) {
				build_nodes.push_back(BuildNode());
				build_nodes.back().instance_index = i;
				build_nodes.back().bbox = assembly->instance_bounds_at(0.5f, i);
				build_nodes.back().center = build_nodes.back().bbox.center();
				const Vec3 scale = assembly->instance_xform_at(0.5f, i).get_inv_scale();
				const float surface_scale = ((scale[0]*scale[1]) + (scale[0]*scale[2]) + (scale[1]*scale[2])) * 0.33333333f;
				build_nodes.back().energy = obj->total_emitted_color().energy() / surface_scale;

				++total_lights;
			}
		}
		// If it's an assembly
		else if (instance.type == Instance::ASSEMBLY) {
			const Assembly* asmb = assembly->assemblies[instance.data_index].get(); // Shorthand
			const auto count = asmb->light_accel.light_count();
			const float energy = asmb->light_accel.total_emitted_color().energy();

			if (count > 0 && energy > 0.0f) {
				build_nodes.push_back(BuildNode());
				build_nodes.back().instance_index = i;
				if (instance.transform_count > 0) {
					auto xstart = assembly->xforms.cbegin() + instance.transform_index;
					auto xend = xstart + instance.transform_count;
					build_nodes.back().bbox = lerp_seq(0.5f, asmb->light_accel.bounds()).inverse_transformed(lerp_seq(0.5f, xstart, xend));
				} else {
					build_nodes.back().bbox = lerp_seq(0.5f, asmb->light_accel.bounds());
				}
				build_nodes.back().center = build_nodes.back().bbox.center();
				const Vec3 scale = assembly->instance_xform_at(0.5f, i).get_inv_scale();
				const float surface_scale = ((scale[0]*scale[1]) + (scale[0]*scale[2]) + (scale[1]*scale[2])) * 0.33333333f;
				build_nodes.back().energy = energy / surface_scale;

				total_lights += count;
			}
		}
	}

	if (build_nodes.size() > 0) {
		recursive_build(build_nodes.begin(), build_nodes.end());
		bounds_ = nodes[0].bounds;
		total_energy = nodes[0].energy;
	} else {
		bounds_.clear();
		bounds_.emplace_back(BBox());
	}
}
Beispiel #8
0
	// TODO: Currently this includes child->parent dependencies.
	defn_dep_graph build_defn_dependency_graph(defn_node dn)
	{
		defn_dep_graph g;
		if(!dn)
		{
			return g;
		}

		defn_build_node_map_t nd_map;
		recursive_build(g, dn, nd_map);
		return g;
	}
Beispiel #9
0
	defn_dep_graph build_defn_dependency_graph(defn_node hierarchy_root, defn_node dep_root)
	{
		defn_dep_graph g;
		if(!hierarchy_root || !dep_root)
		{
			return g;
		}

		// Build up the complete dependency graph
		defn_build_node_map_t nd_map;
		recursive_build(g, hierarchy_root, defn_node{}, nd_map);

		// And then get the subgraph of nodes dependent on nref
		dependent_upon(g, dep_root);
		return g;
	}
Beispiel #10
0
bool BVH4::finalize()
{
	if (prim_bag.size() == 0)
		return true;

	// Build BVH
	recursive_build(0, 0, prim_bag.size()-1);

	// Pack BVH into more efficient form
	pack();

	// Empty the temporary build sets
	prim_bag.clear();
	build_nodes.clear();
	build_bboxes.clear();

	return true;
}
Beispiel #11
0
		result_type operator() (list_defn_node const& list)
		{
			auto entry_dn = list.entrydefn();
			recursive_build(g_, entry_dn, list, nd_map_);
		}