root/juggler/tags/1.0.5/Math/vjMatrix.h

Revision 7539, 15.2 kB (checked in by anonymous, 7 years ago)

This commit was manufactured by cvs2svn to create tag
'RELENG_1_0_5_RELEASE'.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*************** <auto-copyright.pl BEGIN do not edit this line> **************
2  *
3  * VR Juggler is (C) Copyright 1998, 1999, 2000 by Iowa State University
4  *
5  * Original Authors:
6  *   Allen Bierbaum, Christopher Just,
7  *   Patrick Hartling, Kevin Meinert,
8  *   Carolina Cruz-Neira, Albert Baker
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public
21  * License along with this library; if not, write to the
22  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23  * Boston, MA 02111-1307, USA.
24  *
25  * -----------------------------------------------------------------
26  * File:          $RCSfile$
27  * Date modified: $Date$
28  * Version:       $Revision$
29  * -----------------------------------------------------------------
30  *
31  *************** <auto-copyright.pl END do not edit this line> ***************/
32
33
34 #ifndef _VJ_MATRIX_
35 #define _VJ_MATRIX_
36 //#pragma once
37
38 #include <vjConfig.h>
39 #include <math.h>
40 #include <string.h>
41
42 class vjQuat;
43 class vjVec3;
44 class vjCoord;
45
46
47 //-----------------------------------------------------------------------------
48 //: vjMatrix: 4x4 Matrix class (OpenGL ordering)
49 //
50 // C/C++ uses matrices in row major order.  In other words the access
51 // indices look like: <br>
52 // (0,0) (0,1) (0,2) (0,3)   <=== Array      <br>
53 // (1,0) (1,1) (1,2) (1,3)   <=== Array      <br>
54 // (2,0) (2,1) (2,2) (2,3)   <=== Array      <br>
55 // (3,0) (3,1) (3,2) (3,3)   <=== Array      <br>
56 // <br>
57 // OpenGL ordering specifies that the matrix has to be column major in memory,
58 // so we need to access it more like: <br>
59 //    NOTE: The given indexes are what the cells have to be called in C/C++
60 //          notation.  Since we are putting the columns into memory
61 //          back-to-back.        <br>
62 // (0,0) (1,0) (2,0) (3,0)       <br>
63 // (0,1) (1,1) (2,1) (3,1)       <br>
64 // (0,2) (1,2) (2,2) (3,2)       <br>
65 // (0,3) (1,3) (2,3) (3,3)       <br>
66 //   ^     ^     ^     ^         <br>
67 //   ====================== Arrays     <br>
68 //
69 //-----------------------------------------------------------------------------
70 //!PUBLIC_API:
71 class vjMatrix
72 {
73 public:
74    // Column major.  In other words {Column1, Column2, Column3, Column4} in memory
75    // Access element mat[column][row]
76    float mat[4][4];
77
78 public:
79    //: Default Constructor (Identity constructor)
80    vjMatrix() : mat() { makeIdent(); };
81
82    //: Constructor: Specify each element
83    vjMatrix(float a00, float a01, float a02, float a03,
84             float a10, float a11, float a12, float a13,
85             float a20, float a21, float a22, float a23,
86             float a30, float a31, float a32, float a33)
87    {
88       mat[0][0] = a00; mat[1][0] = a01; mat[2][0] = a02; mat[3][0] = a03;
89       mat[0][1] = a10; mat[1][1] = a11; mat[2][1] = a12; mat[3][1] = a13;
90       mat[0][2] = a20; mat[1][2] = a21; mat[2][2] = a22; mat[3][2] = a23;
91       mat[0][3] = a30; mat[1][3] = a31; mat[2][3] = a32; mat[3][3] = a33;
92    }
93
94    //: Build matrix from a vjCoord object
95    //! POST: mat = coord represented as a matrix
96    vjMatrix(vjCoord coord);
97
98    //: copy constructor
99    //! POST: *this = matrix
100    vjMatrix( const vjMatrix& matrix )
101    {
102       this->copy( matrix );
103    }
104
105 public:
106    //: Set from a memory region
107    //! PRE: m refers to an array of 16 floats
108    //! POST: this' = *m
109    void    set(float *m) {
110       memcpy(mat, m, sizeof(float) * 16);
111    }
112
113    //: Set matrix elementwise
114    //!POST: this' is set to pass args
115    //!ARGS: a00 - Upper left
116    //!ARGS: a33 - Lower left
117    void set(float a00, float a01, float a02, float a03,
118             float a10, float a11, float a12, float a13,
119             float a20, float a21, float a22, float a23,
120             float a30, float a31, float a32, float a33)
121    {
122       mat[0][0] = a00; mat[1][0] = a01; mat[2][0] = a02; mat[3][0] = a03;
123       mat[0][1] = a10; mat[1][1] = a11; mat[2][1] = a12; mat[3][1] = a13;
124       mat[0][2] = a20; mat[1][2] = a21; mat[2][2] = a22; mat[3][2] = a23;
125       mat[0][3] = a30; mat[1][3] = a31; mat[2][3] = a32; mat[3][3] = a33;
126    }
127
128 public:
129    //: Create Identity Matrix
130    //! POST: this' is identity
131    void makeIdent()
132    { zero(); mat[0][0] = mat[1][1] = mat[2][2] = mat[3][3] = 1.0f;}
133
134    //: Zero out the matrix
135    //! POST: this' is all zeros
136    void zero()
137    {
138       mat[0][0]=0.0f; mat[1][0]=0.0f; mat[2][0]=0.0f; mat[3][0]=0.0f;
139       mat[0][1]=0.0f; mat[1][1]=0.0f; mat[2][1]=0.0f; mat[3][1]=0.0f;
140       mat[0][2]=0.0f; mat[1][2]=0.0f; mat[2][2]=0.0f; mat[3][2]=0.0f;
141       mat[0][3]=0.0f; mat[1][3]=0.0f; mat[2][3]=0.0f; mat[3][3]=0.0f;
142    }
143
144    //: Make XYZEuler matrix
145    //!ARGS: rotX - Rotation about the x-axis
146    //!ARGS: rotY - Rotation about the y-axis
147    //!ARGS: rotZ - Rotation about the z-axis
148    //
149    //!POST: mat = rX*rY*rZ
150    void makeXYZEuler(float xRot, float yRot, float zRot);
151    void getXYZEuler(float& xRot, float& yRot, float& zRot) const;
152
153    //: Make ZYX Euler matrix
154    //!POST: mat = rZ*rY*rX
155    //!ARGS: rotZ - Rotation about the z-axis
156    //!ARGS: rotY - Rotation about the y-axis
157    //!ARGS: rotX - Rotation about the x-axis
158    void makeZYXEuler(float zRot, float yRot, float xRot);
159    void getZYXEuler(float& zRot, float& yRot, float& xRot) const;
160
161    //!POST: mat = rZ*rX*rY
162    void makeZXYEuler( float zRot, float xRot, float yRot );
163    void getZXYEuler( float& zRot, float& xRot, float& yRot ) const;
164
165    //: extract the yaw information from the matrix
166    //!POST:  returned value is from -180 to 180, where 0 is none
167    float    getYRot() const;
168    float    getYaw() const
169    { return getYRot(); }
170
171    //: extract the pitch information from the matrix
172    //!POST:  returned value is from -180 to 180, where 0 none
173    float    getXRot() const;
174    float    getPitch() const
175    {return getXRot();}
176
177    //: extract the roll information from the matrix
178    //!POST:  returned value is from -180 to 180, where 0 is no roll
179    float    getZRot() const;
180    float    getRoll() const
181    { return getZRot();}
182
183    //: constrain the matrix rotation to a certain axis or axes
184    //  Uses getTrans, getYaw, getPitch, getRoll to recreate the matrix.<BR><BR>
185    //
186    //!ARGS:  allowXRot = true to keep the x rotation info<BR>
187    //+       allowYRot = true to keep the y rotation info<BR>
188    //+       allowZRot = true to keep the z rotation info<BR>
189    //!POST:  result returned is a constrained matrix.
190    void     constrainRotAxis( const bool& allowXRot, const bool& allowYRot, const bool& allowZRot, vjMatrix& result );
191    void     _kevn_constrainRotAxis( const bool& pitch, const bool& yaw, const bool& roll, vjMatrix& result );
192
193
194
195    //: Make a matrix using direction cosines
196    //
197    //!ARGS: secXAxis - The x-axis of the secondary coord system in terms of the first
198    //+      secYAxis - The y-axis of the secondary coord system in terms of the first
199    //+      secZAxis - The z-axis of the secondary coord system in terms of the first
200    //
201    //!PRE: The axis must be normalized
202    //!POST: mat = direction cosine matrix
203    //!NOTE: Based on "Virtual Reality Sytems" pg. 26
204    //+      The matrix created is able to transform a pt in the first coord
205    //+      system to the second coord system. Ps = sMf*Pf
206    void     makeDirCos( vjVec3 secXAxis, vjVec3 secYAxis, vjVec3 secZAxis );
207
208    //: Make matrix from given quaternion
209    //!POST: mat = Matrix specified by Quaternion _quat
210    //!POST: sets every cell, no need to call makeIdent before this.
211    void     makeQuaternion( const float* const q );
212    void     makeQuaternion( const vjQuat& q );
213
214
215    //: Make rotation matrix around _axis
216    //!ARGS: _degrees - Number of degrees to rotate
217    //+      _axis - The axis to rotate around
218    void makeRot(float _degrees, vjVec3 _axis);
219
220    //: Make translation matrix
221    //!POST: mat = matrix with only the new translation
222    void makeTrans(float _x, float _y, float _z);
223    void makeTrans(const vjVec3& trans);
224
225    //: Sets given translation to current matrix
226    //!POST: mat = old(mat) with the tranlation portion set to the parameters
227    void setTrans(float _x, float _y, float _z);
228    void setTrans(const vjVec3& trans);
229
230    //: Get the translation portion of the matrix
231    //!POST: _x, _y, and _z contain the translation portion of the matrix
232    void getTrans(float& _x, float& _y, float& _z) const;
233    vjVec3 getTrans() const;
234
235    //: Make scale matrix
236    void makeScale(float _x, float _y, float _z);
237
238 //    void  makeVecRotVec(const vjVec3&  _v1, const vjVec3&  _v2)
239 // {;}
240 //    void  makeCoord(const sgCoord* _c)
241 // {;}
242
243    //: Copy matrix
244    //!POST: *this' = _m
245    void copy( const vjMatrix& _m )
246    {
247       ((mat)[0][0] = (_m)[0][0]); ((mat)[0][1] = (_m)[0][1]); ((mat)[0][2] = (_m)[0][2]); ((mat)[0][3] = (_m)[0][3]);
248       ((mat)[1][0] = (_m)[1][0]); ((mat)[1][1] = (_m)[1][1]); ((mat)[1][2] = (_m)[1][2]); ((mat)[1][3] = (_m)[1][3]);
249       ((mat)[2][0] = (_m)[2][0]); ((mat)[2][1] = (_m)[2][1]); ((mat)[2][2] = (_m)[2][2]); ((mat)[2][3] = (_m)[2][3]);
250       ((mat)[3][0] = (_m)[3][0]); ((mat)[3][1] = (_m)[3][1]); ((mat)[3][2] = (_m)[3][2]); ((mat)[3][3] = (_m)[3][3]);
251    }
252
253    //: Compare matrix for equality
254    //!RETVAL: true - this == _m
255    //!RETVAL: false - this != _m
256    bool     equal(const vjMatrix&  _m) const  {
257       return (((mat)[0][0] == (_m)[0][0]) &&
258               ((mat)[0][1] == (_m)[0][1]) &&
259               ((mat)[0][2] == (_m)[0][2]) &&
260               ((mat)[0][3] == (_m)[0][3]) &&
261               ((mat)[1][0] == (_m)[1][0]) &&
262               ((mat)[1][1] == (_m)[1][1]) &&
263               ((mat)[1][2] == (_m)[1][2]) &&
264               ((mat)[1][3] == (_m)[1][3]) &&
265               ((mat)[2][0] == (_m)[2][0]) &&
266               ((mat)[2][1] == (_m)[2][1]) &&
267               ((mat)[2][2] == (_m)[2][2]) &&
268               ((mat)[2][3] == (_m)[2][3]) &&
269               ((mat)[3][0] == (_m)[3][0]) &&
270               ((mat)[3][1] == (_m)[3][1]) &&
271               ((mat)[3][2] == (_m)[3][2]) &&
272               ((mat)[3][3] == (_m)[3][3]));
273    }
274
275    //: Clamps the values of the matrix to zero
276    //!POST: Any values in matrix < (some epsilon) are set to 0
277    void zeroClamp()
278    {
279       // Clamp values near zero.  Just for looks.
280       // Could be removed
281        for(int i=0;i<4;i++)
282           for(int j=0;j<4;j++)
283              mat[i][j] = VJ_ZERO_CLAMP(mat[i][j]);
284    }
285
286 public:
287    //: Set to the transpose of the matrix
288    //!POST: mat = transpose(_m)
289    void transpose(vjMatrix&  _m)
290    {
291       for (int i=0; i<4; i++)
292          for (int j=0; j<4; j++)
293             mat[i][j] = _m.mat[j][i];
294    }
295
296    //: Multiple 2 matrices
297    //!POST: mat = m1 * m2
298    void mult(const vjMatrix& _m1, const vjMatrix &_m2)
299    {
300       *this = _m1;       //  Set equal to param 1
301       postMult(_m2);     // Now post mult be the second param
302    }
303
304    //: Add 2 matrices
305    //!POST: mat = m1 + m2
306    void add(const vjMatrix& _m1, const vjMatrix &_m2)
307    {
308       for (int n=0;n<4;n++)
309          for (int m=0;m<4;m++)
310             mat[n][m] = (_m1.mat[n][m] + _m2.mat[n][m]);
311    }
312
313    //: Subtract a matrix
314    //!POST: mat' = m1 - m2
315    void sub(const vjMatrix& _m1, const vjMatrix &_m2)
316    {
317       for (int n=0;n<4;n++)
318          for (int m=0;m<4;m++)
319             mat[n][m] = (_m1.mat[n][m] - _m2.mat[n][m]);
320    }
321
322    //: Scale a matrix by a scalar
323    //!POST: Each element of mat' = mat * _s
324    //!NOTE: Not a 3D scale
325    void scale(float _s, const vjMatrix &_m)
326    {
327       for (int n=0;n<4;n++)
328          for (int m=0;m<4;m++)
329             mat[n][m] = (_m.mat[n][m] * _s);
330    }
331
332    //: Post multiply by a matrix
333    //!POST: mat' = mat * m
334    void postMult(const vjMatrix&  _m);
335
336    //: Pre multiply by a matrix
337    //!POST: mat' = m * mat
338    void preMult(const vjMatrix&  _m);
339
340    //: Find inverse of a matrix
341    //!POST: mat = inverse(_m)
342    //! RETURNS: 1 - Success
343    int invert(vjMatrix& _m);
344
345 public:
346    // --- Transformation functions --- //
347
348    //: Pre translate a matrix
349    //!POST: mat' = trans(_x,_y,_z) * _m
350    void preTrans(float _x, float _y, float _z, vjMatrix&  _m);
351
352    //: Pre translate a matrix
353    //!POST: mat' = trans(_x,_y,_z) * _m
354    void preTrans(vjVec3& _trans, vjMatrix&  _m);
355
356    //: Post translate a matrix
357    //!POST: mat' = _m * trans(_x,_y,_z)
358    void postTrans(const vjMatrix&  _m, float _x, float _y, float _z);
359
360    //: Post translate a matrix
361    //!POST: mat' = _m * trans(_x,_y,_z)
362    void postTrans(const vjMatrix&  _m, vjVec3& _trans);
363
364    //: Pre rotate a matrix
365    //!POST: mat' = rot(_degrees, axis) * _m
366    void preRot(const float& _degrees, const vjVec3& axis, vjMatrix&  _m);
367
368    //: Post rotate a matrix
369    //!POST: mat' = _m * rot(_degrees, axis)
370    void postRot( const vjMatrix&  _m, const float& _degrees, const vjVec3& axis );
371
372    void preXYZEuler( float x, float y, float z, vjMatrix& _m );
373    void postXYZEuler( vjMatrix& _m, float x, float y, float z );
374
375    //!POST: mat' = scale(_xs,_ys,_zs) * _m;
376    void preScale( float _xs, float _ys, float _zs, vjMatrix&  _m );
377
378    //!POST: mat' = _m * scale(_xs,_ys,_zs)
379    void postScale( const vjMatrix&  _m, float _xs, float _ys, float _zs );
380
381 public:
382    //: Get a float pointer to the matrix data
383    //!RETVAL: Returns a ptr to the head of the matrix data
384    inline float*        getFloatPtr() { return (float*)mat;}
385    inline const float*  getFloatPtr() const { return (float*)mat;}
386
387    // Operators
388    inline float*        operator[]( int i )        { return &mat[i][0];}
389    inline const float*  operator[]( int i ) const  { return &mat[i][0];}
390    inline float&        operator()( const int& row, const int& column ) { return mat[column][row];}
391    inline const float&  operator()( const int& row, const int& column ) const { return mat[column][row];}
392
393    int operator==( const vjMatrix&  _m ) const
394    {
395       return this->equal(_m);
396    }
397
398    int operator!=( const vjMatrix&  _m ) const
399    {
400       return !this->equal(_m);
401    }
402
403 public:
404    // vjMatrix operators (N.B. return by value can be quite slow)
405    vjMatrix operator*( const vjMatrix&  _m ) const
406    {
407       vjMatrix dst; dst.mult(*this, _m); return dst;
408    }
409
410    //: addition
411    vjMatrix operator+( const vjMatrix&  _m ) const
412    {
413       vjMatrix dst; dst.add(*this, _m); return dst;
414    }
415
416    //: subtraction
417    vjMatrix operator-(const vjMatrix&  _m) const
418    {
419       vjMatrix dst;
420       dst.sub(*this, _m);
421       return dst;
422    }
423
424    friend inline vjMatrix operator*(float _s, const vjMatrix&);
425    friend inline vjMatrix operator*(const vjMatrix& _v, float _s);
426    friend inline vjMatrix operator/(const vjMatrix& _v, float _s);
427    friend std::ostream& operator<<(std::ostream& out, vjMatrix& _mat);
428
429 public:
430    // Assignment operators
431    //!POST: *this' = _m
432    inline vjMatrix&  operator=( const vjMatrix&  _m )
433    {
434       this->copy( _m );
435       return *this;
436    }
437
438    vjMatrix&  operator*=( const vjMatrix&  _m )
439    {
440       this->postMult(_m); return *this;
441    }
442
443    vjMatrix&  operator*=(float _s)
444    {
445       for (int i=0; i<4; i++)
446          for (int j=0; j<4; j++)
447             mat[i][j] = mat[i][j] * _s;
448
449       return *this;
450    }
451
452    //vjMatrix&  operator/=( float _s );
453    //vjMatrix&  operator+=( const vjMatrix&  _m );
454    //vjMatrix&  operator-=( const vjMatrix&  _m );
455 };
456
457 #endif
Note: See TracBrowser for help on using the browser.