Add multiple object support
This commit is contained in:
parent
202d4c3dc8
commit
35159a93b2
2 changed files with 44 additions and 29 deletions
|
@ -4,32 +4,42 @@
|
||||||
|
|
||||||
#include <tiny_obj_loader.h>
|
#include <tiny_obj_loader.h>
|
||||||
|
|
||||||
struct Scene {
|
struct Object {
|
||||||
|
glm::vec3 position = glm::vec3(0);
|
||||||
|
|
||||||
tinyobj::attrib_t attrib;
|
tinyobj::attrib_t attrib;
|
||||||
std::vector<tinyobj::shape_t> shapes;
|
std::vector<tinyobj::shape_t> shapes;
|
||||||
std::vector<tinyobj::material_t> materials;
|
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::index_t idx = mesh.indices[(index * 3) +vertex];
|
||||||
|
|
||||||
tinyobj::real_t vx = scene.attrib.vertices[3*idx.vertex_index+0];
|
tinyobj::real_t vx = object.attrib.vertices[3*idx.vertex_index+0];
|
||||||
tinyobj::real_t vy = scene.attrib.vertices[3*idx.vertex_index+1];
|
tinyobj::real_t vy = object.attrib.vertices[3*idx.vertex_index+1];
|
||||||
tinyobj::real_t vz = scene.attrib.vertices[3*idx.vertex_index+2];
|
tinyobj::real_t vz = object.attrib.vertices[3*idx.vertex_index+2];
|
||||||
|
|
||||||
return glm::vec3(vx, vy, vz);
|
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::index_t idx = mesh.indices[(index * 3) + vertex];
|
||||||
|
|
||||||
tinyobj::real_t nx = scene.attrib.normals[3*idx.normal_index+0];
|
tinyobj::real_t nx = object.attrib.normals[3*idx.normal_index+0];
|
||||||
tinyobj::real_t ny = scene.attrib.normals[3*idx.normal_index+1];
|
tinyobj::real_t ny = object.attrib.normals[3*idx.normal_index+1];
|
||||||
tinyobj::real_t nz = scene.attrib.normals[3*idx.normal_index+2];
|
tinyobj::real_t nz = object.attrib.normals[3*idx.normal_index+2];
|
||||||
|
|
||||||
return glm::vec3(nx, ny, nz);
|
return glm::vec3(nx, ny, nz);
|
||||||
}
|
}
|
||||||
|
@ -39,22 +49,21 @@ struct HitResult {
|
||||||
tinyobj::mesh_t* mesh = nullptr;
|
tinyobj::mesh_t* mesh = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::optional<HitResult> test_mesh(const Ray ray, const Object& object, const tinyobj::mesh_t& mesh, float& tClosest) {
|
||||||
std::optional<HitResult> test_mesh(const Ray ray, const Scene& scene, const tinyobj::mesh_t& mesh, float& tClosest) {
|
|
||||||
bool intersection = false;
|
bool intersection = false;
|
||||||
HitResult result = {};
|
HitResult result = {};
|
||||||
|
|
||||||
for (size_t i = 0; i < mesh.num_face_vertices.size(); i++) {
|
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 v0 = fetch_position(object, mesh, i, 0) + object.position;
|
||||||
const glm::vec3 v1 = fetch_position(scene, mesh, i, 1);
|
const glm::vec3 v1 = fetch_position(object, mesh, i, 1) + object.position;
|
||||||
const glm::vec3 v2 = fetch_position(scene, mesh, i, 2);
|
const glm::vec3 v2 = fetch_position(object, mesh, i, 2) + object.position;
|
||||||
|
|
||||||
float t = std::numeric_limits<float>::infinity(), u, v;
|
float t = std::numeric_limits<float>::infinity(), u, v;
|
||||||
if (intersections::ray_triangle(ray, v0, v1, v2, t, u, v)) {
|
if (intersections::ray_triangle(ray, v0, v1, v2, t, u, v)) {
|
||||||
if (t < tClosest && t > epsilon) {
|
if (t < tClosest && t > epsilon) {
|
||||||
const glm::vec3 n0 = fetch_normal(scene, mesh, i, 0);
|
const glm::vec3 n0 = fetch_normal(object, mesh, i, 0);
|
||||||
const glm::vec3 n1 = fetch_normal(scene, mesh, i, 1);
|
const glm::vec3 n1 = fetch_normal(object, mesh, i, 1);
|
||||||
const glm::vec3 n2 = fetch_normal(scene, mesh, i, 2);
|
const glm::vec3 n2 = fetch_normal(object, mesh, i, 2);
|
||||||
|
|
||||||
result.normal = (1 - u - v) * n0 + u * n1 + v * n2;
|
result.normal = (1 - u - v) * n0 + u * n1 + v * n2;
|
||||||
result.position = ray.origin + ray.direction * t;
|
result.position = ray.origin + ray.direction * t;
|
||||||
|
@ -76,16 +85,18 @@ std::optional<HitResult> test_scene(const Ray ray, const Scene& scene, float tCl
|
||||||
bool intersection = false;
|
bool intersection = false;
|
||||||
HitResult result = {};
|
HitResult result = {};
|
||||||
|
|
||||||
for (uint32_t i = 0; i < scene.shapes.size(); i++) {
|
for(auto& object : scene.objects) {
|
||||||
auto mesh = scene.shapes[i].mesh;
|
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)) {
|
|
||||||
intersection = true;
|
if(auto hit = test_mesh(ray, object, mesh, tClosest)) {
|
||||||
result = hit.value();
|
intersection = true;
|
||||||
result.mesh = &mesh;
|
result = hit.value();
|
||||||
|
result.mesh = &mesh;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(intersection)
|
if(intersection)
|
||||||
return result;
|
return result;
|
||||||
else
|
else
|
||||||
|
|
|
@ -234,8 +234,12 @@ int main(int, char*[]) {
|
||||||
|
|
||||||
if(ImGui::BeginMainMenuBar()) {
|
if(ImGui::BeginMainMenuBar()) {
|
||||||
if(ImGui::BeginMenu("File")) {
|
if(ImGui::BeginMenu("File")) {
|
||||||
if(ImGui::Button("Load"))
|
if(ImGui::Button("Load")) {
|
||||||
scene.load_from_file("suzanne.obj");
|
scene.load_from_file("suzanne.obj");
|
||||||
|
|
||||||
|
auto& plane = scene.load_from_file("plane.obj");
|
||||||
|
plane.position.y = -1;
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue