.TRK File Layout by N.Pattinson(edited by P.A.Flack)
contact: phil@flack99.freeserve.co.uk
or NPattinson@compuserve.com
last revised 19/June1999
15/July/99:  Tutorial on creating a TRK
19/June/99: HTML'd; added pics & extra info.

Overview

The TRK file contains information about the track layout necessary to run the simulation aspects (rather than the graphical aspects) of GPL. The main facets of information are -

The track is divided lengthwise into a number of sections. Each section is either straight or curved. A section has an associated set of walls and surfaces.

The track has a number of lines drawn along it at fixed positions across the track. A height is recorded at the intersection of each line and section boundary. This together with the curvature information from the section produces the track layout. I have
called these lines traces in this document.

The data in the file is layed out as follows

  1. Header
  2. Trace Positions
  3. Section Offsets
  4. Altitude Data
  5. Wall Data
  6. Section Data
There are some 'magic' values used in some fields that appear to normally have a non-magic value. Such values seen so far are:

0x07070707
0x08080808
0x40000000

The following data layouts are all specified in 32bit words.


Header
Bytes Values Notes
0-3 
4-7 
8-11 
12-15
16-19
20-23
24-27
"KART" 
3000 (int)
Length (trk)
Traces (int)
Sections (int)
WallSize (int)
SectionSize (int)
Section Type (reversed) 
Version (3000 for GPL)
Track Length (trk number)
Number of traces (<=16)
Number of sections
Length of wall data
Length of section data


TRK numbers
These are 32bit signed integers, that when divided by 19685.03937 will give a measurement in metres.  Without dividing, they are a count of 2inch lengths.


Trace Positions

There are always 16 trace positions recorded in the file.  Any beyond the 'Number of traces' from the header are unused.  Each trace position is a trk number representing the offset from the nominal track centreline. Negative values are to the right, positive to the left.


Section Offsets

One integer for each section, being the offset of that section within the section data. Since each section's data is 52 bytes long, these numbers are just n * 52


Altitude Data

There is one record per trace per section. Each record is 32 bytes long, giving a total length of 32 * traces * sections
 

Bytes Values Notes
0-3 
4-7 
8-11 
12-15
16-19
20-23
24-27
28-31
trk
trk
trk
trk
trk
trk
trk
trk
Delta1
Delta2
Delta3
Altitude at start of section
Delta4
Delta5
XCoordinate/Radius
YCoordinate/Unused

For a given trace, the start altitude of the next section is always the start altitude of this section plus deltas 1,2 and 3 (allowing for rounding errors). I don't know why there are 3 separate values, or why deltas 4 and 5 exist.

For straight sections, words 6 and 7 are the coordinates of the trace point at the start of the section.
For curved sections, word 6 is the distance to the centre point of this curve, i.e. the radius of this altitude.  Word 7 appears to be unused for curve sections.


Wall Data

NB I have named this section wall data, but it also includes information unrelated to walls.

These records are referenced by the section data - each section has its own number of wall records.

Each record is 32 bytes long.
 

Bytes Values Notes
0-3 
4-7 
8-11 
12-15
16-19
20-23
24-27
28-31
From (trk)
To (trk)
Surface (int)
Unknown1
Height (trk)
Unknown2
0
0
Lateral position at start of section
Lateral position at end of section
Type of surface
Unknown
Height of wall/zero for ground
Unknown
Always zero
Always zero

The from and to attributes are the lateral positions on the track at the start and end of the section respectively, thus describing a line. This line may or may not be a wall. It is also used as the right margin for an area of grip which extends leftwards to the next line.  Currently known surface types are:
 

Type What is it?
1
4
6
10
Track
Grass
Gravel
Leftmost (unused) area of track

2048 is sometimes bitwise or'd with these values, usually when height isn't zero.

The height is the height of a wall if present.

The unknown values probably describe the wall/kerb characteristics (hedge, armco etc)


Section Data

There is one record for each section. Each record is 52 bytes long
 

