Merge pull request #69 from benbuzbee/serialization-fixes

Serialization fixes for single-number values and integers
This commit is contained in:
Syoyo Fujita 2018-04-26 14:06:18 +09:00 committed by GitHub
commit 7c56f8eb9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -334,10 +334,11 @@ using ColorValue = std::array<double, 4>;
struct Parameter {
bool bool_value;
bool has_number_value = false;
std::string string_value;
std::vector<double> number_array;
std::map<std::string, double> json_double_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
@ -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<double> translation; // length must be 0 or 3
std::vector<double> matrix; // length must be 0 or 16
std::vector<double> 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<unsigned char> *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<std::string>());
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,10 +1859,8 @@ static bool ParseJSONProperty(std::map<std::string, double> *ret,
}
static bool ParseParameterProperty(Parameter *param, std::string *err,
const json &o,
const std::string &prop, bool required) {
double num_val;
const json &o, const std::string &prop,
bool required) {
// 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
@ -1885,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_array.push_back(num_val);
return true;
} else if (ParseNumberProperty(&param->number_value, err, o, prop, false)) {
return param->has_number_value = true;
} else if (ParseJSONProperty(&param->json_double_value, err, o, prop,
false)) {
return true;
@ -1903,8 +1890,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 +1903,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 +2048,7 @@ static bool ParseTexture(Texture *texture, std::string *err, const json &o,
texture->sampler = static_cast<int>(sampler);
texture->source = static_cast<int>(source);
ParseExtensionsProperty(&texture->extensions, err, o);
ParseExtrasProperty(&texture->extras, o);
@ -2465,9 +2451,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(&param, err, o, it.key(), false)) {
material->additionalValues[it.key()] = param;
@ -3519,7 +3506,7 @@ static void SerializeNumberArrayProperty(const std::string &key,
json vals;
for (unsigned int i = 0; i < value.size(); ++i) {
vals.push_back(static_cast<double>(value[i]));
vals.push_back(static_cast<T>(value[i]));
}
if (!vals.is_null()) {
obj[key] = vals;
@ -3544,62 +3531,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<double>());
break;
break;
case INT_TYPE:
obj = json(value.Get<int>());
break;
break;
case BOOL_TYPE:
obj = json(value.Get<bool>());
break;
break;
case STRING_TYPE:
obj = json(value.Get<std::string>());
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<std::vector<unsigned char>>());
// TODO
// obj = json(value.Get<std::vector<unsigned char>>());
return false;
break;
case OBJECT_TYPE:
{
case OBJECT_TYPE: {
Value::Object objMap = value.Get<Value::Object>();
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<unsigned char> &data,
@ -3626,31 +3606,35 @@ static void SerializeParameterMap(ParameterMap &param, json &o) {
paramIt->second.number_array, o);
} else if (paramIt->second.json_double_value.size()) {
json json_double_value;
for (std::map<std::string, double>::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.has_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 +3726,7 @@ static void SerializeGltfAsset(Asset &asset, json &o) {
if (asset.extras.Keys().size()) {
SerializeValue("extras", asset.extras, o);
}
SerializeExtensionMap(asset.extensions, o);
}
@ -3794,9 +3778,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 +4187,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;