|
@@ -182,10 +182,7 @@ static void ReadMesh(
|
|
const FbxVector4 meshTranslation = pNode->GetGeometricTranslation(FbxNode::eSourcePivot);
|
|
const FbxVector4 meshTranslation = pNode->GetGeometricTranslation(FbxNode::eSourcePivot);
|
|
const FbxVector4 meshRotation = pNode->GetGeometricRotation(FbxNode::eSourcePivot);
|
|
const FbxVector4 meshRotation = pNode->GetGeometricRotation(FbxNode::eSourcePivot);
|
|
const FbxVector4 meshScaling = pNode->GetGeometricScaling(FbxNode::eSourcePivot);
|
|
const FbxVector4 meshScaling = pNode->GetGeometricScaling(FbxNode::eSourcePivot);
|
|
- FbxAMatrix meshTransform(meshTranslation, meshRotation, meshScaling);
|
|
|
|
- const FbxVector4 meshRotationPivot = pNode->GetRotationPivot(FbxNode::eSourcePivot);
|
|
|
|
- const FbxAMatrix meshPivotTransform(-meshRotationPivot, FbxVector4(0, 0, 0, 0), FbxVector4(1, 1, 1, 1));
|
|
|
|
- meshTransform *= meshPivotTransform;
|
|
|
|
|
|
+ const FbxAMatrix meshTransform(meshTranslation, meshRotation, meshScaling);
|
|
const FbxMatrix transform = meshTransform;
|
|
const FbxMatrix transform = meshTransform;
|
|
|
|
|
|
// Remove translation & scaling from transforms that will bi applied to normals, tangents &
|
|
// Remove translation & scaling from transforms that will bi applied to normals, tangents &
|
|
@@ -686,23 +683,6 @@ static FbxVector4 computeLocalScale(FbxNode* pNode, FbxTime pTime = FBXSDK_TIME_
|
|
return FbxVector4(1, 1, 1, 1);
|
|
return FbxVector4(1, 1, 1, 1);
|
|
}
|
|
}
|
|
|
|
|
|
-/**
|
|
|
|
- * Compute the local position incorporating the rotation pivot offset, and subtracting out the pivot
|
|
|
|
- * of the parent node.
|
|
|
|
- */
|
|
|
|
-static FbxVector4 computeLocalTranslation(FbxNode* pNode, FbxTime pTime = FBXSDK_TIME_INFINITE) {
|
|
|
|
- const FbxVector4 meshRotationPivot = pNode->GetRotationPivot(FbxNode::eSourcePivot);
|
|
|
|
- const FbxAMatrix meshPivotTransform(meshRotationPivot, FbxVector4(0, 0, 0, 0), FbxVector4(1, 1, 1, 1));
|
|
|
|
- FbxAMatrix localTransform = pNode->EvaluateLocalTransform(pTime);
|
|
|
|
- localTransform *= meshPivotTransform;
|
|
|
|
- FbxVector4 lTranslation = localTransform.GetT();
|
|
|
|
- FbxNode* parent = pNode->GetParent();
|
|
|
|
- if (pNode->GetParent() != nullptr) {
|
|
|
|
- lTranslation -= parent->GetRotationPivot(FbxNode::eSourcePivot);
|
|
|
|
- }
|
|
|
|
- return lTranslation;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static void ReadNodeHierarchy(
|
|
static void ReadNodeHierarchy(
|
|
RawModel& raw,
|
|
RawModel& raw,
|
|
FbxScene* pScene,
|
|
FbxScene* pScene,
|
|
@@ -745,9 +725,9 @@ static void ReadNodeHierarchy(
|
|
|
|
|
|
// Set the initial node transform.
|
|
// Set the initial node transform.
|
|
const FbxAMatrix localTransform = pNode->EvaluateLocalTransform();
|
|
const FbxAMatrix localTransform = pNode->EvaluateLocalTransform();
|
|
- FbxVector4 localTranslation = computeLocalTranslation(pNode);
|
|
|
|
- FbxQuaternion localRotation = localTransform.GetQ();
|
|
|
|
- FbxVector4 localScaling = computeLocalScale(pNode);
|
|
|
|
|
|
+ const FbxVector4 localTranslation = localTransform.GetT();
|
|
|
|
+ const FbxQuaternion localRotation = localTransform.GetQ();
|
|
|
|
+ const FbxVector4 localScaling = computeLocalScale(pNode);
|
|
|
|
|
|
node.translation = toVec3f(localTranslation) * scaleFactor;
|
|
node.translation = toVec3f(localTranslation) * scaleFactor;
|
|
node.rotation = toQuatf(localRotation);
|
|
node.rotation = toQuatf(localRotation);
|
|
@@ -782,6 +762,7 @@ static void ReadAnimations(RawModel& raw, FbxScene* pScene, const GltfOptions& o
|
|
eMode = FbxTime::eFrames60;
|
|
eMode = FbxTime::eFrames60;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
+ const double epsilon = 1e-5f;
|
|
|
|
|
|
const int animationCount = pScene->GetSrcObjectCount<FbxAnimStack>();
|
|
const int animationCount = pScene->GetSrcObjectCount<FbxAnimStack>();
|
|
for (size_t animIx = 0; animIx < animationCount; animIx++) {
|
|
for (size_t animIx = 0; animIx < animationCount; animIx++) {
|
|
@@ -855,9 +836,13 @@ static void ReadAnimations(RawModel& raw, FbxScene* pScene, const GltfOptions& o
|
|
for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) {
|
|
for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) {
|
|
FbxNode* pNode = pScene->GetNode(nodeIndex);
|
|
FbxNode* pNode = pScene->GetNode(nodeIndex);
|
|
const FbxAMatrix baseTransform = pNode->EvaluateLocalTransform();
|
|
const FbxAMatrix baseTransform = pNode->EvaluateLocalTransform();
|
|
- const FbxVector4 baseTranslation = computeLocalTranslation(pNode);
|
|
|
|
|
|
+ const FbxVector4 baseTranslation = baseTransform.GetT();
|
|
const FbxQuaternion baseRotation = baseTransform.GetQ();
|
|
const FbxQuaternion baseRotation = baseTransform.GetQ();
|
|
const FbxVector4 baseScaling = computeLocalScale(pNode);
|
|
const FbxVector4 baseScaling = computeLocalScale(pNode);
|
|
|
|
+ bool hasTranslation = false;
|
|
|
|
+ bool hasRotation = false;
|
|
|
|
+ bool hasScale = false;
|
|
|
|
+ bool hasMorphs = false;
|
|
|
|
|
|
RawChannel channel;
|
|
RawChannel channel;
|
|
channel.nodeIndex = raw.GetNodeById(pNode->GetUniqueID());
|
|
channel.nodeIndex = raw.GetNodeById(pNode->GetUniqueID());
|
|
@@ -867,10 +852,24 @@ static void ReadAnimations(RawModel& raw, FbxScene* pScene, const GltfOptions& o
|
|
pTime.SetFrame(frameIndex, eMode);
|
|
pTime.SetFrame(frameIndex, eMode);
|
|
|
|
|
|
const FbxAMatrix localTransform = pNode->EvaluateLocalTransform(pTime);
|
|
const FbxAMatrix localTransform = pNode->EvaluateLocalTransform(pTime);
|
|
- const FbxVector4 localTranslation = computeLocalTranslation(pNode, pTime);
|
|
|
|
|
|
+ const FbxVector4 localTranslation = localTransform.GetT();
|
|
const FbxQuaternion localRotation = localTransform.GetQ();
|
|
const FbxQuaternion localRotation = localTransform.GetQ();
|
|
const FbxVector4 localScale = computeLocalScale(pNode, pTime);
|
|
const FbxVector4 localScale = computeLocalScale(pNode, pTime);
|
|
|
|
|
|
|
|
+ hasTranslation |=
|
|
|
|
+ (fabs(localTranslation[0] - baseTranslation[0]) > epsilon ||
|
|
|
|
+ fabs(localTranslation[1] - baseTranslation[1]) > epsilon ||
|
|
|
|
+ fabs(localTranslation[2] - baseTranslation[2]) > epsilon);
|
|
|
|
+ hasRotation |=
|
|
|
|
+ (fabs(localRotation[0] - baseRotation[0]) > epsilon ||
|
|
|
|
+ fabs(localRotation[1] - baseRotation[1]) > epsilon ||
|
|
|
|
+ fabs(localRotation[2] - baseRotation[2]) > epsilon ||
|
|
|
|
+ fabs(localRotation[3] - baseRotation[3]) > epsilon);
|
|
|
|
+ hasScale |=
|
|
|
|
+ (fabs(localScale[0] - baseScaling[0]) > epsilon ||
|
|
|
|
+ fabs(localScale[1] - baseScaling[1]) > epsilon ||
|
|
|
|
+ fabs(localScale[2] - baseScaling[2]) > epsilon);
|
|
|
|
+
|
|
channel.translations.push_back(toVec3f(localTranslation) * scaleFactor);
|
|
channel.translations.push_back(toVec3f(localTranslation) * scaleFactor);
|
|
channel.rotations.push_back(toQuatf(localRotation));
|
|
channel.rotations.push_back(toQuatf(localRotation));
|
|
channel.scales.push_back(toVec3f(localScale));
|
|
channel.scales.push_back(toVec3f(localScale));
|
|
@@ -925,6 +924,7 @@ static void ReadAnimations(RawModel& raw, FbxScene* pScene, const GltfOptions& o
|
|
if (!std::isnan(result)) {
|
|
if (!std::isnan(result)) {
|
|
// we're transitioning into targetIx
|
|
// we're transitioning into targetIx
|
|
channel.weights.push_back(result);
|
|
channel.weights.push_back(result);
|
|
|
|
+ hasMorphs = true;
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
if (targetIx != targetCount - 1) {
|
|
if (targetIx != targetCount - 1) {
|
|
@@ -932,6 +932,7 @@ static void ReadAnimations(RawModel& raw, FbxScene* pScene, const GltfOptions& o
|
|
if (!std::isnan(result)) {
|
|
if (!std::isnan(result)) {
|
|
// we're transitioning AWAY from targetIx
|
|
// we're transitioning AWAY from targetIx
|
|
channel.weights.push_back(1.0f - result);
|
|
channel.weights.push_back(1.0f - result);
|
|
|
|
+ hasMorphs = true;
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -945,12 +946,27 @@ static void ReadAnimations(RawModel& raw, FbxScene* pScene, const GltfOptions& o
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- animation.channels.emplace_back(channel);
|
|
|
|
|
|
+ if (hasTranslation || hasRotation || hasScale || hasMorphs) {
|
|
|
|
+ if (!hasTranslation) {
|
|
|
|
+ channel.translations.clear();
|
|
|
|
+ }
|
|
|
|
+ if (!hasRotation) {
|
|
|
|
+ channel.rotations.clear();
|
|
|
|
+ }
|
|
|
|
+ if (!hasScale) {
|
|
|
|
+ channel.scales.clear();
|
|
|
|
+ }
|
|
|
|
+ if (!hasMorphs) {
|
|
|
|
+ channel.weights.clear();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ animation.channels.emplace_back(channel);
|
|
|
|
|
|
- totalSizeInBytes += channel.translations.size() * sizeof(channel.translations[0]) +
|
|
|
|
- channel.rotations.size() * sizeof(channel.rotations[0]) +
|
|
|
|
- channel.scales.size() * sizeof(channel.scales[0]) +
|
|
|
|
- channel.weights.size() * sizeof(channel.weights[0]);
|
|
|
|
|
|
+ totalSizeInBytes += channel.translations.size() * sizeof(channel.translations[0]) +
|
|
|
|
+ channel.rotations.size() * sizeof(channel.rotations[0]) +
|
|
|
|
+ channel.scales.size() * sizeof(channel.scales[0]) +
|
|
|
|
+ channel.weights.size() * sizeof(channel.weights[0]);
|
|
|
|
+ }
|
|
|
|
|
|
if (verboseOutput) {
|
|
if (verboseOutput) {
|
|
fmt::printf(
|
|
fmt::printf(
|