1 /******************************************************************************
2 * Arachnoid Graphics Plugin for Mupen64Plus
3 * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
5 * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *****************************************************************************/
28 //*****************************************************************************
30 //! Math class defining a 4x4 matrix or an array of 16 float.
31 //! @details Used for viewprojection matrix and vertex transformation.
32 //*****************************************************************************
37 //! The matrix entries, indexed by [row][col].
45 //! Default constructor.
46 inline Matrix4() { operator=(IDENTITY); }
48 float m00, float m01, float m02, float m03,
49 float m10, float m11, float m12, float m13,
50 float m20, float m21, float m22, float m23,
51 float m30, float m31, float m32, float m33 )
71 //! Matrix multiplication
72 inline Matrix4 operator * ( const Matrix4 &m2 ) const
75 r.m[0][0] = m[0][0] * m2.m[0][0] + m[0][1] * m2.m[1][0] + m[0][2] * m2.m[2][0] + m[0][3] * m2.m[3][0];
76 r.m[0][1] = m[0][0] * m2.m[0][1] + m[0][1] * m2.m[1][1] + m[0][2] * m2.m[2][1] + m[0][3] * m2.m[3][1];
77 r.m[0][2] = m[0][0] * m2.m[0][2] + m[0][1] * m2.m[1][2] + m[0][2] * m2.m[2][2] + m[0][3] * m2.m[3][2];
78 r.m[0][3] = m[0][0] * m2.m[0][3] + m[0][1] * m2.m[1][3] + m[0][2] * m2.m[2][3] + m[0][3] * m2.m[3][3];
80 r.m[1][0] = m[1][0] * m2.m[0][0] + m[1][1] * m2.m[1][0] + m[1][2] * m2.m[2][0] + m[1][3] * m2.m[3][0];
81 r.m[1][1] = m[1][0] * m2.m[0][1] + m[1][1] * m2.m[1][1] + m[1][2] * m2.m[2][1] + m[1][3] * m2.m[3][1];
82 r.m[1][2] = m[1][0] * m2.m[0][2] + m[1][1] * m2.m[1][2] + m[1][2] * m2.m[2][2] + m[1][3] * m2.m[3][2];
83 r.m[1][3] = m[1][0] * m2.m[0][3] + m[1][1] * m2.m[1][3] + m[1][2] * m2.m[2][3] + m[1][3] * m2.m[3][3];
85 r.m[2][0] = m[2][0] * m2.m[0][0] + m[2][1] * m2.m[1][0] + m[2][2] * m2.m[2][0] + m[2][3] * m2.m[3][0];
86 r.m[2][1] = m[2][0] * m2.m[0][1] + m[2][1] * m2.m[1][1] + m[2][2] * m2.m[2][1] + m[2][3] * m2.m[3][1];
87 r.m[2][2] = m[2][0] * m2.m[0][2] + m[2][1] * m2.m[1][2] + m[2][2] * m2.m[2][2] + m[2][3] * m2.m[3][2];
88 r.m[2][3] = m[2][0] * m2.m[0][3] + m[2][1] * m2.m[1][3] + m[2][2] * m2.m[2][3] + m[2][3] * m2.m[3][3];
90 r.m[3][0] = m[3][0] * m2.m[0][0] + m[3][1] * m2.m[1][0] + m[3][2] * m2.m[2][0] + m[3][3] * m2.m[3][0];
91 r.m[3][1] = m[3][0] * m2.m[0][1] + m[3][1] * m2.m[1][1] + m[3][2] * m2.m[2][1] + m[3][3] * m2.m[3][1];
92 r.m[3][2] = m[3][0] * m2.m[0][2] + m[3][1] * m2.m[1][2] + m[3][2] * m2.m[2][2] + m[3][3] * m2.m[3][2];
93 r.m[3][3] = m[3][0] * m2.m[0][3] + m[3][1] * m2.m[1][3] + m[3][2] * m2.m[2][3] + m[3][3] * m2.m[3][3];
99 inline float* operator [] ( size_t iRow ) { return m[iRow]; }
101 inline const float* const operator [] ( size_t iRow ) const { return m[iRow]; }
104 inline Matrix4 operator + ( const Matrix4 &m2 ) const
108 r.m[0][0] = m[0][0] + m2.m[0][0];
109 r.m[0][1] = m[0][1] + m2.m[0][1];
110 r.m[0][2] = m[0][2] + m2.m[0][2];
111 r.m[0][3] = m[0][3] + m2.m[0][3];
113 r.m[1][0] = m[1][0] + m2.m[1][0];
114 r.m[1][1] = m[1][1] + m2.m[1][1];
115 r.m[1][2] = m[1][2] + m2.m[1][2];
116 r.m[1][3] = m[1][3] + m2.m[1][3];
118 r.m[2][0] = m[2][0] + m2.m[2][0];
119 r.m[2][1] = m[2][1] + m2.m[2][1];
120 r.m[2][2] = m[2][2] + m2.m[2][2];
121 r.m[2][3] = m[2][3] + m2.m[2][3];
123 r.m[3][0] = m[3][0] + m2.m[3][0];
124 r.m[3][1] = m[3][1] + m2.m[3][1];
125 r.m[3][2] = m[3][2] + m2.m[3][2];
126 r.m[3][3] = m[3][3] + m2.m[3][3];
131 //! Matrix subtraction.
132 inline Matrix4 operator - ( const Matrix4 &m2 ) const
135 r.m[0][0] = m[0][0] - m2.m[0][0];
136 r.m[0][1] = m[0][1] - m2.m[0][1];
137 r.m[0][2] = m[0][2] - m2.m[0][2];
138 r.m[0][3] = m[0][3] - m2.m[0][3];
140 r.m[1][0] = m[1][0] - m2.m[1][0];
141 r.m[1][1] = m[1][1] - m2.m[1][1];
142 r.m[1][2] = m[1][2] - m2.m[1][2];
143 r.m[1][3] = m[1][3] - m2.m[1][3];
145 r.m[2][0] = m[2][0] - m2.m[2][0];
146 r.m[2][1] = m[2][1] - m2.m[2][1];
147 r.m[2][2] = m[2][2] - m2.m[2][2];
148 r.m[2][3] = m[2][3] - m2.m[2][3];
150 r.m[3][0] = m[3][0] - m2.m[3][0];
151 r.m[3][1] = m[3][1] - m2.m[3][1];
152 r.m[3][2] = m[3][2] - m2.m[3][2];
153 r.m[3][3] = m[3][3] - m2.m[3][3];
158 //! Tests 2 matrices for equality.
159 inline bool operator == ( const Matrix4& m2 ) const
162 m[0][0] != m2.m[0][0] || m[0][1] != m2.m[0][1] || m[0][2] != m2.m[0][2] || m[0][3] != m2.m[0][3] ||
163 m[1][0] != m2.m[1][0] || m[1][1] != m2.m[1][1] || m[1][2] != m2.m[1][2] || m[1][3] != m2.m[1][3] ||
164 m[2][0] != m2.m[2][0] || m[2][1] != m2.m[2][1] || m[2][2] != m2.m[2][2] || m[2][3] != m2.m[2][3] ||
165 m[3][0] != m2.m[3][0] || m[3][1] != m2.m[3][1] || m[3][2] != m2.m[3][2] || m[3][3] != m2.m[3][3] )
170 //! Tests 2 matrices for inequality.
171 inline bool operator != ( const Matrix4& m2 ) const
174 m[0][0] != m2.m[0][0] || m[0][1] != m2.m[0][1] || m[0][2] != m2.m[0][2] || m[0][3] != m2.m[0][3] ||
175 m[1][0] != m2.m[1][0] || m[1][1] != m2.m[1][1] || m[1][2] != m2.m[1][2] || m[1][3] != m2.m[1][3] ||
176 m[2][0] != m2.m[2][0] || m[2][1] != m2.m[2][1] || m[2][2] != m2.m[2][2] || m[2][3] != m2.m[2][3] ||
177 m[3][0] != m2.m[3][0] || m[3][1] != m2.m[3][1] || m[3][2] != m2.m[3][2] || m[3][3] != m2.m[3][3] )
182 //!Transpose Matrix (Switch columns with rows)
183 inline Matrix4 transpose() const
185 return Matrix4(m[0][0], m[1][0], m[2][0], m[3][0],
186 m[0][1], m[1][1], m[2][1], m[3][1],
187 m[0][2], m[1][2], m[2][2], m[3][2],
188 m[0][3], m[1][3], m[2][3], m[3][3]);
191 //! Set Translation Part of the matrix
192 inline void setTranslationPart(const float v[3] )
199 //! Builds a translation matrix
200 inline void setTranslation(float tx, float ty, float tz)
202 m[0][0] = 1.0; m[0][1] = 0.0; m[0][2] = 0.0; m[0][3] = tx;
203 m[1][0] = 0.0; m[1][1] = 1.0; m[1][2] = 0.0; m[1][3] = ty;
204 m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 1.0; m[2][3] = tz;
205 m[3][0] = 0.0; m[3][1] = 0.0; m[3][2] = 0.0; m[3][3] = 1.0;
208 //! Set scale part of matrix
209 inline void setScalePart( const float v[3] )
216 static const Matrix4 ZERO;
217 static const Matrix4 IDENTITY;
218 static const Matrix4 CLIPSPACE2DTOIMAGESPACE; //! Useful little matrix which takes 2D clipspace {-1, 1} to {0,1} and inverts the Y.
221 inline Matrix4 operator*(float scalar) const
224 scalar*m[0][0], scalar*m[0][1], scalar*m[0][2], scalar*m[0][3],
225 scalar*m[1][0], scalar*m[1][1], scalar*m[1][2], scalar*m[1][3],
226 scalar*m[2][0], scalar*m[2][1], scalar*m[2][2], scalar*m[2][3],
227 scalar*m[3][0], scalar*m[3][1], scalar*m[3][2], scalar*m[3][3]);
230 //! Function for writing to a stream.
231 inline friend std::ostream& operator << ( std::ostream& o, const Matrix4& m )
234 for (size_t i = 0; i < 4; ++i)
236 o << " row" << (unsigned)i << "{";
237 for(size_t j = 0; j < 4; ++j)
247 float determinant() const;
248 Matrix4 inverse() const;