1
Fork 0

Add multiple object support

This commit is contained in:
redstrate 2020-05-29 19:12:37 -04:00
parent 202d4c3dc8
commit 35159a93b2
2 changed files with 44 additions and 29 deletions

View file

@ -4,32 +4,42 @@
#include <tiny_obj_loader.h>
struct Scene {
struct Object {
glm::vec3 position = glm::vec3(0);
tinyobj::attrib_t attrib;
std::vector<tinyobj::shape_t> shapes;
std::vector<tinyobj::material_t> materials;
};
bool load_from_file(const std::string_view path) {
return tinyobj::LoadObj(&attrib, &shapes, &materials, nullptr, path.data());
struct Scene {
std::vector<Object> 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<HitResult> test_mesh(const Ray ray, const Scene& scene, const tinyobj::mesh_t& mesh, float& tClosest) {
std::optional<HitResult> 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<float>::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,15 +85,17 @@ std::optional<HitResult> 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;
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, scene, mesh, tClosest)) {
if(auto hit = test_mesh(ray, object, mesh, tClosest)) {
intersection = true;
result = hit.value();
result.mesh = &mesh;
}
}
}
if(intersection)
return result;

View file

@ -234,9 +234,13 @@ 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();
}