/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * Copyright (C) 2003-2005 3Dlabs Inc. Ltd. * Copyright (C) 2008 Zebra Imaging * Copyright (C) 2012 David Callu * * This application is open source and may be redistributed and/or modified * freely and without restriction, both in commercial and non commercial * applications, as long as this copyright notice is maintained. * * This application is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ /* file: include/osg/MatrxTemplate * author: Mike Weiblen 2008-01-02 */ #ifndef OSG_MATRIXTEMPLATE #define OSG_MATRIXTEMPLATE 1 namespace osg { /////////////////////////////////////////////////////////////////////////// // C++ classes to represent the GLSL-specific types. // // Warning : // OSG is Row major // GLSL is Column Major // // If you define an Uniform with type Uniform::FLOAT_MAT4X2 and so use a Matrix4x2 to setup your Uniform, // like this : // 1 2 // 3 4 // 5 6 // 7 8 // // you will get in your shader a Column Major Matrix like this : // 1 3 5 7 // 2 4 6 8 // // In simple term, you matrix in OSG will be a transposed matrix in GLSL // // // You can avoid this behaviours starting GLSL version 1.40 with uniform layout : // // // layout(row_major) uniform matrix4x2 myVariable; // // // template class TemplateMatrix { public: enum { col_count = ColN }; enum { row_count = RowN }; enum { value_count = ColN * RowN }; typedef T value_type; public: TemplateMatrix() {} ~TemplateMatrix() {} value_type& operator()(int row, int col) { return _mat[row][col]; } value_type operator()(int row, int col) const { return _mat[row][col]; } TemplateMatrix& operator = (const TemplateMatrix& rhs) { if( &rhs == this ) return *this; set(rhs.ptr()); return *this; } void set(const TemplateMatrix& rhs) { set(rhs.ptr()); } void set(value_type const * const ptr) { value_type* local_ptr = (value_type*)_mat; for(int i=0;i(0.0); } protected: value_type _mat[row_count][col_count]; }; template class Matrix2Template : public TemplateMatrix { public: typedef TemplateMatrix base_class; typedef typename base_class::value_type value_type; public: Matrix2Template() { makeIdentity(); } Matrix2Template( const Matrix2Template& mat ) { set(mat.ptr()); } Matrix2Template( value_type a00, value_type a01, value_type a10, value_type a11 ) { set( a00, a01, a10, a11 ); } ~Matrix2Template() {} using base_class::set; void set(value_type a00, value_type a01, value_type a10, value_type a11 ) { base_class::_mat[0][0]=a00; base_class::_mat[0][1]=a01; base_class::_mat[1][0]=a10; base_class::_mat[1][1]=a11; } void makeIdentity() { set( 1, 0, 0, 1 ); } }; template class Matrix2x3Template : public TemplateMatrix { public: typedef TemplateMatrix base_class; typedef typename base_class::value_type value_type; public: Matrix2x3Template() { base_class::reset(); } Matrix2x3Template( const Matrix2x3Template& mat ) { set(mat.ptr()); } Matrix2x3Template( value_type a00, value_type a01, value_type a02, value_type a10, value_type a11, value_type a12 ) { set( a00, a01, a02, a10, a11, a12 ); } ~Matrix2x3Template() {} using base_class::set; void set( value_type a00, value_type a01, value_type a02, value_type a10, value_type a11, value_type a12 ) { base_class::_mat[0][0]=a00; base_class::_mat[0][1]=a01; base_class::_mat[0][2]=a02; base_class::_mat[1][0]=a10; base_class::_mat[1][1]=a11; base_class::_mat[1][2]=a12; } }; template class Matrix2x4Template : public TemplateMatrix { public: typedef TemplateMatrix base_class; typedef typename base_class::value_type value_type; public: Matrix2x4Template() { base_class::reset(); } Matrix2x4Template( const Matrix2x4Template& mat ) { set(mat.ptr()); } Matrix2x4Template( value_type a00, value_type a01, value_type a02, value_type a03, value_type a10, value_type a11, value_type a12, value_type a13 ) { set( a00, a01, a02, a03, a10, a11, a12, a13 ); } ~Matrix2x4Template() {} using base_class::set; void set( value_type a00, value_type a01, value_type a02, value_type a03, value_type a10, value_type a11, value_type a12, value_type a13 ) { base_class::_mat[0][0]=a00; base_class::_mat[0][1]=a01; base_class::_mat[0][2]=a02; base_class::_mat[0][3]=a03; base_class::_mat[1][0]=a10; base_class::_mat[1][1]=a11; base_class::_mat[1][2]=a12; base_class::_mat[1][3]=a13; } }; template class Matrix3x2Template : public TemplateMatrix { public: typedef TemplateMatrix base_class; typedef typename base_class::value_type value_type; public: Matrix3x2Template() { base_class::reset(); } Matrix3x2Template( const Matrix3x2Template& mat ) { set(mat.ptr()); } Matrix3x2Template( value_type a00, value_type a01, value_type a10, value_type a11, value_type a20, value_type a21 ) { set( a00, a01, a10, a11, a20, a21 ); } ~Matrix3x2Template() {} using base_class::set; void set( value_type a00, value_type a01, value_type a10, value_type a11, value_type a20, value_type a21 ) { base_class::_mat[0][0]=a00; base_class::_mat[0][1]=a01; base_class::_mat[1][0]=a10; base_class::_mat[1][1]=a11; base_class::_mat[2][0]=a20; base_class::_mat[2][1]=a21; } }; template class Matrix3Template : public TemplateMatrix { public: typedef TemplateMatrix base_class; typedef typename base_class::value_type value_type; public: Matrix3Template() { base_class::reset(); } Matrix3Template( const Matrix3Template& mat ) { set(mat.ptr()); } Matrix3Template( value_type a00, value_type a01, value_type a02, value_type a10, value_type a11, value_type a12, value_type a20, value_type a21, value_type a22 ) { set( a00, a01, a02, a10, a11, a12, a20, a21, a22 ); } ~Matrix3Template() {} using base_class::set; void set( value_type a00, value_type a01, value_type a02, value_type a10, value_type a11, value_type a12, value_type a20, value_type a21, value_type a22 ) { base_class::_mat[0][0]=a00; base_class::_mat[0][1]=a01; base_class::_mat[0][2]=a02; base_class::_mat[1][0]=a10; base_class::_mat[1][1]=a11; base_class::_mat[1][2]=a12; base_class::_mat[2][0]=a20; base_class::_mat[2][1]=a21; base_class::_mat[2][2]=a22; } void makeIdentity() { set( 1, 0, 0, 0, 1, 0, 0, 0, 1 ); } }; template class Matrix3x4Template : public TemplateMatrix { public: typedef TemplateMatrix base_class; typedef typename base_class::value_type value_type; public: Matrix3x4Template() { base_class::reset(); } Matrix3x4Template( const Matrix3x4Template& mat ) { set(mat.ptr()); } Matrix3x4Template( value_type a00, value_type a01, value_type a02, value_type a03, value_type a10, value_type a11, value_type a12, value_type a13, value_type a20, value_type a21, value_type a22, value_type a23 ) { set( a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23 ); } ~Matrix3x4Template() {} using base_class::set; void set( value_type a00, value_type a01, value_type a02, value_type a03, value_type a10, value_type a11, value_type a12, value_type a13, value_type a20, value_type a21, value_type a22, value_type a23 ) { base_class::_mat[0][0]=a00; base_class::_mat[0][1]=a01; base_class::_mat[0][2]=a02; base_class::_mat[0][3]=a03; base_class::_mat[1][0]=a10; base_class::_mat[1][1]=a11; base_class::_mat[1][2]=a12; base_class::_mat[1][3]=a13; base_class::_mat[2][0]=a20; base_class::_mat[2][1]=a21; base_class::_mat[2][2]=a22; base_class::_mat[2][3]=a23; } }; template class Matrix4x2Template : public TemplateMatrix { public: typedef TemplateMatrix base_class; typedef typename base_class::value_type value_type; public: Matrix4x2Template() { base_class::reset(); } Matrix4x2Template( const Matrix4x2Template& mat ) { set(mat.ptr()); } Matrix4x2Template( value_type a00, value_type a01, value_type a10, value_type a11, value_type a20, value_type a21, value_type a30, value_type a31 ) { set( a00, a01, a10, a11, a20, a21, a30, a31 ); } ~Matrix4x2Template() {} using base_class::set; void set( value_type a00, value_type a01, value_type a10, value_type a11, value_type a20, value_type a21, value_type a30, value_type a31 ) { base_class::_mat[0][0]=a00; base_class::_mat[0][1]=a01; base_class::_mat[1][0]=a10; base_class::_mat[1][1]=a11; base_class::_mat[2][0]=a20; base_class::_mat[2][1]=a21; base_class::_mat[3][0]=a30; base_class::_mat[3][1]=a31; } }; template class Matrix4x3Template : public TemplateMatrix { public: typedef TemplateMatrix base_class; typedef typename base_class::value_type value_type; public: Matrix4x3Template() { base_class::reset(); } Matrix4x3Template( const Matrix4x3Template& mat ) { set(mat.ptr()); } Matrix4x3Template( value_type a00, value_type a01, value_type a02, value_type a10, value_type a11, value_type a12, value_type a20, value_type a21, value_type a22, value_type a30, value_type a31, value_type a32 ) { set( a00, a01, a02, a10, a11, a12, a20, a21, a22, a30, a31, a32 ); } ~Matrix4x3Template() {} using base_class::set; void set( value_type a00, value_type a01, value_type a02, value_type a10, value_type a11, value_type a12, value_type a20, value_type a21, value_type a22, value_type a30, value_type a31, value_type a32 ) { base_class::_mat[0][0]=a00; base_class::_mat[0][1]=a01; base_class::_mat[0][2]=a02; base_class::_mat[1][0]=a10; base_class::_mat[1][1]=a11; base_class::_mat[1][2]=a12; base_class::_mat[2][0]=a20; base_class::_mat[2][1]=a21; base_class::_mat[2][2]=a22; base_class::_mat[3][0]=a30; base_class::_mat[3][1]=a31; base_class::_mat[3][2]=a32; } }; typedef Matrix2Template Matrix2; typedef Matrix2x3Template Matrix2x3; typedef Matrix2x4Template Matrix2x4; typedef Matrix3x2Template Matrix3x2; typedef Matrix3Template Matrix3; typedef Matrix3x4Template Matrix3x4; typedef Matrix4x2Template Matrix4x2; typedef Matrix4x3Template Matrix4x3; typedef Matrix2Template Matrix2d; typedef Matrix2x3Template Matrix2x3d; typedef Matrix2x4Template Matrix2x4d; typedef Matrix3x2Template Matrix3x2d; typedef Matrix3Template Matrix3d; typedef Matrix3x4Template Matrix3x4d; typedef Matrix4x2Template Matrix4x2d; typedef Matrix4x3Template Matrix4x3d; } #endif