Serialize extension with empty object. Fixes #97
Use pretty printing JSON when serializing for the readability.
diff --git a/models/Extensions-issue97/test.gltf b/models/Extensions-issue97/test.gltf
new file mode 100644
index 0000000..c40af40
--- /dev/null
+++ b/models/Extensions-issue97/test.gltf
@@ -0,0 +1,66 @@
+
+{
+ "scenes" : [
+ {
+ "nodes" : [ 0 ]
+ }
+ ],
+
+ "nodes" : [
+ {
+ "mesh" : 0
+ }
+ ],
+
+ "meshes" : [
+ {
+ "primitives" : [ {
+ "attributes" : {
+ "POSITION" : 0
+ }
+ } ]
+ }
+ ],
+
+ "buffers" : [
+ {
+ "uri" : "data:application/octet-stream;base64,AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAA",
+ "byteLength" : 36
+ }
+ ],
+ "bufferViews" : [
+ {
+ "buffer" : 0,
+ "byteOffset" : 0,
+ "byteLength" : 36,
+ "target" : 34962
+ }
+ ],
+ "accessors" : [
+ {
+ "bufferView" : 0,
+ "byteOffset" : 0,
+ "componentType" : 5126,
+ "count" : 3,
+ "type" : "VEC3",
+ "max" : [ 1.0, 1.0, 0.0 ],
+ "min" : [ 0.0, 0.0, 0.0 ]
+ }
+ ],
+
+ "asset" : {
+ "version" : "2.0"
+ },
+
+ "materials" : [
+ { "name" : "WHITE",
+ "extensions": {
+ "VENDOR_material_some_ext" : { }
+ }
+ }
+ ],
+
+ "extensionsUsed" : [
+ "VENDOR_material_some_ext"
+ ]
+}
diff --git a/tests/tester.cc b/tests/tester.cc
index ca0ced3..bb29e18 100644
--- a/tests/tester.cc
+++ b/tests/tester.cc
@@ -41,4 +41,48 @@
REQUIRE(true == ret);
}
+TEST_CASE("extension-with-empty-object", "[issue-97]") {
+
+ tinygltf::Model model;
+ tinygltf::TinyGLTF ctx;
+ std::string err;
+ std::string warn;
+
+ bool ret = ctx.LoadASCIIFromFile(&model, &err, &warn, "../models/Extensions-issue97/test.gltf");
+ if (!err.empty()) {
+ std::cerr << err << std::endl;
+ }
+ REQUIRE(true == ret);
+
+ REQUIRE(model.extensionsUsed.size() == 1);
+ REQUIRE(model.extensionsUsed[0].compare("VENDOR_material_some_ext") == 0);
+
+ REQUIRE(model.materials.size() == 1);
+ REQUIRE(model.materials[0].extensions.size() == 1);
+ REQUIRE(model.materials[0].extensions.count("VENDOR_material_some_ext") == 1);
+
+ // TODO(syoyo): create temp directory.
+ {
+ ret = ctx.WriteGltfSceneToFile(&model, "issue-97.gltf", true, true);
+ REQUIRE(true == ret);
+
+ tinygltf::Model m;
+
+ // read back serialized glTF
+ bool ret = ctx.LoadASCIIFromFile(&m, &err, &warn, "issue-97.gltf");
+ if (!err.empty()) {
+ std::cerr << err << std::endl;
+ }
+ REQUIRE(true == ret);
+
+ REQUIRE(m.extensionsUsed.size() == 1);
+ REQUIRE(m.extensionsUsed[0].compare("VENDOR_material_some_ext") == 0);
+
+ REQUIRE(m.materials.size() == 1);
+ REQUIRE(m.materials[0].extensions.size() == 1);
+ REQUIRE(m.materials[0].extensions.count("VENDOR_material_some_ext") == 1);
+ }
+
+}
+
diff --git a/tiny_gltf.h b/tiny_gltf.h
index 8b43da0..b42020e 100644
--- a/tiny_gltf.h
+++ b/tiny_gltf.h
@@ -4115,7 +4115,17 @@
for (ExtensionMap::iterator extIt = extensions.begin();
extIt != extensions.end(); ++extIt) {
json extension_values;
- SerializeValue(extIt->first, extIt->second, extMap);
+
+ // Allow an empty object for extension(#97)
+ json ret;
+ if (ValueToJson(extIt->second, &ret)) {
+ extMap[extIt->first] = ret;
+ } else {
+ if (!(extIt->first.empty())) { // name should not be empty, but for sure
+ // create empty object so that an extension name is still included in json.
+ extMap[extIt->first] = json({});
+ }
+ }
}
o["extensions"] = extMap;
}
@@ -4760,7 +4770,8 @@
SerializeValue("extras", model->extras, output);
}
- return WriteGltfFile(filename, output.dump());
+ // pretty printing with spacing 2
+ return WriteGltfFile(filename, output.dump(2));
}
} // namespace tinygltf