[Unity]硬表面模型描边断裂问题解决过程记录( 三 )

Normals;for (int x = 0; x < SameControlPointsIndex.Size(); x++){FbxVector4 Normal = VertNormal->GetDirectArray()[SameControlPointsIndex[x]];Normals.AddUnique(Normal);}//将所有不同方向的法线加在一起并归一化获得光滑法线FbxVector4 SmoothNormal;for (int n = 0; n < Normals.Size(); n++){SmoothNormal += Normals[n];}SmoothNormal.Normalize();//分别获取当前顶点的切线、法线、副切线用于构建模型→切线空间的转换矩阵//需要注意的是:法线、切线、副切线的映射方式(也就是存储方式)是与顶点//序列一一对应 , 所以直接GetDirectArray()[顶点序号]就可以FbxVector4 Tangent = VertTangent->GetDirectArray()[j];FbxVector4 Normal = VertNormal->GetDirectArray()[j];FbxVector4 Bitangent = VertBinomral->GetDirectArray()[j];//将法线从模型空间转为切线空间//FbxSdk的内置矩阵类型不会使 , 算出来的值有问题 , 所以还是手动计算FbxVector4 tmpVector;tmpVector = SmoothNormal;tmpVector[0] = Tangent.DotProduct(SmoothNormal);tmpVector[1] = Bitangent.DotProduct(SmoothNormal);tmpVector[2] = Normal.DotProduct(SmoothNormal);tmpVector[3] = 0;SmoothNormal = tmpVector;//获取当前顶点的颜色信息存放于其layer中的序号//与法切副不同 , 顶点色数据在layer中的存储方式(映射Mapping方式)稍微复杂//首先要使用GetIndexArray()[顶点序号]获取其颜色值在DirectArray中的序号//然后使用GetDirectArray()[获得的序号]来获得该顶点的顶点色信息int VertColorIndex = VertColor->GetIndexArray()[j];//声明一个颜色值 , 将法线数值范围从-1~1处理为0~1后存入RGB通道中 , A通道保持//不变 , 因为其中存放着轮廓线大小信息FbxColor Color;Color.mRed = SmoothNormal[0] * 0.5f + 0.5f;Color.mGreen = SmoothNormal[1] * 0.5f + 0.5f;Color.mBlue = SmoothNormal[2] * 0.5f + 0.5f;Color.mAlpha = VertColor->GetDirectArray()[VertColorIndex].mAlpha;//将颜色写入顶点颜色layer中VertColor->GetDirectArray().SetAt(VertColorIndex, Color);}}//递归调用 , 确保场景中所有mesh都得到处理StoreNormalsToVertColor(node->GetChild(i));}}}int main(int argc, char** argv) {// lFilename是输入路径 , lFilename2是输出路径const char* lFilename = "Weapon.fbx";const char* lFilename2 = "Export.fbx";//主函数中几乎都是FbxSdk文档中所写的代码 , 是导入导出fbx所需要的的标准流程// Initialize the SDK manager. This object handles all our memory management.FbxManager* lSdkManager = FbxManager::Create();// Create the IO settings object.FbxIOSettings *ios = FbxIOSettings::Create(lSdkManager, IOSROOT);lSdkManager->SetIOSettings(ios);// Create an importer using the SDK manager.FbxImporter* lImporter = FbxImporter::Create(lSdkManager, "");// Use the first argument as the filename for the importer.if (!lImporter->Initialize(lFilename, -1, lSdkManager->GetIOSettings())) {printf("Call to FbxImporter::Initialize() failed.\n");printf("Error returned: %s\n\n", lImporter->GetStatus().GetErrorString());exit(-1);}// Create a new scene so that it can be populated by the imported file.FbxScene* lScene = FbxScene::Create(lSdkManager, "myScene");// Import the contents of the file into the scene.lImporter->Import(lScene);// The file is imported; so get rid of the importer.lImporter->Destroy();//获取场景中根节点 , 然后对其调用自定义的StoreNormalsToVertColor函数 FbxNode* lRootNode = lScene->GetRootNode();if (lRootNode) {StoreNormalsToVertColor(lRootNode);}//导出Fbx文件FbxExporter* lExporter = FbxExporter::Create(lSdkManager, "");bool lExportStatus = lExporter->Initialize(lFilename2, -1, lSdkManager->GetIOSettings());if (!lExportStatus) {printf("Call to FbxExporter::Initialize() failed.\n");printf("Error returned: %s\n\n", lExporter->GetStatus().GetErrorString());return false;}lExporter->Export(lScene);lExporter->Destroy();// Destroy the SDK manager and all the other objects it was handling.lSdkManager->Destroy();return 0;}