Commit d95650f3 authored by TheNumbat's avatar TheNumbat
Browse files

remove bvh.cpp

parent c2e97d52
#include "../rays/bvh.h"
#include "debug.h"
#include <stack>
namespace PT {
template <typename Primitive>
void BVH<Primitive>::build(std::vector<Primitive> &&prims, size_t max_leaf_size) {
// NOTE (PathTracer):
// This BVH is parameterized on the type of the primitive it contains. This allows
// us to build a BVH over any type that defines a certain interface. Specifically,
// we use this to both build a BVH over triangles within each Tri_Mesh, and over
// a variety of Objects (which might be Tri_Meshes, Spheres, etc.) in Pathtracer.
//
// The Primitive interface must implement these two functions:
// BBox bbox() const;
// Trace hit(const Ray& ray) const;
// Hence, you may call bbox() and hit() on any value of type Primitive.
//
// Finally, also note that while a BVH is a tree structure, our BVH nodes don't
// contain pointers to children, but rather indicies. This is because instead
// of allocating each node individually, the BVH class contains a vector that
// holds all of the nodes. Hence, to get the child of a node, you have to
// look up the child index in this vector (e.g. nodes[node.l]). Similarly,
// to create a new node, don't allocate one yourself - use BVH::new_node, which
// returns the index of a newly added node.
nodes.clear();
primitives = std::move(prims);
// TODO (PathTracer): Task 3
// Construct a BVH from the given vector of primitives and maximum leaf
// size configuration. The starter code builds a BVH with a
// single leaf node (which is also the root) that encloses all the
// primitives.
BBox box;
for (const Primitive &prim : primitives)
box.enclose(prim.bbox());
new_node(box, 0, primitives.size(), 0, 0);
}
template <typename Primitive> Trace BVH<Primitive>::hit(const Ray &ray) const {
// TODO (PathTracer): Task 3
// Implement ray - BVH intersection test. A ray intersects
// with a BVH aggregate if and only if it intersects a primitive in
// the BVH that is not an aggregate.
// The starter code simply iterates through all the primitives.
// Again, remember you can use hit() on any Primitive value.
Trace ret;
for (const Primitive &prim : primitives) {
Trace hit = prim.hit(ray);
ret = Trace::min(ret, hit);
}
return ret;
}
template <typename Primitive>
BVH<Primitive>::BVH(std::vector<Primitive> &&prims, size_t max_leaf_size) {
build(std::move(prims), max_leaf_size);
}
template <typename Primitive> bool BVH<Primitive>::Node::is_leaf() const {
return l == 0 && r == 0;
}
template <typename Primitive>
size_t BVH<Primitive>::new_node(BBox box, size_t start, size_t size, size_t l, size_t r) {
Node n;
n.bbox = box;
n.start = start;
n.size = size;
n.l = l;
n.r = r;
nodes.push_back(n);
return nodes.size() - 1;
}
template <typename Primitive> BBox BVH<Primitive>::bbox() const { return nodes[0].bbox; }
template <typename Primitive> std::vector<Primitive> BVH<Primitive>::destructure() {
nodes.clear();
return std::move(primitives);
}
template <typename Primitive> void BVH<Primitive>::clear() {
nodes.clear();
primitives.clear();
}
template <typename Primitive>
size_t BVH<Primitive>::visualize(GL::Lines &lines, GL::Lines &active, size_t level,
const Mat4 &trans) const {
std::stack<std::pair<size_t, size_t>> tstack;
tstack.push({0, 0});
size_t max_level = 0;
if (nodes.empty())
return max_level;
while (!tstack.empty()) {
auto [idx, lvl] = tstack.top();
max_level = std::max(max_level, lvl);
const Node &node = nodes[idx];
tstack.pop();
Vec3 color = lvl == level ? Vec3(1.0f, 0.0f, 0.0f) : Vec3(1.0f);
GL::Lines &add = lvl == level ? active : lines;
BBox box = node.bbox;
box.transform(trans);
Vec3 min = box.min, max = box.max;
auto edge = [&](Vec3 a, Vec3 b) { add.add(a, b, color); };
edge(min, Vec3{max.x, min.y, min.z});
edge(min, Vec3{min.x, max.y, min.z});
edge(min, Vec3{min.x, min.y, max.z});
edge(max, Vec3{min.x, max.y, max.z});
edge(max, Vec3{max.x, min.y, max.z});
edge(max, Vec3{max.x, max.y, min.z});
edge(Vec3{min.x, max.y, min.z}, Vec3{max.x, max.y, min.z});
edge(Vec3{min.x, max.y, min.z}, Vec3{min.x, max.y, max.z});
edge(Vec3{min.x, min.y, max.z}, Vec3{max.x, min.y, max.z});
edge(Vec3{min.x, min.y, max.z}, Vec3{min.x, max.y, max.z});
edge(Vec3{max.x, min.y, min.z}, Vec3{max.x, max.y, min.z});
edge(Vec3{max.x, min.y, min.z}, Vec3{max.x, min.y, max.z});
if (node.l)
tstack.push({node.l, lvl + 1});
if (node.r)
tstack.push({node.r, lvl + 1});
if (!node.l && !node.r) {
for (size_t i = node.start; i < node.start + node.size; i++) {
size_t c = primitives[i].visualize(lines, active, level - lvl, trans);
max_level = std::max(c, max_level);
}
}
}
return max_level;
}
} // namespace PT
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment