Skip to content

Binary CMOD specification

Hleb Valoshka edited this page Apr 11, 2021 · 1 revision

Made by Andrew Tribick at https://celestia.space/forum/viewtopic.php?p=153376&sid=6bed40228aaf5b89c3b60ee9dbc5086b#p153376

While the CMOD ASCII format is documented, as far as I'm aware this hasn't been done for the binary format. I've included the places in the Celestia code base where the enums are defined.

Values are stored in a little-endian format.

Tokens are 16-bit integers. The values are defined in modelfile.h, the equivalents to the CMOD ASCII keywords are as follows:

1001 - material
1002 - end_material
1003 - diffuse
1004 - specular
1005 - specpower
1006 - opacity
1007 - texture
1009 - mesh
1010 - end_mesh
1011 - vertexdesc
1012 - end_vertexdesc
1013 - vertices
1014 - emissive
1015 - blend

Texture semantics are 16-bit integers. These correspond to the numeric values at the end of the "texture" and "texcoord" tokens in the ASCII file. Texture semantics are defined in material.h as follows:

0 - diffuse (texture0, texcoord0)
1 - normal (texture1, texcoord1)
2 - specular (texture2, texcoord2)
3 - emissive (texture3, texcoord3)

Data types (used in the material definitions) are 16-bit integers. The values are defined in modelfile.h:

1 - float1
2 - float2
3 - float3
4 - float4
5 - string
6 - uint32
7 - color

Blend modes are 16-bit integers. The values are defined in material.h, the equivalents to CMOD ASCII keywords are as follows:

0 - normal
1 - add
2 - premultiplied

Vertex attribute semantics are 16-bit integers. The values are defined in mesh.h, the equivalents to CMOD ASCII keywords are as follows:

0 - position
1 - color0
2 - color1
3 - normal
4 - tangent
5 - texcoord0
6 - texcoord1
7 - texcoord2
8 - texcoord3
9 - pointsize
10 - no ASCII equivalent (nextposition) - is this used?
11 - no ASCII equivalent (scalefactor) - is this used?

Vertex attribute formats are 16-bit integers. The values are defined in mesh.h, the equivalents to CMOD ASCII keywords and the corresponding data format are as follows:

0 - f1 - 1×32-bit float value
1 - f2 - 2×32-bit float values
2 - f3 - 3×32-bit float values
3 - f4 - 4×32-bit float values
4 - ub4 - 4×unsigned bytes

Primitive types are 16-bit integers. The values are defined in mesh.h, the equivalents to CMOD ASCII keywords are as follows:

0 - trilist
1 - tristrip
2 - trifan
3 - linelist
4 - linestrip
5 - points
6 - sprites

Overall file structure is essentially the same as a CMOD ASCII file, encoded as follows:

16-byte header "#celmodel_binary" (ASCII encoded)
One or more materials (see below)
One or more meshes (see below)

Materials are encoded as follows:

Token "material" (1001)
One or more of the following properties:
    Token "diffuse" (1003), data type "color" (7), followed by 3×32-bit float values r, g, b.
    Token "specular" (1004), data type "color" (7), followed by 3×32-bit float values r, g, b.
    Token "specpower" (1005), data type "float1" (1), followed by a 32-bit float value.
    Token "opacity" (1006), data type "float1" (1), followed by a 32-bit float value.
    Token "texture" (1007), texture semantic, data type "string" (5), followed by unsigned 16-bit integer length value, followed by specified number of ASCII-encoded bytes.
    Token "emissive" (1014), data type "color" (7), followed by 3×32-bit float values r, g, b.
    Token "blend" (1015), followed by a blend mode.
Token "end_material" (1002)

Meshes are encoded as follows:

Token "mesh" (1009)
Vertex description
    Token "vertexdesc" (1011)
    One or more vertex description entries, each of which consists of:
        Vertex attribute semantic
        Vertex attribute format
    Token "end_vertexdesc" (1012)
Vertex data, consisting of:
    Token "vertices" (1013)
    Unsigned 32-bit integer vertex count
    vertex count×vertex data in format given by the vertex description.
One or more primitives, each of which consists of:
    Primitive type
    32-bit unsigned integer material index
    32-bit unsigned integer index count
    index count×32-bit unsigned integer vertex indices
Token "end_mesh" (1010)