KCL (File Format)/Wii

From Wexos's Wiki
Jump to navigationJump to search

KCL files are collision files, which is the model the game runs collision against. KCL files has been used since at least Mario Kart DS, but this documentation is about the format used in Nintendo DS, Wii and Nintendo 3DS. The only differences is that Nintendo DS uses a specific format which replaces all floats. For other formats, see KCL (File Format).

KCL stores triangle in a format which allow fast access and collision calculation, and has an octree which splits the world space into many cubes, to make the game test collision on less triangles, which allows for much faster collision detection.

File Format

Header

The header is a 0x3C byte structure as follows:

Offset Type Description
0x00 UInt32 Offset to vertex positions, relative to the start of the file.
0x04 UInt32 Offset to directional vectors, relative to the start of the file.
0x08 UInt32 Offset to triangles - 0x10, relative to the start of the file. To get the actual offset, add 0x10 to this value. It works like this because the octree triangle indices are 1-based.
0x0C UInt32 Offset to octree, relative to the start of the file.
0x10 Float Unknown. Always 300.
0x14 Float[3] Octree origin.
0x20 UInt32 X mask.
0x24 UInt32 Y mask.
0x28 UInt32 Z mask.
0x2C UInt32 Coordinate shift.
0x30 UInt32 Y shift.
0x34 UInt32 Z shift.
0x38 Float Unknown. Always 250.

Vertices

Section 1 is simply a large array of vertices, stored as 3 successive singles for x, y and z. The length of this array is not stored, but can usually be calculated by subtracting the section 1 offset from the section 2 offset and dividing by 0x0C.

Directional Vectors

Section 2 is much the same as section 1, in that it is a large array of directional vectors. Again the values are stored as 3 successive singles for x, y and z. The length of this array is not stored, but can usually be calculated by subtracting the section 2 offset from the section 3 offset and dividing by 0x0C.

Triangles

The third section is the section containing the actual model information. The structure of each entry in this section is a 0x10 byte structure given below.

Offset Type Description
0x00 Float Length of triangle.
0x04 UInt16 The index of the first vertex position into the vertex array.
0x06 UInt16 The index of the normal into the directional vector array.
0x08 UInt16 The index of the direction A into the directional vector array.
0x0A UInt16 The index of the direction B into the directional vector array.
0x0C UInt16 The index of the direction C into the directional vector array.
0x0E UInt16 Collision attributes.

All indices in this section are 0 indexed. The position index is an index for section 1, and the others are indices to section 2. The exact manner in which the values are used for collision detection is unknown, however a method for converting this form of triangle to a set of three coordinates is outlined below. The coordinate system is right handed.

CrossA = Cross(DirectionA, Normal)
CrossB = Cross(DirectionB, Normal)
Vertex1 = Position
Vertex2 = Position + CrossB * (Length / Dot(CrossB, DirectionC))
Vertex3 = Position + CrossA * (Length / Dot(CrossA, DirectionC))

A method for converting three vertices into the KCL form is given below. This method assumes the vertices are arranged anti clockwise when viewed from the collidable side.

Position = Vertex1
Direction = Normalize(Cross(Vertex2 - Vertex1, Vertex3 - Vertex1 ))
DirectionA = Normalize(Cross(Normal, Vertex3 - Vertex1 ))
DirectionB = Normalize(-Cross(Normal, Vertex2 - Vertex1 ))
DirectionC = Normalize(Cross(Normal, Vertex2 - Vertex3 ))
Length = Dot(Vertex2 - Vertex1, DirectionC )

Octree

The octree subdivides the world space into cubes, to allow much faster triangle collision detection. The number of root nodes can be calculated by the following algorithm:

NrRootNodes = (~MaskX >> CoordinateShift + 1) * (~MaskY >> CoordinateShift + 1) * (~MaskZ >> CoordinateShift + 1)

Then the number of root nodes are written to the file. These nodes link to more nodes or triangle lists.

Node

Each node has the following structure:

Offset Type Description
0x00 UInt32 Flag: ABBB BBBB BBBB BBBB BBBB BBBB BBBB BBBB

A: 1 means it's a leaf. See below.
B: Offset to next structure, relative to the parent node, or start of octree data if the node is a root node.

If the node is a leaf, then it means it isn't subdivided anymore and it contains triangle lists. This triangle list is terminated by 0, and contains 1-based indices of the triangles that are present in this subspace. If it's not a leaf, then this node is subdivided into 8 more nodes, which the offset into the structure links to.

Tools

The following tools can handle KCL files: