fix(render): S2 chunk 6 review round — one particle turn per cell per stamp, cheap empty cells, dead owner-set stub deleted
Retail-lens review of chunk 6 (no blocking finding). Fixed: - a cell that gets two object-list turns in one frame (a chamber reached through two portals) submitted its emitters twice; retail's particle parts sit in the same shadow_part_list as every other part and CPhysicsPart::Draw's frame stamp suppresses the second draw, so the walk now dedupes the particle turn with the same frame-scoped set that dedupes the cell shell; - every visited land cell paid the full per-cell draw setup even with no emitter; DrawForCell now returns after the cell lookup, retail's own cost (DrawPartCell 0x005a07a0 `num_shadow_parts > 0`); - CopyRenderableEmittersInCell maintains LastRenderScopeEmitterVisitCount; - the OutdoorSceneParticleEntityIds / outdoorOwnerIds stub chain (permanently empty, never read) is deleted through IWorldSceneRenderer, WorldScenePViewRenderer, IWorldScenePasses and the composition root; - AD-117 item 4 names the two behavioral residuals (owner-cell substitution; no per-emission AddPartToShadowCells); - ParticleHookSinkTests pins that an emitter's draw cell is its owner's pose cell and survives the projection-visibility switch across the per-frame view pass. Gates: Core 4,988/4,988 (Vfx 108/108), App hermetic 6,760/6,760, Runtime 1,884/1,884. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
7969c2e6ad
commit
6d5afcccde
11 changed files with 891 additions and 800 deletions
|
|
@ -313,8 +313,6 @@ public sealed class WorldSceneRendererTests
|
|||
|
||||
Assert.True(result.NormalWorldDrawn);
|
||||
Assert.Contains("particles:pviewScoped", rig.Calls);
|
||||
Assert.Same(rig.PView.OutdoorSceneParticleEntityIds, rig.Passes.ParticleOwners);
|
||||
Assert.Equal([0xCAFEu], rig.Passes.ParticleOwners);
|
||||
Assert.DoesNotContain("flat:weather", rig.Calls);
|
||||
}
|
||||
|
||||
|
|
@ -756,9 +754,6 @@ public sealed class WorldSceneRendererTests
|
|||
diagnosticPartition: null);
|
||||
}
|
||||
|
||||
public IReadOnlySet<uint> OutdoorSceneParticleEntityIds { get; } =
|
||||
new HashSet<uint> { 0xCAFEu };
|
||||
|
||||
public RetailPViewFrameInput? LastInput { get; private set; }
|
||||
|
||||
public bool ThrowOnDraw { get; set; }
|
||||
|
|
@ -800,7 +795,6 @@ public sealed class WorldSceneRendererTests
|
|||
|
||||
public float WeatherDayFraction { get; private set; }
|
||||
|
||||
public IReadOnlySet<uint>? ParticleOwners { get; private set; }
|
||||
|
||||
public void BeginFrame() => calls.Add("passes:begin");
|
||||
|
||||
|
|
@ -837,10 +831,8 @@ public sealed class WorldSceneRendererTests
|
|||
LoadedCell? clipRoot,
|
||||
ClipFrameAssembly? clipAssembly,
|
||||
in WorldCameraFrame camera,
|
||||
IReadOnlySet<uint> outdoorOwnerIds,
|
||||
string currentSignature)
|
||||
{
|
||||
ParticleOwners = outdoorOwnerIds;
|
||||
string kind = clipRoot switch
|
||||
{
|
||||
null => "global",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue