From da9eac2fbe035f4576476827b310be992a02950e Mon Sep 17 00:00:00 2001 From: David Harmon Date: Thu, 30 Aug 2018 08:06:05 -0400 Subject: [PATCH] Enable support for writing binary glTF. --- tiny_gltf.h | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/tiny_gltf.h b/tiny_gltf.h index b12827b..00a2aaa 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -874,7 +874,8 @@ class TinyGLTF { /// bool WriteGltfSceneToFile(Model *model, const std::string &filename, bool embedImages, - bool embedBuffers /*, bool writeBinary*/); + bool embedBuffers, + bool writeBinary); /// /// Set callback to use for loading image data @@ -4238,10 +4239,39 @@ static void WriteGltfFile(const std::string &output, gltfFile << content << std::endl; } +static void WriteBinaryGltfFile(const std::string &output, + const std::string &content) { + std::ofstream gltfFile(output.c_str(), std::ios::binary); + + const std::string header = "glTF"; + const int version = 2; + const int padding_size = content.size() % 4; + + // 12 bytes for header, JSON content length, 8 bytes for JSON chunk info, padding + const int length = 12 + 8 + content.size() + padding_size; + + gltfFile.write(header.c_str(), header.size()); + gltfFile.write(reinterpret_cast(&version), sizeof(version)); + gltfFile.write(reinterpret_cast(&length), sizeof(length)); + + // JSON chunk info, then JSON data + const int model_length = content.size() + padding_size; + const int model_format = 0x4E4F534A; + gltfFile.write(reinterpret_cast(&model_length), sizeof(model_length)); + gltfFile.write(reinterpret_cast(&model_format), sizeof(model_format)); + gltfFile.write(content.c_str(), content.size()); + + // Chunk must be multiplies of 4, so pad with spaces + if (padding_size > 0) { + const std::string padding = std::string(padding_size, ' '); + gltfFile.write(padding.c_str(), padding.size()); + } +} + bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename, bool embedImages = false, - bool embedBuffers = false - /*, bool writeBinary*/) { + bool embedBuffers = false, + bool writeBinary = false) { json output; // ACCESSORS @@ -4458,7 +4488,12 @@ bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename, SerializeValue("extras", model->extras, output); } - WriteGltfFile(filename, output.dump()); + if (writeBinary) { + WriteBinaryGltfFile(filename, output.dump()); + } else { + WriteGltfFile(filename, output.dump()); + } + return true; }