galaxer och motion blur

This commit is contained in:
2026-11-01 15:46:28 +01:00
parent 8274a20001
commit 9d44d14cc9
39 changed files with 1502 additions and 72 deletions

View File

@@ -0,0 +1,84 @@
using Universe.App.Runtime;
using Universe.Core.Generation;
using Universe.Core.Math;
using Universe.Core.World;
namespace Universe.Tests;
public sealed class GalaxyTests
{
private static GalaxyUniverse Create() => new(0x554E495645525345UL,UniverseScale.DefaultCellSizeMeters,new(),Path.Combine(AppContext.BaseDirectory,"KnownGalaxies.json"));
[Fact]
public void HierarchicalAddressKeepsLocalMetresAtRemoteGalaxyCoordinates()
{
var universe=Create();
var address=new GalaxyAddress(new(1_000_000_000,-1_000_000_000,500),new(-53,21,700),new(456.75,901.125,18));
var position=address.ToPosition(universe.RegionCells);
Assert.Equal(address,GalaxyAddress.FromPosition(position,universe.RegionCells));
var moved=position.Add(new(.125,.25,.5),universe.CellSize);
Assert.Equal(new DVector3(.125,.25,.5),moved.RelativeTo(position,universe.CellSize));
var negative=new UniversePosition(new(-universe.RegionCells/2-1,0,0),DVector3.Zero);
Assert.Equal(-1,GalaxyAddress.FromPosition(negative,universe.RegionCells).Region.X);
}
[Fact]
public void TextureBrightnessAndAlphaControlActualSystemOccupancy()
{
var universe=Create();var galaxy=universe.Get(new());
var white=new RasterImage(2,2,Enumerable.Repeat((byte)255,16).ToArray());
var transparent=white.Rgba.ToArray();for(var i=3;i<16;i+=4)transparent[i]=0;
var bright=galaxy with {Texture=white,Center=UniversePosition.AtCellCenter(new(),universe.CellSize)};
var dark=bright with {Texture=new(2,2,new byte[16])};
var alpha=bright with {Texture=new(2,2,transparent)};
Assert.Equal(1,bright.PlanarDensity(0,0),10);
Assert.Equal(0,dark.PlanarDensity(0,0));Assert.Equal(0,alpha.PlanarDensity(0,0));
var count=0;
for(var x=-3;x<=3;x++)for(var z=-3;z<=3;z++)
{
if(universe.Candidate(bright,new(x,0,z),out _))count++;
Assert.False(universe.Candidate(dark,new(x,0,z),out _));
Assert.False(universe.Candidate(alpha,new(x,0,z),out _));
}
Assert.True(count>20);
}
[Fact]
public void GeneratedGalaxiesAreDeterministicAndSystemsHaveParents()
{
var a=Create();var b=Create();var coordinate=new GalaxyCoordinate(1,0,0);
var first=a.Get(coordinate);var second=b.Get(coordinate);
Assert.Equal(first.Center,second.Center);Assert.Equal(first.Seed,second.Seed);
var sector=a.SelectSystem(first);Assert.Equal(sector,b.SelectSystem(second));
var generator=new UniverseGenerator(a.Seed,galaxies:a);
var system=generator.Generate(sector);
Assert.NotEmpty(system.Stars);Assert.NotEmpty(system.Planets);
Assert.Equal(first.Id,system.GalaxyId);Assert.NotNull(system.NebulaId);
Assert.Empty(generator.Generate(first.Center.Add(new(first.RadiusMeters*2,0,0),a.CellSize).Sector).Stars);
}
[Fact]
public void JourneyVisitsBothGalaxiesLandsAtEyeHeightAndDetectsFrameSpikes()
{
var galaxies=Create();
var home=new UniverseGenerator(123).Generate(new());
var earth=home.Planets[0] with {Id="earth"};home=home with {Planets=[earth]};
var body=UniversePosition.AtCellCenter(home.Coordinate,galaxies.CellSize).Add(earth.PositionMeters,galaxies.CellSize);
var radial=new DVector3(1,.2,.1).Normalized();var start=body.Add(radial*earth.RadiusMeters*3,galaxies.CellSize);
var generator=new UniverseGenerator(galaxies.Seed,galaxies:galaxies);
var journey=new GalaxyJourneyBenchmark(galaxies,generator,home,earth,start,-radial,new(0,1,0));
var camera=new FlyCamera(start,galaxies.CellSize);var streamer=new UniverseStreamer(generator);var visitedTarget=false;
while(journey.IsRunning)
{
journey.Update(.25,camera);
var loaded=streamer.Load(camera.Position.Sector);
if(loaded.ActiveSystem.Coordinate==journey.TargetSystem.Coordinate && loaded.ActiveSystem.Planets.Count>0)visitedTarget=true;
if(journey.Phase=="GROUND WALK")
{
var targetBody=UniversePosition.AtCellCenter(journey.TargetSystem.Coordinate,galaxies.CellSize).Add(journey.TargetPlanet.PositionMeters,galaxies.CellSize);
var delta=camera.Position.RelativeTo(targetBody,galaxies.CellSize);
Assert.InRange(delta.Length-TerrainHeight.Sample(journey.TargetPlanet,delta),1.79,1.81);
}
journey.RecordFrame(journey.ElapsedSeconds is >30 and <31?.1:.01);
}
Assert.True(visitedTarget);Assert.Equal(7,journey.VisitedPhases.Count);Assert.Equal(start,camera.Position);
Assert.False(journey.PerformancePassed);
Assert.Contains(journey.GraphSamples,fps=>fps<20);
}
}

View File

@@ -0,0 +1,42 @@
using Universe.App.Runtime;
using Universe.Core.Generation;
using Universe.Core.Math;
using Universe.Core.World;
namespace Universe.Tests;
public sealed class StarMotionTests
{
[Fact]
public void HistoryRetainsSmallMovementAtLargeCoordinatesAndResetsOnCameraCuts()
{
var cell=UniverseScale.DefaultCellSizeMeters;
var position=UniversePosition.AtCellCenter(new(600_000_000_000_000_000,-500,200),cell);
var camera=new FlyCamera(position,cell);
var history=new StarMotionHistory();var settings=new StarMotionBlurSettings();
history.Advance(camera,1440,900,1d/60,settings);
Assert.False(history.Valid);
camera.SetPlayerPose(position.Add(new(.125,.25,.5),cell),camera.Forward,camera.Up);
history.Advance(camera,1440,900,1d/60,settings);
Assert.True(history.Valid);
Assert.Equal(new DVector3(.125,.25,.5),history.Current.Position.RelativeTo(history.Previous.Position,cell));
camera.SetPlayerPose(position.Add(new(1e20,0,0),cell),camera.Forward,camera.Up,resetMotionHistory:true);
history.Advance(camera,1440,900,1d/60,settings);
Assert.False(history.Valid);
Assert.Equal(history.Current,history.Previous);
}
[Fact]
public void PauseResizeAndLongFramesCannotSmearUnrelatedFramesTogether()
{
var camera=new FlyCamera(UniversePosition.AtCellCenter(new(),UniverseScale.DefaultCellSizeMeters),UniverseScale.DefaultCellSizeMeters);
var history=new StarMotionHistory();var settings=new StarMotionBlurSettings();
history.Advance(camera,1440,900,1d/60,settings);
history.Advance(camera,1440,900,1d/60,settings);Assert.True(history.Valid);
history.Advance(camera,1920,1080,1d/60,settings);Assert.False(history.Valid);
history.Advance(camera,1920,1080,0,settings);Assert.False(history.Valid);
history.Advance(camera,1920,1080,.5,settings);Assert.False(history.Valid);
history.Advance(camera,1920,1080,1d/60,settings);Assert.True(history.Valid);
history.Advance(camera,1920,1080,1d/60,settings with {Enabled=false});Assert.False(history.Valid);
}
}

View File

@@ -21,6 +21,9 @@
<ProjectReference Include="..\..\src\Universe.Core\Universe.Core.csproj" />
<ProjectReference Include="..\..\src\Universe.App\Universe.App.csproj" />
<Content Include="..\..\config.json" Link="config.json" CopyToOutputDirectory="PreserveNewest" />
<Content Include="..\..\KnownGalaxies.json" Link="KnownGalaxies.json" CopyToOutputDirectory="PreserveNewest" />
<Content Include="..\..\Content\Galaxies\*" Link="Content\Galaxies\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" />
<Content Include="..\..\Content\Nebulae\*" Link="Content\Nebulae\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" />
<Content Include="..\..\KnownSolarSystem\**\*" Link="KnownSolarSystem\%(RecursiveDir)%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>