using System; using UnitTestSharp; namespace Azimuth.UnitTests { public class ViewProjectionTests : TestFixture { public class CtorTests : TestFixture { public void StraightDown_AssignsTheCoefficients() { var projection = new ViewProjection(yawTurns: 0, pitchTurns: 0.25); CheckEqual(1, projection.XToScreenX); CheckEqual(0, projection.YToScreenX); CheckEqual(0, projection.XToScreenY); CheckEqual(1, projection.YToScreenY); CheckEqual(0, projection.AltitudeToScreenY); CheckEqual(0, projection.XToDepth); CheckEqual(0, projection.YToDepth); CheckEqual(-1, projection.AltitudeToDepth); } public void SideOn_AssignsTheCoefficients() { var projection = new ViewProjection(yawTurns: 0.25, pitchTurns: 0); CheckEqual(0, projection.XToScreenX); CheckEqual(-1, projection.YToScreenX); CheckEqual(0, projection.XToScreenY); CheckEqual(0, projection.YToScreenY); CheckEqual(1, projection.AltitudeToScreenY); CheckEqual(1, projection.XToDepth); CheckEqual(0, projection.YToDepth); CheckEqual(0, projection.AltitudeToDepth); } public void PitchesAtTheEnds_AreAllowed() { new ViewProjection(yawTurns: 0, pitchTurns: 0); new ViewProjection(yawTurns: 0, pitchTurns: 0.25); } public void AnyFiniteYaw_IsAllowed() { new ViewProjection(yawTurns: -3.5, pitchTurns: 0.1); new ViewProjection(yawTurns: 12, pitchTurns: 0.1); } public void NaNYaw_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); new ViewProjection(yawTurns: double.NaN, pitchTurns: 0.1); } public void InfiniteYaw_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); new ViewProjection(yawTurns: double.PositiveInfinity, pitchTurns: 0.1); } public void NaNPitch_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); new ViewProjection(yawTurns: 0, pitchTurns: double.NaN); } public void NegativePitch_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); new ViewProjection(yawTurns: 0, pitchTurns: -0.01); } public void PitchBeyondStraightDown_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); new ViewProjection(yawTurns: 0, pitchTurns: 0.26); } } public class ProjectTests : TestFixture { public void TheOrigin_LandsOnTheOrigin() { CheckEqual(new Vector(0, 0), ViewProjection.Isometric.Project(new Vector3(0, 0, 0))); } public void YawZeroAndPitchZero_KeepsGroundXAndTakesAltitudeForUp() { var projection = new ViewProjection(yawTurns: 0, pitchTurns: 0); CheckEqual(new Vector(1, 3), projection.Project(new Vector3(1, 2, 3))); } public void APositiveYaw_TurnsTheGroundCounterClockwise() { var projection = new ViewProjection(yawTurns: 0.25, pitchTurns: 0.25); CheckEqual(new Vector(0, 1), projection.Project(new Vector3(1, 0, 0))); CheckEqual(new Vector(-1, 0), projection.Project(new Vector3(0, 1, 0))); } public void ANegativeYaw_TurnsTheGroundClockwise() { var projection = new ViewProjection(yawTurns: -0.25, pitchTurns: 0.25); CheckEqual(new Vector(0, -1), projection.Project(new Vector3(1, 0, 0))); } public void TopDown_IgnoresAltitude() { CheckEqual(new Vector(3, 4), ViewProjection.TopDown.Project(new Vector3(3, 4, 5))); CheckEqual(new Vector(3, 4), ViewProjection.TopDown.Project(new Vector3(3, 4, -5))); } public void Isometric_GroundXGoesRightAndUp() { CheckEqual( new Vector(0.707106781187, 0.408248290464), ViewProjection.Isometric.Project(new Vector3(1, 0, 0))); } public void Isometric_GroundYGoesLeftAndUp() { CheckEqual( new Vector(-0.707106781187, 0.408248290464), ViewProjection.Isometric.Project(new Vector3(0, 1, 0))); } public void Isometric_AltitudeGoesStraightUp() { CheckEqual(new Vector(0, 0.816496580928), ViewProjection.Isometric.Project(new Vector3(0, 0, 1))); } public void Isometric_AGroundDiagonalIsAsTallAsAnAltitudeStep() { CheckEqual(new Vector(0, 0.816496580928), ViewProjection.Isometric.Project(new Vector3(1, 1, 0))); } public void Dimetric2To1_GroundXIsTwiceAsWideAsItIsTall() { CheckEqual( new Vector(0.707106781187, 0.353553390593), ViewProjection.Dimetric2To1.Project(new Vector3(1, 0, 0))); } public void Dimetric2To1_TheTwoGroundDiagonalsLieOnTheScreenAxes() { CheckEqual(new Vector(0, 0.707106781187), ViewProjection.Dimetric2To1.Project(new Vector3(1, 1, 0))); CheckEqual(new Vector(1.414213562373, 0), ViewProjection.Dimetric2To1.Project(new Vector3(1, -1, 0))); } public void Dimetric2To1_AltitudeGoesStraightUp() { CheckEqual(new Vector(0, 0.866025403784), ViewProjection.Dimetric2To1.Project(new Vector3(0, 0, 1))); } public void ScalesLinearlyWithThePosition() { CheckEqual( new Vector(2.121320343560, 3.674234614176), ViewProjection.Isometric.Project(new Vector3(3, 0, 3))); } } public class TryUnprojectTests : TestFixture { public void TopDown_ReadsTheScreenAsTheGround() { bool found = ViewProjection.TopDown.TryUnproject(new Vector(3, 4), 0, out Vector3 position); CheckTrue(found); CheckEqual(new Vector3(3, 4, 0), position); } public void TopDown_KeepsTheAltitudeAsGiven() { ViewProjection.TopDown.TryUnproject(new Vector(3, 4), 7, out Vector3 position); CheckEqual(new Vector3(3, 4, 7), position); } public void Dimetric2To1_FindsTheGroundPositionThatProjectedThere() { var ground = new Vector3(5, -2, 0); Vector screen = ViewProjection.Dimetric2To1.Project(ground); bool found = ViewProjection.Dimetric2To1.TryUnproject(screen, 0, out Vector3 position); CheckTrue(found); CheckEqual(ground, position); } public void Dimetric2To1_AtAnAltitude_FindsThePositionAtThatAltitude() { var raised = new Vector3(5, -2, 3); Vector screen = ViewProjection.Dimetric2To1.Project(raised); ViewProjection.Dimetric2To1.TryUnproject(screen, 3, out Vector3 position); CheckEqual(raised, position); } public void Isometric_FindsTheGroundPositionThatProjectedThere() { var ground = new Vector3(-4, 6, 0); Vector screen = ViewProjection.Isometric.Project(ground); ViewProjection.Isometric.TryUnproject(screen, 0, out Vector3 position); CheckEqual(ground, position); } public void ATurnedView_FindsTheGroundPositionThatProjectedThere() { var projection = new ViewProjection(yawTurns: 0.3, pitchTurns: 0.1); var ground = new Vector3(2, 9, 0); projection.TryUnproject(projection.Project(ground), 0, out Vector3 position); CheckEqual(ground, position); } public void SideOn_FindsNothing() { var projection = new ViewProjection(yawTurns: 0, pitchTurns: 0); bool found = projection.TryUnproject(new Vector(1, 2), 0, out Vector3 position); CheckFalse(found); CheckEqual(new Vector3(0, 0, 0), position); } } public class DepthTests : TestFixture { public void TheOrigin_IsAtZeroDepth() { CheckEqual(0, ViewProjection.Isometric.Depth(new Vector3(0, 0, 0))); } public void SideOn_IsGroundXAlone() { var projection = new ViewProjection(yawTurns: 0.25, pitchTurns: 0); CheckEqual(1, projection.Depth(new Vector3(1, 7, 7))); } public void TopDown_HigherIsNearerTheCamera() { CheckEqual(-5, ViewProjection.TopDown.Depth(new Vector3(3, 4, 5))); CheckEqual(5, ViewProjection.TopDown.Depth(new Vector3(3, 4, -5))); } public void Dimetric2To1_FartherAlongGroundYIsFartherAway() { CheckEqual(0.612372435696, ViewProjection.Dimetric2To1.Depth(new Vector3(0, 1, 0))); } public void Isometric_AltitudeBringsItNearer() { CheckEqual(-0.577350269190, ViewProjection.Isometric.Depth(new Vector3(0, 0, 1))); } } public class PresetTests : TestFixture { public void TopDown_IsAStraightDownPitch() { CheckEqual(new ViewProjection(yawTurns: 0, pitchTurns: 0.25).Project(new Vector3(3, 4, 5)), ViewProjection.TopDown.Project(new Vector3(3, 4, 5))); } public void Dimetric2To1_IsAThirtyDegreePitchAtFortyFiveDegreesYaw() { var projection = new ViewProjection(yawTurns: 0.125, pitchTurns: 30.0 / 360); CheckEqual(projection.Project(new Vector3(3, 4, 5)), ViewProjection.Dimetric2To1.Project(new Vector3(3, 4, 5))); } } } }