From fe77cc5cdd1bab6d7ae0642c92ad72d104364d5c Mon Sep 17 00:00:00 2001 From: Syoyo Date: Sat, 9 May 2020 02:41:07 +0900 Subject: [PATCH 01/26] Serialize extension and extras for Camera. Fixes #257 --- tiny_gltf.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tiny_gltf.h b/tiny_gltf.h index 4dfaf8f..18484ea 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -7083,6 +7083,12 @@ static void SerializeGltfCamera(const Camera &camera, json &o) { } else { // ??? } + + if(camera.extras.Type() != NULL_TYPE) + { + SerializeValue("extras", camera.extras, o); + } + SerializeExtensionMap(camera.extensions, o); } static void SerializeGltfScene(Scene &scene, json &o) { From ff0a2e9fb4b3609268a6781c6432368212ce360a Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Mon, 11 May 2020 19:07:00 +0900 Subject: [PATCH 02/26] Return type must be int for GetNumberAsInt(). Fixes #258 --- tiny_gltf.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tiny_gltf.h b/tiny_gltf.h index 18484ea..7a4e6b5 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -323,7 +323,8 @@ class Value { } // Use this function if you want to have number value as int. - double GetNumberAsInt() const { + // TODO(syoyo): Support int value larger than 32 bits + int GetNumberAsInt() const { if (type_ == REAL_TYPE) { return int(real_value_); } else { From 3dad303bea479effc8034d5486df0f7288ac6183 Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Wed, 13 May 2020 21:22:23 +0900 Subject: [PATCH 03/26] Only serialize light.range when `range` > 0. Fixes #260 --- tiny_gltf.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tiny_gltf.h b/tiny_gltf.h index 7a4e6b5..088cbed 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -1115,9 +1115,9 @@ struct SpotLight { struct Light { std::string name; std::vector color; - double intensity; + double intensity{1.0}; std::string type; - double range; + double range{0.0}; // 0.0 = inifinite SpotLight spot; Light() : intensity(1.0), range(0.0) {} @@ -6970,7 +6970,9 @@ static void SerializeSpotLight(SpotLight &spot, json &o) { static void SerializeGltfLight(Light &light, json &o) { if (!light.name.empty()) SerializeStringProperty("name", light.name, o); SerializeNumberProperty("intensity", light.intensity, o); - SerializeNumberProperty("range", light.range, o); + if (light.range > 0.0) { + SerializeNumberProperty("range", light.range, o); + } SerializeNumberArrayProperty("color", light.color, o); SerializeStringProperty("type", light.type, o); if (light.type == "spot") { From 6fad7adb9c74fc00212fbacc49255d069e4432b1 Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Fri, 15 May 2020 21:32:06 +0900 Subject: [PATCH 04/26] Fix existing "extensions" were overwritten in serialization when the scene contains lights(serialized as "KHR_light_punctual") Append "KHR_light_punctual" to `extensionsUsed` if not exist in serialization. Apply clang-format. Fixes #261 --- .../issue-261.bin | Bin 0 -> 240 bytes .../issue-261.gltf | 376 ++++++++++++++++++ tests/tester.cc | 53 +++ tiny_gltf.h | 124 +++--- 4 files changed, 495 insertions(+), 58 deletions(-) create mode 100644 models/Extensions-overwrite-issue261/issue-261.bin create mode 100644 models/Extensions-overwrite-issue261/issue-261.gltf diff --git a/models/Extensions-overwrite-issue261/issue-261.bin b/models/Extensions-overwrite-issue261/issue-261.bin new file mode 100644 index 0000000000000000000000000000000000000000..60ed1b7fff4d33bc8833138dca9c1c8706c67afb GIT binary patch literal 240 zcmZY12?~Hf3`5blAIqbAHT$3i!9w_%q@5&B{<=FG+TlmulMTP!c+67Tm>OJ5vZHjh bN1bdho$XO4Gj4g*@oxObqtW}%EsyqJSx*dS literal 0 HcmV?d00001 diff --git a/models/Extensions-overwrite-issue261/issue-261.gltf b/models/Extensions-overwrite-issue261/issue-261.gltf new file mode 100644 index 0000000..7dd85e2 --- /dev/null +++ b/models/Extensions-overwrite-issue261/issue-261.gltf @@ -0,0 +1,376 @@ +{ + "accessors": [ + { + "bufferView": 0, + "componentType": 5126, + "count": 8, + "max": [ + 0.5, + 0.5, + 0.5 + ], + "min": [ + -0.5, + -0.5, + -0.5 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "componentType": 5125, + "count": 36, + "type": "SCALAR" + } + ], + "asset": { + "copyright": "NVIDIA Corporation", + "generator": "Iray glTF plugin", + "version": "2.0" + }, + "bufferViews": [ + { + "buffer": 0, + "byteLength": 96, + "byteStride": 12 + }, + { + "buffer": 0, + "byteLength": 144, + "byteOffset": 96 + } + ], + "buffers": [ + { + "byteLength": 240, + "uri": "issue-261.bin" + } + ], + "cameras": [ + { + "extensions": { + "NV_Iray": { + "mip_burn_highlights": 0.699999988079071, + "mip_burn_highlights_per_component": false, + "mip_camera_shutter": 4.0, + "mip_cm2_factor": 1.0, + "mip_crush_blacks": 0.5, + "mip_f_number": 1.0, + "mip_film_iso": 100.0, + "mip_gamma": 2.200000047683716, + "mip_saturation": 1.0, + "mip_vignetting": 0.00019999999494757503, + "mip_whitepoint": [ + 1.0, + 1.0, + 1.0, + 1.0 + ], + "tm_enable_tonemapper": true, + "tm_tonemapper": "mia_exposure_photographic" + } + }, + "extras": { + "resolution": [ + 640, + 480 + ] + }, + "name": "default", + "perspective": { + "aspectRatio": 1.3333333730697632, + "yfov": 0.9272952079772949, + "zfar": 1000.0, + "znear": 0.1 + }, + "type": "perspective" + } + ], + "extensions": { + "KHR_lights_punctual": { + "lights": [ + { + "color": [ + 1.0, + 1.0, + 1.0 + ], + "intensity": 1000.0, + "name": "light", + "type": "point" + } + ] + }, + "NV_MDL": { + "modules": [ + "mdl::base", + "mdl::nvidia::core_definitions", + "mdl::state" + ], + "shaders": [ + { + "definition": "mdl::base::environment_spherical(texture_2d)", + "name": "env_shd" + }, + { + "arguments": { + "base_color": [ + 0.0055217444896698, + 0.36859095096588135, + 0.0041161770932376385 + ], + "normal=": 2 + }, + "definition": "mdl::nvidia::core_definitions::flex_material", + "name": "cube_instance_material" + }, + { + "definition": "mdl::state::normal()", + "name": "mdl::state::normal_341" + }, + { + "arguments": { + "base_color": [ + 0.0055217444896698, + 0.36859095096588135, + 0.0041161770932376385 + ], + "normal=": 4 + }, + "definition": "mdl::nvidia::core_definitions::flex_material", + "name": "cube_instance_material" + }, + { + "definition": "mdl::state::normal()", + "name": "mdl::state::normal_341" + } + ] + } + }, + "extensionsUsed": [ + "NV_MDL", + "NV_Iray", + "KHR_lights_punctual" + ], + "materials": [ + { + "doubleSided": true, + "extras": { + "mdl_shader": 1 + }, + "name": "cube_instance_material", + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.0055217444896698, + 0.36859095096588135, + 0.0041161770932376385, + 1.0 + ] + } + } + ], + "meshes": [ + { + "name": "cube", + "primitives": [ + { + "attributes": { + "POSITION": 0 + }, + "indices": 1, + "material": 0, + "mode": 4 + } + ] + } + ], + "nodes": [ + { + "camera": 0, + "extensions": { + "NV_Iray": { + "iview:fkey": -1, + "iview:fov": 53.130104064941406, + "iview:interest": [ + 0.1342654824256897, + -0.14356137812137604, + 0.037264324724674225 + ], + "iview:position": [ + 0.9729073643684387, + 1.2592438459396362, + 2.4199187755584717 + ], + "iview:roll": 0.0, + "iview:up": [ + 0.0, + 1.0, + 0.0 + ] + } + }, + "matrix": [ + 0.9432751389105357, + -1.1769874756875739e-16, + -0.3320120665176343, + 0.0, + -0.16119596696756341, + 0.8742297945345237, + -0.45797175303889276, + 0.0, + 0.290254840694694, + 0.48551237507207207, + 0.8246392308792816, + 0.0, + 0.9729073377709113, + 1.2592438262175363, + 2.419918748461627, + 1.0 + ], + "name": "CamInst" + }, + { + "extensions": { + "NV_Iray": { + "caustic": true, + "caustic_cast": true, + "caustic_recv": true, + "face_back": true, + "face_front": true, + "finalgather": true, + "finalgather_cast": true, + "finalgather_recv": true, + "globillum": true, + "globillum_cast": true, + "globillum_recv": true, + "material=": 3, + "pickable": true, + "reflection_cast": true, + "reflection_recv": true, + "refraction_cast": true, + "refraction_recv": true, + "shadow_cast": true, + "shadow_recv": true, + "transparency_cast": true, + "transparency_recv": true, + "visible": true + } + }, + "mesh": 0, + "name": "cube_instance" + }, + { + "extensions": { + "KHR_lights_punctual": { + "light": 0 + }, + "NV_Iray": { + "shadow_cast": true, + "visible": false + } + }, + "matrix": [ + 0.6988062355563571, + -7.76042172309776e-17, + -0.7153110128800992, + -0.0, + -0.4276881690736487, + 0.8015668284138362, + -0.41781987700564616, + -0.0, + 0.57336957992379, + 0.5979051928078428, + 0.5601398979107212, + 0.0, + 2.3640632834071384, + 2.465226204472449, + 2.309515908392224, + 1.0 + ], + "name": "light_inst" + } + ], + "scene": 0, + "scenes": [ + { + "extensions": { + "NV_Iray": { + "CP_canny_threshold1": 40, + "CP_canny_threshold2": 120, + "CP_color_quantization": 8, + "IVP_color": [ + 1.0, + 0.0, + 0.0, + 1.0 + ], + "TM_drago_bias": 0.8500000238418579, + "TM_drago_gamma2": 2.200000047683716, + "TM_drago_saturation": 1.0, + "TM_durand_contrast": 4.0, + "TM_durand_gamma": 2.200000047683716, + "TM_durand_saturation": 1.0, + "TM_durand_sigma_color": 2.0, + "TM_durand_sigma_space": 2.0, + "TM_linear_gamma": 2.200000047683716, + "TM_reinhard_color_adapt": 0.8999999761581421, + "TM_reinhard_gamma": 1.0, + "TM_reinhard_intensity": 0.0, + "TM_reinhard_light_adapt": 1.0, + "TM_reye_Ywhite": 1000000.0, + "TM_reye_bsize": 2, + "TM_reye_bthres": 3.0, + "TM_reye_gamma": 2.200000047683716, + "TM_reye_key": 0.5, + "TM_reye_saturation": 1.0, + "TM_reye_whitebalance": [ + 1.0, + 0.9965101480484009, + 0.9805564880371094, + 0.0 + ], + "environment_dome_depth": 200.0, + "environment_dome_height": 200.0, + "environment_dome_mode": "infinite", + "environment_dome_position": [ + 0.0, + 0.0, + 0.0 + ], + "environment_dome_radius": 100.0, + "environment_dome_rotation_angle": 0.0, + "environment_dome_width": 200.0, + "environment_function=": 0, + "environment_function_intensity": 1.9900000095367432, + "iray_instancing": "off", + "iview::inline_color": [ + 1.0, + 0.0, + 0.0, + 1.0 + ], + "iview::inline_width": 1.0, + "iview::magnifier_size": 300, + "iview::offset": 10.0, + "iview::outline_color": [ + 0.0, + 0.0, + 0.0, + 1.0 + ], + "iview::outline_width": 2.0, + "iview::overview": true, + "iview::zoom_factor": 1.0, + "samples": 4.0, + "shadow_cast": true, + "shadow_recv": true + } + }, + "nodes": [ + 0, + 1, + 2 + ] + } + ] +} diff --git a/tests/tester.cc b/tests/tester.cc index c6d31b0..e7a7006 100644 --- a/tests/tester.cc +++ b/tests/tester.cc @@ -93,6 +93,59 @@ TEST_CASE("extension-with-empty-object", "[issue-97]") { } +TEST_CASE("extension-overwrite", "[issue-261]") { + + tinygltf::Model model; + tinygltf::TinyGLTF ctx; + std::string err; + std::string warn; + + bool ret = ctx.LoadASCIIFromFile(&model, &err, &warn, "../models/Extensions-overwrite-issue261/issue-261.gltf"); + if (!err.empty()) { + std::cerr << err << std::endl; + } + REQUIRE(true == ret); + + REQUIRE(model.extensionsUsed.size() == 3); + { + bool has_ext_lights = false; + has_ext_lights |= (model.extensionsUsed[0].compare("KHR_lights_punctual") == 0); + has_ext_lights |= (model.extensionsUsed[1].compare("KHR_lights_punctual") == 0); + has_ext_lights |= (model.extensionsUsed[2].compare("KHR_lights_punctual") == 0); + + REQUIRE(true == has_ext_lights); + } + + { + REQUIRE(model.extensions.size() == 2); + REQUIRE(model.extensions.count("NV_MDL")); + REQUIRE(model.extensions.count("KHR_lights_punctual")); + } + + // TODO(syoyo): create temp directory. + { + ret = ctx.WriteGltfSceneToFile(&model, "issue-261.gltf", true, true); + REQUIRE(true == ret); + + tinygltf::Model m; + + // read back serialized glTF + bool ret = ctx.LoadASCIIFromFile(&m, &err, &warn, "issue-261.gltf"); + if (!err.empty()) { + std::cerr << err << std::endl; + } + REQUIRE(true == ret); + + REQUIRE(m.extensionsUsed.size() == 3); + + REQUIRE(m.extensions.size() == 2); + REQUIRE(m.extensions.count("NV_MDL")); + REQUIRE(m.extensions.count("KHR_lights_punctual")); + + } + +} + TEST_CASE("invalid-primitive-indices", "[bounds-checking]") { tinygltf::Model model; tinygltf::TinyGLTF ctx; diff --git a/tiny_gltf.h b/tiny_gltf.h index 088cbed..9bba9c4 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -52,6 +52,7 @@ #include #include +#include // std::fabs #include #include #include @@ -59,7 +60,6 @@ #include #include #include -#include // std::fabs #ifndef TINYGLTF_USE_CPP14 #include @@ -1117,7 +1117,7 @@ struct Light { std::vector color; double intensity{1.0}; std::string type; - double range{0.0}; // 0.0 = inifinite + double range{0.0}; // 0.0 = inifinite SpotLight spot; Light() : intensity(1.0), range(0.0) {} @@ -2662,12 +2662,10 @@ bool WriteWholeFile(std::string *err, const std::string &filepath, const std::vector &contents, void *) { #ifdef _WIN32 #if defined(__GLIBCXX__) // mingw - int file_descriptor = - _wopen(UTF8ToWchar(filepath).c_str(), _O_CREAT | _O_WRONLY | - _O_TRUNC | _O_BINARY); - __gnu_cxx::stdio_filebuf wfile_buf(file_descriptor, - std::ios_base::out | - std::ios_base::binary); + int file_descriptor = _wopen(UTF8ToWchar(filepath).c_str(), + _O_CREAT | _O_WRONLY | _O_TRUNC | _O_BINARY); + __gnu_cxx::stdio_filebuf wfile_buf( + file_descriptor, std::ios_base::out | std::ios_base::binary); std::ostream f(&wfile_buf); #elif defined(_MSC_VER) std::ofstream f(UTF8ToWchar(filepath).c_str(), std::ofstream::binary); @@ -2722,10 +2720,9 @@ static void UpdateImageObject(Image &image, std::string &baseDir, int index, if (image.uri.size()) { filename = GetBaseFilename(image.uri); ext = GetFilePathExtension(filename); - } - else if (image.bufferView != -1) { - //If there's no URI and the data exists in a buffer, - //don't change properties or write images + } else if (image.bufferView != -1) { + // If there's no URI and the data exists in a buffer, + // don't change properties or write images } else if (image.name.size()) { ext = MimeToExt(image.mimeType); // Otherwise use name as filename @@ -4868,13 +4865,13 @@ static bool ParseAnimationChannel( } return false; } - ParseExtensionsProperty(&channel->target_extensions, err, target_object); - if (store_original_json_for_extras_and_extensions) { + ParseExtensionsProperty(&channel->target_extensions, err, target_object); + if (store_original_json_for_extras_and_extensions) { json_const_iterator it; if (FindMember(target_object, "extensions", it)) { channel->target_extensions_json_string = JsonToString(GetValue(it)); } - } + } } channel->sampler = samplerIndex; @@ -5685,9 +5682,11 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn, .target = TINYGLTF_TARGET_ARRAY_BUFFER; } - for(auto &target : primitive.targets) { - for(auto &attribute : target) { - model->bufferViews[size_t(model->accessors[size_t(attribute.second)].bufferView)] + for (auto &target : primitive.targets) { + for (auto &attribute : target) { + model + ->bufferViews[size_t( + model->accessors[size_t(attribute.second)].bufferView)] .target = TINYGLTF_TARGET_ARRAY_BUFFER; } } @@ -6423,12 +6422,10 @@ static bool SerializeGltfBufferData(const std::vector &data, const std::string &binFilename) { #ifdef _WIN32 #if defined(__GLIBCXX__) // mingw - int file_descriptor = - _wopen(UTF8ToWchar(binFilename).c_str(), _O_CREAT | _O_WRONLY | - _O_TRUNC | _O_BINARY); - __gnu_cxx::stdio_filebuf wfile_buf(file_descriptor, - std::ios_base::out | - std::ios_base::binary); + int file_descriptor = _wopen(UTF8ToWchar(binFilename).c_str(), + _O_CREAT | _O_WRONLY | _O_TRUNC | _O_BINARY); + __gnu_cxx::stdio_filebuf wfile_buf( + file_descriptor, std::ios_base::out | std::ios_base::binary); std::ostream output(&wfile_buf); if (!wfile_buf.is_open()) return false; #elif defined(_MSC_VER) @@ -6563,7 +6560,7 @@ static void SerializeGltfAnimationChannel(AnimationChannel &channel, json &o) { SerializeNumberProperty("node", channel.target_node, target); SerializeStringProperty("path", channel.target_path, target); - SerializeExtensionMap(channel.target_extensions, target); + SerializeExtensionMap(channel.target_extensions, target); JsonAddMember(o, "target", std::move(target)); } @@ -7087,8 +7084,7 @@ static void SerializeGltfCamera(const Camera &camera, json &o) { // ??? } - if(camera.extras.Type() != NULL_TYPE) - { + if (camera.extras.Type() != NULL_TYPE) { SerializeValue("extras", camera.extras, o); } SerializeExtensionMap(camera.extensions, o); @@ -7170,7 +7166,7 @@ static void SerializeGltfModel(Model *model, json &o) { JsonAddMember(o, "asset", std::move(asset)); // BUFFERVIEWS - if(model->bufferViews.size()) { + if (model->bufferViews.size()) { json bufferViews; JsonReserveArray(bufferViews, model->bufferViews.size()); for (unsigned int i = 0; i < model->bufferViews.size(); ++i) { @@ -7181,11 +7177,6 @@ static void SerializeGltfModel(Model *model, json &o) { JsonAddMember(o, "bufferViews", std::move(bufferViews)); } - // Extensions used - if (model->extensionsUsed.size()) { - SerializeStringArrayProperty("extensionsUsed", model->extensionsUsed, o); - } - // Extensions required if (model->extensionsRequired.size()) { SerializeStringArrayProperty("extensionsRequired", @@ -7296,7 +7287,9 @@ static void SerializeGltfModel(Model *model, json &o) { // EXTENSIONS SerializeExtensionMap(model->extensions, o); - // LIGHTS as KHR_lights_cmn + auto extensionsUsed = model->extensionsUsed; + + // LIGHTS as KHR_lights_punctual if (model->lights.size()) { json lights; JsonReserveArray(lights, model->lights.size()); @@ -7311,7 +7304,7 @@ static void SerializeGltfModel(Model *model, json &o) { { json_const_iterator it; - if (!FindMember(o, "extensions", it)) { + if (FindMember(o, "extensions", it)) { JsonAssign(ext_j, GetValue(it)); } } @@ -7319,6 +7312,23 @@ static void SerializeGltfModel(Model *model, json &o) { JsonAddMember(ext_j, "KHR_lights_punctual", std::move(khr_lights_cmn)); JsonAddMember(o, "extensions", std::move(ext_j)); + + // Also add "KHR_lights_punctual" to `extensionsUsed` + { + auto has_khr_lights_punctual = std::find_if( + extensionsUsed.begin(), extensionsUsed.end(), [](const std::string &s) { + return (s.compare("KHR_lights_punctual") == 0); + }); + + if (has_khr_lights_punctual == extensionsUsed.end()) { + extensionsUsed.push_back("KHR_lights_punctual"); + } + } + } + + // Extensions used + if (model->extensionsUsed.size()) { + SerializeStringArrayProperty("extensionsUsed", extensionsUsed, o); } // EXTRAS @@ -7338,12 +7348,10 @@ static bool WriteGltfFile(const std::string &output, #if defined(_MSC_VER) std::ofstream gltfFile(UTF8ToWchar(output).c_str()); #elif defined(__GLIBCXX__) - int file_descriptor = - _wopen(UTF8ToWchar(output).c_str(), _O_CREAT | _O_WRONLY | - _O_TRUNC | _O_BINARY); - __gnu_cxx::stdio_filebuf wfile_buf(file_descriptor, - std::ios_base::out | - std::ios_base::binary); + int file_descriptor = _wopen(UTF8ToWchar(output).c_str(), + _O_CREAT | _O_WRONLY | _O_TRUNC | _O_BINARY); + __gnu_cxx::stdio_filebuf wfile_buf( + file_descriptor, std::ios_base::out | std::ios_base::binary); std::ostream gltfFile(&wfile_buf); if (!wfile_buf.is_open()) return false; #else @@ -7429,12 +7437,10 @@ static void WriteBinaryGltfFile(const std::string &output, #if defined(_MSC_VER) std::ofstream gltfFile(UTF8ToWchar(output).c_str(), std::ios::binary); #elif defined(__GLIBCXX__) - int file_descriptor = - _wopen(UTF8ToWchar(output).c_str(), _O_CREAT | _O_WRONLY | - _O_TRUNC | _O_BINARY); - __gnu_cxx::stdio_filebuf wfile_buf(file_descriptor, - std::ios_base::out | - std::ios_base::binary); + int file_descriptor = _wopen(UTF8ToWchar(output).c_str(), + _O_CREAT | _O_WRONLY | _O_TRUNC | _O_BINARY); + __gnu_cxx::stdio_filebuf wfile_buf( + file_descriptor, std::ios_base::out | std::ios_base::binary); std::ostream gltfFile(&wfile_buf); #else std::ofstream gltfFile(output.c_str(), std::ios::binary); @@ -7455,13 +7461,13 @@ bool TinyGLTF::WriteGltfSceneToStream(Model *model, std::ostream &stream, // BUFFERS std::vector binBuffer; - if(model->buffers.size()) { + if (model->buffers.size()) { json buffers; JsonReserveArray(buffers, model->buffers.size()); for (unsigned int i = 0; i < model->buffers.size(); ++i) { json buffer; - if (writeBinary && i==0 && model->buffers[i].uri.empty()){ - SerializeGltfBufferBin(model->buffers[i], buffer,binBuffer); + if (writeBinary && i == 0 && model->buffers[i].uri.empty()) { + SerializeGltfBufferBin(model->buffers[i], buffer, binBuffer); } else { SerializeGltfBuffer(model->buffers[i], buffer); } @@ -7478,10 +7484,11 @@ bool TinyGLTF::WriteGltfSceneToStream(Model *model, std::ostream &stream, json image; std::string dummystring = ""; - // UpdateImageObject need baseDir but only uses it if embeddedImages is - // enabled, since we won't write separate images when writing to a stream we - UpdateImageObject(model->images[i], dummystring, int(i), false, - &this->WriteImageData, this->write_image_user_data_); + // UpdateImageObject need baseDir but only uses it if embeddedImages is + // enabled, since we won't write separate images when writing to a stream + // we + UpdateImageObject(model->images[i], dummystring, int(i), false, + &this->WriteImageData, this->write_image_user_data_); SerializeGltfImage(model->images[i], image); JsonPushBack(images, std::move(image)); } @@ -7526,14 +7533,15 @@ bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename, JsonReserveArray(buffers, model->buffers.size()); for (unsigned int i = 0; i < model->buffers.size(); ++i) { json buffer; - if (writeBinary && i==0 && model->buffers[i].uri.empty()){ - SerializeGltfBufferBin(model->buffers[i], buffer,binBuffer); + if (writeBinary && i == 0 && model->buffers[i].uri.empty()) { + SerializeGltfBufferBin(model->buffers[i], buffer, binBuffer); } else if (embedBuffers) { SerializeGltfBuffer(model->buffers[i], buffer); } else { std::string binSavePath; std::string binUri; - if (!model->buffers[i].uri.empty() && !IsDataURI(model->buffers[i].uri)) { + if (!model->buffers[i].uri.empty() && + !IsDataURI(model->buffers[i].uri)) { binUri = model->buffers[i].uri; } else { binUri = defaultBinFilename + defaultBinFileExt; @@ -7559,7 +7567,7 @@ bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename, } JsonPushBack(buffers, std::move(buffer)); } - JsonAddMember(output, "buffers", std::move(buffers)); + JsonAddMember(output, "buffers", std::move(buffers)); } // IMAGES From aba57bb9077da6012ad9f6b1a2185584d52b61a4 Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Mon, 18 May 2020 20:50:45 +0900 Subject: [PATCH 05/26] Support llvm-mingw(clang + libcxx) to open UTF-8 path in ifstream. --- tiny_gltf.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tiny_gltf.h b/tiny_gltf.h index 9bba9c4..49c313b 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -2618,9 +2618,11 @@ bool ReadWholeFile(std::vector *out, std::string *err, _wopen(UTF8ToWchar(filepath).c_str(), _O_RDONLY | _O_BINARY); __gnu_cxx::stdio_filebuf wfile_buf(file_descriptor, std::ios_base::in); std::istream f(&wfile_buf); -#elif defined(_MSC_VER) +#elif defined(_MSC_VER) || defined(_LIBCPP_VERSION) + // For libcxx, assume _LIBCPP_HAS_OPEN_WITH_WCHAR is defined to accept `wchar_t *` std::ifstream f(UTF8ToWchar(filepath).c_str(), std::ifstream::binary); -#else // clang? +#else + // Unknown compiler/runtime std::ifstream f(filepath.c_str(), std::ifstream::binary); #endif #else From f3bf6ee78eda50141a264fcfb35823a4b6f62d04 Mon Sep 17 00:00:00 2001 From: Syoyo Date: Fri, 22 May 2020 01:25:03 +0900 Subject: [PATCH 06/26] Add TDME2 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2d9143d..9a14ea3 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@ In extension(`ExtensionMap`), JSON number value is parsed as int or float(number * [QuickLook GLTF](https://github.com/toshiks/glTF-quicklook) - quicklook plugin for macos. Also SceneKit wrapper for tinygltf. * [GlslViewer](https://github.com/patriciogonzalezvivo/glslViewer) - live GLSL coding for MacOS and Linux * [Vulkan-Samples](https://github.com/KhronosGroup/Vulkan-Samples) - The Vulkan Samples is collection of resources to help you develop optimized Vulkan applications. +* [TDME2](https://github.com/andreasdr/tdme2) - TDME2 - ThreeDeeMiniEngine2 is a lightweight 3D engine including tools suited for 3D game development using C++11 * Your projects here! (Please send PR) ## TODOs From 272a9dfa5fb4da221ac019e7ff99566a07557e3e Mon Sep 17 00:00:00 2001 From: Ivo van Dongen Date: Fri, 29 May 2020 11:24:11 +0300 Subject: [PATCH 07/26] cast size_t to uint_64_t for rapidjson serialization --- tiny_gltf.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tiny_gltf.h b/tiny_gltf.h index 49c313b..b8b6c9a 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -6274,6 +6274,13 @@ static void SerializeNumberProperty(const std::string &key, T number, JsonAddMember(obj, key.c_str(), json(number)); } +#ifdef TINYGLTF_USE_RAPIDJSON +template <> +void SerializeNumberProperty(const std::string &key, size_t number, json &obj) { + JsonAddMember(obj, key.c_str(), json(static_cast(number))); +} +#endif + template static void SerializeNumberArrayProperty(const std::string &key, const std::vector &value, From 73e73bf3c16b44410ff5f1daf47aa64e8fc228b2 Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Fri, 29 May 2020 20:57:39 +0900 Subject: [PATCH 08/26] Create github actions workflow --- .github/workflows/c-cpp.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/workflows/c-cpp.yml diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml new file mode 100644 index 0000000..51164be --- /dev/null +++ b/.github/workflows/c-cpp.yml @@ -0,0 +1,17 @@ +name: C/C++ CI + +on: [push, pull_request] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: cmake + run: | + mkdir build + cd build + cmake .. + make From 7b69c778fe8be9cb8c01feaa476a1010e5092205 Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Fri, 29 May 2020 22:21:24 +0900 Subject: [PATCH 09/26] Add rapidjson build job --- .github/workflows/c-cpp.yml | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 51164be..4bfe2db 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -3,15 +3,30 @@ name: C/C++ CI on: [push, pull_request] jobs: - build: + + build-linux: runs-on: ubuntu-latest + name: Buld with gcc steps: - uses: actions/checkout@v2 - - name: cmake + - name: build run: | - mkdir build - cd build - cmake .. - make + g++ -std=c++11 -o loader_example loader_example.cc + - name: test + ./loader_example + + build-rapidjson-linux: + + runs-on: ubuntu-latest + name: Buld with gcc + rapidjson + + steps: + - uses: actions/checkout@v2 + - name: build + run: | + git clone https://github.com/Tencent/rapidjson + g++ -DTINYGLTF_USE_RAPIDJSON -I./rapidjson/include/rapidjson -std=c++11 -o loader_example loader_example.cc + - name: test + ./loader_example From ddfa1f2f0b31392909f957d22f95ce8a50366569 Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Sat, 30 May 2020 01:56:35 +0900 Subject: [PATCH 10/26] Fix workflow --- .github/workflows/c-cpp.yml | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 4bfe2db..966d0f5 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -17,6 +17,19 @@ jobs: - name: test ./loader_example + - name: tests + run: | + cd tests + g++ -I../ -std=c++11 -g -O0 -o tester tester.cc + ./tester + + - name: noexcept_tests + run: | + cd tests + g++ -DTINYGLTF_NOEXCEPTION -I../ -std=c++11 -g -O0 -o tester_noexcept tester.cc + ./tester_noexcept + + build-rapidjson-linux: runs-on: ubuntu-latest @@ -27,6 +40,22 @@ jobs: - name: build run: | git clone https://github.com/Tencent/rapidjson + g++ -v g++ -DTINYGLTF_USE_RAPIDJSON -I./rapidjson/include/rapidjson -std=c++11 -o loader_example loader_example.cc - - name: test + + - name: loader_example_test + run: | ./loader_example + + - name: tests + run: | + cd tests + g++ -DTINYGLTF_USE_RAPIDJSON -I../../rapidjson/include/rapidjson -I../ -std=c++11 -g -O0 -o tester tester.cc + ./tester + + - name: noexcept_tests + run: | + cd tests + g++ -DTINYGLTF_USE_RAPIDJSON -I../../rapidjson/include/rapidjson -DTINYGLTF_NOEXCEPTION -I../ -std=c++11 -g -O0 -o tester_noexcept tester.cc + ./tester_noexcept + From db5c3bea45d54ebbec85ba66dbaf08e5501c7098 Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Sat, 30 May 2020 01:59:02 +0900 Subject: [PATCH 11/26] Add gcc-4.8 build job. --- .github/workflows/c-cpp.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 966d0f5..84669c3 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -4,6 +4,32 @@ on: [push, pull_request] jobs: + # compile with older gcc4.8 + build-gcc48: + + runs-on: ubuntu-18.04 + name: Build with gcc 4.8 + + steps: + - name: Checkout + uses: actions/checkout@v1 + + - name: Build + run: | + sudo apt-get update + sudo apt-get install -y build-essential + sudo apt-get install -y gcc-4.8 g++-4.8 + g++-4.8 -std=c++11 -o loader_example loader_example.cc + + - name: NoexceptBuild + run: | + g++-4.8 -DTINYGLTF_NOEXCEPTION -std=c++11 -o loader_example loader_example.cc + + - name: RapidjsonBuild + run: | + git clone https://github.com/Tencent/rapidjson + g++-4.8 -DTINYGLTF_USE_RAPIDJSON -I./rapidjson/include/rapidjson -std=c++11 -o loader_example loader_example.cc + build-linux: runs-on: ubuntu-latest From b48c027c9aa08679afdb1b1f07f4c0f7062e51cd Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Sat, 30 May 2020 02:00:03 +0900 Subject: [PATCH 12/26] Fix yaml syntax. --- .github/workflows/c-cpp.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 84669c3..956e97e 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -41,6 +41,7 @@ jobs: run: | g++ -std=c++11 -o loader_example loader_example.cc - name: test + run: | ./loader_example - name: tests From aca196e8d381bf081012a1de98607fa39e1f35fa Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Sat, 30 May 2020 02:04:06 +0900 Subject: [PATCH 13/26] add aarch64 cross compile and macos build job. --- .github/workflows/c-cpp.yml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 956e97e..f2b8504 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -86,3 +86,36 @@ jobs: g++ -DTINYGLTF_USE_RAPIDJSON -I../../rapidjson/include/rapidjson -DTINYGLTF_NOEXCEPTION -I../ -std=c++11 -g -O0 -o tester_noexcept tester.cc ./tester_noexcept + # Cross-compile for aarch64 linux target + build-cross-aarch64: + + runs-on: ubuntu-18.04 + name: Build on cross aarch64 + + steps: + - name: Checkout + uses: actions/checkout@v1 + - name: Build + run: | + sudo apt-get update + sudo apt-get install -y build-essential + sudo apt-get install -y gcc-8-aarch64-linux-gnu g++-8-aarch64-linux-gnu + + git clone https://github.com/Tencent/rapidjson + aarch64-linux-gnu-g++-8 -DTINYGLTF_USE_RAPIDJSON -I./rapidjson/include/rapidjson -std=c++11 -g -O0 -o loader_example loader_example.cc + + # macOS clang + build-macos: + + runs-on: macos-latest + name: Build on macOS + + steps: + - name: Checkout + uses: actions/checkout@v1 + - name: Build + run: | + clang++ -std=c++11 -g -O0 -o loader_example loader_example.cc + git clone https://github.com/Tencent/rapidjson + clang++ -DTINYGLTF_USE_RAPIDJSON -I./rapidjson/include/rapidjson -std=c++11 -g -O0 -o loader_example loader_example.cc + From c43266fdc9475f6424a1512a621311e244db3892 Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Sat, 30 May 2020 02:07:00 +0900 Subject: [PATCH 14/26] Add argument to loader_example run --- .github/workflows/c-cpp.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index f2b8504..397d66c 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -42,7 +42,7 @@ jobs: g++ -std=c++11 -o loader_example loader_example.cc - name: test run: | - ./loader_example + ./loader_example models/Cube/Cube.gltf - name: tests run: | @@ -72,7 +72,7 @@ jobs: - name: loader_example_test run: | - ./loader_example + ./loader_example models/Cube/Cube.gltf - name: tests run: | @@ -116,6 +116,8 @@ jobs: - name: Build run: | clang++ -std=c++11 -g -O0 -o loader_example loader_example.cc + ./loader_example models/Cube/Cube.gltf + git clone https://github.com/Tencent/rapidjson clang++ -DTINYGLTF_USE_RAPIDJSON -I./rapidjson/include/rapidjson -std=c++11 -g -O0 -o loader_example loader_example.cc From c0467690545ac63ba3967469e8d9c3a716383b97 Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Sat, 30 May 2020 02:12:48 +0900 Subject: [PATCH 15/26] Add mingw build job --- .github/workflows/c-cpp.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 397d66c..3776ba1 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -30,6 +30,24 @@ jobs: git clone https://github.com/Tencent/rapidjson g++-4.8 -DTINYGLTF_USE_RAPIDJSON -I./rapidjson/include/rapidjson -std=c++11 -o loader_example loader_example.cc + # compile with mingw gcc cross + build-mingw-cross: + + runs-on: ubuntu-18.04 + name: Build with MinGW gcc cross + + steps: + - name: Checkout + uses: actions/checkout@v1 + + - name: Build + run: | + sudo apt-get update + sudo apt-get install -y build-essential + sudo apt-get install -y mingw-w64 + x86_64-w64-mingw32-g++ -std=c++11 -o loader_example loader_example.cc + + build-linux: runs-on: ubuntu-latest From 014dce27f4ee0a5c43de7c0eb59c692348ccf145 Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Sat, 30 May 2020 02:16:41 +0900 Subject: [PATCH 16/26] Add VS2019 build job. --- .github/workflows/c-cpp.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 3776ba1..2c45220 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -47,6 +47,26 @@ jobs: sudo apt-get install -y mingw-w64 x86_64-w64-mingw32-g++ -std=c++11 -o loader_example loader_example.cc + # Windows(x64) + Visual Studio 2019 build + build-windows-msvc: + + runs-on: windows-latest + name: Build for Windows(x64, MSVC) + + # Use system installed cmake + # https://help.github.com/en/actions/reference/software-installed-on-github-hosted-runners + steps: + - name: Checkout + uses: actions/checkout@v1 + - name: Configure + run: | + mkdir build + cd build + cmake -G "Visual Studio 16 2019" -DTINYGLTF_BUILD_EXAMPLES=Off .. + cd .. + - name: Build + run: cmake --build build --config Release + build-linux: From 50a3061ddf0540ef837c63df8e4ac48c64b7c113 Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Sat, 30 May 2020 02:19:47 +0900 Subject: [PATCH 17/26] Fix path to rapidjson headers --- .github/workflows/c-cpp.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 2c45220..ffb0822 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -87,12 +87,14 @@ jobs: cd tests g++ -I../ -std=c++11 -g -O0 -o tester tester.cc ./tester + cd .. - name: noexcept_tests run: | cd tests g++ -DTINYGLTF_NOEXCEPTION -I../ -std=c++11 -g -O0 -o tester_noexcept tester.cc ./tester_noexcept + cd .. build-rapidjson-linux: @@ -115,14 +117,16 @@ jobs: - name: tests run: | cd tests - g++ -DTINYGLTF_USE_RAPIDJSON -I../../rapidjson/include/rapidjson -I../ -std=c++11 -g -O0 -o tester tester.cc + g++ -DTINYGLTF_USE_RAPIDJSON -I../rapidjson/include/rapidjson -I../ -std=c++11 -g -O0 -o tester tester.cc ./tester + cd .. - name: noexcept_tests run: | cd tests - g++ -DTINYGLTF_USE_RAPIDJSON -I../../rapidjson/include/rapidjson -DTINYGLTF_NOEXCEPTION -I../ -std=c++11 -g -O0 -o tester_noexcept tester.cc + g++ -DTINYGLTF_USE_RAPIDJSON -I../rapidjson/include/rapidjson -DTINYGLTF_NOEXCEPTION -I../ -std=c++11 -g -O0 -o tester_noexcept tester.cc ./tester_noexcept + cd .. # Cross-compile for aarch64 linux target build-cross-aarch64: From d9c03d041a674633155e64acc6b8829c31b55e4a Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Sat, 30 May 2020 02:21:07 +0900 Subject: [PATCH 18/26] Build examples for VS2019 build job. --- .github/workflows/c-cpp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index ffb0822..c9ba5bb 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -62,7 +62,7 @@ jobs: run: | mkdir build cd build - cmake -G "Visual Studio 16 2019" -DTINYGLTF_BUILD_EXAMPLES=Off .. + cmake -G "Visual Studio 16 2019" -DTINYGLTF_BUILD_EXAMPLES=On .. cd .. - name: Build run: cmake --build build --config Release From 2e7006797b6a4ec6852a7cd80f4ff351586cc55f Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Sat, 30 May 2020 02:27:25 +0900 Subject: [PATCH 19/26] Separrate build of examples. --- CMakeLists.txt | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e7864e5..30cc854 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,18 +4,24 @@ PROJECT (tinygltf) SET(CMAKE_CXX_STANDARD 11) -option(TINYGLTF_BUILD_EXAMPLES "Build examples" ON) +option(TINYGLTF_BUILD_LOADER_EXAMPLE "Build loader_example" ON) +option(TINYGLTF_BUILD_GL_EXAMPLES "Build GL exampels(requires glfw, OpenGL, etc)" OFF) +option(TINYGLTF_BUILD_VALIDATOR_EXAMPLE "Build validator exampe" OFF) -if (TINYGLTF_BUILD_EXAMPLES) +if (TINYGLTF_BUILD_LOADER_EXAMPLE) ADD_EXECUTABLE ( loader_example loader_example.cc ) +endif (TINYGLTF_BUILD_LOADER_EXAMPLE) +if (TINYGLTF_BUILD_GL_EXAMPLES) ADD_SUBDIRECTORY ( examples/gltfutil ) ADD_SUBDIRECTORY ( examples/glview ) - ADD_SUBDIRECTORY ( examples/validator ) -endif (TINYGLTF_BUILD_EXAMPLES) +endif (TINYGLTF_BUILD_GL_EXAMPLES) +if (TINYGLTF_BUILD_VALIDATOR_EXAMPLE) + ADD_SUBDIRECTORY ( examples/validator ) +endif (TINYGLTF_BUILD_VALIDATOR_EXAMPLE) # # TinuGLTF is a header-only library, so no library build. just install header files. # From 34894a6325a2c6a62bc131a16b7c213810ec4c32 Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Sat, 30 May 2020 02:28:58 +0900 Subject: [PATCH 20/26] Build validator for MSVC build. --- .github/workflows/c-cpp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index c9ba5bb..9424b6d 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -62,7 +62,7 @@ jobs: run: | mkdir build cd build - cmake -G "Visual Studio 16 2019" -DTINYGLTF_BUILD_EXAMPLES=On .. + cmake -G "Visual Studio 16 2019" -DTINYGLTF_BUILD_LOADER_EXAMPLE=On -DTINYGLTF_BUILD_GL_EXAMPLES=Off -DTINYGLTF_BUILD_VALIDATOR_EXAMPLE=On .. cd .. - name: Build run: cmake --build build --config Release From 28bafe4b11d687b6a5c13def4fd810f2491dded3 Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Sat, 30 May 2020 17:06:45 +0900 Subject: [PATCH 21/26] Add GitHub Actions badge. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 9a14ea3..e9b4134 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,8 @@ If you are looking for old, C++03 version, please use `devel-picojson` branch. [![Build status](https://ci.appveyor.com/api/projects/status/warngenu9wjjhlm8?svg=true)](https://ci.appveyor.com/project/syoyo/tinygltf) +![C/C++ CI](https://github.com/syoyo/tinygltf/workflows/C/C++%20CI/badge.svg) + ## Features * Written in portable C++. C++-11 with STL dependency only. From 2f5aa9f13b072c2081906f305911cdacdd07b47e Mon Sep 17 00:00:00 2001 From: cwbhhjl Date: Thu, 4 Jun 2020 10:40:38 +0800 Subject: [PATCH 22/26] fix an error occurred while expanding utf8 path --- tiny_gltf.h | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/tiny_gltf.h b/tiny_gltf.h index b8b6c9a..108c8e1 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -2483,6 +2483,15 @@ static inline std::wstring UTF8ToWchar(const std::string &str) { (int)wstr.size()); return wstr; } + +static inline std::string WcharToUTF8(const std::wstring &wstr) { + int str_size = WideCharToMultiByte(CP_UTF8, 0, wstr.data(), (int)wstr.size(), + nullptr, 0, NULL, NULL); + std::string str(str_size, 0); + WideCharToMultiByte(CP_UTF8, 0, wstr.data(), (int)wstr.size(), &str[0], + (int)str.size(), NULL, NULL); + return str; +} #endif #ifndef TINYGLTF_NO_FS @@ -2534,15 +2543,15 @@ bool FileExists(const std::string &abs_filename, void *) { std::string ExpandFilePath(const std::string &filepath, void *) { #ifdef _WIN32 - DWORD len = ExpandEnvironmentStringsA(filepath.c_str(), NULL, 0); - char *str = new char[len]; - ExpandEnvironmentStringsA(filepath.c_str(), str, len); + std::wstring wfilepath = UTF8ToWchar(filepath); + DWORD wlen = ExpandEnvironmentStringsW(wfilepath.c_str(), NULL, 0); + wchar_t *wstr = new wchar_t[wlen]; + ExpandEnvironmentStringsW(wfilepath.c_str(), wstr, wlen); - std::string s(str); - - delete[] str; - - return s; + std::wstring ws(wstr); + delete[] wstr; + return WcharToUTF8(ws); + #else #if defined(TARGET_OS_IPHONE) || defined(TARGET_IPHONE_SIMULATOR) || \ @@ -7326,8 +7335,8 @@ static void SerializeGltfModel(Model *model, json &o) { { auto has_khr_lights_punctual = std::find_if( extensionsUsed.begin(), extensionsUsed.end(), [](const std::string &s) { - return (s.compare("KHR_lights_punctual") == 0); - }); + return (s.compare("KHR_lights_punctual") == 0); + }); if (has_khr_lights_punctual == extensionsUsed.end()) { extensionsUsed.push_back("KHR_lights_punctual"); From cef1787ef8251331f558e3ad20015d64f7e194e7 Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Sat, 6 Jun 2020 17:10:49 +0900 Subject: [PATCH 23/26] Add regression test for PR-266. --- tests/tester.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/tester.cc b/tests/tester.cc index e7a7006..012b54d 100644 --- a/tests/tester.cc +++ b/tests/tester.cc @@ -412,3 +412,19 @@ TEST_CASE("image-uri-spaces", "[issue-236]") { REQUIRE(true == ret); } +#ifndef TINYGLTF_NO_FS +TEST_CASE("expandpath-utf-8", "[pr-226]") { + + std::string s1 = "\xe5\xaf\xb9"; // utf-8 string + + std::string ret = tinygltf::ExpandFilePath(s1, /* userdata */nullptr); + + // expected: E5 AF B9 + REQUIRE(3 == ret.size()); + + REQUIRE(0xe5 == static_cast(ret[0])); + REQUIRE(0xaf == static_cast(ret[1])); + REQUIRE(0xb9 == static_cast(ret[2])); + +} +#endif From fbbeb4d6a9c42921d4a146134d18fcc40cda7be6 Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Sat, 6 Jun 2020 17:11:50 +0900 Subject: [PATCH 24/26] Use nullptr instead of NULL. --- tiny_gltf.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tiny_gltf.h b/tiny_gltf.h index 108c8e1..708ca02 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -2543,15 +2543,16 @@ bool FileExists(const std::string &abs_filename, void *) { std::string ExpandFilePath(const std::string &filepath, void *) { #ifdef _WIN32 + // Assume input `filepath` is encoded in UTF-8 std::wstring wfilepath = UTF8ToWchar(filepath); - DWORD wlen = ExpandEnvironmentStringsW(wfilepath.c_str(), NULL, 0); + DWORD wlen = ExpandEnvironmentStringsW(wfilepath.c_str(), nullptr, 0); wchar_t *wstr = new wchar_t[wlen]; ExpandEnvironmentStringsW(wfilepath.c_str(), wstr, wlen); std::wstring ws(wstr); delete[] wstr; return WcharToUTF8(ws); - + #else #if defined(TARGET_OS_IPHONE) || defined(TARGET_IPHONE_SIMULATOR) || \ From 3d939fd3eebce29a79bc01fdc01e6536546b2e76 Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Sat, 6 Jun 2020 18:13:15 +0900 Subject: [PATCH 25/26] Add comment on tinygltf::ExpandFilePath() --- tiny_gltf.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tiny_gltf.h b/tiny_gltf.h index 708ca02..fa16ec5 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -1249,7 +1249,13 @@ struct FsCallbacks { bool FileExists(const std::string &abs_filename, void *); -std::string ExpandFilePath(const std::string &filepath, void *); +/// +/// Expand file path(e.g. `~` to home directory on posix, `%APPDATA%` to `C:\Users\tinygltf\AppData`) +/// +/// @param[in] filepath File path string. Assume UTF-8 +/// @param[in] userdata User data. Set to `nullptr` if you don't need it. +/// +std::string ExpandFilePath(const std::string &filepath, void *userdata); bool ReadWholeFile(std::vector *out, std::string *err, const std::string &filepath, void *); From bafde6a53e2341afba1899f6aaa42c8b35d32fe7 Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Mon, 8 Jun 2020 16:46:33 +0900 Subject: [PATCH 26/26] Use TINYGLTF_ENABLE_SERIALIZER ifdef to enable/disable serialization code. --- README.md | 1 + tiny_gltf.h | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/README.md b/README.md index e9b4134..0b9d4c5 100644 --- a/README.md +++ b/README.md @@ -153,6 +153,7 @@ if (!ret) { ## Compile options +* `TINYGLTF_ENABLE_SERIALIZER` : Enable glTF serialization feature. * `TINYGLTF_NOEXCEPTION` : Disable C++ exception in JSON parsing. You can use `-fno-exceptions` or by defining the symbol `JSON_NOEXCEPTION` and `TINYGLTF_NOEXCEPTION` to fully remove C++ exception codes when compiling TinyGLTF. * `TINYGLTF_NO_STB_IMAGE` : Do not load images with stb_image. Instead use `TinyGLTF::SetImageLoader(LoadimageDataFunction LoadImageData, void *user_data)` to set a callback for loading images. * `TINYGLTF_NO_STB_IMAGE_WRITE` : Do not write images with stb_image_write. Instead use `TinyGLTF::SetImageWriter(WriteimageDataFunction WriteImageData, void *user_data)` to set a callback for writing images. diff --git a/tiny_gltf.h b/tiny_gltf.h index fa16ec5..8025202 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -26,6 +26,7 @@ // THE SOFTWARE. // Version: +// - v2.4.3 Introduce TINYGLTF_ENABLE_SERIALIZER. // - v2.4.2 Decode percent-encoded URI. // - v2.4.1 Fix some glTF object class does not have `extensions` and/or // `extras` property. @@ -1323,6 +1324,8 @@ class TinyGLTF { const std::string &base_dir = "", unsigned int check_sections = REQUIRE_VERSION); +#if defined(TINYGLTF_ENABLE_SERIALIZER) + /// /// Write glTF to stream, buffers and images will be embeded /// @@ -1336,16 +1339,22 @@ class TinyGLTF { bool embedImages, bool embedBuffers, bool prettyPrint, bool writeBinary); +#endif + /// /// Set callback to use for loading image data /// void SetImageLoader(LoadImageDataFunction LoadImageData, void *user_data); +#if defined(TINYGLTF_ENABLE_SERIALIZER) + /// /// Set callback to use for writing image data /// void SetImageWriter(WriteImageDataFunction WriteImageData, void *user_data); +#endif + /// /// Set callbacks to use for filesystem (fs) access and their user data /// @@ -2393,11 +2402,15 @@ bool LoadImageData(Image *image, const int image_idx, std::string *err, } #endif +#if defined(TINYGLTF_ENABLE_SERIALIZER) + void TinyGLTF::SetImageWriter(WriteImageDataFunction func, void *user_data) { WriteImageData = func; write_image_user_data_ = user_data; } +#endif + #ifndef TINYGLTF_NO_STB_IMAGE_WRITE static void WriteToMemory_stbi(void *context, void *data, int size) { std::vector *buffer = @@ -6214,6 +6227,8 @@ bool TinyGLTF::LoadBinaryFromFile(Model *model, std::string *err, return ret; } +#if defined(TINYGLTF_ENABLE_SERIALIZER) + /////////////////////// // GLTF Serialization /////////////////////// @@ -7619,6 +7634,8 @@ bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename, return true; } +#endif // TINYGLTF_ENABLE_SERIALIZER + } // namespace tinygltf #ifdef __clang__