Update README.md to include project description, developer documentation links, and license information.
CI / build-test (push) Successful in 1m6s

This commit is contained in:
Leonid Pershin
2026-06-11 04:03:07 +03:00
parent 31aba3aeee
commit ff2231a8ab
72 changed files with 4113 additions and 0 deletions
@@ -0,0 +1,83 @@
using Microsoft.Xna.Framework;
using MrGameEng.Graphics;
using Xunit;
namespace MrGameEng.Graphics.Tests;
public class CameraMathTests
{
private static void AssertVector(Vector2 expected, Vector2 actual, float tolerance = 0.001f)
{
Assert.InRange(actual.X, expected.X - tolerance, expected.X + tolerance);
Assert.InRange(actual.Y, expected.Y - tolerance, expected.Y + tolerance);
}
[Fact]
public void CameraPosition_MapsToScreenCenter()
{
var camera = new Camera(new Vector2(500f, 300f), zoom: 2f, rotation: 0.7f);
var state = CameraMath.Compute(camera, 800, 600, ViewportMapping.Identity);
AssertVector(new Vector2(400f, 300f), state.WorldToScreen(camera.Position));
}
[Fact]
public void ScreenToWorld_RoundTripsWithWorldToScreen()
{
var camera = new Camera(new Vector2(123f, -45f), zoom: 1.5f, rotation: 0.3f);
var state = CameraMath.Compute(camera, 1280, 720, new ViewportMapping(new Vector2(0f, 60f), 1.5f));
var screen = new Vector2(200f, 500f);
var world = state.ScreenToWorld(screen);
AssertVector(screen, state.WorldToScreen(world));
}
[Fact]
public void Zoom_ShrinksCullRect()
{
var camera = new Camera(Vector2.Zero, zoom: 2f);
var state = CameraMath.Compute(camera, 800, 600, ViewportMapping.Identity);
Assert.Equal(400f, state.CullRect.Width, 1);
Assert.Equal(300f, state.CullRect.Height, 1);
AssertVector(Vector2.Zero, state.CullRect.Center);
}
[Fact]
public void Rotation_ExpandsCullRectToCoverRotatedView()
{
var straight = CameraMath.Compute(new Camera(Vector2.Zero), 800, 600, ViewportMapping.Identity);
var rotated = CameraMath.Compute(new Camera(Vector2.Zero, rotation: MathF.PI / 4f), 800, 600, ViewportMapping.Identity);
Assert.True(rotated.CullRect.Width > straight.CullRect.Width);
Assert.True(rotated.CullRect.Height > straight.CullRect.Height);
}
[Fact]
public void Bounds_ClampCameraToWorldEdges()
{
var bounds = new RectF(0f, 0f, 2000f, 1000f);
var camera = new Camera(new Vector2(-500f, 500f), bounds: bounds);
var state = CameraMath.Compute(camera, 800, 600, ViewportMapping.Identity);
// Camera should be clamped so the view's left edge sits at the world's left edge.
AssertVector(new Vector2(0f, 200f), state.ScreenToWorld(Vector2.Zero));
}
[Fact]
public void Mapping_CentersVirtualResolutionInWiderWindow()
{
var mapping = CameraMath.ComputeMapping(1920, 1080, 640, 360);
Assert.Equal(3f, mapping.Scale);
Assert.Equal(Vector2.Zero, mapping.Offset);
var letterboxed = CameraMath.ComputeMapping(1920, 1200, 640, 360);
Assert.Equal(3f, letterboxed.Scale);
Assert.Equal(new Vector2(0f, 60f), letterboxed.Offset);
}
}