Roto serialisation format

See also Curve serialisation format

Curve tree

The curve tree consists of a hierarchy of one or more layers, each containing zero or more curvegroups. Here we give a general description of the format, using AUgmented Backhaus Naur Form.

It disregards some fine lexer details, and is not necessarily suitable for turning directly into a parser. In particular, it has not been checked for ambiguity in the definition, and begin and end can be followed and preceded by whitespace.

begin                          = "{"

end                            = "}"

float                          = "0x" 8HEXDIG
float                          =/ ["-"] (1*DIGIT "." 1*DIGIT) / 1*DIGIT

  ; Floating point numbers can, in addition to being written out as normal
  ; decimals literals, be written out as hexadecimal literals (represented
  ; under IEEE 754).  For endianness considerations, see serialisation code
  ; further down.

int                            = ["-"] 1*DIGIT

unquoted-char                  = "!" / %x23-26 / %x28-5B / %x5D-7B / %x7C / %x7E

  ; everything ASCII except space, " ' \ { }

escaped-char                   = %x7D DQUOTE   ; "
escaped-char                   =/ %x7D %x27    ; '
escaped-char                   =/ %x7D %x5C    ; \
escaped-char                   =/ %x7D %x7B    ; {
escaped-char                   =/ %x7D %x7D    ; }

printable-char                 = unquoted-char / escaped-char

string                         = 1*unquoted-char
string                         =/ DQUOTE 0*printable-char DQUOTE

  ; the effect of this is that a string with space, " ' \ { } within it must be
  ; quoted

flag                           = int

  ; Flags are a bitmask.  See below for the significance of the bits.

wsp                            = 1*SP

view-name                      = string

attribute-name                 = string

  ; the view name "-" means the default view.

anim-curve-key-time            = float

anim-curve-key-value           = float

anim-curve-key-left-tangent    = wsp float wsp float

anim-curve-key-right-tangent   = wsp float wsp float

anim-curve-key-interpolation   = wsp int

  ; This is a bitmask.  The interpolation type can be found when masked
  ; with 255; the extrapolation can be found when shifted right 8 bits and
  ; masked with 255.
  ;
  ; The defined interpolation types are:
  ;   0 - step
  ;   1 - linear
  ;   2 - cubic
  ;
  ; The default value for this is "256" - i.e. linear extrapolation
  ; and step interpolation.

anim-curve-key-extra           = wsp "-"
anim-curve-key-extra           =/ anim-curve-key-left-tangent [anim-curve-key-right-tangent [anim-curve-key-interpolation]]

anim-curve-key                 = begin anim-curve-key-time wsp anim-curve-key-value [anim-curve-key-extra] end
anim-curve-key                 =/ begin anim-curve-key-time end

  ; Together these mean that a basic anim curve key consists of a group with
  ; time and value, separated by spaces, and then a list of optional
  ; elements that are in order the left tangents (2 floats), the right
  ; tangents (2 floats) and then the the interpolation type (which is a
  ; bitmask)
  ;
  ; If any of these are not provided the tangents default to 0 and the
  ; interpolation defaults to 256.  Instead of the optional elements, the
  ; literal "-" can be provided, which defaults both tangents to (0, 1) and
  ; the interpolation to 256.
  ;
  ; If this consists of only one element, then this represents the time
  ; alone, and can only appear as a medial or final element in the key-list.
  ; The other fields are copied from the immediately previous curve key.

anim-curve-expression          = "=" string
anim-curve-key-list            = anim-curve-key 0*(wsp anim-curve-key)

anim-curve-constant-value      = float

anim-curve-rle-key-count       = int

anim-curve-rle-key-entry       = begin anim-curve-key anim-curve-rle-key-count end

  ; The anim-curve-key is repeated anim-curve-key-count numbers of times,
  ; with each key's time being incremented by one from the base.

anim-curve-rle-key-list        = anim-curve-rle-key-entry 0*(wsp anim-curve-rle-key-entry)

anim-curve-data                = anim-curve-constant-value
anim-curve-data                =/ begin anim-curve-key-list end
anim-curve-data                =/ begin "r" begin anim-curve-rle-key-list end end

