Skip to content
Snippets Groups Projects
Commit e8fab659 authored by Yoel's avatar Yoel
Browse files

Optimized 2.0

parent b44480af
No related branches found
No related tags found
No related merge requests found
......@@ -3,6 +3,7 @@
#include "TriangleMesh.h"
#include <cassert>
#include <limits>
#include <sstream>
#include <string>
......@@ -23,7 +24,57 @@ TriangleMesh::TriangleMesh(std::istream& in,
hierarch(0, v);
}
std::optional<cam::Hit> TriangleMesh::intersect(const cam::Ray& r) const {
return std::nullopt;
return intersect(0, r);
}
std::optional<cam::Hit> TriangleMesh::intersect(size_t i,
const cam::Ray& r) const {
std::array<cam::Hit, 3> hits = {
cam::Hit(util::Vec3(0), util::Vec3(0),
std::numeric_limits<float>::infinity(), nullptr),
cam::Hit(util::Vec3(0), util::Vec3(0),
std::numeric_limits<float>::infinity(), nullptr),
cam::Hit(util::Vec3(0), util::Vec3(0),
std::numeric_limits<float>::infinity(), nullptr)};
// Check left
size_t left_i = hierarchy[i].left;
std::optional<cam::Hit> left_hit = std::nullopt;
if (left_i != -1) left_hit = intersect(left_i, r);
hits[0] = left_hit.value_or(cam::Hit(util::Vec3(0), util::Vec3(0),
std::numeric_limits<float>::infinity(),
nullptr));
// Check right
size_t right_i = hierarchy[i].right;
std::optional<cam::Hit> right_hit = std::nullopt;
if (right_i != -1) right_hit = intersect(right_i, r);
hits[1] = right_hit.value_or(
cam::Hit(util::Vec3(0), util::Vec3(0),
std::numeric_limits<float>::infinity(), nullptr));
std::optional<cam::Hit> temp = std::nullopt;
std::optional<cam::Hit> mid_hit = std::nullopt;
int_fast16_t bound = hierarchy[i].leaves_i + hierarchy[i].leaves_size - 1;
assert(!(hierarchy[i].leaves_i == -1 ^ hierarchy[i].leaves_size == -1));
for (size_t tri_i = hierarchy[i].leaves_i; tri_i <= bound; tri_i++) {
auto tri = leaves[tri_i];
std::optional<cam::Hit> temp = tri.intersect(r);
if (temp) {
if (r.in_range(temp->scalar())) {
if (!mid_hit) {
mid_hit = temp;
} else if (mid_hit->scalar() > temp->scalar()) {
mid_hit = temp;
}
}
}
}
hits[2] = mid_hit.value_or(cam::Hit(util::Vec3(0), util::Vec3(0),
std::numeric_limits<float>::infinity(),
nullptr));
std::sort(hits.begin(), hits.end(),
[](cam::Hit a, cam::Hit b) { return a.scalar() < b.scalar(); });
if (hits[0].material == nullptr) return std::nullopt;
// for (auto hit : hits) std::cout << hit << std::endl;
return hits[0];
}
util::AxisAlignedBoundingBox TriangleMesh::bounds() const {
return hierarchy[0].bb;
......@@ -44,7 +95,6 @@ util::AxisAlignedBoundingBox TriangleMesh::initBB() {
void TriangleMesh::hierarch(size_t i,
std::vector<std::shared_ptr<Triangle>> v) {
if (v.empty()) return;
auto bb_pair = util::splitAABB(hierarchy[i].bb);
TriMeshNode left({bb_pair[0], -1, -1, -1, -1});
TriMeshNode right({bb_pair[1], -1, -1, -1, -1});
......@@ -57,31 +107,42 @@ void TriangleMesh::hierarch(size_t i,
} else if (right.bb.contains(tri_ptr->bounds())) {
right_non_leaves.push_back(tri_ptr);
} else {
if (!left.bb.partiallyContains(tri_ptr->bounds())) {
std::cout << "Node " << hierarchy[i].bb << std::endl;
std::cout << left.bb << "//////" << tri_ptr->bounds()
<< std::endl;
}
assert(left.bb.partiallyContains(tri_ptr->bounds()));
assert(right.bb.partiallyContains(tri_ptr->bounds()));
middle.push_back(tri_ptr);
}
}
// std::cout << depth << " Left: " << left.shapeList.size() << std::endl;
// std::cout << depth << " Right: " << right.shapeList.size() << std::endl;
// std::cout << depth << " Middle: " << group.shapeList.size() << std::endl;
// std::cout << depth << " Left: " << left.shapeList.size() <<
// std::endl; std::cout << depth << " Right: " << right.shapeList.size()
// << std::endl; std::cout << depth << " Middle: " <<
// group.shapeList.size() << std::endl;
// Handle middle leaves
hierarchy[i].leaves_i = leaves.size();
hierarchy[i].leaves_size = middle.size();
for (auto tri_ptr : middle) leaves.push_back(*tri_ptr);
if (!middle.empty()) {
hierarchy[i].leaves_i = leaves.size();
hierarchy[i].leaves_size = middle.size();
for (auto tri_ptr : middle) leaves.push_back(*tri_ptr);
}
// Handle left box
hierarchy.push_back(left);
std::cout << i << std::endl;
hierarchy[i].left = hierarchy.size();
if (!left_non_leaves.empty()) {
hierarchy[i].left = hierarchy.size();
hierarchy.push_back(left);
}
// Handle right box
hierarchy.push_back(right);
hierarchy[i].right = hierarchy.size();
if (!right_non_leaves.empty()) {
hierarchy[i].right = hierarchy.size();
hierarchy.push_back(right);
}
// Handle recursion
hierarch(hierarchy.size() - 2, left_non_leaves);
hierarch(hierarchy.size() - 1, right_non_leaves);
if (!left_non_leaves.empty()) hierarch(hierarchy[i].left, left_non_leaves);
if (!right_non_leaves.empty())
hierarch(hierarchy[i].right, right_non_leaves);
/*size_t hierarch_min_cluster_size = 1;
if (left.shapeList.size() >= hierarch_min_cluster_size) {
......
......@@ -37,6 +37,8 @@ class TriangleMesh : public Light, public Shape {
private:
util::AxisAlignedBoundingBox initBB();
std::optional<cam::Hit> TriangleMesh::intersect(size_t i,
const cam::Ray& r) const;
void hierarch(size_t i, const std::vector<std::shared_ptr<Triangle>> v);
};
} // namespace shapes
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment