Merge pull request #393 from pknowlesnv/serialize_const

allow serializing a const Model
This commit is contained in:
Syoyo Fujita 2022-12-29 21:00:24 +09:00 committed by GitHub
commit a40ca4c5ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 135 additions and 54 deletions

View File

@ -540,3 +540,66 @@ TEST_CASE("empty-bin-buffer", "[issue-382]") {
} }
REQUIRE(true == ret); REQUIRE(true == ret);
} }
TEST_CASE("serialize-const-image", "[issue-394]") {
tinygltf::Model m;
tinygltf::Image i;
i.width = 1;
i.height = 1;
i.component = 4;
i.bits = 8;
i.pixel_type = TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE;
i.image = {255, 255, 255, 255};
i.uri = "image.png";
m.images.push_back(i);
std::stringstream os;
tinygltf::TinyGLTF ctx;
ctx.WriteGltfSceneToStream(const_cast<const tinygltf::Model *>(&m), os, false,
false);
REQUIRE(m.images[0].uri == i.uri);
// use nlohmann json
nlohmann::json j = nlohmann::json::parse(os.str());
REQUIRE(1 == j["images"].size());
REQUIRE(j["images"][0].is_object());
REQUIRE(j["images"][0]["uri"].get<std::string>() != i.uri);
REQUIRE(j["images"][0]["uri"].get<std::string>().rfind("data:", 0) == 0);
}
TEST_CASE("serialize-image-callback", "[issue-394]") {
tinygltf::Model m;
tinygltf::Image i;
i.width = 1;
i.height = 1;
i.bits = 32;
i.image = {255, 255, 255, 255};
i.uri = "foo";
m.images.push_back(i);
std::stringstream os;
auto writer = [](const std::string *basepath, const std::string *filename,
const tinygltf::Image *image, bool embedImages,
std::string *out_uri, void *user_pointer) -> bool {
REQUIRE(*filename == "foo");
REQUIRE(embedImages == true);
REQUIRE(user_pointer == (void *)0xba5e1e55);
*out_uri = "bar";
return true;
};
tinygltf::TinyGLTF ctx;
ctx.SetImageWriter(writer, (void *)0xba5e1e55);
ctx.WriteGltfSceneToStream(const_cast<const tinygltf::Model *>(&m), os, false,
false);
// use nlohmann json
nlohmann::json j = nlohmann::json::parse(os.str());
REQUIRE(1 == j["images"].size());
REQUIRE(j["images"][0].is_object());
REQUIRE(j["images"][0]["uri"].get<std::string>() == "bar");
}

View File

