如何将fbx关键帧动画导入到自己的游戏引擎中?

问题描述 投票:0回答:1

我正在构建一个小型游戏引擎并使用fbx sdk来ipmort fbx网格和动画,这意味着我想将动画存储在我自己的类中。现在,有两种方法可以实现这一目标:

  1. 第一种方法是仅存储关键帧。如果我只存储关键帧,我将在 fbx 文件中拥有raw动画数据,并且我可以随时操纵或调整动画。
  2. 第二种方法是以固定速率对帧进行采样。我没有存储关键帧,而是从 fbx 文件中获取一些我需要的帧并存储它们。这样,我可能会丢失raw动画数据,因为当我采样帧时,所选帧可能不是关键帧,从而导致细节的轻微丢失。

从我的角度来看,第一种方式是最好的方式,但网上大部分教程都使用第二种方式。例如,这里。下面是其中的一个片段:

for (FbxLongLong i = start.GetFrameCount(FbxTime::eFrames24); i <= end.GetFrameCount(FbxTime::eFrames24); ++i)
{
    FbxTime currTime;
    currTime.SetFrame(i, FbxTime::eFrames24);
    *currAnim = new Keyframe();
    (*currAnim)->mFrameNum = i;
    FbxAMatrix currentTransformOffset = inNode->EvaluateGlobalTransform(currTime) * geometryTransform;
    (*currAnim)->mGlobalTransform = currentTransformOffset.Inverse() * currCluster->GetLink()->EvaluateGlobalTransform(currTime);
    currAnim = &((*currAnim)->mNext);
}

请注意,函数 EvaluateGlobalTransform(..) 是一个 fbxsdk 函数,它似乎是我们和我们可以依赖的 fbx 动画之间唯一安全的接口。另外,第二种方法(使用 EvaluateGlobalTransform 以特定速率采样)似乎是完成这项工作的标准且普遍接受的方法。 那里有一个解释说:

“FBX SDK 为您提供了多种获取数据的方法 想。不幸的是,由于不同的 DCC 工具(Max/Maya/等),您可能会 无法准确获取您想要的数据。例如,假设 您找到根骨骼,它在动画中具有翻译。 您可以通过多种方式访问转换。您可以使用 LclTransform 属性并在不同时间请求 FbxAMatrix。或者 您可以调用带有时间的评估函数来获取矩阵。 或者您可以使用评估器的 EvaluateNode 函数来评估 一次节点。最后,最复杂的版本是你可以 从属性中获取曲线节点并查看曲线的关键点。

考虑到所有这些选项,您可能会认为获取曲线是 要走的路。不幸的是,例如,Maya 烘焙了动画 数据到一组与实际的键无关的键 在 Maya 中设置。原因是 Maya 使用的曲线是 与 FBX 支持的不一样。所以,即使你得到了曲线 直接地,他们可能有数百把钥匙,因为他们可能有 已经烤好了。

这意味着基本上除非 Max 有由 FBX,它可能正在烘烤它们,而你将无法找到它们的内容 用你的话说,原来的两个姿势是。一般来说你会迭代 通过时间并以固定速率对场景进行采样。是的,有点糟糕 通常您会希望在采样后简化数据。”

总结一下:

  1. 第一种方式:

    优点:易于操作和调整,细节准确,内存消耗更少(如果您动态生成顶点变换矩阵)

    缺点:获取这些关键帧比较困难,不适用于某些fbx文件

  2. 第二种方式:

    优点:轻松获取所选帧,适用于所有 fbx 文件

    缺点:动画更改困难、内存消耗大、细节不准确

所以,我的问题是:

  1. 第二种方法真的是常见的方法吗?
  2. Unreal、Unity等著名游戏引擎都采用什么方式?
  3. 如果我想使用第一种方法,即使它在某些情况下可能不起作用,我怎样才能从fbx文件中只获取关键帧(即不使用EvaluateGlobalTransform而是使用FbxAnimStack、FbxAnimLayer、FbxAnimCurveNode、FbxAnimCurve、FbxAnimCurveKey)?
opengl graphics 3d game-engine fbx
1个回答
0
投票

您可以深入研究行业使用的库,例如 assimp,并且可能以与

aiAnimation
struct 类似的方式实现您自己的存储类。它将具有映射到骨骼层次结构的通道,并且将存在存储在矩阵结构中的任何变换数组。您必须编写一些线性插值逻辑来填充播放动画的两个关键帧之间的中间帧。

© www.soinside.com 2019 - 2024. All rights reserved.