+Matrix::Matrix():
+ Base(Base::identity())
+{ }
+
+Matrix::Matrix(const float *m):
+ Base(m)
+{ }
+
+Matrix::Matrix(const LinAl::Matrix<float, 4, 4> &other):
+ Base(other)
+{ }
+
+void Matrix::multiply(const Matrix &other)
+{
+ *this = *this*other;
+}
+
+void Matrix::translate(const Vector3 &t)
+{
+ multiply(translation(t));
+}
+
+void Matrix::rotate(const Angle &a, const Vector3 &x)
+{
+ multiply(rotation(a, x));
+}
+
+void Matrix::scale(const Vector3 &s)
+{
+ multiply(scaling(s));
+}
+
+Matrix Matrix::operator*(const Matrix &other) const
+{
+ return static_cast<const Base &>(*this)*static_cast<const Base &>(other);
+}
+
+Matrix &Matrix::operator*=(const Matrix &other)
+{
+ multiply(other);
+ return *this;
+}
+
+Vector4 Matrix::operator*(const Vector4 &vec) const
+{
+ return static_cast<const Base &>(*this)*LinAl::Vector<float, 4>(vec);
+}
+
+Vector3 Matrix::operator*(const Vector3 &vec) const
+{
+ return Vector3((*this)*Vector4(vec, 1.0f));
+}
+
+float Matrix::operator[](unsigned i) const
+{
+ if(i>=16)
+ throw out_of_range("Matrix::operator[]");
+ return operator()(i%4, i/4);
+}
+
+Matrix Matrix::translation(const Vector3 &t)
+{
+ return Geometry::AffineTransformation<float, 3>::translation(t).get_matrix();
+}
+
+Matrix Matrix::rotation(const Angle &a, const Vector3 &x)
+{
+ return Geometry::AffineTransformation<float, 3>::rotation(a, x).get_matrix();
+}
+
+Matrix Matrix::scaling(const Vector3 &s)
+{
+ return Geometry::AffineTransformation<float, 3>::scaling(s).get_matrix();
+}
+
+Matrix Matrix::ortho(float l, float r, float b, float t, float n, float f)
+{
+ if(l==r || b==t || n==f)
+ throw invalid_argument("Matrix::ortho");
+
+ Matrix result;
+ result(0, 0) = 2/(r-l);
+ result(1, 1) = 2/(t-b);
+ result(2, 2) = -2/(f-n);
+ result(0, 3) = -(r+l)/(r-l);
+ result(1, 3) = -(t+b)/(t-b);
+ result(2, 3) = -(f+n)/(f-n);
+ return result;
+}
+
+Matrix Matrix::ortho_centered(float w, float h)
+{
+ return ortho(-w/2, w/2, -h/2, h/2, -1, 1);
+}
+
+Matrix Matrix::ortho_bottomleft(float w, float h)
+{
+ return ortho(0, w, 0, h, -1, 1);
+}
+
+Matrix Matrix::ortho_topleft(float w, float h)