FBX SDK进口正态与玛雅正常的肤色和动画几何形状不一致
我目前正在使用FBX SDK 2020编写FBX进口商,并且我一直在验证我拥有的数据是正确的,通过将FBX拖放到Maya中,并查看Maya的组件编辑器显示的数据显示。
我目前遇到的问题是,当我从FBX SDK中导入正态时,与仅针对皮肤网眼的Maya 相比,它们似乎略有偏离(又称绑定到骨架的网眼)并具有动画数据。
我的过程基本上是将FBX拖到Maya中,并将模型放入绑定姿势,并在Maya的组件编辑器中查看数据。
以下是我的进口商中使用FBX SDK
下面是同一顶点的图片,但如在Maya的组件编辑器中
所示.sstatic.net/w6zmf.png“ alt =” Maya的组件中看到编辑器“>
如上所述,在数百个小数位的名称值中存在一些错误,而位置值基本上是相同的。
下面是相同数据的另一幅图片,但是在删除骨骼之后,然后从Maya重新出口到新的FBX文件
更新
我尝试了一个不同的型号 - 带有骨头的单位球,同样的问题也发生了,除了这次正: 。
这是用于产生问题的代码,再次使用FBX SDK 2020(最近的LIB)
namespace test
{
FbxSample::FbxSample()
{
}
void FbxSample::ImportMesh(FbxNode& node, int depth)
{
auto log = std::ofstream("C:\\Projects\\FbxSamples\\log.txt");
auto& globalTransform = node.EvaluateGlobalTransform(FBXSDK_TIME_INFINITE);
FbxMesh* fbxMesh = (FbxMesh*)node.GetNodeAttribute();
int triangleCount = fbxMesh->GetPolygonCount();
auto meshControlPoints = fbxMesh->GetControlPoints();
int meshControlPointsCount = fbxMesh->GetControlPointsCount();
auto normals = fbxMesh->GetElementNormal();
int vertexCount = 0;
for (int polygonId = 0; polygonId < triangleCount; ++polygonId)
{
int polygonSize = fbxMesh->GetPolygonSize(polygonId);
for (int j = 0; j < polygonSize; ++j, ++vertexCount)
{
int vertexIndex = fbxMesh->GetPolygonVertex(polygonId, j);
auto position = meshControlPoints[vertexIndex];
FbxVector4 normal;
switch (normals->GetMappingMode())
{
case FbxGeometryElement::eByControlPoint:
switch (normals->GetReferenceMode())
{
case FbxGeometryElement::eDirect:
normal = normals->GetDirectArray().GetAt(vertexIndex);
break;
case FbxGeometryElement::eIndexToDirect:
{
int id = normals->GetIndexArray().GetAt(vertexIndex);
normal = normals->GetDirectArray().GetAt(id);
}
break;
}
break;
case FbxGeometryElement::eByPolygonVertex:
switch (normals->GetReferenceMode())
{
case FbxGeometryElement::eDirect:
normal = normals->GetDirectArray().GetAt(vertexCount);
break;
case FbxGeometryElement::eIndexToDirect:
{
int id = normals->GetIndexArray().GetAt(vertexCount);
normal = normals->GetDirectArray().GetAt(id);
}
break;
}
break;
}
FbxVector4 normal2;
fbxMesh->GetPolygonVertexNormal(polygonId, j, normal2);
log << "Vertex Count: " << vertexCount << " Vertex Index: " << vertexIndex << std::endl;
log << "Position: X: " << position[0] << " Y: " << position[1] << " Z: " << position[2] << " W: " << position[3] << std::endl;
log << "Normal: X: " << normal[0] << " Y: " << normal[1] << " Z: " << normal[2] << " W: " << normal[3] << std::endl;
log << "Normal2: X: " << normal2[0] << " Y: " << normal2[1] << " Z: " << normal2[2] << " W: " << normal2[3] << std::endl;
log << std::endl;
}
}
log.flush();
log.close();
}
void FbxSample::Walk(FbxNode& node, int depth)
{
auto nodeAttribute = node.GetNodeAttribute();
if (nodeAttribute)
{
FbxNodeAttribute::EType attributeType = nodeAttribute->GetAttributeType();
switch (attributeType)
{
case fbxsdk::FbxNodeAttribute::eMesh:
ImportMesh(node, depth);
break;
}
}
for (int i = 0; i < node.GetChildCount(); i++)
{
Walk(*node.GetChild(i), depth + 1);
}
}
void FbxSample::Walk(FbxScene& fbxScene)
{
FbxNode* node = fbxScene.GetRootNode();
if (node)
{
for (int i = 0; i < node->GetChildCount(); ++i)
{
Walk(*node->GetChild(i), 1);
}
}
}
void FbxSample::Test()
{
FbxManager* sdkManager = FbxManager::Create();
if (!sdkManager)
{
FBXSDK_printf("Error: Unable to create FBX Manager!\n");
exit(1);
}
else
{
FBXSDK_printf("Autodesk FBX SDK version %s\n", sdkManager->GetVersion());
}
FbxIOSettings* ios = FbxIOSettings::Create(sdkManager, IOSROOT);
ios->SetBoolProp(IMP_FBX_MATERIAL, true);
ios->SetBoolProp(IMP_FBX_TEXTURE, true);
ios->SetBoolProp(IMP_GEOMETRY, true);
ios->SetBoolProp(IMP_FBX_MODEL, true);
ios->SetBoolProp(IMP_SKINS, true);
ios->SetBoolProp(IMP_FBX_ANIMATION, true);
ios->SetBoolProp(IMP_FBX_GLOBAL_SETTINGS, true);
sdkManager->SetIOSettings(ios);
auto importer = FbxImporter::Create(sdkManager, "");
importer->Initialize("C:\\Projects\\FbxSamples\\SphereWithBones.fbx", -1, sdkManager->GetIOSettings());
auto fbxScene = FbxScene::Create(sdkManager, "Scene");
importer->Import(fbxScene);
Walk(*fbxScene);
}
}
是输出:
Vertex Count: 0 Vertex Index: 20
Position: X: 0.293893 Y: -0.951057 Z: -0.0954916 W: 0
Normal: X: 0.298177 Y: 0.267987 Z: -0.916119 W: 1
Normal2: X: 0.298177 Y: 0.267987 Z: -0.916119 W: 1
Vertex Count: 1 Vertex Index: 0
Position: X: 0.148778 Y: -0.987688 Z: -0.0483409 W: 0
Normal: X: 0.18352 Y: 0.228479 Z: -0.956095 W: 1
Normal2: X: 0.18352 Y: 0.228479 Z: -0.956095 W: 1
Vertex Count: 2 Vertex Index: 21
Position: X: 0.25 Y: -0.951057 Z: -0.181636 W: 0
Normal: X: 0.246448 Y: 0.378525 Z: -0.892179 W: 1
Normal2: X: 0.246448 Y: 0.378525 Z: -0.892179 W: 1
如上所述 - 绑定姿势中的单位球体应具有接近x/y/z位置的正态范围。高于正常的地方只是错了。
在同一FBX文件中删除骨头,并在上面重新运行代码 - 正态正确匹配Maya中的内容。
我还在Autodesk论坛上发布了同样的问题,其中包含示例FBX文件,您可以下载 +上面的代码来复制问题
https://forums.autodesk.com/t5/fbx-forum/fbx-sdk-normals-inmals-incorrect-with-skinned-meshes/td-p/11279705
I am currently writing a FBX Importer using FBX SDK 2020, and I've been validating that the data I have is correct, by dragging and dropping the FBX into Maya, and viewing what Maya's Component Editor shows the data to be.
My problem I have currently, is that when I am importing the Normals from FBX SDK, they appear to be slightly off compared to that of Maya for skinned meshes only (aka meshes that are bound to a skeleton) and have animation data.
My process has basically been to drag / drop the FBX into Maya, and put the model into Bind Pose, and view data in Maya's Component Editor.
Below is a picture of Normals from the fbx file from my Importer using FBX SDK
Below is a picture of the same vertex but as seen in Maya's Component Editor
As seen above there is some error in the Nomal values in the hundreds decimal place, while the Position values are basically identical.
Below is another picture of the same data, but after deleting the Skeleton, and re-exporting from Maya to a new FBX file
UPDATE
I've tried with a different model, -- a unit sphere with bones, and same problem happens, except this time normals are way off.
Here is the code used to produce issue, again using FBX SDK 2020 (most recent lib)
namespace test
{
FbxSample::FbxSample()
{
}
void FbxSample::ImportMesh(FbxNode& node, int depth)
{
auto log = std::ofstream("C:\\Projects\\FbxSamples\\log.txt");
auto& globalTransform = node.EvaluateGlobalTransform(FBXSDK_TIME_INFINITE);
FbxMesh* fbxMesh = (FbxMesh*)node.GetNodeAttribute();
int triangleCount = fbxMesh->GetPolygonCount();
auto meshControlPoints = fbxMesh->GetControlPoints();
int meshControlPointsCount = fbxMesh->GetControlPointsCount();
auto normals = fbxMesh->GetElementNormal();
int vertexCount = 0;
for (int polygonId = 0; polygonId < triangleCount; ++polygonId)
{
int polygonSize = fbxMesh->GetPolygonSize(polygonId);
for (int j = 0; j < polygonSize; ++j, ++vertexCount)
{
int vertexIndex = fbxMesh->GetPolygonVertex(polygonId, j);
auto position = meshControlPoints[vertexIndex];
FbxVector4 normal;
switch (normals->GetMappingMode())
{
case FbxGeometryElement::eByControlPoint:
switch (normals->GetReferenceMode())
{
case FbxGeometryElement::eDirect:
normal = normals->GetDirectArray().GetAt(vertexIndex);
break;
case FbxGeometryElement::eIndexToDirect:
{
int id = normals->GetIndexArray().GetAt(vertexIndex);
normal = normals->GetDirectArray().GetAt(id);
}
break;
}
break;
case FbxGeometryElement::eByPolygonVertex:
switch (normals->GetReferenceMode())
{
case FbxGeometryElement::eDirect:
normal = normals->GetDirectArray().GetAt(vertexCount);
break;
case FbxGeometryElement::eIndexToDirect:
{
int id = normals->GetIndexArray().GetAt(vertexCount);
normal = normals->GetDirectArray().GetAt(id);
}
break;
}
break;
}
FbxVector4 normal2;
fbxMesh->GetPolygonVertexNormal(polygonId, j, normal2);
log << "Vertex Count: " << vertexCount << " Vertex Index: " << vertexIndex << std::endl;
log << "Position: X: " << position[0] << " Y: " << position[1] << " Z: " << position[2] << " W: " << position[3] << std::endl;
log << "Normal: X: " << normal[0] << " Y: " << normal[1] << " Z: " << normal[2] << " W: " << normal[3] << std::endl;
log << "Normal2: X: " << normal2[0] << " Y: " << normal2[1] << " Z: " << normal2[2] << " W: " << normal2[3] << std::endl;
log << std::endl;
}
}
log.flush();
log.close();
}
void FbxSample::Walk(FbxNode& node, int depth)
{
auto nodeAttribute = node.GetNodeAttribute();
if (nodeAttribute)
{
FbxNodeAttribute::EType attributeType = nodeAttribute->GetAttributeType();
switch (attributeType)
{
case fbxsdk::FbxNodeAttribute::eMesh:
ImportMesh(node, depth);
break;
}
}
for (int i = 0; i < node.GetChildCount(); i++)
{
Walk(*node.GetChild(i), depth + 1);
}
}
void FbxSample::Walk(FbxScene& fbxScene)
{
FbxNode* node = fbxScene.GetRootNode();
if (node)
{
for (int i = 0; i < node->GetChildCount(); ++i)
{
Walk(*node->GetChild(i), 1);
}
}
}
void FbxSample::Test()
{
FbxManager* sdkManager = FbxManager::Create();
if (!sdkManager)
{
FBXSDK_printf("Error: Unable to create FBX Manager!\n");
exit(1);
}
else
{
FBXSDK_printf("Autodesk FBX SDK version %s\n", sdkManager->GetVersion());
}
FbxIOSettings* ios = FbxIOSettings::Create(sdkManager, IOSROOT);
ios->SetBoolProp(IMP_FBX_MATERIAL, true);
ios->SetBoolProp(IMP_FBX_TEXTURE, true);
ios->SetBoolProp(IMP_GEOMETRY, true);
ios->SetBoolProp(IMP_FBX_MODEL, true);
ios->SetBoolProp(IMP_SKINS, true);
ios->SetBoolProp(IMP_FBX_ANIMATION, true);
ios->SetBoolProp(IMP_FBX_GLOBAL_SETTINGS, true);
sdkManager->SetIOSettings(ios);
auto importer = FbxImporter::Create(sdkManager, "");
importer->Initialize("C:\\Projects\\FbxSamples\\SphereWithBones.fbx", -1, sdkManager->GetIOSettings());
auto fbxScene = FbxScene::Create(sdkManager, "Scene");
importer->Import(fbxScene);
Walk(*fbxScene);
}
}
Here is output:
Vertex Count: 0 Vertex Index: 20
Position: X: 0.293893 Y: -0.951057 Z: -0.0954916 W: 0
Normal: X: 0.298177 Y: 0.267987 Z: -0.916119 W: 1
Normal2: X: 0.298177 Y: 0.267987 Z: -0.916119 W: 1
Vertex Count: 1 Vertex Index: 0
Position: X: 0.148778 Y: -0.987688 Z: -0.0483409 W: 0
Normal: X: 0.18352 Y: 0.228479 Z: -0.956095 W: 1
Normal2: X: 0.18352 Y: 0.228479 Z: -0.956095 W: 1
Vertex Count: 2 Vertex Index: 21
Position: X: 0.25 Y: -0.951057 Z: -0.181636 W: 0
Normal: X: 0.246448 Y: 0.378525 Z: -0.892179 W: 1
Normal2: X: 0.246448 Y: 0.378525 Z: -0.892179 W: 1
As seen above -- a unit sphere in bind pose should have Normals close to that of the Position X/Y/Z -- where above normals are just flat out wrong.
Removing bones in the same FBX file, and re-running code above -- normals correctly match what is in Maya.
I've also posted the same question on autodesk forum that has the sample FBX file that you can download + use code above to reproduce the issue
https://forums.autodesk.com/t5/fbx-forum/fbx-sdk-normals-incorrect-with-skinned-meshes/td-p/11279705
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论