From 30c5347afe06a6713a387de9513b6d61987b1a72 Mon Sep 17 00:00:00 2001 From: johan bowald Date: Fri, 30 Mar 2018 11:49:36 +0200 Subject: [PATCH] added embed buffers as an option in serializer --- examples/saver/main.cc | 4 +++ tiny_gltf.h | 75 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 72 insertions(+), 7 deletions(-) diff --git a/examples/saver/main.cc b/examples/saver/main.cc index cbc478b..2fa1291 100644 --- a/examples/saver/main.cc +++ b/examples/saver/main.cc @@ -17,6 +17,7 @@ int main(int argc, char *argv[]) std::string err; std::string input_filename(argv[1]); std::string output_filename(argv[2]); + std::string embedded_filename = output_filename.substr(0, output_filename.size() - 5) + "-Embedded.gltf"; // assume ascii glTF. bool ret = loader.LoadASCIIFromFile(&model, &err, input_filename.c_str()); @@ -28,6 +29,9 @@ int main(int argc, char *argv[]) } loader.WriteGltfSceneToFile(&model, output_filename); + // embed buffers + loader.WriteGltfSceneToFile(&model, embedded_filename, true); + return EXIT_SUCCESS; } diff --git a/tiny_gltf.h b/tiny_gltf.h index 1e7b59c..b29c2ea 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -794,8 +794,8 @@ class TinyGLTF { /// bool WriteGltfSceneToFile( Model *model, - const std::string & - filename /*, bool embedImages, bool embedBuffers, bool writeBinary*/); + const std::string &filename, + bool embedBuffers /*, bool embedImages, bool writeBinary*/); /// /// Set callback to use for loading image data @@ -1033,7 +1033,7 @@ std::string GetBaseFilename(const std::string &filepath) { return filepath.substr(filepath.find_last_of("/\\") + 1); } -// std::string base64_encode(unsigned char const* , unsigned int len); +std::string base64_encode(unsigned char const* , unsigned int len); std::string base64_decode(std::string const &s); /* @@ -1079,6 +1079,48 @@ static inline bool is_base64(unsigned char c) { return (isalnum(c) || (c == '+') || (c == '/')); } +std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) { + std::string ret; + int i = 0; + int j = 0; + unsigned char char_array_3[3]; + unsigned char char_array_4[4]; + + while (in_len--) { + char_array_3[i++] = *(bytes_to_encode++); + if (i == 3) { + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for(i = 0; (i <4) ; i++) + ret += base64_chars[char_array_4[i]]; + i = 0; + } + } + + if (i) + { + for(j = i; j < 3; j++) + char_array_3[j] = '\0'; + + char_array_4[0] = ( char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + + for (j = 0; (j < i + 1); j++) + ret += base64_chars[char_array_4[j]]; + + while((i++ < 3)) + ret += '='; + + } + + return ret; + +} + std::string base64_decode(std::string const &encoded_string) { int in_len = static_cast(encoded_string.size()); int i = 0; @@ -3344,6 +3386,13 @@ static void SerializeValue(const std::string &key, const Value &value, } } +static void SerializeGltfBufferData(const std::vector &data, + json &o) { + std::string header = "data:application/octet-stream;base64,"; + std::string encodedData = base64_encode(&data[0], (unsigned int) data.size()); + SerializeStringProperty("uri", header + encodedData, o); +} + static void SerializeGltfBufferData(const std::vector &data, const std::string &binFilename) { std::ofstream output(binFilename.c_str(), std::ofstream::binary); @@ -3465,6 +3514,13 @@ static void SerializeGltfAsset(Asset &asset, json &o) { } } +static void SerializeGltfBuffer(Buffer &buffer, json &o) { + SerializeNumberProperty("byteLength", buffer.data.size(), o); + SerializeGltfBufferData(buffer.data, o); + + if (buffer.name.size()) SerializeStringProperty("name", buffer.name, o); +} + static void SerializeGltfBuffer(Buffer &buffer, json &o, const std::string &binFilename, const std::string &binBaseFilename) { @@ -3712,8 +3768,8 @@ static void WriteGltfFile(const std::string &output, bool TinyGLTF::WriteGltfSceneToFile( Model *model, - const std::string - &filename /*, bool embedImages, bool embedBuffers, bool writeBinary*/) { + const std::string &filename, + bool embedBuffers = false /*, bool embedImages, bool writeBinary*/) { json output; // ACCESSORS @@ -3763,8 +3819,13 @@ bool TinyGLTF::WriteGltfSceneToFile( json buffers; for (unsigned int i = 0; i < model->buffers.size(); ++i) { json buffer; - SerializeGltfBuffer(model->buffers[i], buffer, binSaveFilePath, - binFilename); + if (embedBuffers) { + SerializeGltfBuffer(model->buffers[i], buffer); + } + else { + SerializeGltfBuffer(model->buffers[i], buffer, binSaveFilePath, + binFilename); + } buffers.push_back(buffer); } output["buffers"] = buffers;