Blend shape keys to accessor names (#122)

Map blendshape keys to accessor names
This commit is contained in:
Artem Titoulenko 2018-09-25 19:09:18 -04:00 committed by Pär Winzell
parent 52de0d20d8
commit 5282f693f9
8 changed files with 50 additions and 15 deletions

View File

@ -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 ++) { for (size_t targetIx = 0; targetIx < blendShapes.GetTargetShapeCount(channelIx); targetIx ++) {
const FbxBlendShapesAccess::TargetShape &shape = blendShapes.GetTargetShape(channelIx, targetIx); const FbxBlendShapesAccess::TargetShape &shape = blendShapes.GetTargetShape(channelIx, targetIx);
targetShapes.push_back(&shape); targetShapes.push_back(&shape);
auto &blendChannel = blendShapes.GetBlendChannel(channelIx);
rawSurface.blendChannels.push_back(RawBlendChannel { rawSurface.blendChannels.push_back(RawBlendChannel {
static_cast<float>(blendShapes.GetBlendChannel(channelIx).deformPercent), static_cast<float>(blendChannel.deformPercent),
shape.normals.LayerPresent(), shape.normals.LayerPresent(),
shape.tangents.LayerPresent(), shape.tangents.LayerPresent(),
blendChannel.name
}); });
} }
} }

View File

@ -27,11 +27,12 @@ FbxAnimCurve *FbxBlendShapesAccess::BlendChannel::ExtractAnimation(unsigned int
FbxBlendShapesAccess::BlendChannel::BlendChannel( FbxBlendShapesAccess::BlendChannel::BlendChannel(
FbxMesh *mesh, const unsigned int blendShapeIx, const unsigned int channelIx, const FbxDouble deformPercent, FbxMesh *mesh, const unsigned int blendShapeIx, const unsigned int channelIx, const FbxDouble deformPercent,
const std::vector<FbxBlendShapesAccess::TargetShape> &targetShapes) : mesh(mesh), const std::vector<FbxBlendShapesAccess::TargetShape> &targetShapes, std::string name) : mesh(mesh),
blendShapeIx(blendShapeIx), blendShapeIx(blendShapeIx),
channelIx(channelIx), channelIx(channelIx),
deformPercent(deformPercent), deformPercent(deformPercent),
targetShapes(targetShapes) targetShapes(targetShapes),
name(name)
{} {}
std::vector<FbxBlendShapesAccess::BlendChannel> FbxBlendShapesAccess::extractChannels(FbxMesh *mesh) const std::vector<FbxBlendShapesAccess::BlendChannel> FbxBlendShapesAccess::extractChannels(FbxMesh *mesh) const
@ -46,11 +47,17 @@ std::vector<FbxBlendShapesAccess::BlendChannel> FbxBlendShapesAccess::extractCha
if (fbxChannel->GetTargetShapeCount() > 0) { if (fbxChannel->GetTargetShapeCount() > 0) {
std::vector<TargetShape> targetShapes; std::vector<TargetShape> targetShapes;
const double *fullWeights = fbxChannel->GetTargetShapeFullWeights(); 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 ++) { for (int targetIx = 0; targetIx < fbxChannel->GetTargetShapeCount(); targetIx ++) {
FbxShape *fbxShape = fbxChannel->GetTargetShape(targetIx); FbxShape *fbxShape = fbxChannel->GetTargetShape(targetIx);
targetShapes.emplace_back(fbxShape, fullWeights[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);
} }
} }
} }

View File

@ -64,7 +64,8 @@ public:
const unsigned int blendShapeIx, const unsigned int blendShapeIx,
const unsigned int channelIx, const unsigned int channelIx,
const FbxDouble deformPercent, const FbxDouble deformPercent,
const std::vector<TargetShape> &targetShapes const std::vector<TargetShape> &targetShapes,
const std::string name
); );
FbxAnimCurve *ExtractAnimation(unsigned int animIx) const; FbxAnimCurve *ExtractAnimation(unsigned int animIx) const;
@ -74,6 +75,7 @@ public:
const unsigned int blendShapeIx; const unsigned int blendShapeIx;
const unsigned int channelIx; const unsigned int channelIx;
const std::vector<TargetShape> targetShapes; const std::vector<TargetShape> targetShapes;
const std::string name;
const FbxDouble deformPercent; const FbxDouble deformPercent;
}; };

View File

