From 417481d17f3864c8b7b47e000a857d1f4279946b Mon Sep 17 00:00:00 2001 From: Bengt Rosenberger Date: Fri, 22 Jul 2022 00:44:51 +0200 Subject: [PATCH 1/9] Rewrote gltf2 node extras import and added node extras export. No support for AI_AIVECTOR3D metadata type. No support for json arrays of metadata, just json objects. --- code/AssetLib/glTF2/glTF2Asset.h | 47 ++++++++++++++++++- code/AssetLib/glTF2/glTF2Asset.inl | 46 ++++++++++++++++++- code/AssetLib/glTF2/glTF2AssetWriter.inl | 41 ++++++++++++++++- code/AssetLib/glTF2/glTF2Exporter.cpp | 57 +++++++++++++++++++++++- code/AssetLib/glTF2/glTF2Importer.cpp | 34 +++++++++++--- code/Common/SceneCombiner.cpp | 3 ++ 6 files changed, 218 insertions(+), 10 deletions(-) diff --git a/code/AssetLib/glTF2/glTF2Asset.h b/code/AssetLib/glTF2/glTF2Asset.h index c597fc951..bdc62dbc2 100644 --- a/code/AssetLib/glTF2/glTF2Asset.h +++ b/code/AssetLib/glTF2/glTF2Asset.h @@ -376,6 +376,51 @@ struct CustomExtension { } }; +struct ExtrasValue; + +//! Represents a union of metadata values +struct ExtrasValue { + std::string name; + + Nullable mBoolValue; + Nullable mInt32Value; + Nullable mUint64Value; + Nullable mFloatValue; + Nullable mDoubleValue; + Nullable mStringValue; + Nullable> mMetadataValue; + + ExtrasValue() = default; + ~ExtrasValue() = default; + + ExtrasValue(const ExtrasValue& other) : + name(other.name), + mStringValue(other.mStringValue), + mDoubleValue(other.mDoubleValue), + mUint64Value(other.mUint64Value), + mInt32Value(other.mInt32Value), + mBoolValue(other.mBoolValue), + mMetadataValue(other.mMetadataValue) { + } +}; + +//! Represents metadata in an glTF object +struct Extras { + std::vector mValues; + + inline bool HasExtras() const { + return mValues.size() != 0; + } + + Extras() = default; + ~Extras() = default; + + Extras(const Extras &other) : + 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 @@ -384,7 +429,7 @@ struct Object { std::string name; //!< The user-defined name of this object CustomExtension customExtensions; - CustomExtension extras; + Extras extras; //! Objects marked as special are not exported (used to emulate the binary body buffer) virtual bool IsSpecial() const { return false; } diff --git a/code/AssetLib/glTF2/glTF2Asset.inl b/code/AssetLib/glTF2/glTF2Asset.inl index db47915d6..5dc51e7fa 100644 --- a/code/AssetLib/glTF2/glTF2Asset.inl +++ b/code/AssetLib/glTF2/glTF2Asset.inl @@ -139,6 +139,50 @@ inline CustomExtension ReadExtensions(const char *name, Value &obj) { return ret; } +inline ExtrasValue ReadExtrasValue(const char *name, Value &obj) { + ExtrasValue ret; + ret.name = name; + + if (obj.IsObject()) { + ret.mMetadataValue.value.reserve(obj.MemberCount()); + ret.mMetadataValue.isPresent = true; + for (auto it = obj.MemberBegin(); it != obj.MemberEnd(); ++it) { + auto &val = it->value; + ret.mMetadataValue.value.push_back(ReadExtrasValue(it->name.GetString(), val)); + } + } else if (obj.IsNumber()) { + if (obj.IsUint64()) { + ret.mUint64Value.value = obj.GetUint64(); + ret.mUint64Value.isPresent = true; + } else if (obj.IsInt()) { + ret.mInt32Value.value = obj.GetInt64(); + ret.mInt32Value.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 Extras ReadExtras(Value &obj) { + Extras ret; + + ret.mValues.reserve(obj.MemberCount()); + for (auto it = obj.MemberBegin(); it != obj.MemberEnd(); ++it) { + auto &val = it->value; + ret.mValues.push_back(ReadExtrasValue(it->name.GetString(), val)); + } + + return ret; +} + inline void CopyData(size_t count, const uint8_t *src, size_t src_stride, uint8_t *dst, size_t dst_stride) { if (src_stride == dst_stride) { @@ -248,7 +292,7 @@ inline void Object::ReadExtensions(Value &val) { inline void Object::ReadExtras(Value &val) { if (Value *curExtras = FindObject(val, "extras")) { - this->extras = glTF2::ReadExtensions("extras", *curExtras); + this->extras = glTF2::ReadExtras(*curExtras); } } diff --git a/code/AssetLib/glTF2/glTF2AssetWriter.inl b/code/AssetLib/glTF2/glTF2AssetWriter.inl index 0be139595..e1fcaefd4 100644 --- a/code/AssetLib/glTF2/glTF2AssetWriter.inl +++ b/code/AssetLib/glTF2/glTF2AssetWriter.inl @@ -620,6 +620,44 @@ namespace glTF2 { } } + inline void WriteExtrasValue(Value &parent, const ExtrasValue &value, AssetWriter &w) { + Value valueNode; + + if (value.mStringValue.isPresent) { + MakeValue(valueNode, value.mStringValue.value.c_str(), w.mAl); + } else if (value.mDoubleValue.isPresent) { + MakeValue(valueNode, value.mDoubleValue.value, w.mAl); + } else if (value.mUint64Value.isPresent) { + MakeValue(valueNode, value.mUint64Value.value, w.mAl); + } else if (value.mInt32Value.isPresent) { + MakeValue(valueNode, value.mInt32Value.value, w.mAl); + } else if (value.mBoolValue.isPresent) { + MakeValue(valueNode, value.mBoolValue.value, w.mAl); + } else if (value.mMetadataValue.isPresent) { + valueNode.SetObject(); + for (auto const &subvalue : value.mMetadataValue.value) { + WriteExtrasValue(valueNode, subvalue, w); + } + } + + parent.AddMember(StringRef(value.name), valueNode, w.mAl); + } + + inline void WriteExtras(Value &obj, const Extras &extras, AssetWriter &w) { + if (!extras.HasExtras()) { + return; + } + + Value extrasNode; + extrasNode.SetObject(); + + for (auto const &value : extras.mValues) { + WriteExtrasValue(extrasNode, value, w); + } + + obj.AddMember("extras", extrasNode, w.mAl); + } + inline void Write(Value& obj, Node& n, AssetWriter& w) { if (n.matrix.isPresent) { @@ -655,6 +693,8 @@ namespace glTF2 { if(n.skeletons.size()) { AddRefsVector(obj, "skeletons", n.skeletons, w.mAl); } + + WriteExtras(obj, n.extras, w); } inline void Write(Value& /*obj*/, Program& /*b*/, AssetWriter& /*w*/) @@ -728,7 +768,6 @@ namespace glTF2 { } } - inline AssetWriter::AssetWriter(Asset& a) : mDoc() , mAsset(a) diff --git a/code/AssetLib/glTF2/glTF2Exporter.cpp b/code/AssetLib/glTF2/glTF2Exporter.cpp index da7591d52..f8b1995d9 100644 --- a/code/AssetLib/glTF2/glTF2Exporter.cpp +++ b/code/AssetLib/glTF2/glTF2Exporter.cpp @@ -445,6 +445,57 @@ inline Ref ExportData(Asset &a, std::string &meshName, Ref &bu return acc; } +inline void ExportNodeExtras(const aiMetadataEntry &metadataEntry, aiString name, ExtrasValue &value) { + + value.name = name.C_Str(); + switch (metadataEntry.mType) { + case AI_BOOL: + value.mBoolValue.value = *static_cast(metadataEntry.mData); + value.mBoolValue.isPresent = true; + break; + case AI_INT32: + value.mInt32Value.value = *static_cast(metadataEntry.mData); + value.mInt32Value.isPresent = true; + break; + case AI_UINT64: + value.mUint64Value.value = *static_cast(metadataEntry.mData); + value.mUint64Value.isPresent = true; + break; + case AI_FLOAT: + value.mFloatValue.value = *static_cast(metadataEntry.mData); + value.mFloatValue.isPresent = true; + break; + case AI_DOUBLE: + value.mDoubleValue.value = *static_cast(metadataEntry.mData); + value.mDoubleValue.isPresent = true; + break; + case AI_AISTRING: + value.mStringValue.value = static_cast(metadataEntry.mData)->C_Str(); + value.mStringValue.isPresent = true; + break; + case AI_AIMETADATA: + const aiMetadata *subMetadata = static_cast(metadataEntry.mData); + value.mMetadataValue.value.resize(subMetadata->mNumProperties); + value.mMetadataValue.isPresent = true; + + for (unsigned i = 0; i < subMetadata->mNumProperties; ++i) { + ExportNodeExtras(subMetadata->mValues[i], subMetadata->mKeys[i], value.mMetadataValue.value.at(i)); + } + break; + } +} + +inline void ExportNodeExtras(const aiMetadata *metadata, Extras &extras) { + if (metadata == nullptr) { + return; + } + + extras.mValues.resize(metadata->mNumProperties); + for (unsigned int i = 0; i < metadata->mNumProperties; ++i) { + ExportNodeExtras(metadata->mValues[i], metadata->mKeys[i], extras.mValues.at(i)); + } +} + inline void SetSamplerWrap(SamplerWrap &wrap, aiTextureMapMode map) { switch (map) { case aiTextureMapMode_Clamp: @@ -1344,7 +1395,7 @@ unsigned int glTF2Exporter::ExportNodeHierarchy(const aiNode *n) { return node.GetIndex(); } -/* + /* * Export node and recursively calls ExportNode for all children. * Since these nodes are not the root node, we also export the parent Ref */ @@ -1355,6 +1406,10 @@ unsigned int glTF2Exporter::ExportNode(const aiNode *n, Ref &parent) { node->parent = parent; node->name = name; + if (n->mMetaData != nullptr && n->mMetaData->mNumProperties > 0) { + ExportNodeExtras(n->mMetaData, node->extras); + } + if (!n->mTransformation.IsIdentity()) { if (mScene->mNumAnimations > 0 || (mProperties && mProperties->HasPropertyBool("GLTF2_NODE_IN_TRS"))) { aiQuaternion quaternion; diff --git a/code/AssetLib/glTF2/glTF2Importer.cpp b/code/AssetLib/glTF2/glTF2Importer.cpp index 293d3dea7..a14e6ad6f 100644 --- a/code/AssetLib/glTF2/glTF2Importer.cpp +++ b/code/AssetLib/glTF2/glTF2Importer.cpp @@ -1033,11 +1033,33 @@ void ParseExtensions(aiMetadata *metadata, const CustomExtension &extension) { } } -void ParseExtras(aiMetadata *metadata, const CustomExtension &extension) { - if (extension.mValues.isPresent) { - for (auto const &subExtension : extension.mValues.value) { - ParseExtensions(metadata, subExtension); +void ParseExtrasValue(aiMetadata *metadata, const ExtrasValue &value) { + + if (value.mBoolValue.isPresent) { + metadata->Add(value.name, value.mBoolValue.value); + } else if (value.mInt32Value.isPresent) { + metadata->Add(value.name, value.mInt32Value.value); + } else if (value.mUint64Value.isPresent) { + metadata->Add(value.name, value.mUint64Value.value); + } else if (value.mFloatValue.isPresent) { + metadata->Add(value.name, value.mFloatValue.value); + } else if (value.mDoubleValue.isPresent) { + metadata->Add(value.name, value.mDoubleValue.value); + } else if (value.mStringValue.isPresent) { + metadata->Add(value.name, aiString(value.mStringValue.value)); + } else if (value.mMetadataValue.isPresent) { + aiMetadata subMetadata; + for (auto const &subValue : value.mMetadataValue.value) { + ParseExtrasValue(&subMetadata, subValue); } + + metadata->Add(value.name, subMetadata); + } +} + +void ParseExtras(aiMetadata* metadata, const Extras& extras) { + for (auto const &value : extras.mValues) { + ParseExtrasValue(metadata, value); } } @@ -1059,12 +1081,12 @@ aiNode *ImportNode(aiScene *pScene, glTF2::Asset &r, std::vector & } } - if (node.customExtensions || node.extras) { + if (node.customExtensions || !node.extras.HasExtras()) { ainode->mMetaData = new aiMetadata; if (node.customExtensions) { ParseExtensions(ainode->mMetaData, node.customExtensions); } - if (node.extras) { + if (node.extras.HasExtras()) { ParseExtras(ainode->mMetaData, node.extras); } } diff --git a/code/Common/SceneCombiner.cpp b/code/Common/SceneCombiner.cpp index 2c2539e54..1d32436c2 100644 --- a/code/Common/SceneCombiner.cpp +++ b/code/Common/SceneCombiner.cpp @@ -1349,6 +1349,9 @@ void SceneCombiner::Copy(aiMetadata **_dest, const aiMetadata *src) { case AI_AIVECTOR3D: out.mData = new aiVector3D(*static_cast(in.mData)); break; + case AI_AIMETADATA: + out.mData = new aiMetadata(*static_cast(in.mData)); + break; default: ai_assert(false); break; From 5a2b811ba34cfd45d58349b3c3d1894e23f3e05e Mon Sep 17 00:00:00 2001 From: Bengt Rosenberger Date: Fri, 22 Jul 2022 01:04:05 +0200 Subject: [PATCH 2/9] Fixed extras presence check in gltf2 import. --- code/AssetLib/glTF2/glTF2Exporter.cpp | 6 ++---- code/AssetLib/glTF2/glTF2Importer.cpp | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/code/AssetLib/glTF2/glTF2Exporter.cpp b/code/AssetLib/glTF2/glTF2Exporter.cpp index f8b1995d9..d3c88e479 100644 --- a/code/AssetLib/glTF2/glTF2Exporter.cpp +++ b/code/AssetLib/glTF2/glTF2Exporter.cpp @@ -486,7 +486,7 @@ inline void ExportNodeExtras(const aiMetadataEntry &metadataEntry, aiString name } inline void ExportNodeExtras(const aiMetadata *metadata, Extras &extras) { - if (metadata == nullptr) { + if (metadata == nullptr || metadata->mNumProperties == 0) { return; } @@ -1406,9 +1406,7 @@ unsigned int glTF2Exporter::ExportNode(const aiNode *n, Ref &parent) { node->parent = parent; node->name = name; - if (n->mMetaData != nullptr && n->mMetaData->mNumProperties > 0) { - ExportNodeExtras(n->mMetaData, node->extras); - } + ExportNodeExtras(n->mMetaData, node->extras); if (!n->mTransformation.IsIdentity()) { if (mScene->mNumAnimations > 0 || (mProperties && mProperties->HasPropertyBool("GLTF2_NODE_IN_TRS"))) { diff --git a/code/AssetLib/glTF2/glTF2Importer.cpp b/code/AssetLib/glTF2/glTF2Importer.cpp index a14e6ad6f..e88cd0f08 100644 --- a/code/AssetLib/glTF2/glTF2Importer.cpp +++ b/code/AssetLib/glTF2/glTF2Importer.cpp @@ -1081,7 +1081,7 @@ aiNode *ImportNode(aiScene *pScene, glTF2::Asset &r, std::vector & } } - if (node.customExtensions || !node.extras.HasExtras()) { + if (node.customExtensions || node.extras.HasExtras()) { ainode->mMetaData = new aiMetadata; if (node.customExtensions) { ParseExtensions(ainode->mMetaData, node.customExtensions); From 517fd3c76c81450e3967ffc1df5f7b90c1a7d94c Mon Sep 17 00:00:00 2001 From: Bengt Rosenberger Date: Fri, 22 Jul 2022 01:07:42 +0200 Subject: [PATCH 3/9] Added missing member copy in gltf2::ExtrasValue ctor. --- code/AssetLib/glTF2/glTF2Asset.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/code/AssetLib/glTF2/glTF2Asset.h b/code/AssetLib/glTF2/glTF2Asset.h index bdc62dbc2..064634e40 100644 --- a/code/AssetLib/glTF2/glTF2Asset.h +++ b/code/AssetLib/glTF2/glTF2Asset.h @@ -376,9 +376,7 @@ struct CustomExtension { } }; -struct ExtrasValue; - -//! Represents a union of metadata values +//! Represents a union of metadata values. Only one nullable is supposed to be set. struct ExtrasValue { std::string name; @@ -396,6 +394,7 @@ struct ExtrasValue { ExtrasValue(const ExtrasValue& other) : name(other.name), mStringValue(other.mStringValue), + mFloatValue(other.mFloatValue), mDoubleValue(other.mDoubleValue), mUint64Value(other.mUint64Value), mInt32Value(other.mInt32Value), @@ -404,7 +403,7 @@ struct ExtrasValue { } }; -//! Represents metadata in an glTF object +//! Represents metadata in an glTF2 object struct Extras { std::vector mValues; From bdee65e577caa6f2eea8e6e22d2175407cde5de3 Mon Sep 17 00:00:00 2001 From: Bengt Rosenberger Date: Fri, 22 Jul 2022 01:33:05 +0200 Subject: [PATCH 4/9] Got rid of gltf2::ExtrasValue and used gltf2::CustomExtension instead --- code/AssetLib/glTF2/glTF2Asset.h | 29 +------------------- code/AssetLib/glTF2/glTF2Asset.inl | 34 +----------------------- code/AssetLib/glTF2/glTF2AssetWriter.inl | 10 +++---- code/AssetLib/glTF2/glTF2Exporter.cpp | 16 +++++------ code/AssetLib/glTF2/glTF2Importer.cpp | 26 +----------------- 5 files changed, 14 insertions(+), 101 deletions(-) diff --git a/code/AssetLib/glTF2/glTF2Asset.h b/code/AssetLib/glTF2/glTF2Asset.h index 064634e40..9a117205d 100644 --- a/code/AssetLib/glTF2/glTF2Asset.h +++ b/code/AssetLib/glTF2/glTF2Asset.h @@ -376,36 +376,9 @@ struct CustomExtension { } }; -//! Represents a union of metadata values. Only one nullable is supposed to be set. -struct ExtrasValue { - std::string name; - - Nullable mBoolValue; - Nullable mInt32Value; - Nullable mUint64Value; - Nullable mFloatValue; - Nullable mDoubleValue; - Nullable mStringValue; - Nullable> mMetadataValue; - - ExtrasValue() = default; - ~ExtrasValue() = default; - - ExtrasValue(const ExtrasValue& other) : - name(other.name), - mStringValue(other.mStringValue), - mFloatValue(other.mFloatValue), - mDoubleValue(other.mDoubleValue), - mUint64Value(other.mUint64Value), - mInt32Value(other.mInt32Value), - mBoolValue(other.mBoolValue), - mMetadataValue(other.mMetadataValue) { - } -}; - //! Represents metadata in an glTF2 object struct Extras { - std::vector mValues; + std::vector mValues; inline bool HasExtras() const { return mValues.size() != 0; diff --git a/code/AssetLib/glTF2/glTF2Asset.inl b/code/AssetLib/glTF2/glTF2Asset.inl index 5dc51e7fa..3a7d127d3 100644 --- a/code/AssetLib/glTF2/glTF2Asset.inl +++ b/code/AssetLib/glTF2/glTF2Asset.inl @@ -139,45 +139,13 @@ inline CustomExtension ReadExtensions(const char *name, Value &obj) { return ret; } -inline ExtrasValue ReadExtrasValue(const char *name, Value &obj) { - ExtrasValue ret; - ret.name = name; - - if (obj.IsObject()) { - ret.mMetadataValue.value.reserve(obj.MemberCount()); - ret.mMetadataValue.isPresent = true; - for (auto it = obj.MemberBegin(); it != obj.MemberEnd(); ++it) { - auto &val = it->value; - ret.mMetadataValue.value.push_back(ReadExtrasValue(it->name.GetString(), val)); - } - } else if (obj.IsNumber()) { - if (obj.IsUint64()) { - ret.mUint64Value.value = obj.GetUint64(); - ret.mUint64Value.isPresent = true; - } else if (obj.IsInt()) { - ret.mInt32Value.value = obj.GetInt64(); - ret.mInt32Value.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 Extras ReadExtras(Value &obj) { Extras ret; ret.mValues.reserve(obj.MemberCount()); for (auto it = obj.MemberBegin(); it != obj.MemberEnd(); ++it) { auto &val = it->value; - ret.mValues.push_back(ReadExtrasValue(it->name.GetString(), val)); + ret.mValues.push_back(ReadExtensions(it->name.GetString(), val)); } return ret; diff --git a/code/AssetLib/glTF2/glTF2AssetWriter.inl b/code/AssetLib/glTF2/glTF2AssetWriter.inl index e1fcaefd4..3acec58a5 100644 --- a/code/AssetLib/glTF2/glTF2AssetWriter.inl +++ b/code/AssetLib/glTF2/glTF2AssetWriter.inl @@ -620,7 +620,7 @@ namespace glTF2 { } } - inline void WriteExtrasValue(Value &parent, const ExtrasValue &value, AssetWriter &w) { + inline void WriteExtrasValue(Value &parent, const CustomExtension &value, AssetWriter &w) { Value valueNode; if (value.mStringValue.isPresent) { @@ -629,13 +629,13 @@ namespace glTF2 { MakeValue(valueNode, value.mDoubleValue.value, w.mAl); } else if (value.mUint64Value.isPresent) { MakeValue(valueNode, value.mUint64Value.value, w.mAl); - } else if (value.mInt32Value.isPresent) { - MakeValue(valueNode, value.mInt32Value.value, w.mAl); + } else if (value.mInt64Value.isPresent) { + MakeValue(valueNode, value.mInt64Value.value, w.mAl); } else if (value.mBoolValue.isPresent) { MakeValue(valueNode, value.mBoolValue.value, w.mAl); - } else if (value.mMetadataValue.isPresent) { + } else if (value.mValues.isPresent) { valueNode.SetObject(); - for (auto const &subvalue : value.mMetadataValue.value) { + for (auto const &subvalue : value.mValues.value) { WriteExtrasValue(valueNode, subvalue, w); } } diff --git a/code/AssetLib/glTF2/glTF2Exporter.cpp b/code/AssetLib/glTF2/glTF2Exporter.cpp index d3c88e479..028ab5c17 100644 --- a/code/AssetLib/glTF2/glTF2Exporter.cpp +++ b/code/AssetLib/glTF2/glTF2Exporter.cpp @@ -445,7 +445,7 @@ inline Ref ExportData(Asset &a, std::string &meshName, Ref &bu return acc; } -inline void ExportNodeExtras(const aiMetadataEntry &metadataEntry, aiString name, ExtrasValue &value) { +inline void ExportNodeExtras(const aiMetadataEntry &metadataEntry, aiString name, CustomExtension &value) { value.name = name.C_Str(); switch (metadataEntry.mType) { @@ -454,17 +454,13 @@ inline void ExportNodeExtras(const aiMetadataEntry &metadataEntry, aiString name value.mBoolValue.isPresent = true; break; case AI_INT32: - value.mInt32Value.value = *static_cast(metadataEntry.mData); - value.mInt32Value.isPresent = true; + value.mInt64Value.value = *static_cast(metadataEntry.mData); + value.mInt64Value.isPresent = true; break; case AI_UINT64: value.mUint64Value.value = *static_cast(metadataEntry.mData); value.mUint64Value.isPresent = true; break; - case AI_FLOAT: - value.mFloatValue.value = *static_cast(metadataEntry.mData); - value.mFloatValue.isPresent = true; - break; case AI_DOUBLE: value.mDoubleValue.value = *static_cast(metadataEntry.mData); value.mDoubleValue.isPresent = true; @@ -475,11 +471,11 @@ inline void ExportNodeExtras(const aiMetadataEntry &metadataEntry, aiString name break; case AI_AIMETADATA: const aiMetadata *subMetadata = static_cast(metadataEntry.mData); - value.mMetadataValue.value.resize(subMetadata->mNumProperties); - value.mMetadataValue.isPresent = true; + value.mValues.value.resize(subMetadata->mNumProperties); + value.mValues.isPresent = true; for (unsigned i = 0; i < subMetadata->mNumProperties; ++i) { - ExportNodeExtras(subMetadata->mValues[i], subMetadata->mKeys[i], value.mMetadataValue.value.at(i)); + ExportNodeExtras(subMetadata->mValues[i], subMetadata->mKeys[i], value.mValues.value.at(i)); } break; } diff --git a/code/AssetLib/glTF2/glTF2Importer.cpp b/code/AssetLib/glTF2/glTF2Importer.cpp index e88cd0f08..f34465444 100644 --- a/code/AssetLib/glTF2/glTF2Importer.cpp +++ b/code/AssetLib/glTF2/glTF2Importer.cpp @@ -1033,33 +1033,9 @@ void ParseExtensions(aiMetadata *metadata, const CustomExtension &extension) { } } -void ParseExtrasValue(aiMetadata *metadata, const ExtrasValue &value) { - - if (value.mBoolValue.isPresent) { - metadata->Add(value.name, value.mBoolValue.value); - } else if (value.mInt32Value.isPresent) { - metadata->Add(value.name, value.mInt32Value.value); - } else if (value.mUint64Value.isPresent) { - metadata->Add(value.name, value.mUint64Value.value); - } else if (value.mFloatValue.isPresent) { - metadata->Add(value.name, value.mFloatValue.value); - } else if (value.mDoubleValue.isPresent) { - metadata->Add(value.name, value.mDoubleValue.value); - } else if (value.mStringValue.isPresent) { - metadata->Add(value.name, aiString(value.mStringValue.value)); - } else if (value.mMetadataValue.isPresent) { - aiMetadata subMetadata; - for (auto const &subValue : value.mMetadataValue.value) { - ParseExtrasValue(&subMetadata, subValue); - } - - metadata->Add(value.name, subMetadata); - } -} - void ParseExtras(aiMetadata* metadata, const Extras& extras) { for (auto const &value : extras.mValues) { - ParseExtrasValue(metadata, value); + ParseExtensions(metadata, value); } } From 99c31045886039034bae70d44ba59320508d4e57 Mon Sep 17 00:00:00 2001 From: Bengt Rosenberger Date: Fri, 22 Jul 2022 00:44:51 +0200 Subject: [PATCH 5/9] Rewrote gltf2 node extras import and added node extras export. No support for AI_AIVECTOR3D metadata type. No support for json arrays of metadata, just json objects. --- code/AssetLib/glTF2/glTF2Asset.h | 47 ++++++++++++++++++- code/AssetLib/glTF2/glTF2Asset.inl | 46 ++++++++++++++++++- code/AssetLib/glTF2/glTF2AssetWriter.inl | 41 ++++++++++++++++- code/AssetLib/glTF2/glTF2Exporter.cpp | 57 +++++++++++++++++++++++- code/AssetLib/glTF2/glTF2Importer.cpp | 34 +++++++++++--- code/Common/SceneCombiner.cpp | 3 ++ 6 files changed, 218 insertions(+), 10 deletions(-) diff --git a/code/AssetLib/glTF2/glTF2Asset.h b/code/AssetLib/glTF2/glTF2Asset.h index 44ab6c9c8..a4a615131 100644 --- a/code/AssetLib/glTF2/glTF2Asset.h +++ b/code/AssetLib/glTF2/glTF2Asset.h @@ -378,6 +378,51 @@ struct CustomExtension { CustomExtension& operator=(const CustomExtension&) = default; }; +struct ExtrasValue; + +//! Represents a union of metadata values +struct ExtrasValue { + std::string name; + + Nullable mBoolValue; + Nullable mInt32Value; + Nullable mUint64Value; + Nullable mFloatValue; + Nullable mDoubleValue; + Nullable mStringValue; + Nullable> mMetadataValue; + + ExtrasValue() = default; + ~ExtrasValue() = default; + + ExtrasValue(const ExtrasValue& other) : + name(other.name), + mStringValue(other.mStringValue), + mDoubleValue(other.mDoubleValue), + mUint64Value(other.mUint64Value), + mInt32Value(other.mInt32Value), + mBoolValue(other.mBoolValue), + mMetadataValue(other.mMetadataValue) { + } +}; + +//! Represents metadata in an glTF object +struct Extras { + std::vector mValues; + + inline bool HasExtras() const { + return mValues.size() != 0; + } + + Extras() = default; + ~Extras() = default; + + Extras(const Extras &other) : + 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 @@ -386,7 +431,7 @@ struct Object { std::string name; //!< The user-defined name of this object CustomExtension customExtensions; - CustomExtension extras; + Extras extras; //! Objects marked as special are not exported (used to emulate the binary body buffer) virtual bool IsSpecial() const { return false; } diff --git a/code/AssetLib/glTF2/glTF2Asset.inl b/code/AssetLib/glTF2/glTF2Asset.inl index db47915d6..5dc51e7fa 100644 --- a/code/AssetLib/glTF2/glTF2Asset.inl +++ b/code/AssetLib/glTF2/glTF2Asset.inl @@ -139,6 +139,50 @@ inline CustomExtension ReadExtensions(const char *name, Value &obj) { return ret; } +inline ExtrasValue ReadExtrasValue(const char *name, Value &obj) { + ExtrasValue ret; + ret.name = name; + + if (obj.IsObject()) { + ret.mMetadataValue.value.reserve(obj.MemberCount()); + ret.mMetadataValue.isPresent = true; + for (auto it = obj.MemberBegin(); it != obj.MemberEnd(); ++it) { + auto &val = it->value; + ret.mMetadataValue.value.push_back(ReadExtrasValue(it->name.GetString(), val)); + } + } else if (obj.IsNumber()) { + if (obj.IsUint64()) { + ret.mUint64Value.value = obj.GetUint64(); + ret.mUint64Value.isPresent = true; + } else if (obj.IsInt()) { + ret.mInt32Value.value = obj.GetInt64(); + ret.mInt32Value.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 Extras ReadExtras(Value &obj) { + Extras ret; + + ret.mValues.reserve(obj.MemberCount()); + for (auto it = obj.MemberBegin(); it != obj.MemberEnd(); ++it) { + auto &val = it->value; + ret.mValues.push_back(ReadExtrasValue(it->name.GetString(), val)); + } + + return ret; +} + inline void CopyData(size_t count, const uint8_t *src, size_t src_stride, uint8_t *dst, size_t dst_stride) { if (src_stride == dst_stride) { @@ -248,7 +292,7 @@ inline void Object::ReadExtensions(Value &val) { inline void Object::ReadExtras(Value &val) { if (Value *curExtras = FindObject(val, "extras")) { - this->extras = glTF2::ReadExtensions("extras", *curExtras); + this->extras = glTF2::ReadExtras(*curExtras); } } diff --git a/code/AssetLib/glTF2/glTF2AssetWriter.inl b/code/AssetLib/glTF2/glTF2AssetWriter.inl index 0be139595..e1fcaefd4 100644 --- a/code/AssetLib/glTF2/glTF2AssetWriter.inl +++ b/code/AssetLib/glTF2/glTF2AssetWriter.inl @@ -620,6 +620,44 @@ namespace glTF2 { } } + inline void WriteExtrasValue(Value &parent, const ExtrasValue &value, AssetWriter &w) { + Value valueNode; + + if (value.mStringValue.isPresent) { + MakeValue(valueNode, value.mStringValue.value.c_str(), w.mAl); + } else if (value.mDoubleValue.isPresent) { + MakeValue(valueNode, value.mDoubleValue.value, w.mAl); + } else if (value.mUint64Value.isPresent) { + MakeValue(valueNode, value.mUint64Value.value, w.mAl); + } else if (value.mInt32Value.isPresent) { + MakeValue(valueNode, value.mInt32Value.value, w.mAl); + } else if (value.mBoolValue.isPresent) { + MakeValue(valueNode, value.mBoolValue.value, w.mAl); + } else if (value.mMetadataValue.isPresent) { + valueNode.SetObject(); + for (auto const &subvalue : value.mMetadataValue.value) { + WriteExtrasValue(valueNode, subvalue, w); + } + } + + parent.AddMember(StringRef(value.name), valueNode, w.mAl); + } + + inline void WriteExtras(Value &obj, const Extras &extras, AssetWriter &w) { + if (!extras.HasExtras()) { + return; + } + + Value extrasNode; + extrasNode.SetObject(); + + for (auto const &value : extras.mValues) { + WriteExtrasValue(extrasNode, value, w); + } + + obj.AddMember("extras", extrasNode, w.mAl); + } + inline void Write(Value& obj, Node& n, AssetWriter& w) { if (n.matrix.isPresent) { @@ -655,6 +693,8 @@ namespace glTF2 { if(n.skeletons.size()) { AddRefsVector(obj, "skeletons", n.skeletons, w.mAl); } + + WriteExtras(obj, n.extras, w); } inline void Write(Value& /*obj*/, Program& /*b*/, AssetWriter& /*w*/) @@ -728,7 +768,6 @@ namespace glTF2 { } } - inline AssetWriter::AssetWriter(Asset& a) : mDoc() , mAsset(a) diff --git a/code/AssetLib/glTF2/glTF2Exporter.cpp b/code/AssetLib/glTF2/glTF2Exporter.cpp index da7591d52..f8b1995d9 100644 --- a/code/AssetLib/glTF2/glTF2Exporter.cpp +++ b/code/AssetLib/glTF2/glTF2Exporter.cpp @@ -445,6 +445,57 @@ inline Ref ExportData(Asset &a, std::string &meshName, Ref &bu return acc; } +inline void ExportNodeExtras(const aiMetadataEntry &metadataEntry, aiString name, ExtrasValue &value) { + + value.name = name.C_Str(); + switch (metadataEntry.mType) { + case AI_BOOL: + value.mBoolValue.value = *static_cast(metadataEntry.mData); + value.mBoolValue.isPresent = true; + break; + case AI_INT32: + value.mInt32Value.value = *static_cast(metadataEntry.mData); + value.mInt32Value.isPresent = true; + break; + case AI_UINT64: + value.mUint64Value.value = *static_cast(metadataEntry.mData); + value.mUint64Value.isPresent = true; + break; + case AI_FLOAT: + value.mFloatValue.value = *static_cast(metadataEntry.mData); + value.mFloatValue.isPresent = true; + break; + case AI_DOUBLE: + value.mDoubleValue.value = *static_cast(metadataEntry.mData); + value.mDoubleValue.isPresent = true; + break; + case AI_AISTRING: + value.mStringValue.value = static_cast(metadataEntry.mData)->C_Str(); + value.mStringValue.isPresent = true; + break; + case AI_AIMETADATA: + const aiMetadata *subMetadata = static_cast(metadataEntry.mData); + value.mMetadataValue.value.resize(subMetadata->mNumProperties); + value.mMetadataValue.isPresent = true; + + for (unsigned i = 0; i < subMetadata->mNumProperties; ++i) { + ExportNodeExtras(subMetadata->mValues[i], subMetadata->mKeys[i], value.mMetadataValue.value.at(i)); + } + break; + } +} + +inline void ExportNodeExtras(const aiMetadata *metadata, Extras &extras) { + if (metadata == nullptr) { + return; + } + + extras.mValues.resize(metadata->mNumProperties); + for (unsigned int i = 0; i < metadata->mNumProperties; ++i) { + ExportNodeExtras(metadata->mValues[i], metadata->mKeys[i], extras.mValues.at(i)); + } +} + inline void SetSamplerWrap(SamplerWrap &wrap, aiTextureMapMode map) { switch (map) { case aiTextureMapMode_Clamp: @@ -1344,7 +1395,7 @@ unsigned int glTF2Exporter::ExportNodeHierarchy(const aiNode *n) { return node.GetIndex(); } -/* + /* * Export node and recursively calls ExportNode for all children. * Since these nodes are not the root node, we also export the parent Ref */ @@ -1355,6 +1406,10 @@ unsigned int glTF2Exporter::ExportNode(const aiNode *n, Ref &parent) { node->parent = parent; node->name = name; + if (n->mMetaData != nullptr && n->mMetaData->mNumProperties > 0) { + ExportNodeExtras(n->mMetaData, node->extras); + } + if (!n->mTransformation.IsIdentity()) { if (mScene->mNumAnimations > 0 || (mProperties && mProperties->HasPropertyBool("GLTF2_NODE_IN_TRS"))) { aiQuaternion quaternion; diff --git a/code/AssetLib/glTF2/glTF2Importer.cpp b/code/AssetLib/glTF2/glTF2Importer.cpp index 293d3dea7..a14e6ad6f 100644 --- a/code/AssetLib/glTF2/glTF2Importer.cpp +++ b/code/AssetLib/glTF2/glTF2Importer.cpp @@ -1033,11 +1033,33 @@ void ParseExtensions(aiMetadata *metadata, const CustomExtension &extension) { } } -void ParseExtras(aiMetadata *metadata, const CustomExtension &extension) { - if (extension.mValues.isPresent) { - for (auto const &subExtension : extension.mValues.value) { - ParseExtensions(metadata, subExtension); +void ParseExtrasValue(aiMetadata *metadata, const ExtrasValue &value) { + + if (value.mBoolValue.isPresent) { + metadata->Add(value.name, value.mBoolValue.value); + } else if (value.mInt32Value.isPresent) { + metadata->Add(value.name, value.mInt32Value.value); + } else if (value.mUint64Value.isPresent) { + metadata->Add(value.name, value.mUint64Value.value); + } else if (value.mFloatValue.isPresent) { + metadata->Add(value.name, value.mFloatValue.value); + } else if (value.mDoubleValue.isPresent) { + metadata->Add(value.name, value.mDoubleValue.value); + } else if (value.mStringValue.isPresent) { + metadata->Add(value.name, aiString(value.mStringValue.value)); + } else if (value.mMetadataValue.isPresent) { + aiMetadata subMetadata; + for (auto const &subValue : value.mMetadataValue.value) { + ParseExtrasValue(&subMetadata, subValue); } + + metadata->Add(value.name, subMetadata); + } +} + +void ParseExtras(aiMetadata* metadata, const Extras& extras) { + for (auto const &value : extras.mValues) { + ParseExtrasValue(metadata, value); } } @@ -1059,12 +1081,12 @@ aiNode *ImportNode(aiScene *pScene, glTF2::Asset &r, std::vector & } } - if (node.customExtensions || node.extras) { + if (node.customExtensions || !node.extras.HasExtras()) { ainode->mMetaData = new aiMetadata; if (node.customExtensions) { ParseExtensions(ainode->mMetaData, node.customExtensions); } - if (node.extras) { + if (node.extras.HasExtras()) { ParseExtras(ainode->mMetaData, node.extras); } } diff --git a/code/Common/SceneCombiner.cpp b/code/Common/SceneCombiner.cpp index 2c2539e54..1d32436c2 100644 --- a/code/Common/SceneCombiner.cpp +++ b/code/Common/SceneCombiner.cpp @@ -1349,6 +1349,9 @@ void SceneCombiner::Copy(aiMetadata **_dest, const aiMetadata *src) { case AI_AIVECTOR3D: out.mData = new aiVector3D(*static_cast(in.mData)); break; + case AI_AIMETADATA: + out.mData = new aiMetadata(*static_cast(in.mData)); + break; default: ai_assert(false); break; From 233198baefa8be47bbea4235d438e337c8eda0f2 Mon Sep 17 00:00:00 2001 From: Bengt Rosenberger Date: Fri, 22 Jul 2022 01:04:05 +0200 Subject: [PATCH 6/9] Fixed extras presence check in gltf2 import. --- code/AssetLib/glTF2/glTF2Exporter.cpp | 6 ++---- code/AssetLib/glTF2/glTF2Importer.cpp | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/code/AssetLib/glTF2/glTF2Exporter.cpp b/code/AssetLib/glTF2/glTF2Exporter.cpp index f8b1995d9..d3c88e479 100644 --- a/code/AssetLib/glTF2/glTF2Exporter.cpp +++ b/code/AssetLib/glTF2/glTF2Exporter.cpp @@ -486,7 +486,7 @@ inline void ExportNodeExtras(const aiMetadataEntry &metadataEntry, aiString name } inline void ExportNodeExtras(const aiMetadata *metadata, Extras &extras) { - if (metadata == nullptr) { + if (metadata == nullptr || metadata->mNumProperties == 0) { return; } @@ -1406,9 +1406,7 @@ unsigned int glTF2Exporter::ExportNode(const aiNode *n, Ref &parent) { node->parent = parent; node->name = name; - if (n->mMetaData != nullptr && n->mMetaData->mNumProperties > 0) { - ExportNodeExtras(n->mMetaData, node->extras); - } + ExportNodeExtras(n->mMetaData, node->extras); if (!n->mTransformation.IsIdentity()) { if (mScene->mNumAnimations > 0 || (mProperties && mProperties->HasPropertyBool("GLTF2_NODE_IN_TRS"))) { diff --git a/code/AssetLib/glTF2/glTF2Importer.cpp b/code/AssetLib/glTF2/glTF2Importer.cpp index a14e6ad6f..e88cd0f08 100644 --- a/code/AssetLib/glTF2/glTF2Importer.cpp +++ b/code/AssetLib/glTF2/glTF2Importer.cpp @@ -1081,7 +1081,7 @@ aiNode *ImportNode(aiScene *pScene, glTF2::Asset &r, std::vector & } } - if (node.customExtensions || !node.extras.HasExtras()) { + if (node.customExtensions || node.extras.HasExtras()) { ainode->mMetaData = new aiMetadata; if (node.customExtensions) { ParseExtensions(ainode->mMetaData, node.customExtensions); From cb4d0ab7aa497f0ab4ac53e4ace079a7eb53d95f Mon Sep 17 00:00:00 2001 From: Bengt Rosenberger Date: Fri, 22 Jul 2022 01:07:42 +0200 Subject: [PATCH 7/9] Added missing member copy in gltf2::ExtrasValue ctor. --- code/AssetLib/glTF2/glTF2Asset.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/code/AssetLib/glTF2/glTF2Asset.h b/code/AssetLib/glTF2/glTF2Asset.h index a4a615131..722e6d119 100644 --- a/code/AssetLib/glTF2/glTF2Asset.h +++ b/code/AssetLib/glTF2/glTF2Asset.h @@ -378,9 +378,7 @@ struct CustomExtension { CustomExtension& operator=(const CustomExtension&) = default; }; -struct ExtrasValue; - -//! Represents a union of metadata values +//! Represents a union of metadata values. Only one nullable is supposed to be set. struct ExtrasValue { std::string name; @@ -398,6 +396,7 @@ struct ExtrasValue { ExtrasValue(const ExtrasValue& other) : name(other.name), mStringValue(other.mStringValue), + mFloatValue(other.mFloatValue), mDoubleValue(other.mDoubleValue), mUint64Value(other.mUint64Value), mInt32Value(other.mInt32Value), @@ -406,7 +405,7 @@ struct ExtrasValue { } }; -//! Represents metadata in an glTF object +//! Represents metadata in an glTF2 object struct Extras { std::vector mValues; From da58fbe8fbe3252b5406cdfd2be6562d9d14ce69 Mon Sep 17 00:00:00 2001 From: Bengt Rosenberger Date: Fri, 22 Jul 2022 01:33:05 +0200 Subject: [PATCH 8/9] Got rid of gltf2::ExtrasValue and used gltf2::CustomExtension instead --- code/AssetLib/glTF2/glTF2Asset.h | 29 +------------------- code/AssetLib/glTF2/glTF2Asset.inl | 34 +----------------------- code/AssetLib/glTF2/glTF2AssetWriter.inl | 10 +++---- code/AssetLib/glTF2/glTF2Exporter.cpp | 16 +++++------ code/AssetLib/glTF2/glTF2Importer.cpp | 26 +----------------- 5 files changed, 14 insertions(+), 101 deletions(-) diff --git a/code/AssetLib/glTF2/glTF2Asset.h b/code/AssetLib/glTF2/glTF2Asset.h index 722e6d119..1aa37b569 100644 --- a/code/AssetLib/glTF2/glTF2Asset.h +++ b/code/AssetLib/glTF2/glTF2Asset.h @@ -378,36 +378,9 @@ struct CustomExtension { CustomExtension& operator=(const CustomExtension&) = default; }; -//! Represents a union of metadata values. Only one nullable is supposed to be set. -struct ExtrasValue { - std::string name; - - Nullable mBoolValue; - Nullable mInt32Value; - Nullable mUint64Value; - Nullable mFloatValue; - Nullable mDoubleValue; - Nullable mStringValue; - Nullable> mMetadataValue; - - ExtrasValue() = default; - ~ExtrasValue() = default; - - ExtrasValue(const ExtrasValue& other) : - name(other.name), - mStringValue(other.mStringValue), - mFloatValue(other.mFloatValue), - mDoubleValue(other.mDoubleValue), - mUint64Value(other.mUint64Value), - mInt32Value(other.mInt32Value), - mBoolValue(other.mBoolValue), - mMetadataValue(other.mMetadataValue) { - } -}; - //! Represents metadata in an glTF2 object struct Extras { - std::vector mValues; + std::vector mValues; inline bool HasExtras() const { return mValues.size() != 0; diff --git a/code/AssetLib/glTF2/glTF2Asset.inl b/code/AssetLib/glTF2/glTF2Asset.inl index 5dc51e7fa..3a7d127d3 100644 --- a/code/AssetLib/glTF2/glTF2Asset.inl +++ b/code/AssetLib/glTF2/glTF2Asset.inl @@ -139,45 +139,13 @@ inline CustomExtension ReadExtensions(const char *name, Value &obj) { return ret; } -inline ExtrasValue ReadExtrasValue(const char *name, Value &obj) { - ExtrasValue ret; - ret.name = name; - - if (obj.IsObject()) { - ret.mMetadataValue.value.reserve(obj.MemberCount()); - ret.mMetadataValue.isPresent = true; - for (auto it = obj.MemberBegin(); it != obj.MemberEnd(); ++it) { - auto &val = it->value; - ret.mMetadataValue.value.push_back(ReadExtrasValue(it->name.GetString(), val)); - } - } else if (obj.IsNumber()) { - if (obj.IsUint64()) { - ret.mUint64Value.value = obj.GetUint64(); - ret.mUint64Value.isPresent = true; - } else if (obj.IsInt()) { - ret.mInt32Value.value = obj.GetInt64(); - ret.mInt32Value.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 Extras ReadExtras(Value &obj) { Extras ret; ret.mValues.reserve(obj.MemberCount()); for (auto it = obj.MemberBegin(); it != obj.MemberEnd(); ++it) { auto &val = it->value; - ret.mValues.push_back(ReadExtrasValue(it->name.GetString(), val)); + ret.mValues.push_back(ReadExtensions(it->name.GetString(), val)); } return ret; diff --git a/code/AssetLib/glTF2/glTF2AssetWriter.inl b/code/AssetLib/glTF2/glTF2AssetWriter.inl index e1fcaefd4..3acec58a5 100644 --- a/code/AssetLib/glTF2/glTF2AssetWriter.inl +++ b/code/AssetLib/glTF2/glTF2AssetWriter.inl @@ -620,7 +620,7 @@ namespace glTF2 { } } - inline void WriteExtrasValue(Value &parent, const ExtrasValue &value, AssetWriter &w) { + inline void WriteExtrasValue(Value &parent, const CustomExtension &value, AssetWriter &w) { Value valueNode; if (value.mStringValue.isPresent) { @@ -629,13 +629,13 @@ namespace glTF2 { MakeValue(valueNode, value.mDoubleValue.value, w.mAl); } else if (value.mUint64Value.isPresent) { MakeValue(valueNode, value.mUint64Value.value, w.mAl); - } else if (value.mInt32Value.isPresent) { - MakeValue(valueNode, value.mInt32Value.value, w.mAl); + } else if (value.mInt64Value.isPresent) { + MakeValue(valueNode, value.mInt64Value.value, w.mAl); } else if (value.mBoolValue.isPresent) { MakeValue(valueNode, value.mBoolValue.value, w.mAl); - } else if (value.mMetadataValue.isPresent) { + } else if (value.mValues.isPresent) { valueNode.SetObject(); - for (auto const &subvalue : value.mMetadataValue.value) { + for (auto const &subvalue : value.mValues.value) { WriteExtrasValue(valueNode, subvalue, w); } } diff --git a/code/AssetLib/glTF2/glTF2Exporter.cpp b/code/AssetLib/glTF2/glTF2Exporter.cpp index d3c88e479..028ab5c17 100644 --- a/code/AssetLib/glTF2/glTF2Exporter.cpp +++ b/code/AssetLib/glTF2/glTF2Exporter.cpp @@ -445,7 +445,7 @@ inline Ref ExportData(Asset &a, std::string &meshName, Ref &bu return acc; } -inline void ExportNodeExtras(const aiMetadataEntry &metadataEntry, aiString name, ExtrasValue &value) { +inline void ExportNodeExtras(const aiMetadataEntry &metadataEntry, aiString name, CustomExtension &value) { value.name = name.C_Str(); switch (metadataEntry.mType) { @@ -454,17 +454,13 @@ inline void ExportNodeExtras(const aiMetadataEntry &metadataEntry, aiString name value.mBoolValue.isPresent = true; break; case AI_INT32: - value.mInt32Value.value = *static_cast(metadataEntry.mData); - value.mInt32Value.isPresent = true; + value.mInt64Value.value = *static_cast(metadataEntry.mData); + value.mInt64Value.isPresent = true; break; case AI_UINT64: value.mUint64Value.value = *static_cast(metadataEntry.mData); value.mUint64Value.isPresent = true; break; - case AI_FLOAT: - value.mFloatValue.value = *static_cast(metadataEntry.mData); - value.mFloatValue.isPresent = true; - break; case AI_DOUBLE: value.mDoubleValue.value = *static_cast(metadataEntry.mData); value.mDoubleValue.isPresent = true; @@ -475,11 +471,11 @@ inline void ExportNodeExtras(const aiMetadataEntry &metadataEntry, aiString name break; case AI_AIMETADATA: const aiMetadata *subMetadata = static_cast(metadataEntry.mData); - value.mMetadataValue.value.resize(subMetadata->mNumProperties); - value.mMetadataValue.isPresent = true; + value.mValues.value.resize(subMetadata->mNumProperties); + value.mValues.isPresent = true; for (unsigned i = 0; i < subMetadata->mNumProperties; ++i) { - ExportNodeExtras(subMetadata->mValues[i], subMetadata->mKeys[i], value.mMetadataValue.value.at(i)); + ExportNodeExtras(subMetadata->mValues[i], subMetadata->mKeys[i], value.mValues.value.at(i)); } break; } diff --git a/code/AssetLib/glTF2/glTF2Importer.cpp b/code/AssetLib/glTF2/glTF2Importer.cpp index e88cd0f08..f34465444 100644 --- a/code/AssetLib/glTF2/glTF2Importer.cpp +++ b/code/AssetLib/glTF2/glTF2Importer.cpp @@ -1033,33 +1033,9 @@ void ParseExtensions(aiMetadata *metadata, const CustomExtension &extension) { } } -void ParseExtrasValue(aiMetadata *metadata, const ExtrasValue &value) { - - if (value.mBoolValue.isPresent) { - metadata->Add(value.name, value.mBoolValue.value); - } else if (value.mInt32Value.isPresent) { - metadata->Add(value.name, value.mInt32Value.value); - } else if (value.mUint64Value.isPresent) { - metadata->Add(value.name, value.mUint64Value.value); - } else if (value.mFloatValue.isPresent) { - metadata->Add(value.name, value.mFloatValue.value); - } else if (value.mDoubleValue.isPresent) { - metadata->Add(value.name, value.mDoubleValue.value); - } else if (value.mStringValue.isPresent) { - metadata->Add(value.name, aiString(value.mStringValue.value)); - } else if (value.mMetadataValue.isPresent) { - aiMetadata subMetadata; - for (auto const &subValue : value.mMetadataValue.value) { - ParseExtrasValue(&subMetadata, subValue); - } - - metadata->Add(value.name, subMetadata); - } -} - void ParseExtras(aiMetadata* metadata, const Extras& extras) { for (auto const &value : extras.mValues) { - ParseExtrasValue(metadata, value); + ParseExtensions(metadata, value); } } From abfe8ad413f031c144b4b4bdf00e7541092a9135 Mon Sep 17 00:00:00 2001 From: Bengt Rosenberger Date: Mon, 1 Aug 2022 14:39:10 +0200 Subject: [PATCH 9/9] Added suggested changes and fixed automated check errors --- code/AssetLib/glTF2/glTF2Asset.h | 27 +-------------------------- code/AssetLib/glTF2/glTF2Asset.inl | 2 +- code/AssetLib/glTF2/glTF2Exporter.cpp | 10 +++++++++- 3 files changed, 11 insertions(+), 28 deletions(-) diff --git a/code/AssetLib/glTF2/glTF2Asset.h b/code/AssetLib/glTF2/glTF2Asset.h index 1a44b8377..754d6b593 100644 --- a/code/AssetLib/glTF2/glTF2Asset.h +++ b/code/AssetLib/glTF2/glTF2Asset.h @@ -383,32 +383,7 @@ struct Extras { std::vector mValues; inline bool HasExtras() const { - return mValues.size() != 0; - } - - Extras() = default; - ~Extras() = default; - - Extras(const Extras &other) : - mValues(other.mValues) { - // empty - } -}; - -//! Represents metadata in an glTF2 object -struct Extras { - std::vector mValues; - - inline bool HasExtras() const { - return mValues.size() != 0; - } - - Extras() = default; - ~Extras() = default; - - Extras(const Extras &other) : - mValues(other.mValues) { - // empty + return !mValues.empty(); } }; diff --git a/code/AssetLib/glTF2/glTF2Asset.inl b/code/AssetLib/glTF2/glTF2Asset.inl index 3a7d127d3..891fa27b5 100644 --- a/code/AssetLib/glTF2/glTF2Asset.inl +++ b/code/AssetLib/glTF2/glTF2Asset.inl @@ -145,7 +145,7 @@ inline Extras ReadExtras(Value &obj) { ret.mValues.reserve(obj.MemberCount()); for (auto it = obj.MemberBegin(); it != obj.MemberEnd(); ++it) { auto &val = it->value; - ret.mValues.push_back(ReadExtensions(it->name.GetString(), val)); + ret.mValues.emplace_back(ReadExtensions(it->name.GetString(), val)); } return ret; diff --git a/code/AssetLib/glTF2/glTF2Exporter.cpp b/code/AssetLib/glTF2/glTF2Exporter.cpp index 028ab5c17..2996a8805 100644 --- a/code/AssetLib/glTF2/glTF2Exporter.cpp +++ b/code/AssetLib/glTF2/glTF2Exporter.cpp @@ -461,6 +461,10 @@ inline void ExportNodeExtras(const aiMetadataEntry &metadataEntry, aiString name value.mUint64Value.value = *static_cast(metadataEntry.mData); value.mUint64Value.isPresent = true; break; + case AI_FLOAT: + value.mDoubleValue.value = *static_cast(metadataEntry.mData); + value.mDoubleValue.isPresent = true; + break; case AI_DOUBLE: value.mDoubleValue.value = *static_cast(metadataEntry.mData); value.mDoubleValue.isPresent = true; @@ -469,7 +473,7 @@ inline void ExportNodeExtras(const aiMetadataEntry &metadataEntry, aiString name value.mStringValue.value = static_cast(metadataEntry.mData)->C_Str(); value.mStringValue.isPresent = true; break; - case AI_AIMETADATA: + case AI_AIMETADATA: { const aiMetadata *subMetadata = static_cast(metadataEntry.mData); value.mValues.value.resize(subMetadata->mNumProperties); value.mValues.isPresent = true; @@ -479,6 +483,10 @@ inline void ExportNodeExtras(const aiMetadataEntry &metadataEntry, aiString name } break; } + default: + // AI_AIVECTOR3D not handled + break; + } } inline void ExportNodeExtras(const aiMetadata *metadata, Extras &extras) {