openscenegraph
Matrixf
Go to the documentation of this file.
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2004 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version. The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#ifndef OSG_MATRIXF
15#define OSG_MATRIXF 1
16
17#include <osg/Object>
18#include <osg/Vec3d>
19#include <osg/Vec4d>
20#include <osg/Quat>
21
22namespace osg {
23
24class Matrixf;
25
26class OSG_EXPORT Matrixf
27{
28 public:
29
30 typedef float value_type;
31 typedef double other_value_type;
32
33 inline Matrixf() { makeIdentity(); }
34 inline Matrixf( const Matrixf& mat) { set(mat.ptr()); }
35 Matrixf( const Matrixd& mat );
36 inline explicit Matrixf( float const * const ptr ) { set(ptr); }
37 inline explicit Matrixf( double const * const ptr ) { set(ptr); }
38 inline explicit Matrixf( const Quat& quat ) { makeRotate(quat); }
39
40 Matrixf( value_type a00, value_type a01, value_type a02, value_type a03,
41 value_type a10, value_type a11, value_type a12, value_type a13,
42 value_type a20, value_type a21, value_type a22, value_type a23,
43 value_type a30, value_type a31, value_type a32, value_type a33);
44
45 ~Matrixf() {}
46
47 int compare(const Matrixf& m) const;
48
49 bool operator < (const Matrixf& m) const { return compare(m)<0; }
50 bool operator == (const Matrixf& m) const { return compare(m)==0; }
51 bool operator != (const Matrixf& m) const { return compare(m)!=0; }
52
53 inline value_type& operator()(int row, int col) { return _mat[row][col]; }
54 inline value_type operator()(int row, int col) const { return _mat[row][col]; }
55
56 inline bool valid() const { return !isNaN(); }
57 inline bool isNaN() const { return osg::isNaN(_mat[0][0]) || osg::isNaN(_mat[0][1]) || osg::isNaN(_mat[0][2]) || osg::isNaN(_mat[0][3]) ||
58 osg::isNaN(_mat[1][0]) || osg::isNaN(_mat[1][1]) || osg::isNaN(_mat[1][2]) || osg::isNaN(_mat[1][3]) ||
59 osg::isNaN(_mat[2][0]) || osg::isNaN(_mat[2][1]) || osg::isNaN(_mat[2][2]) || osg::isNaN(_mat[2][3]) ||
60 osg::isNaN(_mat[3][0]) || osg::isNaN(_mat[3][1]) || osg::isNaN(_mat[3][2]) || osg::isNaN(_mat[3][3]); }
61
62 inline Matrixf& operator = (const Matrixf& rhs)
63 {
64 if( &rhs == this ) return *this;
65 set(rhs.ptr());
66 return *this;
67 }
68
69 Matrixf& operator = (const Matrixd& other);
70
71 inline void set(const Matrixf& rhs) { set(rhs.ptr()); }
72
73 void set(const Matrixd& rhs);
74
75 inline void set(float const * const ptr)
76 {
77 value_type* local_ptr = (value_type*)_mat;
78 for(int i=0;i<16;++i) local_ptr[i]=(value_type)ptr[i];
79 }
80
81 inline void set(double const * const ptr)
82 {
83 value_type* local_ptr = (value_type*)_mat;
84 for(int i=0;i<16;++i) local_ptr[i]=(value_type)ptr[i];
85 }
86
87 void set(value_type a00, value_type a01, value_type a02,value_type a03,
88 value_type a10, value_type a11, value_type a12,value_type a13,
89 value_type a20, value_type a21, value_type a22,value_type a23,
90 value_type a30, value_type a31, value_type a32,value_type a33);
91
92 value_type * ptr() { return (value_type*)_mat; }
93 const value_type * ptr() const { return (const value_type *)_mat; }
94
95 bool isIdentity() const
96 {
97 return _mat[0][0]==1.0f && _mat[0][1]==0.0f && _mat[0][2]==0.0f && _mat[0][3]==0.0f &&
98 _mat[1][0]==0.0f && _mat[1][1]==1.0f && _mat[1][2]==0.0f && _mat[1][3]==0.0f &&
99 _mat[2][0]==0.0f && _mat[2][1]==0.0f && _mat[2][2]==1.0f && _mat[2][3]==0.0f &&
100 _mat[3][0]==0.0f && _mat[3][1]==0.0f && _mat[3][2]==0.0f && _mat[3][3]==1.0f;
101 }
102
103 void makeIdentity();
104
105 void makeScale( const Vec3f& );
106 void makeScale( const Vec3d& );
107 void makeScale( value_type, value_type, value_type );
108
109 void makeTranslate( const Vec3f& );
110 void makeTranslate( const Vec3d& );
111 void makeTranslate( value_type, value_type, value_type );
112
113 void makeRotate( const Vec3f& from, const Vec3f& to );
114 void makeRotate( const Vec3d& from, const Vec3d& to );
115 void makeRotate( value_type angle, const Vec3f& axis );
116 void makeRotate( value_type angle, const Vec3d& axis );
117 void makeRotate( value_type angle, value_type x, value_type y, value_type z );
118 void makeRotate( const Quat& );
119 void makeRotate( value_type angle1, const Vec3f& axis1,
120 value_type angle2, const Vec3f& axis2,
121 value_type angle3, const Vec3f& axis3);
122 void makeRotate( value_type angle1, const Vec3d& axis1,
123 value_type angle2, const Vec3d& axis2,
124 value_type angle3, const Vec3d& axis3);
125
126
127 /** decompose the matrix into translation, rotation, scale and scale orientation.*/
128 void decompose( osg::Vec3f& translation,
129 osg::Quat& rotation,
130 osg::Vec3f& scale,
131 osg::Quat& so ) const;
132
133 /** decompose the matrix into translation, rotation, scale and scale orientation.*/
134 void decompose( osg::Vec3d& translation,
135 osg::Quat& rotation,
136 osg::Vec3d& scale,
137 osg::Quat& so ) const;
138
139
140 /** Set to an orthographic projection.
141 * See glOrtho for further details.
142 */
143 void makeOrtho(double left, double right,
144 double bottom, double top,
145 double zNear, double zFar);
146
147 /** Get the orthographic settings of the orthographic projection matrix.
148 * Note, if matrix is not an orthographic matrix then invalid values
149 * will be returned.
150 */
151 bool getOrtho(double& left, double& right,
152 double& bottom, double& top,
153 double& zNear, double& zFar) const;
154
155 /** float version of getOrtho(..) */
156 bool getOrtho(float& left, float& right,
157 float& bottom, float& top,
158 float& zNear, float& zFar) const;
159
160
161 /** Set to a 2D orthographic projection.
162 * See glOrtho2D for further details.
163 */
164 inline void makeOrtho2D(double left, double right,
165 double bottom, double top)
166 {
167 makeOrtho(left,right,bottom,top,-1.0,1.0);
168 }
169
170
171 /** Set to a perspective projection.
172 * See glFrustum for further details.
173 */
174 void makeFrustum(double left, double right,
175 double bottom, double top,
176 double zNear, double zFar);
177
178 /** Get the frustum settings of a perspective projection matrix.
179 * Note, if matrix is not a perspective matrix then invalid values
180 * will be returned.
181 */
182 bool getFrustum(double& left, double& right,
183 double& bottom, double& top,
184 double& zNear, double& zFar) const;
185
186 /** float version of getFrustum(..) */
187 bool getFrustum(float& left, float& right,
188 float& bottom, float& top,
189 float& zNear, float& zFar) const;
190
191 /** Set to a symmetrical perspective projection.
192 * See gluPerspective for further details.
193 * Aspect ratio is defined as width/height.
194 */
195 void makePerspective(double fovy, double aspectRatio,
196 double zNear, double zFar);
197
198 /** Get the frustum settings of a symmetric perspective projection
199 * matrix.
200 * Return false if matrix is not a perspective matrix,
201 * where parameter values are undefined.
202 * Note, if matrix is not a symmetric perspective matrix then the
203 * shear will be lost.
204 * Asymmetric matrices occur when stereo, power walls, caves and
205 * reality center display are used.
206 * In these configuration one should use the AsFrustum method instead.
207 */
208 bool getPerspective(double& fovy, double& aspectRatio,
209 double& zNear, double& zFar) const;
210
211 /** float version of getPerspective(..) */
212 bool getPerspective(float& fovy, float& aspectRatio,
213 float& zNear, float& zFar) const;
214
215 /** Set the position and orientation to be a view matrix,
216 * using the same convention as gluLookAt.
217 */
218 void makeLookAt(const Vec3d& eye,const Vec3d& center,const Vec3d& up);
219
220 /** Get to the position and orientation of a modelview matrix,
221 * using the same convention as gluLookAt.
222 */
223 void getLookAt(Vec3f& eye,Vec3f& center,Vec3f& up,
224 value_type lookDistance=1.0f) const;
225
226 /** Get to the position and orientation of a modelview matrix,
227 * using the same convention as gluLookAt.
228 */
229 void getLookAt(Vec3d& eye,Vec3d& center,Vec3d& up,
230 value_type lookDistance=1.0f) const;
231
232 /** invert the matrix rhs, automatically select invert_4x3 or invert_4x4. */
233 inline bool invert( const Matrixf& rhs)
234 {
235 bool is_4x3 = (rhs._mat[0][3]==0.0f && rhs._mat[1][3]==0.0f && rhs._mat[2][3]==0.0f && rhs._mat[3][3]==1.0f);
236 return is_4x3 ? invert_4x3(rhs) : invert_4x4(rhs);
237 }
238
239 /** 4x3 matrix invert, not right hand column is assumed to be 0,0,0,1. */
240 bool invert_4x3( const Matrixf& rhs);
241
242 /** full 4x4 matrix invert. */
243 bool invert_4x4( const Matrixf& rhs);
244
245 /** transpose matrix **/
246 bool transpose(const Matrixf&rhs);
247
248 /** transpose orthogonal part of the matrix **/
249 bool transpose3x3(const Matrixf&rhs);
250
251 /** ortho-normalize the 3x3 rotation & scale matrix */
252 void orthoNormalize(const Matrixf& rhs);
253
254 //basic utility functions to create new matrices
255 inline static Matrixf identity( void );
256 inline static Matrixf scale( const Vec3f& sv);
257 inline static Matrixf scale( const Vec3d& sv);
258 inline static Matrixf scale( value_type sx, value_type sy, value_type sz);
259 inline static Matrixf translate( const Vec3f& dv);
260 inline static Matrixf translate( const Vec3d& dv);
261 inline static Matrixf translate( value_type x, value_type y, value_type z);
262 inline static Matrixf rotate( const Vec3f& from, const Vec3f& to);
263 inline static Matrixf rotate( const Vec3d& from, const Vec3d& to);
264 inline static Matrixf rotate( value_type angle, value_type x, value_type y, value_type z);
265 inline static Matrixf rotate( value_type angle, const Vec3f& axis);
266 inline static Matrixf rotate( value_type angle, const Vec3d& axis);
267 inline static Matrixf rotate( value_type angle1, const Vec3f& axis1,
268 value_type angle2, const Vec3f& axis2,
269 value_type angle3, const Vec3f& axis3);
270 inline static Matrixf rotate( value_type angle1, const Vec3d& axis1,
271 value_type angle2, const Vec3d& axis2,
272 value_type angle3, const Vec3d& axis3);
273 inline static Matrixf rotate( const Quat& quat);
274 inline static Matrixf inverse( const Matrixf& matrix);
275 inline static Matrixf orthoNormal(const Matrixf& matrix);
276
277 /** Create an orthographic projection matrix.
278 * See glOrtho for further details.
279 */
280 inline static Matrixf ortho(double left, double right,
281 double bottom, double top,
282 double zNear, double zFar);
283
284 /** Create a 2D orthographic projection.
285 * See glOrtho for further details.
286 */
287 inline static Matrixf ortho2D(double left, double right,
288 double bottom, double top);
289
290 /** Create a perspective projection.
291 * See glFrustum for further details.
292 */
293 inline static Matrixf frustum(double left, double right,
294 double bottom, double top,
295 double zNear, double zFar);
296
297 /** Create a symmetrical perspective projection.
298 * See gluPerspective for further details.
299 * Aspect ratio is defined as width/height.
300 */
301 inline static Matrixf perspective(double fovy, double aspectRatio,
302 double zNear, double zFar);
303
304 /** Create the position and orientation as per a camera,
305 * using the same convention as gluLookAt.
306 */
307 inline static Matrixf lookAt(const Vec3f& eye,
308 const Vec3f& center,
309 const Vec3f& up);
310
311 /** Create the position and orientation as per a camera,
312 * using the same convention as gluLookAt.
313 */
314 inline static Matrixf lookAt(const Vec3d& eye,
315 const Vec3d& center,
316 const Vec3d& up);
317
318 inline Vec3f preMult( const Vec3f& v ) const;
319 inline Vec3d preMult( const Vec3d& v ) const;
320 inline Vec3f postMult( const Vec3f& v ) const;
321 inline Vec3d postMult( const Vec3d& v ) const;
322 inline Vec3f operator* ( const Vec3f& v ) const;
323 inline Vec3d operator* ( const Vec3d& v ) const;
324 inline Vec4f preMult( const Vec4f& v ) const;
325 inline Vec4d preMult( const Vec4d& v ) const;
326 inline Vec4f postMult( const Vec4f& v ) const;
327 inline Vec4d postMult( const Vec4d& v ) const;
328 inline Vec4f operator* ( const Vec4f& v ) const;
329 inline Vec4d operator* ( const Vec4d& v ) const;
330
331#ifdef OSG_USE_DEPRECATED_API
332 inline void set(const Quat& q) { makeRotate(q); }
333 inline void get(Quat& q) const { q = getRotate(); }
334#endif
335
336 void setRotate(const Quat& q);
337 /** Get the matrix rotation as a Quat. Note that this function
338 * assumes a non-scaled matrix and will return incorrect results
339 * for scaled matrixces. Consider decompose() instead.
340 */
341 Quat getRotate() const;
342
343
344 void setTrans( value_type tx, value_type ty, value_type tz );
345 void setTrans( const Vec3f& v );
346 void setTrans( const Vec3d& v );
347
348 inline Vec3d getTrans() const { return Vec3d(_mat[3][0],_mat[3][1],_mat[3][2]); }
349
350 inline Vec3d getScale() const {
351 Vec3d x_vec(_mat[0][0],_mat[1][0],_mat[2][0]);
352 Vec3d y_vec(_mat[0][1],_mat[1][1],_mat[2][1]);
353 Vec3d z_vec(_mat[0][2],_mat[1][2],_mat[2][2]);
354 return Vec3d(x_vec.length(), y_vec.length(), z_vec.length());
355 }
356
357 /** apply a 3x3 transform of v*M[0..2,0..2]. */
358 inline static Vec3f transform3x3(const Vec3f& v,const Matrixf& m);
359
360 /** apply a 3x3 transform of v*M[0..2,0..2]. */
361 inline static Vec3d transform3x3(const Vec3d& v,const Matrixf& m);
362
363 /** apply a 3x3 transform of M[0..2,0..2]*v. */
364 inline static Vec3f transform3x3(const Matrixf& m,const Vec3f& v);
365
366 /** apply a 3x3 transform of M[0..2,0..2]*v. */
367 inline static Vec3d transform3x3(const Matrixf& m,const Vec3d& v);
368
369 // basic Matrixf multiplication, our workhorse methods.
370 void mult( const Matrixf&, const Matrixf& );
371 void preMult( const Matrixf& );
372 void postMult( const Matrixf& );
373
374 /** Optimized version of preMult(translate(v)); */
375 inline void preMultTranslate( const Vec3d& v );
376 inline void preMultTranslate( const Vec3f& v );
377 /** Optimized version of postMult(translate(v)); */
378 inline void postMultTranslate( const Vec3d& v );
379 inline void postMultTranslate( const Vec3f& v );
380
381 /** Optimized version of preMult(scale(v)); */
382 inline void preMultScale( const Vec3d& v );
383 inline void preMultScale( const Vec3f& v );
384 /** Optimized version of postMult(scale(v)); */
385 inline void postMultScale( const Vec3d& v );
386 inline void postMultScale( const Vec3f& v );
387
388 /** Optimized version of preMult(rotate(q)); */
389 inline void preMultRotate( const Quat& q );
390 /** Optimized version of postMult(rotate(q)); */
391 inline void postMultRotate( const Quat& q );
392
393 inline void operator *= ( const Matrixf& other )
394 { if( this == &other ) {
395 Matrixf temp(other);
396 postMult( temp );
397 }
398 else postMult( other );
399 }
400
401 inline Matrixf operator * ( const Matrixf &m ) const
402 {
403 osg::Matrixf r;
404 r.mult(*this,m);
405 return r;
406 }
407
408 /** Multiply by scalar. */
409 inline Matrixf operator * (value_type rhs) const
410 {
411 return Matrixf(
412 _mat[0][0]*rhs, _mat[0][1]*rhs, _mat[0][2]*rhs, _mat[0][3]*rhs,
413 _mat[1][0]*rhs, _mat[1][1]*rhs, _mat[1][2]*rhs, _mat[1][3]*rhs,
414 _mat[2][0]*rhs, _mat[2][1]*rhs, _mat[2][2]*rhs, _mat[2][3]*rhs,
415 _mat[3][0]*rhs, _mat[3][1]*rhs, _mat[3][2]*rhs, _mat[3][3]*rhs);
416 }
417
418 /** Unary multiply by scalar. */
419 inline Matrixf& operator *= (value_type rhs)
420 {
421 _mat[0][0]*=rhs;
422 _mat[0][1]*=rhs;
423 _mat[0][2]*=rhs;
424 _mat[0][3]*=rhs;
425 _mat[1][0]*=rhs;
426 _mat[1][1]*=rhs;
427 _mat[1][2]*=rhs;
428 _mat[1][3]*=rhs;
429 _mat[2][0]*=rhs;
430 _mat[2][1]*=rhs;
431 _mat[2][2]*=rhs;
432 _mat[2][3]*=rhs;
433 _mat[3][0]*=rhs;
434 _mat[3][1]*=rhs;
435 _mat[3][2]*=rhs;
436 _mat[3][3]*=rhs;
437 return *this;
438 }
439
440 /** Divide by scalar. */
441 inline Matrixf operator / (value_type rhs) const
442 {
443 return Matrixf(
444 _mat[0][0]/rhs, _mat[0][1]/rhs, _mat[0][2]/rhs, _mat[0][3]/rhs,
445 _mat[1][0]/rhs, _mat[1][1]/rhs, _mat[1][2]/rhs, _mat[1][3]/rhs,
446 _mat[2][0]/rhs, _mat[2][1]/rhs, _mat[2][2]/rhs, _mat[2][3]/rhs,
447 _mat[3][0]/rhs, _mat[3][1]/rhs, _mat[3][2]/rhs, _mat[3][3]/rhs);
448 }
449
450 /** Unary divide by scalar. */
451 inline Matrixf& operator /= (value_type rhs)
452 {
453 _mat[0][0]/=rhs;
454 _mat[0][1]/=rhs;
455 _mat[0][2]/=rhs;
456 _mat[0][3]/=rhs;
457 _mat[1][0]/=rhs;
458 _mat[1][1]/=rhs;
459 _mat[1][2]/=rhs;
460 _mat[1][3]/=rhs;
461 _mat[2][0]/=rhs;
462 _mat[2][1]/=rhs;
463 _mat[2][2]/=rhs;
464 _mat[2][3]/=rhs;
465 _mat[3][0]/=rhs;
466 _mat[3][1]/=rhs;
467 _mat[3][2]/=rhs;
468 _mat[3][3]/=rhs;
469 return *this;
470 }
471
472 /** Binary vector add. */
473 inline Matrixf operator + (const Matrixf& rhs) const
474 {
475 return Matrixf(
476 _mat[0][0] + rhs._mat[0][0],
477 _mat[0][1] + rhs._mat[0][1],
478 _mat[0][2] + rhs._mat[0][2],
479 _mat[0][3] + rhs._mat[0][3],
480 _mat[1][0] + rhs._mat[1][0],
481 _mat[1][1] + rhs._mat[1][1],
482 _mat[1][2] + rhs._mat[1][2],
483 _mat[1][3] + rhs._mat[1][3],
484 _mat[2][0] + rhs._mat[2][0],
485 _mat[2][1] + rhs._mat[2][1],
486 _mat[2][2] + rhs._mat[2][2],
487 _mat[2][3] + rhs._mat[2][3],
488 _mat[3][0] + rhs._mat[3][0],
489 _mat[3][1] + rhs._mat[3][1],
490 _mat[3][2] + rhs._mat[3][2],
491 _mat[3][3] + rhs._mat[3][3]);
492 }
493
494 /** Unary vector add. Slightly more efficient because no temporary
495 * intermediate object.
496 */
497 inline Matrixf& operator += (const Matrixf& rhs)
498 {
499 _mat[0][0] += rhs._mat[0][0];
500 _mat[0][1] += rhs._mat[0][1];
501 _mat[0][2] += rhs._mat[0][2];
502 _mat[0][3] += rhs._mat[0][3];
503 _mat[1][0] += rhs._mat[1][0];
504 _mat[1][1] += rhs._mat[1][1];
505 _mat[1][2] += rhs._mat[1][2];
506 _mat[1][3] += rhs._mat[1][3];
507 _mat[2][0] += rhs._mat[2][0];
508 _mat[2][1] += rhs._mat[2][1];
509 _mat[2][2] += rhs._mat[2][2];
510 _mat[2][3] += rhs._mat[2][3];
511 _mat[3][0] += rhs._mat[3][0];
512 _mat[3][1] += rhs._mat[3][1];
513 _mat[3][2] += rhs._mat[3][2];
514 _mat[3][3] += rhs._mat[3][3];
515 return *this;
516 }
517
518 protected:
519 value_type _mat[4][4];
520
521};
522
523class RefMatrixf : public Object, public Matrixf
524{
525 public:
526
527 RefMatrixf():Object(false), Matrixf() {}
528 RefMatrixf( const Matrixf& other) : Object(false), Matrixf(other) {}
529 RefMatrixf( const Matrixd& other) : Object(false), Matrixf(other) {}
530 RefMatrixf( const RefMatrixf& other) : Object(other), Matrixf(other) {}
531 explicit RefMatrixf( Matrixf::value_type const * const def ):Object(false), Matrixf(def) {}
532 RefMatrixf( Matrixf::value_type a00, Matrixf::value_type a01, Matrixf::value_type a02, Matrixf::value_type a03,
533 Matrixf::value_type a10, Matrixf::value_type a11, Matrixf::value_type a12, Matrixf::value_type a13,
534 Matrixf::value_type a20, Matrixf::value_type a21, Matrixf::value_type a22, Matrixf::value_type a23,
535 Matrixf::value_type a30, Matrixf::value_type a31, Matrixf::value_type a32, Matrixf::value_type a33):
536 Object(false),
537 Matrixf(a00, a01, a02, a03,
538 a10, a11, a12, a13,
539 a20, a21, a22, a23,
540 a30, a31, a32, a33) {}
541
542 virtual Object* cloneType() const { return new RefMatrixf(); }
543 virtual Object* clone(const CopyOp&) const { return new RefMatrixf(*this); }
544 virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const RefMatrixf*>(obj)!=NULL; }
545 virtual const char* libraryName() const { return "osg"; }
546 virtual const char* className() const { return "Matrix"; }
547
548
549 protected:
550
551 virtual ~RefMatrixf() {}
552};
553
554
555//static utility methods
556inline Matrixf Matrixf::identity(void)
557{
558 Matrixf m;
559 m.makeIdentity();
560 return m;
561}
562
563inline Matrixf Matrixf::scale(value_type sx, value_type sy, value_type sz)
564{
565 Matrixf m;
566 m.makeScale(sx,sy,sz);
567 return m;
568}
569
570inline Matrixf Matrixf::scale(const Vec3f& v )
571{
572 return scale(v.x(), v.y(), v.z() );
573}
574
575inline Matrixf Matrixf::scale(const Vec3d& v )
576{
577 return scale(v.x(), v.y(), v.z() );
578}
579
580inline Matrixf Matrixf::translate(value_type tx, value_type ty, value_type tz)
581{
582 Matrixf m;
583 m.makeTranslate(tx,ty,tz);
584 return m;
585}
586
587inline Matrixf Matrixf::translate(const Vec3f& v )
588{
589 return translate(v.x(), v.y(), v.z() );
590}
591
592inline Matrixf Matrixf::translate(const Vec3d& v )
593{
594 return translate(v.x(), v.y(), v.z() );
595}
596
597inline Matrixf Matrixf::rotate( const Quat& q )
598{
599 return Matrixf(q);
600}
601inline Matrixf Matrixf::rotate(value_type angle, value_type x, value_type y, value_type z )
602{
603 Matrixf m;
604 m.makeRotate(angle,x,y,z);
605 return m;
606}
607inline Matrixf Matrixf::rotate(value_type angle, const Vec3f& axis )
608{
609 Matrixf m;
610 m.makeRotate(angle,axis);
611 return m;
612}
613inline Matrixf Matrixf::rotate(value_type angle, const Vec3d& axis )
614{
615 Matrixf m;
616 m.makeRotate(angle,axis);
617 return m;
618}
619inline Matrixf Matrixf::rotate( value_type angle1, const Vec3f& axis1,
620 value_type angle2, const Vec3f& axis2,
621 value_type angle3, const Vec3f& axis3)
622{
623 Matrixf m;
624 m.makeRotate(angle1,axis1,angle2,axis2,angle3,axis3);
625 return m;
626}
627inline Matrixf Matrixf::rotate( value_type angle1, const Vec3d& axis1,
628 value_type angle2, const Vec3d& axis2,
629 value_type angle3, const Vec3d& axis3)
630{
631 Matrixf m;
632 m.makeRotate(angle1,axis1,angle2,axis2,angle3,axis3);
633 return m;
634}
635inline Matrixf Matrixf::rotate(const Vec3f& from, const Vec3f& to )
636{
637 Matrixf m;
638 m.makeRotate(from,to);
639 return m;
640}
641inline Matrixf Matrixf::rotate(const Vec3d& from, const Vec3d& to )
642{
643 Matrixf m;
644 m.makeRotate(from,to);
645 return m;
646}
647
648inline Matrixf Matrixf::inverse( const Matrixf& matrix)
649{
650 Matrixf m;
651 m.invert(matrix);
652 return m;
653}
654
655inline Matrixf Matrixf::orthoNormal(const Matrixf& matrix)
656{
657 Matrixf m;
658 m.orthoNormalize(matrix);
659 return m;
660}
661
662inline Matrixf Matrixf::ortho(double left, double right,
663 double bottom, double top,
664 double zNear, double zFar)
665{
666 Matrixf m;
667 m.makeOrtho(left,right,bottom,top,zNear,zFar);
668 return m;
669}
670
671inline Matrixf Matrixf::ortho2D(double left, double right,
672 double bottom, double top)
673{
674 Matrixf m;
675 m.makeOrtho2D(left,right,bottom,top);
676 return m;
677}
678
679inline Matrixf Matrixf::frustum(double left, double right,
680 double bottom, double top,
681 double zNear, double zFar)
682{
683 Matrixf m;
684 m.makeFrustum(left,right,bottom,top,zNear,zFar);
685 return m;
686}
687
688inline Matrixf Matrixf::perspective(double fovy,double aspectRatio,
689 double zNear, double zFar)
690{
691 Matrixf m;
692 m.makePerspective(fovy,aspectRatio,zNear,zFar);
693 return m;
694}
695
696inline Matrixf Matrixf::lookAt(const Vec3f& eye,const Vec3f& center,const Vec3f& up)
697{
698 Matrixf m;
699 m.makeLookAt(eye,center,up);
700 return m;
701}
702
703inline Matrixf Matrixf::lookAt(const Vec3d& eye,const Vec3d& center,const Vec3d& up)
704{
705 Matrixf m;
706 m.makeLookAt(eye,center,up);
707 return m;
708}
709
710inline Vec3f Matrixf::postMult( const Vec3f& v ) const
711{
712 value_type d = 1.0f/(_mat[3][0]*v.x()+_mat[3][1]*v.y()+_mat[3][2]*v.z()+_mat[3][3]) ;
713 return Vec3f( (_mat[0][0]*v.x() + _mat[0][1]*v.y() + _mat[0][2]*v.z() + _mat[0][3])*d,
714 (_mat[1][0]*v.x() + _mat[1][1]*v.y() + _mat[1][2]*v.z() + _mat[1][3])*d,
715 (_mat[2][0]*v.x() + _mat[2][1]*v.y() + _mat[2][2]*v.z() + _mat[2][3])*d) ;
716}
717inline Vec3d Matrixf::postMult( const Vec3d& v ) const
718{
719 value_type d = 1.0f/(_mat[3][0]*v.x()+_mat[3][1]*v.y()+_mat[3][2]*v.z()+_mat[3][3]) ;
720 return Vec3d( (_mat[0][0]*v.x() + _mat[0][1]*v.y() + _mat[0][2]*v.z() + _mat[0][3])*d,
721 (_mat[1][0]*v.x() + _mat[1][1]*v.y() + _mat[1][2]*v.z() + _mat[1][3])*d,
722 (_mat[2][0]*v.x() + _mat[2][1]*v.y() + _mat[2][2]*v.z() + _mat[2][3])*d) ;
723}
724
725inline Vec3f Matrixf::preMult( const Vec3f& v ) const
726{
727 value_type d = 1.0f/(_mat[0][3]*v.x()+_mat[1][3]*v.y()+_mat[2][3]*v.z()+_mat[3][3]) ;
728 return Vec3f( (_mat[0][0]*v.x() + _mat[1][0]*v.y() + _mat[2][0]*v.z() + _mat[3][0])*d,
729 (_mat[0][1]*v.x() + _mat[1][1]*v.y() + _mat[2][1]*v.z() + _mat[3][1])*d,
730 (_mat[0][2]*v.x() + _mat[1][2]*v.y() + _mat[2][2]*v.z() + _mat[3][2])*d);
731}
732inline Vec3d Matrixf::preMult( const Vec3d& v ) const
733{
734 value_type d = 1.0f/(_mat[0][3]*v.x()+_mat[1][3]*v.y()+_mat[2][3]*v.z()+_mat[3][3]) ;
735 return Vec3d( (_mat[0][0]*v.x() + _mat[1][0]*v.y() + _mat[2][0]*v.z() + _mat[3][0])*d,
736 (_mat[0][1]*v.x() + _mat[1][1]*v.y() + _mat[2][1]*v.z() + _mat[3][1])*d,
737 (_mat[0][2]*v.x() + _mat[1][2]*v.y() + _mat[2][2]*v.z() + _mat[3][2])*d);
738}
739
740inline Vec4f Matrixf::postMult( const Vec4f& v ) const
741{
742 return Vec4f( (_mat[0][0]*v.x() + _mat[0][1]*v.y() + _mat[0][2]*v.z() + _mat[0][3]*v.w()),
743 (_mat[1][0]*v.x() + _mat[1][1]*v.y() + _mat[1][2]*v.z() + _mat[1][3]*v.w()),
744 (_mat[2][0]*v.x() + _mat[2][1]*v.y() + _mat[2][2]*v.z() + _mat[2][3]*v.w()),
745 (_mat[3][0]*v.x() + _mat[3][1]*v.y() + _mat[3][2]*v.z() + _mat[3][3]*v.w())) ;
746}
747inline Vec4d Matrixf::postMult( const Vec4d& v ) const
748{
749 return Vec4d( (_mat[0][0]*v.x() + _mat[0][1]*v.y() + _mat[0][2]*v.z() + _mat[0][3]*v.w()),
750 (_mat[1][0]*v.x() + _mat[1][1]*v.y() + _mat[1][2]*v.z() + _mat[1][3]*v.w()),
751 (_mat[2][0]*v.x() + _mat[2][1]*v.y() + _mat[2][2]*v.z() + _mat[2][3]*v.w()),
752 (_mat[3][0]*v.x() + _mat[3][1]*v.y() + _mat[3][2]*v.z() + _mat[3][3]*v.w())) ;
753}
754
755inline Vec4f Matrixf::preMult( const Vec4f& v ) const
756{
757 return Vec4f( (_mat[0][0]*v.x() + _mat[1][0]*v.y() + _mat[2][0]*v.z() + _mat[3][0]*v.w()),
758 (_mat[0][1]*v.x() + _mat[1][1]*v.y() + _mat[2][1]*v.z() + _mat[3][1]*v.w()),
759 (_mat[0][2]*v.x() + _mat[1][2]*v.y() + _mat[2][2]*v.z() + _mat[3][2]*v.w()),
760 (_mat[0][3]*v.x() + _mat[1][3]*v.y() + _mat[2][3]*v.z() + _mat[3][3]*v.w()));
761}
762inline Vec4d Matrixf::preMult( const Vec4d& v ) const
763{
764 return Vec4d( (_mat[0][0]*v.x() + _mat[1][0]*v.y() + _mat[2][0]*v.z() + _mat[3][0]*v.w()),
765 (_mat[0][1]*v.x() + _mat[1][1]*v.y() + _mat[2][1]*v.z() + _mat[3][1]*v.w()),
766 (_mat[0][2]*v.x() + _mat[1][2]*v.y() + _mat[2][2]*v.z() + _mat[3][2]*v.w()),
767 (_mat[0][3]*v.x() + _mat[1][3]*v.y() + _mat[2][3]*v.z() + _mat[3][3]*v.w()));
768}
769inline Vec3f Matrixf::transform3x3(const Vec3f& v,const Matrixf& m)
770{
771 return Vec3f( (m._mat[0][0]*v.x() + m._mat[1][0]*v.y() + m._mat[2][0]*v.z()),
772 (m._mat[0][1]*v.x() + m._mat[1][1]*v.y() + m._mat[2][1]*v.z()),
773 (m._mat[0][2]*v.x() + m._mat[1][2]*v.y() + m._mat[2][2]*v.z()));
774}
775inline Vec3d Matrixf::transform3x3(const Vec3d& v,const Matrixf& m)
776{
777 return Vec3d( (m._mat[0][0]*v.x() + m._mat[1][0]*v.y() + m._mat[2][0]*v.z()),
778 (m._mat[0][1]*v.x() + m._mat[1][1]*v.y() + m._mat[2][1]*v.z()),
779 (m._mat[0][2]*v.x() + m._mat[1][2]*v.y() + m._mat[2][2]*v.z()));
780}
781
782inline Vec3f Matrixf::transform3x3(const Matrixf& m,const Vec3f& v)
783{
784 return Vec3f( (m._mat[0][0]*v.x() + m._mat[0][1]*v.y() + m._mat[0][2]*v.z()),
785 (m._mat[1][0]*v.x() + m._mat[1][1]*v.y() + m._mat[1][2]*v.z()),
786 (m._mat[2][0]*v.x() + m._mat[2][1]*v.y() + m._mat[2][2]*v.z()) ) ;
787}
788inline Vec3d Matrixf::transform3x3(const Matrixf& m,const Vec3d& v)
789{
790 return Vec3d( (m._mat[0][0]*v.x() + m._mat[0][1]*v.y() + m._mat[0][2]*v.z()),
791 (m._mat[1][0]*v.x() + m._mat[1][1]*v.y() + m._mat[1][2]*v.z()),
792 (m._mat[2][0]*v.x() + m._mat[2][1]*v.y() + m._mat[2][2]*v.z()) ) ;
793}
794
795inline void Matrixf::preMultTranslate( const Vec3d& v )
796{
797 for (unsigned i = 0; i < 3; ++i)
798 {
799 double tmp = v[i];
800 if (tmp == 0)
801 continue;
802 _mat[3][0] += tmp*_mat[i][0];
803 _mat[3][1] += tmp*_mat[i][1];
804 _mat[3][2] += tmp*_mat[i][2];
805 _mat[3][3] += tmp*_mat[i][3];
806 }
807}
808
809inline void Matrixf::preMultTranslate( const Vec3f& v )
810{
811 for (unsigned i = 0; i < 3; ++i)
812 {
813 float tmp = v[i];
814 if (tmp == 0)
815 continue;
816 _mat[3][0] += tmp*_mat[i][0];
817 _mat[3][1] += tmp*_mat[i][1];
818 _mat[3][2] += tmp*_mat[i][2];
819 _mat[3][3] += tmp*_mat[i][3];
820 }
821}
822
823inline void Matrixf::postMultTranslate( const Vec3d& v )
824{
825 for (unsigned i = 0; i < 3; ++i)
826 {
827 double tmp = v[i];
828 if (tmp == 0)
829 continue;
830 _mat[0][i] += tmp*_mat[0][3];
831 _mat[1][i] += tmp*_mat[1][3];
832 _mat[2][i] += tmp*_mat[2][3];
833 _mat[3][i] += tmp*_mat[3][3];
834 }
835}
836
837inline void Matrixf::postMultTranslate( const Vec3f& v )
838{
839 for (unsigned i = 0; i < 3; ++i)
840 {
841 float tmp = v[i];
842 if (tmp == 0)
843 continue;
844 _mat[0][i] += tmp*_mat[0][3];
845 _mat[1][i] += tmp*_mat[1][3];
846 _mat[2][i] += tmp*_mat[2][3];
847 _mat[3][i] += tmp*_mat[3][3];
848 }
849}
850
851inline void Matrixf::preMultScale( const Vec3d& v )
852{
853 _mat[0][0] *= v[0]; _mat[0][1] *= v[0]; _mat[0][2] *= v[0]; _mat[0][3] *= v[0];
854 _mat[1][0] *= v[1]; _mat[1][1] *= v[1]; _mat[1][2] *= v[1]; _mat[1][3] *= v[1];
855 _mat[2][0] *= v[2]; _mat[2][1] *= v[2]; _mat[2][2] *= v[2]; _mat[2][3] *= v[2];
856}
857
858inline void Matrixf::preMultScale( const Vec3f& v )
859{
860 _mat[0][0] *= v[0]; _mat[0][1] *= v[0]; _mat[0][2] *= v[0]; _mat[0][3] *= v[0];
861 _mat[1][0] *= v[1]; _mat[1][1] *= v[1]; _mat[1][2] *= v[1]; _mat[1][3] *= v[1];
862 _mat[2][0] *= v[2]; _mat[2][1] *= v[2]; _mat[2][2] *= v[2]; _mat[2][3] *= v[2];
863}
864
865inline void Matrixf::postMultScale( const Vec3d& v )
866{
867 _mat[0][0] *= v[0]; _mat[1][0] *= v[0]; _mat[2][0] *= v[0]; _mat[3][0] *= v[0];
868 _mat[0][1] *= v[1]; _mat[1][1] *= v[1]; _mat[2][1] *= v[1]; _mat[3][1] *= v[1];
869 _mat[0][2] *= v[2]; _mat[1][2] *= v[2]; _mat[2][2] *= v[2]; _mat[3][2] *= v[2];
870}
871
872inline void Matrixf::postMultScale( const Vec3f& v )
873{
874 _mat[0][0] *= v[0]; _mat[1][0] *= v[0]; _mat[2][0] *= v[0]; _mat[3][0] *= v[0];
875 _mat[0][1] *= v[1]; _mat[1][1] *= v[1]; _mat[2][1] *= v[1]; _mat[3][1] *= v[1];
876 _mat[0][2] *= v[2]; _mat[1][2] *= v[2]; _mat[2][2] *= v[2]; _mat[3][2] *= v[2];
877}
878
879
880inline void Matrixf::preMultRotate( const Quat& q )
881{
882 if (q.zeroRotation())
883 return;
884 Matrixf r;
885 r.setRotate(q);
886 preMult(r);
887}
888
889inline void Matrixf::postMultRotate( const Quat& q )
890{
891 if (q.zeroRotation())
892 return;
893 Matrixf r;
894 r.setRotate(q);
895 postMult(r);
896}
897
898inline Vec3f operator* (const Vec3f& v, const Matrixf& m )
899{
900 return m.preMult(v);
901}
902inline Vec3d operator* (const Vec3d& v, const Matrixf& m )
903{
904 return m.preMult(v);
905}
906inline Vec4f operator* (const Vec4f& v, const Matrixf& m )
907{
908 return m.preMult(v);
909}
910inline Vec4d operator* (const Vec4d& v, const Matrixf& m )
911{
912 return m.preMult(v);
913}
914
915inline Vec3f Matrixf::operator* (const Vec3f& v) const
916{
917 return postMult(v);
918}
919inline Vec3d Matrixf::operator* (const Vec3d& v) const
920{
921 return postMult(v);
922}
923inline Vec4f Matrixf::operator* (const Vec4f& v) const
924{
925 return postMult(v);
926}
927inline Vec4d Matrixf::operator* (const Vec4d& v) const
928{
929 return postMult(v);
930}
931
932
933} //namespace osg
934
935
936#endif