using Azimuth; using Blacklight.Core.Cameras; namespace Blacklight.Core.UnitTests.Cameras { public class CameraTests : UnitTestSharp.TestFixture { public const int ViewportWidth = 800; public const int ViewportHeight = 600; public static MicroscopeCamera GameCamera(Vector position, Scalar magnification) { return new MicroscopeCamera { Position = position, Magnification = magnification }; } public static ScreenSpaceCamera GlassCamera(int width, int height, Scalar magnification) { return new ScreenSpaceCamera(new Viewport(width, height)) { Magnification = magnification }; } public class WorldToProjectionTests : UnitTestSharp.TestFixture { public void TheCamerasOwnPosition_LandsAtTheProjectionOrigin() { MicroscopeCamera camera = GameCamera(new Vector(10, -4), magnification: 2); CheckEqual(Vector.Zero, camera.WorldToProjection.TransformPoint(new Vector(10, -4))); } public void Magnification_ScalesTheOffsetFromTheCamera() { MicroscopeCamera camera = GameCamera(Vector.Zero, magnification: 2); CheckEqual(new Vector(20, 10), camera.WorldToProjection.TransformPoint(new Vector(10, 5))); } public void TheScreenSpaceWorldOrigin_LandsAtTheTopLeftCorner() { ScreenSpaceCamera camera = GlassCamera(ViewportWidth, ViewportHeight, magnification: 1); CheckEqual(new Vector(-400, 300), camera.WorldToProjection.TransformPoint(Vector.Zero)); } public void TheScreenSpaceVisibleSize_LandsAtTheBottomRightCorner() { ScreenSpaceCamera camera = GlassCamera(ViewportWidth, ViewportHeight, magnification: 1); CheckEqual(new Vector(400, -300), camera.WorldToProjection.TransformPoint(camera.VisibleSize)); } } public class ProjectionToWorldTests : UnitTestSharp.TestFixture { public void TheProjectionOrigin_LandsAtTheCamerasOwnPosition() { MicroscopeCamera camera = GameCamera(new Vector(10, -4), magnification: 2); CheckEqual(new Vector(10, -4), camera.ProjectionToWorld.TransformPoint(Vector.Zero)); } public void Magnification_ShrinksTheOffsetBackTowardTheCamera() { MicroscopeCamera camera = GameCamera(new Vector(10, -4), magnification: 2); CheckEqual(new Vector(20, 1), camera.ProjectionToWorld.TransformPoint(new Vector(20, 10))); } public void TheTopLeftCorner_LandsAtTheScreenSpaceWorldOrigin() { ScreenSpaceCamera camera = GlassCamera(ViewportWidth, ViewportHeight, magnification: 1); CheckEqual(Vector.Zero, camera.ProjectionToWorld.TransformPoint(new Vector(-400, 300))); } public void ComposedWithWorldToProjection_IsTheIdentity() { MicroscopeCamera camera = GameCamera(new Vector(10, -4), magnification: 2); AffineMatrix roundTrip = camera.ProjectionToWorld * camera.WorldToProjection; CheckEqual(new Vector(123, -45), roundTrip.TransformPoint(new Vector(123, -45))); } } public class WorldToWorldOfTests : UnitTestSharp.TestFixture { public void ThePointUnderTheGameCamera_LandsAtTheScreenCenter() { MicroscopeCamera game = GameCamera(Vector.Zero, magnification: 1); ScreenSpaceCamera glass = GlassCamera(ViewportWidth, ViewportHeight, magnification: 1); CheckEqual(new Vector(400, 300), game.WorldToWorldOf(glass).TransformPoint(Vector.Zero)); } public void APointAboveTheGameCamera_LandsAboveTheScreenCenter() { MicroscopeCamera game = GameCamera(Vector.Zero, magnification: 1); ScreenSpaceCamera glass = GlassCamera(ViewportWidth, ViewportHeight, magnification: 1); CheckEqual(new Vector(500, 250), game.WorldToWorldOf(glass).TransformPoint(new Vector(100, 50))); } public void TheTopLeftOfTheView_LandsAtTheGlassOrigin() { MicroscopeCamera game = GameCamera(Vector.Zero, magnification: 1); ScreenSpaceCamera glass = GlassCamera(ViewportWidth, ViewportHeight, magnification: 1); CheckEqual(Vector.Zero, game.WorldToWorldOf(glass).TransformPoint(new Vector(-400, 300))); } public void PanningTheGameCamera_SlidesThePointTheOtherWay() { MicroscopeCamera game = GameCamera(new Vector(100, 0), magnification: 1); ScreenSpaceCamera glass = GlassCamera(ViewportWidth, ViewportHeight, magnification: 1); CheckEqual(new Vector(300, 300), game.WorldToWorldOf(glass).TransformPoint(Vector.Zero)); } public void GameMagnification_ScalesTheOffsetFromTheScreenCenter() { MicroscopeCamera game = GameCamera(Vector.Zero, magnification: 2); ScreenSpaceCamera glass = GlassCamera(ViewportWidth, ViewportHeight, magnification: 1); CheckEqual(new Vector(600, 200), game.WorldToWorldOf(glass).TransformPoint(new Vector(100, 50))); } public void GlassMagnification_ScalesTheOffsetFromTheGlassOrigin() { MicroscopeCamera game = GameCamera(Vector.Zero, magnification: 1); ScreenSpaceCamera glass = GlassCamera(ViewportWidth, ViewportHeight, magnification: 2); CheckEqual(new Vector(250, 125), game.WorldToWorldOf(glass).TransformPoint(new Vector(100, 50))); } public void ADestinationOnASmallerViewport_LandsInItsOwnFrame() { MicroscopeCamera game = GameCamera(Vector.Zero, magnification: 1); ScreenSpaceCamera glass = GlassCamera(width: 400, height: 300, magnification: 1); CheckEqual(new Vector(200, 150), game.WorldToWorldOf(glass).TransformPoint(Vector.Zero)); } public void AnUnboundDestination_LeavesProjectionSpaceMerelyFlipped() { MicroscopeCamera game = GameCamera(Vector.Zero, magnification: 1); var glass = new ScreenSpaceCamera(); CheckEqual(new Vector(100, -50), game.WorldToWorldOf(glass).TransformPoint(new Vector(100, 50))); } public void ACameraBridgedToItself_IsTheIdentity() { MicroscopeCamera camera = GameCamera(new Vector(10, -4), magnification: 2); CheckEqual(new Vector(37, -19), camera.WorldToWorldOf(camera).TransformPoint(new Vector(37, -19))); } public void BridgingBackAgain_ReturnsTheOriginalPoint() { MicroscopeCamera game = GameCamera(new Vector(25, -7), magnification: 2); ScreenSpaceCamera glass = GlassCamera(ViewportWidth, ViewportHeight, magnification: 2); AffineMatrix roundTrip = glass.WorldToWorldOf(game) * game.WorldToWorldOf(glass); CheckEqual(new Vector(123, -45), roundTrip.TransformPoint(new Vector(123, -45))); } } } }