@ -97,7 +97,7 @@ struct GltfModel
template<class T> template<class T>
std::shared_ptr<AccessorData> AddAccessorWithView( std::shared_ptr<AccessorData> AddAccessorWithView(
BufferViewData &bufferView, const GLType &type, const std::vector<T> &source) BufferViewData &bufferView, const GLType &type, const std::vector<T> &source, std::string name)
{ {
auto accessor = accessors.hold(new AccessorData(bufferView, type)); auto accessor = accessors.hold(new AccessorData(bufferView, type));
accessor->appendAsBinaryArray(source, *binary); accessor->appendAsBinaryArray(source, *binary);
@ -110,7 +110,15 @@ struct GltfModel
BufferData &buffer, const GLType &type, const std::vector<T> &source) BufferData &buffer, const GLType &type, const std::vector<T> &source)
{ {
auto bufferView = GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_NONE); auto bufferView = GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_NONE);
return AddAccessorWithView(*bufferView, type, source); return AddAccessorWithView(*bufferView, type, source, std::string(""));
}
template<class T>
std::shared_ptr<AccessorData> AddAccessorAndView(
BufferData &buffer, const GLType &type, const std::vector<T> &source, std::string name)
{
auto bufferView = GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_NONE);
return AddAccessorWithView(*bufferView, type, source, name);
} }
template<class T> template<class T>

View File

@ -124,12 +124,22 @@ struct GLTFData
return result; return result;
} }
template<class T> template<class T>
std::shared_ptr<AccessorData> AddAccessorWithView( std::shared_ptr<AccessorData> AddAccessorWithView(
BufferViewData &bufferView, const GLType &type, const std::vector<T> &source) BufferViewData &bufferView, const GLType &type, const std::vector<T> &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<class T>
std::shared_ptr<AccessorData> AddAccessorWithView(
BufferViewData &bufferView, const GLType &type, const std::vector<T> &source, std::string name)
{
auto accessor = accessors.hold(new AccessorData(bufferView, type, name));
accessor->appendAsBinaryArray(source, *binary); accessor->appendAsBinaryArray(source, *binary);
bufferView.byteLength = accessor->byteLength(); bufferView.byteLength = accessor->byteLength();
return accessor; return accessor;
@ -920,7 +930,7 @@ ModelData *Raw2Gltf(
} }
std::shared_ptr<AccessorData> pAcc = gltf->AddAccessorWithView( std::shared_ptr<AccessorData> pAcc = gltf->AddAccessorWithView(
*gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_BUFFER), *gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_BUFFER),
GLT_VEC3F, positions); GLT_VEC3F, positions, channel.name);
pAcc->min = toStdVec(shapeBounds.min); pAcc->min = toStdVec(shapeBounds.min);
pAcc->max = toStdVec(shapeBounds.max); pAcc->max = toStdVec(shapeBounds.max);
@ -928,14 +938,14 @@ ModelData *Raw2Gltf(
if (!normals.empty()) { if (!normals.empty()) {
nAcc = gltf->AddAccessorWithView( nAcc = gltf->AddAccessorWithView(
*gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_BUFFER), *gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_BUFFER),
GLT_VEC3F, normals); GLT_VEC3F, normals, channel.name);
} }
std::shared_ptr<AccessorData> tAcc; std::shared_ptr<AccessorData> tAcc;
if (!tangents.empty()) { if (!tangents.empty()) {
nAcc = gltf->AddAccessorWithView( nAcc = gltf->AddAccessorWithView(
*gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_BUFFER), *gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_BUFFER),
GLT_VEC4F, tangents); GLT_VEC4F, tangents, channel.name);
} }
primitive->AddTarget(pAcc.get(), nAcc.get(), tAcc.get()); primitive->AddTarget(pAcc.get(), nAcc.get(), tAcc.get());

View File

@ -10,12 +10,13 @@
#include "AccessorData.hpp" #include "AccessorData.hpp"
#include "BufferViewData.hpp" #include "BufferViewData.hpp"
AccessorData::AccessorData(const BufferViewData &bufferView, GLType type) AccessorData::AccessorData(const BufferViewData &bufferView, GLType type, std::string name)
: Holdable(), : Holdable(),
bufferView(bufferView.ix), bufferView(bufferView.ix),
type(std::move(type)), type(std::move(type)),
byteOffset(0), byteOffset(0),
count(0) count(0),
name(name)
{ {
} }
@ -45,5 +46,8 @@ json AccessorData::serialize() const
if (!max.empty()) { if (!max.empty()) {
result["max"] = max; result["max"] = max;
} }
if (name.length() > 0) {
result["name"] = name;
}
return result; return result;
} }

View File

@ -13,7 +13,7 @@
struct AccessorData : Holdable struct AccessorData : Holdable
{ {
AccessorData(const BufferViewData &bufferView, GLType type); AccessorData(const BufferViewData &bufferView, GLType type, std::string name);
explicit AccessorData(GLType type); explicit AccessorData(GLType type);
json serialize() const override; json serialize() const override;
@ -42,4 +42,5 @@ struct AccessorData : Holdable
unsigned int count; unsigned int count;
std::vector<float> min; std::vector<float> min;
std::vector<float> max; std::vector<float> max;
std::string name;
}; };

View File

@ -331,6 +331,7 @@ struct RawBlendChannel
float defaultDeform; float defaultDeform;
bool hasNormals; bool hasNormals;
bool hasTangents; bool hasTangents;
std::string name;
}; };
struct RawSurface struct RawSurface