perf(vfx): port retail particle visibility degradation

Resolve DAT-authored particle ranges from the hardware GfxObj, apply retail distance and completed-cell visibility gates, and preserve the exact finite/infinite off-view update semantics. This removes dense-world simulation work without shortening terrain, entity, fog, or streaming distance.

Publish doorway-clipped outdoor cells through a focused frame controller, retain effect cell identity for outdoor statics, reject hidden emitters before particle-slot scans, and offer an explicit opt-in Extended particle range.

Release build succeeds and all 5,857 tests pass with five intentional skips. Retail-conformance, architecture, and adversarial review cycles are clean; connected Aerlinthe visual/performance gate pending.

Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-17 15:27:36 +02:00
parent 82789eea88
commit f1ba147ac5
29 changed files with 1810 additions and 125 deletions

View file

@ -113,6 +113,23 @@ loader when preloading emitter meshes. This is not a second DAT reader:
`CreateBlockingParticleHook::Execute` `0x00526EF0` and
`ParticleManager::CreateBlockingParticleEmitter` `0x0051B8A0`.
**Retail particle visibility/degradation seam (2026-07-17).** WorldBuilder's
particle simulator remains a useful DAT-integrator and batching reference, but
it does not carry the live retail client's `CObjCell::IsInView` degradation
path. `EmitterDescRegistry` now resolves the hardware particle GfxObj and its
ordered `GfxObjDegradeInfo` entries through the same sole `DatCollection`;
`ParticleSystem` ports the retail finite/infinite degraded branches; App feeds
the unified PView interior set plus the landscape renderer's independently
computed outdoor landcell set through a focused
`ParticleVisibilityController`. Examination and dedicated-pass emitters carry
an explicit bypass policy; missing/portal world views are empty rather than
fail-open.
No WorldBuilder dependency or second DAT access layer was introduced. Retail
anchors: `CPhysicsPart::GetMaxDegradeDistance` `0x0050D510`,
`GfxObjDegradeInfo::get_max_degrade_distance` `0x0051E2D0`,
`CPhysicsObj::ShouldDrawParticles` `0x0050FE60`, and
`ParticleEmitter::UpdateParticles` `0x0051D180`.
**Retail portal-space viewport adapter (2026-07-15).**
`src/AcDream.App/Rendering/PortalTunnelPresentation.cs` uses the extracted
Setup/GfxObj mesh pipeline and mandatory `WbDrawDispatcher` for retail's