FBX SDK 总结之矩阵(Transform)

FBX中的Node的变换矩阵主要是通过FbxNode::EvaluateGlobalTransform(FbxTime)与FbxNode::EvaluateLocalTransform(FbxTime)这两个API获取, 通过字面意思我们就可以得知第一个得到的是Node的本地到世界空间变换矩阵,第二个则是Node的本地到父节点空间变换矩阵。如果不考虑动画影响FbxTime参数可忽略。这里我主要想说下的是有时候我们使用这两个矩阵变换出的模型的位置不正确会有偏差,经过自己的测试验证发现是因为还有一个Geometric矩阵需要考虑进来, 在SDK文档中找到相关信息对FbxNode的转换矩阵算是做了比较详细的介绍可以参考SDK Document中Nodes and Scene Graph >> FBX Nodes中的内容,其中关于Geometric矩阵有如下说明:

Geometric Transformation Properties

TheFbxNodegeometric transformation properties (FbxNode::GeometricTranslation,FbxNode::GeometricRotation, andFbxNode::GeometricScaling) describe how aFbxNodeAttributeis offset from theFbxNode’s local frame of reference. These geometric transforms are applied to theFbxNodeAttributeafter theFbxNode’s local transforms are computed, and are not inherited across the node hierarchy.

NoteThe geometric transformation properties are related to how 3ds Max represents pivot information. It is comparable to 3ds Max’s object-offset transformation.

通过上述信息我们可以得知Geometric矩阵是为了兼容3dmax中模型的偏移矩阵的概念而设计的,也即意味着解析通过3dmax导出的FBX文件,计算Node的变换矩阵时必须将Geometric矩阵也计算在内。若是如Maya之类的建模软件导出的FBX文件,可不考虑Geometric矩阵,即使考虑也不会影响到模型的最终方位变换,因为此时的Geometric矩阵总是单位矩阵,为了兼容性和统一性,,我们还是每次计算Node的变换矩阵都将Geometric矩阵也计算在内,代码如下:

得到当前Node的Geometric矩阵

FbxAMatrix GetNodeGeometryTransform(FbxNode* pNode){FbxAMatrix matrixGeo;matrixGeo.SetIdentity();if(pNode->GetNodeAttribute()){const FbxVector4 lT = pNode->GetGeometricTranslation(FbxNode::eSourcePivot);const FbxVector4 lR = pNode->GetGeometricRotation(FbxNode::eSourcePivot);const FbxVector4 lS = pNode->GetGeometricScaling(FbxNode::eSourcePivot);matrixGeo.SetT(lT);matrixGeo.SetR(lR);matrixGeo.SetS(lS);}return matrixGeo;}

得到当前Node的本地到世界空间变换矩阵

FbxAMatrix GetNodeWorldTransform(FbxNode* pNode){FbxAMatrix matrixL2W;matrixL2W.SetIdentity();if(NULL== pNode){return matrixL2W;}matrixL2W=pNode->EvaluateGlobalTransform();FbxAMatrix matrixGeo=GetNodeGeometryTransform(pNode);matrixL2W*=matrixGeo;return matrixL2W;}如SDK 文档所说Geometric矩阵是不能被继承的,也即意味着不能参与父子Node矩阵的累积运算,对于子Node而言的父Node的矩阵是不包含Geometric矩阵,现举例说明,A为父Node,B为儿子Node,C为孙子Node,通过矩阵累积求得Node C的本地到世界空间变换矩阵matrixA=nodeA.EvaluateLocalTransform();matrixB=nodeA.EvaluateLocalTransform();matrixC=nodeC.EvaluateLocalTransform();matrixC=matrixA*matrixB*matrixC*GetNodeGeometryTransform(pNodeC);

我个人觉得可以这样理解Geometric矩阵,在FbxNode空间下还存在着一个Geometry空间,通过Geometric矩阵可以将几何元素如顶点从Geometry空间转换到FbxNode空间,而后就可以利用FbxNode的继承树进行进一步的空间变换。

SDK Document 下载和在线查看链接?siteID=123112&id=16707768

在人生的大海中,我们虽然不能把握风的大小,却可以调整帆的方向。

FBX SDK 总结之矩阵(Transform)

相关文章:

你感兴趣的文章:

标签云: