mirror of
https://git.mirrors.martin98.com/https://github.com/syoyo/tinygltf.git
synced 2025-08-13 21:06:02 +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
164
tiny_gltf.h
164
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
|
||||
@ -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(¶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");
|
||||
@ -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(¶m, 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 ¶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) {
|
||||
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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user