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>
76 lines
2.2 KiB
C#
76 lines
2.2 KiB
C#
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);
|
|
}
|
|
}
|