using XFEEDToolBox.Core.Navigation;
using XFEEDToolBox.Core.Rendering;
using XFEExtension.NetCore.XUnit.Attributes;
namespace XFEEDToolBox.Test;
[TestFixture]
public sealed class LocalSystemViewLockTests
{
private static CurrentSystemSnapshot Binary()
{
var a=new SystemLocation(1,11,"Star A","",1,SystemLocationCategory.Star,null,new(1e12,0,0),null,false,"a");
var b=new SystemLocation(2,22,"Star B","",1,SystemLocationCategory.Star,null,new(-2e12,0,0),null,false,"b");
SystemOrbit Orbit(SystemLocation child,double major,Vector3d x,Vector3d z)=>new(){SystemAddress=1,ChildWorldAddress=child.WorldAddress,ChildIdentity=child.Identity,
ParentWorldAddress=33,ParentIdentity="AB",ParentPosition=new(0,0,0),ParentName="A/B barycentre",SemiMajorAxisMetres=major,Eccentricity=0,
PeriapsisDirection=x,TransverseDirection=z,Source="isolated binary regression fixture",Quality=SystemOrbitQuality.NativeVerified};
return new(1,"Binary",1,1,DateTimeOffset.UtcNow,[a,b]){Orbits=[Orbit(a,1e12,new(1,0,0),new(0,0,1)),Orbit(b,2e12,new(-1,0,0),new(0,0,-1))],PlayerPosition=new(1e12,0,1e6),PlayerForward=new(0,0,1),PlayerReferenceWorld=11};
}
[Test]public void BinaryOrbitsRemainCompleteCirclesAroundTheirCommonBarycentre()
{
var scene=new LocalSystemScene(Binary());Check.That(scene.HierarchicalOrbitScale);Check.Equal(2,scene.Orbits.Count);
foreach(var path in scene.Orbits)
{
Check.Equal(path.Points[0],path.Points[^1]);var centre=(path.Points[0]+path.Points[64])/2;
Check.That(centre.Length<1e-9);var radius=(path.Points[0]-centre).Length;
Check.That(path.Points.All(point=>Math.Abs((point-centre).Length-radius)<1e-9));
Check.Equal(scene.Nodes.Single(node=>node.Location.Identity==path.Child.Identity).Position,path.Points[0]);
Check.That(path.Points.Any(point=>point.X>0)&&path.Points.Any(point=>point.X<0)&&path.Points.Any(point=>point.Z>0)&&path.Points.Any(point=>point.Z<0));
}
}
[Test]public void ReferenceRotationDoesNotRotateBodiesOrOrbitsButRealPositionChangesRemainVisible()
{
var first=Binary();var frame=new LocalSystemViewLock();Check.That(frame.Observe(first));var before=new LocalSystemScene(first,null,frame.Orientation);
Vector3d R(Vector3d p)=>new(-p.Z,p.Y,p.X);
var rotated=first with{Locations=first.Locations.Select(row=>row with{Position=R(row.Position!.Value)}).ToArray(),
Orbits=first.Orbits.Select(orbit=>orbit with{ParentPosition=R(orbit.ParentPosition!.Value),PeriapsisDirection=R(orbit.PeriapsisDirection!.Value),TransverseDirection=R(orbit.TransverseDirection!.Value)}).ToArray(),
PlayerPosition=R(first.PlayerPosition!.Value),PlayerForward=R(first.PlayerForward!.Value)};
Check.That(frame.Observe(rotated));var after=new LocalSystemScene(rotated,null,frame.Orientation);
foreach(var pair in before.Nodes.Zip(after.Nodes))Check.That((pair.First.Position-pair.Second.Position).Length<1e-9);
foreach(var pair in before.Orbits.Zip(after.Orbits))Check.That(pair.First.Points.Zip(pair.Second.Points).All(points=>(points.First-points.Second).Length<1e-9));
Check.That((before.PlayerPosition!.Value-after.PlayerPosition!.Value).Length<1e-9);Check.Equal(before.PlayerForward,after.PlayerForward);
var moved=rotated with{PlayerPosition=rotated.PlayerPosition+new Vector3d(0,0,1e9)};
Check.That((new LocalSystemScene(moved,null,frame.Orientation).PlayerPosition!.Value-after.PlayerPosition.Value).Length>1e-5);
}
[Test]public void MissingAnchorKeepsTheLastVerifiedFrameAndChangingSystemResetsIt()
{
var frame=new LocalSystemViewLock();var snapshot=Binary();frame.Observe(snapshot);var before=frame.Orientation;
Check.That(!frame.Observe(snapshot with{Orbits=[]}));Check.Equal(before,frame.Orientation);
Check.That(frame.Observe(snapshot with{SystemAddress=2,Orbits=[]}));Check.That(!frame.Locked);Check.Equal(LocalSystemOrientation.Identity,frame.Orientation);
}
[Test]public void NativeSpectralClassesDoNotAllBecomeOrangeStars()
{
var f=LocalSystemStellarStyle.Colour(3);var m=LocalSystemStellarStyle.Colour(6);var o=LocalSystemStellarStyle.Colour(0);
Check.That(f.B>m.B&&o.B>o.R&&m.R>m.B);Check.That(LocalSystemStellarStyle.Colour(null)!=m);
}
}
using XFEEDToolBox.Core.Navigation;
using XFEEDToolBox.Core.Rendering;
using XFEExtension.NetCore.XUnit.Attributes;
namespace XFEEDToolBox.Test;
[TestFixture]
public sealed class LocalSystemViewLockTests
{
private static CurrentSystemSnapshot Binary()
{
var a=new SystemLocation(1,11,"Star A","",1,SystemLocationCategory.Star,null,new(1e12,0,0),null,false,"a");
var b=new SystemLocation(2,22,"Star B","",1,SystemLocationCategory.Star,null,new(-2e12,0,0),null,false,"b");
SystemOrbit Orbit(SystemLocation child,double major,Vector3d x,Vector3d z)=>new(){SystemAddress=1,ChildWorldAddress=child.WorldAddress,ChildIdentity=child.Identity,
ParentWorldAddress=33,ParentIdentity="AB",ParentPosition=new(0,0,0),ParentName="A/B barycentre",SemiMajorAxisMetres=major,Eccentricity=0,
PeriapsisDirection=x,TransverseDirection=z,Source="isolated binary regression fixture",Quality=SystemOrbitQuality.NativeVerified};
return new(1,"Binary",1,1,DateTimeOffset.UtcNow,[a,b]){Orbits=[Orbit(a,1e12,new(1,0,0),new(0,0,1)),Orbit(b,2e12,new(-1,0,0),new(0,0,-1))],PlayerPosition=new(1e12,0,1e6),PlayerForward=new(0,0,1),PlayerReferenceWorld=11};
}
[Test]public void BinaryOrbitsRemainCompleteCirclesAroundTheirCommonBarycentre()
{
var scene=new LocalSystemScene(Binary());Check.That(scene.HierarchicalOrbitScale);Check.Equal(2,scene.Orbits.Count);
foreach(var path in scene.Orbits)
{
Check.Equal(path.Points[0],path.Points[^1]);var centre=(path.Points[0]+path.Points[64])/2;
Check.That(centre.Length<1e-9);var radius=(path.Points[0]-centre).Length;
Check.That(path.Points.All(point=>Math.Abs((point-centre).Length-radius)<1e-9));
Check.Equal(scene.Nodes.Single(node=>node.Location.Identity==path.Child.Identity).Position,path.Points[0]);
Check.That(path.Points.Any(point=>point.X>0)&&path.Points.Any(point=>point.X<0)&&path.Points.Any(point=>point.Z>0)&&path.Points.Any(point=>point.Z<0));
}
}
[Test]public void ReferenceRotationDoesNotRotateBodiesOrOrbitsButRealPositionChangesRemainVisible()
{
var first=Binary();var frame=new LocalSystemViewLock();Check.That(frame.Observe(first));var before=new LocalSystemScene(first,null,frame.Orientation);
Vector3d R(Vector3d p)=>new(-p.Z,p.Y,p.X);
var rotated=first with{Locations=first.Locations.Select(row=>row with{Position=R(row.Position!.Value)}).ToArray(),
Orbits=first.Orbits.Select(orbit=>orbit with{ParentPosition=R(orbit.ParentPosition!.Value),PeriapsisDirection=R(orbit.PeriapsisDirection!.Value),TransverseDirection=R(orbit.TransverseDirection!.Value)}).ToArray(),
PlayerPosition=R(first.PlayerPosition!.Value),PlayerForward=R(first.PlayerForward!.Value)};
Check.That(frame.Observe(rotated));var after=new LocalSystemScene(rotated,null,frame.Orientation);
foreach(var pair in before.Nodes.Zip(after.Nodes))Check.That((pair.First.Position-pair.Second.Position).Length<1e-9);
foreach(var pair in before.Orbits.Zip(after.Orbits))Check.That(pair.First.Points.Zip(pair.Second.Points).All(points=>(points.First-points.Second).Length<1e-9));
Check.That((before.PlayerPosition!.Value-after.PlayerPosition!.Value).Length<1e-9);Check.Equal(before.PlayerForward,after.PlayerForward);
var moved=rotated with{PlayerPosition=rotated.PlayerPosition+new Vector3d(0,0,1e9)};
Check.That((new LocalSystemScene(moved,null,frame.Orientation).PlayerPosition!.Value-after.PlayerPosition.Value).Length>1e-5);
}
[Test]public void MissingAnchorKeepsTheLastVerifiedFrameAndChangingSystemResetsIt()
{
var frame=new LocalSystemViewLock();var snapshot=Binary();frame.Observe(snapshot);var before=frame.Orientation;
Check.That(!frame.Observe(snapshot with{Orbits=[]}));Check.Equal(before,frame.Orientation);
Check.That(frame.Observe(snapshot with{SystemAddress=2,Orbits=[]}));Check.That(!frame.Locked);Check.Equal(LocalSystemOrientation.Identity,frame.Orientation);
}
[Test]public void NativeSpectralClassesDoNotAllBecomeOrangeStars()
{
var f=LocalSystemStellarStyle.Colour(3);var m=LocalSystemStellarStyle.Colour(6);var o=LocalSystemStellarStyle.Colour(0);
Check.That(f.B>m.B&&o.B>o.R&&m.R>m.B);Check.That(LocalSystemStellarStyle.Colour(null)!=m);
}
}