]> git.tdb.fi Git - libs/gl.git/commitdiff
Use libmspmath to provide vector and matrix operations
authorMikko Rasa <tdb@tdb.fi>
Sat, 18 May 2013 21:27:42 +0000 (00:27 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sat, 18 May 2013 21:27:42 +0000 (00:27 +0300)
Pulling them from a math library enables interoperability for programs
where it is desirable for some parts to avoid an OpenGL dependency.  A
full complement of vector operations helps with readable code.

The flag tracking from Matrix was removed as a benchmark showed it to
actually hurt performance with compiler optimizations enabled.

15 files changed:
Build
source/animation.cpp
source/box.cpp
source/camera.cpp
source/camera.h
source/grid.cpp
source/matrix.cpp
source/matrix.h
source/pose.cpp
source/programdata.h
source/shadowmap.cpp
source/texturecube.cpp
source/uniformblock.h
source/vector.h
source/vertexbuilder.h

diff --git a/Build b/Build
index 7b64dde536c62abed41f022938407f56bf71fa84..cb03fd379b5e393296fb9b46cea9411ce5fa2acb 100644 (file)
--- a/Build
+++ b/Build
@@ -5,6 +5,7 @@ package "mspgl"
 
        require "mspcore";
        require "mspdatafile";
+       require "mspmath";
        require "mspgui";
        require "opengl";
 
index 255e63cc8102128299076d345cb99dd8904ca6ed..c0b508180b0da9f8676cd12e6f5c74a4a77cede1 100644 (file)
@@ -223,10 +223,11 @@ Matrix Animation::Iterator::get_pose_matrix(unsigned link) const
        }
 
        // We must redo the base point correction since interpolation throws if off
+       // XXX This should probably be done on local matrices
        Matrix result = iter->pose_matrices[link].get(time_since_keyframe/iter->delta_t);
        const Vector3 &base = animation.armature->get_link(link).get_base();
        Vector3 new_base = result*base;
-       result = Matrix::translation(base.x-new_base.x, base.y-new_base.y, base.z-new_base.z)*result;
+       result = Matrix::translation(base-new_base)*result;
        return result;
 }
 
