Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Extras / glui / algebra3.h
1 /*
2
3   algebra3.cpp, algebra3.h -  C++ Vector and Matrix Algebra routines
4
5   GLUI User Interface Toolkit (LGPL)
6   Copyright (c) 1998 Paul Rademacher
7
8   WWW:    http://sourceforge.net/projects/glui/
9   Forums: http://sourceforge.net/forum/?group_id=92496
10
11   This library is free software; you can redistribute it and/or
12   modify it under the terms of the GNU Lesser General Public
13   License as published by the Free Software Foundation; either
14   version 2.1 of the License, or (at your option) any later version.
15
16   This library is distributed in the hope that it will be useful,
17   but WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19   Lesser General Public License for more details.
20
21   You should have received a copy of the GNU Lesser General Public
22   License along with this library; if not, write to the Free Software
23   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
25 */
26
27 /**************************************************************************
28     
29   There are three vector classes and two matrix classes: vec2, vec3,
30   vec4, mat3, and mat4.
31
32   All the standard arithmetic operations are defined, with '*'
33   for dot product of two vectors and multiplication of two matrices,
34   and '^' for cross product of two vectors.
35
36   Additional functions include length(), normalize(), homogenize for
37   vectors, and print(), set(), apply() for all classes.
38
39   There is a function transpose() for matrices, but note that it 
40   does not actually change the matrix, 
41
42   When multiplied with a matrix, a vector is treated as a row vector
43   if it precedes the matrix (v*M), and as a column vector if it
44   follows the matrix (M*v).
45
46   Matrices are stored in row-major form.
47
48   A vector of one dimension (2d, 3d, or 4d) can be cast to a vector
49   of a higher or lower dimension.  If casting to a higher dimension,
50   the new component is set by default to 1.0, unless a value is
51   specified:
52      vec3 a(1.0, 2.0, 3.0 );
53      vec4 b( a, 4.0 );       // now b == {1.0, 2.0, 3.0, 4.0};
54   When casting to a lower dimension, the vector is homogenized in
55   the lower dimension.  E.g., if a 4d {X,Y,Z,W} is cast to 3d, the
56   resulting vector is {X/W, Y/W, Z/W}.  It is up to the user to 
57   insure the fourth component is not zero before casting.
58
59   There are also the following function for building matrices:
60      identity2D(), translation2D(), rotation2D(),
61      scaling2D(),  identity3D(),    translation3D(),
62      rotation3D(), rotation3Drad(),  scaling3D(),
63      perspective3D()
64
65   NOTE: When compiling for Windows, include this file first, to avoid
66         certain name conflicts
67  
68   ---------------------------------------------------------------------
69   
70   Author: Jean-Francois DOUEg                   
71   Revised: Paul Rademacher                                      
72   Version 3.2 - Feb 1998
73   Revised: Nigel Stewart (GLUI Code Cleaning)
74   
75 **************************************************************************/
76
77 #ifndef GLUI_ALGEBRA3_H
78 #define GLUI_ALGEBRA3_H
79
80 #include <cmath>
81 #include <cstdio>
82 #include <cstdlib>
83
84 // this line defines a new type: pointer to a function which returns a
85 // float and takes as argument a float
86 typedef float (*V_FCT_PTR)(float);
87
88 class vec2;
89 class vec3;
90 class vec4;
91 class mat3;
92 class mat4;
93
94 #ifndef M_PI
95 #define M_PI 3.141592654
96 #endif
97
98 enum {VX, VY, VZ, VW};           // axes
99 enum {PA, PB, PC, PD};           // planes
100 enum {RED, GREEN, BLUE, ALPHA};  // colors
101 enum {KA, KD, KS, ES};           // phong coefficients
102
103 /****************************************************************
104  *                                                              *
105  *              2D Vector                                       *
106  *                                                              *
107  ****************************************************************/
108
109 class vec2
110 {
111   friend class vec3;
112
113 protected:
114
115   float n[2];
116
117 public:
118
119   // Constructors
120
121   vec2();
122   vec2(float x, float y);
123   vec2(const vec2 &v);                   // copy constructor
124   vec2(const vec3 &v);                   // cast v3 to v2
125   vec2(const vec3 &v, int dropAxis);     // cast v3 to v2
126
127   // Assignment operators
128
129   vec2  &operator  = (const vec2 &v);    // assignment of a vec2
130   vec2  &operator += (const vec2 &v);    // incrementation by a vec2
131   vec2  &operator -= (const vec2 &v);    // decrementation by a vec2
132   vec2  &operator *= (float d);    // multiplication by a constant
133   vec2  &operator /= (float d);    // division by a constant
134
135   // special functions
136
137   float  length()  const;                   // length of a vec2
138   float  length2() const;                   // squared length of a vec2
139   vec2  &normalize();                       // normalize a vec2
140   vec2  &apply(V_FCT_PTR fct);              // apply a func. to each component
141   void   set(float x, float y);             // set vector
142
143   float &operator [] (int i);         // indexing
144   const float &operator [] (int i) const;   // indexing
145
146   // friends
147
148   friend vec2  operator -  (const vec2 &v);                   // -v1
149   friend vec2  operator +  (const vec2 &a, const vec2 &b);    // v1 + v2
150   friend vec2  operator -  (const vec2 &a, const vec2 &b);    // v1 - v2
151   friend vec2  operator *  (const vec2 &a, float d);          // v1 * 3.0
152   friend vec2  operator *  (float d, const vec2 &a);          // 3.0 * v1
153   friend vec2  operator *  (const mat3 &a, const vec2 &v);    // M . v
154   friend vec2  operator *  (const vec2 &v, const mat3 &a);    // v . M
155   friend float operator *  (const vec2 &a, const vec2 &b);    // dot product
156   friend vec2  operator /  (const vec2 &a, float d);          // v1 / 3.0
157   friend vec3  operator ^  (const vec2 &a, const vec2 &b);    // cross product
158   friend int   operator == (const vec2 &a, const vec2 &b);    // v1 == v2 ?
159   friend int   operator != (const vec2 &a, const vec2 &b);    // v1 != v2 ?
160   //friend ostream& operator << (ostream& s, vec2& v);        // output to stream
161   //friend istream& operator >> (istream& s, vec2& v);        // input from strm.
162   friend void swap(vec2 &a, vec2 &b);                         // swap v1 & v2
163   friend vec2 min_vec(const vec2 &a, const vec2 &b);          // min(v1, v2)
164   friend vec2 max_vec(const vec2 &a, const vec2 &b);          // max(v1, v2)
165   friend vec2 prod   (const vec2 &a, const vec2 &b);          // term by term *
166 };
167
168 /****************************************************************
169  *                                                              *
170  *               3D Vector                                      *
171  *                                                              *
172  ****************************************************************/
173
174 class vec3
175 {
176   friend class vec2;
177   friend class vec4;
178   friend class mat3;
179
180 protected:
181
182   float n[3];
183
184 public:
185
186   // Constructors
187
188   vec3();
189   vec3(float x, float y, float z);
190   vec3(const vec3 &v);               // copy constructor
191   vec3(const vec2 &v);               // cast v2 to v3
192   vec3(const vec2 &v, float d);      // cast v2 to v3
193   vec3(const vec4 &v);               // cast v4 to v3
194   vec3(const vec4 &v, int dropAxis); // cast v4 to v3
195
196   // Assignment operators
197
198   vec3  &operator  = (const vec3 &v);      // assignment of a vec3
199   vec3  &operator += (const vec3 &v);      // incrementation by a vec3
200   vec3  &operator -= (const vec3 &v);      // decrementation by a vec3
201   vec3  &operator *= (float d);      // multiplication by a constant
202   vec3  &operator /= (float d);      // division by a constant
203
204   // special functions
205
206   float  length()  const;                     // length of a vec3
207   float  length2() const;                     // squared length of a vec3
208   vec3&  normalize();                         // normalize a vec3
209   vec3&  homogenize();                        // homogenize (div by Z)
210   vec3&  apply(V_FCT_PTR fct);                // apply a func. to each component
211   void   set(float x, float y, float z);      // set vector
212
213   void   print(FILE *file, const char *name) const; // print vector to a file
214
215
216   float &operator [] (int i);       // indexing
217   const float &operator [] (int i) const; // indexing
218
219   // friends
220
221   friend vec3  operator -  (const vec3 &v);                 // -v1
222   friend vec3  operator +  (const vec3 &a, const vec3 &b);  // v1 + v2
223   friend vec3  operator -  (const vec3 &a, const vec3 &b);  // v1 - v2
224   friend vec3  operator *  (const vec3 &a, float d);        // v1 * 3.0
225   friend vec3  operator *  (float d, const vec3 &a);        // 3.0 * v1
226   friend vec3  operator *  (const mat4 &a, const vec3 &v);  // M . v
227   friend vec3  operator *  (const vec3 &v, const mat4 &a);  // v . M
228   friend float operator *  (const vec3 &a, const vec3 &b);  // dot product
229   friend vec3  operator /  (const vec3 &a, float d);  // v1 / 3.0
230   friend vec3  operator ^  (const vec3 &a, const vec3 &b);  // cross product
231   friend int   operator == (const vec3 &a, const vec3 &b);  // v1 == v2 ?
232   friend int   operator != (const vec3 &a, const vec3 &b);  // v1 != v2 ?
233   //friend ostream& operator << (ostream& s, vec3& v);      // output to stream
234   //friend istream& operator >> (istream& s, vec3& v);      // input from strm.
235   friend void swap(vec3 &a, vec3 &b);                       // swap v1 & v2
236   friend vec3 min_vec(const vec3 &a, const vec3 &b);        // min(v1, v2)
237   friend vec3 max_vec(const vec3 &a, const vec3 &b);        // max(v1, v2)
238   friend vec3 prod(const vec3 &a, const vec3 &b);           // term by term *
239
240   // necessary friend declarations
241
242   friend vec2 operator * (const mat3 &a, const vec2 &v);    // linear transform
243   friend vec3 operator * (const mat3 &a, const vec3 &v);    // linear transform
244   friend mat3 operator * (const mat3 &a, const mat3 &b);    // matrix 3 product
245 };
246
247 /****************************************************************
248  *                                                              *
249  *              4D Vector                                       *
250  *                                                              *
251  ****************************************************************/
252
253 class vec4
254 {
255   friend class vec3;
256   friend class mat4;
257
258 protected:
259
260   float n[4];
261
262 public:
263
264   // Constructors
265
266   vec4();
267   vec4(float x, float y, float z, float w);
268   vec4(const vec4 &v);             // copy constructor
269   vec4(const vec3 &v);             // cast vec3 to vec4
270   vec4(const vec3 &v, float d);    // cast vec3 to vec4
271
272   // Assignment operators
273
274   vec4  &operator  = (const vec4 &v);    // assignment of a vec4
275   vec4  &operator += (const vec4 &v);    // incrementation by a vec4
276   vec4  &operator -= (const vec4 &v);    // decrementation by a vec4
277   vec4  &operator *= (float d);    // multiplication by a constant
278   vec4  &operator /= (float d);    // division by a constant
279
280   // special functions
281
282   float  length()  const;                     // length of a vec4
283   float  length2() const;                     // squared length of a vec4
284   vec4  &normalize();                         // normalize a vec4
285   vec4  &apply(V_FCT_PTR fct);                // apply a func. to each component
286   vec4  &homogenize();
287
288   void   print(FILE *file, const char *name) const; // print vector to a file
289
290   void   set(float x, float y, float z, float a);                        
291
292   float &operator [] (int i);             // indexing
293   const float &operator [] (int i) const; // indexing
294
295   // friends
296
297   friend vec4  operator -  (const vec4 &v);                  // -v1
298   friend vec4  operator +  (const vec4 &a, const vec4 &b);   // v1 + v2
299   friend vec4  operator -  (const vec4 &a, const vec4 &b);   // v1 - v2
300   friend vec4  operator *  (const vec4 &a, float d);         // v1 * 3.0
301   friend vec4  operator *  (float d, const vec4 &a);         // 3.0 * v1
302   friend vec4  operator *  (const mat4 &a, const vec4 &v);   // M . v
303   friend vec4  operator *  (const vec4 &v, const mat4 &a);   // v . M
304   friend float operator *  (const vec4 &a, const vec4 &b);   // dot product
305   friend vec4  operator /  (const vec4 &a, float d);   // v1 / 3.0
306   friend int   operator == (const vec4 &a, const vec4 &b);   // v1 == v2 ?
307   friend int   operator != (const vec4 &a, const vec4 &b);   // v1 != v2 ?
308   //friend ostream& operator << (ostream& s, vec4& v);       // output to stream
309   //friend istream& operator >> (istream& s, vec4& v);       // input from strm.
310   friend void swap(vec4 &a, vec4 &b);                        // swap v1 & v2
311   friend vec4 min_vec(const vec4 &a, const vec4 &b);         // min(v1, v2)
312   friend vec4 max_vec(const vec4 &a, const vec4 &b);         // max(v1, v2)
313   friend vec4 prod   (const vec4 &a, const vec4 &b);         // term by term *
314
315   // necessary friend declarations
316
317   friend vec3 operator * (const mat4 &a, const vec3 &v);     // linear transform
318   friend mat4 operator * (const mat4 &a, const mat4 &b);     // matrix 4 product
319 };
320
321 /****************************************************************
322  *                                                              *
323  *             3x3 Matrix                                       *
324  *                                                              *
325  ****************************************************************/
326
327 class mat3
328 {
329 protected:
330
331   vec3 v[3];
332
333 public:
334
335   // Constructors
336
337   mat3();
338   mat3(const vec3 &v0, const vec3 &v1, const vec3 &v2);
339   mat3(const mat3 &m);
340
341   // Assignment operators
342
343   mat3 &operator  = (const mat3  &m);        // assignment of a mat3
344   mat3 &operator += (const mat3  &m);        // incrementation by a mat3
345   mat3 &operator -= (const mat3  &m);        // decrementation by a mat3
346   mat3 &operator *= (float  d);        // multiplication by a constant
347   mat3 &operator /= (float  d);        // division by a constant
348
349   // special functions
350
351   mat3  transpose() const;                    // transpose
352   mat3  inverse() const;                      // inverse
353   mat3 &apply(V_FCT_PTR fct);                 // apply a func. to each element
354
355   void  print(FILE *file, const char *name ) const; // print matrix to a file
356
357   void  set(const vec3 &v0, const vec3 &v1, const vec3 &v2);
358
359   vec3 &operator [] (int i);       // indexing
360   const vec3 &operator [] (int i) const; // indexing
361
362   // friends
363
364   friend mat3 operator -  (const mat3 &a);                     // -m1
365   friend mat3 operator +  (const mat3 &a, const mat3 &b);      // m1 + m2
366   friend mat3 operator -  (const mat3 &a, const mat3 &b);      // m1 - m2
367   friend mat3 operator *  (const mat3 &a, const mat3 &b);      // m1 * m2
368   friend mat3 operator *  (const mat3 &a, float d);            // m1 * 3.0
369   friend mat3 operator *  (float d, const mat3 &a);            // 3.0 * m1
370   friend mat3 operator /  (const mat3 &a, float d);            // m1 / 3.0
371   friend int  operator == (const mat3 &a, const mat3 &b);      // m1 == m2 ?
372   friend int  operator != (const mat3 &a, const mat3 &b);      // m1 != m2 ?
373   //friend ostream& operator << (ostream& s, mat3& m);         // output to stream
374   //friend istream& operator >> (istream& s, mat3& m);         // input from strm.
375   friend void swap(mat3 &a, mat3 &b);                          // swap m1 & m2
376
377   // necessary friend declarations
378
379   friend vec3 operator * (const mat3 &a, const vec3 &v);     // linear transform
380   friend vec2 operator * (const mat3 &a, const vec2 &v);     // linear transform
381 };
382
383 /****************************************************************
384  *                                                              *
385  *             4x4 Matrix                                       *
386  *                                                              *
387  ****************************************************************/
388
389 class mat4
390 {
391 protected:
392
393   vec4 v[4];
394
395 public:
396
397   // Constructors
398
399   mat4();
400   mat4(const vec4 &v0, const vec4 &v1, const vec4 &v2, const vec4 &v3);
401   mat4(const mat4 &m);
402   mat4(float a00, float a01, float a02, float a03,
403        float a10, float a11, float a12, float a13,
404        float a20, float a21, float a22, float a23,
405        float a30, float a31, float a32, float a33 );
406
407
408   // Assignment operators
409
410   mat4 &operator  = (const mat4 &m);        // assignment of a mat4
411   mat4 &operator += (const mat4 &m);        // incrementation by a mat4
412   mat4 &operator -= (const mat4 &m);        // decrementation by a mat4
413   mat4 &operator *= (float d);        // multiplication by a constant
414   mat4 &operator /= (float d);        // division by a constant
415
416   // special functions
417
418   mat4  transpose() const;                   // transpose
419   mat4  inverse() const;                     // inverse
420   mat4 &apply(V_FCT_PTR fct);                // apply a func. to each element
421
422   void  print(FILE *file, const char *name) const; // print matrix to a file
423     
424   vec4 &operator [] (int i);       // indexing
425   const vec4 &operator [] (int i) const; // indexing
426
427   void  swap_rows(int i, int j); // swap rows i and j
428   void  swap_cols(int i, int j); // swap cols i and j
429
430   // friends
431
432   friend mat4 operator -  (const mat4 &a);                     // -m1
433   friend mat4 operator +  (const mat4 &a, const mat4 &b);      // m1 + m2
434   friend mat4 operator -  (const mat4 &a, const mat4 &b);      // m1 - m2
435   friend mat4 operator *  (const mat4 &a, const mat4 &b);      // m1 * m2
436   friend mat4 operator *  (const mat4 &a, float d);            // m1 * 4.0
437   friend mat4 operator *  (float d, const mat4 &a);            // 4.0 * m1
438   friend mat4 operator /  (const mat4 &a, float d);            // m1 / 3.0
439   friend int  operator == (const mat4 &a, const mat4 &b);      // m1 == m2 ?
440   friend int  operator != (const mat4 &a, const mat4 &b);      // m1 != m2 ?
441   //friend ostream& operator << (ostream& s, mat4& m);         // output to stream
442   //friend istream& operator >> (istream& s, mat4& m);         // input from strm.
443   friend void swap(mat4 &a, mat4 &b);                          // swap m1 & m2
444
445   // necessary friend declarations
446
447   friend vec4 operator * (const mat4 &a, const vec4 &v);      // linear transform
448   //friend vec4 operator * (const vec4& v, const mat4& a);    // linear transform
449   friend vec3 operator * (const mat4 &a, const vec3 &v);      // linear transform
450   friend vec3 operator * (const vec3 &v, const mat4 &a);      // linear transform
451 };
452
453 /****************************************************************
454  *                                                              *
455  *         2D functions and 3D functions                        *
456  *                                                              *
457  ****************************************************************/
458
459 mat3 identity2D   ();                                   // identity 2D
460 mat3 translation2D(const vec2 &v);                      // translation 2D
461 mat3 rotation2D   (const vec2 &Center, float angleDeg); // rotation 2D
462 mat3 scaling2D    (const vec2 &scaleVector);            // scaling 2D
463 mat4 identity3D   ();                                   // identity 3D
464 mat4 translation3D(const vec3 &v);                      // translation 3D
465 mat4 rotation3D   (const vec3 &Axis, float angleDeg);   // rotation 3D
466 mat4 rotation3Drad(const vec3 &Axis, float angleRad);   // rotation 3D
467 mat4 scaling3D    (const vec3 &scaleVector);            // scaling 3D
468 mat4 perspective3D(float d);                            // perspective 3D
469
470 vec3 operator * (const vec3 &v, const mat3 &a);
471 vec2 operator * (const vec2 &v, const mat3 &a);
472 vec3 operator * (const vec3 &v, const mat4 &a);
473 vec4 operator * (const vec4 &v, const mat4 &a);
474
475 #endif