Browse Source

glTF: Try to remove duplicate code.

kimkulling 5 years ago
parent
commit
7ff7a5d64e

+ 2 - 0
code/CMakeLists.txt

@@ -766,6 +766,8 @@ ADD_ASSIMP_EXPORTER( X3D
 )
 )
 
 
 ADD_ASSIMP_IMPORTER( GLTF
 ADD_ASSIMP_IMPORTER( GLTF
+  glTF/glTFCommon.h
+  glTF/glTFCommon.cpp
   glTF/glTFAsset.h
   glTF/glTFAsset.h
   glTF/glTFAsset.inl
   glTF/glTFAsset.inl
   glTF/glTFAssetWriter.h
   glTF/glTFAssetWriter.h

+ 1 - 1
code/Common/BaseImporter.cpp

@@ -85,7 +85,7 @@ void BaseImporter::UpdateImporterScale( Importer* pImp )
     double activeScale = importerScale * fileScale;
     double activeScale = importerScale * fileScale;
 
 
     // Set active scaling
     // Set active scaling
-    pImp->SetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, activeScale);
+    pImp->SetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, static_cast<float>( activeScale) );
 
 
     ASSIMP_LOG_DEBUG_F("UpdateImporterScale scale set: %f", activeScale );
     ASSIMP_LOG_DEBUG_F("UpdateImporterScale scale set: %f", activeScale );
 }
 }

+ 8 - 61
code/glTF/glTFAsset.h

@@ -92,38 +92,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #   endif
 #   endif
 #endif
 #endif
 
 
