Search code examples
gltf

How to parse animations.samplers.input from gltf


The spec explains the animations.samplers.input property as:

The index of an accessor containing keyframe input values, e.g., time. That accessor must have componentType FLOAT. The values represent time in seconds with time[0] >= 0.0, and strictly increasing values, i.e., time[n + 1] > time[n].

However, I'm having a bit of trouble understanding this from the first basic example on the demo repo, Animated Triangle

Specifically, if we bring the relevant binary data for the animation from animation.bin and decode it into a Float32Array, we get the following list of values:

[0, 0.25, 0.5, 0.75, 1, 0, 0, 0, 1, 0, 0, 0.7070000171661377, 0.7070000171661377, 0, 0, 1, 0, 0, 0, 0.7070000171661377, -0.7070000171661377, 0, 0, 0, 1]

This of course does not make sense in light of "strictly increasing values".

What am I misunderstanding here? How are these values meant to be used (in combination with output) in order to update the rotation over time?

Note that animation.bin is the view referenced from the input sampler. In other words, from the gltf

  • input == accessor 2
  • accessor 2 == bufferView 2
  • bufferView 2 == bytes(0-100) from buffer 1
  • buffer 1 == animation.bin

Solution

  • You've decoded too far. Although bufferView 2 is bytes 0 to 100, accessor 2 does not call for all those bytes. Here's accessor 2:

    {
      "bufferView" : 2,
      "byteOffset" : 0,
      "componentType" : 5126,
      "count" : 5,
      "type" : "SCALAR",
      "max" : [ 1.0 ],
      "min" : [ 0.0 ]
    },
    

    Note the count: 5 in there. Count is defined as:

    The number of attributes referenced by this accessor, not to be confused with the number of bytes or number of components.

    So, accesessor 2 is the first five SCALAR values from offset 0 in bufferView 2, namely the first five numbers from your decoded output above:

    [0, 0.25, 0.5, 0.75, 1]
    

    FWIW, there are tools to help investigate glTF binary files. Here's the "Peek Definition" function from VSCode's glTF extension:

    Decoded accessor

    (Disclaimer, I'm one of the authors of this extension, although I did not write this decode feature myself).