diff options
Diffstat (limited to 'docs/tomes')
| -rw-r--r-- | docs/tomes/04-world.md | 24 | ||||
| -rw-r--r-- | docs/tomes/05-render.md | 72 | ||||
| -rw-r--r-- | docs/tomes/06-behavior.md | 22 |
3 files changed, 103 insertions, 15 deletions
diff --git a/docs/tomes/04-world.md b/docs/tomes/04-world.md index f9c0e67..e486e18 100644 --- a/docs/tomes/04-world.md +++ b/docs/tomes/04-world.md @@ -430,6 +430,30 @@ full 00000040 -> compact 2000 full 00200000 -> compact 8000 ``` +Бит `0x400` в маске грани рельефа управляет detail-текстурой. В `Terrain.dll` +метод `CShade` по смещению `+0x10` таблицы `0x10065108` ведёт к `0x10028A50`: +он читает `flags` по смещению `+0x3C` и проверяет бит в `0x10029191`. Ветка для +очищенного бита обнуляет указатель detail-текстуры в `0x10029427`. Затем +`Ngi32` применяет режим 1 или 7: для RGB stage 0 умножает текстуру на diffuse- +цвет, а stage 1 отключён. Alpha режима 1 берётся из texture, режима 7 — из +diffuse; на проверенных непрозрачных полосах основания это различие не меняет +цвет фрагмента. Текущий код сохраняет выбор в каждой полосе отрисовки рельефа: + +```rust +let terrain_base_only = first_face.flags.0 & 0x400 == 0; +``` + +Фрагментный шейдер пропускает умножение на detail-текстуру: + +```glsl +bool terrain_base_only = (mode & 16) != 0; +vec3 base_rgb = terrain_base_only ? base.rgb : 2.0 * base.rgb * detail.rgb; +``` + +В исходных картах бит установлен у всех 275 882 граней рельефа. У полос +основания, которые создаются процедурно при загрузке миссии, бит очищен; +именно поэтому им нужен этот вариант без detail-текстуры. + Для шестибитного material-поля используются full-биты `0x100`, `0x8000`, `0x10000`, `0x40000`, `0x80000` и `0x80`; они переходят соответственно в compact-биты `1`, `2`, `4`, `8`, `0x10`, `0x20`. diff --git a/docs/tomes/05-render.md b/docs/tomes/05-render.md index b04af31..545aa1a 100644 --- a/docs/tomes/05-render.md +++ b/docs/tomes/05-render.md @@ -362,12 +362,30 @@ local.set_translation(pose.position); world[n] = world[parent(n)] * local; ``` -Статический Vulkan preview берёт начальный кадр узла из явной ссылки прототипа -на CTLD `.ctl`. Используются только включённые строки, а при повторе node ID -поздняя строка заменяет раннюю. Без `--static-animation-frame` preview применяет -эти настройки узлов; узлы без настройки остаются на кадре `0`. Явный -`--static-animation-frame N` переопределяет их и задаёт `N` всем узлам. -Результат — одна статическая поза, не обновление анимации, Control или AI. +Статический Vulkan preview берёт CTLD `.ctl` из явной ссылки прототипа. +Поддерживаемые Control timeline с tag 21 сэмплируются при запуске на native +clock `0`; разрешённые NDP providers передают конечные type-1 значения. +Неподдерживаемый режим или variable mapping, а также отсутствующее или +неразрешённое gate value оставляют компонент на статических CTLD bindings. В +timeline участвуют только включённые строки; при повторном node ID поздняя +строка заменяет раннюю. + +Без `--static-animation-frame` preview сохраняет экземпляр Control и при +каждом redraw сэмплирует поддерживаемый timeline на текущем native clock. +Обновлённая Node38-поза перепроецирует видимую геометрию в заранее выделенный +vertex span, оставляя индексы и draw ranges неизменными. Если в пути Unit DAT +компонента есть такой Control, заново вычисляется его EXTO mount socket и +перепроецируется дочерняя геометрия; дочерний mount использует preorder-порядок +Unit DAT. Внутренние INTO-компоненты здесь не считаются глобальными MSH +socket mounts. Обновлённые вершины и shadow-треугольники попадают в общий +mesh upload перед следующим кадром. Culling sphere восстанавливается от +начальной native sphere и расширяется до текущих shadow-треугольников; это +`shortcut:`, потому что native обновление bounding sphere для анимированной +геометрии пока не установлено. Это путь сэмплирования Control-позы, не AI или +анимация эффектов. + +Явный `--static-animation-frame N` переопределяет timeline и задаёт `N` всем +узлам, пропуская runtime Control-сэмпл. MSH sampler выбирает type 19 frame округлением `(time - 0.5)` к ближайшему целому с ties-to-even, затем интерполирует выбранный type 8 key и следующий key в исходном `time`; это portable-вариант native x87 conversion в default @@ -625,15 +643,20 @@ Lightmap не является обычной diffuse texture. WEAR содерж отдельным slot или texture stage. Замена lightmap предварительным умножением в diffuse texture ломает LOD, atlas coordinates и динамическую модуляцию. -Vulkan preview строит projected shadows для выбранных зданий и роботов, -отбрасывает spheres вне шести clip-плоскостей с радиусом `sphere + 100` и +Vulkan preview строит проецируемые тени для объектов, отбрасывающих тени, +отбрасывает сферы вне шести clip-плоскостей с радиусом `sphere + 100` и сохраняет порядок видимых кандидатов; frame builder обрабатывает не более 20 -casters. Текущая реализация выделяет страницы в atlas `256 x 256` с 28 page -slots и использует одну smoothing pass. Вызов preview передаёт `fade = 1.0` и -LOD defaults: minimum LOD `1` и detail multiplier `1.0` отдельно для зданий и -роботов. Rust-путь не загружает `shade.cfg`: эти значения задаются кодом, а -параметры файла пока не влияют на preview. Проекция учитывает вклад -directional и point lights. +объектов. Текущая реализация выделяет страницы в atlas `256 x 256` с 28 page +slots и использует одно сглаживание. Preview применяет native defaults +`RobShadowsOn = true` и `BldShadowsOn = false`: объект kind `4` проверяет +первый флаг, остальные kinds — второй. Поэтому роботы BTLU остаются объектами, +отбрасывающими тени, а объекты FORT и STAT их не создают. Preview пока не +загружает `shade.cfg`, поэтому значения из пользовательского файла не меняют +список объектов, отбрасывающих тени. Проверка действует только на проецируемые +тени: отдельный список объектов для затенения солнца по-прежнему включает +FORT, BTLU и STAT. Вызов preview передаёт `fade = 1.0` и LOD defaults: +minimum LOD `1` и detail multiplier `1.0` отдельно для зданий и роботов. +Проекция учитывает вклад directional и point lights. Receiver projection обрезает projected quad по рёбрам треугольника. Native ray query descriptor в `+0x10` требует наличия всех переданных bits, а descriptor @@ -955,6 +978,23 @@ for (face, assignment) in mesh.faces.iter().zip(assignments.iter()) { } ``` +Подготовка BAS вынесена в `fparkan-terrain::build_basement_foundations`. +Функция получает внешние и внутренние кольца в порядке размещения, строит +упорядоченные пересечения внешней границы с текущей поверхностью и возвращает +исходные фрагменты рельефа вместе с треугольниками отмостки в одном наборе. +`TerrainWorld::with_basement_foundation` принимает этот набор во владение и +устанавливает те же координаты и маски в BVH высотных запросов и пересечений. +Предпросмотр миссии на Vulkan пока строит только LOD0: связывание BAS-записей +с этой подготовкой ещё не подключено, поэтому наличие API не означает, что +геометрия миссии уже обрезана. + +Внешнее кольцо должно лежать на области LOD0, а каждый его сегмент — оставаться +покрытым текущей поверхностью. Непокрытый сегмент или пересекающиеся контуры +дают ошибку; карта не остаётся частично обрезанной. Первичная нормализация +использует исходные грани и соседей LOD0, последующие пересечения и вырезания — +канонические фрагменты после предыдущих размещений. Соответствие динамических +соседей, создаваемых нативным движком, пока не моделируется. + ## Материалы ландшафта Рядом с `Land.msh` лежат `Land1.wea` и `Land2.wea`. Старший байт @@ -996,7 +1036,9 @@ animation phase; object batches сохраняют их legacy blend/depth/alpha После загрузки world path создаёт интерактивную free-flight камеру (`WASD`, `E/Q`, `Shift`, `Ctrl`, RMB relative-look), обновляет listener и на каждом -кадре собирает environment frame. Mission-local `sky.ske`/`sky.wea` выбирают +кадре собирает environment frame. После шага движения камера проверяет высоту +`TerrainWorld`: над конечной поверхностью сохраняется начальный просвет, а вне +поверхности высота не ограничивается. Mission-local `sky.ske`/`sky.wea` выбирают атмосферное расписание и sky materials, `effects.rlb/env_lightning` даёт lightning visual; weather particles, flares, sun/moon, point lights, projected shadows и audio events обновляются вместе с камерой и временем. diff --git a/docs/tomes/06-behavior.md b/docs/tomes/06-behavior.md index e663389..d1af7ba 100644 --- a/docs/tomes/06-behavior.md +++ b/docs/tomes/06-behavior.md @@ -424,6 +424,15 @@ type 4, в том числе четыре `f_smalllight_y` с offsets 104–107 offsets 119–121. В `fr_l_gener.ctl` найдено 35 строк type 4, включая `f_gener_ball` с offset 85. +Control.dll `+0x8B10` передаёт указатель текущей записи диспетчеру `+0x2D4B0`. +Теги 2 и 5 направляются в общий читатель `+0x21D50`: таблица виртуальных методов +тега 2 (`+0x3CBD8`) вызывает его через обёртку `+0x29650`, а таблица тега 5 +(`+0x3CDF8`) указывает прямо на него в позиции `+0x1C`. Читатель потребляет +заголовок размером `0xB0` байт со счётчиком `u32` по `+0xAC`, затем `count` +значений `u32`, слово длины и, при ненулевой длине, строку с завершающим NUL; +указатель возврата указывает на следующую запись. Поэтому для тегов 2 и 5 подтверждён общий +структурный формат; смысл их полей пока не назначен. + Resolver прототипов хранит явную registry-ссылку на `.cpt` отдельно от ссылки на `.ctl`. Если строки type 4 разобраны и явная ссылка на CPT есть, подготовка читает ровно указанные archive/name; имя CPT не выводится из имени CTL. В CPT @@ -445,6 +454,19 @@ C0 равен 0, поэтому найденные offsets 104–107, 119–121 условий, загрузка FX materials, activation, выполнение FX opcodes и видимый рендер эффектов пока не реализованы. +После типизированных записей CTLD хранит 21 ссылку на группу эффектов. В +`fr_l_plant.ctl` первая ссылка равна `8`, остальные 20 содержат `u32::MAX`; за +ними расположены 13 таблиц групп. При разборе по адресу `+0x8B10` к каждой +ссылке, кроме `u32::MAX`, прибавляется число групп, зарегистрированных до +таблиц этого CTL; получившиеся индексы сохраняются в control mapping. При +событии `0x80000020` код по адресу `+0x7830` сразу выходит, если поле дескриптора +`+0xC0` равно нулю. Разбор по адресу `+0x8B10` вызывает диспетчер групп `+0x2800` +с индексом группы по умолчанию только при ненулевом `+0xC0`. Назначение поля +дескриптора и условия его заполнения на стороне producer пока неизвестны. +`initial_effect_group` хранит проверенную ссылку на группу по умолчанию. Это +поле описывает данные CTL и не выполняет activation, загрузку FX materials, +FX opcodes или рендер эффектов. + CPU-only обход `MISSIONS/Autodemo.00/data.tma` подготовил четыре CTL с 80 строками type 4 и четыре явных CPT-списка (всего 322 записи). Среди пар были `fortif.rlb/fr_l_plant.ctl` и `fortif.rlb/fr_l_plant.cpt` (155 точек), а также |
