1 module prova.graphics.camera;
2 
3 import prova.core,
4        prova.math;
5 
6 ///
7 enum SortingMethod { Z, Distance }
8 ///
9 enum Projection { Perspective, Orthographic }
10 
11 ///
12 class Camera : Entity
13 {
14   ///
15   Projection projection = Projection.Perspective;
16   ///
17   SortingMethod sortingMethod = SortingMethod.Distance;
18   ///
19   bool useDepthBuffer = true;
20   /// Width and height will be set to the screen resolution when true
21   bool resolutionDependent = false;
22   ///
23   float zNear = 0;
24   ///
25   float zFar = 1000;
26   /// For orthographic projection and UI
27   float width = 1;
28   /// For orthographic projection and UI
29   float height = 1;
30   /// For perspective projection
31   float FOV = 90;
32 
33   ///
34   @property float zRange()
35   {
36     return zFar - zNear;
37   }
38 
39   ///
40   Matrix getViewMatrix()
41   {
42     Vector3 worldPosition = getWorldPosition();
43     Quaternion worldRotation = getWorldRotation();
44 
45     Matrix transform = Matrix.identity;
46     transform = transform.translate(-worldPosition);
47     transform = transform.rotate(worldRotation.getConjugate());
48     transform = transform.scale(scale);
49 
50     return transform;
51   }
52 
53   ///
54   Matrix getProjectionMatrix()
55   {
56     if(projection == Projection.Orthographic)
57       return Matrix.ortho(-width/2, width/2, height/2, -height/2, zNear, zFar);
58     return Matrix.perspective(width, height, zNear, zFar, FOV);
59   }
60 
61   /**
62    * Converts world position to screen position
63    * - This is equal to getProjectionMatrix() * getViewMatrix()
64    */
65   Matrix getScreenMatrix()
66   {
67     return getProjectionMatrix() * getViewMatrix();
68   }
69 
70   ///
71   Matrix getUIMatrix()
72   {
73     const float left = 0;
74     const float right = width / scale.x;
75     const float top = height / scale.y;
76     const float bottom = 0;
77 
78     return Matrix.ortho(left, right, top, bottom, -1, 1);
79   }
80 }