mirror of
https://git.mirrors.martin98.com/https://github.com/syoyo/tinygltf.git
synced 2025-08-11 01:09:02 +08:00
Now material is parsed as a struct with explicit parameter definitions.
Implement Material struct serialization.
This commit is contained in:
parent
89fd93f815
commit
046400b17f
@ -175,7 +175,10 @@ static std::string PrintIntArray(const std::vector<int> &arr) {
|
|||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "[ ";
|
ss << "[ ";
|
||||||
for (size_t i = 0; i < arr.size(); i++) {
|
for (size_t i = 0; i < arr.size(); i++) {
|
||||||
ss << arr[i] << ((i != arr.size() - 1) ? ", " : "");
|
ss << arr[i];
|
||||||
|
if (i != arr.size() - 1) {
|
||||||
|
ss << ", ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ss << " ]";
|
ss << " ]";
|
||||||
|
|
||||||
@ -190,7 +193,10 @@ static std::string PrintFloatArray(const std::vector<double> &arr) {
|
|||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "[ ";
|
ss << "[ ";
|
||||||
for (size_t i = 0; i < arr.size(); i++) {
|
for (size_t i = 0; i < arr.size(); i++) {
|
||||||
ss << arr[i] << ((i != arr.size() - 1) ? ", " : "");
|
ss << arr[i];
|
||||||
|
if (i != arr.size() - 1) {
|
||||||
|
ss << ", ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ss << " ]";
|
ss << " ]";
|
||||||
|
|
||||||
@ -243,35 +249,36 @@ static std::string PrintValue(const std::string &name,
|
|||||||
if (tag) {
|
if (tag) {
|
||||||
ss << Indent(indent) << name << " : " << value.Get<std::string>();
|
ss << Indent(indent) << name << " : " << value.Get<std::string>();
|
||||||
} else {
|
} else {
|
||||||
ss << " " << value.Get<std::string>() << " ";
|
ss << Indent(indent) << value.Get<std::string>() << " ";
|
||||||
}
|
}
|
||||||
} else if (value.IsBool()) {
|
} else if (value.IsBool()) {
|
||||||
if (tag) {
|
if (tag) {
|
||||||
ss << Indent(indent) << name << " : " << value.Get<bool>();
|
ss << Indent(indent) << name << " : " << value.Get<bool>();
|
||||||
} else {
|
} else {
|
||||||
ss << " " << value.Get<bool>() << " ";
|
ss << Indent(indent) << value.Get<bool>() << " ";
|
||||||
}
|
}
|
||||||
} else if (value.IsNumber()) {
|
} else if (value.IsNumber()) {
|
||||||
if (tag) {
|
if (tag) {
|
||||||
ss << Indent(indent) << name << " : " << value.Get<double>();
|
ss << Indent(indent) << name << " : " << value.Get<double>();
|
||||||
} else {
|
} else {
|
||||||
ss << " " << value.Get<double>() << " ";
|
ss << Indent(indent) << value.Get<double>() << " ";
|
||||||
}
|
}
|
||||||
} else if (value.IsInt()) {
|
} else if (value.IsInt()) {
|
||||||
if (tag) {
|
if (tag) {
|
||||||
ss << Indent(indent) << name << " : " << value.Get<int>();
|
ss << Indent(indent) << name << " : " << value.Get<int>();
|
||||||
} else {
|
} else {
|
||||||
ss << " " << value.Get<int>() << " ";
|
ss << Indent(indent) << value.Get<int>() << " ";
|
||||||
}
|
}
|
||||||
} else if (value.IsArray()) {
|
} else if (value.IsArray()) {
|
||||||
ss << Indent(indent) << name << " [ ";
|
// TODO(syoyo): Better pretty printing of array item
|
||||||
|
ss << Indent(indent) << name << " [ \n";
|
||||||
for (size_t i = 0; i < value.Size(); i++) {
|
for (size_t i = 0; i < value.Size(); i++) {
|
||||||
ss << PrintValue("", value.Get(int(i)), indent + 1, /* tag */ false);
|
ss << PrintValue("", value.Get(int(i)), indent + 1, /* tag */ false);
|
||||||
if (i != (value.ArrayLen() - 1)) {
|
if (i != (value.ArrayLen() - 1)) {
|
||||||
ss << ", ";
|
ss << ", \n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ss << Indent(indent) << "] ";
|
ss << "\n" << Indent(indent) << "] ";
|
||||||
}
|
}
|
||||||
|
|
||||||
// @todo { binary }
|
// @todo { binary }
|
||||||
@ -339,6 +346,54 @@ static void DumpExtensions(const tinygltf::ExtensionMap &extension,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void DumpTextureInfo(const tinygltf::TextureInfo &texinfo,
|
||||||
|
const int indent) {
|
||||||
|
std::cout << Indent(indent) << "index : " << texinfo.index << "\n";
|
||||||
|
std::cout << Indent(indent) << "texCoord : TEXCOORD_" << texinfo.texCoord
|
||||||
|
<< "\n";
|
||||||
|
DumpExtensions(texinfo.extensions, indent + 1);
|
||||||
|
std::cout << PrintValue("extras", texinfo.extras, indent + 1) << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DumpNormalTextureInfo(const tinygltf::NormalTextureInfo &texinfo,
|
||||||
|
const int indent) {
|
||||||
|
std::cout << Indent(indent) << "index : " << texinfo.index << "\n";
|
||||||
|
std::cout << Indent(indent) << "texCoord : TEXCOORD_" << texinfo.texCoord
|
||||||
|
<< "\n";
|
||||||
|
std::cout << Indent(indent) << "scale : " << texinfo.scale << "\n";
|
||||||
|
DumpExtensions(texinfo.extensions, indent + 1);
|
||||||
|
std::cout << PrintValue("extras", texinfo.extras, indent + 1) << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DumpOcclusionTextureInfo(
|
||||||
|
const tinygltf::OcclusionTextureInfo &texinfo, const int indent) {
|
||||||
|
std::cout << Indent(indent) << "index : " << texinfo.index << "\n";
|
||||||
|
std::cout << Indent(indent) << "texCoord : TEXCOORD_" << texinfo.texCoord
|
||||||
|
<< "\n";
|
||||||
|
std::cout << Indent(indent) << "strength : " << texinfo.strength << "\n";
|
||||||
|
DumpExtensions(texinfo.extensions, indent + 1);
|
||||||
|
std::cout << PrintValue("extras", texinfo.extras, indent + 1) << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DumpPbrMetallicRoughness(const tinygltf::PbrMetallicRoughness &pbr,
|
||||||
|
const int indent) {
|
||||||
|
std::cout << Indent(indent)
|
||||||
|
<< "baseColorFactor : " << PrintFloatArray(pbr.baseColorFactor)
|
||||||
|
<< "\n";
|
||||||
|
std::cout << Indent(indent) << "baseColorTexture :\n";
|
||||||
|
DumpTextureInfo(pbr.baseColorTexture, indent + 1);
|
||||||
|
|
||||||
|
std::cout << Indent(indent) << "metallicFactor : " << pbr.metallicFactor
|
||||||
|
<< "\n";
|
||||||
|
std::cout << Indent(indent) << "roughnessFactor : " << pbr.roughnessFactor
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
|
std::cout << Indent(indent) << "metallicRoughnessTexture :\n";
|
||||||
|
DumpTextureInfo(pbr.metallicRoughnessTexture, indent + 1);
|
||||||
|
DumpExtensions(pbr.extensions, indent + 1);
|
||||||
|
std::cout << PrintValue("extras", pbr.extras, indent + 1) << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
static void Dump(const tinygltf::Model &model) {
|
static void Dump(const tinygltf::Model &model) {
|
||||||
std::cout << "=== Dump glTF ===" << std::endl;
|
std::cout << "=== Dump glTF ===" << std::endl;
|
||||||
std::cout << "asset.copyright : " << model.asset.copyright
|
std::cout << "asset.copyright : " << model.asset.copyright
|
||||||
@ -509,16 +564,44 @@ static void Dump(const tinygltf::Model &model) {
|
|||||||
<< std::endl;
|
<< std::endl;
|
||||||
for (size_t i = 0; i < model.materials.size(); i++) {
|
for (size_t i = 0; i < model.materials.size(); i++) {
|
||||||
const tinygltf::Material &material = model.materials[i];
|
const tinygltf::Material &material = model.materials[i];
|
||||||
std::cout << Indent(1) << "name : " << material.name << std::endl;
|
std::cout << Indent(1) << "name : " << material.name
|
||||||
std::cout << Indent(1) << "values(items=" << material.values.size() << ")"
|
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
|
std::cout << Indent(1) << "alphaMode : " << material.alphaMode
|
||||||
|
<< std::endl;
|
||||||
|
std::cout << Indent(1)
|
||||||
|
<< "alphaCutoff : " << material.alphaCutoff
|
||||||
|
<< std::endl;
|
||||||
|
std::cout << Indent(1) << "doubleSided : "
|
||||||
|
<< (material.doubleSided ? "true" : "false") << std::endl;
|
||||||
|
std::cout << Indent(1) << "emissiveFactor : "
|
||||||
|
<< PrintFloatArray(material.emissiveFactor) << std::endl;
|
||||||
|
|
||||||
|
std::cout << Indent(1) << "pbrMetallicRoughness :\n";
|
||||||
|
DumpPbrMetallicRoughness(material.pbrMetallicRoughness, 2);
|
||||||
|
|
||||||
|
std::cout << Indent(1) << "normalTexture :\n";
|
||||||
|
DumpNormalTextureInfo(material.normalTexture, 2);
|
||||||
|
|
||||||
|
std::cout << Indent(1) << "occlusionTexture :\n";
|
||||||
|
DumpOcclusionTextureInfo(material.occlusionTexture, 2);
|
||||||
|
|
||||||
|
std::cout << Indent(1) << "emissiveTexture :\n";
|
||||||
|
DumpTextureInfo(material.emissiveTexture, 2);
|
||||||
|
|
||||||
|
std::cout << Indent(1) << "---- legacy material parameter ----\n";
|
||||||
|
std::cout << Indent(1) << "values(items=" << material.values.size() << ")"
|
||||||
|
<< std::endl;
|
||||||
tinygltf::ParameterMap::const_iterator p(material.values.begin());
|
tinygltf::ParameterMap::const_iterator p(material.values.begin());
|
||||||
tinygltf::ParameterMap::const_iterator pEnd(material.values.end());
|
tinygltf::ParameterMap::const_iterator pEnd(material.values.end());
|
||||||
for (; p != pEnd; p++) {
|
for (; p != pEnd; p++) {
|
||||||
std::cout << Indent(2) << p->first << ": "
|
std::cout << Indent(2) << p->first << ": "
|
||||||
<< PrintParameterValue(p->second) << std::endl;
|
<< PrintParameterValue(p->second) << std::endl;
|
||||||
}
|
}
|
||||||
|
std::cout << Indent(1) << "-------------------------------------\n";
|
||||||
|
|
||||||
|
DumpExtensions(material.extensions, 1);
|
||||||
|
std::cout << PrintValue("extras", material.extras, 2) << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
224
models/Cube-texture-ext/Cube-textransform.gltf
Normal file
224
models/Cube-texture-ext/Cube-textransform.gltf
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
{
|
||||||
|
"accessors": [
|
||||||
|
{
|
||||||
|
"bufferView": 0,
|
||||||
|
"byteOffset": 0,
|
||||||
|
"componentType": 5123,
|
||||||
|
"count": 36,
|
||||||
|
"max": [
|
||||||
|
35
|
||||||
|
],
|
||||||
|
"min": [
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"type": "SCALAR"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView": 1,
|
||||||
|
"byteOffset": 0,
|
||||||
|
"componentType": 5126,
|
||||||
|
"count": 36,
|
||||||
|
"max": [
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1.000001
|
||||||
|
],
|
||||||
|
"min": [
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1
|
||||||
|
],
|
||||||
|
"type": "VEC3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView": 2,
|
||||||
|
"byteOffset": 0,
|
||||||
|
"componentType": 5126,
|
||||||
|
"count": 36,
|
||||||
|
"max": [
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"min": [
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1
|
||||||
|
],
|
||||||
|
"type": "VEC3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView": 3,
|
||||||
|
"byteOffset": 0,
|
||||||
|
"componentType": 5126,
|
||||||
|
"count": 36,
|
||||||
|
"max": [
|
||||||
|
1,
|
||||||
|
-0,
|
||||||
|
-0,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"min": [
|
||||||
|
0,
|
||||||
|
-0,
|
||||||
|
-1,
|
||||||
|
-1
|
||||||
|
],
|
||||||
|
"type": "VEC4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView": 4,
|
||||||
|
"byteOffset": 0,
|
||||||
|
"componentType": 5126,
|
||||||
|
"count": 36,
|
||||||
|
"max": [
|
||||||
|
1,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"min": [
|
||||||
|
-1,
|
||||||
|
-1
|
||||||
|
],
|
||||||
|
"type": "VEC2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"asset": {
|
||||||
|
"generator": "VKTS glTF 2.0 exporter",
|
||||||
|
"version": "2.0"
|
||||||
|
},
|
||||||
|
"bufferViews": [
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteLength": 72,
|
||||||
|
"byteOffset": 0,
|
||||||
|
"target": 34963
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteLength": 432,
|
||||||
|
"byteOffset": 72,
|
||||||
|
"target": 34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteLength": 432,
|
||||||
|
"byteOffset": 504,
|
||||||
|
"target": 34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteLength": 576,
|
||||||
|
"byteOffset": 936,
|
||||||
|
"target": 34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteLength": 288,
|
||||||
|
"byteOffset": 1512,
|
||||||
|
"target": 34962
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buffers": [
|
||||||
|
{
|
||||||
|
"byteLength": 1800,
|
||||||
|
"uri": "Cube.bin"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"images": [
|
||||||
|
{
|
||||||
|
"0comment": "Use Cube_MetallicRoughness.png to reduce scene filesize",
|
||||||
|
"uri": "Cube_MetallicRoughness.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uri": "Cube_MetallicRoughness.png"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"materials": [
|
||||||
|
{
|
||||||
|
"emissiveTexture": {
|
||||||
|
"index": 0,
|
||||||
|
"extensions": {
|
||||||
|
"KHR_texture_transform": {
|
||||||
|
"offset": [
|
||||||
|
0,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"scale": [
|
||||||
|
1,
|
||||||
|
-1
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Cube",
|
||||||
|
"pbrMetallicRoughness": {
|
||||||
|
"baseColorTexture": {
|
||||||
|
"index": 0
|
||||||
|
},
|
||||||
|
"metallicRoughnessTexture": {
|
||||||
|
"index": 1,
|
||||||
|
"extensions": {
|
||||||
|
"KHR_texture_transform": {
|
||||||
|
"offset": [
|
||||||
|
0,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"rotation": 1.57079632679,
|
||||||
|
"scale": [
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meshes": [
|
||||||
|
{
|
||||||
|
"name": "Cube",
|
||||||
|
"primitives": [
|
||||||
|
{
|
||||||
|
"attributes": {
|
||||||
|
"NORMAL": 2,
|
||||||
|
"POSITION": 1,
|
||||||
|
"TANGENT": 3,
|
||||||
|
"TEXCOORD_0": 4
|
||||||
|
},
|
||||||
|
"indices": 0,
|
||||||
|
"material": 0,
|
||||||
|
"mode": 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"mesh": 0,
|
||||||
|
"name": "Cube"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"samplers": [
|
||||||
|
{}
|
||||||
|
],
|
||||||
|
"scene": 0,
|
||||||
|
"scenes": [
|
||||||
|
{
|
||||||
|
"nodes": [
|
||||||
|
0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"sampler": 0,
|
||||||
|
"source": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sampler": 0,
|
||||||
|
"source": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
BIN
models/Cube-texture-ext/Cube.bin
Normal file
BIN
models/Cube-texture-ext/Cube.bin
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
BIN
models/Cube-texture-ext/Cube_MetallicRoughness.png
Normal file
BIN
models/Cube-texture-ext/Cube_MetallicRoughness.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 319 B |
6
models/Cube-texture-ext/README.md
Normal file
6
models/Cube-texture-ext/README.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
Added KHR_texture_transform property to Cube scene.
|
||||||
|
|
||||||
|
License: Donated by Norbert Nopper for glTF testing.
|
||||||
|
|
||||||
|
https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/Cube
|
||||||
|
|
@ -279,3 +279,37 @@ TEST_CASE("parse-integer-array", "[bounds-checking]") {
|
|||||||
REQUIRE_THAT(err, Catch::Contains("not an integer type"));
|
REQUIRE_THAT(err, Catch::Contains("not an integer type"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("pbr-khr-texture-transform", "[material]") {
|
||||||
|
tinygltf::Model model;
|
||||||
|
tinygltf::TinyGLTF ctx;
|
||||||
|
std::string err;
|
||||||
|
std::string warn;
|
||||||
|
|
||||||
|
// Loading is expected to fail, but not crash.
|
||||||
|
bool ret = ctx.LoadASCIIFromFile(
|
||||||
|
&model, &err, &warn,
|
||||||
|
"../models/Cube-texture-ext/Cube-textransform.gltf");
|
||||||
|
REQUIRE(ret == true);
|
||||||
|
|
||||||
|
REQUIRE(model.materials.size() == 2);
|
||||||
|
REQUIRE(model.materials[0].emissiveTexture.extensions.count("KHR_texture_transform") == 1);
|
||||||
|
REQUIRE(model.materials[0].emissiveTexture.extensions["KHR_texture_transform"].IsObject());
|
||||||
|
|
||||||
|
tinygltf::Value::Object &texform = model.materials[0].emissiveTexture.extensions["KHR_texture_transform"].Get<tinygltf::Value::Object>();
|
||||||
|
|
||||||
|
REQUIRE(texform.count("scale"));
|
||||||
|
|
||||||
|
REQUIRE(texform["scale"].IsArray());
|
||||||
|
std::cout << "ty " << int(texform["scale"].Get(0).Type()) << "\n";
|
||||||
|
REQUIRE(texform["scale"].Get(0).IsNumberOrInt());
|
||||||
|
REQUIRE(texform["scale"].Get(1).IsNumberOrInt());
|
||||||
|
|
||||||
|
double scale[2];
|
||||||
|
scale[0] = texform["scale"].Get(0).GetAsFloat();
|
||||||
|
scale[1] = texform["scale"].Get(1).GetAsFloat();
|
||||||
|
|
||||||
|
REQUIRE(scale[0] == Approx(1.0));
|
||||||
|
REQUIRE(scale[1] == Approx(-1.0));
|
||||||
|
|
||||||
|
}
|
||||||
|
418
tiny_gltf.h
418
tiny_gltf.h
@ -26,6 +26,8 @@
|
|||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
|
|
||||||
// Version:
|
// Version:
|
||||||
|
// - v2.3.0 Modified Material representation according to glTF 2.0 schema
|
||||||
|
// (and introduced TextureInfo class)
|
||||||
// - v2.2.0 Add loading 16bit PNG support. Add Sparse accessor support(Thanks
|
// - v2.2.0 Add loading 16bit PNG support. Add Sparse accessor support(Thanks
|
||||||
// to @Ybalrid)
|
// to @Ybalrid)
|
||||||
// - v2.1.0 Add draco compression.
|
// - v2.1.0 Add draco compression.
|
||||||
@ -46,6 +48,7 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <limits>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -228,7 +231,11 @@ class Value {
|
|||||||
typedef std::vector<Value> Array;
|
typedef std::vector<Value> Array;
|
||||||
typedef std::map<std::string, Value> Object;
|
typedef std::map<std::string, Value> Object;
|
||||||
|
|
||||||
Value() : type_(NULL_TYPE) {}
|
Value()
|
||||||
|
: type_(NULL_TYPE),
|
||||||
|
int_value_(0),
|
||||||
|
number_value_(0.0),
|
||||||
|
boolean_value_(false) {}
|
||||||
|
|
||||||
explicit Value(bool b) : type_(BOOL_TYPE) { boolean_value_ = b; }
|
explicit Value(bool b) : type_(BOOL_TYPE) { boolean_value_ = b; }
|
||||||
explicit Value(int i) : type_(INT_TYPE) { int_value_ = i; }
|
explicit Value(int i) : type_(INT_TYPE) { int_value_ = i; }
|
||||||
@ -253,8 +260,14 @@ class Value {
|
|||||||
|
|
||||||
bool IsInt() const { return (type_ == INT_TYPE); }
|
bool IsInt() const { return (type_ == INT_TYPE); }
|
||||||
|
|
||||||
|
// for backward compatibility, we use `IsNumber` for floating point value
|
||||||
|
// only.
|
||||||
bool IsNumber() const { return (type_ == NUMBER_TYPE); }
|
bool IsNumber() const { return (type_ == NUMBER_TYPE); }
|
||||||
|
|
||||||
|
bool IsNumberOrInt() const {
|
||||||
|
return (type_ == INT_TYPE) || (type_ == NUMBER_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
bool IsString() const { return (type_ == STRING_TYPE); }
|
bool IsString() const { return (type_ == STRING_TYPE); }
|
||||||
|
|
||||||
bool IsBinary() const { return (type_ == BINARY_TYPE); }
|
bool IsBinary() const { return (type_ == BINARY_TYPE); }
|
||||||
@ -263,6 +276,17 @@ class Value {
|
|||||||
|
|
||||||
bool IsObject() const { return (type_ == OBJECT_TYPE); }
|
bool IsObject() const { return (type_ == OBJECT_TYPE); }
|
||||||
|
|
||||||
|
double GetAsFloat() const {
|
||||||
|
if (type_ == INT_TYPE) {
|
||||||
|
return double(int_value_);
|
||||||
|
} else if (type_ == NUMBER_TYPE) {
|
||||||
|
return number_value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(syoyo): Raise error?
|
||||||
|
return std::numeric_limits<double>::quiet_NaN();
|
||||||
|
}
|
||||||
|
|
||||||
// Accessor
|
// Accessor
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const T &Get() const;
|
const T &Get() const;
|
||||||
@ -317,15 +341,15 @@ class Value {
|
|||||||
bool operator==(const tinygltf::Value &other) const;
|
bool operator==(const tinygltf::Value &other) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int type_;
|
int type_ = NULL_TYPE;
|
||||||
|
|
||||||
int int_value_;
|
int int_value_ = 0;
|
||||||
double number_value_;
|
double number_value_ = 0.0;
|
||||||
std::string string_value_;
|
std::string string_value_;
|
||||||
std::vector<unsigned char> binary_value_;
|
std::vector<unsigned char> binary_value_;
|
||||||
Array array_value_;
|
Array array_value_;
|
||||||
Object object_value_;
|
Object object_value_;
|
||||||
bool boolean_value_;
|
bool boolean_value_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
@ -359,6 +383,8 @@ TINYGLTF_VALUE_GET(Value::Object, object_value_)
|
|||||||
/// Agregate object for representing a color
|
/// Agregate object for representing a color
|
||||||
using ColorValue = std::array<double, 4>;
|
using ColorValue = std::array<double, 4>;
|
||||||
|
|
||||||
|
// === legacy interface ====
|
||||||
|
// TODO(syoyo): Deprecate `Parameter` class.
|
||||||
struct Parameter {
|
struct Parameter {
|
||||||
bool bool_value = false;
|
bool bool_value = false;
|
||||||
bool has_number_value = false;
|
bool has_number_value = false;
|
||||||
@ -366,6 +392,7 @@ struct Parameter {
|
|||||||
std::vector<double> number_array;
|
std::vector<double> number_array;
|
||||||
std::map<std::string, double> json_double_value;
|
std::map<std::string, double> json_double_value;
|
||||||
double number_value = 0.0;
|
double number_value = 0.0;
|
||||||
|
|
||||||
// context sensitive methods. depending the type of the Parameter you are
|
// context sensitive methods. depending the type of the Parameter you are
|
||||||
// accessing, these are either valid or not
|
// accessing, these are either valid or not
|
||||||
// If this parameter represent a texture map in a material, will return the
|
// If this parameter represent a texture map in a material, will return the
|
||||||
@ -560,9 +587,9 @@ struct Texture {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct TextureInfo {
|
struct TextureInfo {
|
||||||
int index; // required
|
int index = -1; // required.
|
||||||
int texCoord; // The set index of texture's TEXCOORD attribute used for
|
int texCoord; // The set index of texture's TEXCOORD attribute used for
|
||||||
// texture coordinate mapping.
|
// texture coordinate mapping.
|
||||||
|
|
||||||
Value extras;
|
Value extras;
|
||||||
ExtensionMap extensions;
|
ExtensionMap extensions;
|
||||||
@ -572,11 +599,11 @@ struct TextureInfo {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct NormalTextureInfo {
|
struct NormalTextureInfo {
|
||||||
int index; // required
|
int index = -1; // required
|
||||||
int texCoord; // The set index of texture's TEXCOORD attribute used for
|
int texCoord; // The set index of texture's TEXCOORD attribute used for
|
||||||
// texture coordinate mapping.
|
// texture coordinate mapping.
|
||||||
double scale; // scaledNormal = normalize((<sampled normal texture value>
|
double scale; // scaledNormal = normalize((<sampled normal texture value>
|
||||||
// * 2.0 - 1.0) * vec3(<normal scale>, <normal scale>, 1.0))
|
// * 2.0 - 1.0) * vec3(<normal scale>, <normal scale>, 1.0))
|
||||||
|
|
||||||
Value extras;
|
Value extras;
|
||||||
ExtensionMap extensions;
|
ExtensionMap extensions;
|
||||||
@ -586,7 +613,7 @@ struct NormalTextureInfo {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct OcclusionTextureInfo {
|
struct OcclusionTextureInfo {
|
||||||
int index; // required
|
int index = -1; // required
|
||||||
int texCoord; // The set index of texture's TEXCOORD attribute used for
|
int texCoord; // The set index of texture's TEXCOORD attribute used for
|
||||||
// texture coordinate mapping.
|
// texture coordinate mapping.
|
||||||
double strength; // occludedColor = lerp(color, color * <sampled occlusion
|
double strength; // occludedColor = lerp(color, color * <sampled occlusion
|
||||||
@ -601,7 +628,7 @@ struct OcclusionTextureInfo {
|
|||||||
|
|
||||||
// pbrMetallicRoughness class defined in glTF 2.0 spec.
|
// pbrMetallicRoughness class defined in glTF 2.0 spec.
|
||||||
struct PbrMetallicRoughness {
|
struct PbrMetallicRoughness {
|
||||||
double baseColorFactor[4]; // default [1,1,1,1]
|
std::vector<double> baseColorFactor; // len = 4. default [1,1,1,1]
|
||||||
TextureInfo baseColorTexture;
|
TextureInfo baseColorTexture;
|
||||||
double metallicFactor; // default 1
|
double metallicFactor; // default 1
|
||||||
double roughnessFactor; // default 1
|
double roughnessFactor; // default 1
|
||||||
@ -610,12 +637,7 @@ struct PbrMetallicRoughness {
|
|||||||
Value extras;
|
Value extras;
|
||||||
ExtensionMap extensions;
|
ExtensionMap extensions;
|
||||||
|
|
||||||
PbrMetallicRoughness() : metallicFactor(1.0), roughnessFactor(1.0) {
|
PbrMetallicRoughness() : metallicFactor(1.0), roughnessFactor(1.0) {}
|
||||||
baseColorFactor[0] = 1.0;
|
|
||||||
baseColorFactor[1] = 1.0;
|
|
||||||
baseColorFactor[2] = 1.0;
|
|
||||||
baseColorFactor[3] = 1.0;
|
|
||||||
}
|
|
||||||
bool operator==(const PbrMetallicRoughness &) const;
|
bool operator==(const PbrMetallicRoughness &) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -626,9 +648,9 @@ struct Material {
|
|||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
std::vector<double> emissiveFactor; // length 3. default [0, 0, 0]
|
std::vector<double> emissiveFactor; // length 3. default [0, 0, 0]
|
||||||
std::string alphaMode; // default "OPAQUE"
|
std::string alphaMode; // default "OPAQUE"
|
||||||
double alphaCutoff; // default 0.5
|
double alphaCutoff; // default 0.5
|
||||||
bool doubleSided; // default false;
|
bool doubleSided; // default false;
|
||||||
|
|
||||||
PbrMetallicRoughness pbrMetallicRoughness;
|
PbrMetallicRoughness pbrMetallicRoughness;
|
||||||
|
|
||||||
@ -636,14 +658,15 @@ struct Material {
|
|||||||
OcclusionTextureInfo occlusionTexture;
|
OcclusionTextureInfo occlusionTexture;
|
||||||
TextureInfo emissiveTexture;
|
TextureInfo emissiveTexture;
|
||||||
|
|
||||||
// ParameterMap values;
|
// For backward compatibility
|
||||||
// ParameterMap additionalValues;
|
// TODO(syoyo): Remove `values` and `additionalValues` in the next release.
|
||||||
|
ParameterMap values;
|
||||||
|
ParameterMap additionalValues;
|
||||||
|
|
||||||
ExtensionMap extensions;
|
ExtensionMap extensions;
|
||||||
Value extras;
|
Value extras;
|
||||||
|
|
||||||
Material() : alphaMode("OPAQUE"), alphaCutoff(0.5), doubleSided(false) {
|
Material() : alphaMode("OPAQUE"), alphaCutoff(0.5), doubleSided(false) {}
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const Material &) const;
|
bool operator==(const Material &) const;
|
||||||
};
|
};
|
||||||
@ -1435,17 +1458,14 @@ bool Material::operator==(const Material &other) const {
|
|||||||
(this->normalTexture == other.normalTexture) &&
|
(this->normalTexture == other.normalTexture) &&
|
||||||
(this->occlusionTexture == other.occlusionTexture) &&
|
(this->occlusionTexture == other.occlusionTexture) &&
|
||||||
(this->emissiveTexture == other.emissiveTexture) &&
|
(this->emissiveTexture == other.emissiveTexture) &&
|
||||||
TINYGLTF_DOUBLE_EQUAL(this->emissiveFactor[0],
|
Equals(this->emissiveFactor, other.emissiveFactor) &&
|
||||||
other.emissiveFactor[0]) &&
|
|
||||||
TINYGLTF_DOUBLE_EQUAL(this->emissiveFactor[1],
|
|
||||||
other.emissiveFactor[1]) &&
|
|
||||||
TINYGLTF_DOUBLE_EQUAL(this->emissiveFactor[2],
|
|
||||||
other.emissiveFactor[2]) &&
|
|
||||||
(this->alphaMode == other.alphaMode) &&
|
(this->alphaMode == other.alphaMode) &&
|
||||||
(this->alphaCutoff == other.alphaCutoff) &&
|
(this->alphaCutoff == other.alphaCutoff) &&
|
||||||
(this->doubleSided == other.doubleSided) &&
|
(this->doubleSided == other.doubleSided) &&
|
||||||
(this->extensions == other.extensions) &&
|
(this->extensions == other.extensions) &&
|
||||||
(this->extras == other.extras) && this->name == other.name;
|
(this->extras == other.extras) && (this->values == other.values) &&
|
||||||
|
(this->additionalValues == other.additionalValues) &&
|
||||||
|
(this->name == other.name);
|
||||||
}
|
}
|
||||||
bool Mesh::operator==(const Mesh &other) const {
|
bool Mesh::operator==(const Mesh &other) const {
|
||||||
return this->extensions == other.extensions && this->extras == other.extras &&
|
return this->extensions == other.extensions && this->extras == other.extras &&
|
||||||
@ -1562,14 +1582,7 @@ bool PbrMetallicRoughness::operator==(const PbrMetallicRoughness &other) const {
|
|||||||
return this->extensions == other.extensions && this->extras == other.extras &&
|
return this->extensions == other.extensions && this->extras == other.extras &&
|
||||||
(this->baseColorTexture == other.baseColorTexture) &&
|
(this->baseColorTexture == other.baseColorTexture) &&
|
||||||
(this->metallicRoughnessTexture == other.metallicRoughnessTexture) &&
|
(this->metallicRoughnessTexture == other.metallicRoughnessTexture) &&
|
||||||
TINYGLTF_DOUBLE_EQUAL(this->baseColorFactor[0],
|
Equals(this->baseColorFactor, other.baseColorFactor) &&
|
||||||
other.baseColorFactor[0]) &&
|
|
||||||
TINYGLTF_DOUBLE_EQUAL(this->baseColorFactor[1],
|
|
||||||
other.baseColorFactor[1]) &&
|
|
||||||
TINYGLTF_DOUBLE_EQUAL(this->baseColorFactor[2],
|
|
||||||
other.baseColorFactor[2]) &&
|
|
||||||
TINYGLTF_DOUBLE_EQUAL(this->baseColorFactor[3],
|
|
||||||
other.baseColorFactor[3]) &&
|
|
||||||
TINYGLTF_DOUBLE_EQUAL(this->metallicFactor, other.metallicFactor) &&
|
TINYGLTF_DOUBLE_EQUAL(this->metallicFactor, other.metallicFactor) &&
|
||||||
TINYGLTF_DOUBLE_EQUAL(this->roughnessFactor, other.roughnessFactor);
|
TINYGLTF_DOUBLE_EQUAL(this->roughnessFactor, other.roughnessFactor);
|
||||||
}
|
}
|
||||||
@ -2999,6 +3012,65 @@ static bool ParseTexture(Texture *texture, std::string *err, const json &o,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ParseTextureInfo(TextureInfo *texinfo, std::string *err,
|
||||||
|
const json &o) {
|
||||||
|
if (texinfo == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ParseIntegerProperty(&texinfo->index, err, o, "index",
|
||||||
|
/* required */ true, "TextureInfo")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseIntegerProperty(&texinfo->texCoord, err, o, "texCoord", false);
|
||||||
|
|
||||||
|
ParseExtensionsProperty(&texinfo->extensions, err, o);
|
||||||
|
ParseExtrasProperty(&texinfo->extras, o);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ParseNormalTextureInfo(NormalTextureInfo *texinfo, std::string *err,
|
||||||
|
const json &o) {
|
||||||
|
if (texinfo == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ParseIntegerProperty(&texinfo->index, err, o, "index",
|
||||||
|
/* required */ true, "NormalTextureInfo")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseIntegerProperty(&texinfo->texCoord, err, o, "texCoord", false);
|
||||||
|
ParseNumberProperty(&texinfo->scale, err, o, "scale", false);
|
||||||
|
|
||||||
|
ParseExtensionsProperty(&texinfo->extensions, err, o);
|
||||||
|
ParseExtrasProperty(&texinfo->extras, o);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ParseOcclusionTextureInfo(OcclusionTextureInfo *texinfo,
|
||||||
|
std::string *err, const json &o) {
|
||||||
|
if (texinfo == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ParseIntegerProperty(&texinfo->index, err, o, "index",
|
||||||
|
/* required */ true, "NormalTextureInfo")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseIntegerProperty(&texinfo->texCoord, err, o, "texCoord", false);
|
||||||
|
ParseNumberProperty(&texinfo->strength, err, o, "strength", false);
|
||||||
|
|
||||||
|
ParseExtensionsProperty(&texinfo->extensions, err, o);
|
||||||
|
ParseExtrasProperty(&texinfo->extras, o);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool ParseBuffer(Buffer *buffer, std::string *err, const json &o,
|
static bool ParseBuffer(Buffer *buffer, std::string *err, const json &o,
|
||||||
FsCallbacks *fs, const std::string &basedir,
|
FsCallbacks *fs, const std::string &basedir,
|
||||||
bool is_binary = false,
|
bool is_binary = false,
|
||||||
@ -3601,23 +3673,106 @@ static bool ParseNode(Node *node, std::string *err, const json &o) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ParsePbrMetallicRoughness(PbrMetallicRoughness *pbr,
|
||||||
|
std::string *err, const json &o) {
|
||||||
|
if (pbr == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> baseColorFactor;
|
||||||
|
if (ParseNumberArrayProperty(&baseColorFactor, err, o, "baseColorFactor",
|
||||||
|
/* required */ false)) {
|
||||||
|
if (baseColorFactor.size() != 4) {
|
||||||
|
if (err) {
|
||||||
|
(*err) +=
|
||||||
|
"Array length of `baseColorFactor` parameter in "
|
||||||
|
"pbrMetallicRoughness must be 4, but got " +
|
||||||
|
std::to_string(baseColorFactor.size()) + "\n";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// fill with default values
|
||||||
|
baseColorFactor = {1.0, 1.0, 1.0, 1.0};
|
||||||
|
}
|
||||||
|
pbr->baseColorFactor = baseColorFactor;
|
||||||
|
|
||||||
|
{
|
||||||
|
json::const_iterator it = o.find("baseColorTexture");
|
||||||
|
if (it != o.end()) {
|
||||||
|
ParseTextureInfo(&pbr->baseColorTexture, err, it.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
json::const_iterator it = o.find("metallicRoughnessTexture");
|
||||||
|
if (it != o.end()) {
|
||||||
|
ParseTextureInfo(&pbr->metallicRoughnessTexture, err, it.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseNumberProperty(&pbr->metallicFactor, err, o, "metallicFactor", false);
|
||||||
|
ParseNumberProperty(&pbr->roughnessFactor, err, o, "roughnessFactor", false);
|
||||||
|
|
||||||
|
ParseExtensionsProperty(&pbr->extensions, err, o);
|
||||||
|
ParseExtrasProperty(&pbr->extras, o);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool ParseMaterial(Material *material, std::string *err, const json &o) {
|
static bool ParseMaterial(Material *material, std::string *err, const json &o) {
|
||||||
//material->values.clear();
|
ParseStringProperty(&material->name, err, o, "name", /* required */ false);
|
||||||
//material->additionalValues.clear();
|
|
||||||
material->extensions.clear();
|
ParseNumberArrayProperty(&material->emissiveFactor, err, o, "emissiveFactor",
|
||||||
|
/* required */ false);
|
||||||
|
|
||||||
|
ParseStringProperty(&material->alphaMode, err, o, "alphaMode",
|
||||||
|
/* required */ false);
|
||||||
|
ParseNumberProperty(&material->alphaCutoff, err, o, "alphaCutoff",
|
||||||
|
/* required */ false);
|
||||||
|
ParseBooleanProperty(&material->doubleSided, err, o, "doubleSided",
|
||||||
|
/* required */ false);
|
||||||
|
|
||||||
|
{
|
||||||
|
json::const_iterator it = o.find("pbrMetallicRoughness");
|
||||||
|
if (it != o.end()) {
|
||||||
|
ParsePbrMetallicRoughness(&material->pbrMetallicRoughness, err,
|
||||||
|
it.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
json::const_iterator it = o.find("normalTexture");
|
||||||
|
if (it != o.end()) {
|
||||||
|
ParseNormalTextureInfo(&material->normalTexture, err, it.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
json::const_iterator it = o.find("occlusionTexture");
|
||||||
|
if (it != o.end()) {
|
||||||
|
ParseOcclusionTextureInfo(&material->occlusionTexture, err, it.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
json::const_iterator it = o.find("emissiveTexture");
|
||||||
|
if (it != o.end()) {
|
||||||
|
ParseTextureInfo(&material->emissiveTexture, err, it.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Old code path. For backward compatibility, we still store material values
|
||||||
|
// as Parameter. This will create duplicated information for
|
||||||
|
// example(pbrMetallicRoughness), but should be neglible in terms of memory
|
||||||
|
// consumption.
|
||||||
|
// TODO(syoyo): Remove in the next major release.
|
||||||
|
material->values.clear();
|
||||||
|
material->additionalValues.clear();
|
||||||
|
|
||||||
json::const_iterator it(o.begin());
|
json::const_iterator it(o.begin());
|
||||||
json::const_iterator itEnd(o.end());
|
json::const_iterator itEnd(o.end());
|
||||||
|
|
||||||
ParseStringProperty(&material->name, err, o, "name", /* required */false);
|
|
||||||
|
|
||||||
ParseNumberArrayProperty(&material->emissiveFactor, err, o, "emissiveFactor", /* required */false);
|
|
||||||
|
|
||||||
ParseStringProperty(&material->alphaMode, err, o, "alphaMode", /* required */false);
|
|
||||||
ParseNumberProperty(&material->alphaCutoff, err, o, "alphaCutoff", /* required */false);
|
|
||||||
ParseBooleanProperty(&material->doubleSided, err, o, "doubleSided", /* required */false);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
for (; it != itEnd; it++) {
|
for (; it != itEnd; it++) {
|
||||||
if (it.key() == "pbrMetallicRoughness") {
|
if (it.key() == "pbrMetallicRoughness") {
|
||||||
if (it.value().is_object()) {
|
if (it.value().is_object()) {
|
||||||
@ -3634,8 +3789,6 @@ static bool ParseMaterial(Material *material, std::string *err, const json &o) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (it.key() == "normalTexture") {
|
|
||||||
} else if (it.key() == "occlusionTexture") {
|
|
||||||
} else if (it.key() == "extensions" || it.key() == "extras") {
|
} else if (it.key() == "extensions" || it.key() == "extras") {
|
||||||
// done later, skip, otherwise poorly parsed contents will be saved in the
|
// done later, skip, otherwise poorly parsed contents will be saved in the
|
||||||
// parametermap and serialized again later
|
// parametermap and serialized again later
|
||||||
@ -3648,8 +3801,8 @@ static bool ParseMaterial(Material *material, std::string *err, const json &o) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
material->extensions.clear();
|
||||||
ParseExtensionsProperty(&material->extensions, err, o);
|
ParseExtensionsProperty(&material->extensions, err, o);
|
||||||
ParseExtrasProperty(&(material->extras), o);
|
ParseExtrasProperty(&(material->extras), o);
|
||||||
|
|
||||||
@ -5155,10 +5308,146 @@ static void SerializeGltfImage(Image &image, json &o) {
|
|||||||
SerializeExtensionMap(image.extensions, o);
|
SerializeExtensionMap(image.extensions, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SerializeGltfMaterial(Material &material, json &o) {
|
static void SerializeGltfTextureInfo(TextureInfo &texinfo, json &o) {
|
||||||
if (material.extras.Size()) SerializeValue("extras", material.extras, o);
|
SerializeNumberProperty("index", texinfo.index, o);
|
||||||
SerializeExtensionMap(material.extensions, o);
|
|
||||||
|
|
||||||
|
if (texinfo.texCoord != 0) {
|
||||||
|
SerializeNumberProperty("texCoord", texinfo.texCoord, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texinfo.extras.Type() != NULL_TYPE) {
|
||||||
|
SerializeValue("extras", texinfo.extras, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
SerializeExtensionMap(texinfo.extensions, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SerializeGltfNormalTextureInfo(NormalTextureInfo &texinfo,
|
||||||
|
json &o) {
|
||||||
|
SerializeNumberProperty("index", texinfo.index, o);
|
||||||
|
|
||||||
|
if (texinfo.texCoord != 0) {
|
||||||
|
SerializeNumberProperty("texCoord", texinfo.texCoord, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TINYGLTF_DOUBLE_EQUAL(texinfo.scale, 0.0)) {
|
||||||
|
SerializeNumberProperty("scale", texinfo.scale, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texinfo.extras.Type() != NULL_TYPE) {
|
||||||
|
SerializeValue("extras", texinfo.extras, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
SerializeExtensionMap(texinfo.extensions, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SerializeGltfOcclusionTextureInfo(OcclusionTextureInfo &texinfo,
|
||||||
|
json &o) {
|
||||||
|
SerializeNumberProperty("index", texinfo.index, o);
|
||||||
|
|
||||||
|
if (texinfo.texCoord != 0) {
|
||||||
|
SerializeNumberProperty("texCoord", texinfo.texCoord, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TINYGLTF_DOUBLE_EQUAL(texinfo.strength, 0.0)) {
|
||||||
|
SerializeNumberProperty("strength", texinfo.strength, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texinfo.extras.Type() != NULL_TYPE) {
|
||||||
|
SerializeValue("extras", texinfo.extras, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
SerializeExtensionMap(texinfo.extensions, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SerializeGltfPbrMetallicRoughness(PbrMetallicRoughness &pbr,
|
||||||
|
json &o) {
|
||||||
|
std::vector<double> default_baseColorFactor = {1.0, 1.0, 1.0, 1.0};
|
||||||
|
if (!Equals(pbr.baseColorFactor, default_baseColorFactor)) {
|
||||||
|
SerializeNumberArrayProperty<double>("baseColorFactor", pbr.baseColorFactor,
|
||||||
|
o);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TINYGLTF_DOUBLE_EQUAL(pbr.metallicFactor, 0.0)) {
|
||||||
|
SerializeNumberProperty("metallicFactor", pbr.metallicFactor, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TINYGLTF_DOUBLE_EQUAL(pbr.roughnessFactor, 0.0)) {
|
||||||
|
SerializeNumberProperty("roughnessFactor", pbr.roughnessFactor, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pbr.baseColorTexture.index >= -1) {
|
||||||
|
json texinfo;
|
||||||
|
SerializeGltfTextureInfo(pbr.baseColorTexture, texinfo);
|
||||||
|
o["baseColorTexture"] = texinfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pbr.metallicRoughnessTexture.index >= -1) {
|
||||||
|
json texinfo;
|
||||||
|
SerializeGltfTextureInfo(pbr.metallicRoughnessTexture, texinfo);
|
||||||
|
o["metallicRoughnessTexture"] = texinfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
SerializeExtensionMap(pbr.extensions, o);
|
||||||
|
|
||||||
|
if (pbr.extras.Type() != NULL_TYPE) {
|
||||||
|
SerializeValue("extras", pbr.extras, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SerializeGltfMaterial(Material &material, json &o) {
|
||||||
|
if (material.name.size()) {
|
||||||
|
SerializeStringProperty("name", material.name, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
// QUESTION(syoyo): Write material parameters regardless of its default value?
|
||||||
|
|
||||||
|
if (!TINYGLTF_DOUBLE_EQUAL(material.alphaCutoff, 0.5)) {
|
||||||
|
SerializeNumberProperty("alphaCutoff", material.alphaCutoff, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (material.alphaMode.compare("OPAQUE") == 0) {
|
||||||
|
SerializeStringProperty("alphaMode", material.alphaMode, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TINYGLTF_DOUBLE_EQUAL(material.alphaCutoff, 0.5)) {
|
||||||
|
SerializeNumberProperty("alphaCutoff", material.alphaCutoff, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
o["doubleSided"] = json(material.doubleSided);
|
||||||
|
|
||||||
|
if (material.normalTexture.index >= -1) {
|
||||||
|
json texinfo;
|
||||||
|
SerializeGltfNormalTextureInfo(material.normalTexture, texinfo);
|
||||||
|
o["normalTexture"] = texinfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (material.occlusionTexture.index >= -1) {
|
||||||
|
json texinfo;
|
||||||
|
SerializeGltfOcclusionTextureInfo(material.occlusionTexture, texinfo);
|
||||||
|
o["occlusionTexture"] = texinfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (material.emissiveTexture.index >= -1) {
|
||||||
|
json texinfo;
|
||||||
|
SerializeGltfTextureInfo(material.emissiveTexture, texinfo);
|
||||||
|
o["emissiveTexture"] = texinfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> default_emissiveFactor = {0.0, 0.0, 0.0};
|
||||||
|
if (!Equals(material.emissiveFactor, default_emissiveFactor)) {
|
||||||
|
SerializeNumberArrayProperty<double>("emissiveFactor",
|
||||||
|
material.emissiveFactor, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
json pbrMetallicRoughness;
|
||||||
|
SerializeGltfPbrMetallicRoughness(material.pbrMetallicRoughness,
|
||||||
|
pbrMetallicRoughness);
|
||||||
|
o["pbrMetallicRoughness"] = pbrMetallicRoughness;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0 // legacy way. just for the record.
|
||||||
if (material.values.size()) {
|
if (material.values.size()) {
|
||||||
json pbrMetallicRoughness;
|
json pbrMetallicRoughness;
|
||||||
SerializeParameterMap(material.values, pbrMetallicRoughness);
|
SerializeParameterMap(material.values, pbrMetallicRoughness);
|
||||||
@ -5166,10 +5455,11 @@ static void SerializeGltfMaterial(Material &material, json &o) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SerializeParameterMap(material.additionalValues, o);
|
SerializeParameterMap(material.additionalValues, o);
|
||||||
|
#else
|
||||||
|
|
||||||
if (material.name.size()) {
|
#endif
|
||||||
SerializeStringProperty("name", material.name, o);
|
|
||||||
}
|
SerializeExtensionMap(material.extensions, o);
|
||||||
|
|
||||||
if (material.extras.Type() != NULL_TYPE) {
|
if (material.extras.Type() != NULL_TYPE) {
|
||||||
SerializeValue("extras", material.extras, o);
|
SerializeValue("extras", material.extras, o);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user