Browse Source

Merge branch 'master' into master

Pankaj003 4 năm trước cách đây
mục cha
commit
72075f984e

+ 51 - 46
code/AssetLib/glTF2/glTF2Asset.h

@@ -356,6 +356,53 @@ struct Nullable {
             isPresent(true) {}
 };
 
+struct CustomExtension {
+    //
+    // A struct containing custom extension data added to a glTF2 file
+    // Has to contain Object, Array, String, Double, Uint64, and Int64 at a minimum
+    // String, Double, Uint64, and Int64 are stored in the Nullables
+    // Object and Array are stored in the std::vector
+    //
+    std::string name;
+
+    Nullable<std::string> mStringValue;
+    Nullable<double> mDoubleValue;
+    Nullable<uint64_t> mUint64Value;
+    Nullable<int64_t> mInt64Value;
+    Nullable<bool> mBoolValue;
+
+    // std::vector<CustomExtension> handles both Object and Array
+    Nullable<std::vector<CustomExtension>> mValues;
+
+    operator bool() const {
+        return Size() != 0;
+    }
+
+    size_t Size() const {
+        if (mValues.isPresent) {
+            return mValues.value.size();
+        } else if (mStringValue.isPresent || mDoubleValue.isPresent || mUint64Value.isPresent || mInt64Value.isPresent || mBoolValue.isPresent) {
+            return 1;
+        }
+        return 0;
+    }
+
+    CustomExtension() = default;
+    
+    ~CustomExtension() = default;
+    
+    CustomExtension(const CustomExtension &other) :
+            name(other.name),
+            mStringValue(other.mStringValue),
+            mDoubleValue(other.mDoubleValue),
+            mUint64Value(other.mUint64Value),
+            mInt64Value(other.mInt64Value),
+            mBoolValue(other.mBoolValue),
+            mValues(other.mValues) {
+        // empty
+    }
+};
+
 //! Base class for all glTF top-level objects
 struct Object {
     int index; //!< The index of this object within its property container
@@ -363,6 +410,8 @@ struct Object {
     std::string id; //!< The globally unique ID used to reference this object
     std::string name; //!< The user-defined name of this object
 
+    CustomExtension customExtensions;
+
     //! Objects marked as special are not exported (used to emulate the binary body buffer)
     virtual bool IsSpecial() const { return false; }
 
@@ -377,6 +426,8 @@ struct Object {
     inline Value *FindArray(Value &val, const char *id);
     inline Value *FindObject(Value &val, const char *id);
     inline Value *FindExtension(Value &val, const char *extensionId);
+
+    inline void ReadExtensions(Value &val);
 };
 
 //
@@ -834,50 +885,6 @@ struct Mesh : public Object {
     void Read(Value &pJSON_Object, Asset &pAsset_Root);
 };
 
-struct CustomExtension : public Object {
-    //
-    // A struct containing custom extension data added to a glTF2 file
-    // Has to contain Object, Array, String, Double, Uint64, and Int64 at a minimum
-    // String, Double, Uint64, and Int64 are stored in the Nullables
-    // Object and Array are stored in the std::vector
-    //
-
-    Nullable<std::string> mStringValue;
-    Nullable<double> mDoubleValue;
-    Nullable<uint64_t> mUint64Value;
-    Nullable<int64_t> mInt64Value;
-    Nullable<bool> mBoolValue;
-
-    // std::vector<CustomExtension> handles both Object and Array
-    Nullable<std::vector<CustomExtension>> mValues;
-
-    operator bool() const {
-        return Size() != 0;
-    }
-
-    size_t Size() const {
-        if (mValues.isPresent) {
-            return mValues.value.size();
-        } else if (mStringValue.isPresent || mDoubleValue.isPresent || mUint64Value.isPresent || mInt64Value.isPresent || mBoolValue.isPresent) {
-            return 1;
-        }
-        return 0;
-    }
-
-    CustomExtension() = default;
-
-    CustomExtension(const CustomExtension &other)
-        : Object(other)
-        , mStringValue(other.mStringValue)
-        , mDoubleValue(other.mDoubleValue)
-        , mUint64Value(other.mUint64Value)
-        , mInt64Value(other.mInt64Value)
-        , mBoolValue(other.mBoolValue)
-        , mValues(other.mValues)
-    {
-    }
-};
-
 struct Node : public Object {
     std::vector<Ref<Node>> children;
     std::vector<Ref<Mesh>> meshes;
@@ -896,8 +903,6 @@ struct Node : public Object {
 
     Ref<Node> parent; //!< This is not part of the glTF specification. Used as a helper.
 
-    CustomExtension extensions;
-
     Node() {}
     void Read(Value &obj, Asset &r);
 };

+ 72 - 61
code/AssetLib/glTF2/glTF2Asset.inl

@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
 
 Copyright (c) 2006-2021, assimp team
 
-
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -304,6 +303,43 @@ inline Value *FindObject(Document &doc, const char *memberId) {
 inline Value *FindExtension(Value &val, const char *extensionId) {
     return FindExtensionInContext(val, extensionId, "the document");
 }
+
+inline CustomExtension ReadExtensions(const char *name, Value &obj) {
+    CustomExtension ret;
+    ret.name = name;
+    if (obj.IsObject()) {
+        ret.mValues.isPresent = true;
+        for (auto it = obj.MemberBegin(); it != obj.MemberEnd(); ++it) {
+            auto &val = it->value;
+            ret.mValues.value.push_back(ReadExtensions(it->name.GetString(), val));
+        }
+    } else if (obj.IsArray()) {
+        ret.mValues.value.reserve(obj.Size());
+        ret.mValues.isPresent = true;
+        for (unsigned int i = 0; i < obj.Size(); ++i) {
+            ret.mValues.value.push_back(ReadExtensions(name, obj[i]));
+        }
+    } else if (obj.IsNumber()) {
+        if (obj.IsUint64()) {
+            ret.mUint64Value.value = obj.GetUint64();
+            ret.mUint64Value.isPresent = true;
+        } else if (obj.IsInt64()) {
+            ret.mInt64Value.value = obj.GetInt64();
+            ret.mInt64Value.isPresent = true;
+        } else if (obj.IsDouble()) {
+            ret.mDoubleValue.value = obj.GetDouble();
+            ret.mDoubleValue.isPresent = true;
+        }
+    } else if (obj.IsString()) {
+        ReadValue(obj, ret.mStringValue);
+        ret.mStringValue.isPresent = true;
+    } else if (obj.IsBool()) {
+        ret.mBoolValue.value = obj.GetBool();
+        ret.mBoolValue.isPresent = true;
+    }
+    return ret;
+}
+
 } // namespace
 
 inline Value *Object::FindString(Value &val, const char *memberId) {
@@ -330,6 +366,12 @@ inline Value *Object::FindExtension(Value &val, const char *extensionId) {
     return FindExtensionInContext(val, extensionId, id.c_str(), name.c_str());
 }
 
+inline void Object::ReadExtensions(Value &val) {
+    if (Value *curExtensions = FindObject(val, "extensions")) {
+        this->customExtensions = glTF2::ReadExtensions("extensions", *curExtensions);
+    }
+}
+
 #ifdef ASSIMP_ENABLE_DRACO
 
 template <typename T>
@@ -569,6 +611,7 @@ Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
     inst->oIndex = i;
     ReadMember(obj, "name", inst->name);
     inst->Read(obj, mAsset);
+    inst->ReadExtensions(obj);
 
     Ref<T> result = Add(inst.release());
     mRecursiveReferenceCheck.erase(i);
@@ -733,12 +776,13 @@ inline void Buffer::EncodedRegion_Mark(const size_t pOffset, const size_t pEncod
 }
 
 inline void Buffer::EncodedRegion_SetCurrent(const std::string &pID) {
-    if ((EncodedRegion_Current != nullptr) && (EncodedRegion_Current->ID == pID)) return;
+    if ((EncodedRegion_Current != nullptr) && (EncodedRegion_Current->ID == pID)) {
+        return;
+    }
 
     for (SEncodedRegion *reg : EncodedRegion_List) {
         if (reg->ID == pID) {
             EncodedRegion_Current = reg;
-
             return;
         }
     }
@@ -788,10 +832,13 @@ inline bool Buffer::ReplaceData_joint(const size_t pBufferData_Offset, const siz
 }
 
 inline size_t Buffer::AppendData(uint8_t *data, size_t length) {
-    size_t offset = this->byteLength;
+    const size_t offset = this->byteLength;
+    
     // Force alignment to 4 bits
-    Grow((length + 3) & ~3);
+    const size_t paddedLength = (length + 3) & ~3;
+    Grow(paddedLength);
     memcpy(mData.get() + offset, data, length);
+    memset(mData.get() + offset + length, 0, paddedLength - length);
     return offset;
 }
 
@@ -820,9 +867,7 @@ inline void Buffer::Grow(size_t amount) {
 //
 // struct BufferView
 //
-
 inline void BufferView::Read(Value &obj, Asset &r) {
-
     if (Value *bufferVal = FindUInt(obj, "buffer")) {
         buffer = r.buffers.Retrieve(bufferVal->GetUint());
     }
@@ -842,16 +887,21 @@ inline void BufferView::Read(Value &obj, Asset &r) {
 }
 
 inline uint8_t *BufferView::GetPointer(size_t accOffset) {
-    if (!buffer) return nullptr;
+    if (!buffer) {
+        return nullptr;
+    }
     uint8_t *basePtr = buffer->GetPointer();
-    if (!basePtr) return nullptr;
+    if (!basePtr) {
+        return nullptr;
+    }
 
     size_t offset = accOffset + byteOffset;
     if (buffer->EncodedRegion_Current != nullptr) {
         const size_t begin = buffer->EncodedRegion_Current->Offset;
         const size_t end = begin + buffer->EncodedRegion_Current->DecodedData_Length;
-        if ((offset >= begin) && (offset < end))
+        if ((offset >= begin) && (offset < end)) {
             return &buffer->EncodedRegion_Current->DecodedData[offset - begin];
+        }
     }
 
     return basePtr + offset;
@@ -877,18 +927,18 @@ inline void Accessor::Sparse::PatchData(unsigned int elementSize) {
     while (pIndices != indicesEnd) {
         size_t offset;
         switch (indicesType) {
-        case ComponentType_UNSIGNED_BYTE:
-            offset = *pIndices;
-            break;
-        case ComponentType_UNSIGNED_SHORT:
-            offset = *reinterpret_cast<uint16_t *>(pIndices);
-            break;
-        case ComponentType_UNSIGNED_INT:
-            offset = *reinterpret_cast<uint32_t *>(pIndices);
-            break;
-        default:
-            // have fun with float and negative values from signed types as indices.
-            throw DeadlyImportError("Unsupported component type in index.");
+            case ComponentType_UNSIGNED_BYTE:
+                offset = *pIndices;
+                break;
+            case ComponentType_UNSIGNED_SHORT:
+                offset = *reinterpret_cast<uint16_t *>(pIndices);
+                break;
+            case ComponentType_UNSIGNED_INT:
+                offset = *reinterpret_cast<uint32_t *>(pIndices);
+                break;
+            default:
+                // have fun with float and negative values from signed types as indices.
+                throw DeadlyImportError("Unsupported component type in index.");
         }
 
         offset *= elementSize;
@@ -900,7 +950,6 @@ inline void Accessor::Sparse::PatchData(unsigned int elementSize) {
 }
 
 inline void Accessor::Read(Value &obj, Asset &r) {
-
     if (Value *bufferViewVal = FindUInt(obj, "bufferView")) {
         bufferView = r.bufferViews.Retrieve(bufferViewVal->GetUint());
     }
@@ -1683,42 +1732,6 @@ inline void Light::Read(Value &obj, Asset & /*r*/) {
     }
 }
 
-inline CustomExtension ReadExtensions(const char *name, Value &obj) {
-    CustomExtension ret;
-    ret.name = name;
-    if (obj.IsObject()) {
-        ret.mValues.isPresent = true;
-        for (auto it = obj.MemberBegin(); it != obj.MemberEnd(); ++it) {
-            auto &val = it->value;
-            ret.mValues.value.push_back(ReadExtensions(it->name.GetString(), val));
-        }
-    } else if (obj.IsArray()) {
-        ret.mValues.value.reserve(obj.Size());
-        ret.mValues.isPresent = true;
-        for (unsigned int i = 0; i < obj.Size(); ++i) {
-            ret.mValues.value.push_back(ReadExtensions(name, obj[i]));
-        }
-    } else if (obj.IsNumber()) {
-        if (obj.IsUint64()) {
-            ret.mUint64Value.value = obj.GetUint64();
-            ret.mUint64Value.isPresent = true;
-        } else if (obj.IsInt64()) {
-            ret.mInt64Value.value = obj.GetInt64();
-            ret.mInt64Value.isPresent = true;
-        } else if (obj.IsDouble()) {
-            ret.mDoubleValue.value = obj.GetDouble();
-            ret.mDoubleValue.isPresent = true;
-        }
-    } else if (obj.IsString()) {
-        ReadValue(obj, ret.mStringValue);
-        ret.mStringValue.isPresent = true;
-    } else if (obj.IsBool()) {
-        ret.mBoolValue.value = obj.GetBool();
-        ret.mBoolValue.isPresent = true;
-    }
-    return ret;
-}
-
 inline void Node::Read(Value &obj, Asset &r) {
     if (name.empty()) {
         name = id;
@@ -1775,8 +1788,6 @@ inline void Node::Read(Value &obj, Asset &r) {
 
     Value *curExtensions = FindObject(obj, "extensions");
     if (nullptr != curExtensions) {
-        this->extensions = ReadExtensions("extensions", *curExtensions);
-
         if (r.extensionsUsed.KHR_lights_punctual) {
             if (Value *ext = FindObject(*curExtensions, "KHR_lights_punctual")) {
                 Value *curLight = FindUInt(*ext, "light");

+ 8 - 4
code/AssetLib/glTF2/glTF2Importer.cpp

@@ -503,7 +503,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
                                                "\" does not match the vertex count");
                     continue;
                 }
-                
+
                 auto componentType = attr.color[c]->componentType;
                 if (componentType == glTF2::ComponentType_FLOAT) {
                     attr.color[c]->ExtractData(aim->mColors[c]);
@@ -1016,9 +1016,9 @@ aiNode *ImportNode(aiScene *pScene, glTF2::Asset &r, std::vector<unsigned int> &
             }
         }
 
-        if (node.extensions) {
+        if (node.customExtensions) {
             ainode->mMetaData = new aiMetadata;
-            ParseExtensions(ainode->mMetaData, node.extensions);
+            ParseExtensions(ainode->mMetaData, node.customExtensions);
         }
 
         GetNodeTransform(ainode->mTransformation, node);
@@ -1512,7 +1512,8 @@ void glTF2Importer::ImportCommonMetadata(glTF2::Asset& a) {
     const bool hasVersion = !a.asset.version.empty();
     const bool hasGenerator = !a.asset.generator.empty();
     const bool hasCopyright = !a.asset.copyright.empty();
-    if (hasVersion || hasGenerator || hasCopyright) {
+    const bool hasSceneMetadata = a.scene->customExtensions;
+    if (hasVersion || hasGenerator || hasCopyright || hasSceneMetadata) {
         mScene->mMetaData = new aiMetadata;
         if (hasVersion) {
             mScene->mMetaData->Add(AI_METADATA_SOURCE_FORMAT_VERSION, aiString(a.asset.version));
@@ -1523,6 +1524,9 @@ void glTF2Importer::ImportCommonMetadata(glTF2::Asset& a) {
         if (hasCopyright) {
             mScene->mMetaData->Add(AI_METADATA_SOURCE_COPYRIGHT, aiString(a.asset.copyright));
         }
+        if (hasSceneMetadata) {
+            ParseExtensions(mScene->mMetaData, a.scene->customExtensions);
+        }
     }
 }
 

+ 1 - 21
include/assimp/material.h

@@ -1499,8 +1499,6 @@ ASSIMP_API C_ENUM aiReturn aiGetMaterialFloatArray(
         ai_real *pOut,
         unsigned int *pMax);
 
-#ifdef __cplusplus
-
 // ---------------------------------------------------------------------------
 /** @brief Retrieve a single float property with a specific key from the material.
 *
@@ -1520,7 +1518,7 @@ ASSIMP_API C_ENUM aiReturn aiGetMaterialFloatArray(
 * @return Specifies whether the key has been found. If not, the output
 *   float remains unmodified.*/
 // ---------------------------------------------------------------------------
-inline aiReturn aiGetMaterialFloat(const aiMaterial *pMat,
+inline aiReturn aiGetMaterialFloat(const C_STRUCT aiMaterial *pMat,
         const char *pKey,
         unsigned int type,
         unsigned int index,
@@ -1528,14 +1526,6 @@ inline aiReturn aiGetMaterialFloat(const aiMaterial *pMat,
     return aiGetMaterialFloatArray(pMat, pKey, type, index, pOut, (unsigned int *)0x0);
 }
 
-#else
-
-// Use our friend, the C preprocessor
-#define aiGetMaterialFloat (pMat, type, index, pKey, pOut) \
-        aiGetMaterialFloatArray(pMat, type, index, pKey, pOut, NULL)
-
-#endif //!__cplusplus
-
 // ---------------------------------------------------------------------------
 /** @brief Retrieve an array of integer values with a specific key
  *  from a material
@@ -1548,8 +1538,6 @@ ASSIMP_API C_ENUM aiReturn aiGetMaterialIntegerArray(const C_STRUCT aiMaterial *
         int *pOut,
         unsigned int *pMax);
 
-#ifdef __cplusplus
-
 // ---------------------------------------------------------------------------
 /** @brief Retrieve an integer property with a specific key from a material
  *
@@ -1563,14 +1551,6 @@ inline aiReturn aiGetMaterialInteger(const C_STRUCT aiMaterial *pMat,
     return aiGetMaterialIntegerArray(pMat, pKey, type, index, pOut, (unsigned int *)0x0);
 }
 
-#else
-
-// use our friend, the C preprocessor
-#define aiGetMaterialInteger (pMat, type, index, pKey, pOut) \
-        aiGetMaterialIntegerArray(pMat, type, index, pKey, pOut, NULL)
-
-#endif //!__cplusplus
-
 // ---------------------------------------------------------------------------
 /** @brief Retrieve a color value from the material property table
 *

+ 1 - 1
include/assimp/metadata.h

@@ -432,7 +432,7 @@ struct aiMetadata {
 
     /// Check whether there is a metadata entry for the given key.
     /// \param [in] Key - the key value value to check for.
-    inline bool HasKey(const char *key) {
+    inline bool HasKey(const char *key) const {
         if (nullptr == key) {
             return false;
         }