将刚体模拟保存为动画

时间:2017-12-13 20:38:35

标签: animation simulation collada gltf

我在自动机器人领域工作。我经常模拟没有可视化的机器人,将导出位置和旋转数据导出到~30 fps的文件,然后再播放该文件。目前,我将动画数据保存为自定义格式的JSON文件,并使用three.js进行动画处理。

我想知道是否有更好的方法来导出这些数据?

我不熟悉动画,但我怀疑我可以导出像COLLADA或glTF这样的东西,并获得使用许多系统已设置导入的格式的好处。 / p>

我有几个问题(一些具体的和一些一般的):

  1. 动画通常如何以这些格式导出?似乎大多数都与骷髅或变形有关,但这两个概念似乎都不适用于我的情况。 (我可以获得指向一般动画概念概述的指针吗?)

  2. 我真的不需要关键帧。在不需要插值的情况下,将关键帧设置为30到60 fps是否合理?

  3. 是否有任何标准动画格式以不采用某种形式插值的格式保存数据?

  4. 我错过了什么吗?我确信我在该领域缺乏知识已经隐藏了一些对动画师来说很明显的东西。

2 个答案:

答案 0 :(得分:2)

您描述的动画类型通常称为“烘焙”动画,其中一些计算已被采样,可能为30~60 fps,关键帧以高采样率保存。对于这样的动画,通常应用线性插值。例如,在Blender中,有一种方法可以运行Blender Game Engine并将物理模拟记录到(密集)关键帧。

至于插值,这是一个思想实验:考虑一下基于多边形的渲染引擎想要渲染一个圆,但必须只使用直线。围绕圆的边缘计算一些有限数量的点,并且数十个或数百个小线段填充点之间的间隙。有足够的密度,或者相机足够远,它看起来很圆,但线段确保在想要的圆圈中没有泄漏或间隙。相同的概念(在时间而不是在空间中)适用于烘焙关键帧。样本密度高,直线(线性插值)填补空白。如果以超慢动作播放,则可能会在达到新关键帧时检测到速度的细微变化。但是在正常速度下,它看起来很正常,并且帧速率不需要保持锁定到采样率。

我建议在这里阅读section on animations for glTF 2.0(免责声明,我是glTF撰稿人和工作组成员)。特别是,请看一下使用线性插值的基于节点的动画的描述。

对于机器人技术,你需要避开皮肤和基于骨架的动画。无论如何,这些东西并不总是与基于节点的动画兼容(我们最近遇到了问题)。基于节点的动画更适用于具有铰接关节等的非变形机器人。

答案 1 :(得分:2)

您特别提到了自主机器人,特别是位置和旋转。所以我假设机器人本身是应该存储在这里的粒度级别。 (只是为了区别于铰接式机器人 - 基本上是一个操纵器(“手臂”),带有几个可能有不同角度的旋转或平移关节)

对于这种情况,非常简短的高级描述,关于如何将其存储在glTF (*)中:

您可以将机器人(或每个机器人)存储为glTF资产的一个node。每个节点都可以包含translationrotation属性(以3D向量和四元数形式给出)。然后,这些节点将简单描述机器人的位置和方向。你可以想象机器人被“附着”到这些节点上。 (事实上​​,你可以在glTF中将这些节点附加mesh,然后可以作为机器人的直观表示。

动画数据本身就是关于这些属性(平移和旋转)如何随时间变化的描述。存储此信息的方式可以设想为表格,您可以将翻译和轮换与每个时间戳关联起来:

time (s)        0.1   0.2  ...  1.0

translation x   1.2   1.3  ...  2.3
translation y   3.4   3.4  ...  4.3
translation z   4.5   4.6  ...  4.9

rotation x      0.12  0.13 ...  0.42
rotation y      0.32  0.43 ...  0.53
rotation z      0.14  0.13 ...  0.34
rotation w      0.53  0.46 ...  0.45

然后以二进制形式存储此信息,并由所谓的accessor对象提供。

glTF资产的animation基本上建立了这个二进制动画数据与节点中受其影响的属性之间的连接:每个animation指的是这样一个“数据表” ,以及node,其属性将随着时间的推移用新的平移和旋转值填充。

关于插值:

在您的情况下,从模拟中以高速率对输出进行采样,基本上每个帧 是一个“关键帧”,并且没有关于关键帧或插值方案的显式信息将具有要存储。只是声明动画插值应该是LINEARSTEP类型应该足以满足此用例。

(将其声明为LINEAR插值的选项主要与播放有关。想象一下,你在0.15秒后完全停止播放:它是否应该显示机器人在时间戳0.1或者时间戳上的状态时间戳0.2处的状态,或线性插值的状态?但是,这主要适用于标准查看器,而不一定适用于自定义播放)

(*)附注:在概念级别,glTF和COLLADA中信息的表示方式类似。粗略地说,COLLADA是用于创作应用程序的交换格式,glTF是一种可以有效传输和呈现的传输格式。因此,虽然到目前为止的答案都是指glTF,但您也应该考虑COLLADA,具体取决于您的优先级,用例或者您提到的“回放”应该如何实现。

免责声明:我也是glTF的贡献者。我还创建了glTF tutorial section showing a simple animation和解释some concepts of animations in glTF的那个。您可能会发现它们很有用,但它们显然建立在前面部分中解释的一些概念之上。