Subversion Repositories gelsvn

Rev

Rev 325 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 325 Rev 393
1
#ifndef __CGLA_ARITHSQMAT4X4FLOAT_H
1
#ifndef __CGLA_ARITHSQMAT4X4FLOAT_H
2
#define __CGLA_ARITHSQMAT4X4FLOAT_H
2
#define __CGLA_ARITHSQMAT4X4FLOAT_H
3
 
3
 
4
#include "ExceptionStandard.h"
4
#include "ExceptionStandard.h"
5
#include "CGLA.h"
5
#include "CGLA.h"
6
#include "Vec3f.h"
6
#include "Vec3f.h"
7
#include "Vec3Hf.h"
7
#include "Vec3Hf.h"
8
#include "Vec4f.h"
8
#include "Vec4f.h"
9
#include "ArithSqMatFloat.h"
9
#include "ArithSqMatFloat.h"
10
 
10
 
11
 
11
 
12
namespace CGLA 
12
namespace CGLA 
13
{
13
{
14
  CGLA_DERIVEEXCEPTION(Mat4x4fException)
14
  CGLA_DERIVEEXCEPTION(Mat4x4fException)
15
  CGLA_DERIVEEXCEPTION(Mat4x4fNotAffine)
15
  CGLA_DERIVEEXCEPTION(Mat4x4fNotAffine)
16
  CGLA_DERIVEEXCEPTION(Mat4x4fSingular)
16
  CGLA_DERIVEEXCEPTION(Mat4x4fSingular)
17
    
17
    
18
  /** \brief 4 by 4 float matrix template.
18
  /** \brief 4 by 4 float matrix template.
19
			
19
			
20
      this class template is useful for transformations such as perspective 
20
      this class template is useful for transformations such as perspective 
21
      projections or translation where 3x3 matrices do not suffice. */
21
      projections or translation where 3x3 matrices do not suffice. */
22
  template<class VT, class M>
22
  template<class VT, class M>
23
  class ArithSqMat4x4Float: public ArithSqMatFloat<VT, M, 4>
23
  class ArithSqMat4x4Float: public ArithSqMatFloat<VT, M, 4>
24
  {
24
  {
25
  public:
25
  public:
26
    
26
    
27
    /// Vector type
27
    /// Vector type
28
    typedef VT VectorType;
28
    typedef VT VectorType;
29
    
29
    
30
    /// The type of a matrix element
30
    /// The type of a matrix element
31
    typedef typename VT::ScalarType ScalarType;
31
    typedef typename VT::ScalarType ScalarType;
32
    
32
    
33
  public:
33
  public:
34
    
34
    
35
    /// Construct a Mat4x4f from four V vectors
35
    /// Construct a Mat4x4f from four V vectors
36
    ArithSqMat4x4Float(VT a, VT b, VT c, VT d): 
36
    ArithSqMat4x4Float(VT a, VT b, VT c, VT d): 
37
      ArithSqMatFloat<VT, M, 4> (a,b,c,d) {}
37
      ArithSqMatFloat<VT, M, 4> (a,b,c,d) {}
38
  
38
  
39
    /// Construct the NAN matrix
39
    /// Construct the NAN matrix
40
    ArithSqMat4x4Float() {}
40
    ArithSqMat4x4Float() {}
41
 
41
 
42
    /// Construct matrix where all values are equal to constructor argument.
42
    /// Construct matrix where all values are equal to constructor argument.
43
    explicit ArithSqMat4x4Float(ScalarType  _a):
43
    explicit ArithSqMat4x4Float(ScalarType  _a):
44
      ArithSqMatFloat<VT,M,4>(_a) {}
44
      ArithSqMatFloat<VT,M,4>(_a) {}
45
 
45
 
46
    /** Multiply vector onto matrix. Here the fourth coordinate 
46
    /** Multiply vector onto matrix. Here the fourth coordinate 
47
	is se to 0. This removes any translation from the matrix.
47
	is se to 0. This removes any translation from the matrix.
48
	Useful if one wants to transform a vector which does not
48
	Useful if one wants to transform a vector which does not
49
	represent a point but a direction. Note that this is not
49
	represent a point but a direction. Note that this is not
50
	correct for transforming normal vectors if the matric 
50
	correct for transforming normal vectors if the matric 
51
	contains anisotropic scaling. */
51
	contains anisotropic scaling. */
52
    template<class T, class VecT>
52
    template<class T, class VecT>
53
    const VecT mul_3D_vector(const ArithVec3Float<T,VecT>& v_in) const
53
    const VecT mul_3D_vector(const ArithVec3Float<T,VecT>& v_in) const
54
    {
54
    {
55
      VT v_out  = (*this) * VT(v_in[0],v_in[1],v_in[2],0);
55
      VT v_out  = (*this) * VT(v_in[0],v_in[1],v_in[2],0);
56
      return VecT(v_out[0],v_out[1],v_out[2]);
56
      return VecT(v_out[0],v_out[1],v_out[2]);
57
    }
57
    }
58
 
58
 
59
    /** Multiply 3D point onto matrix. Here the fourth coordinate 
59
    /** Multiply 3D point onto matrix. Here the fourth coordinate 
60
	becomes 1 to ensure that the point is translated. Note that
60
	becomes 1 to ensure that the point is translated. Note that
61
	the vector is converted back into a Vec3f without any 
61
	the vector is converted back into a Vec3f without any 
62
	division by w. This is deliberate: Typically, w=1 except
62
	division by w. This is deliberate: Typically, w=1 except
63
	for projections. If we are doing projection, we can use
63
	for projections. If we are doing projection, we can use
64
	project_3D_point instead */
64
	project_3D_point instead */
65
    template<class T, class VecT>
65
    template<class T, class VecT>
66
    const VecT mul_3D_point(const ArithVec3Float<T,VecT> & v_in) const
66
    const VecT mul_3D_point(const ArithVec3Float<T,VecT> & v_in) const
67
    {
67
    {
68
      VT v_out  = (*this) * VT(v_in[0],v_in[1],v_in[2],1);
68
      VT v_out  = (*this) * VT(v_in[0],v_in[1],v_in[2],1);
69
      return VecT(v_out[0],v_out[1],v_out[2]);
69
      return VecT(v_out[0],v_out[1],v_out[2]);
70
    }
70
    }
71
 
71
 
72
    /** Multiply 3D point onto matrix. We set w=1 before 
72
    /** Multiply 3D point onto matrix. We set w=1 before 
73
	multiplication and divide by w after multiplication. */
73
	multiplication and divide by w after multiplication. */
74
    template<class T, class VecT>
74
    template<class T, class VecT>
75
    const VecT project_3D_point(const ArithVec3Float<T,VecT>& v_in) const
75
    const VecT project_3D_point(const ArithVec3Float<T,VecT>& v_in) const
76
    {
76
    {
77
      VT v_out = (*this) * VT(v_in[0],v_in[1],v_in[2],1);
77
      VT v_out = (*this) * VT(v_in[0],v_in[1],v_in[2],1);
78
      v_out.de_homogenize();
78
      v_out.de_homogenize();
79
      return VecT(v_out[0],v_out[1],v_out[2]);
79
      return VecT(v_out[0],v_out[1],v_out[2]);
80
    }
80
    }
81
 
81
 
82
  };
82
  };
83
 
83
 
84
  /** Compute the adjoint of a matrix. This is the matrix where each
84
  /** Compute the adjoint of a matrix. This is the matrix where each
85
      entry is the subdeterminant of 'in' where the row and column of 
85
      entry is the subdeterminant of 'in' where the row and column of 
86
      the element is removed. Use mostly to compute the inverse */
86
      the element is removed. Use mostly to compute the inverse */
87
  template<class VT, class M>
87
  template<class VT, class M>
88
  M adjoint(const ArithSqMat4x4Float<VT,M>&);
88
  M adjoint(const ArithSqMat4x4Float<VT,M>&);
89
		
89
		
90
	/** Compute the determinant of a 4x4 matrix. The code below is what
90
	/** Compute the determinant of a 4x4 matrix. The code below is what
91
			I found to be most robust. The original implementation used direct
91
			I found to be most robust. The original implementation used direct
92
			computation of the 3x3 sub-determinants and I also tried a direct
92
			computation of the 3x3 sub-determinants and I also tried a direct
93
			computation based on enumerating all permutations. The code below
93
			computation based on enumerating all permutations. The code below
94
			is better. */
94
			is better. */
95
	template<class V, class M>
95
	template<class V, class M>
96
			inline double determinant(const ArithSqMat4x4Float<V,M>& m)
96
			inline double determinant(const ArithSqMat4x4Float<V,M>& m)
97
			{
97
			{
98
/* 					return m[0][0] * (m[1][1]*(m[2][2]*m[3][3]-m[3][2]*m[2][3])- */
98
/* 					return m[0][0] * (m[1][1]*(m[2][2]*m[3][3]-m[3][2]*m[2][3])- */
99
/* 														m[2][1]*(m[1][2]*m[3][3]-m[3][2]*m[1][3])+ */
99
/* 														m[2][1]*(m[1][2]*m[3][3]-m[3][2]*m[1][3])+ */
100
/* 														m[3][1]*(m[1][2]*m[2][3]-m[2][2]*m[1][3])) */
100
/* 														m[3][1]*(m[1][2]*m[2][3]-m[2][2]*m[1][3])) */
101
/* 							- m[1][0] * (m[0][1]*(m[2][2]*m[3][3]-m[3][2]*m[2][3])- */
101
/* 							- m[1][0] * (m[0][1]*(m[2][2]*m[3][3]-m[3][2]*m[2][3])- */
102
/* 													 m[2][1]*(m[0][2]*m[3][3]-m[3][2]*m[0][3])+ */
102
/* 													 m[2][1]*(m[0][2]*m[3][3]-m[3][2]*m[0][3])+ */
103
/* 													 m[3][1]*(m[0][2]*m[2][3]-m[2][2]*m[0][3])) */
103
/* 													 m[3][1]*(m[0][2]*m[2][3]-m[2][2]*m[0][3])) */
104
/* 							+ m[2][0] * (m[0][1]*(m[1][2]*m[3][3]-m[3][2]*m[1][3])- */
104
/* 							+ m[2][0] * (m[0][1]*(m[1][2]*m[3][3]-m[3][2]*m[1][3])- */
105
/* 													 m[1][1]*(m[0][2]*m[3][3]-m[3][2]*m[0][3])+ */
105
/* 													 m[1][1]*(m[0][2]*m[3][3]-m[3][2]*m[0][3])+ */
106
/* 													 m[3][1]*(m[0][2]*m[1][3]-m[1][2]*m[0][3])) */
106
/* 													 m[3][1]*(m[0][2]*m[1][3]-m[1][2]*m[0][3])) */
107
/* 							- m[3][0] * (m[0][1]*(m[1][2]*m[2][3]-m[2][2]*m[1][3])- */
107
/* 							- m[3][0] * (m[0][1]*(m[1][2]*m[2][3]-m[2][2]*m[1][3])- */
108
/* 													 m[1][1]*(m[0][2]*m[2][3]-m[2][2]*m[0][3])+ */
108
/* 													 m[1][1]*(m[0][2]*m[2][3]-m[2][2]*m[0][3])+ */
109
/* 													 m[2][1]*(m[0][2]*m[1][3]-m[1][2]*m[0][3])); */
109
/* 													 m[2][1]*(m[0][2]*m[1][3]-m[1][2]*m[0][3])); */
110
		typedef typename M::ScalarType ScalarType;
110
		typedef typename M::ScalarType ScalarType;
111
    ScalarType a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4;
111
    ScalarType a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4;
112
    
112
    
113
    /* assign to individual variable names to aid selecting */
113
    /* assign to individual variable names to aid selecting */
114
		/*  correct elements */
114
		/*  correct elements */
115
		
115
		
116
		a1 = m[0][0]; b1 = m[1][0]; c1 = m[2][0]; d1 = m[3][0];
116
		a1 = m[0][0]; b1 = m[1][0]; c1 = m[2][0]; d1 = m[3][0];
117
		a2 = m[0][1]; b2 = m[1][1]; c2 = m[2][1]; d2 = m[3][1];
117
		a2 = m[0][1]; b2 = m[1][1]; c2 = m[2][1]; d2 = m[3][1];
118
		a3 = m[0][2]; b3 = m[1][2]; c3 = m[2][2]; d3 = m[3][2];
118
		a3 = m[0][2]; b3 = m[1][2]; c3 = m[2][2]; d3 = m[3][2];
119
		a4 = m[0][3]; b4 = m[1][3]; c4 = m[2][3]; d4 = m[3][3];
119
		a4 = m[0][3]; b4 = m[1][3]; c4 = m[2][3]; d4 = m[3][3];
120
 
120
 
121
					return 
121
					return 
122
							a1 * (b2*(c3*d4-d3*c4)-c2*(b3*d4-d3*b4)+d2*(b3*c4-c3*b4))
122
							a1 * (b2*(c3*d4-d3*c4)-c2*(b3*d4-d3*b4)+d2*(b3*c4-c3*b4))
123
							- b1 * (a2*(c3*d4-d3*c4)-c2*(a3*d4-d3*a4)+d2*(a3*c4-c3*a4))
123
							- b1 * (a2*(c3*d4-d3*c4)-c2*(a3*d4-d3*a4)+d2*(a3*c4-c3*a4))
124
							+ c1 * (a2*(b3*d4-d3*b4)-b2*(a3*d4-d3*a4)+d2*(a3*b4-b3*a4))
124
							+ c1 * (a2*(b3*d4-d3*b4)-b2*(a3*d4-d3*a4)+d2*(a3*b4-b3*a4))
125
							- d1 * (a2*(b3*c4-c3*b4)-b2*(a3*c4-c3*a4)+c2*(a3*b4-b3*a4));
125
							- d1 * (a2*(b3*c4-c3*b4)-b2*(a3*c4-c3*a4)+c2*(a3*b4-b3*a4));
126
 
126
 
127
			}
127
			}
128
 
128
 
129
  /// Compute the inverse matrix of a Mat4x4f.
129
  /// Compute the inverse matrix of a Mat4x4f.
130
  template<class VT, class M>
130
  template<class VT, class M>
131
  M invert(const ArithSqMat4x4Float<VT,M>&);
131
  M invert(const ArithSqMat4x4Float<VT,M>&);
132
 
132
 
133
  /// Compute the inverse matrix of a Mat4x4f that is affine
133
  /// Compute the inverse matrix of a Mat4x4f that is affine
134
  template<class VT, class M>
134
  template<class VT, class M>
135
  M invert_affine(const ArithSqMat4x4Float<VT,M>&);
135
  M invert_affine(const ArithSqMat4x4Float<VT,M>&);
136
 
136
 
137
}
137
}
138
#endif
138
#endif
139
 
139
 
140
 
140
 
141
 
141
 
142
 
142
 
143
 
143
 
144
 
144
 
145
 
145
 
146
 
146