MT5

From Wulinshu
Jump to navigation Jump to search

MT5 is an model container format for Shenmue I.
The model format is based on an node based hierarchy tree.

For an C# implementation based on this documentation look here.

Header

Position Length Type Description
0x00 0x04 string Identifier (HRCM)
0x04 0x04 uint TEXD offset
0x08 0x04 uint First node offset
HRCM Format

The image above shows the general format of the HRCM(.mt5) model format used in Shenmue. The file is broken down into three major sections, the header, model data and texture data. The header is given in the first 12 bytes of the file and provides three values and uint32_t. The first value is the magic number of 'HRCM' indicating the model format. The second value is the offset to the texture data (provided as a list of embedded .pvr images). The third value is the offset to the first node (bone) definition for the model data.

typdef struct {
  uint32_t magic;
  uint32_t texd_ofs;
  uint32_t node_ofs;
} Mt5_Header_t;

MT5 Node

Position Length Type Description
0x00 0x04 uint ID
0x04 0x04 uint Mesh offset
0x08 0x0C short Rotation (X, Y, Z)
0x14 0x0C float Scale (X, Y, Z)
0x20 0x0C float Position/Translate (X, Y, Z)
0x2C 0x04 uint Child offset
0x30 0x04 uint Sibling offset
0x34 0x04 uint Parent offset
0x38 0x04 string Node name
0x3C 0x04 ? Reserved

Mesh Data

Position Length Type Description
0x00 0x04 uint Polytype?
0x04 0x04 uint Vertices offset
0x08 0x04 uint Vertex count
0x0C 0x04 uint Instructions offset
0x10 0x0C float Mesh center (X, Y, Z)
0x1C 0x04 float Mesh radius

Instructions

These instructions are state machine like. Each instruction changes the state of how to render the strip.
Each instruction identifier is 2 bytes long.

  • Instructions can act as padding (2 bytes)
  • Instructions can be followed by a single 2 byte value (4 bytes)
  • Otherwise instructions can provide a list of values of (n) bytes in which the length of the chunk follows the instruction.
Unused (0x0E00, 0x0F00)

Ignored. Skip 10 bytes.

0x0E00 is likely the material definition

  • [ 0x0e00 (2) ] [ 0x08 (2) ] [ 0xffffffff (4) ][ 0x000000ff (4) ]
  • The material definition is often given by the format above.
  • The instruction for 0x0e00 is provided
  • The length of the chunk is declared (static 8 value)
  • The value of 0xffffffff is likely diffuse color rgba(255, 255, 255, 1.0);
  • The value of 0x000000ff is likely ambient color rgba(0,0,0,1);

Note:
Since the color is only ever white, this effectively means the texture is applied directly. This hypothesis can be tested by changing these values to see if it changes the tint of the characters in game.

Unused (0x8000, 0xA000)

Ignored. Skip 2 bytes.

UV Size (0x0B00)

Size of the as UV which divides the raw UV value being read.
Only usable for non-UVH coordinates.

[ 0x0B00 (2) ] [ UV Size 0x400 (2) ]

Strip Attributes (0x0200 - 0x0700)

First byte holds UV flag for how they are interpreted. Holds information about the texture UV wrap modes.

Texture (0x0900)

Sets the texture to use for the next instructions.

[ 0x0900 (2) ] [ Texture Id (2) ]

Strip Group (0x1000 - 0x1400, 0x1800 - 0x1C00)
Position Length Type Description
0x00 0x02 ushort Strip count

These strip groups have the following vertex structure based on the identifiers:

Identifier Vertex Size Description
0x1000, 0x1300, 0x1800, 0x1B00 2 Bytes (Index) Vertex index
0x1200, 0x1A00 2 Bytes (Index) + 4 Bytes (BGRA) Vertex index, Color
0x1100, 0x1900 2 Bytes (Index) + 4 Bytes (UV) Vertex index, UV
0x1400, 0x1C00 2 Bytes (Index) + 4 Bytes (UV) + 4 Bytes (BGRA) Vertex index, UV, Color
  • The index values in each strip group are defined locally to the weighted vertices being defined with the mesh group.
  • Negative index values are defined as relative to the end of the parent node's vertex list
Strip
Position Length Type Description
0x00 0x02 short Strip vertex count

Sometimes the vertex count can be negativ, just abs() it.
The reason for this behavior is to indicate the wind direction of the first triangle when converting from strips to triangles.

let clockwise = stripLen < 0;
for (let i = 0; i < strip.length - 2; i++) {
    let a, b, c;

    if (clockwise && i % 2 === 0) {
        a = strip[i + 1];
        b = strip[i + 0];
        c = strip[i + 2];
    } else {
        a = strip[i + 0];
        b = strip[i + 1];
        c = strip[i + 2];
    }

    let face = new THREE.Face3(a.i, b.i, c.i);
    face.materialIndex = texId;
    this.faces.push(face);

    let auv = new THREE.Vector2(a.u, a.v);
    let buv = new THREE.Vector2(b.u, b.v);
    let cuv = new THREE.Vector2(c.u, c.v);

    this.faceVertexUvs.push([auv, buv, cuv]);
}
Strip "Vertex"
Type Size Description
short 0x02 Vertex index
short 0x04 (optional) Texture Coordinate (UV)
byte 0x04 (optional) BGRA8888 Color

The vertex structure is based on the strip group identifier.
Often the vertex index can be negativ, this is an optimization and is used to point to the parents vertices.
The UV coordinates are UVH (UV high-resolution) and need to be divided by 1024 to get normalized UV coordnates.

End (0x0080)

Defines the end of instructions.

Vertices

The vertices only hold the position and normal of an vertex.

Vertex
Position Length Type Description
0x00 0x0C float Position (X, Y, Z)
0x0C 0x0C float Normals (X, Y, Z)

TEXD (Texture Definition)

This sections holds texture count for the model.

Position Length Type Description
0x00 0x04 string Identifier (TEXD)
0x04 0x04 uint Size in bytes
0x08 0x04 uint Texture count

Texture Entry

The MT5 format support external and embedded textures.

Texture ID

Each texture entry has an texture ID which is 8 bytes long.
The actual data type of the ID is still unknown, sometimes it looks like ASCII strings, Shift-JIS or plain garbage.

Position Length Type Description
0x00 0x08 string Texture ID

TEXN (Texture Entry)

This entry defines an embedded PVRT texture.

Position Length Type Description
0x00 0x08 TextureID Texture ID
0x08 0x0? PVRT Texture

NAME (Texture Names)

This entry defines external PVRT textures each using the texture id for reference.

Position Length Type Description
0x00 0x04 string Identifier (NAME)
0x04 0x04 uint Size in bytes
0x08 0x0? TextureID[] Texture ID Array

TEXL (Texture Library)

This sections holds offsets to the texture IDs.

Position Length Type Description
0x00 0x04 string Identifier (TEXL)
0x04 0x04 uint Size in bytes
0x08 0x04 uint Texture count

TEXL Entry

Position Length Type Description
0x00 0x04 uint Offset to TextureID
0x04 0x04 uint Unknown
0x08 0x04 uint Unknown

PTRL

This sections holds offsets to various parts of the model.
Its purpose is still unclear.

Position Length Type Description
0x00 0x04 string Identifier (PTRL)
0x04 0x04 uint Size in bytes