CMDL (Donkey Kong Country Returns)

See CMDL (File Format) for the other revisions of this format.

The CMDL format is DKCR's model format. It's similar to the CMDL format found in the Metroid Prime trilogy, but with a lot of additions and changes, and some layout changes.

Format
Like the previous CMDL formats, DKCR CMDL files are split up into a number of 32-byte aligned sections. Every section both starts and ends on a 32-byte boundary. These are used to separate different parts of the file; different types of sections typically indicate different sets of data. The header declares the section count and the size of each one; using these is the only way to navigate the file.

Flags
The following flags are possible:

Visibility Groups
Visibility group data is present in the header if bit 0x10 is set, after the material set count and before the section sizes. Visibility groups are used to toggle the visibility of certain meshes on or off during animations; for instance, Diddy's jetpack.

The following structure repeats for each group:

Finally, it ends with this before the sizes begin:

Materials
See Materials (Metroid Prime 3)

DKCR uses the same material format as Metroid Prime 3, with the main differences being what pass types and UV animation modes are supported (a few have been added/removed). The only other significant difference in DKCR compared to Prime 3 is that in Prime 3, each material set would get its own section. In DKCR, every material set is in the same section. Each material set begins with a material count, and each material begins with its own size.

Vertex Coordinates
Vertex coords can be stored as either floats or signed shorts, depending whether flag 0x20 is set in the header. If they're shorts, then they need to be divided by 0x2000 to get the corresponding float value. Since they're signed numbers, that means that 0 to 0x7FFF correspond to the range 0.0-4.0, and 0x8000 to 0xFFFF correspond to the range -4.0-0.0.

Normals
Vertex normals are usually stored as shorts. To get the corresponding float value, read as a signed short and divide by 0x4000.

Vertex Color
Normally unused, so this section is typically empty and zeroed out.

Float UV Coordinates
These are stored as a sequence of two floats.

Short UV Coordinates
Like the short vertex coordinates, these are stored as signed shorts that should be divided by 0x2000 to get the corresponding float value. The short UVs section has received a fairly significant increase in usage in DKCR compared to the Prime series; in the Prime games, they were generally only used for lightmaps, whereas in DKCR they're often used by pretty much anything.

Submesh Definitions
This section is very small and simple; it simply declares a submesh count and then lists the offsets to the end of each submesh. Following this section, there'll be one additional section per submesh.

Submesh
There will be one of these sections per submesh. Each submesh starts with a small 0x20-byte header; after that, the primitive data begins.

The primitive data is a standard GX display list. Each primitive begins with a byte that contains the primitive type in the upper 5 bits, and the vertex format setting in the lower 3. After that is a 16-bit vertex count, followed by a series of 16-bit vertex attribute indices.

You'll need to check some settings on the material to read the primitive data properly; the material determines which vertex attributes are present.

There is no primitive count value; you'll need to continue reading data until you hit the end of the primitive table. There are a couple values you can use for reference; either the submesh's section size, or the submesh's end offset. It's not recommended to use the primitive table size value because that value has been shown to be inaccurate in some cases in the Prime series and this may be the case in DKCR as well.

There are 7 primitive types supported by GX, indicated in the upper 5 bits of the flag value. Note that the game only ever actually uses triangles, triangle strips, and triangle fans; however, all of these primitives are supported by GX and are therefore supported by the game, and so they could be used in custom model files.