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:
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.