XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using XFEExtension.NetCore.XUnit.Attributes;
using XFEEDToolBox.Core.Galaxy;

namespace XFEEDToolBox.Test;

[TestFixture]
public class GalaxyOriginalCameraSmoothingTests
{
    static void Near(double expected, double actual, double tolerance = 1e-9) =>
        Check.That(Math.Abs(expected - actual) <= tolerance, $"Expected {expected}, actual {actual}");

    [Test]
    public void OriginalNormalUpdateUsesFourIndependentChannelsAndGeometricZoom()
    {
        var actual = new GalaxyCameraPose(new(100, -2, 300), -.5, .25, 10);
        var target = new GalaxyCameraPose(new(120, 3, 260), .5, -.75, 320);
        var next = GalaxyOriginalCameraControls.Smooth(actual, target);
        Near(106.00000023841858, next.Focus.X);
        Near(-.4999999403953552, next.Focus.Y);
        Near(287.99999952316284, next.Focus.Z);
        Near(-.29999999701976776, next.Yaw);
        Near(.04999999701976776, next.Pitch);
        Near(20.00000020657396, next.Distance, 1e-8);
        Check.That(next.Distance < 30); // Arithmetic-distance interpolation would be 72.
    }

    [Test]
    public void TargetFloorSettlesWhileActualHeightRemainsContinuous()
    {
        var actual = new GalaxyCameraPose(new(4, 2.75, 6), 0, 0, 20);
        var target = GalaxyOriginalCameraControls.PrepareTarget(actual, false, 0);
        Near(3, target.Focus.Y);
        var next = GalaxyOriginalCameraControls.Smooth(actual, target);
        Near(2.8250000029802322, next.Focus.Y);
        Check.That(next.Focus.Y != target.Focus.Y);
        Check.That(GalaxyOriginalCameraControls.PrepareTarget(actual, true, 0).Focus == actual.Focus);
        Check.That(GalaxyOriginalCameraControls.PrepareTarget(actual, false, -.01).Focus == actual.Focus);
    }

    [Test]
    public void OriginalDegreeMetadataClampsPitchAndLightYearDistanceOnlyOnTarget()
    {
        var high = GalaxyOriginalCameraControls.PrepareTarget(new(new(1, 0, 2), 100, 2, 100000), false, 0);
        var low = GalaxyOriginalCameraControls.PrepareTarget(new(new(1, 0, 2), -100, -2, .1), false, 0);
        Near((double)(80f * .01745329238474369f), high.Pitch);
        Near(-high.Pitch, low.Pitch);
        Near(25000, high.Distance); Near(6, low.Distance);
        Near(100, high.Yaw); Near(-100, low.Yaw);
        Near((double)(45f * .01745329238474369f), GalaxyOriginalCameraControls.DefaultPitch);
    }

    [Test]
    public void YawFollowsOriginalUnwrappedDeltaAndCallerToleranceIsExplicit()
    {
        var actual = new GalaxyCameraPose(new(0, 0, 0), 6, 0, 20);
        var target = new GalaxyCameraPose(new(1, 0, 0), 0, 1, 21);
        var next = GalaxyOriginalCameraControls.Smooth(actual, target);
        Near(4.799999982118607, next.Yaw);
        Check.That(next.Focus != target.Focus && next.Distance != target.Distance);
        Check.That(GalaxyOriginalCameraControls.Smooth(actual, target, new(1, 7, 2)) == target);
        Check.That(GalaxyOriginalCameraControls.Smooth(target, target) == target);
    }

    [Test]
    public void MultipleUpdatesApplyPerTickFactorsWithoutElapsedTimeScaling()
    {
        var actual = new GalaxyCameraPose(new(0, 0, 0), 0, 0, 10);
        var target = new GalaxyCameraPose(new(100, 0, 0), 1, 1, 1000);
        for (var index = 0; index < 5; index++) actual = GalaxyOriginalCameraControls.Smooth(actual, target);
        Near(100 * (1 - Math.Pow(1 - (double).3f, 5)), actual.Focus.X);
        var angular = 1 - Math.Pow(1 - (double).2f, 5);
        Near(angular, actual.Yaw); Near(angular, actual.Pitch);
        Near(10 * Math.Pow(100, angular), actual.Distance, 1e-8);
    }

    [Test]
    public void InvalidPoseAndInventedNegativeStopThresholdCannotEnterCameraState()
    {
        var valid = new GalaxyCameraPose(new(0, 0, 0), 0, 0, 10);
        Check.Throws<ArgumentException>(() => GalaxyOriginalCameraControls.Smooth(default, valid));
        Check.Throws<ArgumentException>(() => GalaxyOriginalCameraControls.Smooth(valid, valid with { Distance = 0 }));
        Check.Throws<ArgumentException>(() => GalaxyOriginalCameraControls.Smooth(valid, valid with { Pitch = double.NaN }));
        Check.Throws<ArgumentException>(() => GalaxyOriginalCameraControls.Smooth(valid, valid, new(-1, 0, 0)));
        Check.Throws<ArgumentException>(() => GalaxyOriginalCameraControls.PrepareTarget(valid, false, double.NaN));
    }
}