CTransform.h
Go to the documentation of this file.
1 //==============================================================================
2 /*
3  Software License Agreement (BSD License)
4  Copyright (c) 2003-2016, CHAI3D.
5  (www.chai3d.org)
6 
7  All rights reserved.
8 
9  Redistribution and use in source and binary forms, with or without
10  modification, are permitted provided that the following conditions
11  are met:
12 
13  * Redistributions of source code must retain the above copyright
14  notice, this list of conditions and the following disclaimer.
15 
16  * Redistributions in binary form must reproduce the above
17  copyright notice, this list of conditions and the following
18  disclaimer in the documentation and/or other materials provided
19  with the distribution.
20 
21  * Neither the name of CHAI3D nor the names of its contributors may
22  be used to endorse or promote products derived from this software
23  without specific prior written permission.
24 
25  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  POSSIBILITY OF SUCH DAMAGE.
37 
38  \author <http://www.chai3d.org>
39  \author Francois Conti
40  \version 3.2.0 $Rev: 1869 $
41 */
42 //==============================================================================
43 
44 //------------------------------------------------------------------------------
45 #ifndef CTransformH
46 #define CTransformH
47 //------------------------------------------------------------------------------
48 #include "math/CMatrix3d.h"
49 //------------------------------------------------------------------------------
50 
51 //------------------------------------------------------------------------------
52 namespace chai3d {
53 //------------------------------------------------------------------------------
54 
55 //==============================================================================
63 //==============================================================================
64 
65 
66 //==============================================================================
74 //==============================================================================
75 struct cTransform
76 {
77  //--------------------------------------------------------------------------
78  // CONSTRUCTOR & DESTRUCTOR:
79  //--------------------------------------------------------------------------
80 
81 public:
82 
83  //--------------------------------------------------------------------------
87  //--------------------------------------------------------------------------
89  {
90  identity();
91  m_flagTransform = true;
92  }
93 
94 
95  //--------------------------------------------------------------------------
107  //--------------------------------------------------------------------------
108  cTransform(const cVector3d& a_pos, const cMatrix3d& a_rot)
109  {
110  identity();
111  set(a_pos, a_rot);
112  m_flagTransform = true;
113  }
114 
115 
116  //--------------------------------------------------------------------------
126  //--------------------------------------------------------------------------
127  cTransform(const cVector3d& a_pos)
128  {
129  identity();
130  setLocalPos(a_pos);
131  m_flagTransform = true;
132  }
133 
134 
135  //--------------------------------------------------------------------------
145  //--------------------------------------------------------------------------
146  cTransform(const cMatrix3d& a_rot)
147  {
148  identity();
149  setLocalRot(a_rot);
150  m_flagTransform = true;
151  }
152 
153 
154  //--------------------------------------------------------------------------
165  //--------------------------------------------------------------------------
166  inline void setLocalPos(const cVector3d& a_pos)
167  {
168  m[3][0] = a_pos(0); m[3][1] = a_pos(1); m[3][2] = a_pos(2);
169  }
170 
171 
172  //--------------------------------------------------------------------------
183  //--------------------------------------------------------------------------
184  void setLocalRot(const cMatrix3d& a_rot)
185  {
186  m[0][0] = a_rot(0,0); m[0][1] = a_rot(1,0); m[0][2] = a_rot(2,0);
187  m[1][0] = a_rot(0,1); m[1][1] = a_rot(1,1); m[1][2] = a_rot(2,1);
188  m[2][0] = a_rot(0,2); m[2][1] = a_rot(1,2); m[2][2] = a_rot(2,2);
189 
190  m_flagTransform = true;
191  }
192 
193 
194  //--------------------------------------------------------------------------
207  //--------------------------------------------------------------------------
208  void set(const cVector3d& a_pos,
209  const cMatrix3d& a_rot)
210  {
211  m[0][0] = a_rot(0,0); m[0][1] = a_rot(1,0); m[0][2] = a_rot(2,0);
212  m[1][0] = a_rot(0,1); m[1][1] = a_rot(1,1); m[1][2] = a_rot(2,1);
213  m[2][0] = a_rot(0,2); m[2][1] = a_rot(1,2); m[2][2] = a_rot(2,2);
214  m[3][0] = a_pos(0); m[3][1] = a_pos(1); m[3][2] = a_pos(2);
215 
216  m_flagTransform = true;
217  }
218 
219 
220  //--------------------------------------------------------------------------
246  //--------------------------------------------------------------------------
247  inline void set(const double& a_00, const double& a_01, const double& a_02, const double& a_03,
248  const double& a_10, const double& a_11, const double& a_12, const double& a_13,
249  const double& a_20, const double& a_21, const double& a_22, const double& a_23,
250  const double& a_30, const double& a_31, const double& a_32, const double& a_33)
251  {
252  m[0][0] = a_00; m[0][1] = a_01; m[0][2] = a_02; m[0][3] = a_03;
253  m[1][0] = a_10; m[1][1] = a_11; m[1][2] = a_12; m[1][3] = a_13;
254  m[2][0] = a_20; m[2][1] = a_21; m[2][2] = a_22; m[2][3] = a_23;
255  m[3][0] = a_30; m[3][1] = a_31; m[3][2] = a_32; m[3][3] = a_33;
256 
257  m_flagTransform = false;
258  }
259 
260 
261  //--------------------------------------------------------------------------
277  //--------------------------------------------------------------------------
278  inline void setFrustumMatrix(double a_l,
279  double a_r,
280  double a_b,
281  double a_t,
282  double a_n,
283  double a_f)
284  {
285  m[0][0] = (2.0*a_n) / (a_r-a_l);
286  m[0][1] = 0.0;
287  m[0][2] = 0.0;
288  m[0][3] = 0.0;
289 
290  m[1][0] = 0.0;
291  m[1][1] = (2.0*a_n) / (a_t-a_b);
292  m[1][2] = 0.0;
293  m[1][3] = 0.0;
294 
295  m[2][0] = (a_r+a_l) / (a_r-a_l);
296  m[2][1] = (a_t+a_b) / (a_t-a_b);
297  m[2][2] = -(a_f+a_n) / (a_f-a_n);
298  m[2][3] = -1.0;
299 
300  m[3][0] = 0.0;
301  m[3][1] = 0.0;
302  m[3][2] = -(2.0*a_f*a_n) / (a_f-a_n);
303  m[3][3] = 0.0;
304 
305  m_flagTransform = false;
306  }
307 
308 
309  //--------------------------------------------------------------------------
328  //--------------------------------------------------------------------------
329  inline void setLookAtMatrix(const double a_eyeX,
330  const double a_eyeY,
331  const double a_eyeZ,
332  const double a_centerX,
333  const double a_centerY,
334  const double a_centerZ,
335  const double a_upX,
336  const double a_upY,
337  const double a_upZ)
338  {
339  double x[3], y[3], z[3];
340  double mag;
341 
342  // create rotation matrix
343 
344  // Z vector
345  z[0] = a_eyeX - a_centerX;
346  z[1] = a_eyeY - a_centerY;
347  z[2] = a_eyeZ - a_centerZ;
348 
349  mag = sqrt(z[0]*z[0] + z[1]*z[1] + z[2]*z[2]);
350  if (mag > 0.0)
351  {
352  z[0] /= mag;
353  z[1] /= mag;
354  z[2] /= mag;
355  }
356 
357  // Y vector
358  y[0] = a_upX;
359  y[1] = a_upY;
360  y[2] = a_upZ;
361 
362  // X vector = Y cross Z
363  x[0] = y[1]*z[2] - y[2]*z[1];
364  x[1] = -y[0]*z[2] + y[2]*z[0];
365  x[2] = y[0]*z[1] - y[1]*z[0];
366 
367  // recompute Y = Z cross X
368  y[0] = z[1]*x[2] - z[2]*x[1];
369  y[1] = -z[0]*x[2] + z[2]*x[0];
370  y[2] = z[0]*x[1] - z[1]*x[0];
371 
372  // normalize
373  mag = sqrt( x[0]*x[0] + x[1]*x[1] + x[2]*x[2] );
374  if (mag) {
375  x[0] /= mag;
376  x[1] /= mag;
377  x[2] /= mag;
378  }
379 
380  mag = sqrt( y[0]*y[0] + y[1]*y[1] + y[2]*y[2] );
381  if (mag) {
382  y[0] /= mag;
383  y[1] /= mag;
384  y[2] /= mag;
385  }
386 
387  m[0][0] = x[0]; m[1][0] = x[1]; m[2][0] = x[2]; m[3][0] = -x[0]*a_eyeX + -x[1]*a_eyeY + -x[2]*a_eyeZ;
388  m[0][1] = y[0]; m[1][1] = y[1]; m[2][1] = y[2]; m[3][1] = -y[0]*a_eyeX + -y[1]*a_eyeY + -y[2]*a_eyeZ;
389  m[0][2] = z[0]; m[1][2] = z[1]; m[2][2] = z[2]; m[3][2] = -z[0]*a_eyeX + -z[1]*a_eyeY + -z[2]*a_eyeZ;
390  m[0][3] = 0.0; m[1][3] = 0.0; m[2][3] = 0.0; m[3][3] = 1.0;
391 
392  m_flagTransform = true;
393  }
394 
395 
396  //--------------------------------------------------------------------------
409  //--------------------------------------------------------------------------
410  inline void setLookAtMatrix(const cVector3d& a_eye,
411  const cVector3d& a_lookAt,
412  const cVector3d& a_up)
413  {
414  setLookAtMatrix(a_eye(0), a_eye(1), a_eye(2),
415  a_lookAt(0), a_lookAt(1), a_lookAt(2),
416  a_up(0), a_up(1), a_up(2));
417 
418  m_flagTransform = true;
419  }
420 
421 
422  //--------------------------------------------------------------------------
437  //--------------------------------------------------------------------------
438  inline void setPerspectiveMatrix(const double a_fovy,
439  const double a_aspect,
440  const double a_zNear,
441  const double a_zFar)
442  {
443  double xMin, xMax, yMin, yMax;
444 
445  yMax = a_zNear * tan(a_fovy * C_PI / 360.0);
446  yMin = -yMax;
447 
448  xMin = yMin * a_aspect;
449  xMax = yMax * a_aspect;
450 
451  setFrustumMatrix(xMin, xMax, yMin, yMax, a_zNear, a_zFar);
452 
453  m_flagTransform = false;
454  }
455 
456 
457  //--------------------------------------------------------------------------
467  //--------------------------------------------------------------------------
468  inline double* getData()
469  {
470  return (&(m[0][0]));
471  }
472 
473 
474  //--------------------------------------------------------------------------
484  //--------------------------------------------------------------------------
485  inline cVector3d getLocalPos() const
486  {
487  return cVector3d(m[3][0],m[3][1],m[3][2]);
488  }
489 
490 
491  //--------------------------------------------------------------------------
501  //--------------------------------------------------------------------------
502  inline cMatrix3d getLocalRot() const
503  {
504  cMatrix3d mat;
505  mat.set(m[0][0],m[1][0],m[2][0],
506  m[0][1],m[1][1],m[2][1],
507  m[0][2],m[1][2],m[2][2]);
508  return (mat);
509  }
510 
511 
512  //--------------------------------------------------------------------------
527  //--------------------------------------------------------------------------
528  inline void copyto(cTransform& a_destination) const
529  {
530  a_destination.m[0][0] = m[0][0]; a_destination.m[0][1] = m[0][1];
531  a_destination.m[0][2] = m[0][2]; a_destination.m[0][3] = m[0][3];
532  a_destination.m[1][0] = m[1][0]; a_destination.m[1][1] = m[1][1];
533  a_destination.m[1][2] = m[1][2]; a_destination.m[1][3] = m[1][3];
534  a_destination.m[2][0] = m[2][0]; a_destination.m[2][1] = m[2][1];
535  a_destination.m[2][2] = m[2][2]; a_destination.m[2][3] = m[2][3];
536  a_destination.m[3][0] = m[3][0]; a_destination.m[3][1] = m[3][1];
537  a_destination.m[3][2] = m[3][2]; a_destination.m[3][3] = m[3][3];
538 
539  a_destination.m_flagTransform = m_flagTransform;
540  }
541 
542 
543  //--------------------------------------------------------------------------
558  //--------------------------------------------------------------------------
559  inline void copyfrom(const cTransform& a_source)
560  {
561  m[0][0] = a_source.m[0][0]; m[0][1] = a_source.m[0][1];
562  m[0][2] = a_source.m[0][2]; m[0][3] = a_source.m[0][3];
563  m[1][0] = a_source.m[1][0]; m[1][1] = a_source.m[1][1];
564  m[1][2] = a_source.m[1][2]; m[1][3] = a_source.m[1][3];
565  m[2][0] = a_source.m[2][0]; m[2][1] = a_source.m[2][1];
566  m[2][2] = a_source.m[2][2]; m[2][3] = a_source.m[2][3];
567  m[3][0] = a_source.m[3][0]; m[3][1] = a_source.m[3][1];
568  m[3][2] = a_source.m[3][2]; m[3][3] = a_source.m[3][3];
569 
570  m_flagTransform = a_source.m_flagTransform;
571  }
572 
573 
574  //--------------------------------------------------------------------------
583  //--------------------------------------------------------------------------
584  inline void identity()
585  {
586  m[0][0] = 1.0; m[0][1] = 0.0; m[0][2] = 0.0; m[0][3] = 0.0;
587  m[1][0] = 0.0; m[1][1] = 1.0; m[1][2] = 0.0; m[1][3] = 0.0;
588  m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 1.0; m[2][3] = 0.0;
589  m[3][0] = 0.0; m[3][1] = 0.0; m[3][2] = 0.0; m[3][3] = 1.0;
590 
591  m_flagTransform = true;
592  }
593 
594 
595  //--------------------------------------------------------------------------
613  //--------------------------------------------------------------------------
614  inline void mul(const cTransform& a_matrix)
615  {
616  double m00 = m[0][0] * a_matrix.m[0][0] + m[1][0] * a_matrix.m[0][1] +
617  m[2][0] * a_matrix.m[0][2] + m[3][0] * a_matrix.m[0][3];
618  double m01 = m[0][0] * a_matrix.m[1][0] + m[1][0] * a_matrix.m[1][1] +
619  m[2][0] * a_matrix.m[1][2] + m[3][0] * a_matrix.m[1][3];
620  double m02 = m[0][0] * a_matrix.m[2][0] + m[1][0] * a_matrix.m[2][1] +
621  m[2][0] * a_matrix.m[2][2] + m[3][0] * a_matrix.m[2][3];
622  double m03 = m[0][0] * a_matrix.m[3][0] + m[1][0] * a_matrix.m[3][1] +
623  m[2][0] * a_matrix.m[3][2] + m[3][0] * a_matrix.m[3][3];
624 
625  double m10 = m[0][1] * a_matrix.m[0][0] + m[1][1] * a_matrix.m[0][1] +
626  m[2][1] * a_matrix.m[0][2] + m[3][1] * a_matrix.m[0][3];
627  double m11 = m[0][1] * a_matrix.m[1][0] + m[1][1] * a_matrix.m[1][1] +
628  m[2][1] * a_matrix.m[1][2] + m[3][1] * a_matrix.m[1][3];
629  double m12 = m[0][1] * a_matrix.m[2][0] + m[1][1] * a_matrix.m[2][1] +
630  m[2][1] * a_matrix.m[2][2] + m[3][1] * a_matrix.m[2][3];
631  double m13 = m[0][1] * a_matrix.m[3][0] + m[1][1] * a_matrix.m[3][1] +
632  m[2][1] * a_matrix.m[3][2] + m[3][1] * a_matrix.m[3][3];
633 
634  double m20 = m[0][2] * a_matrix.m[0][0] + m[1][2] * a_matrix.m[0][1] +
635  m[2][2] * a_matrix.m[0][2] + m[3][2] * a_matrix.m[0][3];
636  double m21 = m[0][2] * a_matrix.m[1][0] + m[1][2] * a_matrix.m[1][1] +
637  m[2][2] * a_matrix.m[1][2] + m[3][2] * a_matrix.m[1][3];
638  double m22 = m[0][2] * a_matrix.m[2][0] + m[1][2] * a_matrix.m[2][1] +
639  m[2][2] * a_matrix.m[2][2] + m[3][2] * a_matrix.m[2][3];
640  double m23 = m[0][2] * a_matrix.m[3][0] + m[1][2] * a_matrix.m[3][1] +
641  m[2][2] * a_matrix.m[3][2] + m[3][2] * a_matrix.m[3][3];
642 
643  double m30 = m[0][3] * a_matrix.m[0][0] + m[1][3] * a_matrix.m[0][1] +
644  m[2][3] * a_matrix.m[0][2] + m[3][3] * a_matrix.m[0][3];
645  double m31 = m[0][3] * a_matrix.m[1][0] + m[1][3] * a_matrix.m[1][1] +
646  m[2][3] * a_matrix.m[1][2] + m[3][3] * a_matrix.m[1][3];
647  double m32 = m[0][3] * a_matrix.m[2][0] + m[1][3] * a_matrix.m[2][1] +
648  m[2][3] * a_matrix.m[2][2] + m[3][3] * a_matrix.m[2][3];
649  double m33 = m[0][3] * a_matrix.m[3][0] + m[1][3] * a_matrix.m[3][1] +
650  m[2][3] * a_matrix.m[3][2] + m[3][3] * a_matrix.m[3][3];
651 
652  // return values to current matrix
653  m[0][0] = m00; m[0][1] = m10; m[0][2] = m20; m[0][3] = m30;
654  m[1][0] = m01; m[1][1] = m11; m[1][2] = m21; m[1][3] = m31;
655  m[2][0] = m02; m[2][1] = m12; m[2][2] = m22; m[2][3] = m32;
656  m[3][0] = m03; m[3][1] = m13; m[3][2] = m23; m[3][3] = m33;
657  }
658 
659 
660  //--------------------------------------------------------------------------
679  //--------------------------------------------------------------------------
680  inline void mulr(const cTransform& a_matrix,
681  cTransform& a_result) const
682  {
683  double m00 = m[0][0] * a_matrix.m[0][0] + m[1][0] * a_matrix.m[0][1] +
684  m[2][0] * a_matrix.m[0][2] + m[3][0] * a_matrix.m[0][3];
685  double m01 = m[0][0] * a_matrix.m[1][0] + m[1][0] * a_matrix.m[1][1] +
686  m[2][0] * a_matrix.m[1][2] + m[3][0] * a_matrix.m[1][3];
687  double m02 = m[0][0] * a_matrix.m[2][0] + m[1][0] * a_matrix.m[2][1] +
688  m[2][0] * a_matrix.m[2][2] + m[3][0] * a_matrix.m[2][3];
689  double m03 = m[0][0] * a_matrix.m[3][0] + m[1][0] * a_matrix.m[3][1] +
690  m[2][0] * a_matrix.m[3][2] + m[3][0] * a_matrix.m[3][3];
691 
692  double m10 = m[0][1] * a_matrix.m[0][0] + m[1][1] * a_matrix.m[0][1] +
693  m[2][1] * a_matrix.m[0][2] + m[3][1] * a_matrix.m[0][3];
694  double m11 = m[0][1] * a_matrix.m[1][0] + m[1][1] * a_matrix.m[1][1] +
695  m[2][1] * a_matrix.m[1][2] + m[3][1] * a_matrix.m[1][3];
696  double m12 = m[0][1] * a_matrix.m[2][0] + m[1][1] * a_matrix.m[2][1] +
697  m[2][1] * a_matrix.m[2][2] + m[3][1] * a_matrix.m[2][3];
698  double m13 = m[0][1] * a_matrix.m[3][0] + m[1][1] * a_matrix.m[3][1] +
699  m[2][1] * a_matrix.m[3][2] + m[3][1] * a_matrix.m[3][3];
700 
701  double m20 = m[0][2] * a_matrix.m[0][0] + m[1][2] * a_matrix.m[0][1] +
702  m[2][2] * a_matrix.m[0][2] + m[3][2] * a_matrix.m[0][3];
703  double m21 = m[0][2] * a_matrix.m[1][0] + m[1][2] * a_matrix.m[1][1] +
704  m[2][2] * a_matrix.m[1][2] + m[3][2] * a_matrix.m[1][3];
705  double m22 = m[0][2] * a_matrix.m[2][0] + m[1][2] * a_matrix.m[2][1] +
706  m[2][2] * a_matrix.m[2][2] + m[3][2] * a_matrix.m[2][3];
707  double m23 = m[0][2] * a_matrix.m[3][0] + m[1][2] * a_matrix.m[3][1] +
708  m[2][2] * a_matrix.m[3][2] + m[3][2] * a_matrix.m[3][3];
709 
710  double m30 = m[0][3] * a_matrix.m[0][0] + m[1][3] * a_matrix.m[0][1] +
711  m[2][3] * a_matrix.m[0][2] + m[3][3] * a_matrix.m[0][3];
712  double m31 = m[0][3] * a_matrix.m[1][0] + m[1][3] * a_matrix.m[1][1] +
713  m[2][3] * a_matrix.m[1][2] + m[3][3] * a_matrix.m[1][3];
714  double m32 = m[0][3] * a_matrix.m[2][0] + m[1][3] * a_matrix.m[2][1] +
715  m[2][3] * a_matrix.m[2][2] + m[3][3] * a_matrix.m[2][3];
716  double m33 = m[0][3] * a_matrix.m[3][0] + m[1][3] * a_matrix.m[3][1] +
717  m[2][3] * a_matrix.m[3][2] + m[3][3] * a_matrix.m[3][3];
718 
719  // return values to current matrix
720  a_result.m[0][0] = m00; a_result.m[0][1] = m10; a_result.m[0][2] = m20; a_result.m[0][3] = m30;
721  a_result.m[1][0] = m01; a_result.m[1][1] = m11; a_result.m[1][2] = m21; a_result.m[1][3] = m31;
722  a_result.m[2][0] = m02; a_result.m[2][1] = m12; a_result.m[2][2] = m22; a_result.m[2][3] = m32;
723  a_result.m[3][0] = m03; a_result.m[3][1] = m13; a_result.m[3][2] = m23; a_result.m[3][3] = m33;
724  }
725 
726 
727  //--------------------------------------------------------------------------
745  //--------------------------------------------------------------------------
746  inline void mulr(const cVector3d& a_vector,
747  cVector3d& a_result) const
748  {
749  a_result(0) = m[0][0] * a_vector(0) + m[1][0] * a_vector(1) + m[2][0] * a_vector(2) + m[3][0] * 1.0;
750  a_result(1) = m[0][1] * a_vector(0) + m[1][1] * a_vector(1) + m[2][1] * a_vector(2) + m[3][1] * 1.0;
751  a_result(2) = m[0][2] * a_vector(0) + m[1][2] * a_vector(1) + m[2][2] * a_vector(2) + m[3][2] * 1.0;
752  }
753 
754 
755  //--------------------------------------------------------------------------
765  //--------------------------------------------------------------------------
766  inline void trans()
767  {
768  double t;
769 
770  t = m[0][1]; m[0][1] = m[1][0]; m[1][0] = t;
771  t = m[0][2]; m[0][2] = m[2][0]; m[2][0] = t;
772  t = m[0][3]; m[0][3] = m[3][0]; m[3][0] = t;
773  t = m[1][2]; m[1][2] = m[2][1]; m[2][1] = t;
774  t = m[1][3]; m[1][3] = m[3][1]; m[3][1] = t;
775  t = m[2][3]; m[2][3] = m[3][2]; m[3][2] = t;
776  }
777 
778 
779  //--------------------------------------------------------------------------
791  //--------------------------------------------------------------------------
792  inline void transr(cTransform& a_result) const
793  {
794  a_result.m[0][0] = m[0][0];
795  a_result.m[0][1] = m[1][0];
796  a_result.m[0][2] = m[2][0];
797  a_result.m[0][3] = m[3][0];
798 
799  a_result.m[1][0] = m[0][1];
800  a_result.m[1][1] = m[1][1];
801  a_result.m[1][2] = m[2][1];
802  a_result.m[1][3] = m[3][1];
803 
804  a_result.m[2][0] = m[0][2];
805  a_result.m[2][1] = m[1][2];
806  a_result.m[2][2] = m[2][2];
807  a_result.m[2][3] = m[3][2];
808 
809  a_result.m[3][0] = m[0][3];
810  a_result.m[3][1] = m[1][3];
811  a_result.m[3][2] = m[2][3];
812  a_result.m[3][3] = m[3][3];
813  }
814 
815 
816  //--------------------------------------------------------------------------
827  //--------------------------------------------------------------------------
828  bool inline invert()
829  {
830  if (m_flagTransform)
831  {
832  // transpose 3x3 rotation matrix R
833  double t;
834  t = m[0][1]; m[0][1] = m[1][0]; m[1][0] = t;
835  t = m[0][2]; m[0][2] = m[2][0]; m[2][0] = t;
836  t = m[1][2]; m[1][2] = m[2][1]; m[2][1] = t;
837 
838  // compute -R{t} * p
839  double x = - m[0][0] * m[3][0] - m[1][0] * m[3][1] - m[2][0] * m[3][2];
840  double y = - m[0][1] * m[3][0] - m[1][1] * m[3][1] - m[2][1] * m[3][2];
841  double z = - m[0][2] * m[3][0] - m[1][2] * m[3][1] - m[2][2] * m[3][2];
842 
843  m[3][0] = x;
844  m[3][1] = y;
845  m[3][2] = z;
846 
847  return (true);
848  }
849  else
850  {
851  // Macros used during inversion
852  #ifndef DOXYGEN_SHOULD_SKIP_THIS
853  #define SWAP_ROWS(a, b) { double *_tmp = a; (a)=(b); (b)=_tmp; }
854  #define MAT(m,r,c) (m)[(c)*4+(r)]
855  #endif
856  double *mat = m[0];
857 
858  double wtmp[4][8];
859  double m0, m1, m2, m3, s;
860  double *r0, *r1, *r2, *r3;
861 
862  r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3];
863 
864  r0[0] = MAT(mat,0,0), r0[1] = MAT(mat,0,1),
865  r0[2] = MAT(mat,0,2), r0[3] = MAT(mat,0,3),
866  r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0,
867 
868  r1[0] = MAT(mat,1,0), r1[1] = MAT(mat,1,1),
869  r1[2] = MAT(mat,1,2), r1[3] = MAT(mat,1,3),
870  r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0,
871 
872  r2[0] = MAT(mat,2,0), r2[1] = MAT(mat,2,1),
873  r2[2] = MAT(mat,2,2), r2[3] = MAT(mat,2,3),
874  r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0,
875 
876  r3[0] = MAT(mat,3,0), r3[1] = MAT(mat,3,1),
877  r3[2] = MAT(mat,3,2), r3[3] = MAT(mat,3,3),
878  r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0;
879 
880  // choose pivot
881  if (fabs(r3[0])>fabs(r2[0])) SWAP_ROWS(r3, r2);
882  if (fabs(r2[0])>fabs(r1[0])) SWAP_ROWS(r2, r1);
883  if (fabs(r1[0])>fabs(r0[0])) SWAP_ROWS(r1, r0);
884  if (0.0 == r0[0])
885  {
886  return (false);
887  }
888 
889  // eliminate first variable
890  m1 = r1[0]/r0[0]; m2 = r2[0]/r0[0]; m3 = r3[0]/r0[0];
891  s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s;
892  s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s;
893  s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s;
894  s = r0[4];
895  if (s != 0.0) { r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s; }
896  s = r0[5];
897  if (s != 0.0) { r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s; }
898  s = r0[6];
899  if (s != 0.0) { r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s; }
900  s = r0[7];
901  if (s != 0.0) { r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s; }
902 
903  // choose pivot
904  if (fabs(r3[1])>fabs(r2[1])) SWAP_ROWS(r3, r2);
905  if (fabs(r2[1])>fabs(r1[1])) SWAP_ROWS(r2, r1);
906  if (0.0 == r1[1])
907  {
908  return (false);
909  }
910 
911  // eliminate second variable
912  m2 = r2[1]/r1[1]; m3 = r3[1]/r1[1];
913  r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2];
914  r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3];
915  s = r1[4]; if (0.0 != s) { r2[4] -= m2 * s; r3[4] -= m3 * s; }
916  s = r1[5]; if (0.0 != s) { r2[5] -= m2 * s; r3[5] -= m3 * s; }
917  s = r1[6]; if (0.0 != s) { r2[6] -= m2 * s; r3[6] -= m3 * s; }
918  s = r1[7]; if (0.0 != s) { r2[7] -= m2 * s; r3[7] -= m3 * s; }
919 
920  // choose pivot
921  if (fabs(r3[2])>fabs(r2[2])) SWAP_ROWS(r3, r2);
922  if (0.0 == r2[2])
923  {
924  return (false);
925  }
926 
927  // eliminate third variable
928  m3 = r3[2]/r2[2];
929  r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4],
930  r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6],
931  r3[7] -= m3 * r2[7];
932 
933  // last check
934  if (0.0 == r3[3])
935  {
936  return (false);
937  }
938 
939  s = 1.0/r3[3];
940  r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s;
941 
942  m2 = r2[3];
943  s = 1.0/r2[2];
944  r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2),
945  r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2);
946  m1 = r1[3];
947  r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1,
948  r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1;
949  m0 = r0[3];
950  r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0,
951  r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0;
952 
953  m1 = r1[2];
954  s = 1.0/r1[1];
955  r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1),
956  r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1);
957  m0 = r0[2];
958  r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0,
959  r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0;
960 
961  m0 = r0[1];
962  s = 1.0/r0[0];
963  r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0),
964  r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0);
965 
966  MAT(mat,0,0) = r0[4]; MAT(mat,0,1) = r0[5],
967  MAT(mat,0,2) = r0[6]; MAT(mat,0,3) = r0[7],
968  MAT(mat,1,0) = r1[4]; MAT(mat,1,1) = r1[5],
969  MAT(mat,1,2) = r1[6]; MAT(mat,1,3) = r1[7],
970  MAT(mat,2,0) = r2[4]; MAT(mat,2,1) = r2[5],
971  MAT(mat,2,2) = r2[6]; MAT(mat,2,3) = r2[7],
972  MAT(mat,3,0) = r3[4]; MAT(mat,3,1) = r3[5],
973  MAT(mat,3,2) = r3[6]; MAT(mat,3,3) = r3[7];
974 
975  return (true);
976 
977  // Macros used during inversion
978  #undef MAT
979  #undef SWAP_ROWS
980  }
981  }
982 
983 
984  //--------------------------------------------------------------------------
999  //--------------------------------------------------------------------------
1000  inline std::string str(const int a_precision)
1001  {
1002  std::string result;
1003  result.append("[ ");
1004  for (int i=0; i<4; i++)
1005  {
1006  result.append("( ");
1007  for (int j=0; j<4; j++)
1008  {
1009  result.append(cStr(m[j][i], a_precision));
1010  if (j<3)
1011  {
1012  result.append(", ");
1013  }
1014  }
1015  result.append(" ) ");
1016  }
1017  result.append("]");
1018 
1019  return (result);
1020  }
1021 
1022 
1024  inline double& operator() (const int a_index0, const int a_index1)
1025  {
1026  return m[a_index1][a_index0];
1027  }
1028 
1029 
1031  inline const double& operator() (const int a_index0, const int a_index1) const
1032  {
1033  return m[a_index1][a_index0];
1034  }
1035 
1036 
1037  //-----------------------------------------------------------------------
1038  // PUBLIC MEMBERS:
1039  //--------------------------------------------------------------------------
1040 
1041 public:
1042 
1044  double m[4][4];
1045 
1048 };
1049 
1050 
1051 //==============================================================================
1052 // Operators on cTransform
1053 //==============================================================================
1054 
1055 //------------------------------------------------------------------------------
1059 //------------------------------------------------------------------------------
1060 inline cTransform operator*(const cTransform& a_matrix1,
1061  const cTransform& a_matrix2)
1062 {
1063  cTransform result;
1064  a_matrix1.mulr(a_matrix2, result);
1065  return (result);
1066 }
1067 
1068 //------------------------------------------------------------------------------
1072 //------------------------------------------------------------------------------
1073 inline cVector3d operator*(const cTransform& a_matrix,
1074  const cVector3d& a_vector)
1075 {
1076  cVector3d result;
1077  a_matrix.mulr(a_vector, result);
1078  return (result);
1079 }
1080 
1081 
1082 //------------------------------------------------------------------------------
1083 } // namespace chai3d
1084 //------------------------------------------------------------------------------
1085 
1086 //------------------------------------------------------------------------------
1087 #endif
1088 //------------------------------------------------------------------------------
This class implements a 3D vector.
Definition: CVector3d.h:88
std::string str(const int a_precision)
This method converts this matrix to a string representation.
Definition: CTransform.h:1000
void trans()
This method computes the transpose of this matrix.
Definition: CTransform.h:766
cTransform(const cVector3d &a_pos, const cMatrix3d &a_rot)
Constructor of cTransform.
Definition: CTransform.h:108
void identity()
This method builds an identity matrix.
Definition: CTransform.h:584
double * getData()
This method returns a pointer to the matrix array in memory.
Definition: CTransform.h:468
bool m_flagTransform
If true then matrix encodes a translation and rotation matrix. If false matrix is represents a genera...
Definition: CTransform.h:1047
double m[4][4]
Transformation matrix data.
Definition: CTransform.h:1044
cTransform(const cMatrix3d &a_rot)
Constructor of cTransform.
Definition: CTransform.h:146
cVector3d operator*(const cMatrix3d &a_matrix, const cVector3d &a_vector)
An overloaded * operator for matrix/vector multiplication.
Definition: CMatrix3d.h:2078
std::string cStr(const bool a_value)
This function converts a boolean into a string.
Definition: CString.cpp:189
void setFrustumMatrix(double a_l, double a_r, double a_b, double a_t, double a_n, double a_f)
This method creates a frustum matrix.
Definition: CTransform.h:278
void mulr(const cTransform &a_matrix, cTransform &a_result) const
This method left-multiplies this matrix with a transformation matrix passed as argument.
Definition: CTransform.h:680
cVector3d getLocalPos() const
This method returns the translational component of this matrix.
Definition: CTransform.h:485
void copyfrom(const cTransform &a_source)
This method copies all elements from another matrix to this one.
Definition: CTransform.h:559
void setPerspectiveMatrix(const double a_fovy, const double a_aspect, const double a_zNear, const double a_zFar)
This method builds a perspective matrix.
Definition: CTransform.h:438
void setLookAtMatrix(const cVector3d &a_eye, const cVector3d &a_lookAt, const cVector3d &a_up)
This method build a transformation matrix.
Definition: CTransform.h:410
void setLocalRot(const cMatrix3d &a_rot)
This method Builds a transformation matrix from a rotation matrix.
Definition: CTransform.h:184
void mul(const cTransform &a_matrix)
This method left-multiplies this matrix with a transformation matrix passed as argument.
Definition: CTransform.h:614
const double C_PI
PI constant.
Definition: CConstants.h:88
void copyto(cTransform &a_destination) const
This method copies all elements of this matrix to another matrix.
Definition: CTransform.h:528
This class implements a 3D matrix.
Definition: CMatrix3d.h:97
This class implements a 4D transformation matrix encoded as column-major.
Definition: CTransform.h:75
double & operator()(const int a_index0, const int a_index1)
An overloaded () operator.
Definition: CTransform.h:1024
cTransform(const cVector3d &a_pos)
Constructor of cTransform.
Definition: CTransform.h:127
void set(const double &a_value)
This method initializes all elements of this matrix with an input value.
Definition: CMatrix3d.h:345
cTransform()
Definition: CTransform.h:88
void setLocalPos(const cVector3d &a_pos)
This method builds a transformation matrix from a position vector.
Definition: CTransform.h:166
Implements a 3D matrix.
void transr(cTransform &a_result) const
This method computes the transpose of this matrix.
Definition: CTransform.h:792
void mulr(const cVector3d &a_vector, cVector3d &a_result) const
This method multiplies this matrix by a vector passed as argument.
Definition: CTransform.h:746
bool invert()
This method computes the inverse of this matrix.
Definition: CTransform.h:828
cMatrix3d getLocalRot() const
This method returns the rotation component of this matrix.
Definition: CTransform.h:502
Definition: CAudioBuffer.cpp:56
void setLookAtMatrix(const double a_eyeX, const double a_eyeY, const double a_eyeZ, const double a_centerX, const double a_centerY, const double a_centerZ, const double a_upX, const double a_upY, const double a_upZ)
This method build a transformation matrix.
Definition: CTransform.h:329