1
Fork 0
raytracer/include/scene.h

114 lines
3.1 KiB
C
Raw Normal View History

2020-02-17 10:33:56 -05:00
#pragma once
2020-07-30 10:06:47 -04:00
#include <array>
2022-08-16 07:41:12 -04:00
#include <glm/glm.hpp>
#include <optional>
#include <random>
2024-09-25 10:36:54 +02:00
#include <print>
2020-02-17 10:33:56 -05:00
#include <tiny_obj_loader.h>
#include "intersections.h"
#include "lighting.h"
2020-07-30 10:06:47 -04:00
#include "octree.h"
2022-08-16 07:41:12 -04:00
#include "ray.h"
constexpr glm::vec3 light_position = glm::vec3(5);
constexpr float light_bias = 0.01f;
constexpr int max_depth = 2;
inline int num_indirect_samples = 4;
2020-07-30 10:06:47 -04:00
struct TriangleBox {
uint64_t vertice_index = 0;
tinyobj::mesh_t* mesh;
AABB extent;
};
struct Object;
glm::vec3 fetch_position(const Object& object, const tinyobj::mesh_t& mesh, int32_t index, int32_t vertex);
glm::vec3 fetch_normal(const Object& object, const tinyobj::mesh_t& mesh, int32_t index, int32_t vertex);
2020-07-30 10:06:47 -04:00
2020-05-29 19:12:37 -04:00
struct Object {
glm::vec3 position = glm::vec3(0);
glm::vec3 color = glm::vec3(1);
2022-08-16 07:41:12 -04:00
2020-02-17 10:33:56 -05:00
tinyobj::attrib_t attrib;
std::vector<tinyobj::shape_t> shapes;
std::vector<tinyobj::material_t> materials;
2022-08-16 07:41:12 -04:00
2020-07-30 10:06:47 -04:00
std::unique_ptr<Octree<TriangleBox>> octree;
void create_octree() {
octree = std::make_unique<Octree<TriangleBox>>(glm::vec3(-2), glm::vec3(2));
2022-08-16 07:41:12 -04:00
for (auto& shape : shapes) {
for (size_t i = 0; i < shape.mesh.num_face_vertices.size(); i++) {
2020-07-30 10:06:47 -04:00
const glm::vec3 v0 = fetch_position(*this, shape.mesh, i, 0);
const glm::vec3 v1 = fetch_position(*this, shape.mesh, i, 1);
const glm::vec3 v2 = fetch_position(*this, shape.mesh, i, 2);
2022-08-16 07:41:12 -04:00
AABB extent{};
2020-07-30 10:06:47 -04:00
extent.min = glm::min(v0, v1);
extent.min = glm::min(extent.min, v2);
2022-08-16 07:41:12 -04:00
2020-07-30 10:06:47 -04:00
extent.max = glm::max(v0, v1);
extent.max = glm::max(extent.max, v2);
2022-08-16 07:41:12 -04:00
2020-07-30 10:06:47 -04:00
TriangleBox box = {};
box.vertice_index = i;
box.extent = extent;
box.mesh = &shape.mesh;
2022-08-16 07:41:12 -04:00
2020-07-30 10:06:47 -04:00
octree->add(box, box.extent);
}
}
}
2020-05-29 19:12:37 -04:00
};
struct Scene {
2020-07-30 10:06:47 -04:00
std::vector<std::unique_ptr<Object>> objects;
2022-08-16 07:41:12 -04:00
std::random_device rd;
std::mt19937 gen;
std::uniform_real_distribution<> dis;
2022-08-16 07:41:12 -04:00
Scene() : gen(rd()), dis(0.0, 1.0) {}
2022-08-16 07:41:12 -04:00
float distribution() {
return dis(gen);
}
2022-08-16 07:41:12 -04:00
2020-05-29 19:12:37 -04:00
Object& load_from_file(const std::string_view path) {
2020-07-30 10:06:47 -04:00
auto o = std::make_unique<Object>();
2022-08-16 07:33:21 -04:00
std::string err;
2022-08-16 07:41:12 -04:00
if (!tinyobj::LoadObj(&o->attrib, &o->shapes, &o->materials, &err, path.data()))
2024-09-25 10:36:54 +02:00
std::println("Could not load obj: {}", err);
2022-08-16 07:41:12 -04:00
2020-07-30 10:06:47 -04:00
return *objects.emplace_back(std::move(o));
}
2022-08-16 07:41:12 -04:00
2020-07-30 10:06:47 -04:00
void generate_acceleration() {
2022-08-16 07:41:12 -04:00
for (auto& object : objects) {
2020-07-30 10:06:47 -04:00
object->create_octree();
}
2020-02-17 10:33:56 -05:00
}
};
struct HitResult {
glm::vec3 position, normal;
2020-07-30 10:06:47 -04:00
const Object* object = nullptr;
2020-02-17 10:33:56 -05:00
};
std::optional<HitResult> test_mesh(Ray ray, const Object& object, const tinyobj::mesh_t& mesh, float& tClosest);
std::optional<HitResult> test_scene(Ray ray, const Scene& scene);
std::optional<HitResult> test_scene_octree(Ray ray, const Scene& scene);
struct SceneResult {
HitResult hit;
glm::vec3 direct, indirect, reflect, combined;
};
std::optional<SceneResult> cast_scene(Ray ray, Scene& scene, bool use_bvh, int depth = 0);