Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C tech development corp gltf2 metadata export #5109

Merged
merged 13 commits into from May 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 10 additions & 1 deletion code/AssetLib/glTF2/glTF2Asset.h
Expand Up @@ -371,6 +371,15 @@ struct CustomExtension {
CustomExtension& operator=(const CustomExtension&) = default;
};

//! Represents metadata in an glTF2 object
struct Extras {
std::vector<CustomExtension> mValues;

inline bool HasExtras() const {
return !mValues.empty();
}
};

//! Base class for all glTF top-level objects
struct Object {
int index; //!< The index of this object within its property container
Expand All @@ -379,7 +388,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; }
Expand Down
14 changes: 13 additions & 1 deletion code/AssetLib/glTF2/glTF2Asset.inl
Expand Up @@ -139,6 +139,18 @@ inline CustomExtension ReadExtensions(const char *name, Value &obj) {
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.emplace_back(ReadExtensions(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) {
Expand Down Expand Up @@ -248,7 +260,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);
}
}

Expand Down
41 changes: 40 additions & 1 deletion code/AssetLib/glTF2/glTF2AssetWriter.inl
Expand Up @@ -654,6 +654,44 @@ namespace glTF2 {
}
}

inline void WriteExtrasValue(Value &parent, const CustomExtension &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.mInt64Value.isPresent) {
MakeValue(valueNode, value.mInt64Value.value, w.mAl);
} else if (value.mBoolValue.isPresent) {
MakeValue(valueNode, value.mBoolValue.value, w.mAl);
} else if (value.mValues.isPresent) {
valueNode.SetObject();
for (auto const &subvalue : value.mValues.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) {
Expand Down Expand Up @@ -689,6 +727,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*/)
Expand Down Expand Up @@ -762,7 +802,6 @@ namespace glTF2 {
}
}


inline AssetWriter::AssetWriter(Asset& a)
: mDoc()
, mAsset(a)
Expand Down
59 changes: 58 additions & 1 deletion code/AssetLib/glTF2/glTF2Exporter.cpp
Expand Up @@ -443,6 +443,61 @@ inline Ref<Accessor> ExportData(Asset &a, std::string &meshName, Ref<Buffer> &bu
return acc;
}

inline void ExportNodeExtras(const aiMetadataEntry &metadataEntry, aiString name, CustomExtension &value) {

value.name = name.C_Str();
switch (metadataEntry.mType) {
case AI_BOOL:
value.mBoolValue.value = *static_cast<bool *>(metadataEntry.mData);
value.mBoolValue.isPresent = true;
break;
case AI_INT32:
value.mInt64Value.value = *static_cast<int32_t *>(metadataEntry.mData);
value.mInt64Value.isPresent = true;
break;
case AI_UINT64:
value.mUint64Value.value = *static_cast<uint64_t *>(metadataEntry.mData);
value.mUint64Value.isPresent = true;
break;
case AI_FLOAT:
value.mDoubleValue.value = *static_cast<float *>(metadataEntry.mData);
value.mDoubleValue.isPresent = true;
break;
case AI_DOUBLE:
value.mDoubleValue.value = *static_cast<double *>(metadataEntry.mData);
value.mDoubleValue.isPresent = true;
break;
case AI_AISTRING:
value.mStringValue.value = static_cast<aiString *>(metadataEntry.mData)->C_Str();
value.mStringValue.isPresent = true;
break;
case AI_AIMETADATA: {
const aiMetadata *subMetadata = static_cast<aiMetadata *>(metadataEntry.mData);
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.mValues.value.at(i));
}
break;
}
default:
// AI_AIVECTOR3D not handled
break;
}
}

inline void ExportNodeExtras(const aiMetadata *metadata, Extras &extras) {
if (metadata == nullptr || metadata->mNumProperties == 0) {
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:
Expand Down Expand Up @@ -1375,7 +1430,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<Node>
*/
Expand All @@ -1386,6 +1441,8 @@ unsigned int glTF2Exporter::ExportNode(const aiNode *n, Ref<Node> &parent) {
node->parent = parent;
node->name = name;

ExportNodeExtras(n->mMetaData, node->extras);

if (!n->mTransformation.IsIdentity()) {
if (mScene->mNumAnimations > 0 || (mProperties && mProperties->HasPropertyBool("GLTF2_NODE_IN_TRS"))) {
aiQuaternion quaternion;
Expand Down
12 changes: 5 additions & 7 deletions code/AssetLib/glTF2/glTF2Importer.cpp
Expand Up @@ -1103,11 +1103,9 @@ 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 ParseExtras(aiMetadata* metadata, const Extras& extras) {
for (auto const &value : extras.mValues) {
ParseExtensions(metadata, value);
}
}

Expand All @@ -1129,12 +1127,12 @@ aiNode *ImportNode(aiScene *pScene, glTF2::Asset &r, std::vector<unsigned int> &
}
}

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);
}
}
Expand Down