394 lines
13 KiB
Plaintext
394 lines
13 KiB
Plaintext
|
/* -*-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() {}
|
||
|
|
||
|
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() {}
|
||
|
|
||
|
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() {}
|
||
|
|
||
|
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() {}
|
||
|
|
||
|
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() {}
|
||
|
|
||
|
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() {}
|
||
|
|
||
|
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() {}
|
||
|
|
||
|
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() {}
|
||
|
|
||
|
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
|