Snyggare moln
This commit is contained in:
58
tests/Universe.Tests/RingTemporalHistoryTests.cs
Normal file
58
tests/Universe.Tests/RingTemporalHistoryTests.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using System.Numerics;
|
||||
using Universe.App.Runtime;
|
||||
using Universe.Core.Generation;
|
||||
using Universe.Core.Math;
|
||||
using Universe.Core.World;
|
||||
|
||||
namespace Universe.Tests;
|
||||
|
||||
public sealed class RingTemporalHistoryTests
|
||||
{
|
||||
private const float Far=1e12f;
|
||||
private static PlanetData Ring(PlanetOrientation orientation)=>new(0,"Ring",DVector3.Zero,2_500_000,0,220_000,
|
||||
Vector3.One,Vector3.UnitZ,0,0,0,110){Id="ring-world",RingWorld=new(),Orientation=orientation};
|
||||
private static FlyCamera Camera()=>new(UniversePosition.AtCellCenter(new(0,0,0),1e10),1e10);
|
||||
|
||||
[Fact]
|
||||
public void JitteredGeometryAndRayReconstructionUseTheSameSubpixelPosition()
|
||||
{
|
||||
var camera=Camera();camera.SetPlayerPose(camera.Position,new(0,0,-1),new(0,1,0));
|
||||
var ring=Ring(PlanetOrientation.Identity);var history=new RingTemporalHistory();
|
||||
const int width=2560,height=1440;
|
||||
for(var frame=0;frame<16;frame++)
|
||||
{
|
||||
var vp=history.Advance(camera,ring,new(2_499_998,0,0),width,height,Far);
|
||||
var point=new Vector4(1.4f,-.7f,-12,1);var clip=Vector4.Transform(point,vp);
|
||||
var uv=new Vector2(clip.X/clip.W,clip.Y/clip.W)*.5f+new Vector2(.5f);
|
||||
var xy=(uv-new Vector2(history.Jitter.X/width,history.Jitter.Y/height))*2-Vector2.One;
|
||||
var tan=(float)System.Math.Tan(camera.FieldOfViewRadians*.5);
|
||||
var ray=Vector3.Normalize(new(xy.X*tan*width/height,xy.Y*tan,-1));
|
||||
Assert.InRange(Vector3.Distance(ray,Vector3.Normalize(new(point.X,point.Y,point.Z))),0,1e-6);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReprojectionTracksRingRotationAndTranslationAtUniverseScale()
|
||||
{
|
||||
var camera=Camera();var history=new RingTemporalHistory();
|
||||
var prior=Ring(new(35,73));var oldCamera=new DVector3(2_499_998,12345,0);
|
||||
camera.SetPlayerPose(camera.Position,prior.Orientation.ToWorld(new(0,0,1)),prior.Orientation.ToWorld(new(-1,0,0)));
|
||||
history.Advance(camera,prior,oldCamera,2560,1440,Far);
|
||||
var next=Ring(new(35,73.001));var newCamera=oldCamera+new DVector3(0,.1,.2);
|
||||
camera.SetPlayerPose(camera.Position.Add(new(100000,-4000,200),camera.CellSizeMeters),
|
||||
next.Orientation.ToWorld(new(0,0,1)),next.Orientation.ToWorld(new(-1,0,0)));
|
||||
history.Advance(camera,next,newCamera,2560,1440,Far);
|
||||
Assert.True(history.Valid);
|
||||
var bodyPoint=newCamera+new DVector3(-.2,3,12);
|
||||
var current=next.Orientation.ToWorld(bodyPoint-newCamera).ToVector3();
|
||||
var reprojected=Vector3.TransformNormal(current,history.CurrentToPrevious)+history.PreviousCameraOffset;
|
||||
var expected=prior.Orientation.ToWorld(bodyPoint-oldCamera).ToVector3();
|
||||
Assert.InRange(Vector3.Distance(reprojected,expected),0,1e-5);
|
||||
camera.SetPlayerPose(camera.Position,camera.Forward,camera.Up,true);
|
||||
history.Advance(camera,next,newCamera,2560,1440,Far);Assert.False(history.Valid);
|
||||
history.Advance(camera,next,newCamera,2560,1440,Far);Assert.True(history.Valid);
|
||||
history.Advance(camera,next,newCamera,1440,900,Far);Assert.False(history.Valid);
|
||||
history.Advance(camera,next,newCamera+new DVector3(0,1000,0),1440,900,Far);Assert.False(history.Valid);
|
||||
history.Advance(camera,null,newCamera,1440,900,Far);Assert.Equal(Vector2.Zero,history.Jitter);
|
||||
}
|
||||
}
|
||||
@@ -88,6 +88,9 @@ public sealed class RingWorldTests
|
||||
Assert.Throws<InvalidDataException>(() => settings.Validate(1, 220_000, terrain, null));
|
||||
Assert.Throws<InvalidDataException>(() => settings.Validate(2_500_000, 2_500_000, terrain, null));
|
||||
Assert.Throws<InvalidDataException>(() => settings.Validate(2_500_000, 220_000, terrain, new() { DepthMeters = 60_000 }));
|
||||
Assert.Throws<InvalidDataException>(() => (settings with {CloudDetail=new(){NearBaseAltitudeMeters=219000,NearThicknessMeters=2000}}).Validate(2_500_000,220_000,terrain,null));
|
||||
Assert.Throws<InvalidDataException>(() => (settings with {CloudDetail=new(){NearDistanceMeters=double.NaN}}).Validate(2_500_000,220_000,terrain,null));
|
||||
Assert.Throws<InvalidDataException>(() => (settings with {CloudDetail=new(){WeatherVariation=2}}).Validate(2_500_000,220_000,terrain,null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -216,6 +219,33 @@ public sealed class RingWorldTests
|
||||
Assert.True(camera.Position.RelativeTo(body, Cell).Length > planet.MaximumTerrainRadiusMeters * 2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MeadowWrapsWithTheRingAndExcludesWaterAndBareBiomes()
|
||||
{
|
||||
var green=new RasterImage(2,2,Enumerable.Repeat(new byte[]{45,80,35,255},4).SelectMany(p=>p).ToArray());
|
||||
var planet=Ring() with {SurfaceTexture=green};var settings=new RingMeadowSettings();
|
||||
foreach(var column in new[]{0,RingMeadowTile.Columns(planet)-1})
|
||||
{
|
||||
var tile=RingMeadowTile.Build(planet,column,0,settings);
|
||||
Assert.NotEmpty(tile.Instances);
|
||||
Assert.Equal(tile.Instances,RingMeadowTile.Build(planet,column,0,settings).Instances);
|
||||
Assert.All(tile.Instances,n=>Assert.True(float.IsFinite(n)));
|
||||
for(var i=0;i<tile.Instances.Length;i+=9)
|
||||
{
|
||||
var point=tile.Origin+new DVector3(tile.Instances[i],tile.Instances[i+1],tile.Instances[i+2]);
|
||||
var normal=new DVector3(tile.Instances[i+3],tile.Instances[i+4],tile.Instances[i+5]);
|
||||
Assert.InRange(RingWorldGeometry.Clearance(planet,point),-.026,-.024);
|
||||
Assert.True(DVector3.Dot(normal,-RingWorldGeometry.Radial(point))>.9999);
|
||||
}
|
||||
}
|
||||
var wet=planet with {OceanMask=new(2,2,[1,1,1,1])};
|
||||
Assert.Empty(RingMeadowTile.Build(wet,0,0,settings).Instances);
|
||||
var sand=planet with {SurfaceTexture=new(1,1,[205,181,120,255])};
|
||||
Assert.Empty(RingMeadowTile.Build(sand,0,0,settings).Instances);
|
||||
Assert.Throws<InvalidDataException>(()=>(settings with {SpacingMeters=double.NaN}).Validate());
|
||||
Assert.Throws<InvalidDataException>(()=>(settings with {DistanceMeters=1000}).Validate());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void VegetationIsDeterministicFacesInwardAndDoesNotGrowInWater()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user