Creating a KCL with Wiimms Tools
This page is a part of the Custom Track Tutorial. Back to the main tutorial page.
Each track needs a collision (KCL) file named course.kcl. This collision file describes how players and items interact with the world. Therefore the collision file contains lists with triangles and an octree based system to find the triangles efficiently while playing. If touching a triangle, its KCL flag is used to determine the action, like boost, wall or fall down.
Normally the KCL triangles are a copy of the 3D world you made with your favorite 3D Tool, but without any textures or color definitions. The KCL world can also have additional planes for invisible borders or for sound and effect triggering. Creation of this model is explained in the Solidity page.
This article describes how to create a KCL file using Wiimms SZS Tools. The new KCL is made from scratch with a maximum of 65535 triangles, the KCL internal limit.
- Wiimms SZS Tools are command line tools (CLI). There is no graphical user interface (GUI). The user have to type the commands including options and parameters into a text console or as script (batch file). The results are printed to the text console, if not redirected. → more CLI details.
- You can use Wiimm's Tool Manager if you're not familiar with CLI.
Create the KCL
The creation of a KCL is done in 3 steps:
- Export a collision model with your 3D Tool.
- Create a KCL flag assignment file.
- Encode (create) the final KCL file.
Create an OBJ file
This step is really easy. Just export your model as OBJ file with your favorite 3D Tool. See »Solidity« for more details. Unfortunately Wiimms SZS Tools do not work well with Blender OBJs so it is recommended to follow the below tutorial to export your model:
The export may contain all groups of the KCL. If any models present in the OBJ are not needed, they can easily filtered by setting KCL flag to -1 in the flag assignment file. Graphics and textures are not needed and ignored by the KCL encoder. If Blender is being used to export the OBJ, the option "Material Groups" needs to be checked in the export settings. This is unchecked by default.
Create a flag assignment file
A flag file should be created by the command wkclt CFF (Create Flag File), which is recommended. The CFF command reads a KCL or an OBJ file and creates a new flag file as template. If the flag file already exists, it is scanned and only new groups are appended at the end of the existing file. A batch file with this script is included in the pack. The file can also be created manually.
The default filename for the flag file is the filename of the OBJ or KCL file with the new extension .flag (»my_track.obj« becomes »my_track.flag«). The old naming extension with .flag.txt is also supported. See option --flag-file for more details.
The flag file contains lines in the format:
object_group_name = flag_value
It is important to prefix each hexadecimal value with '0x', because the file is interpreted by the text parser of Wiimms SZS Tools, which also allows decimal numbers and numerical expressions. If a flag is set to -1, the object group will not be included into the KCL.
grass_1 = 0x0083 grass_2 = 0x0084 boost = 0x0006 wall = 12 + 0x2b20 # numerical expression decoration = -1 # ignore this group * = -1 # ignore all undefined groups
It's no problem to enter your KCL flags separated by type and variant. Just create a function that will calculate the resulting KCL flag for you:
# First, we define a flag function named f(). # This allows us to define type and variant as 2 values. @function f # (type,variant) @return $1 | $2 << 5 @endfunction # And now we assign the KCL flags to the group names grass_1 = f(0x03,0x004) grass_2 = f(0x04,0x004) boost = f(0x06,0x000) wall = 0x2b2c # mixed usage is also possible decoration = -1 # ignore this group * = -1 # ignore all undefined groups
Encode the KCL file
The command to create the KCL is:
wkclt encode course.obj --kcl=drop
The file course.flag.txt is read automatically, if it exists. This command creates the file course.kcl, but only, if the file does not exist. The recommended option --kcl=drop is discussed below. To overwrite an existing file, add option --overwrite (or short -o):
wkclt encode course.obj --kcl=drop -o
It is a good idea to write a script (.bat batch file) that contains your creation command with all options. This allows to just click the script to execute the command(s). A batch file with this script is included in the pack.
@echo off wkclt encode course.obj --kcl=drop -o pause
There are only some limits while creating the KCL file:
- The number of triangles can't exceed 65535 (0xFFFF), because the octree use only 16 bits for triangle references and value 0 is reserved as end of list marker.
- The number of vertex and normal vectors can't exceed 65536 (0x10000) because of the 16 bit limit of indices. This is not a problem for the vertex section, because each triangle use exact 1 vertex vector. But a triangle needs 4 normal references. Therefore the KCL encoder tries to find duplicates of normals and vertex values to reduce the section size.
The new KCL file is always created from scratch. So the new KCL file is garbage free.
If you're generating your KCL file from scratch now and don't need to set anything else, you should be done with it (for now); move on to the KMP Editing tutorial. You can also test your track now to make sure the KCL works, but you might want to at least set a start position in the KMP before that.
The keyword list of option --kcl defines, how the OBJ+KCL processor internally works. There are different options to remove unwanted triangles, to change the vertex order, to define the material mode for OBJ export and much more. All options are explained in Wiimms KCL Guide.
@echo off wkclt encode export.obj -Nod course.kcl --kcl drop,rm-facedown --scale 1.45 --hrot 90 pause
The command wkclt encode ...
- reads the file export.obj as source, search the file export.flag for KCL flag assignments.
- drops all non regular triangles (--kcl drop).
- remove all face down roads (and other drivable faces) (--kcl rm-facedown).
- scales the model by factor 1.45 for all 3 dimensions (--scale 1.45).
- rotates the model horizontal counterclockwise by 90 degree (--hrot 90).
- do not make KCL checks (-N).
- stores the result as file course.kcl (-d course.kcl).
- overwrites an already existing file named course.kcl (-o).
Ignoring small triangles
Sometimes, the imported file contains very small triangles with an area smaller than 1 unit2. They were accidentally inserted into the model by the user. Because of the small size, the user will not see them in the model view of their 3D Tool. However, machines like the KCL importer of these tools see them and insert them into the KCL — this is not a bug with the tools. The Wii has (mathematical) problems processing them correctly, resulting in KCL glitches like mini walls on the road.
Since v1.58a there are 2 new options: --tri-area=EXPR and --tri-height=EXPR to filter out triangles that are too small.
Option --tri-area=EXPR defines the minimal area size of KCL triangles. The intention is to ignore triangles that are generally too small. EXPR is a floating point number or expression. Triangles are invalidated if their area size is smaller than EXPR. Values between 0.01 and 4.0 are recommended. The careful value 1.0 is used as default. Value 0 disables this filter functionality.
Option --tri-height=EXPR defines the minimal height of KCL triangles. The intention is to ignore deformed triangles (very slim, but long). EXPR is a floating point number or expression. Triangles are invalidated if at least 1 of the 3 heights is smaller than EXPR. Values between 0.01 and 2.0 are recommended. The careful value 1.0 is used as default since v1.58b. Value 0 disables this filter functionality.
The tests for both options are executed after reading files, after transformations, and after calculating normals and lengths.
It is recommended to use v1.58b or later of Wiimm's SZS Tools if creating a KCL.
# set minimal area size to 5.0 and minimal height to 0.5 (=1/2) wkclt encode --tri-area 5 --tri-height 1/2 .... # patch an existing track with same limits wszst patch track.szs --tri-area 5 --tri-height 1/2 --kcl new,drop
Removing garbage from old KCL files
Some older tools create a KCL file, by using an already existing KCL file as base and injecting it with the new data. This has 2 major issues:
- The limited size of the base KCL limits the number of vertices, normals and triangles and also the size of the octree.
- The file contains old triangles, that uses any of the overwritten vertices and normals. The results are unreal triangles, sometimes with invalid vertex coordinates. These triangles are ignored by the KCL processing of the Wii, because they are not referenced by the octree. But if exporting or modifying the KCL, the triangles becomes valid with invalid values.
These unreferenced/unused/invalid triangles can be removed by adding --kcl drop to any command.
# create a new KCL, drop unneeded triangles wkclt encode course.kcl --dest new.kcl --kcl drop # export to an object file, drop unneeded triangles wkclt decode course.kcl --kcl drop # short info dump of a kcl file, but ignore unneeded triangles wkclt db course.kcl --kcl drop # info dump of a kcl file in a track [[SZS]], but ignore unneeded triangles wkclt dump mytrack.szs --kcl drop # show kcl flag statistics of a track file, but ignore unneeded triangles wkclt flags mytrack.szs --kcl drop
Create a small KCL
The tools accept 3 keywords for option --kcl to control the size of the KCL. The main aspect is, how many faces of the neighborhood should be included into the face list of a cube. The keywords are:
- Set the parameters to values to get a relative small KCL file. The neighborhood distance is set to 200. Until now not any disadvantage of SMALL was found. But don't use small if you plan a track with speed factor ≥1.5.
- This is the default. It is anywhere in the middle between SMALL and CHARY. The neighborhood distance is set to 400.
- The parameters are set to Nintendo-like values, that are very careful. This blows up the octree significantly, because of the large neighborhood distance of 600.
Creation of a small KCL may help to reduce the Slow Motion Bug. This is especially true, if the old KCL was made with other tools.
wkclt encode course.kcl --kcl small,drop,rm-facedown wszst patch track.szs --kcl new,small,drop,rm-facedown
Export to OBJ
If you want to make a KCL file visible in a 3D Tool, just export it as OBJ file. For custom tracks it is a good idea to remove unreferenced triangles (see above) and add --kcl drop to the command.
# decode an obj file wkclt decode course.kcl --kcl drop # cat the KCL in OBJ format to a destination wkclt cat course.kcl --kcl drop >new.obj # cat the KCL of a track in OBJ format to a destination wkclt cat track.szs --kcl drop >new.obj
If using any of the wkclt commands, the option --kcl-script=filename allows to define a script to manipulate the the KCL data:
- Remove existing triangles.
- Add new triangles.
- Change the positions of triangles.
- Change the KCL-Flag of triangles.
For the selection of existing triangles, flag, vertex positions, normals and length can be used.
The following sub sections show some examples for popular manipulations. If you want to use more than one of the example scripts, just copy them into one new script file.
Remove face down roads
If roads are defined with face up and face down triangles, a KCL glitch is possible. It is because after jumps the driver can be some pixel below the road. In this case, the face down road becomes active for a short time and vehicle+driver drives in any unwanted direction and the camera view changes rapidly.
In general, there is no need for face down roads. This is also true for all other drivable KCL types like offroad, boost or trick ramp. The following script detects face down drivable triangles (by analyzing the KCL type and the first normal) and removes them:
#--- remove face down roads @def start = mSec() # start time, for the status line @def rm_count = 0 # reset status counter @for t=0; tri$n()-1 # for each triangle (index 0 based) @pdef type = tri$flag(t) & 0x1f # get the KCL type @if kcl$drive & (1<<type) # if it is a drivable KCL type @def norm = tri$normal(t,0) # get the first normal @if norm.y < 0 # if it is face down @def stat = tri$remove(t) # remove the triangle @def rm_count = rm_count + 1 # increment the counter @endif # endif @endif # endif @endfor # print out a summary line @echo " - " rm_count " face down road triangles removed in " (mSec()-start) " msec."
To use the script, extend the command with --kcl-script remove-face-down.txt:
wkclt encode course.obj -o --kcl-script remove-face-down.txt
Since v1.02a it is possible to remove the face down roads directly without a script:
wkclt encode course.obj -o --kcl DROP,RM-FACEDOWN
The option --kcl RM-FACEDOWN does the same as the script above. The advantage of the script is the better fine control: The user can select KCL types and/or track areas to remove the triangles. Combine the RM-FACEDOWN option with DROP, so that additionally all invalid and unused triangles are removed.
You know the problem: Jumping over borders is impossible. If hitting the hard walls, you fall down immediately. This is not a problem of Nintendo's tracks and can be solved by lowering the walls about 20–50 units.
If creating the KCL, you can establish a script that can fix the walls. The script lower-walls.txt is part of the distribution and looks like this:
############################### ### (c) Wiimm, 2015-12-18 ### ############################### # Setup @def start = mSec() # start time, for the status line @def mod_count = 0 # modification counter # Get the value for lowering the walls. # If 'lower' is defined as number by option --const => use it. # Otherwise use the default of 30. @def lower = isNumeric(lower) ? lower : 30 # Limit to walls with inclination <45 degree # If 'degree' is defined by option --const as number >0 => use it. # Otherwise use the default of 45 degrees. @def degree = isNumeric(degree) && degree > 0 ? degree : 45 @def sin_degree = sin(degree) # Define a function to test the KCL flag for walls @function isWall # flag @pdef t = $1 & 0x1f @return t == 0x0c || t == 0x0d || t == 0x0f || t == 0x14 || t == 0x1e || t == 0x1f @endfunction # Main loop: Iterate through all triangles @for t=0;tri$n()-1 @if isWall(tri$flag(t)) @def norm = tri$normal(t,0) # get the first normal @if abs(norm.y) < sin_degree # it's a vertical wall -> lower the wall & increment counter @def status = tri$shift(t,-vy(lower)) @def mod_count = mod_count+1 @endif @endif @endfor # Print a little status line @echo " - " mod_count " of " tri$n() " triangles lowered by " lower > " in " (mSec()-start) " msec."
To use the script, extend the command with --kcl-script lower-walls.txt:
wkclt encode course.obj -o --kcl-script lower-walls.txt
The default is to lower walls with inclination <45 degree by 30 units. Both values can be changed by the command line using option --const:
wkclt encode course.obj -o --kcl-script lower-walls.txt --const lower=50,degree=30
Lowering the walls is also possible for existing KCL files. For custom tracks it is a good idea to remove unreferenced triangles (see above) and add --kcl drop to the command.
wkclt encode course.kcl --dest new.kcl --kcl-script lower-walls.txt --kcl drop
With version v0.39 of Wiimms SZS Tools you can also use the COPY command:
wkclt copy course.kcl new.kcl --kcl-script lower-walls.txt --kcl drop
- Wiiki articles:
- Wiimms SZS Tools
- Wavefront OBJ file (file format)
- Wikipedia: Wavefront .obj file
Introduction – Textures – Scale – Modeling ⇒ Using Blender – BRRES: CTools
BRRES: BrawlBox – Minimap – Solidity – KCL: Wiimms Tools – KMP Editing
Object Editing – Cameras – Cannons – Post-effects – Videos
Getting Files – BrawlBox Tricks – Animations – Shadows – Mipmaps
Moving Terrain – Music – Ports – Paint Remakes – Tutorial Archive
Extended presence flags: Track Tutorial – LE-CODE Track FAQ