X42_VER_V0

This is the starting format. File layout is:

  • File Header
  • Bones
  • Position Times
  • Position Values
  • Rotation Times
  • Rotation Values
  • Scale Times
  • Scale Values
  • Influences
  • Tags
  • Groups
  • Vertex Positions
  • Vertex Normals
  • Vertex Tangent Basis
  • Vertex Attributes
  • Indices

X42_VER_V1

Slight update to the file format. This version introduced support for LODs, who's data segment was inserted before the groups:

  • ...
  • Tags
  • LODs
  • Groups
  • ...

X42_VER_V2a

This version introduced the model flags field.

  • X42_MF_HAS_NORMALS: if this bit is absent the Vertex Normals section does not appear in the file.
  • X42_MF_HAS_TANGENT_BASIS: if this bit is absent the Vertex Tangent Basis section does not appear in the file.
  • X42_MF_HAS_ATTRIBUTES: if this bit is absent the Vertex Attributes section does not appear in the file.
  • X42_MF_PACKED_ROTTRACK: if this bit is set then the Rotation Values are packed into three floats instead of four. The last component is restored as w = sqrt( 1 - x * x - y * y - z * z ).

X42_VER_V2b

This version changes the meaning of the X42_MF_PACKED_ROTTRACK flag. If it is present then the Rotation Values quaternions are stored as four normalized short values.

This change was made because the original packing scheme lost the sign bit of the last component, and while conditionally negating the whole quaternion in order to always have it be positive works in many cases it fails in some. The new format is also smaller than the original.

X42_VER_V3

This version replaces the header's centerBone field with the boundingBox and boundingSphere fields.

X42_VER_V4a

This version breaks the Vertex Attributes data into separate Vertex Texture Coordinate and Vertex Colors segments:

  • ...
  • Vertex Tangent Basis
  • Vertex Texture Coordinates
  • Vertex Colors
  • Indices

It removes support for the following flag bits:

  • X42_MF_PACKED_ROTTRACK
  • X42_MF_HAS_ATTRIBUTES

It also adds the following flag bits:

  • X42_MF_PACKED_BITS: if this bit is present then the advanced bit packing options are enabled.
  • X42_MF_HAS_TEXTURE_COORDINATES: if this bit is absent then the Vertex Texture Coordinates segment is also absent.
  • X42_MF_HAS_COLORS: if this bit is absent then the Vertex Colors segment is absent.

Bit Packing

These changes only take effect if X42_MF_PACKED_BITS is set.

The Model Header section is expanded to include several new fields:

  • packFlags
  • animPack
    • posMin, posMax
    • scaleMin, scaleMax
  • vertPack
    • posMinX, posMaxX, posMinY, posMaxY, posMinZ, posMaxZ
    • tcMinU, tcMaxU, tcMinV, tcMaxV

The packFlags field is broken down into the following options:

X42_PF_ANIM_TRACKS

If this bit is set then the animation track is encoded as follows:

  • Position Values are stored as triples of short that expand to the range [animPack.posMin, animPack.posMax].
  • Rotation Values are packed as they are under X42_MF_PACK_ROTTRACK under X42_VER_V3 and greater.
  • Scale Values are stored as triples of short that expand to the range [animTrack.scaleMin, animTrack.scaleMax].

X42_PF_VERT_POS

If this bit is set then the position track is broken down into Position and Weight tracks:

  • ...
  • Groups
  • Vertex Position XYZs
  • Vertex Blend Indices and Weights
  • Vertex Normals
  • ...

The Vertex Position XYZs data is an array of triples of unsigned short, the first component of which expands to the range [vertPack.posMinX, vertPack.posMaxX], the second to the range [vertPack.posMinY, vertPack.posMaxY], and the third to [vertPack.posMinZ, vertPack.posMaxZ].

The Vertex Blend Indices and Weights is partitioned into segments that must be interpreted based on their respective Group entries. Each segment stores group.maxVertInfluences - 1 index-weight pairs and one additional index. Indices are stored as bytes. Weights are stored as bytes that expand to [0, 1]. The last weight value is inferred as 1 - sum( other weights ).

X42_PF_VERT_NORMALS

If this bit is set then the normals are packed as triples of bytes that expand to [-1, 1].

X42_PF_VERT_TANGENT_BASIS

If this bit is set then the tangents and binormals are packed as triples of bytes that expand to [-1, 1]. Only first of the normal direction flags is kept (as a single byte) which is set to zero if norm = cross( tan, bin ), and one if the normal is the negation of that.

X42_PF_VERT_TEXTURE_COORDINATE

If this bit is set then the Vertex Texture Coordinates segment consists of pairs of unsigned short, the first component of which expands to the range [vertPack.tcMinU, vertPack.tcMaxU], and the second to the range [vertPack.tcMinV, vertPack.tcMaxV].

Group Structure Format

The maximum size of the influences palette is increased to 60 while the maximum number of unique influences in the whole model is reduced to 65,535 (since the palette indices are now stored as unsigned shorts).

The numPrims field is also replaced with a numElems field that lists the number of indices (or vertices, in the case of a non-indexed group) to process in a draw call.

X42_VER_V4b

The time values in the animation tracks are no longer stored in normalized short form, but are now exact frame numbers.