--- /dev/null
+/.config
+/libmsplinal.so
+/msplinal.pc
+/temp
--- /dev/null
+package "msplinal"
+{
+ library "msplinal"
+ {
+ source "source";
+ install true;
+ install_map
+ {
+ map "source" "include/msp/linal";
+ };
+ };
+};
--- /dev/null
+#include "vector.h"
+#include "vector3.h"
+#include "matrix.h"
+#include "squarematrix.h"
+#include "matrix4.h"
+
+/* This dummy file is needed to make Builder happy, and also serves as a syntax
+check by pulling in all the headers. */
--- /dev/null
+#ifndef MSP_LIEAL_MATMIX_H_
+#define MSP_LIEAL_MATMIX_H_
+
+#include "vector.h"
+
+namespace Msp {
+namespace LinAl {
+
+/**
+A general mathematical matrix.
+*/
+template<typename T, unsigned M, unsigned N>
+class Matrix
+{
+private:
+ T data[M*N];
+
+public:
+ Matrix();
+ Matrix(const T *);
+ template<typename U>
+ Matrix(const Matrix<U, M, N> &);
+ static Matrix from_columns(const Vector<T, M> *);
+ static Matrix from_rows(const Vector<T, N> *);
+
+ T &operator()(unsigned, unsigned);
+ const T &operator()(unsigned, unsigned) const;
+
+ Matrix &operator*=(T);
+ Matrix &operator/=(T);
+ Matrix &operator+=(const Matrix &);
+ Matrix &operator-=(const Matrix &);
+
+ Matrix<T, N, M> transpose() const;
+};
+
+template<typename T, unsigned M, unsigned N>
+inline T &Matrix<T, M, N>::operator()(unsigned i, unsigned j)
+{
+ return data[i+M*j];
+}
+
+template<typename T, unsigned M, unsigned N>
+inline const T &Matrix<T, M, N>::operator()(unsigned i, unsigned j) const
+{
+ return data[i+M*j];
+}
+
+template<typename T, unsigned M, unsigned N>
+inline Matrix<T, M, N> &Matrix<T, M, N>::operator*=(T s)
+{
+ for(unsigned i=0; i<M*N; ++i)
+ data[i] *= s;
+ return *this;
+}
+
+template<typename T, unsigned M, unsigned N>
+inline Matrix<T, M, N> operator*(const Matrix<T, M, N> &m, T s)
+{
+ Matrix<T, M, N> r(m);
+ return r *= s;
+}
+
+template<typename T, unsigned M, unsigned N>
+inline Matrix<T, M, N> operator*(T s, const Matrix<T, M, N> &m)
+{
+ return m*s;
+}
+
+template<typename T, unsigned M, unsigned N>
+inline Matrix<T, M, N> &Matrix<T, M, N>::operator/=(T s)
+{
+ for(unsigned i=0; i<M*N; ++i)
+ data[i] /= s;
+ return *this;
+}
+
+template<typename T, unsigned M, unsigned N>
+inline Matrix<T, M, N> operator/(const Matrix<T, M, N> &m, T s)
+{
+ Matrix<T, M, N> r(m);
+ return r /= s;
+}
+
+template<typename T, unsigned M, unsigned N>
+inline Matrix<T, M, N> &Matrix<T, M, N>::operator+=(const Matrix<T, M, N> &m)
+{
+ for(unsigned i=0; i<M*N; ++i)
+ data[i] += m.data[i];
+ return *this;
+}
+
+template<typename T, unsigned M, unsigned N>
+inline Matrix<T, M, N> operator+(const Matrix<T, M, N> &m1, const Matrix<T, M, N> &m2)
+{
+ Matrix<T, M, N> r(m1);
+ return r += m2;
+}
+
+template<typename T, unsigned M, unsigned N>
+inline Matrix<T, M, N> &Matrix<T, M, N>::operator-=(const Matrix<T, M, N> &m)
+{
+ for(unsigned i=0; i<M*N; ++i)
+ data[i] -= m.data[i];
+ return *this;
+}
+
+template<typename T, unsigned M, unsigned N>
+inline Matrix<T, M, N> operator-(const Matrix<T, M, N> &m1, const Matrix<T, M, N> &m2)
+{
+ Matrix<T, M, N> r(m1);
+ return r -= m2;
+}
+
+template<typename T, unsigned M, unsigned P, unsigned N>
+Matrix<T, M, N> operator*(const Matrix<T, M, P> &m1, const Matrix<T, P, N> &m2)
+{
+ Matrix<T, M, N> r;
+ for(unsigned i=0; i<M; ++i)
+ for(unsigned j=0; j<N; ++j)
+ for(unsigned k=0; k<P; ++k)
+ r.at(i, j) += m1(i, k)*m2(k, j);
+ return r;
+}
+
+template<typename T, unsigned M, unsigned N>
+Vector<T, M> operator*(const Matrix<T, M, N> &m, const Vector<T, N> &v)
+{
+ Vector<T, M> r;
+ for(unsigned i=0; i<M; ++i)
+ for(unsigned j=0; j<N; ++j)
+ r[i] += m(i, j)*v[j];
+ return r;
+}
+
+template<typename T, unsigned M, unsigned N>
+Vector<T, N> operator*(const Vector<T, M> &v, const Matrix<T, M, N> &m)
+{
+ Vector<T, N> r;
+ for(unsigned j=0; j<N; ++j)
+ for(unsigned i=0; i<M; ++i)
+ r[j] += v[i]*m.at(i, j);
+ return r;
+}
+
+} // namespace LinAl
+} // namespace Msp
+
+#endif
--- /dev/null
+#ifndef MSP_LINAL_MATRIX4_H_
+#define MSP_LINAL_MATRIX4_H_
+
+#include "squarematrix.h"
+
+namespace Msp {
+namespace LinAl {
+
+/**
+A 4x4 square matrix, capable of expressing affine transformations in a
+three-dimensional vector space.
+*/
+template<typename T>
+class Matrix4: public SquareMatrix<T, 4>
+{
+};
+
+} // namespace LinAl
+} // namespace Msp
+
+#endif
--- /dev/null
+#ifndef MSP_LINAL_SQUAREMATRIX_H_
+#define MSP_LINAL_SQUAREMATRIX_H_
+
+#include "matrix.h"
+
+namespace Msp {
+namespace LinAl {
+
+template<typename T, unsigned S>
+class SquareMatrix: public Matrix<T, S, S>
+{
+public:
+ SquareMatrix();
+ SquareMatrix(const T *);
+ template<typename U>
+ SquareMatrix(const Matrix<U, S, S> &);
+ static SquareMatrix identity();
+
+ SquareMatrix &operator*=(const SquareMatrix &);
+
+ void invert();
+};
+
+} // namespace LinAl
+} // namespace Msp
+
+#endif
--- /dev/null
+#ifndef MSP_LINAL_VECTOR_H_
+#define MSP_LINAL_VECTOR_H_
+
+#include <algorithm>
+#include <cmath>
+
+namespace Msp {
+namespace LinAl {
+
+/**
+A general mathematical vector.
+*/
+template<typename T, unsigned N>
+class Vector
+{
+protected:
+ T data[N];
+
+public:
+ Vector();
+ Vector(const T *d);
+ template<typename U>
+ Vector(const Vector<U, N> &v);
+
+ T &operator[](unsigned i);
+ const T &operator[](unsigned i) const;
+
+ Vector &operator*=(T);
+ Vector &operator/=(T);
+ Vector &operator+=(const Vector &);
+ Vector &operator-=(const Vector &);
+
+ T norm() const;
+ Vector &normalize();
+};
+
+
+template<typename T, unsigned N>
+inline Vector<T, N>::Vector()
+{
+ std::fill(data, data+N, T());
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N>::Vector(const T *d)
+{
+ std::copy(d, d+N, data);
+}
+
+template<typename T, unsigned N>
+template<typename U>
+inline Vector<T, N>::Vector(const Vector<U, N> &v)
+{
+ std::copy(v.data, v.data+N, data);
+}
+
+template<typename T, unsigned N>
+T &Vector<T, N>::operator[](unsigned i)
+{
+ return data[i];
+}
+
+template<typename T, unsigned N>
+const T &Vector<T, N>::operator[](unsigned i) const
+{
+ return data[i];
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> &Vector<T, N>::operator*=(T s)
+{
+ for(unsigned i=0; i<N; ++i)
+ data[i] *= s;
+ return *this;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> operator*(const Vector<T, N> &v, T s)
+{
+ Vector<T, N> r(v);
+ return r *= s;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> operator*(T s, const Vector<T, N> &v)
+{
+ return v*s;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> &Vector<T, N>::operator/=(T s)
+{
+ for(unsigned i=0; i<N; ++i)
+ data[i] /= s;
+ return *this;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> operator/(const Vector<T, N> &v, T s)
+{
+ Vector<T, N> r(v);
+ return r /= s;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> &Vector<T, N>::operator+=(const Vector<T, N> &v)
+{
+ for(unsigned i=0; i<N; ++i)
+ data[i] += v[i];
+ return *this;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> operator+(const Vector<T, N> &v1, const Vector<T, N> &v2)
+{
+ Vector<T, N> r(v1);
+ return r += v2;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> &Vector<T, N>::operator-=(const Vector<T, N> &v)
+{
+ for(unsigned i=0; i<N; ++i)
+ data[i] -= v[i];
+ return *this;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> operator-(const Vector<T, N> &v1, const Vector<T, N> &v2)
+{
+ Vector<T, N> r(v1);
+ return r -= v2;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> operator-(const Vector<T, N> &v)
+{
+ Vector<T, N> r(v);
+ for(unsigned i=0; i<N; ++i)
+ r[i] = -r[i];
+ return r;
+}
+
+template<typename T, unsigned N>
+inline T inner_product(const Vector<T, N> &v1, const Vector<T, N> &v2)
+{
+ T r = T();
+ for(unsigned i=0; i<N; ++i)
+ r += v1[i]*v2[i];
+ return r;
+}
+
+template<typename T, unsigned N>
+inline T Vector<T, N>::norm() const
+{
+ return sqrt(inner_product(*this, *this));
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> &Vector<T, N>::normalize()
+{
+ return *this /= norm();
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> normalize(const Vector<T, N> &v)
+{
+ Vector<T, N> r(v);
+ return r.normalize();
+}
+
+} // namespace LinAl
+} // namespace Msp
+
+#endif
--- /dev/null
+#ifndef MSP_LINAL_VECTOR3_H_
+#define MSP_LINAL_VECTOR3_H_
+
+#include "vector.h"
+
+namespace Msp {
+namespace LinAl {
+
+/**
+A three-dimensional vector, applicable for Euclidean space.
+*/
+template<typename T>
+class Vector3: public Vector<T, 3>
+{
+public:
+ Vector3() { }
+ Vector3(const T *);
+ Vector3(T, T, T);
+ template<typename U>
+ Vector3(const Vector<U, 3> &);
+};
+
+template<typename T>
+inline Vector3<T>::Vector3(const T *d):
+ Vector<T, 3>(d)
+{ }
+
+template<typename T>
+inline Vector3<T>::Vector3(T x, T y, T z)
+{
+ this->data[0] = x;
+ this->data[1] = y;
+ this->data[2] = z;
+}
+
+template<typename T>
+template<typename U>
+inline Vector3<T>::Vector3(const Vector<U, 3> &v):
+ Vector<T, 3>(v)
+{ }
+
+template<typename T>
+inline T dot(const Vector3<T> &v1, const Vector3<T> &v2)
+{
+ return inner_product(v1, v2);
+}
+
+template<typename T>
+inline Vector3<T> cross(const Vector3<T> &v1, const Vector3<T> &v2)
+{
+ return Vector3<T>(v1[1]*v2[2]-v1[2]*v2[1], v1[2]*v2[0]-v1[0]*v2[2], v1[0]*v2[1]-v1[1]*v2[0]);
+}
+
+} // namespace LinAl
+} // namespace LinAl
+
+#endif