Arachnoid GLESv1.1 plugin. Compile and run (a bit glitchy and no frameskip) on the...
[mupen64plus-pandora.git] / source / mupen64plus-video-arachnoid / src / math / Matrix4.h
CommitLineData
22726e4d 1/******************************************************************************
2 * Arachnoid Graphics Plugin for Mupen64Plus
3 * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
4 *
5 * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
6 *
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.
11 *
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.
16 *
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 *****************************************************************************/
21
22#ifndef MATRIX_4_H_
23#define MATRIX_4_H_
24
25#include <iostream>
26#include <ostream>
27
28//*****************************************************************************
29//* Matrix4
30//! Math class defining a 4x4 matrix or an array of 16 float.
31//! @details Used for viewprojection matrix and vertex transformation.
32//*****************************************************************************
33class Matrix4
34{
35public:
36
37 //! The matrix entries, indexed by [row][col].
38 union {
39 float m[4][4];
40 float _m[16];
41 };
42
43public:
44
45 //! Default constructor.
46 inline Matrix4() { operator=(IDENTITY); }
47 inline Matrix4(
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 )
52 {
53 m[0][0] = m00;
54 m[0][1] = m01;
55 m[0][2] = m02;
56 m[0][3] = m03;
57 m[1][0] = m10;
58 m[1][1] = m11;
59 m[1][2] = m12;
60 m[1][3] = m13;
61 m[2][0] = m20;
62 m[2][1] = m21;
63 m[2][2] = m22;
64 m[2][3] = m23;
65 m[3][0] = m30;
66 m[3][1] = m31;
67 m[3][2] = m32;
68 m[3][3] = m33;
69 }
70
71 //! Matrix multiplication
72 inline Matrix4 operator * ( const Matrix4 &m2 ) const
73 {
74 Matrix4 r;
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];
79
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];
84
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];
89
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];
94
95 return r;
96 }
97
98 //Access operators
99 inline float* operator [] ( size_t iRow ) { return m[iRow]; }
100
101 inline const float* const operator [] ( size_t iRow ) const { return m[iRow]; }
102
103 //! Matrix addition.
104 inline Matrix4 operator + ( const Matrix4 &m2 ) const
105 {
106 Matrix4 r;
107
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];
112
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];
117
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];
122
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];
127
128 return r;
129 }
130
131 //! Matrix subtraction.
132 inline Matrix4 operator - ( const Matrix4 &m2 ) const
133 {
134 Matrix4 r;
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];
139
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];
144
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];
149
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];
154
155 return r;
156 }
157
158 //! Tests 2 matrices for equality.
159 inline bool operator == ( const Matrix4& m2 ) const
160 {
161 if(
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] )
166 return false;
167 return true;
168 }
169
170 //! Tests 2 matrices for inequality.
171 inline bool operator != ( const Matrix4& m2 ) const
172 {
173 if(
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] )
178 return true;
179 return false;
180 }
181
182 //!Transpose Matrix (Switch columns with rows)
183 inline Matrix4 transpose() const
184 {
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]);
189 }
190
191 //! Set Translation Part of the matrix
192 inline void setTranslationPart(const float v[3] )
193 {
194 m[0][3] = v[0];
195 m[1][3] = v[1];
196 m[2][3] = v[2];
197 }
198
199 //! Builds a translation matrix
200 inline void setTranslation(float tx, float ty, float tz)
201 {
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;
206 }
207
208 //! Set scale part of matrix
209 inline void setScalePart( const float v[3] )
210 {
211 m[0][0] = v[0];
212 m[1][1] = v[1];
213 m[2][2] = v[2];
214 }
215
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.
219
220
221 inline Matrix4 operator*(float scalar) const
222 {
223 return Matrix4(
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]);
228 }
229
230 //! Function for writing to a stream.
231 inline friend std::ostream& operator << ( std::ostream& o, const Matrix4& m )
232 {
233 o << "Matrix4(";
234 for (size_t i = 0; i < 4; ++i)
235 {
236 o << " row" << (unsigned)i << "{";
237 for(size_t j = 0; j < 4; ++j)
238 {
239 o << m[i][j] << " ";
240 }
241 o << "}";
242 }
243 o << ")";
244 return o;
245 }
246
247 float determinant() const;
248 Matrix4 inverse() const;
249
250};
251
252#endif