fix(render): keep animated entities visible when their landblock is frustum-culled
User report: other characters disappear when the camera rotates, even though they're standing within visible distance. Root cause: InstancedMeshRenderer's landblock-level frustum cull (InstancedMeshRenderer.cs:352-355) skipped the entire landblock's entity list when the landblock AABB was outside the frustum. Static scenery culling that way is fine, but ANIMATED entities (remote players, NPCs, monsters) got culled with the landblock -- they vanished as soon as the camera turned away from their block. Fix: pass an animatedEntityIds set to Draw. Inside CollectGroups the landblock-cull decision is now per-landblock boolean (not a continue), and the per-entity loop bypasses the cull when the entity id is in animatedEntityIds. Static entities still respect the landblock cull. GameWindow rebuilds the set per frame from _animatedEntities (typically <100 entities, cheap). Fast path preserved: when animatedEntityIds is null/empty AND the landblock is culled, skip the entity list entirely -- same O(visible-landblocks) cost as before. Tests stay 1439 green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b93dfe95d8
commit
559b79dc98
2 changed files with 52 additions and 7 deletions
|
|
@ -5023,9 +5023,26 @@ public sealed class GameWindow : IDisposable
|
|||
if (cameraInsideCell)
|
||||
_gl!.Clear(ClearBufferMask.DepthBufferBit);
|
||||
|
||||
// L-fix1 (2026-04-28): pass the set of animated-entity ids so
|
||||
// the renderer keeps remote players / NPCs / monsters
|
||||
// visible even when their landblock rotates out of the
|
||||
// frustum. Without this, other characters wink in/out as
|
||||
// the camera turns. The set is rebuilt per-frame from
|
||||
// _animatedEntities — it's small (<100 entities typically)
|
||||
// so HashSet allocation is cheap. Static scenery still
|
||||
// respects landblock-level cull.
|
||||
HashSet<uint>? animatedIds = null;
|
||||
if (_animatedEntities.Count > 0)
|
||||
{
|
||||
animatedIds = new HashSet<uint>(_animatedEntities.Count);
|
||||
foreach (var k in _animatedEntities.Keys)
|
||||
animatedIds.Add(k);
|
||||
}
|
||||
|
||||
_staticMesh?.Draw(camera, _worldState.LandblockEntries, frustum,
|
||||
neverCullLandblockId: playerLb,
|
||||
visibleCellIds: visibility?.VisibleCellIds);
|
||||
visibleCellIds: visibility?.VisibleCellIds,
|
||||
animatedEntityIds: animatedIds);
|
||||
|
||||
// Phase G.1 / E.3: draw all live particles after opaque
|
||||
// scene geometry so alpha blending composites correctly.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue