BTG file format
Terrain in FlightGear is currently stored using the Binary Terrain Format, in *.btg
or *.btg.gz
files.
These files contain geometry in the form of points, individual triangles, triangle strips and triangle fans.
The authoritative source for the format definition is the SimGear class SGBinObject
(doxygen), which is defined in:
For standard airports, all the lighting points locations and types (and orientation) are computed by terragear and then encoded in a simple format. This is read in by the "btg" loader and then lights are created dynamically on the fly by FlightGear. The light creation scheme could be replaced with something that creates much more realistic lights along with the posts and all the other bits. But light position, type, and orientation is available for all airport lights[1]
General Structure
Each BTG-File contains a header followed by a variable number of objects. Each object is introduced by a header indicating the type of object, the number of associated properties and the number of elements contained in the object.
Coordinates
All coordinates in the file (except for texture coordinates) are cartesian geocentric coordinates.
In order to allow more compact storage, all coordinates are stored as single precision floating point values relative to the center of a bounding sphere, except for the bounding sphere itself, which is stored in double precision format.
All measurements are in meters.
Texture Coordinates
Texture coordinates are used to map textures onto 3D faces. For this each corner vertex of a face is associated with the location of the texture pixel to be shown at this corner. The texture is then projected onto the face using interpolation between the corner vertices.
The x- and y-parts of the coordinates are specified in the range 0.0 to 1.0, where the location (0,0)
relates to the origin of the texture and an x- respectively y-part of 1.0 corresponds to vertices at full width respectively height of the texture.
Texture coordinates exceeding the range 0.0 to 1.0 are wrapped around, so that repeating textures are possible. For example if the x-parts of the texture coordinates of a face cover the range -2.0 to 3.0, the texture repeats five times horizontally. TerraGear makes heavy use of this feature for larger areas of the same material.
Endianness
The files are stored in Little Endian, i.e. the least-significant byte is stored first.
Alignment
Some of the structures used in this file format are not properly aligned, i.e. not all fields start at an offset which is a multiple of their size.
Therefore special care is to be taken when translating these definitions into record types, e.g. C or C++ struct
, as the compiler must be instructed not to enforce proper alignment.
Header
Byte offset | Type | Description |
---|---|---|
0 | unsigned short | Version (currently 7 or 10) |
2 | unsigned short | Magic Number 0x5347 ("SG") |
4 | unsigned int | Creation Time (seconds since the epoch) |
8 | unsigned short | Number of Toplevel Objects |
In files before version 7, the number of toplevel objects was interpreted as a signed short, leading to a maximum number of 32767 objects in a single file.
Objects
Each object starts by an object header.
Byte offset | Type | Description |
---|---|---|
0 | char | Object Type (see below) |
1 | unsigned short | Number of Object Properties |
3 | unsigned short | Number of Object Element |
The object type can be one of the following:
Code | Object Type |
---|---|
0 | Bounding Sphere |
1 | Vertex List |
2 | Normal List |
3 | Texture Coordinates List |
4 | Color List |
9 | Points |
10 | Individual Triangles |
11 | Triangle Strips |
12 | Triangle Fans |
The object header is followed by a list of properties. The number of properties in this list is given by the Number of Object Properties field.
Byte offset | Type | Description |
---|---|---|
0 | char | Property Type (see below) |
1 | unsigned int | Number of Bytes in Property Data |
5 | bytes | Property Data |
The property type can be one of the following (see the object type descriptions for more details):
Code | Property Type |
---|---|
0 | Material |
1 | Index Types |
Similarily, each element starts with a single unsigned integer, giving the number of bytes the element's data occupies.
Bounding Sphere Object
The Bounding Sphere object gives the bounding sphere of the tile, defined by a center and a radius.
The properties of a Bounding Sphere are ignored.
The elements of the Bounding Sphere object are bounding spheres. Even though more than one bounding sphere may be stored in such an object, all except for the last one found in the file are ignored.
Byte offset | Type | Description |
---|---|---|
0 | unsigned int | number of bytes in this element |
4 | double | x-part of the center |
12 | double | y-part of the center |
20 | double | z-part of the center |
28 | float | radius of the bounding sphere |
Note that the element may be longer than 32 bytes, but only the first 32 bytes are actually used.
Vertex List
The Vertex List object contains a list of vertices to be referenced by other geometry primitives.
The properties of a Vertex List object are ignored.
Each element of a Vertex List object is a list of vertices. Each of the vertices gets a unique index, starting with 0 for the first vertex found in the file and incrementing by 1 for each further vertex.
Byte offset | Type | Description |
---|---|---|
0 | unsigned int | number of bytes in this element |
4 | vertices | vertex list |
Each vertex is a triple of single precision floating point values:
Byte offset | Type | Description |
---|---|---|
0 | float | x-part of the vertex coordinate |
4 | float | y-part of the vertex coordinate |
8 | float | z-part of the vertex coordinate |
The number of vertices in an element is therefore the number of bytes in the element divided by 12.
Normal List
The Normal List contains a list of normals to be referenced by other geometry primitives.
The properties of a Normal List object are ignored.
Each element of a Normal List object is a list of normals. Each of the normals gets a unique index, starting with 0 for the first normal found in the file and incrementing by 1 for each further normal.
Byte offset | Type | Description |
---|---|---|
0 | unsigned int | number of bytes in this element |
4 | normals | normal list |
Each normal is a triple of signed bytes, interpreted as fixed point values:
Byte offset | Type | Description |
---|---|---|
0 | byte | x-part of the normal coordinates |
1 | byte | y-part of the normal coordinates |
2 | byte | z-part of the normal coordinates |
The individual parts are interpreted by dividing each of the parts by 127.5 and subtracting 1.0, leading to a linear mapping from the range of 0...255 to the range of -1.0...1.0.
Texture Coordinates List
The Texture Coordinates List object contains a list of texture coordinates to be referenced by other geometry primitives.
The properties of a Texture Coordinates List object are ignored.
Each element of a Texture Coordinates List object is a list of texture coordinates. Each of the coordinates gets a unique index, starting with 0 for the first coordinate found in the file and incrementing by 1 for each further coordinate.
Byte offset | Type | Description |
---|---|---|
0 | unsigned int | number of bytes in this element |
4 | texture coordinates | texture coordinate list |
Each texture coordinate is a pair of single precision floating point values:
Byte offset | Type | Description |
---|---|---|
0 | float | x-part of the texture coordinate |
4 | float | y-part of the texture coordinate |
The number of coordinates in an element is therefore the number of bytes in the element divided by 8.
Color List
The Color List object contains a list of color definitions to be referenced by other geometry primitives.
The properties of a Color List object are ignored.
Each element of a Color List object is a list of color definitions. Each of the colors gets a unique index, starting with 0 for the first color found in the file and incrementing by 1 for each further color.
Byte offset | Type | Description |
---|---|---|
0 | unsigned int | number of bytes in this element |
4 | color definitions | color definition list |
Each color definition is a 4-tuple of single precision floating point values:
Byte offset | Type | Description |
---|---|---|
0 | float | red part |
4 | float | green part |
8 | float | blue part |
12 | float | alpha part |
The number of coordinates in an element is therefore the number of bytes in the element divided by 16.
Geometry Objects
All geometry objects are structured the same way, with each element consisting of a list of index-tuples referencing vertex, normal, color and texture coordinate lists.
Each geometry object may have a Material and an Index Types property.
The material is a string (not null-terminated) indicating the name of the material. There are some special types of materials reserved to indicate that the geometry represents lights instead of solid structure.
The Index Types property is a single byte containing bit field indicating the lists referenced by each entry in the tuple-list. The meaning of the bits is given in the following table:
Bit Number | Description |
---|---|
(least significant) 0 | Each entry has a vertex index |
1 | Each entry has a normal index |
2 | Each entry has a color index |
3 | Each entry has a texture coordinate index |
If no Index Types property is given, the tuples contain a vertex and a texture coordinate index. The only exception is the Point object type, which only has vertex indices by default.
Each element of the object is a list of tuples, containing one or more unsigned short integers in the following order:
- Vertex Index,
- Normal Index,
- Color Index, and
- Texture Coordinate Index.
Only those fields indicated by the Index Types property are included in the file. For example, if the Index Types property indicates that each entry has only a vertex index and a normal index, each entry consists of 4 bytes, the first 2 bytes containing the vertex index and the second 2 bytes containing the normal index.
The indices reference the respective lists, i.e. the vertex index references the vertex list.
We assume that the individual elements are numbered sequentially, starting with index 0 for the first element.
Points
In case of the Points object type, each of the elements represents a single point, e.g. a point lightsource.
Individual Triangles
In case of the Triangle object type, three succeeding elements are combined to form the vertices of a single triangle.
The vertices of triangle i
(starting with 0 for the first triangle) are given by elements 3*i
, 3*i+1
and 3*i+2
.
To represent n
triangles the list must therefore contain 3*n
elements.
Triangle Strips
The Triangle Strips object type also represents triangles, but in a more compact form. Any three succeeding elements in the list represent a triangle.
The vertices of triangle i
(starting with 0 for the first triangle) are given by elements i
, i+1
and i+2
.
In order to represent n
triangles the list must therefore contain n+2
elements.
Triangle Fans
Triangle Fans are similar to Triangle Strips.
However, in case of triangle fans, all triangles share the first element and the other two triangle vertices are provided in pairs of elements, representing a fan of triangles around a single vertex.
The vertices of triangle i
(starting with 0 for the first triangle) are given by elements 0
, i+1
and i+2
.
To represent n
triangles the list must therefore contain n+2
elements, similar to triangle strips.
Related content
- Blender and BTG, import/export .btg files in/from Blender.
|
- ↑ curt (Jan 7th, 2011). Re: LOWI Airport Light System add-on (test version) .