The goal of cast is to create an engine agnostic format that can be parsed and written with ease. In addition, cast should have very similar output on any engine.
- .NET Framework: (Help wanted)
- Python: Libraries/Python
- C++: (Help wanted)
All files start with a cast header:
struct CastHeader
{
uint32_t Magic; // char[4] cast (0x74736163)
uint32_t Version; // 0x1
uint32_t RootNodes; // Number of root nodes, which contain various sub nodes if necessary
uint32_t Flags; // Reserved for flags, or padding, whichever is needed
};
A cast file is basically a group of generic nodes. Nodes are given a unique registered id, which can tell the loader what the data is, and how to handle it.
Following the cast header is a collection of nodes which must be of type CastId::Root.
A node looks like:
struct CastNodeHeader
{
CastId Identifier; // Used to signify which class this node uses
uint32_t NodeSize; // Size of all data and sub data following the node
uint64_t NodeHash; // Unique hash, like an id, used to link nodes together
uint32_t PropertyCount; // The count of properties
uint32_t ChildCount; // The count of direct children nodes
// We must read until the node size hits, and that means we are done.
// The nodes are in a stack layout, so it's easy to load, FILO order.
};
There are several registered cast ids available:
enum class CastId : uint32_t
{
Root = 0x746F6F72,
Model = 0x6C646F6D,
Mesh = 0x6873656D,
BlendShape = 0x68736C62,
Skeleton = 0x6C656B73,
Bone = 0x656E6F62,
Animation = 0x6D696E61,
Curve = 0x76727563,
NotificationTrack = 0x6669746E,
Material = 0x6C74616D,
File = 0x656C6966,
};
Following a node, is the list of properties [Node.PropertyCount], a property looks like:
struct CastPropertyHeader
{
CastPropertyId Identifier; // The element type of this property
uint16_t NameSize; // The size of the name of this property
uint32_t ArrayLength; // The number of elements this property contains (1 for single)
// Following is UTF-8 string lowercase, size of namesize, NOT null terminated
// cast_property[ArrayLength] array of data
};
For properties, cast has several built in types:
enum class CastPropertyId : uint16_t
{
Byte = 'b', // <uint8_t>
Short = 'h', // <uint16_t>
Integer32 = 'i', // <uint32_t>
Integer64 = 'l', // <uint64_t>
Float = 'f', // <float>
Double = 'd', // <double>
String = 's', // Null terminated UTF-8 string
Vector2 = 'v2', // Float precision vector XY
Vector3 = 'v3', // Float precision vector XYZ
Vector4 = 'v4' // Float precision vector XYZW
};
To read a cast file, you just need to traverse the root nodes and their children. Properties always come before a nodes children. Each node has the total size of itself, and all children, so if a processor doesn't understand a node id, it can skip the entire node and continue reading.
Cast ids are integers for performance, unlike FBX where nodes are full strings.
Field | Type(s) | IsArray | Required |
---|---|---|---|
Children | Skeleton, Mesh, Material | True | False |
Parent | Root | False | True |
Field | Type(s) | IsArray | Required |
---|---|---|---|
Children | None | True | False |
Parent | Model | False | True |
Property (id) | Type(s) | IsArray | Required |
---|---|---|---|
Name (n) | String (s) | False | False |
Vertex Position Buffer (vp) | Vector 3 (v3) | True | True |
Vertex Normal Buffer (vn) | Vector 3 (v3) | True | False |
Vertex Tangent Buffer (vt) | Vector 3 (v3) | True | False |
Vertex Color Buffer (vc) | Integer 32 (i) | True | False |
Vertex UV Buffer (u%d) | Vector 2 (v2) | True | False |
Vertex Weight Bone Buffer (wb) | Integer 32 (i), Short (h), Byte (b) | True | False |
Vertex Weight Value Buffer (wv) | Float (f) | True | False |
Face Buffer (f) | Integer 32 (i), Short (h), Byte (b) | True | True |
UV Layer Count (ul) | Integer 32 (i), Short (h), Byte (b) | False | True if has uv layers else False |
Maximum Weight Influence (mi) | Integer 32 (i), Short (h), Byte (b) | False | True if has weights else False |
Material (Hash of CastNode:Material) (m) | Integer 64 (l) | False | False |
Notes:
Face Buffer
is an index into the current meshes vertex data buffers where (0, 1, 2) are the first three vertices from this mesh.- The
Face Buffer
follows CCW (right-handed) winding order, this may be different in other apis, where you may have to remap the indices. - Each vertex descriptor buffer must contain the same number of elements ex: if you have 16 vertices, you must have 16 normals if they exist, 16 colors if the buffer exists. Otherwise it's assumed they are default / skipped.
Field | Type(s) | IsArray | Required |
---|---|---|---|
Children | None | True | False |
Parent | Model | False | True |
Property (id) | Type(s) | IsArray | Required |
---|---|---|---|
Base Shape (Hash of CastNode:Mesh) (b) | Integer 64 (l) | False | True |
Target Shapes (Hashes of CastNode:Mesh) (t) | Integer 64 (l) | True | True |
Target Weight Scales (ts) | Float (f) | True | False |
Notes:
- At a minimum one
Base Shape
and oneTarget Shape
must be present. Target Weight Scales
indicates the maximum value the target shape can deform to. The count usually will matchTarget Shape(s)
but if it does not plugins should fall back to 1.0 as the default.
Field | Type(s) | IsArray | Required |
---|---|---|---|
Children | Bone | True | False |
Parent | Model | False | True |
Field | Type(s) | IsArray | Required |
---|---|---|---|
Children | None | True | False |
Parent | Skeleton | False | True |
Property (id) | Type(s) | IsArray | Required |
---|---|---|---|
Name (n) | String (s) | False | True |
Parent Index (p) | Integer 32 (i) | False | False |
Segment Scale Compensate (ssc) | Byte (b) [True, False] | False | False |
Local Position (lp) | Vector 3 (v3) | False | False |
Local Rotation (lr) | Vector 4 (v4) | False | False |
World Position (wp) | Vector 3 (v3) | False | False |
World Rotation (wr) | Vector 4 (v4) | False | False |
Scale (s) | Vector 3 (v3) | False | False |
Field | Type(s) | IsArray | Required |
---|---|---|---|
Children | File | True | False |
Parent | Model | False | True |
Property (id) | Type(s) | IsArray | Required |
---|---|---|---|
Name (n) | String (s) | False | True |
Type (t) | String (s) | False | True |
Albedo File Hash (albedo) | Integer 64 (l) | False | True |
Diffuse File Hash (diffuse) | Integer 64 (l) | False | True |
Normal File Hash (normal) | Integer 64 (l) | False | True |
Specular File Hash (specular) | Integer 64 (l) | False | True |
Emissive File Hash (emissive) | Integer 64 (l) | False | True |
Gloss File Hash (gloss) | Integer 64 (l) | False | True |
Roughness File Hash (roughness) | Integer 64 (l) | False | True |
Ambient Occlusion File Hash (ao) | Integer 64 (l) | False | True |
Cavity File Hash (cavity) | Integer 64 (l) | False | True |
Extra (x) File Hash (extra%d) | Integer 64 (l) | False | True |
Field | Type(s) | IsArray | Required |
---|---|---|---|
Children | None | True | False |
Parent | CastNode | False | True |
Property (id) | Type(s) | IsArray | Required |
---|---|---|---|
Path (p) | String (s) | False | True |
Field | Type(s) | IsArray | Required |
---|---|---|---|
Children | Skeleton, Curve, NotificiationTrack | True | True |
Parent | Root | False | True |
Property (id) | Type(s) | IsArray | Required |
---|---|---|---|
Framerate (fr) | Float (f) | False | True |
Looping (lo) | Byte (b) [True, False] | False | False |
Transform Space (ts) | String (s) [local, world] | False | False |
Field | Type(s) | IsArray | Required |
---|---|---|---|
Children | None | True | False |
Parent | Animation | False | True |
Property (id) | Type(s) | IsArray | Required |
---|---|---|---|
Node Name (nn) | String (s) | False | True |
Key Property Name (kp) | String (s) [rq, rx, ry, rz, tx, ty, tz, sx, sy, sz, vb] | False | True |
Key Frame Buffer (kb) | Byte (b), Short (h), Integer 32 (i), Float (f) | True | True |
Key Value Buffer (kv) | Byte (b), Short (h), Integer 32 (i), Float (f), Vector 4 (v4) | True | True |
Mode (m) | String (s) [additive, absolute, relative] | False | True |
Additive Blend Weight (ab) | Float (f) | False | False |
Field | Type(s) | IsArray | Required |
---|---|---|---|
Children | None | True | False |
Parent | Animation | False | True |
Property (id) | Type(s) | IsArray | Required |
---|---|---|---|
Name (n) | String (s) | False | True |
Key Frame Buffer (kb) | Byte (b), Short (h), Integer 32 (i), Float (f) | True | True |
- Format designed by DTZxPorter with input from various developers.
- Icons by Smashicons