【译】glTF教程:动画(七)

【译】glTF教程:动画(七)

2019-02-13

动画

例子:一个简单的动画示例所示,[’ 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所示。


图像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,

    previousTimenextTime之间: interpolationValue = (currentTime - previousTime) / (nextTime - previousTime)

  • 利用插值值计算当前时间的平移量:

    currentTranslation = previousTranslation + interpolationValue * (nextTranslation - previousTranslation)

例子:

假设 currentTime1.2times访问器中的下一个小元素是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所示。


图7b:动画频道。