anim-curve-flag-entry          = begin "f" wsp flag end

  ; Flag entry consists of a group with "f" followed by the actual flag value
  ;
  ; There are no interesting flags on curves.  Ignore this.  Do not write it
  ; out.

anim-curve                     = anim-curve-data
anim-curve                     =/ begin [anim-curve-expression wsp] [anim-curve-flag-entry wsp] anim-curve-data end

  ; If there is no animation, an anim-curve can be represented as a single
  ; value, with no futher grouping at this level.
  ;
  ; Alternatively, it will be represented as a keylist, or possibly as an
  ; RLE keylist.
  ;
  ; If these is a flag and/or an expression then this will itself be wrapped
  ; in a group, with the expression or flag.

anim-curve-timeless-key        = anim-curve-key-value / ( begin anim-curve-key-value anim-curve-key-extra end )

  ; Similar to anim-curve-key but without time, which is fed in at a higher
  ; level and shared between multiple curves.  As an additional compaction
  ; step, if the tangents and interpolation are default values (i.e. 0 and
  ; 56), then it will be a single value outside a group, without the braces.

anim-curve-timeless-data-count = int

anim-curve-timeless-data-entry = anim-curve-timeless-key
anim-curve-timeless-data-entry =/ begin "x" wsp anim-curve-timeless-data-count wsp anim-curve-timeless end

anim-curve-timeless-data       = anim-curve-timeless-data-entry [wsp anim-curve-timeless-data-entry]

  ; Keylists for timeless data consists of elements which are either a
  ; timeless key in themselves (which might be a float literal if the
  ; tangents and interpolation is to be copied from the previous key), or a
  ; group which contains "x", a count, and then the actual key, for repeats
  ; of the same values.
  ;
  ; The time is fed in from outside

anim-curve-timeless            = anim-curve-key-value
anim-curve-timeless            =/ anim-curve-timeless-data
anim-curve-timeless            =/ begin [anim-curve-expression wsp] [anim-curve-flag-entry wsp] anim-curve-timeless-data end

anim-curve-views-entry         = view-name wsp anim-curve

anim-curve-views-list          = anim-curve-views-entry [wsp anim-curve-views-entry]

  ; This consists of the view as a string followed by the anim-curve.

anim-curve-views               = anim-curve
anim-curve-views               =/ begin "v" anim-curve-views-list end

  ; An anim-curve-views can be a regular anim-curve.  If so, then this is
  ; the "default" curve, and no others are split.  If it is split then it
  ; will be a group with "v" as its first element, followed by a number of
  ; view-curve entries (not themselves groups).

anim-attribute-entry           = attribute-name wsp anim-curve-views

anim-attribute-list            = anim-attribute-entry 0*(wsp anim-attribute-entry)

anim-attributes                = begin "a" anim-attribute-list end

  ; An AnimAttributes block is made up of a group containing "a", to
  ; indicate a set of attributes, then the name and curve for each
  ; attribute in turn.  Omitted attributes are set to the default,
  ; which will depend upon the type of object these attributes
  ; are for.
  ;
  ; Shape points have 2 dimensions.  Strokes have a third dimension,
  ; used for storing pressure.

anim-control-point             = begin [anim-attributes] 1*4(wsp anim-curve) end

  ; An AnimControlPoint consists of a group containing optionally, a list
  ; of attributes, and then up to four AnimCurves, one for each
  ; dimension.

anim-control-point-timeless    = begin [anim-attributes] 1*4(wsp anim-curve-timeless) end

  ; The timeless version of an AnimControlPoint uses anim-curve-timeless
  ; objects instead of AnimCurves.

anim-cubic-curve-flag-entry    = begin "f" wsp flag end

anim-cubic-curve-tension       = float

anim-cubic-curve-tension-entry = begin "tens" wsp anim-cubic-curve-tension end

key-times-list                 = begin float 1*(wsp float) end

