Fix parsing of glTF version
authorJohn Senneker <johns@matterandform.net>
Wed, 6 Sep 2017 19:32:44 +0000 (15:32 -0400)
committerDaniel Hritzkiv <daniel.hritzkiv@gmail.com>
Mon, 11 Sep 2017 15:02:15 +0000 (11:02 -0400)
Handle version as int in gltf
Fix format specifiers in glTF version parser

code/glTF2Asset.h
code/glTF2Asset.inl
code/glTF2AssetWriter.inl
code/glTF2Exporter.cpp
code/glTF2Importer.cpp
code/glTFAsset.h
code/glTFAsset.inl
code/glTFAssetWriter.inl
code/glTFImporter.cpp

index 12cad25..1711b93 100644 (file)
@@ -1005,13 +1005,13 @@ namespace glTF2
             std::string version; //!< Specifies the target rendering API (default: "1.0.3")
         } profile; //!< Specifies the target rendering API and version, e.g., WebGL 1.0.3. (default: {})
 
-        float version; //!< The glTF format version
+        std::string version; //!< The glTF format version
 
         void Read(Document& doc);
 
         AssetMetadata()
             : premultipliedAlpha(false)
-            , version(0)
+            , version("")
         {
         }
     };
index e2d8125..bc82613 100644 (file)
@@ -985,15 +985,21 @@ inline void Scene::Read(Value& obj, Asset& r)
 
 inline void AssetMetadata::Read(Document& doc)
 {
-    // read the version, etc.
-    std::string statedVersion;
-
     if (Value* obj = FindObject(doc, "asset")) {
         ReadMember(*obj, "copyright", copyright);
         ReadMember(*obj, "generator", generator);
 
         premultipliedAlpha = MemberOrDefault(*obj, "premultipliedAlpha", false);
-        statedVersion = MemberOrDefault(*obj, "version", "0.0");
+
+        if (Value* versionString = FindString(*obj, "version")) {
+            version = versionString->GetString();
+        } else if (Value* versionNumber = FindNumber (*obj, "version")) {
+            char buf[4];
+
+            ai_snprintf(buf, 4, "%.1f", versionNumber->GetDouble());
+
+            version = buf;
+        }
 
         if (Value* profile = FindObject(*obj, "profile")) {
             ReadMember(*profile, "api",     this->profile.api);
@@ -1001,19 +1007,8 @@ inline void AssetMetadata::Read(Document& doc)
         }
     }
 
-    float statedFloatVersion = std::strtof(statedVersion.c_str(), 0);
-
-    version = std::max(statedFloatVersion, version);
-
-    if (version == 0) {
-        // if missing version, we'll assume version 2.0...
-        version = 2;
-    }
-
-    if (version != 2) {
-        char msg[128];
-        ai_snprintf(msg, 128, "GLTF: Unsupported glTF version: %.1f", version);
-        throw DeadlyImportError(msg);
+    if (version.empty() || version[0] != '2') {
+        throw DeadlyImportError("GLTF: Unsupported glTF version: " + version);
     }
 }
 
index ad68a14..1665bee 100644 (file)
@@ -652,13 +652,8 @@ namespace glTF2 {
     {
         Value asset;
         asset.SetObject();
-        {
-            char versionChar[10];
-            ai_snprintf(versionChar, sizeof(versionChar), "%.1f", mAsset.asset.version);
-            asset.AddMember("version", Value(versionChar, mAl).Move(), mAl);
-
-            asset.AddMember("generator", Value(mAsset.asset.generator, mAl).Move(), mAl);
-        }
+        asset.AddMember("version", Value(mAsset.asset.version, mAl).Move(), mAl);
+        asset.AddMember("generator", Value(mAsset.asset.generator, mAl).Move(), mAl);
         mDoc.AddMember("asset", asset, mAl);
     }
 
index 9130c75..f3e0835 100644 (file)
@@ -811,7 +811,7 @@ void glTF2Exporter::ExportScene()
 void glTF2Exporter::ExportMetadata()
 {
     AssetMetadata& asset = mAsset->asset;
-    asset.version = 2;
+    asset.version = "2.0";
 
     char buffer[256];
     ai_snprintf(buffer, 256, "Open Asset Import Library (assimp v%d.%d.%d)",
index 1ab23fd..34144b9 100644 (file)
@@ -111,7 +111,8 @@ bool glTF2Importer::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool
         glTF2::Asset asset(pIOHandler);
         try {
             asset.Load(pFile, extension == "glb");
-            return asset.asset.version >= 2;
+            std::string version = asset.asset.version;
+            return !version.empty() && version[0] == '2';
         } catch (...) {
             return false;
         }
index 30d0bc0..60107be 100644 (file)
@@ -1058,13 +1058,13 @@ namespace glTF
             std::string version; //!< Specifies the target rendering API (default: "1.0.3")
         } profile; //!< Specifies the target rendering API and version, e.g., WebGL 1.0.3. (default: {})
 
-        float version; //!< The glTF format version (should be 1.0)
+        std::string version; //!< The glTF format version (should be 1.0)
 
         void Read(Document& doc);
 
         AssetMetadata()
             : premultipliedAlpha(false)
-            , version(0)
+            , version("")
         {
         }
     };
index 32fe772..bb4bb50 100644 (file)
@@ -40,6 +40,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
 #include "StringUtils.h"
+#include <iomanip>
 
 // Header files, Assimp
 #include <assimp/DefaultLogger.hpp>
@@ -128,6 +129,12 @@ namespace {
         return (it != val.MemberEnd() && it->value.IsString()) ? &it->value : 0;
     }
 
+    inline Value* FindNumber(Value& val, const char* id)
+    {
+        Value::MemberIterator it = val.FindMember(id);
+        return (it != val.MemberEnd() && it->value.IsNumber()) ? &it->value : 0;
+    }
+
     inline Value* FindArray(Value& val, const char* id)
     {
         Value::MemberIterator it = val.FindMember(id);
@@ -1228,13 +1235,21 @@ inline void Scene::Read(Value& obj, Asset& r)
 inline void AssetMetadata::Read(Document& doc)
 {
     // read the version, etc.
-    float statedVersion = 0;
     if (Value* obj = FindObject(doc, "asset")) {
         ReadMember(*obj, "copyright", copyright);
         ReadMember(*obj, "generator", generator);
 
         premultipliedAlpha = MemberOrDefault(*obj, "premultipliedAlpha", false);
-        statedVersion = MemberOrDefault(*obj, "version", 0);
+
+        if (Value* versionString = FindString(*obj, "version")) {
+            version = versionString->GetString();
+        } else if (Value* versionNumber = FindNumber (*obj, "version")) {
+            char buf[4];
+
+            ai_snprintf(buf, 4, "%.1f", versionNumber->GetDouble());
+
+            version = buf;
+        }
 
         if (Value* profile = FindObject(*obj, "profile")) {
             ReadMember(*profile, "api",     this->profile.api);
@@ -1242,12 +1257,8 @@ inline void AssetMetadata::Read(Document& doc)
         }
     }
 
-    version = std::max(statedVersion, version);
-
-    if (version != 1) {
-        char msg[128];
-        ai_snprintf(msg, 128, "GLTF: Unsupported glTF version: %.0f", version);
-        throw DeadlyImportError(msg);
+    if (version.empty() || version[0] != '1') {
+        throw DeadlyImportError("GLTF: Unsupported glTF version: " + version);
     }
 }
 
@@ -1269,7 +1280,7 @@ inline void Asset::ReadBinaryHeader(IOStream& stream)
     }
 
     AI_SWAP4(header.version);
-    asset.version = header.version;
+    asset.version = std::to_string(header.version);
     if (header.version != 1) {
         throw DeadlyImportError("GLTF: Unsupported binary glTF version");
     }
index 166b84f..698f0ba 100644 (file)
@@ -606,13 +606,8 @@ namespace glTF {
     {
         Value asset;
         asset.SetObject();
-        {
-            char versionChar[10];
-            ai_snprintf(versionChar, sizeof(versionChar), "%.0f", mAsset.asset.version);
-            asset.AddMember("version", Value(versionChar, mAl).Move(), mAl);
-
-            asset.AddMember("generator", Value(mAsset.asset.generator, mAl).Move(), mAl);
-        }
+        asset.AddMember("version", Value(mAsset.asset.version, mAl).Move(), mAl);
+        asset.AddMember("generator", Value(mAsset.asset.generator, mAl).Move(), mAl);
         mDoc.AddMember("asset", asset, mAl);
     }
 
index 6dbeb7e..1b5c953 100644 (file)
@@ -109,7 +109,8 @@ bool glTFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool
         glTF::Asset asset(pIOHandler);
         try {
             asset.Load(pFile, extension == "glb");
-            return asset.asset.version < 2;
+            std::string version = asset.asset.version;
+            return !version.empty() && version[0] == '1';
         } catch (...) {
             return false;
         }