fbx模型实现顶点偏移

2022-11-25 19:31:01 浏览数 (1)

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

0 人点赞