https://wiki.beyondunreal.com/w/index.php?action=history&feed=atom PSK & PSA file formats - Revision history 2017-11-17T22:48:10Z Revision history for this page on the wiki MediaWiki 1.25.1 https://wiki.beyondunreal.com/PSK_%26_PSA_file_formats?diff=46314&oldid=prev Wormbo: Created page with "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 si..." 2016-03-13T18:56:47Z <p>Created page with &quot;A &#039;&#039;&#039;PSK file&#039;&#039;&#039; stores shape and bone tree data for a skeletal mesh. A &#039;&#039;&#039;PSA file&#039;&#039;&#039; stores animation data for a particular skeletal bone tree. The two file types share a si...&quot;</p> <p><b>New page</b></p><div>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.<br /> <br /> [[Category:File formats]]<br /> <br /> ==Shared binary format==<br /> 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.<br /> <br /> ===Chunk layout===<br /> {| class=&quot;wikitable&quot;<br /> |+ General chunk layout, offsets and lengths in decimal numbers<br /> ! Byte Offset !! Byte Length !! Type !! Description<br /> |-<br /> | 0 || 20 || Char[20] || Chunk ID.<br /> |-<br /> | 20 || 4 || Int || Type flags. If this value is decimal 1999801 or smaller, you are seeing the version of PSK/PSA files described here.<br /> |-<br /> | 24 || 4 || Int || Data size - how long each of the following data records are.<br /> |-<br /> | 28 || 4 || Int || Data count - how many data records will follow this header.<br /> |-<br /> | 32 || data size || binary || First data record in the chunk.<br /> |-<br /> | 32 + data size || data size || binary || Second data record in the chunk.<br /> |-<br /> | colspan=&quot;4&quot; | ...<br /> |-<br /> | 32 + (data count - 1) * data size || data size || binary || Last data record in the chunk.<br /> |}<br /> <br /> 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.<br /> <br /> ===PSK file layout===<br /> 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:<br /> <br /> ; File header : Chunk ID is &quot;ACTRHEAD&quot;, 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.<br /> ; Points : Lists the vertex points the mesh consists of. Data set type is [[#Point|Point]].<br /> ; Wedges : Lists the wedges, which basically assign a material UV coordinate to a particular mesh point. Data set type is [[#Vertex|Vertex]].<br /> ; Faces : List of triangle faces, combining three wedges to a triangle. Data set type is [[#Triangle|Triangle]].<br /> ; Materials : List of materials used by the mesh. Data set type is [[#Material|Material]].<br /> ; Reference bones : List of skeletal bones, their reference position and how the skeletal bone tree looks. Data set type is [[#Bone|Bone]].<br /> ; Influences : Defines how points are affected when bones move. Data set type is [[#RawBoneInfluence|RawBoneInfluence]].<br /> <br /> ===PSA file layout===<br /> 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:<br /> <br /> ; File header : Chunk ID is &quot;ANIMHEAD&quot;, 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.<br /> ; Bone names : List of skeletal bones, their reference position and how the skeletal bone tree looks. Data set type is [[#Bone|Bone]]. (Same as for PSK files.)<br /> ; Animation infos : Specifies the animations contained in this file, including name, group, length and affected bones. Data set type is [[#AnimInfo|AnimInfo]].<br /> ; Animation keys : Specifies the position, orientation and time index for a single bone. Data set type is [[#QuatAnimKey|QuatAnimKey]].<br /> <br /> ==Individual data structures==<br /> 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.<br /> <br /> ===Byte===<br /> An 8 bit unsigned integer value corresponding to the UnrealScript type [[byte]].<br /> <br /> ===Short===<br /> A 16 bit integer value, usually assumed to be unsigned.<br /> <br /> ===Int===<br /> A 32 bit integer value corresponding to the UnrealScript type [[int]], but usually assumed to be unsigned.<br /> <br /> ===Float===<br /> A 32 bit floating point value corresponding to the UnrealScript type [[float]] or generally a [[wp:single-precision floating-point format|single-precision floating-point number]].<br /> <br /> ===Char[n]===<br /> A series of exactly ''n'' bytes that are interpreted as a zero-terminated ASCII string filled with additional zero bytes to the required length.<br /> <br /> ===Vector===<br /> An Euclidian vector denoting a position in 3D space, corresponding to the UnrealScript struct type [[Vector]]. Length: 12 bytes.<br /> <br /> {| class=&quot;wikitable&quot;<br /> ! Byte Offset !! Byte Length !! Type !! Name<br /> |-<br /> | 0 || 4 || Float || X<br /> |-<br /> | 4 || 4 || Float || Y<br /> |-<br /> | 8 || 4 || Float || Z<br /> |}<br /> <br /> ===Quat===<br /> A unit [[quaternion]] denoting an orientation or rotation in 3D space, corresponding to the UnrealScript struct type [[Quat]]. Length: 16 bytes.<br /> <br /> {| class=&quot;wikitable&quot;<br /> ! Byte Offset !! Byte Length !! Type !! Name<br /> |-<br /> | 0 || 4 || Float || X<br /> |-<br /> | 4 || 4 || Float || Y<br /> |-<br /> | 8 || 4 || Float || Z<br /> |-<br /> | 12 || 4 || Float || W<br /> |}<br /> <br /> ===ChunkHeader===<br /> The chunk header structure. Length: 32 bytes.<br /> <br /> {| class=&quot;wikitable&quot;<br /> ! Byte Offset !! Byte Length !! Type !! Name !! Description<br /> |-<br /> | 0 || 20 || Char[20] || ChunkID || The chunk name. The Unreal Engine does not really care about this value.<br /> |-<br /> | 20 || 4 || Int || TypeFlags || The Unreal Engine does not really care about this value either, even though it supposedly specifies a file version identifier.<br /> |-<br /> | 24 || 4 || Int || DataSize || The size of each data record potentially following this header. <br /> |-<br /> | 28 || 4 || Int || DataCount || The number of data records following this header.<br /> |}<br /> <br /> ===Point===<br /> Specifies a skeletal mesh vertex point. Length: 12 bytes.<br /> <br /> {| class=&quot;wikitable&quot;<br /> ! Byte Offset !! Byte Length !! Type !! Name !! Description<br /> |-<br /> | 0 || 12 || Vector || Point || The location of the point in the skeletal mesh's reference pose.<br /> |}<br /> <br /> ===Vertex===<br /> Associates skeletal mesh points with a UV coordinate of a material. Length: 12 bytes.<br /> <br /> {| class=&quot;wikitable&quot;<br /> ! Byte Offset !! Byte Length !! Type !! Name !! Description<br /> |-<br /> | 0 || 2 || Short || PointIndex || Index of the point in the points list.<br /> |-<br /> | 2 || 4 || Float || U || U coordinate in the material.<br /> |-<br /> | 6 || 4 || Float || V || V coordinate in the material.<br /> |-<br /> | 10 || 1 || Byte || MatIndex || Index of the material in the materials list. (seems unused, probably overridden by face's own MatIndex)<br /> |-<br /> | 11 || 1 || Byte || Reserved || Padding byte to get to a multiple of four bytes for the structure.<br /> |}<br /> <br /> ===Triangle===<br /> Combined three vertices to a triangle face. Length: 12 bytes.<br /> <br /> {| class=&quot;wikitable&quot;<br /> ! Byte Offset !! Byte Length !! Type !! Name !! Description<br /> |-<br /> | 0 || 3x 2 || 3x Short || WedgeIndex || Indices of the three vertices in the wedges list.<br /> |-<br /> | 6 || 1 || Byte || Matindex || Index of the face's material in the materials list.<br /> |-<br /> | 7 || 1 || Byte || AuxMatIndex || Index of an additional material in the materials list.<br /> |-<br /> | 8 || 4 || Int || SmoothingGroups || Bit field of smoothing groups this face belongs to.<br /> |}<br /> <br /> ===Triangle===<br /> Combined three vertices to a triangle face. Length: 12 bytes.<br /> <br /> {| class=&quot;wikitable&quot;<br /> ! Byte Offset !! Byte Length !! Type !! Name !! Description<br /> |-<br /> | 0 || 3x 2 || 3x Short || WedgeIndex || Indices of the three vertices in the wedges list.<br /> |-<br /> | 6 || 1 || Byte || MatIndex || Index of the face's material in the materials list.<br /> |-<br /> | 7 || 1 || Byte || AuxMatIndex || Index of an additional material in the materials list. (seems unused)<br /> |-<br /> | 8 || 4 || Int || SmoothingGroups || Bit field of smoothing groups this face belongs to. (Does the engine actually care about this for skeletal meshes?)<br /> |}<br /> <br /> ===Material===<br /> Specifies a surface material. Length: 88 bytes.<br /> <br /> {| class=&quot;wikitable&quot;<br /> ! Byte Offset !! Byte Length !! Type !! Name !! Description<br /> |-<br /> | 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.<br /> |-<br /> | 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.)<br /> |-<br /> | 68 || 4 || Int || PolyFlags || Poly flags for all faces with this material. (seems unused)<br /> |-<br /> | 72 || 4 || Int || AuxMaterial || ??? (seems unused)<br /> |-<br /> | 76 || 4 || Int || AuxFlags || ??? (seems unused)<br /> |-<br /> | 80 || 4 || Int || LodBias || ??? (seems unused)<br /> |-<br /> | 84 || 4 || Int || LodStyle || ??? (seems unused)<br /> |}<br /> <br /> ===JointPos===<br /> A helper struct for storing the bone position. Length: 44 bytes.<br /> <br /> {| class=&quot;wikitable&quot;<br /> ! Byte Offset !! Byte Length !! Type !! Name !! Description<br /> |-<br /> | 0 || 16 || Quat || Orientation || Rotation of the bone, relative to its parent.<br /> |-<br /> | 16 || 12 || Vector || Position || Location of the bone, relative to its parent.<br /> |-<br /> | 28 || 4 || Float || Length || ??? (seems unused)<br /> |-<br /> | 32 || 4 || Float || XSize || ??? (seems unused)<br /> |-<br /> | 36 || 4 || Float || YSize || ??? (seems unused)<br /> |-<br /> | 40 || 4 || Float || ZSize || ??? (seems unused)<br /> |}<br /> <br /> ===Bone===<br /> Specifies a node in the skeletal bone tree for both the skeletal mesh and its animations. Length: 120 bytes.<br /> <br /> {| class=&quot;wikitable&quot;<br /> ! Byte Offset !! Byte Length !! Type !! Name !! Description<br /> |-<br /> | 0 || 64 || Char[64] || Name || Name of the bone.<br /> |-<br /> | 64 || 4 || Int || Flags || ??? (seems unused)<br /> |-<br /> | 68 || 4 || Int || NumChildren || Number of child nodes in the skeletal bone tree.<br /> |-<br /> | 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.<br /> |-<br /> | 76 || 4 || [[#JointPos|JointPos]] || BonePos || Bone position information.<br /> |}<br /> <br /> ===RawBoneInfluence===<br /> Specifies the influence of a bone's movement (through animation or otherwise) on a skeletal mesh point's position. Length: 12 bytes.<br /> <br /> {| class=&quot;wikitable&quot;<br /> ! Byte Offset !! Byte Length !! Type !! Name !! Description<br /> |-<br /> | 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.<br /> |-<br /> | 4 || 4 || Int || PointIndex || Index of the affected point in the points list.<br /> |-<br /> | 8 || 4 || Int || BoneIndex || Index of the affecting bone in the bones list.<br /> |}<br /> <br /> ===AnimInfo===<br /> Specifies an animation sequence. Length: 168 bytes.<br /> <br /> {| class=&quot;wikitable&quot;<br /> ! Byte Offset !! Byte Length !! Type !! Name !! Description<br /> |-<br /> | 0 || 64 || Char[64] || Name || Name of the animation sequence.<br /> |-<br /> | 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.<br /> |-<br /> | 128 || 4 || Int || TotalBones || Total number of bones involved in this animation.<br /> |-<br /> | 132 || 4 || Int || RootInclude || ??? (seems unused)<br /> |-<br /> | 136 || 4 || Int || KeyCompressionStyle || ??? (related to animation compression)<br /> |-<br /> | 140 || 4 || Int || KeyQuotum || ??? (related to animation compression)<br /> |-<br /> | 144 || 4 || Float || KeyReduction || ??? (related to animation compression)<br /> |-<br /> | 148 || 4 || Float || TrackTime || ??? (seems unused as it's overridden by AnimRate * NumRawFrames)<br /> |-<br /> | 152 || 4 || Float || AnimRate || Default animation speed in frames per second.<br /> |-<br /> | 156 || 4 || Int || StartBone || ??? (something about partial animations, seems unused)<br /> |-<br /> | 160 || 4 || Int || FirstRawFrame || First entry in the animation keys list for this animation.<br /> |-<br /> | 164 || 4 || Int || NumRawFrames || Number of entries in the animation keys list for this animation.<br /> |}<br /> <br /> ===QuatAnimKey===<br /> Specifies the position, orientation and time index for a single bone in an animation sequence. Length: 32 bytes.<br /> <br /> {| class=&quot;wikitable&quot;<br /> ! Byte Offset !! Byte Length !! Type !! Name !! Description<br /> |-<br /> | 0 || 12 || Vector || Position || Position of the bone at this time index, relative to the parent bone.<br /> |-<br /> | 12 || 16 || Quat || Orientation || Orientation of the bone at this time index, relative to the parent bone.<br /> |-<br /> | 28 || 4 || Float || Time || The duration until the next key.<br /> |}<br /> <br /> ==External links==<br /> * [[udn2:BinaryFormatSpecifications|Binary format specifications for skeletal and vertex animation source files]]</div> Wormbo