UDN
Search public documentation:

BinaryFormatSpecifications


Interested in the Unreal Engine?
Visit the Unreal Technology site.

Looking for jobs and company info?
Check out the Epic games site.

Questions about support via UDN?
Contact the UDN Staff

Binary format specifications for skeletal and vertex animation source files

Last updated by Michiel Hendriks, updated for v3323 and redone parts of the layout. Original author - Erik de Neve (EpicGames).

Skeletal animation and mesh source binaries

As exported by ActorX from Max or Maya, the PSA and PSK binary files contain the raw animation and mesh information used to import skeletal animation art into the Unreal engine. Specifications are given here to aid anyone interested in expanding the format or writing 3rd party utilities for it (skin painter programs, exporters for other 3d packages, etc. )

PSK format:

This contains the mesh, bone influence indices and weights for each vertex, the bone names, bone hierarchy, and skeletal default pose.

PSK format, Version 1.0 (note: all headers are of type VChunkHeader). In general the file is constructed from header, data pairs. The header specifies (in the Datacount field) the number of data entries that follow.

Order of appearance Description
General Header When the Typeflag value equals decimal 1999801 or lower it denotes this version 1.0 layout of the PSK file.
Points Header Header specifying number of points, defined in Datacount.
Points Data Array with VPoint .
Wedges Header Header specifying amount of wedges.
Wedges Data VVertex wedges array (a wedge consists of a UV pair with an index into the 3d points array.)
Faces Header Header specifying amount of faces.
Faces Data VTriangle faces array.
Materials Header Header specifying amount of materials.
Materials Data VMaterial Materials array.
Bones Header Header specifying amount of bones.
Bones Data VBone bones array.
Influences Header Header specifying amount of bone influences.
Influences Data VRawBoneInfluence array of Influences.

PSA format:

PSA files contain the bone names, one or more sequence names, and for each sequence, its frame number N, and tracks of N rotations and N translations for each bone.

PSA format, Version 1.0. (note: all headers are of type VChunkHeader). Just like the PSK file the PSA file is constructed from header, data pairs.

Order of appearance Description
General Header When the Typeflag value equals decimal 1999801 or lower it denotes this version 1.0 layout of the PSA file.
Bones Header Header specifying amount of bones.
Bones Data FNamedBoneBinary bone names array.
Animations Header Header specifying amount of animation sequence info chunks.
Animations Data AniminfoBinary array of animation sequence info chunks.
Raw keys Header Header specifying amount of raw keys.
Raw keys Data VQuatAnimKey array.

The raw key array holds all the keys for all the bones in all the specified sequences, organized as follows:

For each AnimInfoBinary's sequence there are [Number of bones] times [Number of frames keys] in the VQuatAnimKeys, laid out as tracks of [numframes] keys for each bone in the order of the bones as defined in the array of FnamedBoneBinary in the PSA.

C++ structures used

The relevant structs and classes are outlined in this header file:

https://udn.epicgames.com/pub/Two/BinaryFormatSpecifications/UnrealAnimDataStructs.h

Note that all structures are assumed padded to multiples of DoubleWord (32 bit) sizes by VC++ - when writing custom code, putting #pragma pack(push,1) around the definitions will break psa/psk binary compatibility. The default packing can be forced with #pragma pack(push,4). Fortunately the 'wasted' space is not an issue because this is for the raw data only. The same padding is assumed in the editor's import code as well as in the Max/Maya exporters.

Animation data inside the engine

Once the data from the PSK (now digested into native skeletal mesh) and PSA (digested into a native animation object containing one or more sequences) are associated together at runtime, bones are linked up by name. Any bone in a skeleton (from the PSK) that finds no partner in the animation sequence (from the PSA) will assume its reference pose stance ( as defined in the offsets & rotations that are in the VBones making up the reference skeleton from the PSK)

The native animation and mesh code data as imported into the editor's animation browser, takes the shape of UKX package files - see the AnimBrowserReference doc.

Vertex animation

The classic vertex animation raw data format hasn't changed since Unreal 1 - though in the engine, rendering has been sped up since, and now works with continuous level-of-detail, unlike skeletal meshes, which - since UT2003 - uses static LOD levels.

Overal CPU overhead for vertex animated meshes is still much larger than for skeletal meshes, so vertex animation should never be your first choice if you can achieve the same animation with a skeletal setup and a reasonable number of bones. Also, the vertex mesh animation code does not support any blending features.

Tools used to generate vertex animated meshes include the Max and Maya ActorX exporter plugins and the older 3DS2UNR tool.

Like the skeletal animation raw data, we have both a 'reference' mesh and the animation data, though unlike skeletal, these two have to be imported together and are inextricably linked; Vertex animation cannot be shared between multiple meshes.

By convention, the mesh's face UV mapping and vertex index data resides in the "Data" file with the extension *_d.3d, while the animation "Aniv" data file has the extension *_a.3d.

The relevant C++ structures mentioned are defined in detail in https://udn.epicgames.com/pub/Two/BinaryFormatSpecifications/UnrealVertexAnimation.h

The files contain the following data:

Data file format

Order of appearance Description
File Header type FJSDataHeader
NumPolygons : number of faces, as present in the array below.
NumVertices : number of vertices.
Data Array of [] elements of type FJSMeshTri

One important clarification: since UT2003, the Flags byte in each FJSMeshTri is no longer relevant since properties like translucency and double-sidedness are now derived from the assigned materials, rather than the intrinsic mesh-face properties they used to be in Unreal 1.

Animation file format

Order of appearance Description
File Header type FJSAnivHeader
NumFrames : number of animation frames, as present in the array below.
FrameSize : size in BYTES of each frame; i.e. number of vertices * 4.
Data Array of ( NumFrames * NumVertices ) 32-bit packed XYZ vectors.

When importing - which can only be done by recompiling the .u scripts, not through the editor as with skeletal animation - it is up to script code to designate sequence names to subsections of the frame sequence.