diff --git a/README.md b/README.md index 7a347f1..3d5dc79 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,7 @@ If you are looking for old, C++03 version, please use `devel-picojson` branch. * Physical based rendering with Vulkan using glTF 2.0 models https://github.com/SaschaWillems/Vulkan-glTF-PBR * GLTF loader plugin for OGRE 2.1. Support for PBR materials via HLMS/PBS https://github.com/Ybalrid/Ogre_glTF * [TinyGltfImporter](http://doc.magnum.graphics/magnum/classMagnum_1_1Trade_1_1TinyGltfImporter.html) plugin for [Magnum](https://github.com/mosra/magnum), a lightweight and modular C++11/C++14 graphics middleware for games and data visualization. +* [Diligent Engine](https://github.com/DiligentGraphics/DiligentEngine) - A modern cross-platform low-level graphics library and rendering framework * Your projects here! (Please send PR) ## TODOs diff --git a/models/BoundsChecking/invalid-buffer-index.gltf b/models/BoundsChecking/invalid-buffer-index.gltf index 88386ef..d3dd923 100644 --- a/models/BoundsChecking/invalid-buffer-index.gltf +++ b/models/BoundsChecking/invalid-buffer-index.gltf @@ -46,5 +46,8 @@ "max": [2], "min": [0] } - ] + ], + "asset": { + "version": "2.0" + } } diff --git a/models/BoundsChecking/invalid-buffer-view-index.gltf b/models/BoundsChecking/invalid-buffer-view-index.gltf index 687fe85..b43c207 100644 --- a/models/BoundsChecking/invalid-buffer-view-index.gltf +++ b/models/BoundsChecking/invalid-buffer-view-index.gltf @@ -29,5 +29,8 @@ "max": [2], "min": [0] } - ] + ], + "asset": { + "version": "2.0" + } } diff --git a/models/BoundsChecking/invalid-primitive-indices.gltf b/models/BoundsChecking/invalid-primitive-indices.gltf index 6dab589..5cde694 100644 --- a/models/BoundsChecking/invalid-primitive-indices.gltf +++ b/models/BoundsChecking/invalid-primitive-indices.gltf @@ -29,5 +29,8 @@ "max": [2], "min": [0] } - ] + ], + "asset": { + "version": "2.0" + } } diff --git a/tiny_gltf.h b/tiny_gltf.h index b49a134..4a5e2d8 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -390,9 +390,34 @@ struct Parameter { if (it != std::end(json_double_value)) { return int(it->second); } + // As per the spec, if texCoord is ommited, this parameter is 0 return 0; } + /// Return the scale of a texture if this Parameter is a normal texture map. + /// Returned value is only valid if the parameter represent a normal texture + /// from a material + double TextureScale() const { + const auto it = json_double_value.find("scale"); + if (it != std::end(json_double_value)) { + return it->second; + } + // As per the spec, if scale is ommited, this paramter is 1 + return 1; + } + + /// Return the strength of a texture if this Parameter is a an occlusion map. + /// Returned value is only valid if the parameter represent an occlusion map + /// from a material + double TextureStrength() const { + const auto it = json_double_value.find("strength"); + if (it != std::end(json_double_value)) { + return it->second; + } + // As per the spec, if strenghth is ommited, this parameter is 1 + return 1; + } + /// Material factor, like the roughness or metalness of a material /// Returned value is only valid if the parameter represent a texture from a /// material @@ -437,8 +462,8 @@ struct AnimationChannel { struct AnimationSampler { int input; // required int output; // required - std::string interpolation; // in ["LINEAR", "STEP", "CATMULLROMSPLINE", - // "CUBICSPLINE"], default "LINEAR" + std::string interpolation; // "LINEAR", "STEP","CUBICSPLINE" or user defined + // string. default "LINEAR" Value extras; AnimationSampler() : input(-1), output(-1), interpolation("LINEAR") {} @@ -708,7 +733,6 @@ struct Mesh { std::string name; std::vector primitives; std::vector weights; // weights to be applied to the Morph Targets - std::vector > targets; ExtensionMap extensions; Value extras; @@ -719,6 +743,7 @@ class Node { public: Node() : camera(-1), skin(-1), mesh(-1) {} + // TODO(syoyo): Could use `default` Node(const Node &rhs) { camera = rhs.camera; @@ -736,6 +761,9 @@ class Node { extras = rhs.extras; } ~Node() {} + + Node &operator=(const Node &rhs) = default; + bool operator==(const Node &) const; int camera; // the index of the camera referenced by this node @@ -796,7 +824,12 @@ struct Light { class Model { public: Model() {} + + Model(const Model &) = default; + Model &operator=(const Model &) = default; + ~Model() {} + bool operator==(const Model &) const; std::vector accessors; @@ -1304,8 +1337,7 @@ bool Material::operator==(const Material &other) const { } bool Mesh::operator==(const Mesh &other) const { return this->extensions == other.extensions && this->extras == other.extras && - this->name == other.name && this->primitives == other.primitives && - this->targets == other.targets && Equals(this->weights, other.weights); + this->name == other.name && this->primitives == other.primitives; } bool Model::operator==(const Model &other) const { return this->accessors == other.accessors && @@ -3097,7 +3129,7 @@ static bool ParseAccessor(Accessor *accessor, std::string *err, const json &o) { if (componentType >= TINYGLTF_COMPONENT_TYPE_BYTE && componentType <= TINYGLTF_COMPONENT_TYPE_DOUBLE) { // OK - accessor->componentType = componentType; + accessor->componentType = int(componentType); } else { std::stringstream ss; ss << "Invalid `componentType` in accessor. Got " << componentType @@ -3383,24 +3415,6 @@ static bool ParseMesh(Mesh *mesh, Model *model, std::string *err, } } - // Look for morph targets - json::const_iterator targetsObject = o.find("targets"); - if ((targetsObject != o.end()) && targetsObject.value().is_array()) { - for (json::const_iterator i = targetsObject.value().begin(); - i != targetsObject.value().end(); i++) { - std::map targetAttribues; - - const json &dict = i.value(); - json::const_iterator dictIt(dict.begin()); - json::const_iterator dictItEnd(dict.end()); - - for (; dictIt != dictItEnd; ++dictIt) { - targetAttribues[dictIt.key()] = static_cast(dictIt.value()); - } - mesh->targets.push_back(targetAttribues); - } - } - // Should probably check if has targets and if dimensions fit ParseNumberArrayProperty(&mesh->weights, err, o, "weights", false); @@ -3478,7 +3492,9 @@ static bool ParseMaterial(Material *material, std::string *err, const json &o) { } else { Parameter param; if (ParseParameterProperty(¶m, err, o, it.key(), false)) { - material->additionalValues[it.key()] = param; + // names of materials have already been parsed. Putting it in this map + // doesn't correctly reflext the glTF specification + if (it.key() != "name") material->additionalValues[it.key()] = param; } } } @@ -4848,6 +4864,10 @@ static void SerializeGltfAsset(Asset &asset, json &o) { SerializeStringProperty("generator", asset.generator, o); } + if (!asset.copyright.empty()) { + SerializeStringProperty("copyright", asset.copyright, o); + } + if (!asset.version.empty()) { SerializeStringProperty("version", asset.version, o); } @@ -4912,14 +4932,13 @@ static void SerializeGltfBufferView(BufferView &bufferView, json &o) { } static void SerializeGltfImage(Image &image, json &o) { - // if uri empty, the mimeType and bufferview should be set + // if uri empty, the mimeType and bufferview should be set if (image.uri.empty()) { - SerializeStringProperty("mimeType", image.mimeType, o); - SerializeNumberProperty("bufferView", image.bufferView, o); - } - else { - SerializeStringProperty("uri", image.uri, o); - } + SerializeStringProperty("mimeType", image.mimeType, o); + SerializeNumberProperty("bufferView", image.bufferView, o); + } else { + SerializeStringProperty("uri", image.uri, o); + } if (image.name.size()) { SerializeStringProperty("name", image.name, o); @@ -5146,6 +5165,9 @@ static void SerializeGltfTexture(Texture &texture, json &o) { if (texture.source > -1) { SerializeNumberProperty("source", texture.source, o); } + if (texture.name.size()) { + SerializeStringProperty("name", texture.name, o); + } if (texture.extras.Type() != NULL_TYPE) { SerializeValue("extras", texture.extras, o); }