Files
ViewDesignEngine/src/foundation/io_gltf.cpp
T

66 lines
2.7 KiB
C++
Raw Normal View History

#include "vde/foundation/io_gltf.h"
#include "vde/core/aabb.h"
#include <fstream>
#include <algorithm>
#include <cmath>
#include <string>
namespace vde::foundation {
static std::string vec3_json(double x, double y, double z) {
return "[" + std::to_string(x) + "," + std::to_string(y) + "," + std::to_string(z) + "]";
}
bool write_gltf(const std::string& filepath, const mesh::HalfedgeMesh& mesh) {
std::ofstream file(filepath);
if (!file) return false;
size_t nv = mesh.num_vertices();
size_t nf = mesh.num_faces();
size_t index_count = nf * 3;
core::AABB3D bounds = mesh.bounds();
file << "{\n";
file << " \"asset\": {\"version\": \"2.0\", \"generator\": \"ViewDesignEngine\"},\n";
file << " \"scene\": 0,\n";
file << " \"scenes\": [{\"nodes\": [0]}],\n";
file << " \"nodes\": [{\"mesh\": 0}],\n";
file << " \"meshes\": [{\"primitives\": [{\"attributes\": {\"POSITION\": 0},\"indices\": 1}]}],\n";
file << " \"buffers\": [{\"uri\": \"mesh.bin\",\"byteLength\": " << (nv*12+index_count*4) << "}],\n";
file << " \"bufferViews\": [\n";
file << " {\"buffer\": 0, \"byteOffset\": 0, \"byteLength\": " << (nv*12) << "},\n";
file << " {\"buffer\": 0, \"byteOffset\": " << (nv*12) << ", \"byteLength\": " << (index_count*4) << "}\n";
file << " ],\n";
file << " \"accessors\": [\n";
file << " {\"bufferView\": 0, \"componentType\": 5126, \"count\": " << nv
<< ", \"type\": \"VEC3\", \"max\": " << vec3_json(bounds.max().x(),bounds.max().y(),bounds.max().z())
<< ", \"min\": " << vec3_json(bounds.min().x(),bounds.min().y(),bounds.min().z()) << "},\n";
file << " {\"bufferView\": 1, \"componentType\": 5125, \"count\": " << index_count << ", \"type\": \"SCALAR\"}\n";
file << " ]\n}\n";
// Write binary data
std::string dot = ".";
std::string binpath = filepath.substr(0, filepath.rfind(dot)) + ".bin";
std::ofstream bin(binpath, std::ios::binary);
for (size_t i = 0; i < nv; ++i) {
const auto& v = mesh.vertex(i);
float fx = static_cast<float>(v.x());
float fy = static_cast<float>(v.y());
float fz = static_cast<float>(v.z());
bin.write(reinterpret_cast<const char*>(&fx), 4);
bin.write(reinterpret_cast<const char*>(&fy), 4);
bin.write(reinterpret_cast<const char*>(&fz), 4);
}
for (size_t i = 0; i < nf; ++i) {
auto vis = mesh.face_vertices(static_cast<int>(i));
for (size_t j = 0; j < std::min(vis.size(), size_t(3)); ++j) {
uint32_t idx = static_cast<uint32_t>(vis[j]);
bin.write(reinterpret_cast<const char*>(&idx), 4);
}
}
return true;
}
} // namespace vde::foundation