From 5282f693f989b3c70976a22a3defca2fa9081b83 Mon Sep 17 00:00:00 2001 From: Artem Titoulenko Date: Tue, 25 Sep 2018 19:09:18 -0400 Subject: [PATCH] Blend shape keys to accessor names (#122) Map blendshape keys to accessor names --- src/fbx/Fbx2Raw.cpp | 4 +++- src/fbx/FbxBlendShapesAccess.cpp | 13 ++++++++++--- src/fbx/FbxBlendShapesAccess.hpp | 4 +++- src/gltf/GltfModel.hpp | 12 ++++++++++-- src/gltf/Raw2Gltf.cpp | 20 +++++++++++++++----- src/gltf/properties/AccessorData.cpp | 8 ++++++-- src/gltf/properties/AccessorData.hpp | 3 ++- src/raw/RawModel.hpp | 1 + 8 files changed, 50 insertions(+), 15 deletions(-) diff --git a/src/fbx/Fbx2Raw.cpp b/src/fbx/Fbx2Raw.cpp index 504bd60..5a771c7 100644 --- a/src/fbx/Fbx2Raw.cpp +++ b/src/fbx/Fbx2Raw.cpp @@ -155,11 +155,13 @@ static void ReadMesh(RawModel &raw, FbxScene *pScene, FbxNode *pNode, const std: for (size_t targetIx = 0; targetIx < blendShapes.GetTargetShapeCount(channelIx); targetIx ++) { const FbxBlendShapesAccess::TargetShape &shape = blendShapes.GetTargetShape(channelIx, targetIx); targetShapes.push_back(&shape); + auto &blendChannel = blendShapes.GetBlendChannel(channelIx); rawSurface.blendChannels.push_back(RawBlendChannel { - static_cast(blendShapes.GetBlendChannel(channelIx).deformPercent), + static_cast(blendChannel.deformPercent), shape.normals.LayerPresent(), shape.tangents.LayerPresent(), + blendChannel.name }); } } diff --git a/src/fbx/FbxBlendShapesAccess.cpp b/src/fbx/FbxBlendShapesAccess.cpp index 141f8c4..ad8d263 100644 --- a/src/fbx/FbxBlendShapesAccess.cpp +++ b/src/fbx/FbxBlendShapesAccess.cpp @@ -27,11 +27,12 @@ FbxAnimCurve *FbxBlendShapesAccess::BlendChannel::ExtractAnimation(unsigned int FbxBlendShapesAccess::BlendChannel::BlendChannel( FbxMesh *mesh, const unsigned int blendShapeIx, const unsigned int channelIx, const FbxDouble deformPercent, - const std::vector &targetShapes) : mesh(mesh), + const std::vector &targetShapes, std::string name) : mesh(mesh), blendShapeIx(blendShapeIx), channelIx(channelIx), deformPercent(deformPercent), - targetShapes(targetShapes) + targetShapes(targetShapes), + name(name) {} std::vector FbxBlendShapesAccess::extractChannels(FbxMesh *mesh) const @@ -46,11 +47,17 @@ std::vector FbxBlendShapesAccess::extractCha if (fbxChannel->GetTargetShapeCount() > 0) { std::vector targetShapes; const double *fullWeights = fbxChannel->GetTargetShapeFullWeights(); + std::string name = std::string(fbxChannel->GetName()); + + if (verboseOutput) { + fmt::printf("\rblendshape channel: %s\n", name); + } + for (int targetIx = 0; targetIx < fbxChannel->GetTargetShapeCount(); targetIx ++) { FbxShape *fbxShape = fbxChannel->GetTargetShape(targetIx); targetShapes.emplace_back(fbxShape, fullWeights[targetIx]); } - channels.emplace_back(mesh, shapeIx, channelIx, fbxChannel->DeformPercent * 0.01, targetShapes); + channels.emplace_back(mesh, shapeIx, channelIx, fbxChannel->DeformPercent * 0.01, targetShapes, name); } } } diff --git a/src/fbx/FbxBlendShapesAccess.hpp b/src/fbx/FbxBlendShapesAccess.hpp index 484fd06..aea1352 100644 --- a/src/fbx/FbxBlendShapesAccess.hpp +++ b/src/fbx/FbxBlendShapesAccess.hpp @@ -64,7 +64,8 @@ public: const unsigned int blendShapeIx, const unsigned int channelIx, const FbxDouble deformPercent, - const std::vector &targetShapes + const std::vector &targetShapes, + const std::string name ); FbxAnimCurve *ExtractAnimation(unsigned int animIx) const; @@ -74,6 +75,7 @@ public: const unsigned int blendShapeIx; const unsigned int channelIx; const std::vector targetShapes; + const std::string name; const FbxDouble deformPercent; }; diff --git a/src/gltf/GltfModel.hpp b/src/gltf/GltfModel.hpp index ec4c05c..9ec17af 100644 --- a/src/gltf/GltfModel.hpp +++ b/src/gltf/GltfModel.hpp @@ -97,7 +97,7 @@ struct GltfModel template std::shared_ptr AddAccessorWithView( - BufferViewData &bufferView, const GLType &type, const std::vector &source) + BufferViewData &bufferView, const GLType &type, const std::vector &source, std::string name) { auto accessor = accessors.hold(new AccessorData(bufferView, type)); accessor->appendAsBinaryArray(source, *binary); @@ -110,7 +110,15 @@ struct GltfModel BufferData &buffer, const GLType &type, const std::vector &source) { auto bufferView = GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_NONE); - return AddAccessorWithView(*bufferView, type, source); + return AddAccessorWithView(*bufferView, type, source, std::string("")); + } + + template + std::shared_ptr AddAccessorAndView( + BufferData &buffer, const GLType &type, const std::vector &source, std::string name) + { + auto bufferView = GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_NONE); + return AddAccessorWithView(*bufferView, type, source, name); } template diff --git a/src/gltf/Raw2Gltf.cpp b/src/gltf/Raw2Gltf.cpp index 853a741..17f4309 100644 --- a/src/gltf/Raw2Gltf.cpp +++ b/src/gltf/Raw2Gltf.cpp @@ -124,12 +124,22 @@ struct GLTFData return result; } - template std::shared_ptr AddAccessorWithView( BufferViewData &bufferView, const GLType &type, const std::vector &source) { - auto accessor = accessors.hold(new AccessorData(bufferView, type)); + auto accessor = accessors.hold(new AccessorData(bufferView, type, std::string(""))); + accessor->appendAsBinaryArray(source, *binary); + bufferView.byteLength = accessor->byteLength(); + return accessor; + } + + + template + std::shared_ptr AddAccessorWithView( + BufferViewData &bufferView, const GLType &type, const std::vector &source, std::string name) + { + auto accessor = accessors.hold(new AccessorData(bufferView, type, name)); accessor->appendAsBinaryArray(source, *binary); bufferView.byteLength = accessor->byteLength(); return accessor; @@ -920,7 +930,7 @@ ModelData *Raw2Gltf( } std::shared_ptr pAcc = gltf->AddAccessorWithView( *gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_BUFFER), - GLT_VEC3F, positions); + GLT_VEC3F, positions, channel.name); pAcc->min = toStdVec(shapeBounds.min); pAcc->max = toStdVec(shapeBounds.max); @@ -928,14 +938,14 @@ ModelData *Raw2Gltf( if (!normals.empty()) { nAcc = gltf->AddAccessorWithView( *gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_BUFFER), - GLT_VEC3F, normals); + GLT_VEC3F, normals, channel.name); } std::shared_ptr tAcc; if (!tangents.empty()) { nAcc = gltf->AddAccessorWithView( *gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_BUFFER), - GLT_VEC4F, tangents); + GLT_VEC4F, tangents, channel.name); } primitive->AddTarget(pAcc.get(), nAcc.get(), tAcc.get()); diff --git a/src/gltf/properties/AccessorData.cpp b/src/gltf/properties/AccessorData.cpp index 6c33b67..64ea1f1 100644 --- a/src/gltf/properties/AccessorData.cpp +++ b/src/gltf/properties/AccessorData.cpp @@ -10,12 +10,13 @@ #include "AccessorData.hpp" #include "BufferViewData.hpp" -AccessorData::AccessorData(const BufferViewData &bufferView, GLType type) +AccessorData::AccessorData(const BufferViewData &bufferView, GLType type, std::string name) : Holdable(), bufferView(bufferView.ix), type(std::move(type)), byteOffset(0), - count(0) + count(0), + name(name) { } @@ -45,5 +46,8 @@ json AccessorData::serialize() const if (!max.empty()) { result["max"] = max; } + if (name.length() > 0) { + result["name"] = name; + } return result; } diff --git a/src/gltf/properties/AccessorData.hpp b/src/gltf/properties/AccessorData.hpp index 1a7edec..685bc11 100644 --- a/src/gltf/properties/AccessorData.hpp +++ b/src/gltf/properties/AccessorData.hpp @@ -13,7 +13,7 @@ struct AccessorData : Holdable { - AccessorData(const BufferViewData &bufferView, GLType type); + AccessorData(const BufferViewData &bufferView, GLType type, std::string name); explicit AccessorData(GLType type); json serialize() const override; @@ -42,4 +42,5 @@ struct AccessorData : Holdable unsigned int count; std::vector min; std::vector max; + std::string name; }; diff --git a/src/raw/RawModel.hpp b/src/raw/RawModel.hpp index 1380dfa..61c6797 100644 --- a/src/raw/RawModel.hpp +++ b/src/raw/RawModel.hpp @@ -331,6 +331,7 @@ struct RawBlendChannel float defaultDeform; bool hasNormals; bool hasTangents; + std::string name; }; struct RawSurface