Rev 2 | Rev 12 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
#ifndef __CGLA_ARITHSQMAT4X4FLOAT_H
#define __CGLA_ARITHSQMAT4X4FLOAT_H
#include "ExceptionStandard.h"
#include "CGLA.h"
#include "Vec3f.h"
#include "Vec3Hf.h"
#include "Vec4f.h"
#include "ArithSqMatFloat.h"
namespace CGLA {
CGLA_DERIVEEXCEPTION(Mat4x4fException)
CGLA_DERIVEEXCEPTION(Mat4x4fNotAffine)
CGLA_DERIVEEXCEPTION(Mat4x4fSingular)
/** Four by four float matrix.
This class is useful for transformations such as perspective projections
or translation where 3x3 matrices do not suffice. */
template<class V, class M>
class ArithSqMat4x4Float: public ArithSqMatFloat<V, M, 4>
{
public:
/// Construct a Mat4x4f from four V vectors
ArithSqMat4x4Float(V a, V b, V c, V d):
ArithSqMatFloat<V, M, 4> (a,b,c,d) {}
/// Construct the NAN matrix
ArithSqMat4x4Float() {}
/// Construct matrix where all values are equal to constructor argument.
/**** SHOULD NOT USE DOUBLE BELOW. USE WHATEVER TYPE SAYS ****/
explicit ArithSqMat4x4Float(double _a):
ArithSqMatFloat<V,M,4>(_a) {}
/// Construct from a pointed to array of 16 floats.
ArithSqMat4x4Float(const float* sa): ArithSqMatFloat<V, M, 4> (sa) {}
/** Multiply vector onto matrix. Here the fourth coordinate
is se to 0. This removes any translation from the matrix.
Useful if one wants to transform a vector which does not
represent a point but a direction. Note that this is not
correct for transforming normal vectors if the matric
contains anisotropic scaling. */
template<class T, class VecT>
const VecT mul_3D_vector(const ArithVec3Float<T,VecT>& v_in) const
{
V v_out = (*this) * V(v_in[0],v_in[1],v_in[2],0);
return VecT(v_out[0],v_out[1],v_out[2]);
}
/** Multiply 3D point onto matrix. Here the fourth coordinate
becomes 1 to ensure that the point is translated. Note that
the vector is converted back into a Vec3f without any
division by w. This is deliberate: Typically, w=1 except
for projections. If we are doing projection, we can use
project_3D_point instead */
template<class T, class VecT>
const VecT mul_3D_point(const ArithVec3Float<T,VecT> & v_in) const
{
V v_out = (*this) * V(v_in[0],v_in[1],v_in[2],1);
return VecT(v_out[0],v_out[1],v_out[2]);
}
/** Multiply 3D point onto matrix. We set w=1 before
multiplication and divide by w after multiplication. */
template<class T, class VecT>
const VecT project_3D_point(const ArithVec3Float<T,VecT>& v_in) const
{
V v_out = (*this) * V(v_in[0],v_in[1],v_in[2],1);
v_out.de_homogenize();
return VecT(v_out[0],v_out[1],v_out[2]);
}
};
/** Compute the adjoint of a matrix. This is the matrix where each
entry is the subdeterminant of 'in' where the row and column of
the element is removed. Use mostly to compute the inverse */
template<class V, class M>
M adjoint(const ArithSqMat4x4Float<V,M>&);
/** Compute the determinant of a 4x4f matrix. */
template<class V, class M>
double
determinant(const ArithSqMat4x4Float<V,M>&);
/// Compute the inverse matrix of a Mat4x4f.
template<class V, class M>
M invert(const ArithSqMat4x4Float<V,M>&);
/// Compute the inverse matrix of a Mat4x4f that is affine
template<class V, class M>
M invert_affine(const ArithSqMat4x4Float<V,M>&);
}
#endif