feat(msh): decode triangle descriptors and query segments
Docs Deploy / Build and Deploy MkDocs (push) Successful in 38s
Docs Deploy / Build and Deploy MkDocs (push) Successful in 38s
This commit is contained in:
6 files changed
+933
-3
No files matched your search
@@ -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`, сравнивает камеру с
|
||||
|
||||
Reference in new issue
Block a user