// Copyright 2024 SquareBlock Inc. All Rights Reserved. // Author: tianlei.richard@qq.com (tianlei.richard) #include "mesh.h" #include "OBJ_Loader.h" #include "spdlog/spdlog.h" #include #define OBJL_VEC2_TO_EIGEN_VECTOR(objl_v) \ Eigen::Vector2d { objl_v.X, objl_v.Y } #define OBJL_VEC3_TO_EIGEN_VECTOR(objl_v) \ Eigen::Vector3d { objl_v.X, objl_v.Y, objl_v.Z } Mesh::Mesh(const std::vector> &vertices, const std::vector &primitives, const std::shared_ptr &phone_material) : vertices_(vertices), primitives_(primitives), material_(phone_material) {} const std::pair & Mesh::get_texture_coordinate(const unsigned int index) const { return (vertices_[index])->texture_coordinate; } std::pair & Mesh::get_texture_coordinate(const unsigned int index) { return (vertices_[index])->texture_coordinate; } Point3d Mesh::get_normal_vector(const unsigned int index) const { return (vertices_[index])->normal; } std::vector Mesh::load_mesh(const std::string &obj_path, const std::vector texture_path) { const auto &obj_file_path = std::filesystem::path(obj_path); const auto &material_directory = obj_file_path.parent_path(); objl::Loader loader{}; assert(loader.LoadFile(obj_path.c_str())); std::vector res; for (const auto &mesh : loader.LoadedMeshes) { spdlog::info("Current mesh has {} vertices.", mesh.Vertices.size()); std::vector> vertices; for (decltype(mesh.Vertices)::size_type i = 0; i < mesh.Vertices.size(); i++) { vertices.push_back(std::make_shared( OBJL_VEC3_TO_EIGEN_VECTOR(mesh.Vertices[i].Position), OBJL_VEC3_TO_EIGEN_VECTOR(mesh.Vertices[i].Normal), OBJL_VEC2_TO_EIGEN_VECTOR(mesh.Vertices[i].TextureCoordinate))); } std::vector primitives; for (decltype(mesh.Indices)::size_type i = 0; i < mesh.Indices.size(); i += 3) { primitives.push_back(Triangle(vertices, mesh.Indices[i], mesh.Indices[i + 1], mesh.Indices[i + 2])); } std::vector texture_file_path; if (!texture_path.empty()) { for (const auto &p : texture_path) { texture_file_path.push_back(std::filesystem::path(p)); } } else if (!mesh.MeshMaterial.map_Kd.empty()) { texture_file_path.push_back(material_directory / mesh.MeshMaterial.map_Kd); } auto material = std::shared_ptr(new PhoneMaterial(texture_file_path)); res.push_back(Mesh(vertices, primitives, material)); } return res; }