diff --git a/primitive/objmodel.cpp b/primitive/objmodel.cpp index 8c82d0d..bb9b824 100644 --- a/primitive/objmodel.cpp +++ b/primitive/objmodel.cpp @@ -1,99 +1,35 @@ -// -// Created by arvids on 21.11.22. -// - -#include -#include -#include #include "objmodel.h" #include "shader/flatshader.h" +#include "../scene/scene.h" -void ObjModel::loadObj(const std::string &fileName, Vector3d scale, Vector3d translation) { +void ObjModel::loadObj(const char* fileName, Vector3d scale, Vector3d translation) { - std::vector vertices; - std::vector vertex_normals; - std::ifstream file; - file.open(fileName.c_str()); - if (file.is_open()) { - while (!file.eof()) { - std::string key; - file >> key; - if (key == "v") { - float x, y, z; - file >> x >> y >> z; - vertices.emplace_back(x, y, z); - } else if (key == "vn") { - float x, y, z; - file >> x >> y >> z; - vertex_normals.emplace_back(x, y, z); - } else if (key == "f") { - int x, y, z, - xn, yn, zn = 0; - { - std::string token; - std::getline(file, token, '/'); - std::stringstream tokens(token); - tokens >> x; - } - file.ignore(1); - file >> xn; - { - std::string token; - std::getline(file, token, '/'); - std::stringstream tokens(token); - tokens >> y; - } - file.ignore(1); - file >> yn; - { - std::string token; - std::getline(file, token, '/'); - std::stringstream tokens(token); - tokens >> z; - } - file.ignore(1); - file >> zn; + this->faces = (Scene::loadObj(fileName, scale, translation, this->shader())); - this->faces.emplace_back(vertices[x - 1] * scale + translation, vertices[y - 1] * scale + translation, - vertices[z - 1] * scale + translation, - vertex_normals[xn - 1], vertex_normals[yn - 1], vertex_normals[zn - 1], - this->shader()); - } else if (key == "#") { - file.ignore(std::numeric_limits::max(), '\n'); - } else { - file.ignore(std::numeric_limits::max(), '\n'); - } - } - file.close(); + Vector3d minBounds; + Vector3d maxBounds; - Vector3d minBounds; - Vector3d maxBounds; + auto minCalc = [this](int dimension) { + return std::min_element(this->faces.begin(), + this->faces.end(), + [&dimension](auto &face1, auto &face2) { + return face1->minimumBounds(dimension) < face2->minimumBounds(dimension); + })->get()->minimumBounds(dimension); + }; + minBounds = {minCalc(0), minCalc(1), minCalc(2)}; - auto minCalc = [this](int dimension) { - return std::min_element(this->faces.begin(), - this->faces.end(), - [&dimension](auto &face1, auto &face2) { - return face1.minimumBounds(dimension) < face2.minimumBounds(dimension); - })->minimumBounds(dimension); - }; - minBounds.x = minCalc(0); - minBounds.y = minCalc(1); - minBounds.z = minCalc(2); + auto maxCalc = [this](int dimension) { + return std::max_element(this->faces.begin(), + this->faces.end(), + [&dimension](auto &face1, auto &face2) { + return face1->maximumBounds(dimension) < face2->maximumBounds(dimension); + })->get()->maximumBounds(dimension); + }; + maxBounds = {maxCalc(0), maxCalc(1), maxCalc(2)}; - auto maxCalc = [this](int dimension) { - return std::max_element(this->faces.begin(), - this->faces.end(), - [&dimension](auto &face1, auto &face2) { - return face1.maximumBounds(dimension) < face2.maximumBounds(dimension); - })->maximumBounds(dimension); - }; - maxBounds.x = maxCalc(0); - maxBounds.y = maxCalc(1); - maxBounds.z = maxCalc(2); + boundingBox.setCenter(minBounds + (maxBounds - minBounds) / 2); + boundingBox.setSize(maxBounds - minBounds); - boundingBox.setCenter(minBounds + (maxBounds - minBounds) / 2); - boundingBox.setSize(maxBounds - minBounds); - } } bool ObjModel::intersect(Ray &ray) const { @@ -104,7 +40,7 @@ bool ObjModel::intersect(Ray &ray) const { return std::count_if(this->faces.begin(), this->faces.end(), [&ray](auto &face) { - return face.intersect(ray); + return face->intersect(ray); }) > 0; } diff --git a/primitive/objmodel.h b/primitive/objmodel.h index cbce7b9..403bce2 100644 --- a/primitive/objmodel.h +++ b/primitive/objmodel.h @@ -2,15 +2,13 @@ #define CG1_TRACER_OBJMODEL_H #include "primitive.h" -#include "triangle.h" #include "box.h" #include -#include class ObjModel : public Primitive { public: explicit ObjModel(const std::shared_ptr &shader); - void loadObj(const std::string& fileName, Vector3d translation, Vector3d upVector); + void loadObj(const char* fileName, Vector3d scale, Vector3d translation); bool intersect(Ray &ray) const override; @@ -18,7 +16,7 @@ public: [[nodiscard]] float maximumBounds(int dimension) const override; protected: - std::vector faces; + std::vector> faces; Box boundingBox; diff --git a/scene/scene.cpp b/scene/scene.cpp index 68e0924..ba59597 100644 --- a/scene/scene.cpp +++ b/scene/scene.cpp @@ -42,9 +42,65 @@ std::vector> Scene::loadObj(char const *fileName, Vec std::vector> faces; std::vector> indices; - // IMPLEMENT ME + std::vector vertices; + std::vector vertex_normals; + std::ifstream file; + file.open(fileName); + if (file.is_open()) { + while (!file.eof()) { + std::string key; + file >> key; + if (key == "v") { + float x, y, z; + file >> x >> y >> z; + vertices.emplace_back(x, y, z); + } else if (key == "vn") { + float x, y, z; + file >> x >> y >> z; + vertex_normals.emplace_back(x, y, z); + } else if (key == "f") { + int x, y, z, + xn, yn, zn = 0; + { + std::string token; + std::getline(file, token, '/'); + std::stringstream tokens(token); + tokens >> x; + } + file.ignore(1); + file >> xn; + { + std::string token; + std::getline(file, token, '/'); + std::stringstream tokens(token); + tokens >> y; + } + file.ignore(1); + file >> yn; + { + std::string token; + std::getline(file, token, '/'); + std::stringstream tokens(token); + tokens >> z; + } + file.ignore(1); + file >> zn; - return faces; + faces.push_back(std::make_shared(vertices[x - 1] * scale + translation, + vertices[y - 1] * scale + translation, + vertices[z - 1] * scale + translation, + vertex_normals[xn - 1], vertex_normals[yn - 1], + vertex_normals[zn - 1], + shader)); + } else if (key == "#") { + file.ignore(std::numeric_limits::max(), '\n'); + } else { + file.ignore(std::numeric_limits::max(), '\n'); + } + } + file.close(); + } + return faces; } Color Scene::traceRay(Ray &ray) const {