From 35159a93b25c006d9ab6ebeefdbae5984388ed4d Mon Sep 17 00:00:00 2001 From: redstrate <54911369+redstrate@users.noreply.github.com> Date: Fri, 29 May 2020 19:12:37 -0400 Subject: [PATCH] Add multiple object support --- include/scene.h | 67 ++++++++++++++++++++++++++++--------------------- src/main.cpp | 6 ++++- 2 files changed, 44 insertions(+), 29 deletions(-) diff --git a/include/scene.h b/include/scene.h index 5211d94..af66db6 100644 --- a/include/scene.h +++ b/include/scene.h @@ -4,32 +4,42 @@ #include -struct Scene { +struct Object { + glm::vec3 position = glm::vec3(0); + tinyobj::attrib_t attrib; std::vector shapes; std::vector materials; - - bool load_from_file(const std::string_view path) { - return tinyobj::LoadObj(&attrib, &shapes, &materials, nullptr, path.data()); +}; + +struct Scene { + std::vector objects; + + Object& load_from_file(const std::string_view path) { + Object o; + + tinyobj::LoadObj(&o.attrib, &o.shapes, &o.materials, nullptr, path.data()); + + return objects.emplace_back(o); } }; -inline glm::vec3 fetch_position(const Scene& scene, const tinyobj::mesh_t& mesh, const int32_t index, const int32_t vertex) { +inline glm::vec3 fetch_position(const Object& object, const tinyobj::mesh_t& mesh, const int32_t index, const int32_t vertex) { tinyobj::index_t idx = mesh.indices[(index * 3) +vertex]; - tinyobj::real_t vx = scene.attrib.vertices[3*idx.vertex_index+0]; - tinyobj::real_t vy = scene.attrib.vertices[3*idx.vertex_index+1]; - tinyobj::real_t vz = scene.attrib.vertices[3*idx.vertex_index+2]; + tinyobj::real_t vx = object.attrib.vertices[3*idx.vertex_index+0]; + tinyobj::real_t vy = object.attrib.vertices[3*idx.vertex_index+1]; + tinyobj::real_t vz = object.attrib.vertices[3*idx.vertex_index+2]; return glm::vec3(vx, vy, vz); } -inline glm::vec3 fetch_normal(const Scene& scene, const tinyobj::mesh_t& mesh, const int32_t index, const int32_t vertex) { +inline glm::vec3 fetch_normal(const Object& object, const tinyobj::mesh_t& mesh, const int32_t index, const int32_t vertex) { tinyobj::index_t idx = mesh.indices[(index * 3) + vertex]; - tinyobj::real_t nx = scene.attrib.normals[3*idx.normal_index+0]; - tinyobj::real_t ny = scene.attrib.normals[3*idx.normal_index+1]; - tinyobj::real_t nz = scene.attrib.normals[3*idx.normal_index+2]; + tinyobj::real_t nx = object.attrib.normals[3*idx.normal_index+0]; + tinyobj::real_t ny = object.attrib.normals[3*idx.normal_index+1]; + tinyobj::real_t nz = object.attrib.normals[3*idx.normal_index+2]; return glm::vec3(nx, ny, nz); } @@ -39,22 +49,21 @@ struct HitResult { tinyobj::mesh_t* mesh = nullptr; }; - -std::optional test_mesh(const Ray ray, const Scene& scene, const tinyobj::mesh_t& mesh, float& tClosest) { +std::optional test_mesh(const Ray ray, const Object& object, const tinyobj::mesh_t& mesh, float& tClosest) { bool intersection = false; HitResult result = {}; for (size_t i = 0; i < mesh.num_face_vertices.size(); i++) { - const glm::vec3 v0 = fetch_position(scene, mesh, i, 0); - const glm::vec3 v1 = fetch_position(scene, mesh, i, 1); - const glm::vec3 v2 = fetch_position(scene, mesh, i, 2); + const glm::vec3 v0 = fetch_position(object, mesh, i, 0) + object.position; + const glm::vec3 v1 = fetch_position(object, mesh, i, 1) + object.position; + const glm::vec3 v2 = fetch_position(object, mesh, i, 2) + object.position; float t = std::numeric_limits::infinity(), u, v; if (intersections::ray_triangle(ray, v0, v1, v2, t, u, v)) { if (t < tClosest && t > epsilon) { - const glm::vec3 n0 = fetch_normal(scene, mesh, i, 0); - const glm::vec3 n1 = fetch_normal(scene, mesh, i, 1); - const glm::vec3 n2 = fetch_normal(scene, mesh, i, 2); + const glm::vec3 n0 = fetch_normal(object, mesh, i, 0); + const glm::vec3 n1 = fetch_normal(object, mesh, i, 1); + const glm::vec3 n2 = fetch_normal(object, mesh, i, 2); result.normal = (1 - u - v) * n0 + u * n1 + v * n2; result.position = ray.origin + ray.direction * t; @@ -76,16 +85,18 @@ std::optional test_scene(const Ray ray, const Scene& scene, float tCl bool intersection = false; HitResult result = {}; - for (uint32_t i = 0; i < scene.shapes.size(); i++) { - auto mesh = scene.shapes[i].mesh; - - if(auto hit = test_mesh(ray, scene, mesh, tClosest)) { - intersection = true; - result = hit.value(); - result.mesh = &mesh; + for(auto& object : scene.objects) { + for (uint32_t i = 0; i < object.shapes.size(); i++) { + auto mesh = object.shapes[i].mesh; + + if(auto hit = test_mesh(ray, object, mesh, tClosest)) { + intersection = true; + result = hit.value(); + result.mesh = &mesh; + } } } - + if(intersection) return result; else diff --git a/src/main.cpp b/src/main.cpp index fdb670e..e0ee502 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -234,8 +234,12 @@ int main(int, char*[]) { if(ImGui::BeginMainMenuBar()) { if(ImGui::BeginMenu("File")) { - if(ImGui::Button("Load")) + if(ImGui::Button("Load")) { scene.load_from_file("suzanne.obj"); + + auto& plane = scene.load_from_file("plane.obj"); + plane.position.y = -1; + } ImGui::EndMenu(); }