10#include "hellfire/utilities/SerializerUtils.h"
16 std::cerr <<
"ModelSerializer: Cannot save failed import result" << std::endl;
20 std::ofstream file(filepath, std::ios::binary);
22 std::cerr <<
"ModelSerializer: Cannot open file for writing: " << filepath << std::endl;
33 const uint32_t node_count =
static_cast<uint32_t>(result.nodes.size());
34 write_binary(file, node_count);
36 for (
const auto& node : result.nodes) {
37 write_binary_string(file, node.name);
38 write_binary(file, node.position);
39 write_binary(file, node.rotation);
40 write_binary(file, node.scale);
43 const uint32_t mesh_idx_count =
static_cast<uint32_t>(node.mesh_indices.size());
44 write_binary(file, mesh_idx_count);
45 for (size_t idx : node.mesh_indices) {
46 write_binary(file,
static_cast<uint32_t>(idx));
50 const uint32_t child_idx_count =
static_cast<uint32_t>(node.child_indices.size());
51 write_binary(file, child_idx_count);
52 for (size_t idx : node.child_indices) {
53 write_binary(file,
static_cast<uint32_t>(idx));
58 const uint32_t mesh_count =
static_cast<uint32_t>(result.meshes.size());
59 write_binary(file, mesh_count);
61 for (
const auto& mesh : result.meshes) {
62 write_binary_string(file, mesh.name);
63 write_binary(file, mesh.mesh_asset);
64 write_binary(file, mesh.material_asset);
71 std::ifstream file(filepath, std::ios::binary);
73 std::cerr <<
"ModelSerializer: Cannot open file: " << filepath << std::endl;
79 if (!read_and_validate_header(file,
MAGIC,
VERSION, version)) {
80 std::cerr <<
"ModelSerializer: Invalid file header: " << filepath << std::endl;
89 if (!read_binary(file, root_idx))
return std::nullopt;
94 if (!read_binary(file, node_count))
return std::nullopt;
95 result.nodes.resize(node_count);
97 for (
auto& node : result.nodes) {
98 if (!read_binary_string(file, node.name))
return std::nullopt;
99 if (!read_binary(file, node.position))
return std::nullopt;
100 if (!read_binary(file, node.rotation))
return std::nullopt;
101 if (!read_binary(file, node.scale))
return std::nullopt;
104 uint32_t mesh_idx_count;
105 if (!read_binary(file, mesh_idx_count))
return std::nullopt;
106 node.mesh_indices.resize(mesh_idx_count);
107 for (uint32_t i = 0; i < mesh_idx_count; i++) {
109 if (!read_binary(file, idx))
return std::nullopt;
110 node.mesh_indices[i] = idx;
114 uint32_t child_idx_count;
115 if (!read_binary(file, child_idx_count))
return std::nullopt;
116 node.child_indices.resize(child_idx_count);
117 for (uint32_t i = 0; i < child_idx_count; i++) {
119 if (!read_binary(file, idx))
return std::nullopt;
120 node.child_indices[i] = idx;
126 if (!read_binary(file, mesh_count))
return std::nullopt;
127 result.meshes.resize(mesh_count);
129 for (
auto& mesh : result.meshes) {
130 if (!read_binary_string(file, mesh.name))
return std::nullopt;
131 if (!read_binary(file, mesh.mesh_asset))
return std::nullopt;
132 if (!read_binary(file, mesh.material_asset))
return std::nullopt;
146 auto& nodes_json = j[
"nodes"];
147 for (
const auto& node : result.nodes) {
148 nlohmann::json node_json;
149 node_json[
"name"] = node.name;
150 node_json[
"position"] = vec3_to_json(node.position);
151 node_json[
"rotation"] = vec3_to_json(node.rotation);
152 node_json[
"scale"] = vec3_to_json(node.scale);
153 node_json[
"mesh_indices"] = node.mesh_indices;
154 node_json[
"child_indices"] = node.child_indices;
155 nodes_json.push_back(node_json);
159 auto& meshes_json = j[
"meshes"];
160 for (
const auto& mesh : result.meshes) {
161 meshes_json.push_back({
163 {
"mesh_asset", mesh.mesh_asset},
164 {
"material_asset", mesh.material_asset}
168 std::ofstream file(filepath);
169 if (!file)
return false;
176 std::ifstream file(filepath);
177 if (!file)
return std::nullopt;
188 for (
const auto& node_json : j[
"nodes"]) {
190 node.name = node_json.value(
"name",
"Node");
192 if (
auto v = json_get_vec3(node_json,
"position")) node.position = *v;
193 if (
auto v = json_get_vec3(node_json,
"rotation")) node.rotation = *v;
194 if (
auto v = json_get_vec3(node_json,
"scale")) node.scale = *v;
195 else node.scale = glm::vec3(1.0f);
197 node.mesh_indices = node_json[
"mesh_indices"].get<std::vector<size_t>>();
198 node.child_indices = node_json[
"child_indices"].get<std::vector<size_t>>();
200 result.nodes.push_back(node);
204 for (
const auto& mesh_json : j[
"meshes"]) {
206 mesh.name = mesh_json.value(
"name",
"Mesh");
207 mesh.mesh_asset = mesh_json.value(
"mesh_asset", INVALID_ASSET_ID);
208 mesh.material_asset = mesh_json.value(
"material_asset", INVALID_ASSET_ID);
209 result.meshes.push_back(mesh);
213 }
catch (
const std::exception& e) {
214 std::cerr <<
"ModelSerializer: JSON parse error: " << e.what() << std::endl;
Serializes the ImportResult to a .hfmodel file.
static std::optional< ImportResult > load_json(const std::filesystem::path &filepath)
static constexpr uint32_t VERSION
static bool save(const std::filesystem::path &filepath, const ImportResult &result)
static constexpr uint32_t MAGIC
static bool save_json(const std::filesystem::path &filepath, const ImportResult &result)
static std::optional< ImportResult > load(const std::filesystem::path &filepath)
Complete result of importing a model file.