MinusculeRender/src/mesh.cc

64 lines
2.3 KiB
C++
Raw Normal View History

2024-03-22 20:12:09 +08:00
// 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"
2024-03-22 20:12:09 +08:00
#include <filesystem>
#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<std::shared_ptr<Vertex>> &vertices,
2024-03-22 20:12:09 +08:00
const std::vector<Triangle> &primitives,
const std::shared_ptr<PhoneMaterial> &phone_material)
: vertices_(vertices), primitives_(primitives), material_(phone_material) {}
Point2d Mesh::get_texture_coordinate(const unsigned int index) const {
return (vertices_[index])->texture_coordinate;
}
Point3d Mesh::get_normal_vector(const unsigned int index) const {
return (vertices_[index])->normal;
}
std::vector<Mesh> Mesh::load_mesh(const std::string &file_path) {
2024-03-22 20:12:09 +08:00
const auto &obj_path = std::filesystem::path(file_path);
const auto &material_directory = obj_path.parent_path();
objl::Loader loader{};
assert(loader.LoadFile(file_path.c_str()));
std::vector<Mesh> res;
for (const auto &mesh : loader.LoadedMeshes) {
spdlog::info("Current mesh has {} vertices.", mesh.Vertices.size());
std::vector<std::shared_ptr<Vertex>> vertices;
2024-03-22 20:12:09 +08:00
for (decltype(mesh.Vertices)::size_type i = 0; i < mesh.Vertices.size();
i++) {
vertices.push_back(std::make_shared<Vertex>(
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<Triangle> primitives;
2024-03-22 20:12:09 +08:00
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]));
}
2024-03-22 20:12:09 +08:00
std::vector<std::filesystem::path> texture_path;
if (!mesh.MeshMaterial.map_Kd.empty()) {
texture_path.push_back(material_directory / mesh.MeshMaterial.map_Kd);
}
auto material =
std::shared_ptr<PhoneMaterial>(new PhoneMaterial(texture_path));
res.push_back(Mesh(vertices, primitives, material));
}
return res;
}