aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/appendices/knowledge-boundaries.md4
-rw-r--r--docs/reference/environment-effects.md11
-rw-r--r--docs/reference/msh.md39
3 files changed, 54 insertions, 0 deletions
diff --git a/docs/appendices/knowledge-boundaries.md b/docs/appendices/knowledge-boundaries.md
index a31b561..68a01d0 100644
--- a/docs/appendices/knowledge-boundaries.md
+++ b/docs/appendices/knowledge-boundaries.md
@@ -14,6 +14,10 @@ state transitions и окончательный порядок части transp
рельефом. Она пока не проверяет стены и проёмы строений; эти ограничения не
подтверждают поведение стратегической камеры или камеры робота оригинала.
+Локальный MSH-запрос `query_slot_segment` сверён с оригиналом на фабричной
+стене и дверном проёме. Мировое преобразование, фильтры категории и
+подключение к свободной камере остаются открытыми ([MSH](../reference/msh.md)).
+
Закрывающий эксперимент: запустить оригинал в совместимой Windows/DirectX
среде, перехватить DirectDraw/Direct3D calls и surface flips, сохранить state
log на минимальных сценах с одним типом материала.
diff --git a/docs/reference/environment-effects.md b/docs/reference/environment-effects.md
index 46a456a..799a969 100644
--- a/docs/reference/environment-effects.md
+++ b/docs/reference/environment-effects.md
@@ -328,6 +328,17 @@ RVA `0x93D0`, ветка mode 1 с `0x9739`, сборка столбцов `0x97
двух столбцов могут немного отличаться от единицы из-за приближённой
нормализации выбранного `g_FastProc`; порядок осей от этого не меняется.
+У сооружения `s_tree_58` в миссии «Конструктор» FXID `tree_ray_58` задаёт два
+слоя жёлтого луча: команды Op3 mode 1 с ресурсами `defl_y_add` и `defl_y1_add`.
+Их геометрию сверили с CPU-вызовом GOG `Effect.dll` `0x93D0`. На семи временных
+фазах и трёх направлениях камеры для каждой команды (42 выборки) вершины
+совпали с Rust evaluator с максимальной покомпонентной разницей `0.0001373291`.
+Оракул получает уже выбранные Rust позицию, ось и масштаб, а world-camera
+переводится в `cameraLocal` тем же component-wise projection, что и native
+`FastProc + 0x68`. Поэтому это подтверждает только геометрию Type 1 helper-а на
+этих входах: обновление и расписание эффекта, UV/material и пиксельное
+совпадение здесь не проверялись.
+
## Частицы Op7
`fparkan-fx::op7` вычисляет фиксированный набор частиц Op7 по body команды,
diff --git a/docs/reference/msh.md b/docs/reference/msh.md
index a28514d..7c6eca7 100644
--- a/docs/reference/msh.md
+++ b/docs/reference/msh.md
@@ -154,6 +154,45 @@ Byte `material_index` выбирает строку WEAR; high word at `+0x02` Ñ
индекс через `base_vertex` попадает в position stream. `vertex_count` и
`local_batch_index` доступны renderer для исходного draw contract.
+## Type 7 и сегментный запрос
+
+Type 7 необязателен для обычного MSH preview. Если stream есть, каждые 16 bytes
+описывают одну грань: `tri_flags` находится по `+0`, четыре неинтерпретируемых
+слова — по `+2`, `+4`, `+6` и `+14`, а signed `normal[3]` — по `+8`, `+0xA` и
+`+0xC`. `ModelAsset.triangle_descriptors` сохраняет декодированную таблицу как
+`Option`; отсутствие Type 7 не делает статическую модель недействительной.
+
+`query_slot_segment` использует Node38 header mask, Batch20 leading DWORD
+`batch_flags | (material_index_hi << 16)` и `tri_flags`. Для каждого поля
+include mask требует все установленные биты, exclude mask пропускает запись при
+любом совпавшем бите. Descriptor cursor начинается с `Slot68.tri_start` и
+сдвигается на `Batch20.index_count / 3` после каждой записи, даже если batch
+или грань отфильтрованы. Индексы грани читаются из type 6 с учётом
+`base_vertex`.
+
+Правило восстановлено для GOG-бинарей `AniMesh.dll`
+(`65659bf67f20e5be77d67a5b2f59968f61b94293143807fa59ca451c560c4f7e`) и
+`Ngi32.dll` (`bab9840d94f4e4e74ffc26677724fa896cf4823845504d09a9e025f80016edf5`).
+Callback `AniMesh.dll+0x11090` переводит signed type-7 normal множителем
+`1 / 32767`; функция `AniMesh.dll+0x11EB0` записывает этот scale в глобальное
+поле. Callback вызывает FastProc slot `+0xB4`: в этой сборке он указывает на
+`Ngi32.dll+0x1D560`. После обычной загрузки DLL порог `Ngi32.dll+0x37224`
+равен нулю, поэтому plane test принимает только переход от положительного
+расстояния к неположительному (`dot(normal, end - start) < 0`, расстояние в
+начале `> 0`, в конце `<= 0`). `Batch20.batch_flags & 0x0002` разрешает повторный
+plane test в обратном направлении, только если прямой plane test не пересёк
+плоскость. Пересечение проверяется export ordinal 202
+(`Ngi32.dll+0x1E60`, `mrnPointInPoly`): проекция выбирает ось с наибольшим по
+модулю normal component, а точка проходит грань, пока ни одно edge expression
+не меньше нуля. Равенство нулю принимается, поэтому попадание на ребро или
+вершину считается попаданием. Поздний кандидат с тем же squared distance
+заменяет предыдущий; расстояние считается от исходного первого endpoint.
+
+Native helper получает точку пересечения через `RCPSS` и один шаг уточнения;
+Rust использует обычное деление `f32`, поэтому последние биты координат могут
+отличаться. Игнорируемый тест с ресурсами проверяет исходную стену, дверной
+проём и обратное направление на `fortif.rlb/fr_l_plant.msh`.
+
## Сторона грани в цветовом проходе
В цветном проходе `Terrain.dll`, функция `0x100296F0`, сравнивает камеру с