KCL (File Format)
KCL Files are collision files used in Mario Kart Wii and many other games. They have been used since at least Mario Kart DS. The documentation here is specifically for the Mario Kart Wii implementation, although other implementations are likely to be similar.
The KCL files contain simplified versions of model files in order to allow rapid collision detection. They use an octree for efficient spatial indexing, as well as storing the actual triangles of the models in a more rapidly accessible format.
The basic file format consists of a header, and four data sections.
The header is a 0x3c byte structure as follows.
|0x00||u32||Offset to section 1.|
|0x04||u32||Offset to section 2.|
|0x08||u32||Offset to section 3.|
|0x0c||u32||Offset to section 4.|
|0x10||single||Unknown. 300.0 typically.|
|0x14||single3||Spatial grid first coordinate.|
|0x38||single||Unknown. 250.0 typically.|
All offsets are relative to the start of the file.
The meaning of the shift and mask values is explained in section 4.
Section 1 - 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 0xc.
Section 2 - Normals
Section 2 is much the same as section 1, in that it is a large array of normals. 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 + 0x10 and dividing by 0xc.
Section 3 - Triangles
The third section is the section containing the actual model information. The offset to this section is stored as 0x10 less than the actual location of the data, because this section is one indexed in section 4. The structure of each entry in this section is a 0x10 byte structure given below.
|0x04||u16||Position index (0 based index into section 1).|
|0x06||u16||Direction index (0 based index into section 2).|
|0x08||u16||Normal A index (0 based index into section 2).|
|0x0a||u16||Normal B index (0 based index into section 2).|
|0x0c||u16||Normal C index (0 based index into section 2).|
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(NormalA,Direction) CrossB = Cross(NormalB,Direction) Vertex1 = Position Vertex2 = Position + CrossB * (Length / Dot(CrossB,NormalC)) Vertex3 = Position + CrossA * (Length / Dot(CrossA,NormalC))
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 = Unit( Cross( Vertex2 - Vertex1, Vertex3 - Vertex1 )) NormalA = Unit( Cross( Direction, Vertex3 - Vertex1 )) NormalB = Unit( -Cross( Direction, Vertex2 - Vertex1 )) NormalC = Unit( Cross( Direction, Vertex2 - Vertex3 )) Length = Dot( Vertex2 - Vertex1, NormalC )
Section 4 - Spatial Index
Section 4 is a spatial index. It is a series of u32 values, followed by lists of u16s. It subdivides three dimensional space using an octree, and indicates which triangles from section 3, if any, appear in each cube of the space. Given a coordinate (x,y,z) in world space, in order to find which triangles are at in range of that location, the spatial grid first coordinate is subtracted from the coordinate. If the value is negative, it is not colliding. If the value is positive, it is rounded to a u32, and then each component is AND'ed with the mask. If the value is non zero, it is also not colliding. If not, then the original u32 components are all shifted right by coordinate shift. The y and z coordinates are then shifted left by their shift values. The resulting components are OR'ed with each other to produce an index into the octree.
The octree is then to be followed until a triangle list is found. At each stage, if the top bit of the current u32 is set, then the remaining 31 bits are an offset to a list of u16 triangle indices. Each of these is a 1 based index to section 3, which is a triangle that must be checked by an object at the original location. The list is 0 terminated. If the top bit is not set, then the remaining 31 bits are an offset to 8 more of the u32s in the octree. The index into these 8 values is calculated by getting the next least significant bit in the u32 of each component, and then shifting z left by 2, y left by 1 and OR'ing them all together. The procedure then repeats with the value at that offset.
The following tools can handle KCL files:
- Collision Tools, by Blank: object ex- and importer, designed for Super Mario Galaxy, but usable for Mario Kart Wii
- CTools, by Chadderz: editor
- SZS Modifier, by Chadderz: editor
- un-beancorner, by Atlas: allows lowering wall collision to prevent clipping over road with walls around them
- Wexos's Toolbox, by Wexos
- Wiimms SZS Tools, by Wiimm: 3D Tools compatible exporter and importer (may create a KCL directly from an OBJ file). Wiimms SZS Tools are recommended for KCL creation, see »Creating a KCL with Wiimms Tools« for details.