83 lines
1.9 KiB
Markdown
83 lines
1.9 KiB
Markdown
|
|
# MSH
|
||
|
|
|
||
|
|
Файл `*.msh` является NRes-контейнером. Geometry, узлы, slots, batches,
|
||
|
|
animation и служебные streams лежат в entries с разными `type_id`.
|
||
|
|
|
||
|
|
## Entry map
|
||
|
|
|
||
|
|
```text
|
||
|
|
type 1 nodes and slot selection
|
||
|
|
type 2 header 0x8C + Slot68 records
|
||
|
|
type 3 positions float3
|
||
|
|
type 4 packed normals
|
||
|
|
type 5 packed UV0
|
||
|
|
type 6 index buffer u16
|
||
|
|
type 7 triangle descriptors
|
||
|
|
type 8 animation keys
|
||
|
|
type 9 service stream
|
||
|
|
type 10 strings and node names
|
||
|
|
type 13 Batch20 records
|
||
|
|
type 15 auxiliary stream
|
||
|
|
type 17 auxiliary data
|
||
|
|
type 18 rare stream
|
||
|
|
type 19 animation frame map
|
||
|
|
type 20 rare auxiliary table
|
||
|
|
```
|
||
|
|
|
||
|
|
Reader ищет entries по type, но сохраняет исходный порядок для roundtrip.
|
||
|
|
|
||
|
|
## Node and slot selection
|
||
|
|
|
||
|
|
Type 1 обычно состоит из records по 38 bytes:
|
||
|
|
|
||
|
|
```c
|
||
|
|
struct Node38 {
|
||
|
|
uint16_t hdr0;
|
||
|
|
uint16_t parent_or_link;
|
||
|
|
uint16_t anim_map_start;
|
||
|
|
uint16_t fallback_key;
|
||
|
|
uint16_t slot_index[15];
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
`slot_index[lod * 5 + group]` выбирает geometry slot. `0xFFFF` означает
|
||
|
|
отсутствие геометрии для комбинации LOD/group.
|
||
|
|
|
||
|
|
## Slot and batch
|
||
|
|
|
||
|
|
Type 2 содержит header `0x8C`, затем `Slot68`:
|
||
|
|
|
||
|
|
```c
|
||
|
|
struct Slot68 {
|
||
|
|
uint16_t tri_start;
|
||
|
|
uint16_t tri_count;
|
||
|
|
uint16_t batch_start;
|
||
|
|
uint16_t batch_count;
|
||
|
|
float aabb_min[3];
|
||
|
|
float aabb_max[3];
|
||
|
|
float sphere_center[3];
|
||
|
|
float sphere_radius;
|
||
|
|
uint32_t opaque[5];
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
Type 13 задаёт draw ranges:
|
||
|
|
|
||
|
|
```c
|
||
|
|
#pragma pack(push, 1)
|
||
|
|
struct Batch20 {
|
||
|
|
uint16_t batch_flags;
|
||
|
|
uint16_t material_index;
|
||
|
|
uint16_t opaque4;
|
||
|
|
uint16_t opaque6;
|
||
|
|
uint16_t index_count;
|
||
|
|
uint32_t index_start;
|
||
|
|
uint16_t opaque14;
|
||
|
|
uint32_t base_vertex;
|
||
|
|
};
|
||
|
|
#pragma pack(pop)
|
||
|
|
```
|
||
|
|
|
||
|
|
Index check выполняется как `base_vertex + index < vertex_count` для всего
|
||
|
|
используемого slice.
|