feat(A.5 T14): GpuWorldState RemoveEntitiesFromLandblock + AddEntitiesToExisting
Two new methods on GpuWorldState, used by two-tier streaming (T13): - RemoveEntitiesFromLandblock(id): drop all entities from an LB while keeping the terrain. Used for Near->Far demote (player walks past the inner ring; LB stays loaded but entities leave). - AddEntitiesToExistingLandblock(id, entities): merge new entities into an already-loaded LB record. Used for Far->Near promote (terrain is already on the GPU; just streaming the entity layer in). Falls back to the pending bucket if the LB hasn't loaded yet. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
774a7070a8
commit
fb10c3fa8c
2 changed files with 121 additions and 0 deletions
|
|
@ -0,0 +1,76 @@
|
|||
using System.Linq;
|
||||
using AcDream.App.Streaming;
|
||||
using AcDream.Core.World;
|
||||
using DatReaderWriter.DBObjs;
|
||||
using Xunit;
|
||||
|
||||
namespace AcDream.Core.Tests.Streaming;
|
||||
|
||||
public class GpuWorldStateTwoTierTests
|
||||
{
|
||||
private static LoadedLandblock MakeStubLandblock(uint canonicalId, params WorldEntity[] entities)
|
||||
=> new(canonicalId, new LandBlock(), entities);
|
||||
|
||||
private static WorldEntity MakeStubEntity(uint id)
|
||||
=> new()
|
||||
{
|
||||
Id = id,
|
||||
SourceGfxObjOrSetupId = 0x01000001u,
|
||||
Position = System.Numerics.Vector3.Zero,
|
||||
Rotation = System.Numerics.Quaternion.Identity,
|
||||
MeshRefs = System.Array.Empty<MeshRef>(),
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void RemoveEntitiesFromLandblock_KeepsLandblockButDropsEntities()
|
||||
{
|
||||
var state = new GpuWorldState();
|
||||
var lb = MakeStubLandblock(0xAAAAFFFFu,
|
||||
MakeStubEntity(1),
|
||||
MakeStubEntity(2));
|
||||
state.AddLandblock(lb);
|
||||
Assert.Equal(2, state.Entities.Count);
|
||||
|
||||
state.RemoveEntitiesFromLandblock(0xAAAAFFFFu);
|
||||
|
||||
Assert.Empty(state.Entities);
|
||||
Assert.True(state.IsLoaded(0xAAAAFFFFu)); // landblock still resident
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddEntitiesToExistingLandblock_MergesIntoExistingRecord()
|
||||
{
|
||||
var state = new GpuWorldState();
|
||||
var lb = MakeStubLandblock(0xAAAAFFFFu, MakeStubEntity(1));
|
||||
state.AddLandblock(lb);
|
||||
|
||||
state.AddEntitiesToExistingLandblock(0xAAAAFFFFu, new[]
|
||||
{
|
||||
MakeStubEntity(2),
|
||||
MakeStubEntity(3),
|
||||
});
|
||||
|
||||
Assert.Equal(3, state.Entities.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddEntitiesToExistingLandblock_LandblockNotYetLoaded_ParksInPending()
|
||||
{
|
||||
var state = new GpuWorldState();
|
||||
|
||||
// Landblock not loaded yet.
|
||||
state.AddEntitiesToExistingLandblock(0xAAAAFFFFu, new[]
|
||||
{
|
||||
MakeStubEntity(1),
|
||||
MakeStubEntity(2),
|
||||
});
|
||||
|
||||
// Nothing in the flat view yet.
|
||||
Assert.Empty(state.Entities);
|
||||
Assert.Equal(2, state.PendingLiveEntityCount);
|
||||
|
||||
// Now load the landblock — pending entities should merge in.
|
||||
state.AddLandblock(MakeStubLandblock(0xAAAAFFFFu));
|
||||
Assert.Equal(2, state.Entities.Count);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue