Subversion Repositories gelsvn

Rev

Rev 2 | Rev 89 | 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