Loading...
Searching...
No Matches
MeshSerializer.cpp
Go to the documentation of this file.
1//
2// Created by denzel on 08/12/2025.
3//
4
5#include "hellfire/graphics/Vertex.h"
7
8#include <fstream>
9
10#include "hellfire/utilities/SerializerUtils.h"
11
12namespace hellfire {
13 bool MeshSerializer::save(const std::filesystem::path &filepath, const Mesh &mesh) {
14 std::ofstream file(filepath, std::ios::binary);
15 if (!file) {
16 std::cerr << "MeshSerializer: Cannot open file for writing: " << filepath << std::endl;
17 return false;
18 }
19
20 // Header
21 if (!write_header(file, MAGIC, VERSION)) {
22 return false;
23 }
24
25 // Mesh flags
26 write_binary(file, mesh.is_wireframe);
27
28 // Vertex data
29 write_vertex_vector(file, mesh.vertices);
30
31 // Index data
32 write_binary_vector(file, mesh.indices);
33
34 return file.good();
35 }
36
37 std::shared_ptr<Mesh> MeshSerializer::load(const std::filesystem::path &filepath) {
38 std::ifstream file(filepath, std::ios::binary);
39 if (!file) {
40 std::cerr << "MeshSerializer: Cannot open file: " << filepath << std::endl;
41 return nullptr;
42 }
43
44 // Validate header
45 uint32_t version;
46 if (!read_and_validate_header(file, MAGIC, VERSION, version)) {
47 std::cerr << "MeshSerializer: Invalid file header: " << filepath << std::endl;
48 return nullptr;
49 }
50
51 auto mesh = std::make_shared<Mesh>();
52
53 // Mesh flags
54 if (!read_binary(file, mesh->is_wireframe)) {
55 return nullptr;
56 }
57
58 // Vertex data
59 if (!read_vertex_vector(file, mesh->vertices)) {
60 return nullptr;
61 }
62
63 // Index data
64 if (!read_binary_vector(file, mesh->indices)) {
65 return nullptr;
66 }
67
68 mesh->build();
69 return mesh;
70 }
71
72 bool MeshSerializer::save_json(const std::filesystem::path &filepath, const Mesh &mesh) {
73 nlohmann::json j;
74 j["version"] = VERSION;
75 j["is_wireframe"] = mesh.is_wireframe;
76
77 // Vertices
78 auto &verts = j["vertices"];
79 for (const auto &v: mesh.vertices) {
80 verts.push_back({
81 {"position", vec3_to_json(v.position)},
82 {"normal", vec3_to_json(v.normal)},
83 {"texCoords", vec2_to_json(v.texCoords)},
84 {"color", vec3_to_json(v.color)},
85 {"tangent", vec3_to_json(v.tangent)},
86 {"bitangent", vec3_to_json(v.bitangent)}
87 });
88 }
89
90 j["indices"] = mesh.indices;
91
92 std::ofstream file(filepath);
93 if (!file) return false;
94
95 file << j.dump(2);
96 return file.good();
97 }
98
99 std::shared_ptr<Mesh> MeshSerializer::load_json(const std::filesystem::path &filepath) {
100 std::ifstream file(filepath);
101 if (!file) return nullptr;
102
103 try {
104 nlohmann::json j;
105 file >> j;
106
107 auto mesh = std::make_shared<Mesh>();
108 mesh->is_wireframe = j.value("is_wireframe", false);
109
110 for (const auto &v: j["vertices"]) {
111 Vertex vert{};
112
113 if (auto pos = json_get_vec3(v, "position")) vert.position = *pos;
114 if (auto norm = json_get_vec3(v, "normal")) vert.normal = *norm;
115 if (auto tex = json_get_vec2(v, "texCoords")) vert.texCoords = *tex;
116 if (auto col = json_get_vec3(v, "color")) vert.color = *col;
117 if (auto tan = json_get_vec3(v, "tangent")) vert.tangent = *tan;
118 if (auto bitan = json_get_vec3(v, "bitangent")) vert.bitangent = *bitan;
119
120 mesh->vertices.push_back(vert);
121 }
122
123 mesh->indices = j["indices"].get<std::vector<unsigned int> >();
124
125 return mesh;
126 } catch (const std::exception &e) {
127 std::cerr << "MeshSerializer: JSON parse error: " << e.what() << std::endl;
128 return nullptr;
129 }
130 }
131}
static bool save_json(const std::filesystem::path &filepath, const Mesh &mesh)
static constexpr uint32_t MAGIC
static constexpr uint32_t VERSION
static std::shared_ptr< Mesh > load_json(const std::filesystem::path &filepath)
static bool save(const std::filesystem::path &filepath, const Mesh &mesh)
static std::shared_ptr< Mesh > load(const std::filesystem::path &filepath)
bool is_wireframe
Definition Mesh.h:32