mirror of
https://git.mirrors.martin98.com/https://github.com/syoyo/tinygltf.git
synced 2025-08-12 12:49:06 +08:00
Updates materials (glTF 2.0)
glTF 2.0 has now PBR materials. Core material is Metallic/Roughness material Specular/glossiness is still in an extension Material properties can be number arrays (colors/factors) or JSON objects (textures)
This commit is contained in:
parent
a25e495fd9
commit
ab7b218385
@ -272,8 +272,10 @@ TINYGLTF_VALUE_GET(Value::Object, object_value_)
|
|||||||
#undef TINYGLTF_VALUE_GET
|
#undef TINYGLTF_VALUE_GET
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
bool bool_value;
|
||||||
std::string string_value;
|
std::string string_value;
|
||||||
std::vector<double> number_array;
|
std::vector<double> number_array;
|
||||||
|
std::map<std::string, double> json_double_value;
|
||||||
} Parameter;
|
} Parameter;
|
||||||
|
|
||||||
typedef std::map<std::string, Parameter> ParameterMap;
|
typedef std::map<std::string, Parameter> ParameterMap;
|
||||||
@ -357,13 +359,18 @@ struct Texture {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
// Each extension should be stored in a ParameterMap.
|
||||||
|
// members not in the values could be included in the ParameterMap
|
||||||
|
// to keep a single material model
|
||||||
|
struct Material {
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string technique;
|
|
||||||
ParameterMap values;
|
|
||||||
|
|
||||||
|
ParameterMap values; // PBR metal/roughness workflow
|
||||||
|
ParameterMap additionalValues; // normal/occlusion/emissive values
|
||||||
|
ParameterMap extCommonValues; // KHR_common_material extension
|
||||||
|
ParameterMap extPBRValues;
|
||||||
Value extras;
|
Value extras;
|
||||||
} Material;
|
};
|
||||||
|
|
||||||
struct BufferView{
|
struct BufferView{
|
||||||
std::string name;
|
std::string name;
|
||||||
@ -1301,6 +1308,43 @@ static bool ParseKHRBinaryExtension(const picojson::object &o, std::string *err,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ParseJSONProperty(std::map<std::string, double> *ret, std::string *err,
|
||||||
|
const picojson::object &o,
|
||||||
|
const std::string &property,
|
||||||
|
bool required)
|
||||||
|
{
|
||||||
|
picojson::object::const_iterator it = o.find(property);
|
||||||
|
if(it == o.end())
|
||||||
|
{
|
||||||
|
if (required) {
|
||||||
|
if(err) {
|
||||||
|
(*err) += "'" + property + "' property is missing. \n'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!it->second.is<picojson::object>()) {
|
||||||
|
if (required) {
|
||||||
|
if (err) {
|
||||||
|
(*err) += "'" + property + "' property is not a JSON object.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret->clear();
|
||||||
|
const picojson::object &obj = it->second.get<picojson::object>();
|
||||||
|
picojson::object::const_iterator it2(obj.begin());
|
||||||
|
picojson::object::const_iterator itEnd(obj.end());
|
||||||
|
for (; it2 != itEnd; it2++) {
|
||||||
|
if(it2->second.is<double>())
|
||||||
|
ret->insert(std::pair<std::string, double>(it2->first, it2->second.get<double>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool ParseAsset(Asset *asset, std::string *err,
|
static bool ParseAsset(Asset *asset, std::string *err,
|
||||||
const picojson::object &o) {
|
const picojson::object &o) {
|
||||||
ParseStringProperty(&asset->generator, err, o, "generator", false);
|
ParseStringProperty(&asset->generator, err, o, "generator", false);
|
||||||
@ -1776,6 +1820,10 @@ static bool ParseParameterProperty(Parameter *param, std::string *err,
|
|||||||
} else if (ParseNumberProperty(&num_val, err, o, prop, false)) {
|
} else if (ParseNumberProperty(&num_val, err, o, prop, false)) {
|
||||||
param->number_array.push_back(num_val);
|
param->number_array.push_back(num_val);
|
||||||
return true;
|
return true;
|
||||||
|
} else if(ParseJSONProperty(¶m->json_double_value, err, o, prop, false)) {
|
||||||
|
return true;
|
||||||
|
} else if(ParseBooleanProperty(¶m->bool_value, err, o, prop, false)) {
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
if (required) {
|
if (required) {
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -1788,24 +1836,63 @@ static bool ParseParameterProperty(Parameter *param, std::string *err,
|
|||||||
|
|
||||||
static bool ParseMaterial(Material *material, std::string *err,
|
static bool ParseMaterial(Material *material, std::string *err,
|
||||||
const picojson::object &o) {
|
const picojson::object &o) {
|
||||||
ParseStringProperty(&material->name, err, o, "name", false);
|
|
||||||
ParseStringProperty(&material->technique, err, o, "technique", false);
|
|
||||||
|
|
||||||
material->values.clear();
|
material->values.clear();
|
||||||
picojson::object::const_iterator valuesIt = o.find("values");
|
material->extPBRValues.clear();
|
||||||
|
material->additionalValues.clear();
|
||||||
|
|
||||||
if ((valuesIt != o.end()) && (valuesIt->second).is<picojson::object>()) {
|
picojson::object::const_iterator it(o.begin());
|
||||||
const picojson::object &values_object =
|
picojson::object::const_iterator itEnd(o.end());
|
||||||
(valuesIt->second).get<picojson::object>();
|
|
||||||
|
|
||||||
picojson::object::const_iterator it(values_object.begin());
|
|
||||||
picojson::object::const_iterator itEnd(values_object.end());
|
|
||||||
|
|
||||||
for (; it != itEnd; it++) {
|
for (; it != itEnd; it++) {
|
||||||
|
if(it->first == "pbrMetallicRoughness")
|
||||||
|
{
|
||||||
|
if ((it->second).is<picojson::object>()) {
|
||||||
|
const picojson::object &values_object =
|
||||||
|
(it->second).get<picojson::object>();
|
||||||
|
|
||||||
|
picojson::object::const_iterator itVal(values_object.begin());
|
||||||
|
picojson::object::const_iterator itEnd(values_object.end());
|
||||||
|
|
||||||
|
for (; itVal != itEnd; itVal++) {
|
||||||
Parameter param;
|
Parameter param;
|
||||||
if (ParseParameterProperty(¶m, err, values_object, it->first,
|
if (ParseParameterProperty(¶m, err, values_object, itVal->first,
|
||||||
false)) {
|
false)) {
|
||||||
material->values[it->first] = param;
|
material->values[itVal->first] = param;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(it->first == "extensions")
|
||||||
|
{
|
||||||
|
if ((it->second).is<picojson::object>()) {
|
||||||
|
const picojson::object &extension = (it->second).get<picojson::object>();
|
||||||
|
|
||||||
|
picojson::object::const_iterator extIt = extension.begin();
|
||||||
|
if(!extIt->second.is<picojson::object>())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const picojson::object &values_object =
|
||||||
|
(extIt->second).get<picojson::object>();
|
||||||
|
|
||||||
|
picojson::object::const_iterator itVal(values_object.begin());
|
||||||
|
picojson::object::const_iterator itEnd(values_object.end());
|
||||||
|
|
||||||
|
for (; itVal != itEnd; itVal++) {
|
||||||
|
Parameter param;
|
||||||
|
if (ParseParameterProperty(¶m, err, values_object, itVal->first,
|
||||||
|
false)) {
|
||||||
|
material->extPBRValues[itVal->first] = param;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Parameter param;
|
||||||
|
if (ParseParameterProperty(¶m, err, o, it->first,
|
||||||
|
false)) {
|
||||||
|
material->additionalValues[it->first] = param;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user