1 module dgt.camera;
2 
3 import dgt.geom;
4 
5 ///A set of projections used to manage windows and views
6 struct Camera
7 {
8     const Transform project, unproject, opengl;
9 
10     ////Create a camera with a given window size and view of the world
11     pure @nogc nothrow this(in Rectangle windowSize, in Rectangle world, in Transform cameraTransform = Transform())
12     {
13         unproject = cameraTransform
14             * Transform.translate(-world.topLeft)
15             * Transform.scale(Vector(world.width / windowSize.width, world.height / windowSize.height).inverse)
16             * Transform.translate(windowSize.topLeft);
17         project = unproject.inverse;
18         opengl = cameraTransform
19             * Transform.translate(-world.topLeft)
20             * Transform.scale(world.size.inverse * 2)
21             * Transform.translate(Vector(-1, -1))
22             * Transform.scale(Vector(1, -1));
23     }
24 }
25 
26 unittest
27 {
28     const cam = Camera(Rectangle(0, 0, 100, 100), Rectangle(0, 0, 50, 50));
29     const screenBottom = Vector(0, 100);
30     const worldBottom = Vector(0, 50);
31     assert(cam.project * screenBottom == worldBottom);
32     assert(cam.unproject * worldBottom == screenBottom);
33     assert(cam.opengl * worldBottom == Vector(-1, -1));
34 }
35 unittest
36 {
37     const cam = Camera(Rectangle(0, 0, 100, 100), Rectangle(50, 50, 50, 50));
38     const worldTop = Vector(50, 50);
39     assert(cam.opengl * worldTop == Vector(-1, 1));
40 }
41 unittest
42 {
43     const cam = Camera(Rectangle(0, 0, 10, 10), Rectangle(0, 0, 10, 10),
44             Transform.rotate(-90));
45     const projected = cam.project * Vector(5, 0);
46     assert(projected == Vector(0, 5));
47 }