This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Galileo Asset File Format

Galileo is an asset file format for game engines, designed to be easy to implement, efficient to load, and simple enough to adapt to existing application designs.

The Galileo format can be implemented incrementally, only supporting a subset of asset types. For example if your application only needs mesh assets, you can choose to implement only Galileo Mesh assets without worrying about any of the other asset types.

The Galileo specification is a draft in early in development and is subject to change. This notice will be removed when the specification is released.

1 - Introduction

Document Conventions

Normative Terminology

The key words MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, MAY and OPTIONAL, when uppercase and emboldened, are normative and have special meaning. These words are to be interpreted as described in BCP 14.

Technical Terminology

slice - A bounded view into an array represented by a pointer or index of the first element of the slice, and a count of elements.

External specifications

Bradner, S., Key words for use in RFCs to Indicate Requirement Levels, BCP 14, RFC 2119, March 1997. Leiba, B., Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words, BCP 14, RFC 8174, May 2017. https://www.rfc-editor.org/info/bcp14

What’s next?

2 - Overview

File data

Galileo assets MUST be encoded in little-endian binary.

File structure

A Galileo asset MUST contain a 36 byte File_Header and a variable length Asset_Body.

struct Galileo_File {
    File_Header     header;     // 36 bytes
    Asset_Body      body;       // variable length
};

The File_Header contains metadata applicable to any asset type, while the Asset_Body contains information specific to its asset type.

All asset types fall under two categories: primitive assets and aggregate assets.

  • Primitives are the lowest-level, “raw data” assets such as meshes, images and audio files. These are self contained and MAY be implemented individually.

  • Aggregates are higher-level collections of other assets - they contain references to other asset files, as well as augmenting data. Where specified, aggregate asset implementations MUST also implement any possible asset types that can be referenced.

What’s next?

3 - Header

Metadata that is common to all asset types, and may be useful to know before parsing the entire file contents.
+-----------------------------------------------------------------------------------------------+
|00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31|
+-----------+-----------+-----------------------------------------------+-----------+-----------+
|   Magic   | Spec ver. |             Asset UUID version 4              | Type enum | Checksum...
+-----------+-----------+-----------------------------------------------+-----------+-----------
            |
 -----------+
struct File_Header {
    uint8_t[4]      magic;                      // String "GALI"
    uint32_t        specification_version;      // Using semantic version - uint8_t major, uint8_t minor, uint16_t patch 
    uint128_t       asset_uuid;                 // UUID version 4
    uint32_t        asset_type;                 // Asset_Type enum backed by a uint32_t
    uint64_t        asset_checksum;             // xxhash XXH3 of the file contents, EXCLUDING the file header.
};
//  36 bytes total

See also

What’s next?

4 - Primitive assets

Lowest level, “raw data” assets.

WIP

Planned:

  • Image
  • Audio

What’s next?

4.1 - Mesh asset

A primitive asset for storing vertex data.

Mesh overview

Mesh assets store an object’s vertex data, and how the vertices are connected to form triangles.

Mesh body

+------------------------+-------------------------+--------------------------+
|        40 bytes        |       n * 64 bytes      |       m * 32 bytes       |
|      Mesh manifest     | Vertex group info array |   Extension info array   |
+------------------------+-------------------------+--------------------------+
| Buffer
+-----------------------------------------------------------------------------
                                      ...
 -----------------------------------------------------------------------------+
                                                                              |
 -----------------------------------------------------------------------------+
struct Asset_Body_Mesh {
    Mesh_Manifest           manifest;               // 40 bytes
    Vertex_Group_Info       []vertex_group_infos;   // Count provided in manifest. 55 bytes each.
    Extension_Info          []extension_infos;      // Count provided in manifest. 32 bytes each.
    uint8_t                 []buffer;               // Size provided in manifest.
};

A mesh asset body MUST contain a 40 byte Mesh_Manifest, followed by a variable length array of 55 byte Vertex_Group_Info structs. Mesh assets MAY include a variable length array of 32 byte Extension_Info structs.

The count of Vertex_Group_Info structs and Extension_Info structs MUST be provided in the manifest.

Manifest

+-----------------------------------------------------------------------------------------------+
|00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31|
+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
|                              Bounding Box                             | VG count  | Ext count |
+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
|      Buffer size      | Next ext. |
+-----------------------+-----------+
struct Mesh_Manifest {
    float32_t[6]    bounding_box;           // center.xyz, extents.xyz. Extents are half of box dimensions.
    uint32_t        vertex_group_count;
    uint32_t        extension_count;
    uint64_t        buffer_size;

