Always snap to grid
PSK & PSA file formats
A PSK file stores shape and bone tree data for a skeletal mesh. A PSA file stores animation data for a particular skeletal bone tree. The two file types share a similar format and purpose, which is why they are described in the same article.
[edit]
Generally PSK and PSA files consist of a number of binary chunks with a common header. The first chunk is empty and serves as the file header.
Chunk layout[edit]
Byte Offset | Byte Length | Type | Description |
---|---|---|---|
0 | 20 | Char[20] | Chunk ID. |
20 | 4 | Int | Type flags. If this value is decimal 1999801 or smaller, you are seeing the version of PSK/PSA files described here. |
24 | 4 | Int | Data size - how long each of the following data records are. |
28 | 4 | Int | Data count - how many data records will follow this header. |
32 | data size | binary | First data record in the chunk. |
32 + data size | data size | binary | Second data record in the chunk. |
... | |||
32 + (data count - 1) * data size | data size | binary | Last data record in the chunk. |
A chunk may be empty, which is indicated by a data count of zero. In that case, data size may be zero as well. This is particularly true for the file header chunk.
PSK file layout[edit]
A PSK file specifies the skeletal mesh in its reference pose. PSK files seem to always consist of the following types of chunks in the specified order:
- File header
- Chunk ID is "ACTRHEAD", type flags value is decimal 1999801 or lower for the file version described in this article. Data size and data count are zero, denoting an empty chunk body.
- Points
- Lists the vertex points the mesh consists of. Data set type is Point.
- Wedges
- Lists the wedges, which basically assign a material UV coordinate to a particular mesh point. Data set type is Vertex.
- Faces
- List of triangle faces, combining three wedges to a triangle. Data set type is Triangle.
- Materials
- List of materials used by the mesh. Data set type is Material.
- Reference bones
- List of skeletal bones, their reference position and how the skeletal bone tree looks. Data set type is Bone.
- Influences
- Defines how points are affected when bones move. Data set type is RawBoneInfluence.
PSA file layout[edit]
A PSA file specifies animation data for a skeletal bone tree. PSA files seem to always consist of the following types of chunks in the specified order:
- File header
- Chunk ID is "ANIMHEAD", type flags value is decimal 1999801 or lower for the file version described in this article. Data size and data count are zero, denoting an empty chunk body.
- Bone names
- List of skeletal bones, their reference position and how the skeletal bone tree looks. Data set type is Bone. (Same as for PSK files.)
- Animation infos
- Specifies the animations contained in this file, including name, group, length and affected bones. Data set type is AnimInfo.
- Animation keys
- Specifies the position, orientation and time index for a single bone. Data set type is QuatAnimKey.
Individual data structures[edit]
This section lists the data structures involved in the file format. Generally, all multi-byte basic types are considered to be in little endian byte order.
Byte[edit]
An 8 bit unsigned integer value corresponding to the UnrealScript type byte.
Short[edit]
A 16 bit integer value, usually assumed to be unsigned.
Int[edit]
A 32 bit integer value corresponding to the UnrealScript type int, but usually assumed to be unsigned.
Float[edit]
A 32 bit floating point value corresponding to the UnrealScript type float or generally a single-precision floating-point number.
Char[n][edit]
A series of exactly n bytes that are interpreted as a zero-terminated ASCII string filled with additional zero bytes to the required length.
Vector[edit]
An Euclidian vector denoting a position in 3D space, corresponding to the UnrealScript struct type Vector. Length: 12 bytes.
Byte Offset | Byte Length | Type | Name |
---|---|---|---|
0 | 4 | Float | X |
4 | 4 | Float | Y |
8 | 4 | Float | Z |
Quat[edit]
A unit quaternion denoting an orientation or rotation in 3D space, corresponding to the UnrealScript struct type Quat. Length: 16 bytes.
Byte Offset | Byte Length | Type | Name |
---|---|---|---|
0 | 4 | Float | X |
4 | 4 | Float | Y |
8 | 4 | Float | Z |
12 | 4 | Float | W |
ChunkHeader[edit]
The chunk header structure. Length: 32 bytes.
Byte Offset | Byte Length | Type | Name | Description |
---|---|---|---|---|
0 | 20 | Char[20] | ChunkID | The chunk name. The Unreal Engine does not really care about this value. |
20 | 4 | Int | TypeFlags | The Unreal Engine does not really care about this value either, even though it supposedly specifies a file version identifier. |
24 | 4 | Int | DataSize | The size of each data record potentially following this header. |
28 | 4 | Int | DataCount | The number of data records following this header. |
Point[edit]
Specifies a skeletal mesh vertex point. Length: 12 bytes.
Byte Offset | Byte Length | Type | Name | Description |
---|---|---|---|---|
0 | 12 | Vector | Point | The location of the point in the skeletal mesh's reference pose. |
Vertex[edit]
Associates skeletal mesh points with a UV coordinate of a material. Length: 12 bytes.
Byte Offset | Byte Length | Type | Name | Description |
---|---|---|---|---|
0 | 2 | Short | PointIndex | Index of the point in the points list. |
2 | 4 | Float | U | U coordinate in the material. |
6 | 4 | Float | V | V coordinate in the material. |
10 | 1 | Byte | MatIndex | Index of the material in the materials list. (seems unused, probably overridden by face's own MatIndex) |
11 | 1 | Byte | Reserved | Padding byte to get to a multiple of four bytes for the structure. |
Triangle[edit]
Combined three vertices to a triangle face. Length: 12 bytes.
Byte Offset | Byte Length | Type | Name | Description |
---|---|---|---|---|
0 | 3x 2 | 3x Short | WedgeIndex | Indices of the three vertices in the wedges list. |
6 | 1 | Byte | Matindex | Index of the face's material in the materials list. |
7 | 1 | Byte | AuxMatIndex | Index of an additional material in the materials list. |
8 | 4 | Int | SmoothingGroups | Bit field of smoothing groups this face belongs to. |
Triangle[edit]
Combined three vertices to a triangle face. Length: 12 bytes.
Byte Offset | Byte Length | Type | Name | Description |
---|---|---|---|---|
0 | 3x 2 | 3x Short | WedgeIndex | Indices of the three vertices in the wedges list. |
6 | 1 | Byte | MatIndex | Index of the face's material in the materials list. |
7 | 1 | Byte | AuxMatIndex | Index of an additional material in the materials list. (seems unused) |
8 | 4 | Int | SmoothingGroups | Bit field of smoothing groups this face belongs to. (Does the engine actually care about this for skeletal meshes?) |
Material[edit]
Specifies a surface material. Length: 88 bytes.
Byte Offset | Byte Length | Type | Name | Description |
---|---|---|---|---|
0 | 64 | Char[64] | MaterialName | Name of the material. The Unreal Engine will use this to find a texture or other material with this name in any package. |
64 | 4 | Int | TextureIndex | Should be the same as this material's index in the materials list. (But it's probably a good idea to not rely on the value being correct.) |
68 | 4 | Int | PolyFlags | Poly flags for all faces with this material. (seems unused) |
72 | 4 | Int | AuxMaterial | ??? (seems unused) |
76 | 4 | Int | AuxFlags | ??? (seems unused) |
80 | 4 | Int | LodBias | ??? (seems unused) |
84 | 4 | Int | LodStyle | ??? (seems unused) |
JointPos[edit]
A helper struct for storing the bone position. Length: 44 bytes.
Byte Offset | Byte Length | Type | Name | Description |
---|---|---|---|---|
0 | 16 | Quat | Orientation | Rotation of the bone, relative to its parent. |
16 | 12 | Vector | Position | Location of the bone, relative to its parent. |
28 | 4 | Float | Length | ??? (seems unused) |
32 | 4 | Float | XSize | ??? (seems unused) |
36 | 4 | Float | YSize | ??? (seems unused) |
40 | 4 | Float | ZSize | ??? (seems unused) |
Bone[edit]
Specifies a node in the skeletal bone tree for both the skeletal mesh and its animations. Length: 120 bytes.
Byte Offset | Byte Length | Type | Name | Description |
---|---|---|---|---|
0 | 64 | Char[64] | Name | Name of the bone. |
64 | 4 | Int | Flags | ??? (seems unused) |
68 | 4 | Int | NumChildren | Number of child nodes in the skeletal bone tree. |
72 | 4 | Int | ParentIndex | Index of this bone's parent in the bone list. The root bone must be the first in the bone list and have ParentIndex zero. |
76 | 4 | JointPos | BonePos | Bone position information. |
RawBoneInfluence[edit]
Specifies the influence of a bone's movement (through animation or otherwise) on a skeletal mesh point's position. Length: 12 bytes.
Byte Offset | Byte Length | Type | Name | Description |
---|---|---|---|---|
0 | 4 | Float | Weight | How strongly the bone's movement affects the point's location. Values are in the range (0.0; 1.0], i.e. zero weights should not appear in the influences list, because they are meaningless. |
4 | 4 | Int | PointIndex | Index of the affected point in the points list. |
8 | 4 | Int | BoneIndex | Index of the affecting bone in the bones list. |
AnimInfo[edit]
Specifies an animation sequence. Length: 168 bytes.
Byte Offset | Byte Length | Type | Name | Description |
---|---|---|---|---|
0 | 64 | Char[64] | Name | Name of the animation sequence. |
64 | 64 | Char[64] | Group | Group name for the animation sequence. While an animation sequence can be part of multiple groups in the Unreal Engine, the PSA format allows only a single group name to be specified here. You can use the AnimIsInGroup() UnrealScript function in Unreal Engine 2 to check if the currently playing animation in a specified channel is part of a particular animation group. You can use the GetAnimGroup() UnrealScript function in Unreal Engine 1 to get the group name of the currently playing animation. |
128 | 4 | Int | TotalBones | Total number of bones involved in this animation. |
132 | 4 | Int | RootInclude | ??? (seems unused) |
136 | 4 | Int | KeyCompressionStyle | ??? (related to animation compression) |
140 | 4 | Int | KeyQuotum | ??? (related to animation compression) |
144 | 4 | Float | KeyReduction | ??? (related to animation compression) |
148 | 4 | Float | TrackTime | ??? (seems unused as it's overridden by AnimRate * NumRawFrames) |
152 | 4 | Float | AnimRate | Default animation speed in frames per second. |
156 | 4 | Int | StartBone | ??? (something about partial animations, seems unused) |
160 | 4 | Int | FirstRawFrame | First entry in the animation keys list for this animation. |
164 | 4 | Int | NumRawFrames | Number of entries in the animation keys list for this animation. |
QuatAnimKey[edit]
Specifies the position, orientation and time index for a single bone in an animation sequence. Length: 32 bytes.
Byte Offset | Byte Length | Type | Name | Description |
---|---|---|---|---|
0 | 12 | Vector | Position | Position of the bone at this time index, relative to the parent bone. |
12 | 16 | Quat | Orientation | Orientation of the bone at this time index, relative to the parent bone. |
28 | 4 | Float | Time | The duration until the next key. |