+#include "glTF/glTFCommon.h"
+
 namespace glTF
 namespace glTF
 {
 {
-#ifdef ASSIMP_API
-    using Assimp::IOStream;
-    using Assimp::IOSystem;
-    using std::shared_ptr;
-#else
-    using std::shared_ptr;
-
-    typedef std::runtime_error DeadlyImportError;
-    typedef std::runtime_error DeadlyExportError;
-
-    enum aiOrigin { aiOrigin_SET = 0, aiOrigin_CUR = 1, aiOrigin_END = 2 };
-    class IOSystem;
-    class IOStream
-    {
-        FILE* f;
-    public:
-        IOStream(FILE* file) : f(file) {}
-        ~IOStream() { fclose(f); f = 0; }
-
-        size_t Read(void* b, size_t sz, size_t n) { return fread(b, sz, n, f); }
-        size_t Write(const void* b, size_t sz, size_t n) { return fwrite(b, sz, n, f); }
-        int    Seek(size_t off, aiOrigin orig) { return fseek(f, off, int(orig)); }
-        size_t Tell() const { return ftell(f); }
-
-        size_t FileSize() {
-            long p = Tell(), len = (Seek(0, aiOrigin_END), Tell());
-            return size_t((Seek(p, aiOrigin_SET), len));
-        }
-    };
-#endif
+    using glTFCommon::shared_ptr;
+    using glTFCommon::IOSystem;
+    using glTFCommon::IOStream;
 
 
     using rapidjson::Value;
     using rapidjson::Value;
     using rapidjson::Document;
     using rapidjson::Document;
@@ -136,37 +111,9 @@ namespace glTF
     struct Light;
     struct Light;
     struct Skin;
     struct Skin;
 
 
-
-    // Vec/matrix types, as raw float arrays
-    typedef float (vec3)[3];
-    typedef float (vec4)[4];
-    typedef float (mat4)[16];
-
-
-    namespace Util
-    {
-        void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out);
-
-        size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
-
-        inline size_t DecodeBase64(const char* in, uint8_t*& out)
-        {
-            return DecodeBase64(in, strlen(in), out);
-        }
-
-        struct DataURI
-        {
-            const char* mediaType;
-            const char* charset;
-            bool base64;
-            const char* data;
-            size_t dataLength;
-        };
-
-        //! Check if a uri is a data URI
-        inline bool ParseDataURI(const char* uri, size_t uriLen, DataURI& out);
-    }
-
+    using glTFCommon::vec3;
+    using glTFCommon::vec4;
+    using glTFCommon::mat4;
 
 
     //! Magic number for GLB files
     //! Magic number for GLB files
     #define AI_GLB_MAGIC_NUMBER "glTF"
     #define AI_GLB_MAGIC_NUMBER "glTF"

+ 4 - 190
code/glTF/glTFAsset.inl

@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
 
 
 Copyright (c) 2006-2019, assimp team
 Copyright (c) 2006-2019, assimp team
 
 
-
 All rights reserved.
 All rights reserved.
 
 
 Redistribution and use of this software in source and binary forms,
 Redistribution and use of this software in source and binary forms,
@@ -52,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #endif
 #endif
 
 
 using namespace Assimp;
 using namespace Assimp;
+using namespace glTFCommon;
 
 
 namespace glTF {
 namespace glTF {
 
 
@@ -301,7 +301,7 @@ inline void Buffer::Read(Value& obj, Asset& r)
 
 
     const char* uri = it->GetString();
     const char* uri = it->GetString();
 
 
-    Util::DataURI dataURI;
+    glTFCommon::Util::DataURI dataURI;
     if (ParseDataURI(uri, it->GetStringLength(), dataURI)) {
     if (ParseDataURI(uri, it->GetStringLength(), dataURI)) {
         if (dataURI.base64) {
         if (dataURI.base64) {
             uint8_t* data = 0;
             uint8_t* data = 0;
@@ -654,12 +654,12 @@ inline void Image::Read(Value& obj, Asset& r)
         if (Value* uri = FindString(obj, "uri")) {
         if (Value* uri = FindString(obj, "uri")) {
             const char* uristr = uri->GetString();
             const char* uristr = uri->GetString();
 
 
-            Util::DataURI dataURI;
+            glTFCommon::Util::DataURI dataURI;
             if (ParseDataURI(uristr, uri->GetStringLength(), dataURI)) {
             if (ParseDataURI(uristr, uri->GetStringLength(), dataURI)) {
                 mimeType = dataURI.mediaType;
                 mimeType = dataURI.mediaType;
                 if (dataURI.base64) {
                 if (dataURI.base64) {
                     uint8_t *ptr = nullptr;
                     uint8_t *ptr = nullptr;
-                    mDataLength = Util::DecodeBase64(dataURI.data, dataURI.dataLength, ptr);
+                    mDataLength = glTFCommon::Util::DecodeBase64(dataURI.data, dataURI.dataLength, ptr);
                     mData.reset(ptr);
                     mData.reset(ptr);
                 }
                 }
             }
             }
@@ -1474,190 +1474,4 @@ inline std::string Asset::FindUniqueID(const std::string& str, const char* suffi
     return id;
     return id;
 }
 }
 
 
-namespace Util {
-
-    inline
-    bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out) {
-        if ( NULL == const_uri ) {
-            return false;
-        }
-
-        if (const_uri[0] != 0x10) { // we already parsed this uri?
-            if (strncmp(const_uri, "data:", 5) != 0) // not a data uri?
-                return false;
-        }
-
-        // set defaults
-        out.mediaType = "text/plain";
-        out.charset = "US-ASCII";
-        out.base64 = false;
-
-        char* uri = const_cast<char*>(const_uri);
-        if (uri[0] != 0x10) {
-            uri[0] = 0x10;
-            uri[1] = uri[2] = uri[3] = uri[4] = 0;
-
-            size_t i = 5, j;
-            if (uri[i] != ';' && uri[i] != ',') { // has media type?
-                uri[1] = char(i);
-                for (; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
-                    // nothing to do!
-                }
-            }
-            while (uri[i] == ';' && i < uriLen) {
-                uri[i++] = '\0';
-                for (j = i; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
-                    // nothing to do!
-                }
-
-                if ( strncmp( uri + j, "charset=", 8 ) == 0 ) {
-                    uri[2] = char(j + 8);
-                } else if ( strncmp( uri + j, "base64", 6 ) == 0 ) {
-                    uri[3] = char(j);
-                }
-            }
-            if (i < uriLen) {
-                uri[i++] = '\0';
-                uri[4] = char(i);
-            } else {
-                uri[1] = uri[2] = uri[3] = 0;
-                uri[4] = 5;
-            }
-        }
-
-        if ( uri[ 1 ] != 0 ) {
-            out.mediaType = uri + uri[ 1 ];
-        }
-        if ( uri[ 2 ] != 0 ) {
-            out.charset = uri + uri[ 2 ];
-        }
-        if ( uri[ 3 ] != 0 ) {
-            out.base64 = true;
-        }
-        out.data = uri + uri[4];
-        out.dataLength = (uri + uriLen) - out.data;
-
-        return true;
-    }
-
-    template<bool B>
-    struct DATA
-    {
-        static const uint8_t tableDecodeBase64[128];
-    };
-
-    template<bool B>
-    const uint8_t DATA<B>::tableDecodeBase64[128] = {
-         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 62,  0,  0,  0, 63,
-        52, 53, 54, 55, 56, 57, 58, 59, 60, 61,  0,  0,  0, 64,  0,  0,
-         0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
-        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,  0,  0,  0,  0,  0,
-         0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
-        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,  0,  0,  0,  0,  0
-    };
-
-    inline char EncodeCharBase64(uint8_t b)
-    {
-        return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="[size_t(b)];
-    }
-
-    inline uint8_t DecodeCharBase64(char c)
-    {
-        return DATA<true>::tableDecodeBase64[size_t(c)]; // TODO faster with lookup table or ifs?
-        /*if (c >= 'A' && c <= 'Z') return c - 'A';
-        if (c >= 'a' && c <= 'z') return c - 'a' + 26;
-        if (c >= '0' && c <= '9') return c - '0' + 52;
-        if (c == '+') return 62;
-        if (c == '/') return 63;
-        return 64; // '-' */
-    }
-
-    inline size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out)
-    {
-        ai_assert(inLength % 4 == 0);
-
-        if (inLength < 4) {
-            out = 0;
-            return 0;
-        }
-
-        int nEquals = int(in[inLength - 1] == '=') +
-                      int(in[inLength - 2] == '=');
-
-        size_t outLength = (inLength * 3) / 4 - nEquals;
-        out = new uint8_t[outLength];
-        memset(out, 0, outLength);
-
-        size_t i, j = 0;
-
-        for (i = 0; i + 4 < inLength; i += 4) {
-            uint8_t b0 = DecodeCharBase64(in[i]);
-            uint8_t b1 = DecodeCharBase64(in[i + 1]);
-            uint8_t b2 = DecodeCharBase64(in[i + 2]);
-            uint8_t b3 = DecodeCharBase64(in[i + 3]);
-
-            out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
-            out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
-            out[j++] = (uint8_t)((b2 << 6) | b3);
-        }
-
-        {
-            uint8_t b0 = DecodeCharBase64(in[i]);
-            uint8_t b1 = DecodeCharBase64(in[i + 1]);
-            uint8_t b2 = DecodeCharBase64(in[i + 2]);
-            uint8_t b3 = DecodeCharBase64(in[i + 3]);
-
-            out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
-            if (b2 < 64) out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
-            if (b3 < 64) out[j++] = (uint8_t)((b2 << 6) | b3);
-        }
-
-        return outLength;
-    }
-
-
-
-    inline void EncodeBase64(
-        const uint8_t* in, size_t inLength,
-        std::string& out)
-    {
-        size_t outLength = ((inLength + 2) / 3) * 4;
-
-        size_t j = out.size();
-        out.resize(j + outLength);
-
-        for (size_t i = 0; i <  inLength; i += 3) {
-            uint8_t b = (in[i] & 0xFC) >> 2;
-            out[j++] = EncodeCharBase64(b);
-
-            b = (in[i] & 0x03) << 4;
-            if (i + 1 < inLength) {
-                b |= (in[i + 1] & 0xF0) >> 4;
-                out[j++] = EncodeCharBase64(b);
-
-                b = (in[i + 1] & 0x0F) << 2;
-                if (i + 2 < inLength) {
-                    b |= (in[i + 2] & 0xC0) >> 6;
-                    out[j++] = EncodeCharBase64(b);
-
-                    b = in[i + 2] & 0x3F;
-                    out[j++] = EncodeCharBase64(b);
-                }
-                else {
-                    out[j++] = EncodeCharBase64(b);
-                    out[j++] = '=';
-                }
-            }
-            else {
-                out[j++] = EncodeCharBase64(b);
-                out[j++] = '=';
-                out[j++] = '=';
-            }
-        }
-    }
-
-}
-
 } // ns glTF
 } // ns glTF

+ 1 - 1
code/glTF/glTFAssetWriter.inl

@@ -215,7 +215,7 @@ namespace glTF {
         else if (img.HasData()) {
         else if (img.HasData()) {
             uri = "data:" + (img.mimeType.empty() ? "application/octet-stream" : img.mimeType);
             uri = "data:" + (img.mimeType.empty() ? "application/octet-stream" : img.mimeType);
             uri += ";base64,";
             uri += ";base64,";
-            Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri);
+            glTFCommon::Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri);
         }
         }
         else {
         else {
             uri = img.uri;
             uri = img.uri;

+ 193 - 0
code/glTF/glTFCommon.cpp

@@ -0,0 +1,193 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2019, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+#include "glTF/glTFCommon.h"
+
+namespace glTFCommon {
+
+using namespace glTFCommon::Util;
+
+namespace Util {
+
+size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out) {
+    ai_assert(inLength % 4 == 0);
+
+    if (inLength < 4) {
+        out = 0;
+        return 0;
+    }
+
+    int nEquals = int(in[inLength - 1] == '=') +
+        int(in[inLength - 2] == '=');
+
+    size_t outLength = (inLength * 3) / 4 - nEquals;
+    out = new uint8_t[outLength];
+    memset(out, 0, outLength);
+
+    size_t i, j = 0;
+
+    for (i = 0; i + 4 < inLength; i += 4) {
+        uint8_t b0 = DecodeCharBase64(in[i]);
+        uint8_t b1 = DecodeCharBase64(in[i + 1]);
+        uint8_t b2 = DecodeCharBase64(in[i + 2]);
+        uint8_t b3 = DecodeCharBase64(in[i + 3]);
+
+        out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
+        out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
+        out[j++] = (uint8_t)((b2 << 6) | b3);
+    }
+
+    {
+        uint8_t b0 = DecodeCharBase64(in[i]);
+        uint8_t b1 = DecodeCharBase64(in[i + 1]);
+        uint8_t b2 = DecodeCharBase64(in[i + 2]);
+        uint8_t b3 = DecodeCharBase64(in[i + 3]);
+
+        out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
+        if (b2 < 64) out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
+        if (b3 < 64) out[j++] = (uint8_t)((b2 << 6) | b3);
+    }
+
+    return outLength;
+}
+
+void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out) {
+    size_t outLength = ((inLength + 2) / 3) * 4;
+
+    size_t j = out.size();
+    out.resize(j + outLength);
+
+    for (size_t i = 0; i < inLength; i += 3) {
+        uint8_t b = (in[i] & 0xFC) >> 2;
+        out[j++] = EncodeCharBase64(b);
+
+        b = (in[i] & 0x03) << 4;
+        if (i + 1 < inLength) {
+            b |= (in[i + 1] & 0xF0) >> 4;
+            out[j++] = EncodeCharBase64(b);
+
+            b = (in[i + 1] & 0x0F) << 2;
+            if (i + 2 < inLength) {
+                b |= (in[i + 2] & 0xC0) >> 6;
+                out[j++] = EncodeCharBase64(b);
+
+                b = in[i + 2] & 0x3F;
+                out[j++] = EncodeCharBase64(b);
+            }
+            else {
+                out[j++] = EncodeCharBase64(b);
+                out[j++] = '=';
+            }
+        }
+        else {
+            out[j++] = EncodeCharBase64(b);
+            out[j++] = '=';
+            out[j++] = '=';
+        }
+    }
+}
+
+bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out) {
+    if (nullptr == const_uri) {
+        return false;
+    }
+
+    if (const_uri[0] != 0x10) { // we already parsed this uri?
+        if (strncmp(const_uri, "data:", 5) != 0) // not a data uri?
+            return false;
+    }
+
+    // set defaults
+    out.mediaType = "text/plain";
+    out.charset = "US-ASCII";
+    out.base64 = false;
+
+    char* uri = const_cast<char*>(const_uri);
+    if (uri[0] != 0x10) {
+        uri[0] = 0x10;
+        uri[1] = uri[2] = uri[3] = uri[4] = 0;
+
+        size_t i = 5, j;
+        if (uri[i] != ';' && uri[i] != ',') { // has media type?
+            uri[1] = char(i);
+            for (; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
+                // nothing to do!
+            }
+        }
+        while (uri[i] == ';' && i < uriLen) {
+            uri[i++] = '\0';
+            for (j = i; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
+                // nothing to do!
+            }
+
+            if (strncmp(uri + j, "charset=", 8) == 0) {
+                uri[2] = char(j + 8);
+            }
+            else if (strncmp(uri + j, "base64", 6) == 0) {
+                uri[3] = char(j);
+            }
+        }
+        if (i < uriLen) {
+            uri[i++] = '\0';
+            uri[4] = char(i);
+        }
+        else {
+            uri[1] = uri[2] = uri[3] = 0;
+            uri[4] = 5;
+        }
+    }
+
+    if (uri[1] != 0) {
+        out.mediaType = uri + uri[1];
+    }
+    if (uri[2] != 0) {
+        out.charset = uri + uri[2];
+    }
+    if (uri[3] != 0) {
+        out.base64 = true;
+    }
+    out.data = uri + uri[4];
+    out.dataLength = (uri + uriLen) - out.data;
+
+    return true;
+}
+
+}
+}

+ 241 - 0
code/glTF/glTFCommon.h

@@ -0,0 +1,241 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2019, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+#ifndef AI_GLFTCOMMON_H_INC
+#define AI_GLFTCOMMON_H_INC
+
+#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
+
+#include <assimp/Exceptional.h>
+
+#include <map>
+#include <string>
+#include <list>
+#include <vector>
+#include <algorithm>
+#include <stdexcept>
+
+#define RAPIDJSON_HAS_STDSTRING 1
+#include <rapidjson/rapidjson.h>
+#include <rapidjson/document.h>
+#include <rapidjson/error/en.h>
+
+#ifdef ASSIMP_API
+#   include <memory>
+#   include <assimp/DefaultIOSystem.h>
+#   include <assimp/ByteSwapper.h>
+#else
+#   include <memory>
+#   define AI_SWAP4(p)
+#   define ai_assert
+#endif
+
+
+#if _MSC_VER > 1500 || (defined __GNUC___)
+#       define ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
+#   else
+#       define gltf_unordered_map map
+#endif
+
+#ifdef ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
+#   include <unordered_map>
+#   if _MSC_VER > 1600
+#       define gltf_unordered_map unordered_map
+#   else
+#       define gltf_unordered_map tr1::unordered_map
+#   endif
+#endif
+
+namespace glTFCommon {
+
+#ifdef ASSIMP_API
+    using Assimp::IOStream;
+    using Assimp::IOSystem;
+    using std::shared_ptr;
+#else
+    using std::shared_ptr;
+
+    typedef std::runtime_error DeadlyImportError;
+    typedef std::runtime_error DeadlyExportError;
+
+    enum aiOrigin {
+        aiOrigin_SET = 0,
+        aiOrigin_CUR = 1,
+        aiOrigin_END = 2
+    };
+
+    class IOSystem;
+
+    class IOStream {
+    public:
+        IOStream(FILE* file) : f(file) {}
+        ~IOStream() { fclose(f); f = 0; }
+
+        size_t Read(void* b, size_t sz, size_t n) { return fread(b, sz, n, f); }
+        size_t Write(const void* b, size_t sz, size_t n) { return fwrite(b, sz, n, f); }
+        int    Seek(size_t off, aiOrigin orig) { return fseek(f, off, int(orig)); }
+        size_t Tell() const { return ftell(f); }
+
+        size_t FileSize() {
+            long p = Tell(), len = (Seek(0, aiOrigin_END), Tell());
+            return size_t((Seek(p, aiOrigin_SET), len));
+        }
+
+    private:
+        FILE* f;
+    };
+#endif
+
+    // Vec/matrix types, as raw float arrays
+    typedef float(vec3)[3];
+    typedef float(vec4)[4];
+    typedef float(mat4)[16];
+
+    static void CopyValue(const glTFCommon::vec3& v, aiColor4D& out) {
+        out.r = v[0];
+        out.g = v[1];
+        out.b = v[2];
+        out.a = 1.0;
+    }
+
+    static void CopyValue(const glTFCommon::vec4& v, aiColor4D& out) {
+        out.r = v[0];
+        out.g = v[1];
+        out.b = v[2];
+        out.a = v[3];
+    }
+
+    static void CopyValue(const glTFCommon::vec4& v, aiColor3D& out) {
+        out.r = v[0];
+        out.g = v[1];
+        out.b = v[2];
+    }
+
+    static void CopyValue(const glTFCommon::vec3& v, aiColor3D& out) {
+        out.r = v[0];
+        out.g = v[1];
+        out.b = v[2];
+    }
+
+    static void CopyValue(const glTFCommon::vec3& v, aiVector3D& out) {
+        out.x = v[0];
+        out.y = v[1];
+        out.z = v[2];
+    }
+
+    static void CopyValue(const glTFCommon::vec4& v, aiQuaternion& out) {
+        out.x = v[0];
+        out.y = v[1];
+        out.z = v[2];
+        out.w = v[3];
+    }
+
+    static void CopyValue(const glTFCommon::mat4& v, aiMatrix4x4& o) {
+        o.a1 = v[0]; o.b1 = v[1]; o.c1 = v[2]; o.d1 = v[3];
+        o.a2 = v[4]; o.b2 = v[5]; o.c2 = v[6]; o.d2 = v[7];
+        o.a3 = v[8]; o.b3 = v[9]; o.c3 = v[10]; o.d3 = v[11];
+        o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15];
+    }
+
+    namespace Util {
+
+        void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out);
+
+        size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
+
+        inline
+            size_t DecodeBase64(const char* in, uint8_t*& out) {
+            return DecodeBase64(in, strlen(in), out);
+        }
+
+        struct DataURI {
+            const char* mediaType;
+            const char* charset;
+            bool base64;
+            const char* data;
+            size_t dataLength;
+        };
+
+        //! Check if a uri is a data URI
+        bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out);
+
+        template<bool B>
+        struct DATA {
+            static const uint8_t tableDecodeBase64[128];
+        };
+
+        template<bool B>
+        const uint8_t DATA<B>::tableDecodeBase64[128] = {
+                0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+                0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+                0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 62,  0,  0,  0, 63,
+            52, 53, 54, 55, 56, 57, 58, 59, 60, 61,  0,  0,  0, 64,  0,  0,
+                0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
+            15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,  0,  0,  0,  0,  0,
+                0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+            41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,  0,  0,  0,  0,  0
+        };
+
+        inline
+            char EncodeCharBase64(uint8_t b) {
+            return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="[size_t(b)];
+        }
+
+        inline
+            uint8_t DecodeCharBase64(char c) {
+            return DATA<true>::tableDecodeBase64[size_t(c)]; // TODO faster with lookup table or ifs?
+            /*if (c >= 'A' && c <= 'Z') return c - 'A';
+            if (c >= 'a' && c <= 'z') return c - 'a' + 26;
+            if (c >= '0' && c <= '9') return c - '0' + 52;
+            if (c == '+') return 62;
+            if (c == '/') return 63;
+            return 64; // '-' */
+        }
+
+        size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
+
+        void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out);
+    }
+
+}
+
+#endif  // ASSIMP_BUILD_NO_GLTF_IMPORTER
+
+#endif // AI_GLFTCOMMON_H_INC