    uint32_t        next_mesh_extension;    // (index + 1) into extension info array. Zero indicates no extensions.
};

A mesh MUST contain one or more vertex groups. Each vertex group SHOULD correspond to one draw call in the renderer, and MAY be used to draw different parts of a mesh with a different material or shader.

A vertex group MUST contain sub-buffer offsets for each vertex attribute.

Vertex Group Info

+-----------------------------------------------------------------------------------------------+
|00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31|
+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
|                              Bounding Box                             |  Buf slice begin idx  |
+-----------+-----------+-----------+-----------+-----------+-----------+--+--+--+--+-----------+
|    Buf slice size     |       Idx count       |      Vert count       |TC|CL|JW|EX| Next ext. |
+-----------+-----------+-----------+-----------+-----------+-----------+--+--+--+--+-----------+
struct Vertex_Group_Info {
    float32_t[6]    bounding_box;               // center.xyz, extents.xyz. Extents are half of box dimensions.
    uint64_t        buffer_slice_begin_index;
    uint64_t        buffer_slice_size;
    
    uint32_t        index_count;
    uint32_t        vertex_count;

    uint8_t         texcoord_channel_count;
    uint8_t         color_channel_count;
    uint8_t         joint_weight_channel_count;
    uint8_t         extension_attribute_channel_count;
    
    uint32_t        next_attribute_extension;   // (index + 1) into extension_info array. Zero indicates no extensions.
};

A vertex group MUST have an index buffer. Its count MUST be a multiple of 3.

A vertex group MUST have the following attributes:

  • float32_t[3] position
  • float32_t[3] normal
  • float32_t[4] tangent

A vertex group MAY have zero or more channels of the following attributes:

  • uint16_t[2] texcoord (in unorm format)
  • uint8_t[4] color (in RGBA format)
  • uint16_t[4] joints
  • uint16_t[4] weights
  • application-specific extension attributes

The number of joint and weight channels for a vertex group MUST be equal.

Buffer

All vertex attribute data for a given vertex group MUST be contiguous and de-interleaved.

For any attributes with multiple channels, all channels of the same attribute type MUST be contiguous and de-interleaved.

+==== Vert group 0 ====+
|  Index list          |
+----------------------+
|  Position            |
+----------------------+
|  Normal              |
+----------------------+
|  Tangent             |
+----------------------+
|  ? Texcoord[0]       |
+----------------------+
|  ? Texcoord[1]       |
+----------------------+
|  ? Color[0]          |
+----------------------+
|  ? Color[1]          |
+----------------------+
|  ? Joints[0]         |
+----------------------+
|  ? Joints[1]         |
+----------------------+
|  ? Weights[0]        |
+----------------------+
|  ? Weights[1]        |
+----------------------+
|  ? Ext attributes[0] |
+==== Vert group 1=====+
|  Index list          |

           ...         
|                      |
+======================+
|  ? Extension data[0] |
+----------------------+

Reference implementation

A reference implementation can be found in the Callisto repository.

5 - Aggregate assets

Assets that are collections of, or store references to other assets.

WIP

Planned:

  • Material - Associates a shader with uniforms (images, etc.)
  • Model - Associates a mesh and materials (one per vertex group)
  • Construct - Somewhere between a scene and prefab. Transform hierarchy with hardpoints.
  • Archive - A compressed collection of many related assets.

6 - Extensions

Provides application-specific data related to an asset.

Extension Info

+-----------------------------------------------------------------------------------------------+
|00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31|
+-----------------------------------------------+-----------+-----------------------+-----------+
|                Extension name                 |  Ext ver. |    Data begin index   | Next ext. |
+-----------------------------------------------+-----------+-----------------------+-----------+
struct Extension_Info {
    uint8_t[16] extension_name;         // Ascii string, null terminated or max length 16.
    uint32_t    extension_version;
    uint64_t    data_begin_index;       // Index into asset's main data buffer.
    uint32_t    next_extension;         // (index + 1) into extension_info array. Zero indicates no extensions.
}

Client implementations of a given asset type MAY ignore extension info and data. Any behaviour that cannot be safely ignored MUST have its own asset type.