From 3b735bb878a9e361a90ecdd7e7c82e3850b07311 Mon Sep 17 00:00:00 2001 From: Ben Buzbee Date: Tue, 24 Apr 2018 11:39:30 -0700 Subject: [PATCH 1/2] Serialization fixes --- tiny_gltf.h | 159 ++++++++++++++++++++++++---------------------------- 1 file changed, 72 insertions(+), 87 deletions(-) diff --git a/tiny_gltf.h b/tiny_gltf.h index 523a367..95af339 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -337,7 +338,7 @@ struct Parameter { std::string string_value; std::vector number_array; std::map json_double_value; - + std::optional number_value; // context sensitive methods. depending the type of the Parameter you are // accessing, these are either valid or not // If this parameter represent a texture map in a material, will return the @@ -357,7 +358,7 @@ struct Parameter { /// Material factor, like the roughness or metalness of a material /// Returned value is only valid if the parameter represent a texture from a /// material - double Factor() const { return number_array[0]; } + double Factor() const { return *number_value; } /// Return the color of a material /// Returned value is only valid if the parameter represent a texture from a @@ -650,7 +651,7 @@ class Node { std::vector translation; // length must be 0 or 3 std::vector matrix; // length must be 0 or 16 std::vector weights; // The weights of the instantiated Morph Target - + ExtensionMap extensions; Value extras; }; @@ -1425,9 +1426,9 @@ static std::string MimeToExt(const std::string &mimeType) { } static void UpdateImageObject(Image &image, std::string &baseDir, int index, - bool embedImages, - WriteImageDataFunction *WriteImageData = nullptr, - void *user_data = nullptr) { + bool embedImages, + WriteImageDataFunction *WriteImageData = nullptr, + void *user_data = nullptr) { std::string filename; std::string ext; @@ -1564,37 +1565,27 @@ static bool DecodeDataURI(std::vector *out, return true; } -static bool ParseJsonAsValue(Value* ret, const json &o) -{ +static bool ParseJsonAsValue(Value *ret, const json &o) { Value val{}; - switch (o.type()) - { - case json::value_t::object: - { + switch (o.type()) { + case json::value_t::object: { Value::Object value_object; for (auto it = o.begin(); it != o.end(); it++) { Value entry; ParseJsonAsValue(&entry, it.value()); - if (entry.Type() != NULL_TYPE) - value_object[it.key()] = entry; + if (entry.Type() != NULL_TYPE) value_object[it.key()] = entry; } - if (value_object.size() > 0) - val = Value(value_object); - } - break; - case json::value_t::array: - { + if (value_object.size() > 0) val = Value(value_object); + } break; + case json::value_t::array: { Value::Array value_array; for (auto it = o.begin(); it != o.end(); it++) { Value entry; ParseJsonAsValue(&entry, it.value()); - if (entry.Type() != NULL_TYPE) - value_array.push_back(entry); + if (entry.Type() != NULL_TYPE) value_array.push_back(entry); } - if (value_array.size() > 0) - val = Value(value_array); - } - break; + if (value_array.size() > 0) val = Value(value_array); + } break; case json::value_t::string: val = Value(o.get()); break; @@ -1610,12 +1601,11 @@ static bool ParseJsonAsValue(Value* ret, const json &o) break; case json::value_t::null: case json::value_t::discarded: - //default: + // default: break; } - if (ret) - *ret = val; - + if (ret) *ret = val; + return val.Type() != NULL_TYPE; } @@ -1869,8 +1859,8 @@ static bool ParseJSONProperty(std::map *ret, } static bool ParseParameterProperty(Parameter *param, std::string *err, - const json &o, - const std::string &prop, bool required) { + const json &o, const std::string &prop, + bool required) { double num_val; // A parameter value can either be a string or an array of either a boolean or @@ -1886,7 +1876,7 @@ static bool ParseParameterProperty(Parameter *param, std::string *err, // Found a number array. return true; } else if (ParseNumberProperty(&num_val, err, o, prop, false)) { - param->number_array.push_back(num_val); + param->number_value = num_val; return true; } else if (ParseJSONProperty(¶m->json_double_value, err, o, prop, false)) { @@ -1903,8 +1893,8 @@ static bool ParseParameterProperty(Parameter *param, std::string *err, } } -static bool ParseExtensionsProperty(ExtensionMap *ret, std::string* err, const json &o) -{ +static bool ParseExtensionsProperty(ExtensionMap *ret, std::string *err, + const json &o) { (void)err; json::const_iterator it = o.find("extensions"); @@ -1916,12 +1906,11 @@ static bool ParseExtensionsProperty(ExtensionMap *ret, std::string* err, const j } ExtensionMap extensions; json::const_iterator extIt = it.value().begin(); - for(; extIt != it.value().end(); extIt++) { - if (!extIt.value().is_object()) - continue; + for (; extIt != it.value().end(); extIt++) { + if (!extIt.value().is_object()) continue; ParseJsonAsValue(&extensions[extIt.key()], extIt.value()); } - if(ret) { + if (ret) { (*ret) = extensions; } return true; @@ -2062,7 +2051,7 @@ static bool ParseTexture(Texture *texture, std::string *err, const json &o, texture->sampler = static_cast(sampler); texture->source = static_cast(source); - + ParseExtensionsProperty(&texture->extensions, err, o); ParseExtrasProperty(&texture->extras, o); @@ -2465,9 +2454,10 @@ static bool ParseMaterial(Material *material, std::string *err, const json &o) { } } } - } else if (it.key() == "extensions" || it.key() == "extras") { - // done later, skip, otherwise poorly parsed contents will be saved in the parametermap and serialized again later - } else { + } else if (it.key() == "extensions" || it.key() == "extras") { + // done later, skip, otherwise poorly parsed contents will be saved in the + // parametermap and serialized again later + } else { Parameter param; if (ParseParameterProperty(¶m, err, o, it.key(), false)) { material->additionalValues[it.key()] = param; @@ -3519,7 +3509,7 @@ static void SerializeNumberArrayProperty(const std::string &key, json vals; for (unsigned int i = 0; i < value.size(); ++i) { - vals.push_back(static_cast(value[i])); + vals.push_back(static_cast(value[i])); } if (!vals.is_null()) { obj[key] = vals; @@ -3544,62 +3534,55 @@ static void SerializeStringArrayProperty(const std::string &key, obj[key] = vals; } -static bool ValueToJson(const Value& value, json *ret) -{ +static bool ValueToJson(const Value &value, json *ret) { json obj; - switch (value.Type()) - { + switch (value.Type()) { case NUMBER_TYPE: obj = json(value.Get()); - break; + break; case INT_TYPE: obj = json(value.Get()); - break; + break; case BOOL_TYPE: obj = json(value.Get()); - break; + break; case STRING_TYPE: obj = json(value.Get()); - break; - case ARRAY_TYPE: - { + break; + case ARRAY_TYPE: { for (unsigned int i = 0; i < value.ArrayLen(); ++i) { Value elementValue = value.Get(int(i)); - json elementJson; - if(ValueToJson(value.Get(int(i)), &elementJson)) + json elementJson; + if (ValueToJson(value.Get(int(i)), &elementJson)) obj.push_back(elementJson); } - break; - } + break; + } case BINARY_TYPE: - //TODO - //obj = json(value.Get>()); + // TODO + // obj = json(value.Get>()); return false; break; - case OBJECT_TYPE: - { + case OBJECT_TYPE: { Value::Object objMap = value.Get(); - for (auto& it : objMap) { + for (auto &it : objMap) { json elementJson; - if (ValueToJson(it.second, &elementJson)) - obj[it.first] = elementJson; + if (ValueToJson(it.second, &elementJson)) obj[it.first] = elementJson; } - break; - } - case NULL_TYPE: - default: - return false; + break; + } + case NULL_TYPE: + default: + return false; } - if (ret) - *ret = obj; + if (ret) *ret = obj; return true; } static void SerializeValue(const std::string &key, const Value &value, json &obj) { json ret; - if (ValueToJson(value, &ret)) - obj[key] = ret; + if (ValueToJson(value, &ret)) obj[key] = ret; } static void SerializeGltfBufferData(const std::vector &data, @@ -3626,31 +3609,35 @@ static void SerializeParameterMap(ParameterMap ¶m, json &o) { paramIt->second.number_array, o); } else if (paramIt->second.json_double_value.size()) { json json_double_value; - for (std::map::iterator it = paramIt->second.json_double_value.begin(); it != paramIt->second.json_double_value.end(); ++it) { - json_double_value[it->first] = it->second; + if (it->first == "index") { + json_double_value[it->first] = paramIt->second.TextureIndex(); + } else { + json_double_value[it->first] = it->second; + } } o[paramIt->first] = json_double_value; } else if (!paramIt->second.string_value.empty()) { SerializeStringProperty(paramIt->first, paramIt->second.string_value, o); + } else if (paramIt->second.number_value) { + o[paramIt->first] = *paramIt->second.number_value; } else { o[paramIt->first] = paramIt->second.bool_value; } } } -static void SerializeExtensionMap(ExtensionMap &extensions, json &o) -{ - if(!extensions.size()) - return; +static void SerializeExtensionMap(ExtensionMap &extensions, json &o) { + if (!extensions.size()) return; json extMap; - for(ExtensionMap::iterator extIt = extensions.begin(); extIt != extensions.end(); ++extIt) { + for (ExtensionMap::iterator extIt = extensions.begin(); + extIt != extensions.end(); ++extIt) { json extension_values; - SerializeValue(extIt->first, extIt->second, extMap); + SerializeValue(extIt->first, extIt->second, extMap); } o["extensions"] = extMap; } @@ -3742,7 +3729,7 @@ static void SerializeGltfAsset(Asset &asset, json &o) { if (asset.extras.Keys().size()) { SerializeValue("extras", asset.extras, o); } - + SerializeExtensionMap(asset.extensions, o); } @@ -3794,9 +3781,7 @@ static void SerializeGltfImage(Image &image, json &o) { } static void SerializeGltfMaterial(Material &material, json &o) { - - if (material.extras.Size()) - SerializeValue("extras", material.extras, o); + if (material.extras.Size()) SerializeValue("extras", material.extras, o); SerializeExtensionMap(material.extensions, o); if (material.values.size()) { @@ -4205,7 +4190,7 @@ bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename, ext_j["KHR_lights_cmn"] = khr_lights_cmn; output["extensions"] = ext_j; - } + } WriteGltfFile(filename, output.dump()); return true; From f6af2241352d0cde67b026031f82817c96f7c9cf Mon Sep 17 00:00:00 2001 From: Ben Buzbee Date: Wed, 25 Apr 2018 15:13:05 -0700 Subject: [PATCH 2/2] Remove use of optional --- tiny_gltf.h | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/tiny_gltf.h b/tiny_gltf.h index 95af339..f60d9fb 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -42,7 +42,6 @@ #include #include #include -#include #include #include @@ -335,10 +334,11 @@ using ColorValue = std::array; struct Parameter { bool bool_value; + bool has_number_value = false; std::string string_value; std::vector number_array; std::map json_double_value; - std::optional number_value; + double number_value; // context sensitive methods. depending the type of the Parameter you are // accessing, these are either valid or not // If this parameter represent a texture map in a material, will return the @@ -358,7 +358,7 @@ struct Parameter { /// Material factor, like the roughness or metalness of a material /// Returned value is only valid if the parameter represent a texture from a /// material - double Factor() const { return *number_value; } + double Factor() const { return number_value; } /// Return the color of a material /// Returned value is only valid if the parameter represent a texture from a @@ -1861,8 +1861,6 @@ static bool ParseJSONProperty(std::map *ret, static bool ParseParameterProperty(Parameter *param, std::string *err, const json &o, const std::string &prop, bool required) { - double num_val; - // A parameter value can either be a string or an array of either a boolean or // a number. Booleans of any kind aren't supported here. Granted, it // complicates the Parameter structure and breaks it semantically in the sense @@ -1875,9 +1873,8 @@ static bool ParseParameterProperty(Parameter *param, std::string *err, false)) { // Found a number array. return true; - } else if (ParseNumberProperty(&num_val, err, o, prop, false)) { - param->number_value = num_val; - return true; + } else if (ParseNumberProperty(¶m->number_value, err, o, prop, false)) { + return param->has_number_value = true; } else if (ParseJSONProperty(¶m->json_double_value, err, o, prop, false)) { return true; @@ -3622,8 +3619,8 @@ static void SerializeParameterMap(ParameterMap ¶m, json &o) { o[paramIt->first] = json_double_value; } else if (!paramIt->second.string_value.empty()) { SerializeStringProperty(paramIt->first, paramIt->second.string_value, o); - } else if (paramIt->second.number_value) { - o[paramIt->first] = *paramIt->second.number_value; + } else if (paramIt->second.has_number_value) { + o[paramIt->first] = paramIt->second.number_value; } else { o[paramIt->first] = paramIt->second.bool_value; }