【译】glTF教程:动画(七)
动画
如例子:一个简单的动画示例所示,[’ Animation ‘ animation
可用于描述节点的’平移’、’旋转’或’缩放’属性如何随时间变化
下面是另一个 animation
的例子。这一次,动画包含两个通道。一个动画平移,另一个动画节点的旋转:
"animations": [
{
"samplers" : [
{
"input" : 2,
"interpolation" : "LINEAR",
"output" : 3
},
{
"input" : 2,
"interpolation" : "LINEAR",
"output" : 4
}
],
"channels" : [
{
"sampler" : 0,
"target" : {
"node" : 0,
"path" : "rotation"
}
},
{
"sampler" : 1,
"target" : {
"node" : 0,
"path" : "translation"
}
}
]
}
],
动画取样器
samplers数组包含animation.sampler
对象,这些对象定义访问器提供的值如何在关键帧之间进行插值,如图7a所示。
为了计算当前动画时间的平移值,可以使用以下算法:
- 将当前动画时间设置为
currentTime
。 -
计算times访问器的下一个更小和下一个更大的元素:
previousTime
= times accessor中小于currentTime
的最大元素nextTime
= times accessor中大于currentTime
的最小元素 -
从对应于这些时间的translation accessor获取元素:
previousTranslation
= 来自*translation * accessor的元素,该元素对应于previousTime
nextTranslation
= 来自translation访问器的元素,对应于nextTime
-
计算插值值。这是一个介于0.0和1.0之间的值,用于描述relative position of the
currentTime
,在
previousTime
和nextTime
之间:interpolationValue = (currentTime - previousTime) / (nextTime - previousTime)
-
利用插值值计算当前时间的平移量:
currentTranslation = previousTranslation + interpolationValue * (nextTranslation - previousTranslation)
例子:
假设 currentTime
是1.2。times访问器中的下一个小元素是0.8。下一个较大的元素是1.6。所以
previousTime = 0.8
nextTime = 1.6
可以从translation accessor中查找对应的值:
previousTranslation = (14.0, 3.0, -2.0)
nextTranslation = (18.0, 1.0, 1.0)
插值值可计算为:
interpolationValue = (currentTime - previousTime) / (nextTime - previousTime)
= (1.2 - 0.8) / (1.6 - 0.8)
= 0.4 / 0.8
= 0.5
由插值值可以计算出当前的平移量:
currentTranslation = previousTranslation + interpolationValue * (nextTranslation - previousTranslation)
= (14.0, 3.0, -2.0) + 0.5 * ( (18.0, 1.0, 1.0) - (14.0, 3.0, -2.0) )
= (14.0, 3.0, -2.0) + 0.5 * (4.0, -2.0, 3.0)
= (16.0, 2.0, -0.5)
因此,当当前时间为1.2时,节点的translation
为 (16.0,2.0,-0.5)。
动画通道
动画包含一个数组 animation.channel
对象。通道在输入(从采样器计算出的值)和输出(动画节点属性)之间建立连接。因此,每个通道引用一个采样器,使用采样器的索引,并包含一个[animation.channel.target
]
(https://github.com/KhronosGroup/glTF/tree/master/specification/2.0/#reference-target).
target
引用一个节点,使用该节点的索引,并包含一个path
,该路径定义了应该动画的节点的属性。采样器的值将写入此属性。
在上面的例子中,动画有两个通道。两者都指向同一个节点。第一通道的路径是指节点的 translation
,第二通道的路径是指节点的rotation
。因此,所有连接到节点上的对象(网格)都会被动画平移和旋转,如图7b所示。