Skip to content

File Formats

Jussi Sammaltupa edited this page Jun 19, 2019 · 4 revisions

This document describes the custom file formats used by the Shinobi engine.

Basic Datatypes

The basic datatypes shared by model and animation formats are:

// A String is a variable length 8-bit string
struct String
{
    uint32  length;
    byte    data[length];
};

// A FourCC is a four character code string used for headers
struct FourCC
{
    byte    data[4];
};

// A Vec3 is a 3D vector
struct Vec3
{
    float32 x, y, z;
};

// A Quaternion represents a rotation in 3D space
struct Quaternion
{
    float32 x, y, z, w;
};

Model Files

A model file stores a hierarchy of meshes as follows:

struct ModelFile
{
    FourCC  magic;           // "MDL1"
    uint32  version;         // currently four
    uint32  numNodes;        // number of nodes following
    Node    nones[numNodes];
};

struct Node
{
    String  name;
    Vec3    position;
    Vec3    rotX;
    Vec3    rotY;
    Vec3    rotZ;
    Vec3    scale;
    uint32  parent;        // index of the parent node or 0xffffffff if no parent
    uint32  type;          // 0xffffffff = no entity data, 0 = MeshEntity follows
    (MeshEntity)           // not present if type is 0xffffffff
};

struct MeshEntity
{
    MeshData meshdata;
    uint32   numBones;         // number of bones for skeletal animation
    Bone     bones[numBones];
    byte     _unused;          // this byte is unused
};

struct Bone
{
    uint32  boneNodeIndex;    // index of the node used to deform the object
    Vec3    rotX;             // transform from model space to bone space
    Vec3    rotY;
    Vec3    rotZ;
    Vec3    position;
};

struct MeshData
{
    uint32      numVertices;    // number of vertices following
    VertexArray vertexArrays[15];
    uint32      numIndices;     // number of triangle indices following
    uint32      indices[numIndices];
    uint32      numSegments;    // number of mesh segments following
    MeshSegment segments[numSegments];
    Vec3        boundCenter;    // center of the bound sphere in model space
    float32     boundRadius;    // radius of the bound sphere in model space
    Vec3        boundMin;       // minimum extents of the bound box in model space
    Vec3        boundMax;       // maximum extents of the bound box in model space
};

// Vertex array indices
VERTEX_ARRAY_POSITION = 0
VERTEX_ARRAY_NORMAL = 1
VERTEX_ARRAY_TANGENT = 2
VERTEX_ARRAY_BITANGENT = 3    
VERTEX_ARRAY_COLOR = 4
VERTEX_ARRAY_TEXCOORD0 = 5
// array indices 6 - 12 are reversed for future use
VERTEX_ARRAY_BONE_INDEX = 13
VERTEX_ARRAY_BONE_WEIGHT = 14

struct VertexArray
{
    // dataType, dim and stride should be 0 if the vertex array is unused
    uint32 dataType;   // 0 = byte, 1 = int16, 2 = int32, 3 = float32
    uint32 dim;        // dimensions of the data type (2-4)
    uint32 stride;     // byte offset from vertex to vertex
    byte   rawVertexData[numVertices*stride];
};

struct MeshSegment
{
    String material;       // name of the material defined in Lua script
    uint32  primitiveType; // always two
    uint32  firstIndex;    // starting location in the index list
    uint32  count;         // number of triangles
};

Animation Files

An animation file adds a single animation to a model.

struct AnimationFile
{
    FourCC  magic;           // "ANIM"
    uint32  version;         // currently three
    float32 frameRate;       // 30.0 or 60.0, most game animations are stored at 60 fps
    uint32  numFrames;       // length of the animation in frames
    uint32  numItems;        // number of animation items following
    Item    items[numItems];
};

struct Item
{
    String     node;             // name of the node to be animated
    int32      numPositionKeys;  // number of position key frames following
    Vec3       positionkeys[numPositionKeys];
    uint32     numRotationKeys;  // number of rotation key frames following
    Quaternion rotationKeys[numRotationKeys];
    uint32     numScaleKeys;     // number of scale key frame following
    Vec3       scale[numScaleKeys];
};