Advertisement
pasholnahuy

Untitled

Oct 28th, 2024
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.67 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include "material.h"
  4. #include "vector.h"
  5. #include "object.h"
  6. #include "light.h"
  7.  
  8. #include <vector>
  9. #include <unordered_map>
  10. #include <string>
  11. #include <filesystem>
  12. #include <fstream>
  13. #include <sstream>
  14.  
  15. class Scene {
  16. public:
  17.     std::vector<Object> objects_;
  18.     std::vector<SphereObject> sphere_objects_;
  19.     std::vector<Light> lights_;
  20.     std::unordered_map<std::string, Material> materials_;
  21.  
  22.     const std::vector<Object>& GetObjects() const {
  23.         return objects_;
  24.     }
  25.     const std::vector<SphereObject>& GetSphereObjects() const {
  26.         return sphere_objects_;
  27.     }
  28.     const std::vector<Light>& GetLights() const {
  29.         return lights_;
  30.     }
  31.     const std::unordered_map<std::string, Material>& GetMaterials() const {
  32.         return materials_;
  33.     }
  34. };
  35.  
  36. struct Face {
  37.     int vertexIndex;
  38.     int normalIndex;
  39. };
  40.  
  41. std::unordered_map<std::string, Material> ReadMaterials(const std::filesystem::path& path) {
  42.     std::ifstream file(path.filename());
  43.     std::unordered_map<std::string, Material> materials_;
  44.     Material currentMaterial;
  45.     std::string line;
  46.     while (std::getline(file, line)) {
  47.         std::istringstream iss(line);
  48.         std::string prefix;
  49.         iss >> prefix;
  50.         if (prefix == "newmtl") {
  51.             if (!currentMaterial.name.empty()) {
  52.                 materials_[currentMaterial.name] = currentMaterial;
  53.             }
  54.             iss >> currentMaterial.name;
  55.         } else if (prefix == "Ka") {
  56.             iss >> currentMaterial.ambient_color[0] >> currentMaterial.ambient_color[1] >>
  57.                 currentMaterial.ambient_color[2];
  58.         } else if (prefix == "Kd") {
  59.             iss >> currentMaterial.diffuse_color[0] >> currentMaterial.diffuse_color[1] >>
  60.                 currentMaterial.diffuse_color[2];
  61.         } else if (prefix == "Ks") {
  62.             iss >> currentMaterial.specular_color[0] >> currentMaterial.specular_color[1] >>
  63.                 currentMaterial.specular_color[2];
  64.         } else if (prefix == "Ns") {
  65.             iss >> currentMaterial.specular_exponent;
  66.         } else if (prefix == "Ke") {
  67.             iss >> currentMaterial.intensity[0] >> currentMaterial.intensity[1] >>
  68.                 currentMaterial.intensity[2];
  69.         } else if (prefix == "Ni") {
  70.             iss >> currentMaterial.refraction_index;
  71.         } else if (prefix == "al") {
  72.             iss >> currentMaterial.albedo[0] >> currentMaterial.albedo[1] >>
  73.                 currentMaterial.albedo[2];
  74.         }
  75.     }
  76.  
  77.     if (!currentMaterial.name.empty()) {
  78.         materials_[currentMaterial.name] = currentMaterial;
  79.     }
  80.     file.close();
  81.     return materials_;
  82. }
  83.  
  84. Scene ReadScene(const std::filesystem::path& path) {
  85.     std::unordered_map<std::string, Material> materials;
  86.     std::unordered_map<std::string, Material> res;
  87.     std::string filename = path.filename();
  88.     std::vector<Vector> vertices;
  89.     std::vector<Vector> normals;
  90.     std::vector<Face> faces;
  91.     std::vector<Light> lights;
  92.     std::vector<Sphere> spheres;
  93.     Scene scene;
  94.     std::ifstream file(filename);
  95.     std::string line;
  96.     std::string cur_material;
  97.     while (std::getline(file, line)) {
  98.         std::istringstream stream(line);
  99.         std::string type;
  100.         stream >> type;
  101.         if (type == "v") {
  102.             Vector vertex;
  103.             stream >> vertex[0] >> vertex[1] >> vertex[2];
  104.             vertices.push_back(vertex);
  105.         } else if (type == "vn") {
  106.             Vector normal;
  107.             stream >> normal[0] >> normal[1] >> normal[2];
  108.             normals.push_back(normal);
  109.         } else if (type == "f") {
  110.             Face face;
  111.             std::string vertexStr;
  112.  
  113.             while (stream >> vertexStr) {
  114.                 std::istringstream vStream(vertexStr);
  115.                 std::string index;
  116.                 std::getline(vStream, index, '/');
  117.                 face.vertexIndex = std::stoi(index) - 1;
  118.                 if (std::getline(vStream, index, '/')) {
  119.                     if (!index.empty()) {
  120.                         face.normalIndex = std::stoi(index) - 1;
  121.                     }
  122.                 }
  123.                 for (size_t i = 2; i < faces.size(); ++i) {
  124.                     Triangle triangle(vertices[faces[0].vertexIndex],
  125.                                       vertices[faces[1].vertexIndex],
  126.                                       vertices[faces[i].vertexIndex]);
  127.                     Object object{&materials[cur_material],
  128.                                   {&normals[faces[0].normalIndex], &normals[faces[1].normalIndex],
  129.                                    &normals[faces[i].normalIndex]},
  130.                                   triangle};
  131.                     scene.objects_.emplace_back(object);
  132.                 }
  133.             }
  134.             faces.push_back(face);
  135.         } else if (type == "P") {
  136.             Light light;
  137.             stream >> light.position[0] >> light.position[1] >> light.position[2] >>
  138.                 light.intensity[0] >> light.intensity[1] >> light.intensity[2];
  139.             light.intensity /= 255.;
  140.             lights.emplace_back(light);
  141.         } else if (type == "S") {
  142.             Vector center;
  143.             double radius;
  144.             stream >> center[0] >> center[1] >> center[2] >> radius;
  145.             Sphere sphere(center, radius);
  146.             SphereObject sphere_object{&materials[cur_material], sphere};
  147.             scene.sphere_objects_.emplace_back(sphere_object);
  148.  
  149.         } else if (type == "mtllib") {
  150.             materials = ReadMaterials(path.filename());
  151.         } else if (type == "usemtl") {
  152.             stream >> cur_material;
  153.         }
  154.     }
  155.     scene.materials_ = materials;
  156.     file.close();
  157.     return scene;
  158. }
  159.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement