mirror of
https://git.mirrors.martin98.com/https://github.com/syoyo/tinygltf.git
synced 2025-08-14 18:35:59 +08:00
Merge pull request #69 from benbuzbee/serialization-fixes
Serialization fixes for single-number values and integers
This commit is contained in:
commit
7c56f8eb9e
102
tiny_gltf.h
102
tiny_gltf.h
@ -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
|
||||
@ -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;
|
||||
@ -1613,8 +1604,7 @@ static bool ParseJsonAsValue(Value* ret, const json &o)
|
||||
// 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(¶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;
|
||||
@ -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");
|
||||
@ -1917,8 +1904,7 @@ 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;
|
||||
if (!extIt.value().is_object()) continue;
|
||||
ParseJsonAsValue(&extensions[extIt.key()], extIt.value());
|
||||
}
|
||||
if (ret) {
|
||||
@ -2466,7 +2452,8 @@ 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
|
||||
// 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)) {
|
||||
@ -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,11 +3531,9 @@ 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;
|
||||
@ -3561,8 +3546,7 @@ static bool ValueToJson(const Value& value, json *ret)
|
||||
case STRING_TYPE:
|
||||
obj = json(value.Get<std::string>());
|
||||
break;
|
||||
case ARRAY_TYPE:
|
||||
{
|
||||
case ARRAY_TYPE: {
|
||||
for (unsigned int i = 0; i < value.ArrayLen(); ++i) {
|
||||
Value elementValue = value.Get(int(i));
|
||||
json elementJson;
|
||||
@ -3576,13 +3560,11 @@ static bool ValueToJson(const Value& value, json *ret)
|
||||
// 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) {
|
||||
json elementJson;
|
||||
if (ValueToJson(it.second, &elementJson))
|
||||
obj[it.first] = elementJson;
|
||||
if (ValueToJson(it.second, &elementJson)) obj[it.first] = elementJson;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -3590,16 +3572,14 @@ static bool ValueToJson(const Value& value, json *ret)
|
||||
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,29 +3606,33 @@ 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<std::string, double>::iterator it =
|
||||
paramIt->second.json_double_value.begin();
|
||||
it != paramIt->second.json_double_value.end(); ++it) {
|
||||
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);
|
||||
}
|
||||
@ -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()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user