Bytes Values Notes
0-3 
4-7 
8-11 
12-15
16-19
20-23
24-27
28-31
32-35
36-39
40-43
44-47
48-51
Type (int)
Start (trk)
Length (trk)
Orientation (angle)
unknown1(0)
Curve Centre X (trk)
Curve Centre Y (trk)
Curvature (angle)
unknown2
unknown3
Trace Idx (int)
Wall Count (int)
Wall Idx (int)
Type of section (1=straight, 2=curve)
Distance from start of track
Length of this section
Orientation of the start of this section (note1)
Zero?
If curve, this is the centre of the circle's x coordinate
" y coordinate
Curvature of this section (note 2)
unknown
unknown
First altitude
Number of walls
First wall

The start of the first section is 0. The start plus the length gives the start of the next section. The total length equals the track length in the header.  The orientation is the way the track is pointing at the start of the section. There are sometimes 2 adjacent straight sections with slightly different orientations.

Note 1: Orientation is an integer.  When divided by 2^31 and multiplied by 180.0, the value is in degrees.
Note 2: Curvature is an integer.  When divided by 2^31 and multiplied by 360.0, the value is in degrees.

Curvature is for curves but unknown for straights. The unit is twice the orientation unit. For a curve, the orientation of the next section is the orientation of this section plus the curvature (allowing for rounding errors).

Note 3: For straights, CurveCentreX & CurveCentreY are:  cos (heading in degrees) * (0.5 * 2^31 / 19685.03937), and sin (....).  I don't know what these values do, or even if they are important, but that's how to calculate them :-)
Similarly, for straights, Curvature is replaced by sin (-heading) * (0.5 * 2^31 / 19685.03937), and unknown2 is cos(-heading) * (0.5 * 2^31 / 19685.03937).  Again, who knows???...

There appear to be some magic values used in the two unknowns

The wall count is the number of wall records for this section.  They are sequential from the wall index.


Straight Section Example

This diagram shows a straight section.  The 4 traces are black lines, and the track centre line is green.  The centre line's start coordinate can be found by interpolating the coordinates of the corresponding altitudes.  E.g. if this was section 4, take the four altitudes 16,17,18 and 19, and interpolate their coordinates with respect to the trace values (-10m, -5m, +5m and +10m).  Next, the Orientation and Length can be used to calculate the end point.

Similar calculations can be done to draw the traces themselves, and the start and end lines (red below - +90deg and -90deg to the start and end coordinates).

Next, the walls can be drawn.  In this example, I have drawn 4 walls (yellow), to represent a barrier either side of the track.  The values might be
Wall n: -11m, -8m, armco, unknown, 1.0m, unknown, 0, 0
Wall n+1: -8m, -6m, 1 (track), unknown, 0.0m, unknown, 0, 0
Wall n+2: +8m, +8m, armco, unknown, 1.0m, unknown, 0, 0
Wall n+3: +9m, +9m, 10 (leftmost), unknown, 0.0m, unknown, 0, 0
 


Curved Section Example

Curved sections are much more complicated, but follow the same rules as straight sections.  Firstly, orientation+curvature gives the heading at the end of the section.  Each curved section has a cx,cy pairing to give the centre of the curve (which is an arc of a circle).  Radius is given as the X coordinate of the altitudes for the curved sections.  So there might be 16 altitudes, one per trace.  Interpolating two of these (max. & min.) will enable the radius of the centre line to be found.  From this, orientation and cx,cy,  (sx,sy) can be calculated.  Similarly (ex,ey) can be calculated, and so can the angles for the start and end lines (red/blue in the diagram).

Note 1:  Negative and positive curvatures need to be dealt with separately (usually just a +180, or -radius, etc. difference)
Note 2:  When drawing walls with different start and end laterals, the radius of the arc will not be constant, so you will need to interpolate between the start and end radii to draw the arc (I don't know of any standard graphics function that will do this though...  I wrote my own :-)
 


Errors/Ommissions

I would like to hear about any errors in this description, or any information about the unknown fields. Please email me.



contact: phil@flack99.freeserve.co.uk
or NPattinson@compuserve.com
last revised 19/June1999