+ 0 - 33
code/glTF/glTFImporter.cpp

@@ -115,39 +115,6 @@ bool glTFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool
     return false;
     return false;
 }
 }
 
 
-static void CopyValue(const glTF::vec4& v, aiColor4D& out) {
-    out.r = v[0];
-    out.g = v[1];
-    out.b = v[2];
-    out.a = v[3];
-}
-
-static void CopyValue(const glTF::vec4& v, aiColor3D& out) {
-    out.r = v[0];
-    out.g = v[1];
-    out.b = v[2];
-}
-
-static void CopyValue(const glTF::vec3& v, aiVector3D& out) {
-    out.x = v[0];
-    out.y = v[1];
-    out.z = v[2];
-}
-
-static void CopyValue(const glTF::vec4& v, aiQuaternion& out) {
-    out.x = v[0];
-    out.y = v[1];
-    out.z = v[2];
-    out.w = v[3];
-}
-
-static void CopyValue(const glTF::mat4& v, aiMatrix4x4& o) {
-    o.a1 = v[ 0]; o.b1 = v[ 1]; o.c1 = v[ 2]; o.d1 = v[ 3];
-    o.a2 = v[ 4]; o.b2 = v[ 5]; o.c2 = v[ 6]; o.d2 = v[ 7];
-    o.a3 = v[ 8]; o.b3 = v[ 9]; o.c3 = v[10]; o.d3 = v[11];
-    o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15];
-}
-
 inline
 inline
 void SetMaterialColorProperty(std::vector<int>& embeddedTexIdxs, Asset& /*r*/, glTF::TexProperty prop, aiMaterial* mat,
 void SetMaterialColorProperty(std::vector<int>& embeddedTexIdxs, Asset& /*r*/, glTF::TexProperty prop, aiMaterial* mat,
         aiTextureType texType, const char* pKey, unsigned int type, unsigned int idx) {
         aiTextureType texType, const char* pKey, unsigned int type, unsigned int idx) {

+ 9 - 60
code/glTF2/glTF2Asset.h

@@ -95,38 +95,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 #include <assimp/StringUtils.h>
 #include <assimp/StringUtils.h>
 
 
+#include "glTF/glTFCommon.h"
+
 namespace glTF2
 namespace glTF2
 {
 {
-#ifdef ASSIMP_API
-    using Assimp::IOStream;
-    using Assimp::IOSystem;
-    using std::shared_ptr;
-#else
-    using std::shared_ptr;
-
-    typedef std::runtime_error DeadlyImportError;
-    typedef std::runtime_error DeadlyExportError;
-
-    enum aiOrigin { aiOrigin_SET = 0, aiOrigin_CUR = 1, aiOrigin_END = 2 };
-    class IOSystem;
-    class IOStream
-    {
-        FILE* f;
-    public:
-        IOStream(FILE* file) : f(file) {}
-        ~IOStream() { fclose(f); f = 0; }
-
-        size_t Read(void* b, size_t sz, size_t n) { return fread(b, sz, n, f); }
-        size_t Write(const void* b, size_t sz, size_t n) { return fwrite(b, sz, n, f); }
-        int    Seek(size_t off, aiOrigin orig) { return fseek(f, off, int(orig)); }
-        size_t Tell() const { return ftell(f); }
-
-        size_t FileSize() {
-            long p = Tell(), len = (Seek(0, aiOrigin_END), Tell());
-            return size_t((Seek(p, aiOrigin_SET), len));
-        }
-    };
-#endif
+    using glTFCommon::shared_ptr;
+    using glTFCommon::IOSystem;
+    using glTFCommon::IOStream;
 
 
     using rapidjson::Value;
     using rapidjson::Value;
     using rapidjson::Document;
     using rapidjson::Document;
@@ -138,35 +113,9 @@ namespace glTF2
     struct Texture;
     struct Texture;
     struct Skin;
     struct Skin;
 
 
-    // Vec/matrix types, as raw float arrays
-    typedef float (vec3)[3];
-    typedef float (vec4)[4];
-    typedef float (mat4)[16];
-
-    namespace Util
-    {
-        void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out);
-
-        size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
-
-        inline size_t DecodeBase64(const char* in, uint8_t*& out)
-        {
-            return DecodeBase64(in, strlen(in), out);
-        }
-
-        struct DataURI
-        {
-            const char* mediaType;
-            const char* charset;
-            bool base64;
-            const char* data;
-            size_t dataLength;
-        };
-
-        //! Check if a uri is a data URI
-        inline bool ParseDataURI(const char* uri, size_t uriLen, DataURI& out);
-    }
-
+    using glTFCommon::vec3;
+    using glTFCommon::vec4;
+    using glTFCommon::mat4;
 
 
     //! Magic number for GLB files
     //! Magic number for GLB files
 	#define AI_GLB_MAGIC_NUMBER "glTF"
 	#define AI_GLB_MAGIC_NUMBER "glTF"
@@ -552,7 +501,7 @@ namespace glTF2
 		/// but in real life you'll get:
 		/// but in real life you'll get:
 		/// "accessor_0" : { byteOffset: 0, byteLength: 4}, "accessor_1" : { byteOffset: 2, byteLength: 4}
 		/// "accessor_0" : { byteOffset: 0, byteLength: 4}, "accessor_1" : { byteOffset: 2, byteLength: 4}
 		/// Yes, accessor of next mesh has offset and length which mean: current mesh data is decoded, all other data is encoded.
 		/// Yes, accessor of next mesh has offset and length which mean: current mesh data is decoded, all other data is encoded.
-		/// And when before you start to read data of current mesh (with encoded data ofcourse) you must decode region of "bufferView", after read finished
+		/// And when before you start to read data of current mesh (with encoded data of course) you must decode region of "bufferView", after read finished
 		/// delete encoding mark. And after that you can repeat process: decode data of mesh, read, delete decoded data.
 		/// delete encoding mark. And after that you can repeat process: decode data of mesh, read, delete decoded data.
 		///
 		///
 		/// Remark. Encoding all data at once is good in world with computers which do not has RAM limitation. So, you must use step by step encoding in
 		/// Remark. Encoding all data at once is good in world with computers which do not has RAM limitation. So, you must use step by step encoding in

+ 4 - 192
code/glTF2/glTF2Asset.inl

@@ -282,9 +282,7 @@ Ref<T> LazyDict<T>::Retrieve(unsigned int i)
 template<class T>
 template<class T>
 Ref<T> LazyDict<T>::Get(unsigned int i)
 Ref<T> LazyDict<T>::Get(unsigned int i)
 {
 {
-
     return Ref<T>(mObjs, i);
     return Ref<T>(mObjs, i);
-
 }
 }
 
 
 template<class T>
 template<class T>
@@ -361,11 +359,11 @@ inline void Buffer::Read(Value& obj, Asset& r)
 
 
     const char* uri = it->GetString();
     const char* uri = it->GetString();
 
 
-    Util::DataURI dataURI;
+    glTFCommon::Util::DataURI dataURI;
     if (ParseDataURI(uri, it->GetStringLength(), dataURI)) {
     if (ParseDataURI(uri, it->GetStringLength(), dataURI)) {
         if (dataURI.base64) {
         if (dataURI.base64) {
             uint8_t* data = 0;
             uint8_t* data = 0;
-            this->byteLength = Util::DecodeBase64(dataURI.data, dataURI.dataLength, data);
+            this->byteLength = glTFCommon::Util::DecodeBase64(dataURI.data, dataURI.dataLength, data);
             this->mData.reset(data, std::default_delete<uint8_t[]>());
             this->mData.reset(data, std::default_delete<uint8_t[]>());
 
 
             if (statedLength > 0 && this->byteLength != statedLength) {
             if (statedLength > 0 && this->byteLength != statedLength) {
@@ -717,12 +715,12 @@ inline void Image::Read(Value& obj, Asset& r)
         if (Value* uri = FindString(obj, "uri")) {
         if (Value* uri = FindString(obj, "uri")) {
             const char* uristr = uri->GetString();
             const char* uristr = uri->GetString();
 
 
-            Util::DataURI dataURI;
+            glTFCommon::Util::DataURI dataURI;
             if (ParseDataURI(uristr, uri->GetStringLength(), dataURI)) {
             if (ParseDataURI(uristr, uri->GetStringLength(), dataURI)) {
                 mimeType = dataURI.mediaType;
                 mimeType = dataURI.mediaType;
                 if (dataURI.base64) {
                 if (dataURI.base64) {
                     uint8_t *ptr = nullptr;
                     uint8_t *ptr = nullptr;
-                    mDataLength = Util::DecodeBase64(dataURI.data, dataURI.dataLength, ptr);
+                    mDataLength = glTFCommon::Util::DecodeBase64(dataURI.data, dataURI.dataLength, ptr);
                     mData.reset(ptr);
                     mData.reset(ptr);
                 }
                 }
             }
             }
@@ -1515,190 +1513,4 @@ inline std::string Asset::FindUniqueID(const std::string& str, const char* suffi
     return id;
     return id;
 }
 }
 
 
-namespace Util {
-
-    inline
-    bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out) {
-        if ( NULL == const_uri ) {
-            return false;
-        }
-
-        if (const_uri[0] != 0x10) { // we already parsed this uri?
-            if (strncmp(const_uri, "data:", 5) != 0) // not a data uri?
-                return false;
-        }
-
-        // set defaults
-        out.mediaType = "text/plain";
-        out.charset = "US-ASCII";
-        out.base64 = false;
-
-        char* uri = const_cast<char*>(const_uri);
-        if (uri[0] != 0x10) {
-            uri[0] = 0x10;
-            uri[1] = uri[2] = uri[3] = uri[4] = 0;
-
-            size_t i = 5, j;
-            if (uri[i] != ';' && uri[i] != ',') { // has media type?
-                uri[1] = char(i);
-                for (; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
-                    // nothing to do!
-                }
-            }
-            while (uri[i] == ';' && i < uriLen) {
-                uri[i++] = '\0';
-                for (j = i; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
-                    // nothing to do!
-                }
-
-                if ( strncmp( uri + j, "charset=", 8 ) == 0 ) {
-                    uri[2] = char(j + 8);
-                } else if ( strncmp( uri + j, "base64", 6 ) == 0 ) {
-                    uri[3] = char(j);
-                }
-            }
-            if (i < uriLen) {
-                uri[i++] = '\0';
-                uri[4] = char(i);
-            } else {
-                uri[1] = uri[2] = uri[3] = 0;
-                uri[4] = 5;
-            }
-        }
-
-        if ( uri[ 1 ] != 0 ) {
-            out.mediaType = uri + uri[ 1 ];
-        }
-        if ( uri[ 2 ] != 0 ) {
-            out.charset = uri + uri[ 2 ];
-        }
-        if ( uri[ 3 ] != 0 ) {
-            out.base64 = true;
-        }
-        out.data = uri + uri[4];
-        out.dataLength = (uri + uriLen) - out.data;
-
-        return true;
-    }
-
-    template<bool B>
-    struct DATA
-    {
-        static const uint8_t tableDecodeBase64[128];
-    };
-
-    template<bool B>
-    const uint8_t DATA<B>::tableDecodeBase64[128] = {
-         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 62,  0,  0,  0, 63,
-        52, 53, 54, 55, 56, 57, 58, 59, 60, 61,  0,  0,  0, 64,  0,  0,
-         0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
-        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,  0,  0,  0,  0,  0,
-         0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
-        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,  0,  0,  0,  0,  0
-    };
-
-    inline char EncodeCharBase64(uint8_t b)
-    {
-        return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="[size_t(b)];
-    }
-
-    inline uint8_t DecodeCharBase64(char c)
-    {
-        return DATA<true>::tableDecodeBase64[size_t(c)]; // TODO faster with lookup table or ifs?
-        /*if (c >= 'A' && c <= 'Z') return c - 'A';
-        if (c >= 'a' && c <= 'z') return c - 'a' + 26;
-        if (c >= '0' && c <= '9') return c - '0' + 52;
-        if (c == '+') return 62;
-        if (c == '/') return 63;
-        return 64; // '-' */
-    }
-
-    inline size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out)
-    {
-        ai_assert(inLength % 4 == 0);
-
-        if (inLength < 4) {
-            out = 0;
-            return 0;
-        }
-
-        int nEquals = int(in[inLength - 1] == '=') +
-                      int(in[inLength - 2] == '=');
-
-        size_t outLength = (inLength * 3) / 4 - nEquals;
-        out = new uint8_t[outLength];
-        memset(out, 0, outLength);
-
-        size_t i, j = 0;
-
-        for (i = 0; i + 4 < inLength; i += 4) {
-            uint8_t b0 = DecodeCharBase64(in[i]);
-            uint8_t b1 = DecodeCharBase64(in[i + 1]);
-            uint8_t b2 = DecodeCharBase64(in[i + 2]);
-            uint8_t b3 = DecodeCharBase64(in[i + 3]);
-
-            out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
-            out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
-            out[j++] = (uint8_t)((b2 << 6) | b3);
-        }
-
-        {
-            uint8_t b0 = DecodeCharBase64(in[i]);
-            uint8_t b1 = DecodeCharBase64(in[i + 1]);
-            uint8_t b2 = DecodeCharBase64(in[i + 2]);
-            uint8_t b3 = DecodeCharBase64(in[i + 3]);
-
-            out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
-            if (b2 < 64) out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
-            if (b3 < 64) out[j++] = (uint8_t)((b2 << 6) | b3);
-        }
-
-        return outLength;
-    }
-
-
-
-    inline void EncodeBase64(
-        const uint8_t* in, size_t inLength,
-        std::string& out)
-    {
-        size_t outLength = ((inLength + 2) / 3) * 4;
-
-        size_t j = out.size();
-        out.resize(j + outLength);
-
-        for (size_t i = 0; i <  inLength; i += 3) {
-            uint8_t b = (in[i] & 0xFC) >> 2;
-            out[j++] = EncodeCharBase64(b);
-
-            b = (in[i] & 0x03) << 4;
-            if (i + 1 < inLength) {
-                b |= (in[i + 1] & 0xF0) >> 4;
-                out[j++] = EncodeCharBase64(b);
-
-                b = (in[i + 1] & 0x0F) << 2;
-                if (i + 2 < inLength) {
-                    b |= (in[i + 2] & 0xC0) >> 6;
-                    out[j++] = EncodeCharBase64(b);
-
-                    b = in[i + 2] & 0x3F;
-                    out[j++] = EncodeCharBase64(b);
-                }
-                else {
-                    out[j++] = EncodeCharBase64(b);
-                    out[j++] = '=';
-                }
-            }
-            else {
-                out[j++] = EncodeCharBase64(b);
-                out[j++] = '=';
-                out[j++] = '=';
-            }
-        }
-    }
-
-}
-
 } // ns glTF
 } // ns glTF

+ 1 - 1
code/glTF2/glTF2AssetWriter.inl

@@ -218,7 +218,7 @@ namespace glTF2 {
             if (img.HasData()) {
             if (img.HasData()) {
                 uri = "data:" + (img.mimeType.empty() ? "application/octet-stream" : img.mimeType);
                 uri = "data:" + (img.mimeType.empty() ? "application/octet-stream" : img.mimeType);
                 uri += ";base64,";
                 uri += ";base64,";
-                Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri);
+                glTFCommon::Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri);
             }
             }
             else {
             else {
                 uri = img.uri;
                 uri = img.uri;

+ 15 - 8
code/glTF2/glTF2Importer.cpp

@@ -64,6 +64,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 using namespace Assimp;
 using namespace Assimp;
 using namespace glTF2;
 using namespace glTF2;
+using namespace glTFCommon;
 
 
 namespace {
 namespace {
     // generate bi-tangents from normals and tangents according to spec
     // generate bi-tangents from normals and tangents according to spec
@@ -140,22 +141,23 @@ static aiTextureMapMode ConvertWrappingMode(SamplerWrap gltfWrapMode)
     }
     }
 }
 }
 
 
-static void CopyValue(const glTF2::vec3& v, aiColor3D& out)
+/*static void CopyValue(const glTF2::vec3& v, aiColor3D& out)
 {
 {
     out.r = v[0]; out.g = v[1]; out.b = v[2];
     out.r = v[0]; out.g = v[1]; out.b = v[2];
 }
 }
 
 
+
 static void CopyValue(const glTF2::vec4& v, aiColor4D& out)
 static void CopyValue(const glTF2::vec4& v, aiColor4D& out)
 {
 {
     out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = v[3];
     out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = v[3];
-}
+}*/
 
 
 /*static void CopyValue(const glTF2::vec4& v, aiColor3D& out)
 /*static void CopyValue(const glTF2::vec4& v, aiColor3D& out)
 {
 {
     out.r = v[0]; out.g = v[1]; out.b = v[2];
     out.r = v[0]; out.g = v[1]; out.b = v[2];
 }*/
 }*/
 
 
-static void CopyValue(const glTF2::vec3& v, aiColor4D& out)
+/*static void CopyValue(const glTF2::vec3& v, aiColor4D& out)
 {
 {
     out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = 1.0;
     out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = 1.0;
 }
 }
@@ -168,15 +170,15 @@ static void CopyValue(const glTF2::vec3& v, aiVector3D& out)
 static void CopyValue(const glTF2::vec4& v, aiQuaternion& out)
 static void CopyValue(const glTF2::vec4& v, aiQuaternion& out)
 {
 {
     out.x = v[0]; out.y = v[1]; out.z = v[2]; out.w = v[3];
     out.x = v[0]; out.y = v[1]; out.z = v[2]; out.w = v[3];
-}
+}*/
 
 
-static void CopyValue(const glTF2::mat4& v, aiMatrix4x4& o)
+/*static void CopyValue(const glTF2::mat4& v, aiMatrix4x4& o)
 {
 {
     o.a1 = v[ 0]; o.b1 = v[ 1]; o.c1 = v[ 2]; o.d1 = v[ 3];
     o.a1 = v[ 0]; o.b1 = v[ 1]; o.c1 = v[ 2]; o.d1 = v[ 3];
     o.a2 = v[ 4]; o.b2 = v[ 5]; o.c2 = v[ 6]; o.d2 = v[ 7];
     o.a2 = v[ 4]; o.b2 = v[ 5]; o.c2 = v[ 6]; o.d2 = v[ 7];
     o.a3 = v[ 8]; o.b3 = v[ 9]; o.c3 = v[10]; o.d3 = v[11];
     o.a3 = v[ 8]; o.b3 = v[ 9]; o.c3 = v[10]; o.d3 = v[11];
     o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15];
     o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15];
-}
+}*/
 
 
 inline void SetMaterialColorProperty(Asset& /*r*/, vec4& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx)
 inline void SetMaterialColorProperty(Asset& /*r*/, vec4& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx)
 {
 {
@@ -188,7 +190,7 @@ inline void SetMaterialColorProperty(Asset& /*r*/, vec4& prop, aiMaterial* mat,
 inline void SetMaterialColorProperty(Asset& /*r*/, vec3& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx)
 inline void SetMaterialColorProperty(Asset& /*r*/, vec3& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx)
 {
 {
     aiColor4D col;
     aiColor4D col;
-    CopyValue(prop, col);
+    glTFCommon::CopyValue(prop, col);
     mat->AddProperty(&col, 1, pKey, type, idx);
     mat->AddProperty(&col, 1, pKey, type, idx);
 }
 }
 
 
@@ -987,7 +989,12 @@ void glTF2Importer::ImportNodes(glTF2::Asset& r)
 }
 }
 
 
 struct AnimationSamplers {
 struct AnimationSamplers {
-    AnimationSamplers() : translation(nullptr), rotation(nullptr), scale(nullptr) {}
+    AnimationSamplers()
+    : translation(nullptr)
+    , rotation(nullptr)
+    , scale(nullptr) {
+        // empty
+    }
 
 
     Animation::Sampler* translation;
     Animation::Sampler* translation;
     Animation::Sampler* rotation;
     Animation::Sampler* rotation;