最近几个月一直在做FBX数据转换方面的工作,记录下一些工作中遇到的问题和相应解决方案,算是对自己多日工作的总结也希望有需要的人能看到。
今天讨论的Fbx中文问题主要是集中在两方面:1、使用Sdk加载的Fbx文件的路径中存在中文 2、Fbx中保存的数据存在中文(例如Node 名称、材质名称等)。当我们按Sdk提供的范例直接加载路径中存在中文的Fbx文件时会直接报错。这里的解决方案是在将Fbx文件路径字符串交由Sdk加载前先进行一次字符编码转换,代码如下:
FbxString filePath=MyString::StdStr2FbxStr(srcFile);// srcFile 为Fbx文件路径
// Use the first argument as the filename for the importer.
if(!lImporter->Initialize(filePath.Buffer(), -1, lSdkManager->GetIOSettings())) {
printf("Call to FbxImporter::Initialize() failed.\n");
printf("Error returned: %s\n\n", lImporter->GetStatus().GetErrorString());
return false;
}
FbxString MyString::StdStr2FbxStr(string str)
{
FbxString retStr="";
char * newStr=NULL;
FbxAnsiToUTF8(str.c_str(),newStr);// Fbx Sdk 提供的字符编码转换API
if(NULL!=newStr)
{
retStr=newStr;
delete[] newStr; // 要记得释放
}
return retStr;
}
解决了Fbx中文路径问题后,我们再来看看Fbx文件中本身数据包含中文的处理方法,若调用Sdk接口返回的字符串不经过转码处理会显示为乱码,这时我们只要我们进行一次转码就OK啦,代码如下:
FbxNode *pNode=...
std::string nodeName=MyString::FbxStr2StdStr(pNode->GetName());
string MyString::FbxStr2StdStr(FbxString fbxStr)
{
string retStr="";
char * newStr=NULL;
FbxUTF8ToAnsi(fbxStr.Buffer(),newStr);
if(NULL!=newStr)
{
retStr=newStr;
delete[] newStr;
}
return retStr;
}
经过上面的解释相信大家都知道了Fbx中的中文问题产生的原因主要是字符编码上面,Fbx内部是以UTF-8编码保存字符的,而我们的开发环境中的字符多是以ANSI或者Unicode存储的,解析使用的编码和实际数据的编码不匹配产生乱码也就在所难免了。
PS:以上只是针对开发环境字符编码设置为ANSI的情况进行说明的,若字符编码设置为Unicode,则可使用windows API WideCharToMultiByte(...)或直接使用FBX SDK提供的FbxWCToAnsi(...)将Unicode字符转成Ansi再按以上处理即可。
FBX SDK编码转换API头文件:
fbxsdk/core/base/fbxstring.h
SDK相关参考:
FBX SDK Programmer's Guide > FBX SDK Object Model > Connections> Supported String Formats