algebra3.cpp
上传用户:gb3593
上传日期:2022-01-07
资源大小:3028k
文件大小:36k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. /*
  2.   algebra3.cpp, algebra3.h -  C++ Vector and Matrix Algebra routines
  3.   GLUI User Interface Toolkit (LGPL)
  4.   Copyright (c) 1998 Paul Rademacher
  5.   WWW:    http://sourceforge.net/projects/glui/
  6.   Forums: http://sourceforge.net/forum/?group_id=92496
  7.   This library is free software; you can redistribute it and/or
  8.   modify it under the terms of the GNU Lesser General Public
  9.   License as published by the Free Software Foundation; either
  10.   version 2.1 of the License, or (at your option) any later version.
  11.   This library is distributed in the hope that it will be useful,
  12.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.   Lesser General Public License for more details.
  15.   You should have received a copy of the GNU Lesser General Public
  16.   License along with this library; if not, write to the Free Software
  17.   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18. */
  19. /**************************************************************************
  20.     
  21.   There are three vector classes and two matrix classes: vec2, vec3,
  22.   vec4, mat3, and mat4.
  23.   All the standard arithmetic operations are defined, with '*'
  24.   for dot product of two vectors and multiplication of two matrices,
  25.   and '^' for cross product of two vectors.
  26.   Additional functions include length(), normalize(), homogenize for
  27.   vectors, and print(), set(), apply() for all classes.
  28.   There is a function transpose() for matrices, but note that it 
  29.   does not actually change the matrix, 
  30.   When multiplied with a matrix, a vector is treated as a row vector
  31.   if it precedes the matrix (v*M), and as a column vector if it
  32.   follows the matrix (M*v).
  33.   Matrices are stored in row-major form.
  34.   A vector of one dimension (2d, 3d, or 4d) can be cast to a vector
  35.   of a higher or lower dimension.  If casting to a higher dimension,
  36.   the new component is set by default to 1.0, unless a value is
  37.   specified:
  38.      vec3 a(1.0, 2.0, 3.0 );
  39.      vec4 b( a, 4.0 );       // now b == {1.0, 2.0, 3.0, 4.0};
  40.   When casting to a lower dimension, the vector is homogenized in
  41.   the lower dimension.  E.g., if a 4d {X,Y,Z,W} is cast to 3d, the
  42.   resulting vector is {X/W, Y/W, Z/W}.  It is up to the user to 
  43.   insure the fourth component is not zero before casting.
  44.   There are also the following function for building matrices:
  45.      identity2D(), translation2D(), rotation2D(),
  46.      scaling2D(),  identity3D(),    translation3D(),
  47.      rotation3D(), rotation3Drad(),  scaling3D(),
  48.      perspective3D()
  49.  
  50.   ---------------------------------------------------------------------
  51.   
  52.   Author: Jean-Francois DOUEg                   
  53.   Revised: Paul Rademacher                                      
  54.   Version 3.2 - Feb 1998
  55.   Revised: Nigel Stewart (GLUI Code Cleaning)
  56.                                 
  57. **************************************************************************/
  58. #include "algebra3.h"
  59. #include "glui_internal.h"
  60. #include <cmath>
  61. #ifdef VEC_ERROR_FATAL
  62. #ifndef VEC_ERROR
  63. #define VEC_ERROR(E) { printf( "VERROR %sn", E ); exit(1); }
  64. #endif
  65. #else
  66. #ifndef VEC_ERROR
  67. #define VEC_ERROR(E) { printf( "VERROR %sn", E ); }
  68. #endif
  69. #endif
  70. /****************************************************************
  71.  *                                                              *
  72.  *          vec2 Member functions                               *
  73.  *                                                              *
  74.  ****************************************************************/
  75. /******************** vec2 CONSTRUCTORS ********************/
  76. vec2::vec2() 
  77. {
  78.     n[VX] = n[VY] = 0.0; 
  79. }
  80. vec2::vec2(float x, float y)
  81.     n[VX] = x; 
  82.     n[VY] = y; 
  83. }
  84. vec2::vec2(const vec2 &v)
  85.     n[VX] = v.n[VX]; 
  86.     n[VY] = v.n[VY]; 
  87. }
  88. vec2::vec2(const vec3 &v) // it is up to caller to avoid divide-by-zero
  89.     n[VX] = v.n[VX]/v.n[VZ]; 
  90.     n[VY] = v.n[VY]/v.n[VZ]; 
  91. }
  92. vec2::vec2(const vec3 &v, int dropAxis) 
  93. {
  94.     switch (dropAxis) 
  95.     {
  96.         case VX: n[VX] = v.n[VY]; n[VY] = v.n[VZ]; break;
  97.         case VY: n[VX] = v.n[VX]; n[VY] = v.n[VZ]; break;
  98.         default: n[VX] = v.n[VX]; n[VY] = v.n[VY]; break;
  99.     }
  100. }
  101. /******************** vec2 ASSIGNMENT OPERATORS ******************/
  102. vec2 & vec2::operator=(const vec2 &v)
  103.     n[VX] = v.n[VX]; 
  104.     n[VY] = v.n[VY]; 
  105.     return *this; 
  106. }
  107. vec2 & vec2::operator+=(const vec2 &v)
  108.     n[VX] += v.n[VX]; 
  109.     n[VY] += v.n[VY]; 
  110.     return *this; 
  111. }
  112. vec2 & vec2::operator-=(const vec2 &v)
  113.     n[VX] -= v.n[VX]; 
  114.     n[VY] -= v.n[VY]; 
  115.     return *this; 
  116. }
  117. vec2 &vec2::operator*=(float d)
  118.     n[VX] *= d; 
  119.     n[VY] *= d; 
  120.     return *this; 
  121. }
  122. vec2 &vec2::operator/=(float d)
  123.     float d_inv = 1.0f/d; 
  124.     n[VX] *= d_inv; 
  125.     n[VY] *= d_inv; 
  126.     return *this; 
  127. }
  128. float &vec2::operator[](int i) 
  129. {
  130.     if (i < VX || i > VY)
  131.       //VEC_ERROR("vec2 [] operator: illegal access; index = " << i << 'n')
  132.       VEC_ERROR("vec2 [] operator: illegal access" );
  133.     return n[i];
  134. }
  135. const float &vec2::operator[](int i) const
  136. {
  137.     if (i < VX || i > VY)
  138.       //VEC_ERROR("vec2 [] operator: illegal access; index = " << i << 'n')
  139.       VEC_ERROR("vec2 [] operator: illegal access" );
  140.     return n[i];
  141. }
  142. /******************** vec2 SPECIAL FUNCTIONS ********************/
  143. float vec2::length() const 
  144.     return (float) sqrt(length2()); 
  145. }
  146. float vec2::length2() const 
  147.     return n[VX]*n[VX] + n[VY]*n[VY]; 
  148. }
  149. vec2 &vec2::normalize() // it is up to caller to avoid divide-by-zero
  150.     *this /= length(); 
  151.     return *this; 
  152. }
  153. vec2 &vec2::apply(V_FCT_PTR fct)
  154.     n[VX] = (*fct)(n[VX]); 
  155.     n[VY] = (*fct)(n[VY]); 
  156.     return *this; 
  157. }
  158. void vec2::set( float x, float y )
  159. {
  160.   n[VX] = x;   n[VY] = y; 
  161. }
  162. /******************** vec2 FRIENDS *****************************/
  163. vec2 operator-(const vec2 &a)
  164.     return vec2(-a.n[VX],-a.n[VY]); 
  165. }
  166. vec2 operator+(const vec2 &a, const vec2& b)
  167.     return vec2(a.n[VX]+b.n[VX], a.n[VY]+b.n[VY]); 
  168. }
  169. vec2 operator-(const vec2 &a, const vec2& b)
  170.     return vec2(a.n[VX]-b.n[VX], a.n[VY]-b.n[VY]); 
  171. }
  172. vec2 operator*(const vec2 &a, float d)
  173.     return vec2(d*a.n[VX], d*a.n[VY]); 
  174. }
  175. vec2 operator*(float d, const vec2 &a)
  176.     return a*d; 
  177. }
  178. vec2 operator*(const mat3 &a, const vec2 &v) 
  179. {
  180.   vec3 av;
  181.   av.n[VX] = a.v[0].n[VX]*v.n[VX] + a.v[0].n[VY]*v.n[VY] + a.v[0].n[VZ];
  182.   av.n[VY] = a.v[1].n[VX]*v.n[VX] + a.v[1].n[VY]*v.n[VY] + a.v[1].n[VZ];
  183.   av.n[VZ] = a.v[2].n[VX]*v.n[VX] + a.v[2].n[VY]*v.n[VY] + a.v[2].n[VZ];
  184.   return av;
  185. }
  186. vec2 operator*(const vec2 &v, const mat3 &a)
  187.     return a.transpose() * v; 
  188. }
  189. vec3 operator*(const mat3 &a, const vec3 &v) 
  190. {
  191.     vec3 av;
  192.     av.n[VX] = a.v[0].n[VX]*v.n[VX] + a.v[0].n[VY]*v.n[VY] + a.v[0].n[VZ]*v.n[VZ];
  193.     av.n[VY] = a.v[1].n[VX]*v.n[VX] + a.v[1].n[VY]*v.n[VY] + a.v[1].n[VZ]*v.n[VZ];
  194.     av.n[VZ] = a.v[2].n[VX]*v.n[VX] + a.v[2].n[VY]*v.n[VY] + a.v[2].n[VZ]*v.n[VZ];
  195.     return av;
  196. }
  197. vec3 operator*(const vec3 &v, const mat3 &a) 
  198.     return a.transpose() * v; 
  199. }
  200. float operator*(const vec2 &a, const vec2 &b)
  201.     return a.n[VX]*b.n[VX] + a.n[VY]*b.n[VY]; 
  202. }
  203. vec2 operator/(const vec2 &a, float d)
  204.     float d_inv = 1.0f/d; 
  205.     return vec2(a.n[VX]*d_inv, a.n[VY]*d_inv); 
  206. }
  207. vec3 operator^(const vec2 &a, const vec2 &b)
  208.     return vec3(0.0, 0.0, a.n[VX] * b.n[VY] - b.n[VX] * a.n[VY]); 
  209. }
  210. int operator==(const vec2 &a, const vec2 &b)
  211.     return (a.n[VX] == b.n[VX]) && (a.n[VY] == b.n[VY]); 
  212. }
  213. int operator!=(const vec2 &a, const vec2 &b)
  214.     return !(a == b); 
  215. }
  216. /*ostream& operator << (ostream& s, vec2& v)
  217. { return s << "| " << v.n[VX] << ' ' << v.n[VY] << " |"; }
  218. */
  219. /*istream& operator >> (istream& s, vec2& v) {
  220.     vec2    v_tmp;
  221.     char    c = ' ';
  222.     while (isspace(c))
  223.     s >> c;
  224.     // The vectors can be formatted either as x y or | x y |
  225.     if (c == '|') {
  226.     s >> v_tmp[VX] >> v_tmp[VY];
  227.     while (s >> c && isspace(c)) ;
  228.     if (c != '|')
  229.         ;//s.set(_bad);
  230.     }
  231.     else {
  232.     s.putback(c);
  233.     s >> v_tmp[VX] >> v_tmp[VY];
  234.     }
  235.     if (s)
  236.     v = v_tmp;
  237.     return s;
  238. }
  239. */
  240. void swap(vec2 &a, vec2 &b)
  241.     vec2 tmp(a);
  242.     a = b; 
  243.     b = tmp; 
  244. }
  245. vec2 min_vec(const vec2 &a, const vec2 &b)
  246.     return vec2(MIN(a.n[VX], b.n[VX]), MIN(a.n[VY], b.n[VY])); 
  247. }
  248. vec2 max_vec(const vec2 &a, const vec2 &b)
  249.     return vec2(MAX(a.n[VX], b.n[VX]), MAX(a.n[VY], b.n[VY])); 
  250. }
  251. vec2 prod(const vec2 &a, const vec2 &b)
  252.     return vec2(a.n[VX] * b.n[VX], a.n[VY] * b.n[VY]); 
  253. }
  254. /****************************************************************
  255.  *                                                              *
  256.  *          vec3 Member functions                               *
  257.  *                                                              *
  258.  ****************************************************************/
  259. // CONSTRUCTORS
  260. vec3::vec3() 
  261. {
  262.     n[VX] = n[VY] = n[VZ] = 0.0;
  263. }
  264. vec3::vec3(float x, float y, float z)
  265.     n[VX] = x; 
  266.     n[VY] = y; 
  267.     n[VZ] = z; 
  268. }
  269. vec3::vec3(const vec3 &v)
  270.     n[VX] = v.n[VX]; n[VY] = v.n[VY]; n[VZ] = v.n[VZ]; 
  271. }
  272. vec3::vec3(const vec2 &v)
  273.     n[VX] = v.n[VX]; 
  274.     n[VY] = v.n[VY]; 
  275.     n[VZ] = 1.0; 
  276. }
  277. vec3::vec3(const vec2 &v, float d)
  278.     n[VX] = v.n[VX]; 
  279.     n[VY] = v.n[VY]; 
  280.     n[VZ] = d; 
  281. }
  282. vec3::vec3(const vec4 &v) // it is up to caller to avoid divide-by-zero
  283.     n[VX] = v.n[VX] / v.n[VW]; 
  284.     n[VY] = v.n[VY] / v.n[VW];
  285.     n[VZ] = v.n[VZ] / v.n[VW]; 
  286. }
  287. vec3::vec3(const vec4 &v, int dropAxis) 
  288. {
  289.     switch (dropAxis) 
  290.     {
  291.         case VX: n[VX] = v.n[VY]; n[VY] = v.n[VZ]; n[VZ] = v.n[VW]; break;
  292.         case VY: n[VX] = v.n[VX]; n[VY] = v.n[VZ]; n[VZ] = v.n[VW]; break;
  293.         case VZ: n[VX] = v.n[VX]; n[VY] = v.n[VY]; n[VZ] = v.n[VW]; break;
  294.         default: n[VX] = v.n[VX]; n[VY] = v.n[VY]; n[VZ] = v.n[VZ]; break;
  295.     }
  296. }
  297. // ASSIGNMENT OPERATORS
  298. vec3 &vec3::operator=(const vec3 &v)
  299.     n[VX] = v.n[VX]; 
  300.     n[VY] = v.n[VY]; 
  301.     n[VZ] = v.n[VZ]; 
  302.     return *this; 
  303. }
  304. vec3 &vec3::operator+=(const vec3 &v)
  305.     n[VX] += v.n[VX]; 
  306.     n[VY] += v.n[VY]; 
  307.     n[VZ] += v.n[VZ]; 
  308.     return *this; 
  309. }
  310. vec3 &vec3::operator-=(const vec3& v)
  311.     n[VX] -= v.n[VX]; 
  312.     n[VY] -= v.n[VY]; 
  313.     n[VZ] -= v.n[VZ];
  314.     return *this; 
  315. }
  316. vec3 &vec3::operator*=(float d)
  317.     n[VX] *= d; 
  318.     n[VY] *= d; 
  319.     n[VZ] *= d; 
  320.     return *this; 
  321. }
  322. vec3 &vec3::operator/=(float d)
  323.     float d_inv = 1.0f/d; 
  324.     n[VX] *= d_inv; 
  325.     n[VY] *= d_inv; 
  326.     n[VZ] *= d_inv;
  327.     return *this; 
  328. }
  329. float &vec3::operator[](int i) 
  330. {
  331.     if (i < VX || i > VZ)
  332.         //VEC_ERROR("vec3 [] operator: illegal access; index = " << i << 'n')
  333.         VEC_ERROR("vec3 [] operator: illegal access" );
  334.     return n[i];
  335. }
  336. const float &vec3::operator[](int i) const
  337. {
  338.     if (i < VX || i > VZ)
  339.         //VEC_ERROR("vec3 [] operator: illegal access; index = " << i << 'n')
  340.         VEC_ERROR("vec3 [] operator: illegal access" );
  341.     return n[i];
  342. }
  343. // SPECIAL FUNCTIONS
  344. float vec3::length() const
  345. {  
  346.     return (float) sqrt(length2()); 
  347. }
  348. float vec3::length2() const
  349. {  
  350.     return n[VX]*n[VX] + n[VY]*n[VY] + n[VZ]*n[VZ]; 
  351. }
  352. vec3 &vec3::normalize() // it is up to caller to avoid divide-by-zero
  353.     *this /= length(); 
  354.     return *this; 
  355. }
  356. vec3 &vec3::homogenize(void) // it is up to caller to avoid divide-by-zero
  357.     n[VX] /= n[VZ];  
  358.     n[VY] /= n[VZ];  
  359.     n[VZ] = 1.0; 
  360.     return *this; 
  361. }
  362. vec3 &vec3::apply(V_FCT_PTR fct)
  363.     n[VX] = (*fct)(n[VX]); 
  364.     n[VY] = (*fct)(n[VY]); 
  365.     n[VZ] = (*fct)(n[VZ]);
  366.     return *this; 
  367. }
  368. void vec3::set(float x, float y, float z)   // set vector
  369.     n[VX] = x; 
  370.     n[VY] = y; 
  371.     n[VZ] = z;  
  372. }
  373. void vec3::print(FILE *file, const char *name) const  // print vector to a file
  374. {
  375.     fprintf( file, "%s: <%f, %f, %f>n", name, n[VX], n[VY], n[VZ] );
  376. }
  377. // FRIENDS
  378. vec3 operator-(const vec3 &a)
  379. {  
  380.     return vec3(-a.n[VX],-a.n[VY],-a.n[VZ]); 
  381. }
  382. vec3 operator+(const vec3 &a, const vec3 &b)
  383.     return vec3(a.n[VX]+ b.n[VX], a.n[VY] + b.n[VY], a.n[VZ] + b.n[VZ]); 
  384. }
  385. vec3 operator-(const vec3 &a, const vec3 &b)
  386.     return vec3(a.n[VX]-b.n[VX], a.n[VY]-b.n[VY], a.n[VZ]-b.n[VZ]); 
  387. }
  388. vec3 operator*(const vec3 &a, float d)
  389.     return vec3(d*a.n[VX], d*a.n[VY], d*a.n[VZ]); 
  390. }
  391. vec3 operator*(float d, const vec3 &a)
  392.     return a*d; 
  393. }
  394. vec3 operator*(const mat4 &a, const vec3 &v)
  395.     return a*vec4(v); 
  396. }
  397. vec3 operator*(const vec3 &v, mat4 &a)
  398.     return a.transpose()*v; 
  399. }
  400. float operator*(const vec3 &a, const vec3 &b)
  401.     return a.n[VX]*b.n[VX] + a.n[VY]*b.n[VY] + a.n[VZ]*b.n[VZ]; 
  402. }
  403. vec3 operator/(const vec3 &a, float d)
  404.     float d_inv = 1.0f/d; 
  405.     return vec3(a.n[VX]*d_inv, a.n[VY]*d_inv, a.n[VZ]*d_inv); 
  406. }
  407. vec3 operator^(const vec3 &a, const vec3 &b) 
  408. {
  409.     return 
  410.         vec3(a.n[VY]*b.n[VZ] - a.n[VZ]*b.n[VY],
  411.              a.n[VZ]*b.n[VX] - a.n[VX]*b.n[VZ],
  412.              a.n[VX]*b.n[VY] - a.n[VY]*b.n[VX]);
  413. }
  414. int operator==(const vec3 &a, const vec3 &b)
  415.     return (a.n[VX] == b.n[VX]) && (a.n[VY] == b.n[VY]) && (a.n[VZ] == b.n[VZ]);
  416. }
  417. int operator!=(const vec3 &a, const vec3 &b)
  418.     return !(a == b); 
  419. }
  420. /*ostream& operator << (ostream& s, vec3& v)
  421. { return s << "| " << v.n[VX] << ' ' << v.n[VY] << ' ' << v.n[VZ] << " |"; }
  422. istream& operator >> (istream& s, vec3& v) {
  423.     vec3    v_tmp;
  424.     char    c = ' ';
  425.     while (isspace(c))
  426.     s >> c;
  427.     // The vectors can be formatted either as x y z or | x y z |
  428.     if (c == '|') {
  429.     s >> v_tmp[VX] >> v_tmp[VY] >> v_tmp[VZ];
  430.     while (s >> c && isspace(c)) ;
  431.     if (c != '|')
  432.         ;//s.set(_bad);
  433.     }
  434.     else {
  435.     s.putback(c);
  436.     s >> v_tmp[VX] >> v_tmp[VY] >> v_tmp[VZ];
  437.     }
  438.     if (s)
  439.     v = v_tmp;
  440.     return s;
  441. }
  442. */
  443. void swap(vec3 &a, vec3 &b)
  444.     vec3 tmp(a); 
  445.     a = b; 
  446.     b = tmp; 
  447. }
  448. vec3 min_vec(const vec3 &a, const vec3 &b)
  449.     return vec3(
  450.         MIN(a.n[VX], b.n[VX]), 
  451.         MIN(a.n[VY], b.n[VY]), 
  452.         MIN(a.n[VZ], b.n[VZ])); 
  453. }
  454. vec3 max_vec(const vec3 &a, const vec3 &b)
  455.     return vec3(
  456.         MAX(a.n[VX], b.n[VX]), 
  457.         MAX(a.n[VY], b.n[VY]), 
  458.         MAX(a.n[VZ], b.n[VZ])); 
  459. }
  460. vec3 prod(const vec3 &a, const vec3 &b)
  461.     return vec3(a.n[VX]*b.n[VX], a.n[VY]*b.n[VY], a.n[VZ]*b.n[VZ]); 
  462. }
  463. /****************************************************************
  464.  *                                                              *
  465.  *          vec4 Member functions                               *
  466.  *                                                              *
  467.  ****************************************************************/
  468. // CONSTRUCTORS
  469. vec4::vec4() 
  470. {
  471.     n[VX] = n[VY] = n[VZ] = 0.0; 
  472.     n[VW] = 1.0; 
  473. }
  474. vec4::vec4(float x, float y, float z, float w)
  475.     n[VX] = x; 
  476.     n[VY] = y; 
  477.     n[VZ] = z; 
  478.     n[VW] = w; 
  479. }
  480. vec4::vec4(const vec4 &v)
  481.     n[VX] = v.n[VX]; 
  482.     n[VY] = v.n[VY]; 
  483.     n[VZ] = v.n[VZ]; 
  484.     n[VW] = v.n[VW]; 
  485. }
  486. vec4::vec4(const vec3 &v)
  487.     n[VX] = v.n[VX]; 
  488.     n[VY] = v.n[VY]; 
  489.     n[VZ] = v.n[VZ]; 
  490.     n[VW] = 1.0; 
  491. }
  492. vec4::vec4(const vec3 &v, float d)
  493.     n[VX] = v.n[VX]; 
  494.     n[VY] = v.n[VY]; 
  495.     n[VZ] = v.n[VZ];  
  496.     n[VW] = d; 
  497. }
  498. // ASSIGNMENT OPERATORS
  499. vec4 &vec4::operator=(const vec4 &v)
  500.     n[VX] = v.n[VX]; 
  501.     n[VY] = v.n[VY]; 
  502.     n[VZ] = v.n[VZ]; 
  503.     n[VW] = v.n[VW];
  504.     return *this; 
  505. }
  506. vec4 &vec4::operator+=(const vec4 &v)
  507.     n[VX] += v.n[VX]; 
  508.     n[VY] += v.n[VY]; 
  509.     n[VZ] += v.n[VZ]; 
  510.     n[VW] += v.n[VW];
  511.     return *this; 
  512. }
  513. vec4 &vec4::operator-=(const vec4 &v)
  514.     n[VX] -= v.n[VX]; 
  515.     n[VY] -= v.n[VY]; 
  516.     n[VZ] -= v.n[VZ]; 
  517.     n[VW] -= v.n[VW];
  518.     return *this; 
  519. }
  520. vec4 &vec4::operator*=(float d)
  521.     n[VX] *= d; 
  522.     n[VY] *= d; 
  523.     n[VZ] *= d; 
  524.     n[VW] *= d; 
  525.     return *this; 
  526. }
  527. vec4 &vec4::operator/=(float d)
  528.     float d_inv = 1.0f/d; 
  529.     n[VX] *= d_inv; 
  530.     n[VY] *= d_inv; 
  531.     n[VZ] *= d_inv;
  532.     n[VW] *= d_inv; 
  533.     return *this; 
  534. }
  535. float &vec4::operator[](int i) 
  536. {
  537.     if (i < VX || i > VW)
  538.         //VEC_ERROR("vec4 [] operator: illegal access; index = " << i << 'n')
  539.         VEC_ERROR("vec4 [] operator: illegal access" );
  540.     return n[i];
  541. }
  542. const float &vec4::operator[](int i) const
  543. {
  544.     if (i < VX || i > VW)
  545.         //VEC_ERROR("vec4 [] operator: illegal access; index = " << i << 'n')
  546.         VEC_ERROR("vec4 [] operator: illegal access" );
  547.     return n[i];
  548. }
  549. // SPECIAL FUNCTIONS
  550. float vec4::length() const
  551.     return (float) sqrt(length2()); 
  552. }
  553. float vec4::length2() const
  554.     return n[VX]*n[VX] + n[VY]*n[VY] + n[VZ]*n[VZ] + n[VW]*n[VW]; 
  555. }
  556. vec4 &vec4::normalize() // it is up to caller to avoid divide-by-zero
  557.     *this /= length(); 
  558.     return *this; 
  559. }
  560. vec4 &vec4::homogenize() // it is up to caller to avoid divide-by-zero
  561.     n[VX] /= n[VW];  
  562.     n[VY] /= n[VW];  
  563.     n[VZ] /= n[VW]; 
  564.     n[VW] = 1.0;  
  565.     return *this; 
  566. }
  567. vec4 &vec4::apply(V_FCT_PTR fct)
  568.     n[VX] = (*fct)(n[VX]); 
  569.     n[VY] = (*fct)(n[VY]); 
  570.     n[VZ] = (*fct)(n[VZ]);
  571.     n[VW] = (*fct)(n[VW]); 
  572.     return *this; 
  573. }
  574. void vec4::print(FILE *file, const char *name) const // print vector to a file
  575. {
  576.     fprintf( file, "%s: <%f, %f, %f, %f>n", name, n[VX], n[VY], n[VZ], n[VW]);
  577. }
  578. void vec4::set(float x, float y, float z, float a)
  579. {
  580.     n[0] = x; 
  581.     n[1] = y; 
  582.     n[2] = z; 
  583.     n[3] = a;
  584. }
  585. // FRIENDS
  586. vec4 operator-(const vec4 &a)
  587.     return vec4(-a.n[VX],-a.n[VY],-a.n[VZ],-a.n[VW]);
  588. }
  589. vec4 operator+(const vec4 &a, const vec4 &b)
  590.     return vec4(
  591.         a.n[VX] + b.n[VX], 
  592.         a.n[VY] + b.n[VY], 
  593.         a.n[VZ] + b.n[VZ],
  594.         a.n[VW] + b.n[VW]); 
  595. }
  596. vec4 operator-(const vec4 &a, const vec4 &b)
  597. {  
  598.     return vec4(
  599.         a.n[VX] - b.n[VX], 
  600.         a.n[VY] - b.n[VY], 
  601.         a.n[VZ] - b.n[VZ],
  602.         a.n[VW] - b.n[VW]); 
  603. }
  604. vec4 operator*(const vec4 &a, float d)
  605.     return vec4(d*a.n[VX], d*a.n[VY], d*a.n[VZ], d*a.n[VW]); 
  606. }
  607. vec4 operator*(float d, const vec4 &a)
  608.     return a*d; 
  609. }
  610. vec4 operator*(const mat4 &a, const vec4 &v) 
  611. {
  612.     #define ROWCOL(i) 
  613.         a.v[i].n[0]*v.n[VX] + 
  614.         a.v[i].n[1]*v.n[VY] + 
  615.         a.v[i].n[2]*v.n[VZ] + 
  616.         a.v[i].n[3]*v.n[VW]
  617.     return vec4(ROWCOL(0), ROWCOL(1), ROWCOL(2), ROWCOL(3));
  618.     #undef ROWCOL
  619. }
  620. vec4 operator*(const vec4 &v, const mat4 &a)
  621.     return a.transpose()*v; 
  622. }
  623. float operator*(const vec4 &a, const vec4 &b)
  624.     return 
  625.         a.n[VX]*b.n[VX] + 
  626.         a.n[VY]*b.n[VY] + 
  627.         a.n[VZ]*b.n[VZ] +
  628.         a.n[VW]*b.n[VW]; 
  629. }
  630. vec4 operator/(const vec4 &a, float d)
  631.     float d_inv = 1.0f/d; 
  632.     return vec4(
  633.         a.n[VX]*d_inv, 
  634.         a.n[VY]*d_inv, 
  635.         a.n[VZ]*d_inv,
  636.         a.n[VW]*d_inv); 
  637. }
  638. int operator==(const vec4 &a, const vec4 &b)
  639.     return 
  640.         (a.n[VX] == b.n[VX]) && 
  641.         (a.n[VY] == b.n[VY]) && 
  642.         (a.n[VZ] == b.n[VZ]) && 
  643.         (a.n[VW] == b.n[VW]); 
  644. }
  645. int operator!=(const vec4 &a, const vec4 &b)
  646.     return !(a == b); 
  647. }
  648. /*ostream& operator << (ostream& s, vec4& v)
  649. { return s << "| " << v.n[VX] << ' ' << v.n[VY] << ' ' << v.n[VZ] << ' '
  650.   << v.n[VW] << " |"; }
  651. istream& operator >> (istream& s, vec4& v) {
  652.     vec4    v_tmp;
  653.     char    c = ' ';
  654.     while (isspace(c))
  655.     s >> c;
  656.     // The vectors can be formatted either as x y z w or | x y z w |
  657.     if (c == '|') {
  658.     s >> v_tmp[VX] >> v_tmp[VY] >> v_tmp[VZ] >> v_tmp[VW];
  659.     while (s >> c && isspace(c)) ;
  660.     if (c != '|')
  661.         ;//s.set(_bad);
  662.     }
  663.     else {
  664.     s.putback(c);
  665.     s >> v_tmp[VX] >> v_tmp[VY] >> v_tmp[VZ] >> v_tmp[VW];
  666.     }
  667.     if (s)
  668.     v = v_tmp;
  669.     return s;
  670. }
  671. */
  672. void swap(vec4 &a, vec4 &b)
  673.     vec4 tmp(a); 
  674.     a = b; 
  675.     b = tmp; 
  676. }
  677. vec4 min_vec(const vec4 &a, const vec4 &b)
  678.     return vec4(
  679.         MIN(a.n[VX], b.n[VX]), 
  680.         MIN(a.n[VY], b.n[VY]), 
  681.         MIN(a.n[VZ], b.n[VZ]), 
  682.         MIN(a.n[VW], b.n[VW])); 
  683. }
  684. vec4 max_vec(const vec4 &a, const vec4 &b)
  685.     return vec4(
  686.         MAX(a.n[VX], b.n[VX]), 
  687.         MAX(a.n[VY], b.n[VY]), 
  688.         MAX(a.n[VZ], b.n[VZ]), 
  689.         MAX(a.n[VW], b.n[VW])); 
  690. }
  691. vec4 prod(const vec4 &a, const vec4 &b)
  692.     return vec4(
  693.         a.n[VX] * b.n[VX], 
  694.         a.n[VY] * b.n[VY], 
  695.         a.n[VZ] * b.n[VZ],
  696.         a.n[VW] * b.n[VW]); 
  697. }
  698. /****************************************************************
  699.  *                                                              *
  700.  *          mat3 member functions                               *
  701.  *                                                              *
  702.  ****************************************************************/
  703. // CONSTRUCTORS
  704. mat3::mat3() 
  705.     *this = identity2D(); 
  706. }
  707. mat3::mat3(const vec3 &v0, const vec3 &v1, const vec3 &v2)
  708.     set(v0, v1, v2); 
  709. }
  710. mat3::mat3(const mat3 &m)
  711.     v[0] = m.v[0]; 
  712.     v[1] = m.v[1]; 
  713.     v[2] = m.v[2]; 
  714. }
  715. // ASSIGNMENT OPERATORS
  716. mat3 &mat3::operator=(const mat3 &m)
  717.     v[0] = m.v[0]; 
  718.     v[1] = m.v[1]; 
  719.     v[2] = m.v[2]; 
  720.     return *this; 
  721. }
  722. mat3 &mat3::operator+=(const mat3& m)
  723.     v[0] += m.v[0]; 
  724.     v[1] += m.v[1]; 
  725.     v[2] += m.v[2]; 
  726.     return *this; 
  727. }
  728. mat3 &mat3::operator-=(const mat3& m)
  729.     v[0] -= m.v[0]; 
  730.     v[1] -= m.v[1]; 
  731.     v[2] -= m.v[2]; 
  732.     return *this; 
  733. }
  734. mat3 &mat3::operator*=(float d)
  735.     v[0] *= d; 
  736.     v[1] *= d; 
  737.     v[2] *= d;
  738.     return *this; 
  739. }
  740. mat3 &mat3::operator/=(float d)
  741.     v[0] /= d; 
  742.     v[1] /= d; 
  743.     v[2] /= d; 
  744.     return *this; 
  745. }
  746. vec3 &mat3::operator[](int i) 
  747. {
  748.     if (i < VX || i > VZ)
  749.       //VEC_ERROR("mat3 [] operator: illegal access; index = " << i << 'n')
  750.       VEC_ERROR("mat3 [] operator: illegal access" );
  751.     return v[i];
  752. }
  753. const vec3 &mat3::operator[](int i) const
  754. {
  755.     if (i < VX || i > VZ)
  756.       //VEC_ERROR("mat3 [] operator: illegal access; index = " << i << 'n')
  757.       VEC_ERROR("mat3 [] operator: illegal access" );
  758.     return v[i];
  759. }
  760. void mat3::set(const vec3 &v0, const vec3 &v1, const vec3 &v2) 
  761. {
  762.     v[0] = v0; 
  763.     v[1] = v1; 
  764.     v[2] = v2; 
  765. }
  766. // SPECIAL FUNCTIONS
  767. mat3 mat3::transpose() const 
  768. {
  769.     return mat3(
  770.         vec3(v[0][0], v[1][0], v[2][0]),
  771.         vec3(v[0][1], v[1][1], v[2][1]),
  772.         vec3(v[0][2], v[1][2], v[2][2]));
  773. }
  774. mat3 mat3::inverse() const       // Gauss-Jordan elimination with partial pivoting
  775. {
  776.     mat3 a(*this);          // As a evolves from original mat into identity
  777.     mat3 b(identity2D());   // b evolves from identity into inverse(a)
  778.     int  i, j, i1;
  779.     // Loop over cols of a from left to right, eliminating above and below diag
  780.     for (j=0; j<3; j++)     // Find largest pivot in column j among rows j..2
  781.     {
  782.         i1 = j;         // Row with largest pivot candidate
  783.         for (i=j+1; i<3; i++)
  784.             if (fabs(a.v[i].n[j]) > fabs(a.v[i1].n[j]))
  785.                 i1 = i;
  786.         // Swap rows i1 and j in a and b to put pivot on diagonal
  787.         swap(a.v[i1], a.v[j]);
  788.         swap(b.v[i1], b.v[j]);
  789.         // Scale row j to have a unit diagonal
  790.         if (a.v[j].n[j]==0.)
  791.             VEC_ERROR("mat3::inverse: singular matrix; can't invertn");
  792.         b.v[j] /= a.v[j].n[j];
  793.         a.v[j] /= a.v[j].n[j];
  794.         // Eliminate off-diagonal elems in col j of a, doing identical ops to b
  795.         for (i=0; i<3; i++)
  796.             if (i!=j) 
  797.             {
  798.                 b.v[i] -= a.v[i].n[j]*b.v[j];
  799.                 a.v[i] -= a.v[i].n[j]*a.v[j];
  800.             }
  801.     }
  802.     return b;
  803. }
  804. mat3 &mat3::apply(V_FCT_PTR fct) 
  805. {
  806.     v[VX].apply(fct);
  807.     v[VY].apply(fct);
  808.     v[VZ].apply(fct);
  809.     return *this;
  810. }
  811. // FRIENDS
  812. mat3 operator-(const mat3 &a)
  813.     return mat3(-a.v[0], -a.v[1], -a.v[2]); 
  814. }
  815. mat3 operator+(const mat3 &a, const mat3 &b)
  816.     return mat3(a.v[0]+b.v[0], a.v[1]+b.v[1], a.v[2]+b.v[2]); 
  817. }
  818. mat3 operator-(const mat3 &a, const mat3 &b)
  819.     return mat3(a.v[0]-b.v[0], a.v[1]-b.v[1], a.v[2]-b.v[2]); 
  820. }
  821. mat3 operator*(const mat3 &a, const mat3 &b) 
  822. {
  823.     #define ROWCOL(i, j) 
  824.     a.v[i].n[0]*b.v[0][j] + a.v[i].n[1]*b.v[1][j] + a.v[i].n[2]*b.v[2][j]
  825.     return mat3(
  826.         vec3(ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2)),
  827.         vec3(ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2)),
  828.         vec3(ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2)));
  829.     
  830.     #undef ROWCOL
  831. }
  832. mat3 operator*(const mat3 &a, float d)
  833.     return mat3(a.v[0]*d, a.v[1]*d, a.v[2]*d); 
  834. }
  835. mat3 operator*(float d, const mat3 &a)
  836.     return a*d; 
  837. }
  838. mat3 operator/(const mat3 &a, float d)
  839.     return mat3(a.v[0]/d, a.v[1]/d, a.v[2]/d); 
  840. }
  841. int operator==(const mat3 &a, const mat3 &b)
  842.     return 
  843.         (a.v[0] == b.v[0]) && 
  844.         (a.v[1] == b.v[1]) && 
  845.         (a.v[2] == b.v[2]); 
  846. }
  847. int operator!=(const mat3 &a, const mat3 &b)
  848.     return !(a == b); 
  849. }
  850. /*ostream& operator << (ostream& s, mat3& m)
  851. { return s << m.v[VX] << 'n' << m.v[VY] << 'n' << m.v[VZ]; }
  852. istream& operator >> (istream& s, mat3& m) {
  853.     mat3    m_tmp;
  854.     s >> m_tmp[VX] >> m_tmp[VY] >> m_tmp[VZ];
  855.     if (s)
  856.     m = m_tmp;
  857.     return s;
  858. }
  859. */
  860. void swap(mat3 &a, mat3 &b)
  861.     mat3 tmp(a); 
  862.     a = b; 
  863.     b = tmp; 
  864. }
  865. void mat3::print(FILE *file, const char *name) const 
  866. {
  867.     int i, j;
  868.     fprintf( stderr, "%s:n", name );
  869.     for( i = 0; i < 3; i++ )
  870.     {
  871.         fprintf( stderr, "   " );
  872.         for( j = 0; j < 3; j++ )
  873.         {
  874.             fprintf( stderr, "%f  ", v[i][j] );
  875.         }
  876.         fprintf( stderr, "n" );
  877.     }
  878. }
  879. /****************************************************************
  880.  *                                                              *
  881.  *          mat4 member functions                               *
  882.  *                                                              *
  883.  ****************************************************************/
  884. // CONSTRUCTORS
  885. mat4::mat4() 
  886.     *this = identity3D();
  887. }
  888. mat4::mat4(const vec4& v0, const vec4& v1, const vec4& v2, const vec4& v3)
  889.     v[0] = v0; 
  890.     v[1] = v1; 
  891.     v[2] = v2; 
  892.     v[3] = v3; 
  893. }
  894. mat4::mat4(const mat4 &m)
  895.     v[0] = m.v[0]; 
  896.     v[1] = m.v[1]; 
  897.     v[2] = m.v[2]; 
  898.     v[3] = m.v[3]; 
  899. }
  900. mat4::mat4(
  901.      float a00, float a01, float a02, float a03,
  902.      float a10, float a11, float a12, float a13,
  903.      float a20, float a21, float a22, float a23,
  904.      float a30, float a31, float a32, float a33 )
  905. {
  906.   v[0][0] = a00;  v[0][1] = a01;  v[0][2] = a02;  v[0][3] = a03;
  907.   v[1][0] = a10;  v[1][1] = a11;  v[1][2] = a12;  v[1][3] = a13;
  908.   v[2][0] = a20;  v[2][1] = a21;  v[2][2] = a22;  v[2][3] = a23;
  909.   v[3][0] = a30;  v[3][1] = a31;  v[3][2] = a32;  v[3][3] = a33;
  910. }
  911. // ASSIGNMENT OPERATORS
  912. mat4 &mat4::operator=(const mat4 &m)
  913.     v[0] = m.v[0]; 
  914.     v[1] = m.v[1]; 
  915.     v[2] = m.v[2]; 
  916.     v[3] = m.v[3];
  917.     return *this; 
  918. }
  919. mat4 &mat4::operator+=(const mat4 &m)
  920.     v[0] += m.v[0]; 
  921.     v[1] += m.v[1]; 
  922.     v[2] += m.v[2]; 
  923.     v[3] += m.v[3];
  924.     return *this; 
  925. }
  926. mat4 &mat4::operator-=(const mat4 &m)
  927.     v[0] -= m.v[0]; 
  928.     v[1] -= m.v[1]; 
  929.     v[2] -= m.v[2]; 
  930.     v[3] -= m.v[3];
  931.     return *this; 
  932. }
  933. mat4 &mat4::operator*=(float d)
  934.     v[0] *= d; 
  935.     v[1] *= d; 
  936.     v[2] *= d; 
  937.     v[3] *= d; 
  938.     return *this; 
  939. }
  940. mat4 &mat4::operator/=(float d)
  941.     v[0] /= d; 
  942.     v[1] /= d; 
  943.     v[2] /= d; 
  944.     v[3] /= d; 
  945.     return *this; 
  946. }
  947. vec4 &mat4::operator[](int i) 
  948. {
  949.     if (i < VX || i > VW)
  950.         //VEC_ERROR("mat4 [] operator: illegal access; index = " << i << 'n')
  951.         VEC_ERROR("mat4 [] operator: illegal access" );
  952.     return v[i];
  953. }
  954. const vec4 &mat4::operator[](int i) const
  955. {
  956.     if (i < VX || i > VW)
  957.         //VEC_ERROR("mat4 [] operator: illegal access; index = " << i << 'n')
  958.         VEC_ERROR("mat4 [] operator: illegal access" );
  959.     return v[i];
  960. }
  961. // SPECIAL FUNCTIONS;
  962. mat4 mat4::transpose() const  
  963. {
  964.     return mat4(
  965.         vec4(v[0][0], v[1][0], v[2][0], v[3][0]),
  966.         vec4(v[0][1], v[1][1], v[2][1], v[3][1]),
  967.         vec4(v[0][2], v[1][2], v[2][2], v[3][2]),
  968.         vec4(v[0][3], v[1][3], v[2][3], v[3][3]));
  969. }
  970. mat4 mat4::inverse() const       // Gauss-Jordan elimination with partial pivoting
  971. {
  972.     mat4 a(*this);          // As a evolves from original mat into identity
  973.     mat4 b(identity3D());   // b evolves from identity into inverse(a)
  974.     int i, j, i1;
  975.     // Loop over cols of a from left to right, eliminating above and below diag
  976.     for (j=0; j<4; j++)    // Find largest pivot in column j among rows j..3
  977.     {
  978.         i1 = j;         // Row with largest pivot candidate
  979.         for (i=j+1; i<4; i++)
  980.             if (fabs(a.v[i].n[j]) > fabs(a.v[i1].n[j]))
  981.                 i1 = i;
  982.         // Swap rows i1 and j in a and b to put pivot on diagonal
  983.         swap(a.v[i1], a.v[j]);
  984.         swap(b.v[i1], b.v[j]);
  985.         // Scale row j to have a unit diagonal
  986.         if (a.v[j].n[j]==0.)
  987.             VEC_ERROR("mat4::inverse: singular matrix; can't invertn");
  988.         b.v[j] /= a.v[j].n[j];
  989.         a.v[j] /= a.v[j].n[j];
  990.         // Eliminate off-diagonal elems in col j of a, doing identical ops to b
  991.         for (i=0; i<4; i++)
  992.             if (i!=j) 
  993.             {
  994.                 b.v[i] -= a.v[i].n[j]*b.v[j];
  995.                 a.v[i] -= a.v[i].n[j]*a.v[j];
  996.             }
  997.     }
  998.     return b;
  999. }
  1000. mat4 &mat4::apply(V_FCT_PTR fct)
  1001.     v[VX].apply(fct); 
  1002.     v[VY].apply(fct); 
  1003.     v[VZ].apply(fct); 
  1004.     v[VW].apply(fct);
  1005.     return *this; 
  1006. }
  1007. void mat4::print(FILE *file, const char *name) const 
  1008. {
  1009.     int i, j;
  1010.     fprintf( stderr, "%s:n", name );
  1011.     for( i = 0; i < 4; i++ )
  1012.     {
  1013.         fprintf( stderr, "   " );
  1014.         for( j = 0; j < 4; j++ )
  1015.         {
  1016.             fprintf( stderr, "%f  ", v[i][j] );
  1017.         }
  1018.         fprintf( stderr, "n" );
  1019.     }
  1020. }
  1021. void mat4::swap_rows(int i, int j)
  1022. {
  1023.     vec4 t;
  1024.     t    = v[i];
  1025.     v[i] = v[j];
  1026.     v[j] = t;
  1027. }
  1028. void mat4::swap_cols(int i, int j)
  1029. {
  1030.     float t;
  1031.     int k;
  1032.     for (k=0; k<4; k++) 
  1033.     {
  1034.         t       = v[k][i];
  1035.         v[k][i] = v[k][j];
  1036.         v[k][j] = t;
  1037.     }
  1038. }
  1039. // FRIENDS
  1040. mat4 operator-(const mat4 &a)
  1041.     return mat4(-a.v[0],-a.v[1],-a.v[2],-a.v[3]); 
  1042. }
  1043. mat4 operator+(const mat4 &a, const mat4 &b)
  1044.     return mat4(
  1045.         a.v[0] + b.v[0], 
  1046.         a.v[1] + b.v[1], 
  1047.         a.v[2] + b.v[2],
  1048.         a.v[3] + b.v[3]);
  1049. }
  1050. mat4 operator-(const mat4 &a, const mat4 &b)
  1051.     return mat4(
  1052.         a.v[0] - b.v[0], 
  1053.         a.v[1] - b.v[1], 
  1054.         a.v[2] - b.v[2], 
  1055.         a.v[3] - b.v[3]); 
  1056. }
  1057. mat4 operator*(const mat4 &a, const mat4 &b) 
  1058. {
  1059.     #define ROWCOL(i, j) 
  1060.         a.v[i].n[0]*b.v[0][j] + 
  1061.         a.v[i].n[1]*b.v[1][j] + 
  1062.         a.v[i].n[2]*b.v[2][j] + 
  1063.         a.v[i].n[3]*b.v[3][j]
  1064.     
  1065.     return mat4(
  1066.         vec4(ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2), ROWCOL(0,3)),
  1067.         vec4(ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2), ROWCOL(1,3)),
  1068.         vec4(ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2), ROWCOL(2,3)),
  1069.         vec4(ROWCOL(3,0), ROWCOL(3,1), ROWCOL(3,2), ROWCOL(3,3))
  1070.         );
  1071.     #undef ROWCOL
  1072. }
  1073. mat4 operator*(const mat4 &a, float d)
  1074.     return mat4(a.v[0]*d, a.v[1]*d, a.v[2]*d, a.v[3]*d); 
  1075. }
  1076. mat4 operator*(float d, const mat4 &a)
  1077.     return a*d; 
  1078. }
  1079. mat4 operator/(const mat4 &a, float d)
  1080.     return mat4(a.v[0]/d, a.v[1]/d, a.v[2]/d, a.v[3]/d); 
  1081. }
  1082. int operator==(const mat4 &a, const mat4 &b)
  1083.     return
  1084.         (a.v[0] == b.v[0]) && 
  1085.         (a.v[1] == b.v[1]) && 
  1086.         (a.v[2] == b.v[2]) &&
  1087.         (a.v[3] == b.v[3]); 
  1088. }
  1089. int operator!=(const mat4 &a, const mat4 &b)
  1090.     return !(a == b); 
  1091. }
  1092. /*ostream& operator << (ostream& s, mat4& m)
  1093. { return s << m.v[VX] << 'n' << m.v[VY] << 'n' << m.v[VZ] << 'n' << m.v[VW]; }
  1094. istream& operator >> (istream& s, mat4& m)
  1095. {
  1096.     mat4    m_tmp;
  1097.     s >> m_tmp[VX] >> m_tmp[VY] >> m_tmp[VZ] >> m_tmp[VW];
  1098.     if (s)
  1099.     m = m_tmp;
  1100.     return s;
  1101. }
  1102. */
  1103. void swap(mat4 &a, mat4 &b)
  1104.     mat4 tmp(a); 
  1105.     a = b; 
  1106.     b = tmp; 
  1107. }
  1108. /****************************************************************
  1109.  *                                                              *
  1110.  *         2D functions and 3D functions                        *
  1111.  *                                                              *
  1112.  ****************************************************************/
  1113. mat3 identity2D()
  1114. {   
  1115.     return mat3(
  1116.         vec3(1.0, 0.0, 0.0),
  1117.         vec3(0.0, 1.0, 0.0),
  1118.         vec3(0.0, 0.0, 1.0)); 
  1119. }
  1120. mat3 translation2D(const vec2 &v)
  1121. {   
  1122.     return mat3(
  1123.         vec3(1.0, 0.0, v[VX]),
  1124.         vec3(0.0, 1.0, v[VY]),
  1125.         vec3(0.0, 0.0, 1.0)); 
  1126. }
  1127. mat3 rotation2D(const vec2 &Center, float angleDeg) 
  1128. {
  1129.     float angleRad = (float) (angleDeg * M_PI / 180.0);
  1130.     float c = (float) cos(angleRad);
  1131.     float s = (float) sin(angleRad);
  1132.     return mat3(
  1133.         vec3(c,    -s, Center[VX] * (1.0f-c) + Center[VY] * s),
  1134.         vec3(s,     c, Center[VY] * (1.0f-c) - Center[VX] * s),
  1135.         vec3(0.0, 0.0, 1.0));
  1136. }
  1137. mat3 scaling2D(const vec2 &scaleVector)
  1138. {   
  1139.     return mat3(
  1140.         vec3(scaleVector[VX], 0.0, 0.0),
  1141.         vec3(0.0, scaleVector[VY], 0.0),
  1142.         vec3(0.0, 0.0, 1.0)); 
  1143. }
  1144. mat4 identity3D()
  1145. {   
  1146.     return mat4(
  1147.         vec4(1.0, 0.0, 0.0, 0.0),
  1148.         vec4(0.0, 1.0, 0.0, 0.0),
  1149.         vec4(0.0, 0.0, 1.0, 0.0),
  1150.         vec4(0.0, 0.0, 0.0, 1.0)); 
  1151. }
  1152. mat4 translation3D(const vec3 &v)
  1153. {   
  1154.     return mat4(
  1155.         vec4(1.0, 0.0, 0.0, v[VX]),
  1156.         vec4(0.0, 1.0, 0.0, v[VY]),
  1157.         vec4(0.0, 0.0, 1.0, v[VZ]),
  1158.         vec4(0.0, 0.0, 0.0, 1.0)); 
  1159. }
  1160. mat4 rotation3D(const vec3 &Axis, float angleDeg) 
  1161. {
  1162.     float angleRad = (float) (angleDeg * M_PI / 180.0);
  1163.     float c = (float) cos(angleRad);
  1164.     float s = (float) sin(angleRad);
  1165.     float t = 1.0f - c;
  1166.     vec3 axis(Axis);
  1167.     axis.normalize();
  1168.     return mat4(
  1169.         vec4(t * axis[VX] * axis[VX] + c,
  1170.              t * axis[VX] * axis[VY] - s * axis[VZ],
  1171.              t * axis[VX] * axis[VZ] + s * axis[VY],
  1172.              0.0),
  1173.         vec4(t * axis[VX] * axis[VY] + s * axis[VZ],
  1174.              t * axis[VY] * axis[VY] + c,
  1175.              t * axis[VY] * axis[VZ] - s * axis[VX],
  1176.              0.0),
  1177.         vec4(t * axis[VX] * axis[VZ] - s * axis[VY],
  1178.              t * axis[VY] * axis[VZ] + s * axis[VX],
  1179.              t * axis[VZ] * axis[VZ] + c,
  1180.              0.0),
  1181.         vec4(0.0, 0.0, 0.0, 1.0));
  1182. }
  1183. mat4 rotation3Drad(const vec3 &Axis, float angleRad) 
  1184. {
  1185.     float c = (float) cos(angleRad);
  1186.     float s = (float) sin(angleRad);
  1187.     float t = 1.0f - c;
  1188.     vec3 axis(Axis);
  1189.     axis.normalize();
  1190.     return mat4(
  1191.         vec4(t * axis[VX] * axis[VX] + c,
  1192.              t * axis[VX] * axis[VY] - s * axis[VZ],
  1193.              t * axis[VX] * axis[VZ] + s * axis[VY],
  1194.              0.0),
  1195.         vec4(t * axis[VX] * axis[VY] + s * axis[VZ],
  1196.              t * axis[VY] * axis[VY] + c,
  1197.              t * axis[VY] * axis[VZ] - s * axis[VX],
  1198.              0.0),
  1199.         vec4(t * axis[VX] * axis[VZ] - s * axis[VY],
  1200.              t * axis[VY] * axis[VZ] + s * axis[VX],
  1201.              t * axis[VZ] * axis[VZ] + c,
  1202.              0.0),
  1203.         vec4(0.0, 0.0, 0.0, 1.0));
  1204. }
  1205. mat4 scaling3D(const vec3 &scaleVector)
  1206. {   
  1207.     return mat4(
  1208.         vec4(scaleVector[VX], 0.0, 0.0, 0.0),
  1209.         vec4(0.0, scaleVector[VY], 0.0, 0.0),
  1210.         vec4(0.0, 0.0, scaleVector[VZ], 0.0),
  1211.         vec4(0.0, 0.0, 0.0, 1.0)); 
  1212. }
  1213. mat4 perspective3D(float d)
  1214. {   
  1215.     return mat4(
  1216.         vec4(1.0f, 0.0f, 0.0f,   0.0f),
  1217.         vec4(0.0f, 1.0f, 0.0f,   0.0f),
  1218.         vec4(0.0f, 0.0f, 1.0f,   0.0f),
  1219.         vec4(0.0f, 0.0f, 1.0f/d, 0.0f)); 
  1220. }