2 * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
4 * Please refer to the NVIDIA end user license agreement (EULA) associated
5 * with this source code for terms and conditions that govern your use of
6 * this software. Any use, reproduction, disclosure, or distribution of
7 * this software and related documentation outside the terms of the EULA
8 * is strictly prohibited.
13 // Template math library for common 3D functionality
15 // nvMatrix.h - template matrix code
17 // This code is in part deriver from glh, a cross platform glut helper library.
18 // The copyright for glh follows this notice.
20 // Copyright (c) NVIDIA Corporation. All rights reserved.
21 ////////////////////////////////////////////////////////////////////////////////
24 Copyright (c) 2000 Cass Everitt
25 Copyright (c) 2000 NVIDIA Corporation
28 Redistribution and use in source and binary forms, with or
29 without modification, are permitted provided that the following
32 * Redistributions of source code must retain the above
33 copyright notice, this list of conditions and the following
36 * Redistributions in binary form must reproduce the above
37 copyright notice, this list of conditions and the following
38 disclaimer in the documentation and/or other materials
39 provided with the distribution.
41 * The names of contributors to this software may not be used
42 to endorse or promote products derived from this software
43 without specific prior written permission.
45 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
46 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
47 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
48 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
49 REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
50 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
51 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
53 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
55 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
56 POSSIBILITY OF SUCH DAMAGE.
59 Cass Everitt - cass@r3.nu
68 template <class T> class vec2;
69 template <class T> class vec3;
70 template <class T> class vec4;
72 ////////////////////////////////////////////////////////////////////////////////
76 ////////////////////////////////////////////////////////////////////////////////
98 matrix4(T a00, T a01, T a02, T a03,
99 T a10, T a11, T a12, T a13,
100 T a20, T a21, T a22, T a23,
101 T a30, T a31, T a32, T a33) :
102 _11(a00), _12(a01), _13(a02), _14(a03),
103 _21(a10), _22(a11), _23(a12), _24(a13),
104 _31(a20), _32(a21), _33(a22), _34(a23),
105 _41(a30), _42(a31), _43(a32), _44(a33)
109 void get_value(T *mp) const
113 for (int j=0; j < 4; j++)
114 for (int i=0; i < 4; i++)
116 mp[c++] = element(i,j);
120 const T *get_value() const
125 void set_value(T *mp)
129 for (int j=0; j < 4; j++)
130 for (int i=0; i < 4; i++)
132 element(i,j) = mp[c++];
138 for (int i=0; i < 4; i++)
139 for (int j=0; j < 4; j++)
168 // set a uniform scale
176 void set_scale(const vec3<T> &s)
178 for (int i = 0; i < 3; i++)
185 void set_translate(const vec3<T> &t)
187 for (int i = 0; i < 3; i++)
193 void set_row(int r, const vec4<T> &t)
195 for (int i = 0; i < 4; i++)
201 void set_column(int c, const vec4<T> &t)
203 for (int i = 0; i < 4; i++)
209 vec4<T> get_row(int r) const
213 for (int i = 0; i < 4; i++)
221 vec4<T> get_column(int c) const
225 for (int i = 0; i < 4; i++)
233 friend matrix4 inverse(const matrix4 &m)
237 T r1[8], r2[8], r3[8], r4[8];
245 register int i,j,p,jj;
251 s[i][j] = m.element(i,j);
268 scp[i] = T(fabs(s[i][0]));
271 if (T(fabs(s[i][j])) > scp[i])
273 scp[i] = T(fabs(s[i][j]));
278 return minv; // singular matrix!
289 scp_max = T(fabs(s[i][i]/scp[i]));
291 // find out which row should be on top
292 for (p=i+1; p<4; p++)
293 if (T(fabs(s[p][i]/scp[p])) > scp_max)
295 scp_max = T(fabs(s[p][i]/scp[p]));
299 // Pivot if necessary
304 s[pivot_to] = tmprow;
307 scp[i] = scp[pivot_to];
308 scp[pivot_to] = tmpscp;
313 // perform gaussian elimination
314 for (j=i+1; j<4; j++)
316 mji = s[j][i]/s[i][i];
319 for (jj=i+1; jj<8; jj++)
321 s[j][jj] -= mji*s[i][jj];
328 return minv; // singular matrix!
332 // Now we have an upper triangular matrix.
339 // we'll back substitute to get the inverse
351 for (j=i-1; j > -1; j--)
353 mij = s[j][i]/s[i][i];
355 for (jj=j+1; jj<8; jj++)
357 s[j][jj] -= mij*s[i][jj];
365 minv(i,j) = s[i][j+4] / s[i][i];
372 friend matrix4 transpose(const matrix4 &m)
376 for (int i=0; i<4; i++)
377 for (int j=0; j<4; j++)
379 mtrans(i,j) = m.element(j,i);
385 matrix4 &operator *= (const matrix4 &rhs)
390 for (int i=0; i < 4; i++)
391 for (int j=0; j < 4; j++)
392 for (int c=0; c < 4; c++)
394 element(i,j) += mt(i,c) * rhs(c,j);
400 friend matrix4 operator * (const matrix4 &lhs, const matrix4 &rhs)
404 for (int i=0; i < 4; i++)
405 for (int j=0; j < 4; j++)
406 for (int c=0; c < 4; c++)
408 r.element(i,j) += lhs(i,c) * rhs(c,j);
415 vec4<T> operator *(const vec4<T> &src) const
419 for (int i = 0; i < 4; i++)
420 r[i] = (src[0] * element(i,0) + src[1] * element(i,1) +
421 src[2] * element(i,2) + src[3] * element(i,3));
427 friend vec4<T> operator *(const vec4<T> &lhs, const matrix4 &rhs)
431 for (int i = 0; i < 4; i++)
432 r[i] = (lhs[0] * rhs.element(0,i) + lhs[1] * rhs.element(1,i) +
433 lhs[2] * rhs.element(2,i) + lhs[3] * rhs.element(3,i));
438 T &operator()(int row, int col)
440 return element(row,col);
443 const T &operator()(int row, int col) const
445 return element(row,col);
448 T &element(int row, int col)
450 return _array[row | (col<<2)];
453 const T &element(int row, int col) const
455 return _array[row | (col<<2)];
458 matrix4 &operator *= (const T &r)
460 for (int i = 0; i < 4; ++i)
471 matrix4 &operator += (const matrix4 &mat)
473 for (int i = 0; i < 4; ++i)
475 element(0,i) += mat.element(0,i);
476 element(1,i) += mat.element(1,i);
477 element(2,i) += mat.element(2,i);
478 element(3,i) += mat.element(3,i);
485 friend bool operator == (const matrix4 &lhs, const matrix4 &rhs)
489 for (int i = 0; i < 16; i++)
491 r &= lhs._array[i] == rhs._array[i];
497 friend bool operator != (const matrix4 &lhs, const matrix4 &rhs)
501 for (int i = 0; i < 16; i++)
503 r &= lhs._array[i] != rhs._array[i];
513 T _11, _12, _13, _14; // standard names for components
514 T _21, _22, _23, _24; // standard names for components
515 T _31, _32, _33, _34; // standard names for components
516 T _41, _42, _43, _44; // standard names for components
518 T _array[16]; // array access