fix(capture): replay the projection used by world geometry
Docs Deploy / Build and Deploy MkDocs (push) Successful in 39s

This commit is contained in:
Valentin Popov committed 2026-10-31 23:13:22 +04:00
1 parent 8a2c3e9840
commit 853d9b115a
7 files changed
+409 -170

No files matched your search

+7 -2
View File
@@ -57,8 +57,13 @@ MSH-запрос со свободной preview-камерой; это не п
Данные type 16 ещё не декодированы. Внутренний ракурс «Конструктора» после
настоящего входа игрока подтверждает исчезновение чёрной поверхности в проходе;
наружные окна обеих миссий сверены на расстояниях около 60/85/110, а ближние
окна — с внутренней стороны. Внутренние дальние ракурсы и clipping на краю
кадра ещё не приняты; общей готовности R2 эти пары не доказывают.
окна — с внутренней стороны. Окно «Конструктора» на правом краю кадра при
дистанции около 85 совпадает; внутренние дальние ракурсы и остальные случаи
отсечения ещё не приняты. Общей готовности R2 эти пары не доказывают.
Старые захваты без `geometry_projection` используют состояние камеры после
обхода мира, которое может отсекать близкие поверхности. Это отмечается
`captured_projection_unverified`; для приёмки таких поверхностей нужен новый захват.
Закрывающий эксперимент: запустить оригинал в совместимой Windows/DirectX
среде, перехватить DirectDraw/Direct3D calls и surface flips, сохранить state
+11
View File
@@ -225,6 +225,17 @@ RVA `0x4EBE0` использует соглашение о вызовах `__std
`right - left` на `bottom - top`. Размер окна превью закреплён: если при
запуске или после ненулевого изменения окна физический размер не совпадает с
заданным, приложение завершает работу, а не растягивает изображение.
Проекция во время рисования может отличаться от восстановленного состояния
камеры после обхода мира. В GOG у `CStridedPrimitive::RenderVB` (Terrain RVA
`0x1D110`) renderer содержит `near = 0.5`, а на границе World3D RVA `0x13CE4`
уже `near = 5`. Поэтому захват отдельно сохраняет `geometry_projection` при
первом вызове геометрии с той же мировой матрицей камеры. Поток, поколение,
renderer, viewport, far и FOV сверяются с последующей границей; только
подтверждённая запись используется при воспроизведении. Иначе пол в трёх
единицах от камеры может исчезнуть из-за чужой ближней плоскости. Старые JSON
без этой записи сохраняют прежнее поведение с явным счётчиком
`captured_projection_unverified`; их нужно переснять для проверки близких поверхностей.
Сравнивайте результат с фрагментом исходного PNG по прямоугольнику
`[left, top, right, bottom]`. В этом режиме `FreeFlightCamera` не создаётся,
но при повторной отрисовке обновляются окружение и проецируемые тени для
+6
View File
@@ -1009,6 +1009,12 @@ sun-ray queries поэтому используют исходные коорд
она не равна одному лишь обратному преобразованию камеры.
В проверенном GOG контексте Ngi32 использовались `n=0.5`, `z=700`, `f=1.3`.
Ближняя плоскость относится к конкретному проходу. После рисования движок
может вернуть прежние настройки камеры: захват только в конце мира видел
`n=5` и при воспроизведении вырезал пол перед игроком. Формат захвата поэтому
хранит проверенную проекцию вызова геометрии отдельно от состояния камеры;
подробности приведены в [описании кадра](../reference/render-frame.md#предпросмотр-по-захвату-камеры-d3d7).
У GOG `Terrain.dll + 0x7355c` хранит указатель на активную внешнюю камеру.
Её selector 0 возвращает 16 слов начиная с `+0x20`, перенос находится в словах
3, 7, 11. Интерфейс `LoadCamera` расположен отдельно, по `+0x134` объекта.