Represents a visual model in the game, from furniture to the world, and characters.
# Reading
First read the model header, which contains some information like the data offsets:
```c++
struct ModelFileHeader {
uint32_t version;
uint32_t stackSize;
uint32_t runtimeSize;
uint16_t vertexDeclarationCount;
uint16_t materialCount;
uint32_t vertexOffsets[3];
uint32_t indexOffsets[3];
uint32_t vertexBufferSize[3];
uint32_t indexBufferSize[3];
uint8_t lodCount;
uint8_t indexBufferStreamingEnabled;
uint8_t hasEdgeGeometry;
uint8_t _unknown1;
};
```
Immediately after this header begins the vertex declarations which describe how vertex data is sequenced and eventually read. These structures define the basis of the vertex declarations:
```c++
enum VertexType : uint8_t {
Invalid = 0,
Single3 = 2,
Single4 = 3,
UInt = 5,
ByteFloat4 = 8,
Half2 = 13,
Half4 = 14,
};
enum VertexUsage : uint8_t {
Position = 0,
BlendWeights = 1,
BlendIndices = 2,
Normal = 3,
UV = 4,
Tangent = 5,
BiTangent = 6,
Color = 7,
};
struct VertexElement {
uint8_t stream;
uint8_t offset;
VertexType vertexType;
VertexUsage vertexUsage;
uint8_t usageIndex;
uint8_t unknown[3];
};
```
For every vertex declaration (the count in `vertexDeclarationCount`) first read a single `VertexElement`. Then keep reading a `VertexElement` (and keeping these in a buffer) until `VertexElement::stream` is `0xFF` (or 255 in decimal.) This implies an "end of stream" and that's the end of that declaration. Before reading the next declaration you need to advance your cursor `17 + 8 - (elements + 1) * 8` where `elements` is the amount of valid `VertexElement`s you just read.