1 #ifndef GFXMAT4_INCLUDED // -*- C++ -*-
2 #define GFXMAT4_INCLUDED
3 #if !defined(__GNUC__)
4 #  pragma once
5 #endif
6 
7 /************************************************************************
8 
9   4x4 Matrix class
10 
11   $Id: mat4.h 427 2004-09-27 04:45:31Z garland $
12 
13  ************************************************************************/
14 
15 #include "vec4.h"
16 
17 namespace gfx
18 {
19 
20 class Mat4
21 {
22 private:
23     Vec4 row[4];
24 
25 public:
26     // Standard constructors
27     //
Mat4()28     Mat4() { *this = 0.0; }
Mat4(const Vec4 & r0,const Vec4 & r1,const Vec4 & r2,const Vec4 & r3)29     Mat4(const Vec4& r0,const Vec4& r1,const Vec4& r2,const Vec4& r3)
30     	{ row[0]=r0; row[1]=r1; row[2]=r2; row[3]=r3; }
Mat4(const Mat4 & m)31     Mat4(const Mat4& m) { *this = m; }
32 
33     // Descriptive interface
34     //
35     typedef double value_type;
36     typedef Vec4 vector_type;
37     typedef Mat4 inverse_type;
dim()38     static int dim() { return 4; }
39 
40     // Access methods
41     //
operator()42     double& operator()(int i, int j)       { return row[i][j]; }
operator()43     double  operator()(int i, int j) const { return row[i][j]; }
44     Vec4&       operator[](int i)       { return row[i]; }
45     const Vec4& operator[](int i) const { return row[i]; }
col(int i)46     inline Vec4 col(int i) const
47         { return Vec4(row[0][i],row[1][i],row[2][i],row[3][i]); }
48 
49     operator       double*()       { return row[0]; }
50     operator const double*()       { return row[0]; }
51     operator const double*() const { return row[0]; }
52 
53     // Assignment methods
54     //
55     inline Mat4& operator=(const Mat4& m);
56     inline Mat4& operator=(double s);
57 
58     inline Mat4& operator+=(const Mat4& m);
59     inline Mat4& operator-=(const Mat4& m);
60     inline Mat4& operator*=(double s);
61     inline Mat4& operator/=(double s);
62 
63     static Mat4 I();
64 };
65 
66 ////////////////////////////////////////////////////////////////////////
67 //
68 // Method definitions
69 //
70 
71 inline Mat4& Mat4::operator=(const Mat4& m)
72 {
73     row[0] = m[0]; row[1] = m[1]; row[2] = m[2]; row[3] = m[3];
74     return *this;
75 }
76 
77 inline Mat4& Mat4::operator=(double s)
78 {
79     row[0]=s;  row[1]=s;  row[2]=s;  row[3]=s;
80     return *this;
81 }
82 
83 inline Mat4& Mat4::operator+=(const Mat4& m)
84 {
85     row[0] += m[0]; row[1] += m[1]; row[2] += m[2]; row[3] += m[3];
86     return *this;
87 }
88 
89 inline Mat4& Mat4::operator-=(const Mat4& m)
90 {
91     row[0] -= m[0]; row[1] -= m[1]; row[2] -= m[2]; row[3] -= m[3];
92     return *this;
93 }
94 
95 inline Mat4& Mat4::operator*=(double s)
96 {
97     row[0] *= s; row[1] *= s; row[2] *= s; row[3] *= s;
98     return *this;
99 }
100 
101 inline Mat4& Mat4::operator/=(double s)
102 {
103     row[0] /= s; row[1] /= s; row[2] /= s; row[3] /= s;
104     return *this;
105 }
106 
107 ////////////////////////////////////////////////////////////////////////
108 //
109 // Operator definitions
110 //
111 
112 inline Mat4 operator+(const Mat4& n, const Mat4& m)
113 	{ return Mat4(n[0]+m[0], n[1]+m[1], n[2]+m[2], n[3]+m[3]); }
114 
115 inline Mat4 operator-(const Mat4& n, const Mat4& m)
116 	{ return Mat4(n[0]-m[0], n[1]-m[1], n[2]-m[2], n[3]-m[3]); }
117 
118 inline Mat4 operator-(const Mat4& n)
119 	{ return Mat4(-n[0], -n[1], -n[2], -n[3]); }
120 
121 inline Mat4 operator*(double s, const Mat4& m)
122 	{ return Mat4(m[0]*s, m[1]*s, m[2]*s, m[3]*s); }
123 inline Mat4 operator*(const Mat4& m, double s)
124 	{ return s*m; }
125 
126 inline Mat4 operator/(const Mat4& m, double s)
127 	{ return Mat4(m[0]/s, m[1]/s, m[2]/s, m[3]/s); }
128 
129 inline Vec4 operator*(const Mat4& m, const Vec4& v)
130 	{ return Vec4(m[0]*v, m[1]*v, m[2]*v, m[3]*v); }
131 
132 extern Mat4 operator*(const Mat4& n, const Mat4& m);
133 
134 //
135 // Transform a homogeneous 3-vector and reproject into normal 3-space
136 //
137 inline Vec3 operator*(const Mat4& m, const Vec3& v)
138 {
139     Vec4 u=Vec4(v,1);
140     double w=m[3]*u;
141 
142     if(w==0.0)  return Vec3(m[0]*u, m[1]*u, m[2]*u);
143     else        return Vec3(m[0]*u/w, m[1]*u/w, m[2]*u/w);
144 }
145 
146 inline std::ostream &operator<<(std::ostream &out, const Mat4& M)
147        { return out<<M[0]<<std::endl<<M[1]<<std::endl<<M[2]<<std::endl<<M[3]; }
148 
149 inline std::istream &operator>>(std::istream &in, Mat4& M)
150        { return in >> M[0] >> M[1] >> M[2] >> M[3]; }
151 
152 ////////////////////////////////////////////////////////////////////////
153 //
154 // Transformations
155 //
156 
157 extern Mat4 translation_matrix(const Vec3& delta);
158 
159 extern Mat4 scaling_matrix(const Vec3& scale);
160 
161 extern Mat4 rotation_matrix_rad(double theta, const Vec3& axis);
162 
rotation_matrix_deg(double theta,const Vec3 & axis)163 inline Mat4 rotation_matrix_deg(double theta, const Vec3& axis)
164 	{ return rotation_matrix_rad(theta*M_PI/180.0, axis); }
165 
166 extern Mat4 perspective_matrix(double fovy, double aspect,
167 			       double zmin=0.0, double zmax=0.0);
168 
169 extern Mat4 lookat_matrix(const Vec3& from, const Vec3& at, const Vec3& up);
170 
171 extern Mat4 viewport_matrix(double w, double h);
172 
173 ////////////////////////////////////////////////////////////////////////
174 //
175 // Misc. function definitions
176 //
177 
det(const Mat4 & m)178 inline double det(const Mat4& m) { return m[0] * cross(m[1], m[2], m[3]); }
179 
trace(const Mat4 & m)180 inline double trace(const Mat4& m) { return m(0,0)+m(1,1)+m(2,2)+m(3,3); }
181 
transpose(const Mat4 & m)182 inline Mat4 transpose(const Mat4& m)
183 	{ return Mat4(m.col(0), m.col(1), m.col(2), m.col(3)); }
184 
185 extern Mat4 adjoint(const Mat4& m);
186 extern double invert(Mat4& m_inv, const Mat4& m);
187 extern double invert_cramer(Mat4& m_inv, const Mat4& m);
188 
189 extern bool eigen(const Mat4& m, Vec4& eig_vals, Vec4 eig_vecs[4]);
190 
191 } // namespace gfx
192 
193 // GFXMAT4_INCLUDED
194 #endif
195