]> git.tdb.fi Git - libs/gl.git/blob - source/core/matrix.cpp
Use persistent cameras in effects
[libs/gl.git] / source / core / matrix.cpp
1 #include <algorithm>
2 #include <cmath>
3 #include <msp/geometry/affinetransformation.h>
4 #include "error.h"
5 #include "matrix.h"
6
7 using namespace std;
8
9 namespace Msp {
10 namespace GL {
11
12 Matrix::Matrix():
13         Base(Base::identity())
14 { }
15
16 Matrix::Matrix(const float *m):
17         Base(m)
18 { }
19
20 Matrix::Matrix(const LinAl::Matrix<float, 4, 4> &other):
21         Base(other)
22 { }
23
24 Matrix &Matrix::translate(const Vector3 &t)
25 {
26         return multiply(translation(t));
27 }
28
29 Matrix &Matrix::rotate(const Angle &a, const Vector3 &x)
30 {
31         return multiply(rotation(a, x));
32 }
33
34 Matrix &Matrix::scale(const Vector3 &s)
35 {
36         return multiply(scaling(s));
37 }
38
39 float Matrix::operator[](unsigned i) const
40 {
41         if(i>=16)
42                 throw out_of_range("Matrix::operator[]");
43         return operator()(i%4, i/4);
44 }
45
46 Matrix Matrix::translation(const Vector3 &t)
47 {
48         return Geometry::AffineTransformation<float, 3>::translation(t).get_matrix();
49 }
50
51 Matrix Matrix::rotation(const Angle &a, const Vector3 &x)
52 {
53         return Geometry::AffineTransformation<float, 3>::rotation(a, x).get_matrix();
54 }
55
56 Matrix Matrix::scaling(const Vector3 &s)
57 {
58         return Geometry::AffineTransformation<float, 3>::scaling(s).get_matrix();
59 }
60
61 Matrix Matrix::ortho(float l, float r, float b, float t, float n, float f)
62 {
63         if(l==r || b==t || n==f)
64                 throw invalid_argument("Matrix::ortho");
65
66         Matrix result;
67         result(0, 0) = 2/(r-l);
68         result(1, 1) = 2/(t-b);
69         result(2, 2) = -2/(f-n);
70         result(0, 3) = -(r+l)/(r-l);
71         result(1, 3) = -(t+b)/(t-b);
72         result(2, 3) = -(f+n)/(f-n);
73         return result;
74 }
75
76 Matrix Matrix::ortho_centered(float w, float h)
77 {
78         return ortho(-w/2, w/2, -h/2, h/2, -1, 1);
79 }
80
81 Matrix Matrix::ortho_bottomleft(float w, float h)
82 {
83         return ortho(0, w, 0, h, -1, 1);
84 }
85
86 Matrix Matrix::ortho_topleft(float w, float h)
87 {
88         return ortho(0, w, h, 0, -1, 1);
89 }
90
91 Matrix Matrix::frustum(float l, float r, float b, float t, float n, float f)
92 {
93         if(l==r || b==t || n<=0 || f<=n)
94                 throw invalid_argument("Matrix::frustum");
95
96         Matrix result;
97         result(0, 0) = 2*n/(r-l);
98         result(1, 1) = 2*n/(t-b);
99         result(0, 2) = (r+l)/(r-l);
100         result(1, 2) = (t+b)/(t-b);
101         result(2, 2) = -(f+n)/(f-n);
102         result(3, 2) = -1;
103         result(2, 3) = -2*f*n/(f-n);
104         result(3, 3) = 0;
105         return result;
106 }
107
108 Matrix Matrix::frustum_centered(float w, float h, float n, float f)
109 {
110         return frustum(-w/2, w/2, -h/2, h/2, n, f);
111 }
112
113 Matrix Matrix::perspective(const Angle &h, float a, float n, float f)
114 {
115         float hh = tan(h/2.0f)*n;
116         return frustum(-hh*a, hh*a, -hh, hh, n, f);
117 }
118
119 } // namespace GL
120 } // namespace Msp