Binary data format

The static scene geometry is stored in a standard .obj file. In addition to telling us how the scene is broken into groups (using the "g [groupname]" syntax), the .obj file also provides mesh connectivity (which is constant throughout the animation), texture coordinates, and materials. A more complete description of the .obj file format can be found here. We provide a parser for the format with our viewer source code.

The motion data is stored in a compressed binary format, since it would be too large uncompressed to use practically. All data is in little-endian (PC byte order). All integers are 32 bits and doubles are 64 bits. At the coarsest level, the file consists of a single block containing all the frame animations, followed by a single block for every group in the .obj file:

endian indicatorINTEGER × 1
framerateINTEGER × 1
frame animationsSee below
group 1 animation"
group 2 animation"
... 
group n animation"

We now break down each of these blocks.

Endian indicator

This is just the integer 1. This is simply a check to make sure you have the correct endian-ness; if it appears to be anything other than 1, you may have to flip the byte order.

Framerate of data

This is the framerate of the data. For the data provided here, all framerates are either 30 fps or 120 fps.

Frame animations

Animation for each group is stored with respect to an animated local coordinate frame. We store these frame animations at the beginning of the file.

number of local frames (k)INTEGER × 1
number of timesteps (n)INTEGER × 1
local frame 0, timestep 0 (see below)DOUBLE × 12
local frame 1, timestep 0DOUBLE × 12
local frame 2, timestep 0DOUBLE × 12
... 
local frame k, timestep 0DOUBLE × 12
local frame 0, timestep 1DOUBLE × 12
local frame 1, timestep 1DOUBLE × 12
... 
local frame k, timestep 1DOUBLE × 12
... 
local frame k, timestep nDOUBLE × 12

Each timestep for a particular local frame consists of a 3 × 4 affine transform matrix, stored in row order:

T[0]T[1]T[2]T[3] T[4]T[5]T[6]T[7] T[8]T[9]T[10]T[11] 0001

Here, the upper-left 3 × 3 block is the rotation component of the transform and the 4th column is the translation component.

Group animations

The motion data for each group is stored in the following format:

Name length (l)INTEGER × 1
Group nameCHAR × l
Vertex count (v)INTEGER × 1
.obj file mapping MINTEGER × v
Mean pose (p)DOUBLE × (3v)
Parent frameINTEGER × 1
U row count (m)INTEGER × 1
U column count (n)INTEGER × 1
Basis matrix UDOUBLE × (mn)
Q row count (p)INTEGER × 1
Q column count (q)INTEGER × 1
matrix QDOUBLE × (pq)

Here the group name references a group in the .obj file. The .obj file mapping is a mapping between vertices in the motion data (as they are ordered in p and U) and vertices in the .obj file. M[i] is a vertex index in the .obj file. Note that .obj vertices are 1-indexed.

As described in our paper, the motion for a particular group k is computed as

TWk (pk + Uk Qk)

where the transform TWk operates on each of the vertices independently. In the provided viewer, we use graphics hardware to do this, but otherwise you should perform the following multiplication on 3 × 1 blocks of the vector v = (pk + Uk Qk):

T[0]T[1]T[2]T[3] T[4]T[5]T[6]T[7] T[8]T[9]T[10]T[11] 0001 v 3i 0 v 3i 1 v 3i 2 1