Subversion Repositories gelsvn

Rev

Rev 325 | Details | Compare with Previous | Last modification | View Log | RSS feed

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