anim-cubic-curve-points-list   = begin "p" wsp anim-control-point 0*(wsp anim-control-point) end
anim-cubic-curve-points-list   =/ begin "px" wsp key-times-list wsp anim-control-point-timeless 0*(wsp anim-control-point-timeless) end

  ; There are two versions of the cubic curve points list.  If all
  ; the AnimCurves within it use the same keyframes, then these are
  ; extracted outwards and a "px" group is made, with that keylist as
  ; the next element in the group - this is then followed by all the
  ; control point data.  This means it doesn't need to keep repeating
  ; common keyframes.
  ;
  ; However, it is not structurally built into the cubic curve that
  ; all control points or dimensions within must be keyed on the
  ; same sets of frames, they may be individually controled.  So a
  ; simpler format exists, which will write out all the control points
  ; in full.
  ;
  ; Note that the attributes are independent of this.

anim-cubic-curve               = begin "cc" wsp anim-cubic-curve-flag-entry [wsp anim-cubic-curve-tension-entry] wsp anim-cubic-curve-points-list end

  ; A cubic curve is a group containing the declaration "cc", the
  ; flags for the curve, an optional tension entry if the tension is
  ; non-default (the default being 0.5) followed by a point-list
  ; in either full or compact format.

anim-curve-group               = begin anim-cubic-curve wsp "idem" end
anim-curve-group               = begin anim-cubic-curve wsp anim-cubic-curve end

  ; An AnimCurveGroup is a group containing exactly two cubic curves.
  ; The first of these is always specified in full, and is the main
  ; curve.  The second of these is the feather, which is specified as
  ; an offset to the main curve (or rather, the 'absolute' points on the main
  ; become offsets to the corresponding ones, whereas the tangents,
  ; which were offsets from those absolute points on the main curve, become
  ; offsets from the absolute points on the feather.
  ;
  ; The feather curve can be replaced simply with "idem", which means
  ; that the feather is identical to the main curve: all the absolute offsets
  ; are zero, and the tangents are the same.

anim-curve-group-views-entry   = view-name wsp anim-curve-group

anim-curve-group-views         = anim-curve-group
anim-curve-group-views         =/ begin "v" anim-curve-group-views-entry 0*(wsp anim-curve-group-views-entry) end

anim-node-curve-type           = "bezier" / "bspline" / "catmullrom"

anim-node-name                 = string

anim-node-flag                 = int

anim-transform                 = begin "t" wsp anim-curve-views 1*(wsp anim-curve-views) end
anim-transform                 =/ begin "tx" wsp key-times-list anim-curve-timeless 1*(wsp anim-curve-timeless) end

 ; An AnimTransform consists of a bunch of animations for each transform curve
 ; these are in order - the pivot point (xyz), the translation (xyz), the scale (xyz),
 ; the rotation (xyz), the skew (xyz), the extra translation (xyz), the skew order;
 ; and then a 4x4 extra matrix.  These default to 0, except for the scale, which
 ; defaults to (1, 1, 1), and the matrix, which defaults to the identity matrix.
 ; any fields not present are the default.
 ;
 ; Transform and rotation orders are fixed, as there is no way of adjusting them
 ; in the UI, and therefore do not appear in the file format.  skew order is
 ; 0 = xy, 1 = yx

anim-curve-group-node          = begin "curvegroup" wsp anim-node-name wsp anim-node-flag wsp anim-node-curve-type wsp anim-curve-group-views wsp anim-transform wsp anim-attributes end

  ; An AnimCurveGroupNode is a group containing a declaration of its
  ; type, a node name, a flag, a curve type, a curve groups list (which
  ; might contain one curve group or one for several diffferent view),
  ; and then a transform and an attributes.
  ;
  ; The default attributes are as follows
  ;    0   : ro go bo ao bm inv mbo mbsot mbso fx fy ft src stx sy str sr sskx
  ;          ssky sso stot sto sv sb ltt tt pt
  ;    1   : vis r g b a opc mb fo ff ssx ssy sf nv view1 ltn ltm
  ;    0.5 : mbs
  ;    240 : spy
  ;    320 : spx

anim-curve-node                = begin "cubiccurve" wsp anim-node-name wsp anim-node-flag wsp anim-node-curve-type wsp anim-cubic-curve wsp anim-transform wsp anim-attributes end

  ; An AnimCurveNode is similar to the AnimCurveGroupNode, except that it only
  ; contains one curve, and that this cannot be split. (the attributes and transforms
  ; can be split)
  ;
  ; The default attributes are as follows
  ;    0    : bu bm ds dh bt inv src stx sty str sr sskx ssky sso sb
  ;           stot sto sv ltt tt ws ep1 ep2 ep3 nv1 view1
  ;    0.05 : bsp
  ;    0.2  : h
  ;    1    : vis r g b a ro go bo ao opc dt ssx ssy sf ltn ltm we
  ;           cookie hard_boundary boundary ab
  ;    25   : bs
  ;    240  : spy
  ;    320  : spx

anim-node                      = anim-curve-group-node / anim-curve-node / anim-layer-node

  ; An AnimNode can be either a CurveGroup, a CubicCurve or a Layer.
  ;
  ; Which is distinguished by the first keyword inside the group.

anim-node-list                 = [anim-node 1*(wsp anim-node)]

anim-layer-node                = begin "layer" wsp anim-node-name wsp begin "f" wsp anim-node-flag end wsp anim-transform wsp anim-node-list end

  ; A Layer node.  This contains a name, some flags, a transform, and then some more nodes.
  ;
  ; The default attributes are as follows
  ;   0     : fx fy pt
  ;   0.5   : mbs
  ;   1     : vis opc mbo mb fo ff warp

anim-tree-version              = float

anim-tree-version-entry        = begin "v" wsp anim-tree-version end

anim-tree-flag-entry           = begin "f" wsp flag end

anim-tree-root-entry           = begin "n" anim-layer-node end

anim-tree                      = begin anim-tree-version-entry wsp anim-tree-flag-entry wsp anim-tree-root-entry end

Floating point format

Floating point values are stored in binary encoded format (‘x01234567’), you can use the following code to convert between the two:

Values of 0.0f and 1.0f (zero and one) are special cased and stored just as ‘0’ or ‘1’.

From floating point to binary encoded:

std::string toString(float fltValue)
{
  static const char* hexDigits = "0123456789abcdef";

  unsigned int value = *reinterpret_cast<unsigned int*>(&fltValue);

  char buf[10];

  buf[9] = '\0';
  buf[8] = hexDigits[(value & 0xf)];
  value >>= 4;
  buf[7] = hexDigits[(value & 0xf)];
  value >>= 4;
  buf[6] = hexDigits[(value & 0xf)];
  value >>= 4;
  buf[5] = hexDigits[(value & 0xf)];
  value >>= 4;
  buf[4] = hexDigits[(value & 0xf)];
  value >>= 4;
  buf[3] = hexDigits[(value & 0xf)];
  value >>= 4;
  buf[2] = hexDigits[(value & 0xf)];
  value >>= 4;
  buf[1] = hexDigits[(value & 0xf)];
  buf[0] = 'x';

  return std::string(buf);
}

From binary encoding to floating point:

float toFloat(const char* str) {
  int value = 0;
  sscanf(str, "x%x", &value);
  return *reinterpret_cast<float*>(&value);
}

Layers

Layers can contain other layers or curve groups

Curve Groups

Curve groups specify the actual curve data for both Bezier and B-Spline curves.

There’s normally two curves in a curve group; the main curve and a feather curve (which can be the same as the main curve, unless the feather has been dragged out.)

SplineWarp curves only contain a main curve.

Keyframes and Animation

Keyframes are defined within a curvegroup in a {px …} block

{px {key0_time key1_time ...}
  {
    {a attribute_name {attribute_value_at_key0}}
    {control_point_position_at_key0}
  }
  {
    {a attribute_name {attribute_value_at_key1}}
    {control_point_positions_at_key1}
  }

  #...
}

Flags

Flag

Binary

Bit shift

eBreakFlag

000000000000000000000001

(1<<0)

eTangentLengthLockFlag

000000000000000000000010

(1<<1)

eKeySelectedFlag

000000000000000000000100

(1<<2)

eLeftTangentSelectedFlag

000000000000000000001000

(1<<3)

eRightTangentSelectedFlag

000000000000000000010000

(1<<4)

eOpenFlag

000000000000000000100000

(1<<5)

eSelectedFlag

000000000000000001000000

(1<<6)

eActiveFlag

000000000000000010000000

(1<<7)

eVisibleFlag

000000000000000100000000

(1<<8)

eRenderableFlag

000000000000001000000000

(1<<9)

eLockedFlag

000000000000010000000000

(1<<10)

ePressureInZFlag

000000000000100000000000

(1<<11)

eNukeAnimCurveEvalFlag

000000000001000000000000

(1<<12)

eRelativeTangentFlag

000000000010000000000000

(1<<13)

Attribute Names

Attribute name

script key

Notes

kRedAttribute

r

Colour

kGreenAttribute

g

kBlueAttribute

b

kAlphaAttribute

a

kFeatherOnAttribute

fo

Feather on/off

kFeatherXAttribute

fx

Relative X coordinate

kFeatherYAttribute

fy

Relative Y coordinate

kFeatherFallOffAttribute

ff

kFeatherTypeAttribute

ft

kBrushSizeAttribute

bs

RotoPaint: Brush size

kBrushSpacingAttribute

bsp

RotoPaint: Brush spacing

kOpacityAttribute

opc

Opacity

kHardnessAttribute

h

kSourceAttribute

src

kBlendingModeAttribute

bm

kBrushTypeAttribute

bt

RotoPaint: Brush type

kBuildUpAttribute

bu

RotoPaint

kDynamicTransparencyAttribute

dt

kDynamicSizeAttribute

ds

kDynamicHardnessAttribute

dh

kViewAttribute

view

kNumberOfViewsAttribute

nv

kInvertedAttribute

inv

kMotionBlurOnAttribute

mbo

Motion blur

kMotionBlurAttribute

mb

kMotionBlurShutterAttribute

mbs

kMotionBlurShutterOffsetTypeAttribute

mbsot

kMotionBlurShutterOffsetAttribute

mbso

kSourceTranslateXAttribute

stx

kSourceTranslateYAttribute

sty

kSourceTranslateRoundAttribute

str

kSourceRotateAttribute

sr

kSourceScaleXAttribute

ssx

kSourceScaleYAttribute

ssy

kSourceSkewXAttribute

sskx

kSourceSkewYAttribute

ssky

kSourceSkewOrderAttribute

sso

kSourcePivotPointXAttribute

spx

kSourcePivotPointYAttribute

spy

kSourceTimeOffsetTypeAttribute

stot

kSourceTimeOffsetAttribute

sto

kSourceFilterAttribute

sf

kSourceBlackOutsideAttribute

sb

kSourceViewAttribute

sv

kLifeTimeNAttribute

ltn

Life time start

kLifeTimeMAttribute

ltm

Life time end

kLifeTimeTypeAttribute

ltt

kWriteOnStartAttribute

ws

kWriteOnEndAttribute

we

kRedOverlayAttribute

ro

kGreenOverlayAttribute

go

kBlueOverlayAttribute

bo

kAlphaOverlayAttribute

ao

kEffectParameter1Attribute

ep1

kEffectParameter2Attribute

ep2

kEffectParameter3Attribute

ep3

kToolTypeAttribute

tt

kPlanarTrackLayerAttribute

pt

kVisibleAttribute

vis

kTensionAttribute

t

kRepeatAttribute

rp

kTensionExponentAttribute

te

kCutoutAttribute

hard_boundary

SplineWarp only

kBoundaryAttribute

boundary

SplineWarp only

kWarpAttribute

warp

SplineWarp only

kMixAttribute

mix

SplineWarp only

kABAttribute

ab

SplineWarp only - whether the curve is in A or B

kCookieCutAttribute

cookie

SplineWarp only

kAnimCurveKeyframeRLE

r

Run-length encoding for key frames (as value, length pairs)