acdream/tests/AcDream.App.Tests/Rendering/Walk/WalkProductionWorldDataTests.cs

279 lines
9 KiB
C#

using System.Numerics;
using AcDream.App.Rendering.Scene;
using AcDream.App.Rendering.Walk;
namespace AcDream.App.Tests.Rendering.Walk;
public sealed class WalkProductionWorldDataTests
{
[Fact]
public void BuildingShellBucketCellId_PortalLessBuildingUsesLandscapePositionCell()
{
const uint positionCellId = 0xF4180011u;
RenderProjectionRecord record = Record(
id: 0xCF418060u,
position: new Vector3(53.57f, 13.874f, 160f)) with
{
Source = new RenderSourceMetadata() with
{
LocalEntityId = 0xCF418060u,
SourceId = 0x01001FD3u,
EffectCellId = positionCellId,
BuildingShellAnchorCellId = 0,
},
EntityPayload = new RenderEntityPayload() with
{
IsBuildingShell = true,
},
};
var building = new WalkBuilding
{
PositionCellId = positionCellId,
Portals = [],
};
Assert.Equal(
positionCellId,
WalkProductionWorldData.BuildingShellBucketCellId(in record));
Assert.Equal(
positionCellId,
WalkProductionWorldData.BuildingShellBucketCellId(building));
}
[Fact]
public void BuildingShellBucketCellId_PortalBearingBuildingKeepsInteriorAnchor()
{
const uint anchorCellId = 0xF4180112u;
RenderProjectionRecord record = Record(
id: 0xCF41805Fu,
position: new Vector3(36f, 13.8349f, 160f)) with
{
Source = new RenderSourceMetadata() with
{
LocalEntityId = 0xCF41805Fu,
SourceId = 0x01001FB7u,
EffectCellId = 0xF4180009u,
BuildingShellAnchorCellId = anchorCellId,
},
EntityPayload = new RenderEntityPayload() with
{
IsBuildingShell = true,
},
};
var building = new WalkBuilding
{
PositionCellId = 0xF4180009u,
Portals =
[
new WalkBldPortal { OtherCellId = anchorCellId },
],
};
Assert.Equal(
anchorCellId,
WalkProductionWorldData.BuildingShellBucketCellId(in record));
Assert.Equal(
anchorCellId,
WalkProductionWorldData.BuildingShellBucketCellId(building));
}
[Fact]
public void BucketOutdoorRecord_UsesEveryOutdoorPhysicsShadowCellAcrossLandblockEdge()
{
RenderProjectionRecord record = Record(
id: 0x1234u,
position: new Vector3(191f, 191f, 0f));
var buckets = new Dictionary<uint, List<RenderProjectionRecord>>();
WalkProductionWorldData.BucketOutdoorRecord(
in record,
[0xF07F0040u, 0xF0800001u, 0xF4180101u],
buckets,
renderCenterLbX: 0xF0,
renderCenterLbY: 0x7F);
Assert.Equal([0xF07F0040u, 0xF0800001u], buckets.Keys.Order());
Assert.All(buckets.Values, bucket => Assert.Equal(record, Assert.Single(bucket)));
}
[Fact]
public void BucketOutdoorRecord_UnregisteredEffectFallsBackToRootPositionCell()
{
RenderProjectionRecord record = Record(
id: 0x5678u,
position: new Vector3(193f, 25f, 0f));
var buckets = new Dictionary<uint, List<RenderProjectionRecord>>();
WalkProductionWorldData.BucketOutdoorRecord(
in record,
Array.Empty<uint>(),
buckets,
renderCenterLbX: 0xEF,
renderCenterLbY: 0x7F);
Assert.Equal([0xF07F0002u], buckets.Keys);
Assert.Equal(record, Assert.Single(buckets[0xF07F0002u]));
}
[Fact]
public void BucketIndoorRecord_InstallsCrossCellPartInBothInteriorCells()
{
RenderProjectionRecord record = Record(
id: 0x48A02035u,
position: new Vector3(55.25f, -46.47f, -3f)) with
{
Source = new RenderSourceMetadata() with
{
LocalEntityId = 0x48A02035u,
ParentCellId = 0x8A02015Fu,
},
};
var indoor = new Dictionary<uint, List<RenderProjectionRecord>>();
var outdoor = new Dictionary<uint, List<RenderProjectionRecord>>();
WalkProductionWorldData.BucketIndoorRecord(
in record,
[0x8A02015Fu, 0x8A02015Eu],
indoor,
outdoor);
Assert.Equal([0x8A02015Eu, 0x8A02015Fu], indoor.Keys.Order());
Assert.All(indoor.Values, bucket => Assert.Equal(record, Assert.Single(bucket)));
Assert.Empty(outdoor);
}
[Fact]
public void BucketIndoorRecord_CanCrossAnExitIntoLandscapeCell()
{
RenderProjectionRecord record = Record(
id: 0x48A02035u,
position: Vector3.Zero) with
{
Source = new RenderSourceMetadata() with
{
LocalEntityId = 0x48A02035u,
ParentCellId = 0x8A02015Fu,
},
};
var indoor = new Dictionary<uint, List<RenderProjectionRecord>>();
var outdoor = new Dictionary<uint, List<RenderProjectionRecord>>();
WalkProductionWorldData.BucketIndoorRecord(
in record,
[0x8A02015Fu, 0x8A020021u],
indoor,
outdoor);
Assert.Equal(record, Assert.Single(indoor[0x8A02015Fu]));
Assert.Equal(record, Assert.Single(outdoor[0x8A020021u]));
}
[Fact]
public void BucketDynamicRecord_InstallsMultipartPlayerInEveryCrossedInteriorCell()
{
RenderProjectionRecord record = Record(
id: 0x000F4243u,
position: new Vector3(58.81f, -49.42f, -0.85f)) with
{
Source = new RenderSourceMetadata() with
{
LocalEntityId = 0x000F4243u,
ParentCellId = 0x8A02015Eu,
},
};
var indoor = new Dictionary<uint, List<RenderProjectionRecord>>();
var outdoor = new Dictionary<uint, List<RenderProjectionRecord>>();
WalkProductionWorldData.BucketDynamicRecord(
in record,
[0x8A02015Eu, 0x8A02015Fu, 0x8A0201C1u],
indoor,
outdoor,
renderCenterLbX: 0x8A,
renderCenterLbY: 0x02);
Assert.Equal(
[0x8A02015Eu, 0x8A02015Fu, 0x8A0201C1u],
indoor.Keys.Order());
Assert.All(
indoor.Values,
bucket => Assert.Equal(record, Assert.Single(bucket)));
Assert.Empty(outdoor);
}
[Fact]
public void BucketDynamicRecord_UnregisteredInteriorEffectFallsBackToParentCell()
{
RenderProjectionRecord record = Record(
id: 0x00001234u,
position: Vector3.Zero) with
{
Source = new RenderSourceMetadata() with
{
LocalEntityId = 0x00001234u,
ParentCellId = 0x8A02015Fu,
},
};
var indoor = new Dictionary<uint, List<RenderProjectionRecord>>();
var outdoor = new Dictionary<uint, List<RenderProjectionRecord>>();
WalkProductionWorldData.BucketDynamicRecord(
in record,
Array.Empty<uint>(),
indoor,
outdoor,
renderCenterLbX: 0x8A,
renderCenterLbY: 0x02);
Assert.Equal(record, Assert.Single(indoor[0x8A02015Fu]));
Assert.Empty(outdoor);
}
[Fact]
public void ResolveDynamicRenderCells_EquippedDescendantInheritsRootCellArray()
{
RenderProjectionRecord wand = Record(
id: 0x800045EEu,
position: Vector3.Zero) with
{
Source = new RenderSourceMetadata() with
{
LocalEntityId = 0x800045EEu,
ParentCellId = 0xF4180104u,
},
EntityPayload = new RenderEntityPayload() with
{
CasterIdentity = RenderCasterIdentityKind.EquippedChild,
},
};
var owners = new Dictionary<uint, IReadOnlyList<uint>>
{
[0x5000000Au] = [0xF4180106u, 0xF4180104u],
};
var parents = new Dictionary<uint, uint>
{
[0x800045EEu] = 0x80000461u,
[0x80000461u] = 0x5000000Au,
};
IReadOnlyList<uint> cells =
WalkProductionWorldData.ResolveDynamicRenderCells(
in wand,
id => owners.TryGetValue(id, out IReadOnlyList<uint>? value)
? value
: Array.Empty<uint>(),
id => parents.TryGetValue(id, out uint value)
? value
: null);
Assert.Equal([0xF4180106u, 0xF4180104u], cells);
}
private static RenderProjectionRecord Record(uint id, Vector3 position) =>
new RenderProjectionRecord() with
{
Id = RenderProjectionId.FromRaw(id),
Transform = new RenderTransform(Matrix4x4.CreateTranslation(position)),
Source = new RenderSourceMetadata() with { LocalEntityId = id },
};
}