OpenSceneGraph/include/osg/MatrixTemplate
2020-08-26 15:19:23 +01:00

450 lines
15 KiB
C++

/* -*-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 :
//
// <GLSL code>
// layout(row_major) uniform matrix4x2 myVariable;
// <GLSL code>
//
//
template <typename T, unsigned int RowN, unsigned int ColN>
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<value_count;++i) local_ptr[i]=ptr[i];
}
value_type* ptr() { return (value_type*)_mat; }
const value_type* ptr() const { return (const value_type*)_mat; }
value_type& operator [] (int i) {return ptr()[i];}
value_type operator [] (int i) const {return ptr()[i];}
void reset() { for(int i=0; i<value_count; ++i) ptr()[i] = static_cast<value_type>(0.0); }
protected:
value_type _mat[row_count][col_count];
};
template <typename T>
class Matrix2Template : public TemplateMatrix<T, 2, 2>
{
public:
typedef TemplateMatrix<T, 2, 2> 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() {}
Matrix2Template& operator = (const Matrix2Template& rhs)
{
if( &rhs == this ) return *this;
set(rhs.ptr());
return *this;
}
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 <typename T>
class Matrix2x3Template : public TemplateMatrix<T, 2, 3>
{
public:
typedef TemplateMatrix<T, 2, 3> 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() {}
Matrix2x3Template& operator = (const Matrix2x3Template& rhs)
{
if( &rhs == this ) return *this;
set(rhs.ptr());
return *this;
}
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 <typename T>
class Matrix2x4Template : public TemplateMatrix<T, 2, 4>
{
public:
typedef TemplateMatrix<T, 2, 4> 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() {}
Matrix2x4Template& operator = (const Matrix2x4Template& rhs)
{
if( &rhs == this ) return *this;
set(rhs.ptr());
return *this;
}
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 <typename T>
class Matrix3x2Template : public TemplateMatrix<T, 3, 2>
{
public:
typedef TemplateMatrix<T, 3, 2> 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() {}
Matrix3x2Template& operator = (const Matrix3x2Template& rhs)
{
if( &rhs == this ) return *this;
set(rhs.ptr());
return *this;
}
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 <typename T>
class Matrix3Template : public TemplateMatrix<T, 3, 3>
{
public:
typedef TemplateMatrix<T, 3, 3> 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() {}
Matrix3Template& operator = (const Matrix3Template& rhs)
{
if( &rhs == this ) return *this;
set(rhs.ptr());
return *this;
}
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 <typename T>
class Matrix3x4Template : public TemplateMatrix<T, 3, 4>
{
public:
typedef TemplateMatrix<T, 3, 4> 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() {}
Matrix3x4Template& operator = (const Matrix3x4Template& rhs)
{
if( &rhs == this ) return *this;
set(rhs.ptr());
return *this;
}
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 <typename T>
class Matrix4x2Template : public TemplateMatrix<T, 4, 2>
{
public:
typedef TemplateMatrix<T, 4, 2> 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() {}
Matrix4x2Template& operator = (const Matrix4x2Template& rhs)
{
if( &rhs == this ) return *this;
set(rhs.ptr());
return *this;
}
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 <typename T>
class Matrix4x3Template : public TemplateMatrix<T, 4, 3>
{
public:
typedef TemplateMatrix<T, 4, 3> 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() {}
Matrix4x3Template& operator = (const Matrix4x3Template& rhs)
{
if( &rhs == this ) return *this;
set(rhs.ptr());
return *this;
}
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<float> Matrix2;
typedef Matrix2x3Template<float> Matrix2x3;
typedef Matrix2x4Template<float> Matrix2x4;
typedef Matrix3x2Template<float> Matrix3x2;
typedef Matrix3Template<float> Matrix3;
typedef Matrix3x4Template<float> Matrix3x4;
typedef Matrix4x2Template<float> Matrix4x2;
typedef Matrix4x3Template<float> Matrix4x3;
typedef Matrix2Template<double> Matrix2d;
typedef Matrix2x3Template<double> Matrix2x3d;
typedef Matrix2x4Template<double> Matrix2x4d;
typedef Matrix3x2Template<double> Matrix3x2d;
typedef Matrix3Template<double> Matrix3d;
typedef Matrix3x4Template<double> Matrix3x4d;
typedef Matrix4x2Template<double> Matrix4x2d;
typedef Matrix4x3Template<double> Matrix4x3d;
}
#endif