Part1前言
有些建筑模型,建模的时候坐标采用高斯投影的方式来设置,这样会导致模型的顶点非常之大。导入到3dmax软件之后,由于其按照float精度进行渲染,从而造成渲染的模型抖动等问题。这里提出一种思路,通过将模型顶点统一进行偏移,从而解决在3dmax中渲染精度问题。
Part2fbx精度
通过如下定义可以看出fbx其实是双精度的。
代码语言:javascript复制class FBXSDK_DLL FbxVector4 : public FbxDouble4
具体fbx格式相关,可以参考之前的文章。看我七十二变:fbx格式
Part3建模测试
新建一个长宽高为1米的模型,然后将其放在x为2米 y为2米的位置,最后将原点移到原点。这种方法做出来的模型,居然顶点不会变化,保存之后如下
代码语言:javascript复制Vertices: *24 {
a: -0.5,-0.5,0,0.5,-0.5,0,-0.5,0.5,0,0.5,0.5,0,-0.5,-0.5,1,0.5,-0.5,1,-0.5,0.5,1,0.5,0.5,1
}
通过重置变换之后,顶点就符合我们预期,发生了偏移。
顶点变换如下
代码语言:javascript复制Vertices: *24 {
a: 1.5,1.5,0,2.5,1.5,0,1.5,2.5,0,2.5,2.5,0,1.5,1.5,1,2.5,1.5,1,1.5,2.5,1,2.5,2.5,1
}
之后我们通过fbx的sdk将顶点的x和y统一减去偏移的2米。
Part4fbxsdk代码实现
整个代码的逻辑参考fbx的sdk的demo的DisplayMesh.cxx这个文件,位置如下
代码语言:javascript复制D:Program FilesAutodeskFBXFBX SDK2020.3.1samplesImportScene
调用逻辑 1 初始化fbx的sdk
代码语言:javascript复制 FbxManager *lSdkManager = NULL;
FbxScene *lScene = NULL;
// Prepare the FBX SDK.
InitializeSdkObjects(lSdkManager, lScene);
2 加载fbx模型
代码语言:javascript复制string lFilePath = R"(D:workcodestudygithubotherfbxsdkcplustt.fbx)";
auto lResult = LoadScene(lSdkManager, lScene, lFilePath.c_str());
3 遍历模型
代码语言:javascript复制 FbxNode *rootNode = lScene->GetRootNode();
if (rootNode)
{
for (auto i = 0; i < rootNode->GetChildCount(); i )
{
DisplayContent(rootNode->GetChild(i));
}
}
DisplayContent函数中,这里只处理FbxNodeAttribute::eMesh格式
代码语言:javascript复制 for (auto i = 0; i < pNode->GetChildCount(); i )
{
DisplayContent(pNode->GetChild(i));
}
FbxNodeAttribute::EType lAttributeType;
if (pNode->GetNodeAttribute() == NULL)
{
std::cout << "NULL Node Attribute" << std::endl;
return;
}
lAttributeType = (pNode->GetNodeAttribute()->GetAttributeType());
if (FbxNodeAttribute::eMesh == lAttributeType)
{
DisplayMesh(pNode);
}
DisplayMesh处理中,我们只处理顶点信息
代码语言:javascript复制 FbxMesh *lMesh = (FbxMesh *)pNode->GetNodeAttribute();
DisplayControlsPoints(lMesh);
DisplayControlsPoints中对顶点信息进行统一偏移,这里减去了x和y的2米
代码语言:javascript复制 int i, lControlPointsCount = pMesh->GetControlPointsCount();
FbxVector4 *lControlPoints = pMesh->GetControlPoints();
for (i = 0; i < lControlPointsCount; i )
{
lControlPoints[i][0] = lControlPoints[i][0] - 2;
lControlPoints[i][1] = lControlPoints[i][1] - 2;
}
4 保存场景
代码语言:javascript复制SaveScene(lSdkManager, lScene, "tt2.fbx");
Part5总结
本文主要实现了通过fbx的sdk来实现模型顶点的统一偏移。代码在github仓库地址如下:https://github.com/inveta/ModelProcess/tree/main/VertexOffset