3 #include <msp/geometry/affinetransformation.h>
13 Base(Base::identity())
16 Matrix::Matrix(const float *m):
17 Base(LinAl::SquareMatrix<float, 4>(m))
20 Matrix::Matrix(const double *m):
24 Matrix::Matrix(const LinAl::Matrix<double, 4, 4> &other):
28 void Matrix::multiply(const Matrix &other)
33 void Matrix::translate(const Vector3 &t)
35 multiply(translation(t));
38 void Matrix::rotate(const Angle &a, const Vector3 &x)
40 multiply(rotation(a, x));
43 void Matrix::scale(const Vector3 &s)
48 Matrix Matrix::operator*(const Matrix &other) const
50 return static_cast<const Base &>(*this)*static_cast<const Base &>(other);
53 Matrix &Matrix::operator*=(const Matrix &other)
59 Vector4 Matrix::operator*(const Vector4 &vec) const
61 return static_cast<const Base &>(*this)*LinAl::Vector<double, 4>(vec);
64 Vector3 Matrix::operator*(const Vector3 &vec) const
66 return Vector3((*this)*Vector4(vec, 1.0f));
69 double Matrix::operator[](unsigned i) const
72 throw out_of_range("Matrix::operator[]");
73 return operator()(i%4, i/4);
76 Matrix Matrix::translation(const Vector3 &t)
78 return Geometry::AffineTransformation<double, 3>::translation(t).get_matrix();
81 Matrix Matrix::rotation(const Angle &a, const Vector3 &x)
83 return Geometry::AffineTransformation<double, 3>::rotation(a, x).get_matrix();
86 Matrix Matrix::scaling(const Vector3 &s)
88 return Geometry::AffineTransformation<double, 3>::scaling(s).get_matrix();
91 Matrix Matrix::ortho(double l, double r, double b, double t, double n, double f)
93 if(l==r || b==t || n==f)
94 throw invalid_argument("Matrix::ortho");
97 result(0, 0) = 2/(r-l);
98 result(1, 1) = 2/(t-b);
99 result(2, 2) = -2/(f-n);
100 result(0, 3) = -(r+l)/(r-l);
101 result(1, 3) = -(t+b)/(t-b);
102 result(2, 3) = -(f+n)/(f-n);
106 Matrix Matrix::ortho_centered(double w, double h)
108 return ortho(-w/2, w/2, -h/2, h/2, -1, 1);
111 Matrix Matrix::ortho_bottomleft(double w, double h)
113 return ortho(0, w, 0, h, -1, 1);
116 Matrix Matrix::ortho_topleft(double w, double h)
118 return ortho(0, w, h, 0, -1, 1);
121 Matrix Matrix::frustum(double l, double r, double b, double t, double n, double f)
123 if(l==r || b==t || n<=0 || f<=n)
124 throw invalid_argument("Matrix::frustum");
127 result(0, 0) = 2*n/(r-l);
128 result(1, 1) = 2*n/(t-b);
129 result(0, 2) = (r+l)/(r-l);
130 result(1, 2) = (t+b)/(t-b);
131 result(2, 2) = -(f+n)/(f-n);
133 result(2, 3) = -2*f*n/(f-n);
138 Matrix Matrix::frustum_centered(double w, double h, double n, double f)
140 return frustum(-w/2, w/2, -h/2, h/2, n, f);
143 Matrix Matrix::perspective(const Angle &h, double a, double n, double f)
145 double hh = tan(h/2.0)*n;
146 return frustum(-hh*a, hh*a, -hh, hh, n, f);
150 GLenum MatrixStack::current_mode = GL_MODELVIEW;
152 MatrixStack::MatrixStack(GLenum m):
155 matrices.reserve(mode==GL_MODELVIEW ? 32 : 4);
156 matrices.push_back(Matrix());
159 MatrixStack::MatrixStack():
162 matrices.reserve(32);
163 matrices.push_back(Matrix());
166 const Matrix &MatrixStack::top() const
168 return matrices.back();
171 void MatrixStack::load(const Matrix &m)
177 void MatrixStack::multiply(const Matrix &m)
179 matrices.back() *= m;
183 void MatrixStack::push()
185 matrices.push_back(top());
188 void MatrixStack::pop()
190 if(matrices.size()==1)
191 throw stack_underflow("MatrixStack::pop()");
197 void MatrixStack::update()
202 if(mode!=current_mode)
208 glLoadMatrixd(matrices.back().data());
211 MatrixStack &MatrixStack::operator=(const Matrix &m)
217 MatrixStack &MatrixStack::operator*=(const Matrix &m)
223 MatrixStack &MatrixStack::modelview()
225 static MatrixStack ms(GL_MODELVIEW);
229 MatrixStack &MatrixStack::projection()
231 static MatrixStack ms(GL_PROJECTION);