diff options
Diffstat (limited to 'docs/reference/environment-effects.md')
| -rw-r--r-- | docs/reference/environment-effects.md | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/docs/reference/environment-effects.md b/docs/reference/environment-effects.md index fdc29f0..29d85f9 100644 --- a/docs/reference/environment-effects.md +++ b/docs/reference/environment-effects.md @@ -236,6 +236,83 @@ Native `z = 0.999` не означает, что спрайт гарантиро native значение сохраняется для совместимости, но само по себе не обещает окклюзию солнца всей геометрией местности. +## Геометрия визуальных FX-команд + +`fparkan-fx::fx_visual` формирует кадры для двух подтверждённых вариантов +`f_gener_ball`. Op4 принимает mode 0 с положительным знаменателем в `body+0xC4` +и выдаёт camera-facing quad; расстояние камеры считается через native +component-wise projection родительской матрицы. Op9 принимает mode 2: +селектор `body+0xC4` со значением 0, 1 или 2 отображается в native flag base +3, 5 или 6 и выбирает одну из трёх сеток; категория render flags выбирает её +детализацию. `body+0xC8` выбирает UV path: +нулевое значение проецирует позицию вершины на XY, ненулевое использует +фиксированные координаты quad и cap. Кадр сохраняет MAT0 resource, фазу, +opacity, вершины и triangle indices для renderer. + +Evaluator получает готовые command body, phase, camera point и внешнюю +матрицу. Выбор Control row, manager gates, owner attachment, header jitter и +global RNG остаются задачей владельца. `fparkan-game` пока использует для Op9 +категорию 0 с наибольшей детализацией; выбор категории по projected size ещё +не реализован. + +Для Op3 поддерживаются body-типы 0, 1 и 2. Поля отсчитываются от +`FxCommand.raw_body`, то есть после 4-байтового command word. Типы 0 и 1 +используют общие position/scale/phase/opacity tracks и camera-facing основу; +тип 1 и тип 2 также интерполируют ось, а тип 2 строит basis через native +D110-порядок. Все три evaluator-а принимают уже собранную матрицу владельца и +не выбирают Control row или attachment. Текущий путь для типов 0 и 1 +предполагает native render context 0: `Effect.dll` проверяет общий gate +`context + 0x60 < 8`, а API этих evaluator-ов не выбирает другой context. +Evaluator типа 2 принимает индекс context явно и учитывает этот gate в `active`. + +## Частицы Op7 + +`fparkan-fx::op7` вычисляет фиксированный набор частиц Op7 по body команды, +фазе эффекта, матрице владельца, позиции камеры и render context. После +инициализации состояние команды сохраняет случайно изменённые треки позиции +и масштаба. Body задаёт время групп, opacity, фазу материала и вертикальное +ускорение; последнее масштабируется переданным world scalar и применяется к +копии матрицы владельца каждой активной группы. Текущий preview +`fparkan-game` передаёт `world_scalar = 10.0`; чтение действующей настройки +мира пока не подключено. + +Часы активной группы обновляются до применения detail cutoff отдельной +частицы. Cutoff сравнивает ordinal render context с постоянным порогом слота. +`Effect.dll` `0x1300` использует тот же порядок, поэтому скрытие слота не +останавливает часы его активной группы. Поток частиц последовательно задаёт +случайные изменения позиции и масштаба; для порогов видимости используется +отдельный поток. Шаг LFSR совпадает с нативным переходом двух половин, однако +семена отдельных экземпляров лишь детерминированно заменяют process-global +состояние и не воспроизводят общий порядок вызовов. + +## Частицы Op8 + +`fparkan-fx::smoke` разбирает body Op8, хранит кольцевой пул команды и выдаёт +quad-ы с ориентацией к камере для активных слотов. Нативная нормализованная +фаза окна ограничивается диапазоном 0–1 и задаёт интервал проверки следующего события; +сравнение строгое (`schedule_base + interval < update_clock`). Все события +catch-up в одном обновлении проверяются по тому же нормализованному интервалу; +после события нативный код продвигает базу расписания интервалом, вычисленным +по сырой фазе эффекта, а возраст слота считает по нормализованному интервалу. +Когда фаза равна единственной границе окна, деление `0/0` даёт NaN, который +нативный unordered-путь сравнения ограничивает нулём. + +Нулевая база расписания служит признаком начального состояния: обновление +сохраняет текущую опору эмиттера и базу времени, не создавая частицу. Если +первое время равно нулю, следующее обновление повторно захватывает опору. При +событии скорость опоры считается от сохранённой позиции до текущей за время +от базы расписания; слот смещает сохранённую опору на `скорость * due_interval`. +Обновление без событий не переносит сохранённую опору к текущему владельцу. +Откат часов корректирует только базу расписания до текущего времени: слоты, +опора и три потока случайных +чисел не сбрасываются. + +Evaluator принимает отдельные начальные состояния для эмиттера, знаковых +отклонений и материала. Переход каждого потока совпадает с общим native LFSR, +но эти локальные seed не воспроизводят порядок process-global вызовов игры. +Предел 100000 событий catch-up — защитная граница evaluator-а; соответствующего +лимита в исследованном native цикле не обнаружено. + ## Что остаётся за владельцем `EnvironmentSystem` не извлекает камеру из renderer, не разрешает материалы |
