Files
fparkan/docs/specs/material.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

5.0 KiB
Raw Permalink Blame History

Material (MAT0)

MAT0 описывает материал и его фазовую анимацию.

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

1. Контейнер

  • Тип ресурса: 0x3054414D (MAT0).
  • Обычно хранится в Material.lib.
  • attr1 используется как битовое поле runtime-флагов материала.
  • attr2 задаёт версию заголовка payload.

2. Бинарный layout

struct Mat0Payload {
    uint16_t phaseCount;
    uint16_t animBlockCount; // должно быть < 20

    // если attr2 >= 2
    uint8_t  metaA8;
    uint8_t  metaB8;
    // если attr2 >= 3
    uint32_t metaC32;
    // если attr2 >= 4
    uint32_t metaD32;

    PhaseRecord34 phases[phaseCount];
    AnimBlockRaw  anim[animBlockCount];
};

Если attr2 < 2, используются runtime-значения по умолчанию:

  • metaA = 255
  • metaB = 255
  • metaC = 1.0f
  • metaD = 0

3. Фазы материала

struct PhaseRecord34 {
    uint8_t params[18];
    char    textureName[16];
};

В рантайме запись разворачивается в структуру ~76 байт:

  • набор коэффициентов цвета/освещения/прозрачности;
  • индекс слота текстуры;
  • дополнительные целочисленные поля.

textureName:

  • пустая строка -> фаза без текстуры (texSlot = -1);
  • непустая строка -> загрузка текстуры по имени.

4. Анимационные блоки

struct AnimBlockRaw {
    uint32_t headerRaw;  // mode = low 3 bits, interpMask = остальные
    uint16_t keyCount;
    KeyRaw   keys[keyCount];
};

struct KeyRaw {
    uint16_t k0;
    uint16_t k1;
    uint16_t k2; // opaque, сохранять 1:1
};

k2 нельзя удалять или нормализовать: это часть бинарного контракта.

5. Выбор текущей фазы

Материал выбирает фазу по времени и по режиму анимации блока:

  • loop;
  • ping-pong;
  • one-shot с clamp;
  • random-offset.

При смешивании интерполируется только часть полей, остальные копируются из активной фазы.
Для 1:1 совместимости важно сохранить эту выборочную интерполяцию.

6. Загрузка и fallback

При запросе материала по имени:

  1. Точный поиск по имени.
  2. Если не найдено — fallback на DEFAULT.
  3. Если DEFAULT отсутствует — используется запись с индексом 0.

7. Атрибуты и флаги

Практически важные биты attr1:

  • бит загрузки текстурной фазы с расширенными флагами;
  • флаги аппаратного профиля;
  • 4-битный режим (nibbleMode);
  • дополнительный флаг material-поведения.

Неизвестные биты должны сохраняться без изменений.

8. Ограничения

  • animBlockCount < 20
  • phaseCount и фактический размер секции фаз должны совпадать
  • textureName должен быть NUL-terminated и укладываться в 16 байт

9. Правила writer/editor

  1. Сохранять attr1/attr2/attr3.
  2. Не менять metaA/B/C/D без явного запроса.
  3. Сохранять opaque-поля анимации (включая k2) 1:1.
  4. Проверять выход за границы payload при парсинге.

10. Статус валидации

  • Инварианты MAT0 зафиксированы в текущем toolchain проекта (docs/specs + tools).
  • Структурная валидация MAT0 включена в корпусный прогон tools/msh_doc_validator.py на полном retail-наборе.

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

Закрыто:

  1. Бинарный layout MAT0 и правила чтения фаз/анимационных блоков.
  2. Fallback-цепочка материала.
  3. Контракт сохранения opaque-полей для lossless editor path.

Осталось:

  1. Полная семантика всех битов attr1 и metaA/B/C/D для авторинга новых материалов.
  2. Полный writer-профиль «канонический MAT0» для генерации ассетов без copy-through.
  3. Набор визуальных parity-тестов по material phase animation на реальных моделях.