Add MSH geometry export and preview rendering tools
All checks were successful
Test / Lint (push) Successful in 46s
Test / Test (push) Successful in 41s

- Implemented msh_export_obj.py for exporting NGI MSH geometry to Wavefront OBJ format, including model selection and geometry extraction.
- Added msh_preview_renderer.py for rendering NGI MSH models to binary PPM images, featuring a primitive software renderer with customizable parameters.
- Both tools utilize the same NRes parsing logic and provide command-line interfaces for listing models and exporting or rendering geometry.
This commit is contained in:
2026-02-10 23:27:43 +00:00
parent ba1789f106
commit 5035d02220
8 changed files with 3268 additions and 393 deletions

View File

@@ -1,69 +0,0 @@
# Эффекты и частицы
Пока что — **не байтовая спецификация**, а “карта” по тому, что видно в библиотеках. Полную документацию по эффектам/шейдерам/частицам можно будет сделать после того, как:
- найдём формат эффекта (файл/ресурс),
- найдём точку загрузки/парсинга,
- найдём точки рендера (создание буферов/вершинного формата/материалов).
---
## 1) Что видно по `Effect.dll`
- Есть экспорт `CreateFxManager(...)`, который создаёт менеджер эффектов и регистрирует его в движке.
- Внутри много логики “сообщений/команд” через виртуальные вызовы (похоже на общий компонентный интерфейс).
- Явного парсера формата эффекта (по типу “читать заголовок, читать эмиттеры…”) в найденных местах пока не идентифицировано.
---
## 2) Что видно по `Terrain.dll` (рендер‑статистика частиц)
В `Terrain.dll` есть отладочная/статистическая телеметрия:
- количество отрендеренных частиц (`Rendered particles`)
- количество батчей (`Rendered batches`)
- количество отрендеренных треугольников
Это подтверждает:
- частицы рендерятся батчами,
- они интегрированы в общий 3Dрендер (через тот же графический слой).
---
## 3) Что важно для совместимости
Даже без точного формата эффекта, из поведения оригинала следует:
- Эффекты/частицы завязаны на общий набор рендер‑фич (фильтрация/мультитекстурность/блендинг).
- На слабом железе (и для минимализма) должны работать деградации:
- без мипмапов,
- без bilinear/trilinear,
- без multitexturing,
- возможно с 16бит текстурами.
---
## 4) План “докопать” до формата эффектов
1. Найти **точку создания эффекта по имени/ID**:
- поискать места, где в строки/лог пишется имя эффекта,
- найти функции, которые принимают “путь/имя” и возвращают handle.
2. Найти **точку загрузки данных**:
- чтение из NRes/RsLi ресурса,
- распаковка/декодирование.
3. Зафиксировать **структуру данных эффекта в памяти**:
- эмиттеры,
- спауны,
- lifetime,
- ключи размера/цвета,
- привязка к текстурам/материалам.
4. Найти рендер‑код:
- какой vertex format у частицы,
- как формируются квадраты/ленты (billboard/trail),
- какие stateы включаются.
После этого можно будет выпустить полноценный документ “FX format”.

File diff suppressed because it is too large Load Diff

View File

@@ -1,90 +0,0 @@
# Текстуры и материалы
На текущем этапе в дизассемблированных библиотеках **не найден полный декодер формата текстурного файла** (нет явных парсеров DDS/TGA/BMP и т.п.). Поэтому документ пока фиксирует:
- что можно достоверно вывести по рендер‑конфигу,
- что видно по структурам модели (materialIndex),
- какие места требуют дальнейшего анализа.
---
## 1) Материал в модели
В batch table модели (см. документацию по MSH/AniMesh) есть поле, очень похожее на:
- `materialIndex: u16` (batch + 2)
Это индекс, по которому рендерер выбирает:
- текстуру(ы),
- параметры (blend, alpha test, двухтекстурность и т.п.),
- “шейдер/пайплайн” (в терминах оригинального рендера — набор stateов).
**Где лежит таблица материалов** (внутри модели или глобально) — требует подтверждения:
- вероятный кандидат — отдельный ресурс/таблица, на которую `materialIndex` ссылается.
- строковая таблица `Res10` может хранить имена материалов/текстур, но маппинг не доказан.
---
## 2) Переключатели рендера, влияющие на текстуры (из Ngi32.dll)
В `Ngi32.dll` есть набор runtimeнастроек (похоже, читаются из системных настроек/INI/registry), которые сильно влияют на текстурный пайплайн:
- `DisableMipmap`
- `DisableBilinear`
- `DisableTrilinear`
- `DisableMultiTexturing`
- `Disable32bitTextures` / `Force16bitTextures`
- `ForceSoftware`
- `ForceNoFiltering`
- `ForceHWTnL`
- `ForceNoHWTnL`
Практический вывод для порта:
- движок может работать **без мипмапов**, **без фильтрации**, и даже **без multitexturing**.
---
## 3) “Две текстуры” и дополнительные UVпотоки
В загрузчике модели присутствуют дополнительные pervertex ресурсы:
- Res15 (stride 8) — кандидат на UV1 (lightmap/second layer)
- Res16 (stride 8, split в 2×4) — кандидат на tangent/bitangent (normal mapping)
- Res18 (stride 4) — кандидат на vertex color / AO
Если материал реально поддерживает:
- вторую текстуру (detail map, lightmap),
- нормалмапы,
то где‑то должен быть код:
- который выбирает эти потоки как входные атрибуты вершинного шейдера/пайплайна,
- который активирует multitexturing.
Сейчас в найденных фрагментах это ещё **не подтверждено**, но структура данных “просится” именно туда.
---
## 4) Что нужно найти дальше (чтобы написать полноценную спецификацию материалов/текстур)
1. Место, где `materialIndex` разворачивается в набор render states:
- alpha blending / alpha test
- zwrite/ztest
- culling
- 1pass vs 2pass (multitexturing)
2. Формат записи “material record”:
- какие поля
- ссылки на текстуры (ID, имя, индекс в таблице)
3. Формат “texture asset”:
- где хранится (внутри NRes или отдельным файлом)
- компрессия/палитра/мipы
4. Привязка строковой таблицы `Res10` к материалам:
- это имена материалов?
- это имена текстур?
- или это имена узлов/анимаций?
До подтверждения этих пунктов разумнее держать документацию как “архитектурную карту”, а не как точный байтовый формат.