@ -1216,9 +1216,13 @@ typedef bool (*LoadImageDataFunction)(Image *, const int, std::string *,
/// ///
/// WriteImageDataFunction type. Signature for custom image writing callbacks. /// WriteImageDataFunction type. Signature for custom image writing callbacks.
/// The out_uri parameter becomes the URI written to the gltf and may reference
/// a file or contain a data URI.
/// ///
typedef bool (*WriteImageDataFunction)(const std::string *, const std::string *, typedef bool (*WriteImageDataFunction)(const std::string *basepath,
Image *, bool, void *); const std::string *filename,
const Image *image, bool embedImages,
std::string *out_uri, void *user_pointer);
#ifndef TINYGLTF_NO_STB_IMAGE #ifndef TINYGLTF_NO_STB_IMAGE
// Declaration of default image loader callback // Declaration of default image loader callback
@ -1230,7 +1234,8 @@ bool LoadImageData(Image *image, const int image_idx, std::string *err,
#ifndef TINYGLTF_NO_STB_IMAGE_WRITE #ifndef TINYGLTF_NO_STB_IMAGE_WRITE
// Declaration of default image writer callback // Declaration of default image writer callback
bool WriteImageData(const std::string *basepath, const std::string *filename, bool WriteImageData(const std::string *basepath, const std::string *filename,
Image *image, bool embedImages, void *); const Image *image, bool embedImages, std::string *out_uri,
void *);
#endif #endif
/// ///
@ -1357,13 +1362,13 @@ class TinyGLTF {
/// ///
/// Write glTF to stream, buffers and images will be embedded /// Write glTF to stream, buffers and images will be embedded
/// ///
bool WriteGltfSceneToStream(Model *model, std::ostream &stream, bool WriteGltfSceneToStream(const Model *model, std::ostream &stream,
bool prettyPrint, bool writeBinary); bool prettyPrint, bool writeBinary);
/// ///
/// Write glTF to file. /// Write glTF to file.
/// ///
bool WriteGltfSceneToFile(Model *model, const std::string &filename, bool WriteGltfSceneToFile(const Model *model, const std::string &filename,
bool embedImages, bool embedBuffers, bool embedImages, bool embedBuffers,
bool prettyPrint, bool writeBinary); bool prettyPrint, bool writeBinary);
@ -2495,7 +2500,8 @@ static void WriteToMemory_stbi(void *context, void *data, int size) {
} }
bool WriteImageData(const std::string *basepath, const std::string *filename, bool WriteImageData(const std::string *basepath, const std::string *filename,
Image *image, bool embedImages, void *fsPtr) { const Image *image, bool embedImages, std::string *out_uri,
void *fsPtr) {
const std::string ext = GetFilePathExtension(*filename); const std::string ext = GetFilePathExtension(*filename);
// Write image to temporary buffer // Write image to temporary buffer
@ -2537,9 +2543,8 @@ bool WriteImageData(const std::string *basepath, const std::string *filename,
if (embedImages) { if (embedImages) {
// Embed base64-encoded image into URI // Embed base64-encoded image into URI
if (data.size()) { if (data.size()) {
image->uri = *out_uri = header +
header + base64_encode(&data[0], static_cast<unsigned int>(data.size()));
base64_encode(&data[0], static_cast<unsigned int>(data.size()));
} else { } else {
// Throw error? // Throw error?
} }
@ -2557,7 +2562,7 @@ bool WriteImageData(const std::string *basepath, const std::string *filename,
} else { } else {
// Throw error? // Throw error?
} }
image->uri = *filename; *out_uri = *filename;
} }
return true; return true;
@ -2828,10 +2833,10 @@ static std::string MimeToExt(const std::string &mimeType) {
return ""; return "";
} }
static void UpdateImageObject(Image &image, std::string &baseDir, int index, static void UpdateImageObject(const Image &image, std::string &baseDir,
bool embedImages, int index, bool embedImages,
WriteImageDataFunction *WriteImageData = nullptr, WriteImageDataFunction *WriteImageData,
void *user_data = nullptr) { std::string *out_uri, void *user_data) {
std::string filename; std::string filename;
std::string ext; std::string ext;
// If image has uri, use it as a filename // If image has uri, use it as a filename
@ -2852,9 +2857,15 @@ static void UpdateImageObject(Image &image, std::string &baseDir, int index,
} }
// If callback is set, modify image data object // If callback is set, modify image data object
bool imageWritten = false;
if (*WriteImageData != nullptr && !filename.empty()) { if (*WriteImageData != nullptr && !filename.empty()) {
std::string uri; imageWritten = (*WriteImageData)(&baseDir, &filename, &image, embedImages,
(*WriteImageData)(&baseDir, &filename, &image, embedImages, user_data); out_uri, user_data);
}
// Use the original uri if the image was not written.
if (!imageWritten) {
*out_uri = image.uri;
} }
} }
@ -6755,7 +6766,7 @@ static void SerializeExtensionMap(const ExtensionMap &extensions, json &o) {
JsonAddMember(o, "extensions", std::move(extMap)); JsonAddMember(o, "extensions", std::move(extMap));
} }
static void SerializeGltfAccessor(Accessor &accessor, json &o) { static void SerializeGltfAccessor(const Accessor &accessor, json &o) {
if (accessor.bufferView >= 0) if (accessor.bufferView >= 0)
SerializeNumberProperty<int>("bufferView", accessor.bufferView, o); SerializeNumberProperty<int>("bufferView", accessor.bufferView, o);
@ -6847,7 +6858,8 @@ static void SerializeGltfAccessor(Accessor &accessor, json &o) {
} }
} }
static void SerializeGltfAnimationChannel(AnimationChannel &channel, json &o) { static void SerializeGltfAnimationChannel(const AnimationChannel &channel,
json &o) {
SerializeNumberProperty("sampler", channel.sampler, o); SerializeNumberProperty("sampler", channel.sampler, o);
{ {
json target; json target;
@ -6866,7 +6878,8 @@ static void SerializeGltfAnimationChannel(AnimationChannel &channel, json &o) {
SerializeExtensionMap(channel.extensions, o); SerializeExtensionMap(channel.extensions, o);
} }
static void SerializeGltfAnimationSampler(AnimationSampler &sampler, json &o) { static void SerializeGltfAnimationSampler(const AnimationSampler &sampler,
json &o) {
SerializeNumberProperty("input", sampler.input, o); SerializeNumberProperty("input", sampler.input, o);
SerializeNumberProperty("output", sampler.output, o); SerializeNumberProperty("output", sampler.output, o);
SerializeStringProperty("interpolation", sampler.interpolation, o); SerializeStringProperty("interpolation", sampler.interpolation, o);
@ -6876,7 +6889,7 @@ static void SerializeGltfAnimationSampler(AnimationSampler &sampler, json &o) {
} }
} }
static void SerializeGltfAnimation(Animation &animation, json &o) { static void SerializeGltfAnimation(const Animation &animation, json &o) {
if (!animation.name.empty()) if (!animation.name.empty())
SerializeStringProperty("name", animation.name, o); SerializeStringProperty("name", animation.name, o);
@ -6912,7 +6925,7 @@ static void SerializeGltfAnimation(Animation &animation, json &o) {
SerializeExtensionMap(animation.extensions, o); SerializeExtensionMap(animation.extensions, o);
} }
static void SerializeGltfAsset(Asset &asset, json &o) { static void SerializeGltfAsset(const Asset &asset, json &o) {
if (!asset.generator.empty()) { if (!asset.generator.empty()) {
SerializeStringProperty("generator", asset.generator, o); SerializeStringProperty("generator", asset.generator, o);
} }
@ -6921,14 +6934,15 @@ static void SerializeGltfAsset(Asset &asset, json &o) {
SerializeStringProperty("copyright", asset.copyright, o); SerializeStringProperty("copyright", asset.copyright, o);
} }
if (asset.version.empty()) { auto version = asset.version;
if (version.empty()) {
// Just in case // Just in case
// `version` must be defined // `version` must be defined
asset.version = "2.0"; version = "2.0";
} }
// TODO(syoyo): Do we need to check if `version` is greater or equal to 2.0? // TODO(syoyo): Do we need to check if `version` is greater or equal to 2.0?
SerializeStringProperty("version", asset.version, o); SerializeStringProperty("version", version, o);
if (asset.extras.Keys().size()) { if (asset.extras.Keys().size()) {
SerializeValue("extras", asset.extras, o); SerializeValue("extras", asset.extras, o);
@ -6937,7 +6951,7 @@ static void SerializeGltfAsset(Asset &asset, json &o) {
SerializeExtensionMap(asset.extensions, o); SerializeExtensionMap(asset.extensions, o);
} }
static void SerializeGltfBufferBin(Buffer &buffer, json &o, static void SerializeGltfBufferBin(const Buffer &buffer, json &o,
std::vector<unsigned char> &binBuffer) { std::vector<unsigned char> &binBuffer) {
SerializeNumberProperty("byteLength", buffer.data.size(), o); SerializeNumberProperty("byteLength", buffer.data.size(), o);
binBuffer = buffer.data; binBuffer = buffer.data;
@ -6949,7 +6963,7 @@ static void SerializeGltfBufferBin(Buffer &buffer, json &o,
} }
} }
static void SerializeGltfBuffer(Buffer &buffer, json &o) { static void SerializeGltfBuffer(const Buffer &buffer, json &o) {
SerializeNumberProperty("byteLength", buffer.data.size(), o); SerializeNumberProperty("byteLength", buffer.data.size(), o);
SerializeGltfBufferData(buffer.data, o); SerializeGltfBufferData(buffer.data, o);
@ -6960,7 +6974,7 @@ static void SerializeGltfBuffer(Buffer &buffer, json &o) {
} }
} }
static bool SerializeGltfBuffer(Buffer &buffer, json &o, static bool SerializeGltfBuffer(const Buffer &buffer, json &o,
const std::string &binFilename, const std::string &binFilename,
const std::string &binBaseFilename) { const std::string &binBaseFilename) {
if (!SerializeGltfBufferData(buffer.data, binFilename)) return false; if (!SerializeGltfBufferData(buffer.data, binFilename)) return false;
@ -6975,7 +6989,7 @@ static bool SerializeGltfBuffer(Buffer &buffer, json &o,
return true; return true;
} }
static void SerializeGltfBufferView(BufferView &bufferView, json &o) { static void SerializeGltfBufferView(const BufferView &bufferView, json &o) {
SerializeNumberProperty("buffer", bufferView.buffer, o); SerializeNumberProperty("buffer", bufferView.buffer, o);
SerializeNumberProperty<size_t>("byteLength", bufferView.byteLength, o); SerializeNumberProperty<size_t>("byteLength", bufferView.byteLength, o);
@ -7001,14 +7015,15 @@ static void SerializeGltfBufferView(BufferView &bufferView, json &o) {
} }
} }
static void SerializeGltfImage(Image &image, json &o) { static void SerializeGltfImage(const Image &image, const std::string uri,
json &o) {
// if uri empty, the mimeType and bufferview should be set // if uri empty, the mimeType and bufferview should be set
if (image.uri.empty()) { if (uri.empty()) {
SerializeStringProperty("mimeType", image.mimeType, o); SerializeStringProperty("mimeType", image.mimeType, o);
SerializeNumberProperty<int>("bufferView", image.bufferView, o); SerializeNumberProperty<int>("bufferView", image.bufferView, o);
} else { } else {
// TODO(syoyo): dlib::urilencode? // TODO(syoyo): dlib::urilencode?
SerializeStringProperty("uri", image.uri, o); SerializeStringProperty("uri", uri, o);
} }
if (image.name.size()) { if (image.name.size()) {
@ -7022,7 +7037,7 @@ static void SerializeGltfImage(Image &image, json &o) {
SerializeExtensionMap(image.extensions, o); SerializeExtensionMap(image.extensions, o);
} }
static void SerializeGltfTextureInfo(TextureInfo &texinfo, json &o) { static void SerializeGltfTextureInfo(const TextureInfo &texinfo, json &o) {
SerializeNumberProperty("index", texinfo.index, o); SerializeNumberProperty("index", texinfo.index, o);
if (texinfo.texCoord != 0) { if (texinfo.texCoord != 0) {
@ -7036,7 +7051,7 @@ static void SerializeGltfTextureInfo(TextureInfo &texinfo, json &o) {
SerializeExtensionMap(texinfo.extensions, o); SerializeExtensionMap(texinfo.extensions, o);
} }
static void SerializeGltfNormalTextureInfo(NormalTextureInfo &texinfo, static void SerializeGltfNormalTextureInfo(const NormalTextureInfo &texinfo,
json &o) { json &o) {
SerializeNumberProperty("index", texinfo.index, o); SerializeNumberProperty("index", texinfo.index, o);
@ -7055,8 +7070,8 @@ static void SerializeGltfNormalTextureInfo(NormalTextureInfo &texinfo,
SerializeExtensionMap(texinfo.extensions, o); SerializeExtensionMap(texinfo.extensions, o);
} }
static void SerializeGltfOcclusionTextureInfo(OcclusionTextureInfo &texinfo, static void SerializeGltfOcclusionTextureInfo(
json &o) { const OcclusionTextureInfo &texinfo, json &o) {
SerializeNumberProperty("index", texinfo.index, o); SerializeNumberProperty("index", texinfo.index, o);
if (texinfo.texCoord != 0) { if (texinfo.texCoord != 0) {
@ -7074,7 +7089,7 @@ static void SerializeGltfOcclusionTextureInfo(OcclusionTextureInfo &texinfo,
SerializeExtensionMap(texinfo.extensions, o); SerializeExtensionMap(texinfo.extensions, o);
} }
static void SerializeGltfPbrMetallicRoughness(PbrMetallicRoughness &pbr, static void SerializeGltfPbrMetallicRoughness(const PbrMetallicRoughness &pbr,
json &o) { json &o) {
std::vector<double> default_baseColorFactor = {1.0, 1.0, 1.0, 1.0}; std::vector<double> default_baseColorFactor = {1.0, 1.0, 1.0, 1.0};
if (!Equals(pbr.baseColorFactor, default_baseColorFactor)) { if (!Equals(pbr.baseColorFactor, default_baseColorFactor)) {
@ -7109,7 +7124,7 @@ static void SerializeGltfPbrMetallicRoughness(PbrMetallicRoughness &pbr,
} }
} }
static void SerializeGltfMaterial(Material &material, json &o) { static void SerializeGltfMaterial(const Material &material, json &o) {
if (material.name.size()) { if (material.name.size()) {
SerializeStringProperty("name", material.name, o); SerializeStringProperty("name", material.name, o);
} }
@ -7185,7 +7200,7 @@ static void SerializeGltfMaterial(Material &material, json &o) {
} }
} }
static void SerializeGltfMesh(Mesh &mesh, json &o) { static void SerializeGltfMesh(const Mesh &mesh, json &o) {
json primitives; json primitives;
JsonReserveArray(primitives, mesh.primitives.size()); JsonReserveArray(primitives, mesh.primitives.size());
for (unsigned int i = 0; i < mesh.primitives.size(); ++i) { for (unsigned int i = 0; i < mesh.primitives.size(); ++i) {
@ -7254,7 +7269,7 @@ static void SerializeGltfMesh(Mesh &mesh, json &o) {
} }
} }
static void SerializeSpotLight(SpotLight &spot, json &o) { static void SerializeSpotLight(const SpotLight &spot, json &o) {
SerializeNumberProperty("innerConeAngle", spot.innerConeAngle, o); SerializeNumberProperty("innerConeAngle", spot.innerConeAngle, o);
SerializeNumberProperty("outerConeAngle", spot.outerConeAngle, o); SerializeNumberProperty("outerConeAngle", spot.outerConeAngle, o);
SerializeExtensionMap(spot.extensions, o); SerializeExtensionMap(spot.extensions, o);
@ -7263,7 +7278,7 @@ static void SerializeSpotLight(SpotLight &spot, json &o) {
} }
} }
static void SerializeGltfLight(Light &light, json &o) { static void SerializeGltfLight(const Light &light, json &o) {
if (!light.name.empty()) SerializeStringProperty("name", light.name, o); if (!light.name.empty()) SerializeStringProperty("name", light.name, o);
SerializeNumberProperty("intensity", light.intensity, o); SerializeNumberProperty("intensity", light.intensity, o);
if (light.range > 0.0) { if (light.range > 0.0) {
@ -7282,7 +7297,7 @@ static void SerializeGltfLight(Light &light, json &o) {
} }
} }
static void SerializeGltfNode(Node &node, json &o) { static void SerializeGltfNode(const Node &node, json &o) {
if (node.translation.size() > 0) { if (node.translation.size() > 0) {
SerializeNumberArrayProperty<double>("translation", node.translation, o); SerializeNumberArrayProperty<double>("translation", node.translation, o);
} }
@ -7320,7 +7335,7 @@ static void SerializeGltfNode(Node &node, json &o) {
SerializeNumberArrayProperty<int>("children", node.children, o); SerializeNumberArrayProperty<int>("children", node.children, o);
} }
static void SerializeGltfSampler(Sampler &sampler, json &o) { static void SerializeGltfSampler(const Sampler &sampler, json &o) {
if (sampler.magFilter != -1) { if (sampler.magFilter != -1) {
SerializeNumberProperty("magFilter", sampler.magFilter, o); SerializeNumberProperty("magFilter", sampler.magFilter, o);
} }
@ -7389,7 +7404,7 @@ static void SerializeGltfCamera(const Camera &camera, json &o) {
SerializeExtensionMap(camera.extensions, o); SerializeExtensionMap(camera.extensions, o);
} }
static void SerializeGltfScene(Scene &scene, json &o) { static void SerializeGltfScene(const Scene &scene, json &o) {
SerializeNumberArrayProperty<int>("nodes", scene.nodes, o); SerializeNumberArrayProperty<int>("nodes", scene.nodes, o);
if (scene.name.size()) { if (scene.name.size()) {
@ -7401,7 +7416,7 @@ static void SerializeGltfScene(Scene &scene, json &o) {
SerializeExtensionMap(scene.extensions, o); SerializeExtensionMap(scene.extensions, o);
} }
static void SerializeGltfSkin(Skin &skin, json &o) { static void SerializeGltfSkin(const Skin &skin, json &o) {
// required // required
SerializeNumberArrayProperty<int>("joints", skin.joints, o); SerializeNumberArrayProperty<int>("joints", skin.joints, o);
@ -7418,7 +7433,7 @@ static void SerializeGltfSkin(Skin &skin, json &o) {
} }
} }
static void SerializeGltfTexture(Texture &texture, json &o) { static void SerializeGltfTexture(const Texture &texture, json &o) {
if (texture.sampler > -1) { if (texture.sampler > -1) {
SerializeNumberProperty("sampler", texture.sampler, o); SerializeNumberProperty("sampler", texture.sampler, o);
} }
@ -7437,7 +7452,7 @@ static void SerializeGltfTexture(Texture &texture, json &o) {
/// ///
/// Serialize all properties except buffers and images. /// Serialize all properties except buffers and images.
/// ///
static void SerializeGltfModel(Model *model, json &o) { static void SerializeGltfModel(const Model *model, json &o) {
// ACCESSORS // ACCESSORS
if (model->accessors.size()) { if (model->accessors.size()) {
json accessors; json accessors;
@ -7763,7 +7778,7 @@ static bool WriteBinaryGltfFile(const std::string &output,
return WriteBinaryGltfStream(gltfFile, content, binBuffer); return WriteBinaryGltfStream(gltfFile, content, binBuffer);
} }
bool TinyGLTF::WriteGltfSceneToStream(Model *model, std::ostream &stream, bool TinyGLTF::WriteGltfSceneToStream(const Model *model, std::ostream &stream,
bool prettyPrint = true, bool prettyPrint = true,
bool writeBinary = false) { bool writeBinary = false) {
JsonDocument output; JsonDocument output;
@ -7799,9 +7814,11 @@ bool TinyGLTF::WriteGltfSceneToStream(Model *model, std::ostream &stream,
// UpdateImageObject need baseDir but only uses it if embeddedImages is // UpdateImageObject need baseDir but only uses it if embeddedImages is
// enabled, since we won't write separate images when writing to a stream // enabled, since we won't write separate images when writing to a stream
// we // we
std::string uri;
UpdateImageObject(model->images[i], dummystring, int(i), true, UpdateImageObject(model->images[i], dummystring, int(i), true,
&this->WriteImageData, this->write_image_user_data_); &this->WriteImageData, &uri,
SerializeGltfImage(model->images[i], image); this->write_image_user_data_);
SerializeGltfImage(model->images[i], uri, image);
JsonPushBack(images, std::move(image)); JsonPushBack(images, std::move(image));
} }
JsonAddMember(output, "images", std::move(images)); JsonAddMember(output, "images", std::move(images));
@ -7812,10 +7829,10 @@ bool TinyGLTF::WriteGltfSceneToStream(Model *model, std::ostream &stream,
} else { } else {
return WriteGltfStream(stream, JsonToString(output, prettyPrint ? 2 : -1)); return WriteGltfStream(stream, JsonToString(output, prettyPrint ? 2 : -1));
} }
} }
bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename, bool TinyGLTF::WriteGltfSceneToFile(const Model *model,
const std::string &filename,
bool embedImages = false, bool embedImages = false,
bool embedBuffers = false, bool embedBuffers = false,
bool prettyPrint = true, bool prettyPrint = true,
@ -7888,9 +7905,11 @@ bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename,
for (unsigned int i = 0; i < model->images.size(); ++i) { for (unsigned int i = 0; i < model->images.size(); ++i) {
json image; json image;
std::string uri;
UpdateImageObject(model->images[i], baseDir, int(i), embedImages, UpdateImageObject(model->images[i], baseDir, int(i), embedImages,
&this->WriteImageData, this->write_image_user_data_); &this->WriteImageData, &uri,
SerializeGltfImage(model->images[i], image); this->write_image_user_data_);
SerializeGltfImage(model->images[i], uri, image);
JsonPushBack(images, std::move(image)); JsonPushBack(images, std::move(image));
} }
JsonAddMember(output, "images", std::move(images)); JsonAddMember(output, "images", std::move(images));
@ -7901,7 +7920,6 @@ bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename,
} else { } else {
return WriteGltfFile(filename, JsonToString(output, (prettyPrint ? 2 : -1))); return WriteGltfFile(filename, JsonToString(output, (prettyPrint ? 2 : -1)));
} }
} }
} // namespace tinygltf } // namespace tinygltf