index b20f0d04e98c237d6c96a1f99844f1898149d0e9..46f1b48ed7bfc315a23a221134544adcccf5c19e 100644 (file)
@@ -38,14 +38,14 @@ void BoxBuilder::build_face(PrimitiveBuilder &builder, const Vector3 &o, const V
        float l1 = 1, l2 = 1;
        if(generate_tbn || tex_fit!=STRETCH)
        {
-               l1 = sqrt(s1.x*s1.x+s1.y*s1.y+s1.z*s1.z);
-               l2 = sqrt(s2.x*s2.x+s2.y*s2.y+s2.z*s2.z);
+               l1 = s1.norm();
+               l2 = s2.norm();
        }
 
        if(generate_tbn)
        {
-               builder.tangent(s1.x/l1, s1.y/l1, s1.z/l1);
-               builder.binormal(s2.x/l2, s2.y/l2, s2.z/l2);
+               builder.tangent(s1/l1);
+               builder.binormal(s2/l2);
        }
 
        float u_size = 1;
@@ -54,13 +54,13 @@ void BoxBuilder::build_face(PrimitiveBuilder &builder, const Vector3 &o, const V
 
        builder.begin(TRIANGLE_STRIP);
        builder.texcoord(0, v_size);
-       builder.vertex(o.x+s2.x, o.y+s2.y, o.z+s2.z);
+       builder.vertex(o+s2);
        builder.texcoord(0, 0);
-       builder.vertex(o.x, o.y, o.z);
+       builder.vertex(o);
        builder.texcoord(u_size, v_size);
-       builder.vertex(o.x+s1.x+s2.x, o.y+s1.y+s2.y, o.z+s1.z+s2.z);
+       builder.vertex(o+s1+s2);
        builder.texcoord(u_size, 0);
-       builder.vertex(o.x+s1.x, o.y+s1.y, o.z+s1.z);
+       builder.vertex(o+s1);
        builder.end();
 }
 
index 98b7598ca16ffa011d1849881ac0d67117bff45f..406135796f3e10c1cc0135cb23a097ee51e32259 100644 (file)
@@ -39,29 +39,21 @@ void Camera::set_position(const Vector3 &p)
 
 void Camera::set_up_direction(const Vector3 &u)
 {
-       float len = sqrt(u.x*u.x+u.y*u.y+u.z*u.z);
-
-       up_dir.x = u.x/len;
-       up_dir.y = u.y/len;
-       up_dir.z = u.z/len;
+       up_dir = normalize(u);
 
        compute_matrix();
 }
 
 void Camera::set_look_direction(const Vector3 &l)
 {
-       float len = sqrt(l.x*l.x+l.y*l.y+l.z*l.z);
-
-       look_dir.x = l.x/len;
-       look_dir.y = l.y/len;
-       look_dir.z = l.z/len;
+       look_dir = normalize(l);
 
        compute_matrix();
 }
 
 void Camera::look_at(const Vector3 &p)
 {
-       set_look_direction(Vector3(p.x-position.x, p.y-position.y, p.z-position.z));
+       set_look_direction(p-position);
 }
 
 Vector3 Camera::project(const Vector4 &p) const
@@ -70,12 +62,15 @@ Vector3 Camera::project(const Vector4 &p) const
        float frustum_w = frustum_h*aspect;
        float z_range = clip_far-clip_near;
 
-       float eye_x = matrix[0]*p.x+matrix[4]*p.y+matrix[8]*p.z+matrix[12]*p.w;
-       float eye_y = matrix[1]*p.x+matrix[5]*p.y+matrix[9]*p.z+matrix[13]*p.w;
-       float eye_z = matrix[2]*p.x+matrix[6]*p.y+matrix[10]*p.z+matrix[14]*p.w;
+       Vector4 eye = matrix*p;
 
-       return Vector3(eye_x/frustum_w/-eye_z, eye_y/frustum_h/-eye_z,
-               (clip_far+clip_near)/z_range+2*clip_far*clip_near/(eye_z*z_range));
+       return Vector3(eye.x/frustum_w/-eye.z, eye.y/frustum_h/-eye.z,
+               (clip_far+clip_near)/z_range+2*clip_far*clip_near/(eye.z*z_range));
+}
+
+Vector3 Camera::project(const Vector3 &p) const
+{
+       return project(Vector4(p.x, p.y, p.z, 1.0));
 }
 
 Vector4 Camera::unproject(const Vector4 &p) const
