Files
fparkan/docs/specs/msh-notes.md
Valentin Popov 0d7ae6a017
Some checks failed
Test / Lint (push) Failing after 1m10s
Test / Test (push) Has been skipped
Test / Render parity (push) Has been skipped
Документирование и обновление спецификаций
- Обновлены спецификации `runtime-pipeline`, `sound`, `terrain-map-loading`, `texture`, `ui` и `wear`.
- Добавлены разделы о статусе покрытия и оставшихся задачах для достижения 100% завершенности.
- Внесены уточнения по архитектурным ролям, минимальным контрактам и требованиям к toolchain для каждой подсистемы.
- Уточнены форматы данных и правила взаимодействия между компонентами системы.
2026-02-19 11:07:04 +04:00

4.8 KiB
Raw Permalink Blame History

3D implementation notes

Контрольная страница с практическими правилами реализации 3D-пайплайна и с перечнем незакрытых зон.
Документ intentionally high-level: без ссылок на внутренние функции/адреса.

Связанные страницы:

1. Базовые двоичные правила

  1. Все форматы в этой подсистеме little-endian.
  2. Внутри NRes данные ресурсов выравниваются по 8 байт.
  3. Внутри payload таблиц padding между записями обычно отсутствует: записи идут подряд по stride.

2. Быстрая карта stride'ов

Ресурс Запись Stride
Res1 Node 38
Res2 Slot 68 (после header 0x8C)
Res3 Position 12
Res4 Normal 4
Res5 UV0 4
Res6 Index 2
Res7 Tri descriptor 16
Res8 Animation key 24
Res13 Batch 20
Res19 Animation map 2

3. Декодирование ключевых потоков

3.1. Позиции (Res3)

float3, stride 12.

3.2. Нормали (Res4)

int8[4], используются первые 3 компоненты:

n = clamp(s8 / 127.0, -1..1)

3.3. UV (Res5)

int16[2]:

u = s16 / 1024.0
v = s16 / 1024.0

3.4. Animation key (Res8)

pos(float3) + time(float) + quat(int16x4):

q = s16 / 32767.0

4. Практический reader-контракт

Для runtime-совместимого чтения модели:

  1. Найти нужные ресурсы по type_id в NRes.
  2. Проверить size/stride-инварианты.
  3. Проверить диапазоны ссылок:
    • slot -> batch/triangles;
    • batch -> indices;
    • indices -> vertices;
    • anim_map -> anim_keys.
  4. Неизвестные поля и неизвестные ресурсы сохранять через copy-through.

5. Практический writer-контракт

  1. Пересчитывать только явно вычислимые поля.
  2. Не нормализовать opaque-данные без уверенной спецификации.
  3. При roundtrip неизмененных данных требовать byte-identical результат.
  4. Для новых ассетов фиксировать отдельную политику «генерация vs preserve».

6. Runtime-связка материалов и текстур

Канонический путь резолва:

  1. Модель -> wear-таблица (*.wea).
  2. Wear-слот -> material name.
  3. Material -> текущая фаза -> textureName.
  4. Texm ищется в Textures.lib (или lightmap-библиотеке для lightmap-ветки).

Fallback:

  • материал: DEFAULT, затем индекс 0;
  • текстура/lightmap: fallback-слот движка.

7. Что уже закрыто для 1:1

  1. Бинарный контракт базовых MSH таблиц.
  2. Контракт animation sampling (Res8 + Res19).
  3. Контракт MAT0/WEAR/Texm на уровне чтения и применения в кадре.
  4. Формат FXID-контейнера, командный поток и fixed command sizes.
  5. Валидация на retail-корпусе через tools/msh_doc_validator.py (0 ошибок/предупреждений).

8. Статус покрытия и что осталось до 100%

  1. Полная field-level семантика части служебных полей:
    • Batch20 opaque-поля;
    • хвостовые служебные поля slot-записей;
    • часть флагов узлов/групп.
  2. Полный writer-путь для авторинга новых анимированных ассетов (не только roundtrip существующих).
  3. Полная формализация семантики FX payload полей по каждому opcode для генерации новых эффектов, а не только для корректного чтения/исполнения.
  4. Полный канонический writer Texm для всех редких форматов и edge-case комбинаций служебных флагов.
  5. Сквозной «импорт внешнего ассета -> игровой пакет» с формальной спецификацией sidecar-метаданных (материал/эффект/анимация).