@@ -102,19 +97,16 @@ void Camera::apply() const
 
 void Camera::compute_matrix()
 {
-       float x = look_dir.y*up_dir.z-look_dir.z*up_dir.y;
-       float y = look_dir.z*up_dir.x-look_dir.x*up_dir.z;
-       float z = look_dir.x*up_dir.y-look_dir.y*up_dir.x;
-       float len = sqrt(x*x+y*y+z*z);
+       Vector3 right_dir = normalize(cross(look_dir, up_dir));
        double mdata[16];
 
-       mdata[0] = x/len;
-       mdata[4] = y/len;
-       mdata[8] = z/len;
+       mdata[0] = right_dir.x;
+       mdata[4] = right_dir.y;
+       mdata[8] = right_dir.z;
 
-       mdata[1] = mdata[4]*look_dir.z-mdata[8]*look_dir.y;
-       mdata[5] = mdata[8]*look_dir.x-mdata[0]*look_dir.z;
-       mdata[9] = mdata[0]*look_dir.y-mdata[4]*look_dir.x;
+       mdata[1] = right_dir.y*look_dir.z-right_dir.z*look_dir.y;
+       mdata[5] = right_dir.z*look_dir.x-right_dir.x*look_dir.z;
+       mdata[9] = right_dir.x*look_dir.y-right_dir.y*look_dir.x;
 
        mdata[2] = -look_dir.x;
        mdata[6] = -look_dir.y;
index 6e83a9c3e761384f3342abb818cad714b1049004..d86725e6cb037bac933c1f2c4c2db3f84b31cdf9 100644 (file)
@@ -41,6 +41,7 @@ public:
        const Matrix &get_matrix() const { return matrix; }
 
        Vector3 project(const Vector4 &) const;
+       Vector3 project(const Vector3 &) const;
        Vector4 unproject(const Vector4 &) const;
 
        void apply() const;
index aaeada8a73130e2ae2dccd4fb53c3da608731def..78a3fecb79906b16e1a7a1c4a4978497730cbb52 100644 (file)
@@ -61,28 +61,15 @@ void GridBuilder::init(bool compute_normals)
 
        if(compute_normals)
        {
-               norm.x = side1.y*side2.z-side1.z*side2.y;
-               norm.y = side1.z*side2.x-side1.x*side2.z;
-               norm.z = side1.x*side2.y-side1.y*side2.x;
-               float l = sqrt(norm.x*norm.x+norm.y*norm.y+norm.z*norm.z);
-               norm.x /= l;
-               norm.y /= l;
-               norm.z /= l;
-
-               binorm.x = norm.y*side1.z-norm.z*side1.y;
-               binorm.y = norm.z*side1.x-norm.x*side1.z;
-               binorm.z = norm.x*side1.y-norm.y*side1.x;
-               l = sqrt(binorm.x*binorm.x+binorm.y*binorm.y+binorm.z*binorm.z);
-               binorm.x /= l;
-               binorm.y /= l;
-               binorm.z /= l;
+               norm = normalize(cross(side1, side2));
+               binorm = normalize(cross(norm, side1));
        }
 }
 
 void GridBuilder::build(PrimitiveBuilder &builder) const
 {
-       float l1_sq = side1.x*side1.x+side1.y*side1.y+side1.z*side1.z;
-       float l2 = side2.x*binorm.x+side2.y*binorm.y+side2.z*binorm.z;
+       float l1_sq = dot(side1, side1);
+       float l2 = dot(side2, binorm);
        float u_scale = 1/l1_sq;
        float v_scale = 1/l2;
        adjust_texture_scale(u_scale, v_scale, sqrt(l1_sq), l2);
@@ -90,20 +77,18 @@ void GridBuilder::build(PrimitiveBuilder &builder) const
        builder.normal(norm.x, norm.y, norm.z);
        if(generate_tbn)
        {
-               builder.tangent(side1.x, side1.y, side1.z);
-               builder.binormal(binorm.x, binorm.y, binorm.z);
+               builder.tangent(side1);
+               builder.binormal(binorm);
        }
 
        for(unsigned j=0; j<=v_div; ++j)
        {
-               float v = j*1.0/v_div;
-               Vector3 row(origin.x+side2.x*v, origin.y+side2.y*v, origin.z+side2.z*v);
-               v = (row.x*binorm.x+row.y*binorm.y+row.z*binorm.z)*v_scale;
+               Vector3 row = origin+side2*(j*1.0f/v_div);
+               float v = dot(row, binorm)*v_scale;
                for(unsigned i=0; i<=u_div; ++i)
                {
-                       float u = i*1.0/u_div;
-                       Vector3 p(row.x+side1.x*u, row.y+side1.y*u, row.z+side1.z*u);
-                       u = (p.x*side1.x+p.y*side1.y+p.z*side1.z)*u_scale;
+                       Vector3 p = row+side1*(i*1.0f/u_div);
+                       float u = dot(p, side1)*u_scale;
                        builder.texcoord(u, v);
                        builder.vertex(p);
                }
index 6ff3b603002f3a43a59cee50f3a4d75508efdae2..8cc9dcba3a513e49b5b7d9367bd3dae733e371ee 100644 (file)
@@ -1,5 +1,6 @@
 #include <algorithm>
 #include <cmath>
+#include <msp/geometry/affinetransformation.h>
 #include "error.h"
 #include "matrix.h"
 
@@ -9,116 +10,44 @@ namespace Msp {
 namespace GL {
 
 Matrix::Matrix():
-       flags(IDENTITY)
-{
-       for(unsigned i=0; i<16; ++i)
-               matrix[i] = (i%5 ? 0 : 1);
-}
+       Base(Base::identity())
+{ }
 
 Matrix::Matrix(const float *m):
-       flags(IDENTITY)
-{
-       copy(m, m+16, matrix);
-       check_flags();
-}
+       Base(LinAl::SquareMatrix<float, 4>(m))
+{ }
 
 Matrix::Matrix(const double *m):
-       flags(IDENTITY)
-{
-       copy(m, m+16, matrix);
-       check_flags();
-}
+       Base(m)
+{ }
 
-void Matrix::check_flags()
-{
-       const double *m = matrix;
-       if(m[12]!=0 || m[13]!=0 || m[14]!=0)
-               flags |= TRANSLATE;
-       if(m[0]!=1)
-       {
-               flags |= SCALE;
-               if(m[5]!=m[0] || m[10]!=m[0])
-                       flags |= ARBITARY;
-       }
-       if(m[1]!=0 || m[2]!=0 || m[4]!=0 || m[6]!=0 || m[8]!=0 || m[9]!=0)
-       {
-               flags |= ROTATE;
-               double x_dot_y = m[0]*m[1]+m[4]*m[5]+m[8]*m[9];
-               double x_dot_z = m[0]*m[2]+m[4]*m[6]+m[8]*m[10];
-               double y_dot_z = m[1]*m[2]+m[5]*m[6]+m[9]*m[10];
-               if(x_dot_y!=0 || x_dot_z!=0 || y_dot_z!=0)
-                       flags |= ARBITARY;
-       }
-       if(m[3]!=0 || m[7]!=0 || m[11]!=0 || m[15]!=1)
-               flags |= ARBITARY;
-}
+Matrix::Matrix(const LinAl::Matrix<double, 4, 4> &other):
+       Base(other)
+{ }
 
 void Matrix::multiply(const Matrix &other)
 {
        *this = *this*other;
 }
 
-void Matrix::translate(double x, double y, double z)
-{
-       multiply(translation(x, y, z));
-}
-
-void Matrix::rotate(double a, double x, double y, double z)
+void Matrix::translate(const Vector3 &t)
 {
-       multiply(rotation(a, x, y, z));
+       multiply(translation(t));
 }
 
-void Matrix::rotate_deg(double a, double x, double y, double z)
+void Matrix::rotate(const Angle &a, const Vector3 &x)
 {
-       multiply(rotation_deg(a, x, y, z));
+       multiply(rotation(a, x));
 }
 
-void Matrix::scale(double s)
+void Matrix::scale(const Vector3 &s)
 {
        multiply(scaling(s));
 }
 
-void Matrix::scale(double x, double y, double z)
-{
-       multiply(scaling(x, y, z));
-}
-
 Matrix Matrix::operator*(const Matrix &other) const
 {
-       if(flags==IDENTITY)
-               return other;
-       else if(other.flags==IDENTITY)
-               return *this;
-       else if(flags==TRANSLATE && !(other.flags&ARBITARY))
-       {
-               Matrix result = other;
-               result.matrix[12] += matrix[12];
-               result.matrix[13] += matrix[13];
-               result.matrix[14] += matrix[14];
-               result.flags |= flags;
-               return result;
-       }
-       else if(!(flags&ARBITARY) && other.flags==TRANSLATE)
-       {
-               Matrix result = *this;
-               const double *m = other.matrix;
-               result.matrix[12] += matrix[0]*m[12]+matrix[4]*m[13]+matrix[8]*m[14];
-               result.matrix[13] += matrix[1]*m[12]+matrix[5]*m[13]+matrix[9]*m[14];
-               result.matrix[14] += matrix[2]*m[12]+matrix[6]*m[13]+matrix[10]*m[14];
-               result.flags |= other.flags;
-               return result;
-       }
-       else
-       {
-               Matrix result;
-               fill(result.matrix, result.matrix+16, 0.0);
-               for(unsigned i=0; i<4; ++i)
-                       for(unsigned j=0; j<4; ++j)
-                               for(unsigned k=0; k<4; ++k)
-                                       result.matrix[i+j*4] += matrix[i+k*4]*other.matrix[k+j*4];
-               result.flags = flags|other.flags;
-               return result;
-       }
+       return static_cast<const Base &>(*this)*static_cast<const Base &>(other);
 }
 
 Matrix &Matrix::operator*=(const Matrix &other)
@@ -129,87 +58,34 @@ Matrix &Matrix::operator*=(const Matrix &other)
 
 Vector4 Matrix::operator*(const Vector4 &vec) const
 {
-       if(flags==IDENTITY)
-               return vec;
-       else if(flags==TRANSLATE)
-               return Vector4(vec.x+vec.w*matrix[12], vec.y+vec.w*matrix[13], vec.z+vec.w*matrix[14], vec.w);
-       else if(flags==SCALE)
-               return Vector4(vec.x*matrix[0], vec.y*matrix[5], vec.z*matrix[10], vec.w);
-       else
-       {
-               Vector4 result;
-               result.x = vec.x*matrix[0]+vec.y*matrix[4]+vec.z*matrix[8]+vec.w*matrix[12];
-               result.y = vec.x*matrix[1]+vec.y*matrix[5]+vec.z*matrix[9]+vec.w*matrix[13];
-               result.z = vec.x*matrix[2]+vec.y*matrix[6]+vec.z*matrix[10]+vec.w*matrix[14];
-               result.w = vec.x*matrix[3]+vec.y*matrix[7]+vec.z*matrix[11]+vec.w*matrix[15];
-               return result;
-       }
+       return static_cast<const Base &>(*this)*LinAl::Vector<double, 4>(vec);
 }
 
-double Matrix::operator[](unsigned i) const
+Vector3 Matrix::operator*(const Vector3 &vec) const
 {
-       if(i>=16)
-               throw out_of_range("Matrix::operator[]");
-       return matrix[i];
+       return Geometry::reduce_vector((*this)*Geometry::augment_vector(vec, 1.0f));
 }
 
-Matrix Matrix::translation(double x, double y, double z)
-{
-       Matrix result;
-       result.matrix[12] = x;
-       result.matrix[13] = y;
-       result.matrix[14] = z;
-       result.flags |= TRANSLATE;
-       return result;
-}
-
-Matrix Matrix::rotation(double a, double x, double y, double z)
+double Matrix::operator[](unsigned i) const
 {
-       double l = sqrt(x*x+y*y+z*z);
-       x /= l;
-       y /= l;
-       z /= l;
-       double c = cos(a);
-       double s = sin(a);
-
-       // http://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_given_an_axis_and_an_angle
-       Matrix result;
-       result.matrix[0] = c+x*x*(1-c);
-       result.matrix[1] = y*x*(1-c)+z*s;
-       result.matrix[2] = z*x*(1-c)-y*s;
-       result.matrix[4] = x*y*(1-c)-z*s;
-       result.matrix[5] = c+y*y*(1-c);
-       result.matrix[6] = z*y*(1-c)+x*s;
-       result.matrix[8] = x*z*(1-c)+y*s;
-       result.matrix[9] = y*z*(1-c)-x*s;
-       result.matrix[10] = c+z*z*(1-c);
-       result.flags |= ROTATE;
-       return result;
+       if(i>=16)
+               throw out_of_range("Matrix::operator[]");
+       return operator()(i%4, i/4);
 }
 
-Matrix Matrix::rotation_deg(double a, double x, double y, double z)
+Matrix Matrix::translation(const Vector3 &t)
 {
-       return rotation(a*M_PI/180, x, y, z);
+       return Geometry::AffineTransformation<double, 3>::translation(t).get_matrix();
 }
 
-Matrix Matrix::scaling(double s)
+Matrix Matrix::rotation(const Angle &a, const Vector3 &x)
 {
-       Matrix result;
-       result.matrix[0] = s;
-       result.matrix[5] = s;
-       result.matrix[10] = s;
-       result.flags |= SCALE;
-       return result;
+       return Geometry::AffineTransformation<double, 3>::rotation(a, x).get_matrix();
 }
 
-Matrix Matrix::scaling(double x, double y, double z)
+Matrix Matrix::scaling(const Vector3 &s)
 {
-       Matrix result;
-       result.matrix[0] = x;
-       result.matrix[5] = y;
-       result.matrix[10] = z;
-       result.flags |= SCALE|ARBITARY;
-       return result;
+       return Geometry::AffineTransformation<double, 3>::scaling(s).get_matrix();
 }
 
 Matrix Matrix::ortho(double l, double r, double b, double t, double n, double f)
@@ -218,13 +94,12 @@ Matrix Matrix::ortho(double l, double r, double b, double t, double n, double f)
                throw invalid_argument("Matrix::ortho");
 
        Matrix result;
-       result.matrix[0] = 2/(r-l);
-       result.matrix[5] = 2/(t-b);
-       result.matrix[10] = -2/(f-n);
-       result.matrix[12] = -(r+l)/(r-l);
-       result.matrix[13] = -(t+b)/(t-b);
-       result.matrix[14] = -(f+n)/(f-n);
-       result.flags = TRANSLATE|SCALE|ARBITARY;
+       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;
 }
 
@@ -249,15 +124,14 @@ Matrix Matrix::frustum(double l, double r, double b, double t, double n, double
                throw invalid_argument("Matrix::frustum");
 
        Matrix result;
-       result.matrix[0] = 2*n/(r-l);
-       result.matrix[5] = 2*n/(t-b);
-       result.matrix[8] = (r+l)/(r-l);
-       result.matrix[9] = (t+b)/(t-b);
-       result.matrix[10] = -(f+n)/(f-n);
-       result.matrix[11] = -1;
-       result.matrix[14] = -2*f*n/(f-n);
-       result.matrix[15] = 0;
-       result.flags = ARBITARY;
+       result(0, 0) = 2*n/(r-l);
+       result(1, 1) = 2*n/(t-b);
+       result(0, 2) = (r+l)/(r-l);
+       result(1, 2) = (t+b)/(t-b);
+       result(2, 2) = -(f+n)/(f-n);
+       result(3, 2) = -1;
+       result(2, 3) = -2*f*n/(f-n);
+       result(3 ,3) = 0;
        return result;
 }
 
index 6aae6df0a0e5f2a494e570932f044cb64c89d8de..5c20d60c7d333b2a4c468bf9c7fcd250dc1ee312 100644 (file)
@@ -2,60 +2,56 @@
 #define MSP_GL_MATRIX_H_
 
 #include <vector>
+#include <msp/geometry/angle.h>
+#include <msp/linal/squarematrix.h>
 #include "gl.h"
 #include "vector.h"
 
 namespace Msp {
 namespace GL {
 
-class Matrix
+class Matrix: public LinAl::SquareMatrix<double, 4>
 {
 private:
-       enum Flags
-       {
-               IDENTITY  = 0,
-               TRANSLATE = 1,
-               ROTATE    = 2,
-               SCALE     = 4,
-               ARBITARY  = 8
-       };
-
-       double matrix[16];
-       unsigned flags;
+       typedef LinAl::SquareMatrix<double, 4> Base;
+       typedef Geometry::Angle<double> Angle;
 
 public:
        Matrix();
        Matrix(const float *);
        Matrix(const double *);
-private:
-       void check_flags();
+       Matrix(const LinAl::Matrix<double, 4, 4> &);
 
-public:
-       const double *data() const { return matrix; }
+       const double *data() const { return &Base::operator()(0, 0); }
 
        void multiply(const Matrix &);
-       void translate(double, double, double);
-       void translate(const Vector3 &t) { translate(t.x, t.y, t.z); }
-       void rotate(double, double, double, double);
-       void rotate(double a, const Vector3 &x) { rotate(a, x.x, x.y, x.z); }
-       void rotate_deg(double, double, double, double);
-       void rotate_deg(double a, const Vector3 & x) { rotate_deg(a, x.x, x.y, x.z); }
-       void scale(double);
-       void scale(double, double, double);
+       void translate(double x, double y, double z) { translate(Vector3(x, y, z)); }
+       void translate(const Vector3 &);
+       void rotate(const Angle &, const Vector3 &);
+       void rotate(double a, double x, double y, double z) { rotate(Angle::from_radians(a), Vector3(x, y, z)); }
+       void rotate(double a, const Vector3 &x) { rotate(Angle::from_radians(a), x); }
+       void rotate_deg(double a, double x, double y, double z) { rotate(Angle::from_degrees(a), Vector3(x, y, z)); }
+       void rotate_deg(double a, const Vector3 & x) { rotate(Angle::from_degrees(a), x); }
+       void scale(double s) { scale(Vector3(s, s, s)); }
+       void scale(double x, double y, double z) { scale(Vector3(x, y, z)); }
+       void scale(const Vector3 &);
 
        Matrix operator*(const Matrix &) const;
        Matrix &operator*=(const Matrix &);
        Vector4 operator*(const Vector4 &) const;
+       Vector3 operator*(const Vector3 &) const;
        double operator[](unsigned) const;
 
-       static Matrix translation(double, double, double);
-       static Matrix translation(const Vector3 &t) { return translation(t.x, t.y, t.z); }
-       static Matrix rotation(double, double, double, double);
-       static Matrix rotation(double a, const Vector3 &x) { return rotation(a, x.x, x.y, x.z); }
-       static Matrix rotation_deg(double, double, double, double);
-       static Matrix rotation_deg(double a, const Vector3 &x) { return rotation_deg(a, x.x, x.y, x.z); }
-       static Matrix scaling(double);
-       static Matrix scaling(double, double, double);
+       static Matrix translation(double x, double y, double z) { return translation(Vector3(x, y, z)); }
+       static Matrix translation(const Vector3 &);
+       static Matrix rotation(const Angle &a, const Vector3 &);
+       static Matrix rotation(double a, double x, double y, double z) { return rotation(Angle::from_radians(a), Vector3(x, y, z)); }
+       static Matrix rotation(double a, const Vector3 &x) { return rotation(Angle::from_radians(a), x); }
+       static Matrix rotation_deg(double a, double x, double y, double z) { return rotation(Angle::from_degrees(a), Vector3(x, y, z)); }
+       static Matrix rotation_deg(double a, const Vector3 &x) { return rotation(Angle::from_degrees(a), x); }
+       static Matrix scaling(double s) { return scaling(Vector3(s, s, s)); }
+       static Matrix scaling(double x, double y, double z) { return scaling(Vector3(x, y, z)); }
+       static Matrix scaling(const Vector3 &);
 
        static Matrix ortho(double, double, double, double, double, double);
        static Matrix ortho_centered(double, double);
index 63346b08fb6944f33ded13f5c9c8f5c5731128f8..7433626fb2e6c8db303809e6bff127385a7c6b5e 100644 (file)
@@ -37,7 +37,7 @@ void Pose::rotate_link(unsigned i, float angle, const Vector3 &axis)
        // Keep the base point stationary
        Vector3 base = arm_link.get_base();
        Vector3 new_base = links[i].local_matrix*base;
-       links[i].local_matrix = GL::Matrix::translation(base.x-new_base.x, base.y-new_base.y, base.z-new_base.z)*links[i].local_matrix;
+       links[i].local_matrix = GL::Matrix::translation(base-new_base)*links[i].local_matrix;
 
        if(const Armature::Link *parent = arm_link.get_parent())
                links[i].matrix = links[parent->get_index()].matrix*links[i].local_matrix;
index 5d6dceb784e997a9b463d1322ebd0b2f96769a8e..e27265d76d5678808f242c3cb89a0553dd1bab6e 100644 (file)
@@ -4,6 +4,7 @@
 #include <map>
 #include <msp/datafile/objectloader.h>
 #include "program.h"
+#include "vector.h"
 
 namespace Msp {
 namespace GL {
@@ -13,8 +14,6 @@ class Color;
 class Matrix;
 class Uniform;
 class UniformBlock;
-class Vector3;
-class Vector4;
 
 /**
 Stores uniform variables for shader programs.  The uniforms are stored in a
index c4dd07b03dbdb288fa55bda158dc305386813d70..d380257d83fc6910b4bab5a181b765ebfd41ebc4 100644 (file)
@@ -80,15 +80,10 @@ void ShadowMap::setup_frame() const
        {
                /* XXX Not really proper way to support positional lights, but good
                enough when the light source is far away */
-               lpos.x -= target.x;
-               lpos.y -= target.y;
-               lpos.z -= target.z;
+               lpos -= Vector4(target.x, target.y, target.z, 1.0f);
        }
 
-       float l = sqrt(lpos.x*lpos.x+lpos.y*lpos.y+lpos.z*lpos.z);
-       lpos.x /= l;
-       lpos.y /= l;
-       lpos.z /= l;
+       lpos.normalize();
 
        float matrix[16];
        if(abs(lpos.z)>=abs(lpos.x) && abs(lpos.z)>=abs(lpos.y))
index 6935e582f5932cd7c000d844c56c976f2c47b0e9..ef9d25297a4285c5ec630cd65e3237c6cddbf471 100644 (file)
@@ -136,7 +136,7 @@ Vector3 TextureCube::get_texel_direction(TextureCubeFace face, unsigned u, unsig
        const Vector3 &fv = get_face_direction(face);
        const Vector3 &sv = get_s_direction(face);
        const Vector3 &tv = get_t_direction(face);
-       return Vector3(fv.x+s*sv.x, fv.y+t*tv.y, fv.z+s*sv.z+t*tv.z);
+       return fv+s*sv+t*tv;
 }
 
 } // namespace GL
index 1a277106040f3757dd6d3c143f61f55137a08266..d694e3674a48e07f56e4abfdd512d149f8c2e547 100644 (file)
@@ -5,6 +5,7 @@
 #include <vector>
 #include "bufferable.h"
 #include "program.h"
+#include "vector.h"
 
 namespace Msp {
 namespace GL {
@@ -13,8 +14,6 @@ class BufferRange;
 class Color;
 class Matrix;
 class Uniform;
-class Vector3;
-class Vector4;
 
 /**
 Stores uniforms with a specific layout.  Both named and default uniform blocks
index 3c2b89880d88b546eedfbab7931dcb0bfdf0284a..5a4ffb666c4cc5b3c778fa4358cd41317ce5e6c5 100644 (file)
@@ -1,33 +1,13 @@
 #ifndef MSP_GL_VECTOR_H_
 #define MSP_GL_VECTOR_H_
 
+#include <msp/linal/vector.h>
+
 namespace Msp {
 namespace GL {
 
-struct Vector4;
-
-struct Vector3
-{
-       float x, y, z;
-
-       Vector3(): x(0), y(0), z(0) { }
-       Vector3(float x_, float y_, float z_): x(x_), y(y_), z(z_) { }
-       Vector3(const Vector4 &);
-};
-
-struct Vector4
-{
-       float x, y, z, w;
-
-       Vector4(): x(0), y(0), z(0), w(1) { }
-       Vector4(float x_, float y_, float z_): x(x_), y(y_), z(z_), w(1) { }
-       Vector4(float x_, float y_, float z_, float w_): x(x_), y(y_), z(z_), w(w_) { }
-       Vector4(const Vector3 &v): x(v.x), y(v.y), z(v.z), w(1) { }
-};
-
-inline Vector3::Vector3(const Vector4 &v):
-       x(v.x/v.w), y(v.y/v.w), z(v.z/v.w)
-{ }
+typedef LinAl::Vector<float, 3> Vector3;
+typedef LinAl::Vector<float, 4> Vector4;
 
 } // namespace GL
 } // namespace Msp
index 7a1c943c9ed18b7f6f2330cdc67b0ebb76bc4197..998f7a6cea4d001c20d41f3529c72aac4ccc8763 100644 (file)
@@ -45,6 +45,9 @@ public:
        void vertex(float x, float y, float z, float w)
        { vertex(Vector4(x, y, z, w)); }
 
+       void vertex(const Vector3 &v)
+       { vertex(Vector4(v.x, v.y, v.z, 1)); }
+
        void vertex(const Vector4 &v)
        { vertex_(mtx.top()*v); }