867 lines
20 KiB
C
867 lines
20 KiB
C
|
#ifndef BLUECORE_MATRIX_H
|
||
|
#define BLUECORE_MATRIX_H
|
||
|
|
||
|
// system includes
|
||
|
#include <algorithm>
|
||
|
#include <cmath>
|
||
|
|
||
|
// local includes
|
||
|
#include "Scalar.h"
|
||
|
#include "Vector.h"
|
||
|
#include "Quaternion.h"
|
||
|
|
||
|
namespace BlueCore
|
||
|
{
|
||
|
template <class T>
|
||
|
class Matrix3x3Template
|
||
|
{
|
||
|
public:
|
||
|
T m[9];
|
||
|
|
||
|
/**
|
||
|
* default constructor
|
||
|
*/
|
||
|
inline Matrix3x3Template()
|
||
|
{
|
||
|
identity();
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* constructor from array
|
||
|
*/
|
||
|
template <class S>
|
||
|
inline Matrix3x3Template( const S a[9] )
|
||
|
{
|
||
|
m[0] = static_cast<T>(a[0]);
|
||
|
m[1] = static_cast<T>(a[1]);
|
||
|
m[2] = static_cast<T>(a[2]);
|
||
|
|
||
|
m[3] = static_cast<T>(a[3]);
|
||
|
m[4] = static_cast<T>(a[4]);
|
||
|
m[5] = static_cast<T>(a[5]);
|
||
|
|
||
|
m[6] = static_cast<T>(a[6]);
|
||
|
m[7] = static_cast<T>(a[7]);
|
||
|
m[8] = static_cast<T>(a[8]);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* copy constructor
|
||
|
*/
|
||
|
template <class S>
|
||
|
inline Matrix3x3Template( const Matrix3x3Template<S> &a )
|
||
|
{
|
||
|
m[0] = static_cast<T>(a.m[0]);
|
||
|
m[1] = static_cast<T>(a.m[1]);
|
||
|
m[2] = static_cast<T>(a.m[2]);
|
||
|
|
||
|
m[3] = static_cast<T>(a.m[3]);
|
||
|
m[4] = static_cast<T>(a.m[4]);
|
||
|
m[5] = static_cast<T>(a.m[5]);
|
||
|
|
||
|
m[6] = static_cast<T>(a.m[6]);
|
||
|
m[7] = static_cast<T>(a.m[7]);
|
||
|
m[8] = static_cast<T>(a.m[8]);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* constructor from heading and up vectors
|
||
|
*/
|
||
|
inline Matrix3x3Template(
|
||
|
const Vector3Template<T> &h,
|
||
|
const Vector3Template<T> &u )
|
||
|
{
|
||
|
Vector3Template<T> a, b, c;
|
||
|
c = h.unit();
|
||
|
a = h.crossProduct( u ).unit();
|
||
|
b = c.crossProduct( a ).unit();
|
||
|
|
||
|
m[0] = a.x;
|
||
|
m[1] = b.x;
|
||
|
m[2] = c.x;
|
||
|
|
||
|
m[3] = a.y;
|
||
|
m[4] = b.y;
|
||
|
m[5] = c.y;
|
||
|
|
||
|
m[6] = a.z;
|
||
|
m[7] = b.z;
|
||
|
m[8] = c.z;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* contructor from euler angles
|
||
|
*/
|
||
|
inline Matrix3x3Template( T a, T e, T t )
|
||
|
{
|
||
|
T ch = cos( a );
|
||
|
T sh = sin( a );
|
||
|
T ca = cos( e );
|
||
|
T sa = sin( e );
|
||
|
T cb = cos( t );
|
||
|
T sb = sin( t );
|
||
|
|
||
|
m[0] = ch * ca;
|
||
|
m[1] = sh*sb - ch*sa*cb;
|
||
|
m[2] = ch*sa*sb + sh*cb;
|
||
|
|
||
|
m[3] = sa;
|
||
|
m[4] = ca*cb;
|
||
|
m[5] = -ca*sb;
|
||
|
|
||
|
m[6] = -sh*ca;
|
||
|
m[7] = sh*sa*cb + ch*sb;
|
||
|
m[8] = -sh*sa*sb + ch*cb;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* contructor from quaternion
|
||
|
*/
|
||
|
template <class S>
|
||
|
inline Matrix3x3Template( const QuaternionTemplate<S> &q )
|
||
|
{
|
||
|
T xx = static_cast<T>(q.x*q.x),
|
||
|
xy = static_cast<T>(q.x*q.y),
|
||
|
xz = static_cast<T>(q.x*q.z),
|
||
|
xw = static_cast<T>(q.x*q.w),
|
||
|
|
||
|
yy = static_cast<T>(q.y*q.y),
|
||
|
yz = static_cast<T>(q.y*q.z),
|
||
|
yw = static_cast<T>(q.y*q.w),
|
||
|
|
||
|
zz = static_cast<T>(q.z*q.z),
|
||
|
zw = static_cast<T>(q.z*q.w);
|
||
|
|
||
|
m[0] = 1 - yy - yy - zz - zz;
|
||
|
m[1] = xy + xy + zw + zw;
|
||
|
m[2] = xz + xz - yw - yw;
|
||
|
|
||
|
m[3] = xy + xy - zw - zw;
|
||
|
m[4] = 1 - xx - xx - zz - zz;
|
||
|
m[5] = yz + yz + xw + xw;
|
||
|
|
||
|
m[6] = xz + xz + yw + yw;
|
||
|
m[7] = yz + yz - xw - xw;
|
||
|
m[8] = 1 - xx - xx - yy - yy;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* set matrix to identity matrix
|
||
|
*/
|
||
|
inline void identity()
|
||
|
{
|
||
|
m[0] = static_cast<T>(1);
|
||
|
m[1] = static_cast<T>(0);
|
||
|
m[2] = static_cast<T>(0);
|
||
|
|
||
|
m[3] = static_cast<T>(0);
|
||
|
m[4] = static_cast<T>(1);
|
||
|
m[5] = static_cast<T>(0);
|
||
|
|
||
|
m[6] = static_cast<T>(0);
|
||
|
m[7] = static_cast<T>(0);
|
||
|
m[8] = static_cast<T>(1);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* get transposed matrix
|
||
|
*/
|
||
|
inline Matrix3x3Template<T> transposed() const
|
||
|
{
|
||
|
Matrix3x3Template<T> a;
|
||
|
|
||
|
a.m[0] = m[0]; a.m[3] = m[1]; a.m[6] = m[2];
|
||
|
a.m[1] = m[3]; a.m[4] = m[4]; a.m[7] = m[5];
|
||
|
a.m[2] = m[6]; a.m[5] = m[7]; a.m[8] = m[8];
|
||
|
|
||
|
return a;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* transpose
|
||
|
*/
|
||
|
inline void transpose()
|
||
|
{
|
||
|
swap( m[3], m[1] );
|
||
|
swap( m[6], m[2] );
|
||
|
swap( m[7], m[5] );
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* determinate
|
||
|
*/
|
||
|
inline T determinant() const
|
||
|
{
|
||
|
return ( m[0]*m[4]*m[8] + m[1]*m[5]*m[6] + m[2]*m[3]*m[7] )
|
||
|
- ( m[6]*m[4]*m[2] + m[7]*m[5]*m[0] + m[8]*m[3]*m[1] );
|
||
|
}
|
||
|
|
||
|
inline Matrix3x3Template<T> inverted()
|
||
|
{
|
||
|
T det = determinant();
|
||
|
T one_over_det = 1.0f / det;
|
||
|
|
||
|
Matrix3x3Template<T> result;
|
||
|
result.m[0] = +(m[4] * m[8] - m[5] * m[7]) * one_over_det;
|
||
|
result.m[1] = -(m[1] * m[8] - m[2] * m[7]) * one_over_det;
|
||
|
result.m[2] = +(m[1] * m[5] - m[2] * m[4]) * one_over_det;
|
||
|
result.m[3] = -(m[3] * m[8] - m[5] * m[6]) * one_over_det;
|
||
|
result.m[4] = +(m[0] * m[8] - m[2] * m[6]) * one_over_det;
|
||
|
result.m[5] = -(m[0] * m[5] - m[2] * m[3]) * one_over_det;
|
||
|
result.m[6] = +(m[3] * m[7] - m[4] * m[6]) * one_over_det;
|
||
|
result.m[7] = -(m[0] * m[7] - m[1] * m[6]) * one_over_det;
|
||
|
result.m[8] = +(m[0] * m[4] - m[1] * m[3]) * one_over_det;
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* add/assign operator
|
||
|
*/
|
||
|
template <class S>
|
||
|
inline Matrix3x3Template<T> &operator += (
|
||
|
const Matrix3x3Template<S> &a )
|
||
|
{
|
||
|
m[0] += static_cast<T>(a.m[0]);
|
||
|
m[1] += static_cast<T>(a.m[1]);
|
||
|
m[2] += static_cast<T>(a.m[2]);
|
||
|
|
||
|
m[3] += static_cast<T>(a.m[3]);
|
||
|
m[4] += static_cast<T>(a.m[4]);
|
||
|
m[5] += static_cast<T>(a.m[5]);
|
||
|
|
||
|
m[6] += static_cast<T>(a.m[6]);
|
||
|
m[7] += static_cast<T>(a.m[7]);
|
||
|
m[8] += static_cast<T>(a.m[8]);
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* matrix multiplication
|
||
|
*/
|
||
|
template <class S>
|
||
|
inline Matrix3x3Template<T> operator * ( const Matrix3x3Template<S> &a )
|
||
|
{
|
||
|
Matrix3x3Template<T> result;
|
||
|
|
||
|
result.m[0] = m[0] * static_cast<T>(a.m[0])
|
||
|
+ m[3] * static_cast<T>(a.m[1])
|
||
|
+ m[6] * static_cast<T>(a.m[2]);
|
||
|
|
||
|
result.m[1] = m[1] * static_cast<T>(a.m[0])
|
||
|
+ m[4] * static_cast<T>(a.m[1])
|
||
|
+ m[7] * static_cast<T>(a.m[2]);
|
||
|
|
||
|
result.m[2] = m[2] * static_cast<T>(a.m[0])
|
||
|
+ m[5] * static_cast<T>(a.m[1])
|
||
|
+ m[8] * static_cast<T>(a.m[2]);
|
||
|
|
||
|
|
||
|
result.m[3] = m[0] * static_cast<T>(a.m[3])
|
||
|
+ m[3] * static_cast<T>(a.m[4])
|
||
|
+ m[6] * static_cast<T>(a.m[5]);
|
||
|
|
||
|
result.m[4] = m[1] * static_cast<T>(a.m[3])
|
||
|
+ m[4] * static_cast<T>(a.m[4])
|
||
|
+ m[7] * static_cast<T>(a.m[5]);
|
||
|
|
||
|
result.m[5] = m[2] * static_cast<T>(a.m[3])
|
||
|
+ m[5] * static_cast<T>(a.m[4])
|
||
|
+ m[8] * static_cast<T>(a.m[5]);
|
||
|
|
||
|
|
||
|
result.m[6] = m[0] * static_cast<T>(a.m[6])
|
||
|
+ m[3] * static_cast<T>(a.m[7])
|
||
|
+ m[6] * static_cast<T>(a.m[8]);
|
||
|
|
||
|
result.m[7] = m[1] * static_cast<T>(a.m[6])
|
||
|
+ m[4] * static_cast<T>(a.m[7])
|
||
|
+ m[7] * static_cast<T>(a.m[8]);
|
||
|
|
||
|
result.m[8] = m[2] * static_cast<T>(a.m[6])
|
||
|
+ m[5] * static_cast<T>(a.m[7])
|
||
|
+ m[8] * static_cast<T>(a.m[8]);
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* matrix vector multiplication
|
||
|
*/
|
||
|
template <class S>
|
||
|
Vector3Template<T> operator * ( const Vector3Template<S>& a )
|
||
|
{
|
||
|
return Vector3Template<T>(
|
||
|
m[0] * static_cast<T>(a.x)
|
||
|
+ m[3] * static_cast<T>(a.y)
|
||
|
+ m[6] * static_cast<T>(a.z),
|
||
|
m[1] * static_cast<T>(a.x)
|
||
|
+ m[4] * static_cast<T>(a.y)
|
||
|
+ m[7] * static_cast<T>(a.z),
|
||
|
m[2] * static_cast<T>(a.x)
|
||
|
+ m[5] * static_cast<T>(a.y)
|
||
|
+ m[8] * static_cast<T>(a.z) );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* matrix scalar multiplication
|
||
|
*/
|
||
|
template <class S>
|
||
|
Matrix3x3Template<T> operator * ( const S a )
|
||
|
{
|
||
|
Matrix3x3Template<T> result;
|
||
|
|
||
|
result.m[0] = m[0] * static_cast<T>(a);
|
||
|
result.m[1] = m[1] * static_cast<T>(a);
|
||
|
result.m[2] = m[2] * static_cast<T>(a);
|
||
|
result.m[3] = m[3] * static_cast<T>(a);
|
||
|
result.m[4] = m[4] * static_cast<T>(a);
|
||
|
result.m[5] = m[5] * static_cast<T>(a);
|
||
|
result.m[6] = m[6] * static_cast<T>(a);
|
||
|
result.m[7] = m[7] * static_cast<T>(a);
|
||
|
result.m[8] = m[8] * static_cast<T>(a);
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
friend std::ostream &operator << ( std::ostream& os, Matrix3x3Template<T> m )
|
||
|
{
|
||
|
os << "( " << m.m[0] << ", " << m.m[1] << ", " << m.m[2] << " )" << std::endl;
|
||
|
os << "( " << m.m[3] << ", " << m.m[4] << ", " << m.m[5] << " )" << std::endl;
|
||
|
os << "( " << m.m[6] << ", " << m.m[7] << ", " << m.m[8] << " )" << std::endl;
|
||
|
return os;
|
||
|
}
|
||
|
|
||
|
};
|
||
|
|
||
|
typedef Matrix3x3Template<float> Matrix3x3Float;
|
||
|
typedef Matrix3x3Template<double> Matrix3x3Double;
|
||
|
typedef Matrix3x3Template<Scalar> Matrix3x3;
|
||
|
|
||
|
|
||
|
template <class T>
|
||
|
class Matrix4x4Template
|
||
|
{
|
||
|
|
||
|
public:
|
||
|
|
||
|
T m[16];
|
||
|
|
||
|
/**
|
||
|
* default constructor
|
||
|
*/
|
||
|
inline Matrix4x4Template()
|
||
|
{
|
||
|
identity();
|
||
|
}
|
||
|
|
||
|
inline void identity()
|
||
|
{
|
||
|
m[0] = static_cast<T>(1);
|
||
|
m[1] = static_cast<T>(0);
|
||
|
m[2] = static_cast<T>(0);
|
||
|
m[3] = static_cast<T>(0);
|
||
|
|
||
|
m[4] = static_cast<T>(0);
|
||
|
m[5] = static_cast<T>(1);
|
||
|
m[6] = static_cast<T>(0);
|
||
|
m[7] = static_cast<T>(0);
|
||
|
|
||
|
m[8] = static_cast<T>(0);
|
||
|
m[9] = static_cast<T>(0);
|
||
|
m[10] = static_cast<T>(1);
|
||
|
m[11] = static_cast<T>(0);
|
||
|
|
||
|
m[12] = static_cast<T>(0);
|
||
|
m[13] = static_cast<T>(0);
|
||
|
m[14] = static_cast<T>(0);
|
||
|
m[15] = static_cast<T>(1);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* constructor from array
|
||
|
*/
|
||
|
inline Matrix4x4Template( const T a[16] )
|
||
|
{
|
||
|
m[0] = a[0]; m[1] = a[1]; m[2] = a[2]; m[3] = a[3];
|
||
|
m[4] = a[4]; m[5] = a[5]; m[6] = a[6]; m[7] = a[7];
|
||
|
m[8] = a[8]; m[9] = a[9]; m[10] = a[10]; m[11] = a[11];
|
||
|
m[12] = a[12]; m[13] = a[13]; m[14] = a[14]; m[15] = a[15];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* constructor from 3x3 matrix, add. element are set to zero
|
||
|
*/
|
||
|
inline Matrix4x4Template( const Matrix3x3Template<T> &a )
|
||
|
{
|
||
|
m[0] = a[0];
|
||
|
m[1] = a[1];
|
||
|
m[2] = a[2];
|
||
|
m[3] = static_cast<T>(0);
|
||
|
|
||
|
m[4] = a[3];
|
||
|
m[5] = a[4];
|
||
|
m[6] = a[5];
|
||
|
m[7] = static_cast<T>(0);
|
||
|
|
||
|
m[8] = a[6];
|
||
|
m[9] = a[7];
|
||
|
m[10] = a[8];
|
||
|
m[11] = static_cast<T>(0);
|
||
|
|
||
|
m[12] = static_cast<T>(0);
|
||
|
m[13] = static_cast<T>(0);
|
||
|
m[14] = static_cast<T>(0);
|
||
|
m[15] = static_cast<T>(1);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* constructor from 3x3 rotation matrix and translation vector
|
||
|
*/
|
||
|
inline Matrix4x4Template(
|
||
|
const Matrix3x3Template<T> &a,
|
||
|
const Vector3Template<T> &b )
|
||
|
{
|
||
|
m[0] = a[0];
|
||
|
m[1] = a[1];
|
||
|
m[2] = a[2];
|
||
|
m[3] = static_cast<T>(0);
|
||
|
|
||
|
m[4] = a[3];
|
||
|
m[5] = a[4];
|
||
|
m[6] = a[5];
|
||
|
m[7] = static_cast<T>(0);
|
||
|
|
||
|
m[8] = a[6];
|
||
|
m[9] = a[7];
|
||
|
m[10] = a[8];
|
||
|
m[11] = static_cast<T>(0);
|
||
|
|
||
|
m[12] = b.x;
|
||
|
m[13] = b.y;
|
||
|
m[14] = b.z;
|
||
|
m[15] = static_cast<T>(1);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* copy constructor
|
||
|
*/
|
||
|
inline Matrix4x4Template( const Matrix4x4Template<T> &a )
|
||
|
{
|
||
|
m[0] = a.m[0];
|
||
|
m[1] = a.m[1];
|
||
|
m[2] = a.m[2];
|
||
|
m[3] = a.m[3];
|
||
|
|
||
|
m[4] = a.m[4];
|
||
|
m[5] = a.m[5];
|
||
|
m[6] = a.m[6];
|
||
|
m[7] = a.m[7];
|
||
|
|
||
|
m[8] = a.m[8];
|
||
|
m[9] = a.m[9];
|
||
|
m[10] = a.m[10];
|
||
|
m[11] = a.m[11];
|
||
|
|
||
|
m[12] = a.m[12];
|
||
|
m[13] = a.m[13];
|
||
|
m[14] = a.m[14];
|
||
|
m[15] = a.m[15];
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* constructor from quaternion
|
||
|
*/
|
||
|
inline Matrix4x4Template( const QuaternionTemplate<T> &q )
|
||
|
{
|
||
|
m[0] = 1 - 2*q.y*q.y - 2*q.z*q.z;
|
||
|
m[1] = 2*q.x*q.y - 2*q.z*q.w;
|
||
|
m[2] = 2*q.x*q.z + 2*q.y*q.w;
|
||
|
m[3] = static_cast<T>(0);
|
||
|
|
||
|
m[4] = 2*q.x*q.y + 2*q.z*q.w;
|
||
|
m[5] = 1 - 2*q.x*q.x - 2*q.z*q.z;
|
||
|
m[6] = 2*q.y*q.z - 2*q.x*q.w;
|
||
|
m[7] = static_cast<T>(0);
|
||
|
|
||
|
m[8] = 2*q.x*q.z - 2*q.y*q.w;
|
||
|
m[9] = 2*q.y*q.z + 2*q.x*q.w;
|
||
|
m[10] = 1 - 2*q.x*q.x - 2*q.y*q.y;
|
||
|
m[11] = static_cast<T>(0);
|
||
|
|
||
|
m[12] = static_cast<T>(0);
|
||
|
m[13] = static_cast<T>(0);
|
||
|
m[14] = static_cast<T>(0);
|
||
|
m[15] = static_cast<T>(1);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* constructor from quaternion and translation vector
|
||
|
*/
|
||
|
inline Matrix4x4Template(
|
||
|
const QuaternionTemplate<T> &q,
|
||
|
const Vector3Template<T> &a )
|
||
|
{
|
||
|
m[0] = 1 - 2*q.y*q.y - 2*q.z*q.z;
|
||
|
m[1] = 2*q.x*q.y - 2*q.z*q.w;
|
||
|
m[2] = 2*q.x*q.z + 2*q.y*q.w;
|
||
|
m[3] = static_cast<T>(0);
|
||
|
|
||
|
m[4] = 2*q.x*q.y + 2*q.z*q.w;
|
||
|
m[5] = 1 - 2*q.x*q.x - 2*q.z*q.z;
|
||
|
m[6] = 2*q.y*q.z - 2*q.x*q.w;
|
||
|
m[7] = static_cast<T>(0);
|
||
|
|
||
|
m[8] = 2*q.x*q.z - 2*q.y*q.w;
|
||
|
m[9] = 2*q.y*q.z + 2*q.x*q.w;
|
||
|
m[10] = 1 - 2*q.x*q.x - 2*q.y*q.y;
|
||
|
m[11] = static_cast<T>(0);
|
||
|
|
||
|
m[12] = a.x;
|
||
|
m[13] = a.y;
|
||
|
m[14] = a.z;
|
||
|
m[15] = static_cast<T>(1);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* constructor from heading, up and translation vectors
|
||
|
*/
|
||
|
inline Matrix4x4Template(
|
||
|
const Vector3Template<T> &h,
|
||
|
const Vector3Template<T> &u,
|
||
|
const Vector3Template<T> &t )
|
||
|
{
|
||
|
Vector3Template<T> a, b, c;
|
||
|
c = h.unit();
|
||
|
a = h.crossProduct( u ).unit();
|
||
|
b = c.crossProduct( a ).unit();
|
||
|
|
||
|
m[0] = a.x;
|
||
|
m[1] = b.x;
|
||
|
m[2] = c.x;
|
||
|
m[3] = static_cast<T>(0);
|
||
|
|
||
|
m[4] = a.y;
|
||
|
m[5] = b.y;
|
||
|
m[6] = c.y;
|
||
|
m[7] = static_cast<T>(0);
|
||
|
|
||
|
m[8] = a.z;
|
||
|
m[9] = b.z;
|
||
|
m[10] = c.z;
|
||
|
m[11] = static_cast<T>(0);
|
||
|
|
||
|
m[12] = t.x;
|
||
|
m[13] = t.y;
|
||
|
m[14] = t.z;
|
||
|
m[15] = static_cast<T>(1);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* contructor from euler angles
|
||
|
*/
|
||
|
inline Matrix4x4Template(
|
||
|
T a,
|
||
|
T e,
|
||
|
T t,
|
||
|
const Vector3Template<T> &tr )
|
||
|
{
|
||
|
T ch = cos( a );
|
||
|
T sh = sin( a );
|
||
|
T ca = cos( e );
|
||
|
T sa = sin( e );
|
||
|
T cb = cos( t );
|
||
|
T sb = sin( t );
|
||
|
|
||
|
m[0] = ch * ca;
|
||
|
m[1] = sh*sb - ch*sa*cb;
|
||
|
m[2] = ch*sa*sb + sh*cb;
|
||
|
m[3] = static_cast<T>(0);
|
||
|
|
||
|
m[4] = sa;
|
||
|
m[5] = ca*cb;
|
||
|
m[6] = -ca*sb;
|
||
|
m[7] = static_cast<T>(0);
|
||
|
|
||
|
|
||
|
m[8] = -sh*ca;
|
||
|
m[9] = sh*sa*cb + ch*sb;
|
||
|
m[10] = -sh*sa*sb + ch*cb;
|
||
|
m[11] = static_cast<T>(0);
|
||
|
|
||
|
m[12] = tr.x;
|
||
|
m[13] = tr.y;
|
||
|
m[14] = tr.z;
|
||
|
m[15] = static_cast<T>(1);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* transpose this matrix
|
||
|
*/
|
||
|
inline void transpose()
|
||
|
{
|
||
|
std::swap( m[4], m[1] );
|
||
|
std::swap( m[8], m[2] );
|
||
|
std::swap( m[12], m[3] );
|
||
|
|
||
|
std::swap( m[9], m[6] );
|
||
|
std::swap( m[13], m[7] );
|
||
|
std::swap( m[14], m[11] );
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* get transposed matrix
|
||
|
*/
|
||
|
inline Matrix4x4Template<T> transposed()
|
||
|
{
|
||
|
Matrix4x4Template<T> a;
|
||
|
|
||
|
a.m[0] = m[0]; a.m[4] = m[1]; a.m[8] = m[2]; a.m[12] = m[3];
|
||
|
a.m[1] = m[4]; a.m[5] = m[5]; a.m[9] = m[6]; a.m[13] = m[7];
|
||
|
a.m[2] = m[8]; a.m[6] = m[9]; a.m[10] = m[10]; a.m[14] = m[11];
|
||
|
a.m[3] = m[12]; a.m[7] = m[13]; a.m[11] = m[14]; a.m[15] = m[15];
|
||
|
|
||
|
return a;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* matrix multiplication
|
||
|
*/
|
||
|
template <class S>
|
||
|
inline Matrix4x4Template<T> operator * ( const Matrix4x4Template<S> &a )
|
||
|
{
|
||
|
Matrix4x4Template<T> result;
|
||
|
|
||
|
result.m[0] = m[0] * static_cast<T>(a.m[0])
|
||
|
+ m[4] * static_cast<T>(a.m[1])
|
||
|
+ m[8] * static_cast<T>(a.m[2])
|
||
|
+ m[12] * static_cast<T>(a.m[3]);
|
||
|
|
||
|
result.m[1] = m[1] * static_cast<T>(a.m[0])
|
||
|
+ m[5] * static_cast<T>(a.m[1])
|
||
|
+ m[9] * static_cast<T>(a.m[2])
|
||
|
+ m[13] * static_cast<T>(a.m[3]);
|
||
|
|
||
|
result.m[2] = m[2] * static_cast<T>(a.m[0])
|
||
|
+ m[6] * static_cast<T>(a.m[1])
|
||
|
+ m[10] * static_cast<T>(a.m[2])
|
||
|
+ m[14] * static_cast<T>(a.m[3]);
|
||
|
|
||
|
result.m[3] = m[3] * static_cast<T>(a.m[0])
|
||
|
+ m[7] * static_cast<T>(a.m[1])
|
||
|
+ m[11] * static_cast<T>(a.m[2])
|
||
|
+ m[15] * static_cast<T>(a.m[3]);
|
||
|
|
||
|
|
||
|
result.m[4] = m[0] * static_cast<T>(a.m[4])
|
||
|
+ m[4] * static_cast<T>(a.m[5])
|
||
|
+ m[8] * static_cast<T>(a.m[6])
|
||
|
+ m[12] * static_cast<T>(a.m[7]);
|
||
|
|
||
|
result.m[5] = m[1] * static_cast<T>(a.m[4])
|
||
|
+ m[5] * static_cast<T>(a.m[5])
|
||
|
+ m[9] * static_cast<T>(a.m[6])
|
||
|
+ m[13] * static_cast<T>(a.m[7]);
|
||
|
|
||
|
result.m[6] = m[2] * static_cast<T>(a.m[4])
|
||
|
+ m[6] * static_cast<T>(a.m[5])
|
||
|
+ m[10] * static_cast<T>(a.m[6])
|
||
|
+ m[14] * static_cast<T>(a.m[7]);
|
||
|
|
||
|
result.m[7] = m[3] * static_cast<T>(a.m[4])
|
||
|
+ m[7] * static_cast<T>(a.m[5])
|
||
|
+ m[11] * static_cast<T>(a.m[6])
|
||
|
+ m[15] * static_cast<T>(a.m[7]);
|
||
|
|
||
|
|
||
|
result.m[8] = m[0] * static_cast<T>(a.m[8])
|
||
|
+ m[4] * static_cast<T>(a.m[9])
|
||
|
+ m[8] * static_cast<T>(a.m[10])
|
||
|
+ m[12] * static_cast<T>(a.m[11]);
|
||
|
|
||
|
result.m[9] = m[1] * static_cast<T>(a.m[8])
|
||
|
+ m[5] * static_cast<T>(a.m[9])
|
||
|
+ m[9] * static_cast<T>(a.m[10])
|
||
|
+ m[13] * static_cast<T>(a.m[11]);
|
||
|
|
||
|
result.m[10] = m[2] * static_cast<T>(a.m[8])
|
||
|
+ m[6] * static_cast<T>(a.m[9])
|
||
|
+ m[10] * static_cast<T>(a.m[10])
|
||
|
+ m[14] * static_cast<T>(a.m[11]);
|
||
|
|
||
|
result.m[11] = m[3] * static_cast<T>(a.m[8])
|
||
|
+ m[7] * static_cast<T>(a.m[9])
|
||
|
+ m[11] * static_cast<T>(a.m[10])
|
||
|
+ m[15] * static_cast<T>(a.m[11]);
|
||
|
|
||
|
|
||
|
result.m[12] = m[0] * static_cast<T>(a.m[12])
|
||
|
+ m[4] * static_cast<T>(a.m[13])
|
||
|
+ m[8] * static_cast<T>(a.m[14])
|
||
|
+ m[12] * static_cast<T>(a.m[15]);
|
||
|
|
||
|
result.m[13] = m[1] * static_cast<T>(a.m[12])
|
||
|
+ m[5] * static_cast<T>(a.m[13])
|
||
|
+ m[9] * static_cast<T>(a.m[14])
|
||
|
+ m[13] * static_cast<T>(a.m[15]);
|
||
|
|
||
|
result.m[14] = m[2] * static_cast<T>(a.m[12])
|
||
|
+ m[6] * static_cast<T>(a.m[13])
|
||
|
+ m[10] * static_cast<T>(a.m[14])
|
||
|
+ m[14] * static_cast<T>(a.m[15]);
|
||
|
|
||
|
result.m[15] = m[3] * static_cast<T>(a.m[12])
|
||
|
+ m[7] * static_cast<T>(a.m[13])
|
||
|
+ m[11] * static_cast<T>(a.m[14])
|
||
|
+ m[15] * static_cast<T>(a.m[15]);
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* matrix multiplication
|
||
|
*/
|
||
|
/*
|
||
|
template <class S>
|
||
|
inline Matrix4x4Template<T> operator *= ( const Matrix4x4Template<S> &a )
|
||
|
{
|
||
|
Matrix4x4Template<T> result;
|
||
|
|
||
|
result.m[0] = m[0] * static_cast<T>(a.m[0])
|
||
|
+ m[4] * static_cast<T>(a.m[1])
|
||
|
+ m[8] * static_cast<T>(a.m[2]);
|
||
|
+ m[12] * static_cast<T>(a.m[3]);
|
||
|
|
||
|
result.m[1] = m[1] * static_cast<T>(a.m[0])
|
||
|
+ m[5] * static_cast<T>(a.m[1])
|
||
|
+ m[9] * static_cast<T>(a.m[2]);
|
||
|
+ m[13] * static_cast<T>(a.m[3]);
|
||
|
|
||
|
result.m[2] = m[2] * static_cast<T>(a.m[0])
|
||
|
+ m[6] * static_cast<T>(a.m[1])
|
||
|
+ m[10] * static_cast<T>(a.m[2]);
|
||
|
+ m[14] * static_cast<T>(a.m[3]);
|
||
|
|
||
|
result.m[3] = m[3] * static_cast<T>(a.m[0])
|
||
|
+ m[7] * static_cast<T>(a.m[1])
|
||
|
+ m[11] * static_cast<T>(a.m[2]);
|
||
|
+ m[15] * static_cast<T>(a.m[3]);
|
||
|
|
||
|
|
||
|
result.m[4] = m[0] * static_cast<T>(a.m[4])
|
||
|
+ m[4] * static_cast<T>(a.m[5])
|
||
|
+ m[8] * static_cast<T>(a.m[6]);
|
||
|
+ m[12] * static_cast<T>(a.m[7]);
|
||
|
|
||
|
result.m[5] = m[1] * static_cast<T>(a.m[4])
|
||
|
+ m[5] * static_cast<T>(a.m[5])
|
||
|
+ m[9] * static_cast<T>(a.m[6]);
|
||
|
+ m[13] * static_cast<T>(a.m[7]);
|
||
|
|
||
|
result.m[6] = m[2] * static_cast<T>(a.m[4])
|
||
|
+ m[6] * static_cast<T>(a.m[5])
|
||
|
+ m[10] * static_cast<T>(a.m[6]);
|
||
|
+ m[14] * static_cast<T>(a.m[7]);
|
||
|
|
||
|
result.m[7] = m[3] * static_cast<T>(a.m[4])
|
||
|
+ m[7] * static_cast<T>(a.m[5])
|
||
|
+ m[11] * static_cast<T>(a.m[6]);
|
||
|
+ m[15] * static_cast<T>(a.m[7]);
|
||
|
|
||
|
|
||
|
result.m[8] = m[0] * static_cast<T>(a.m[8])
|
||
|
+ m[4] * static_cast<T>(a.m[9])
|
||
|
+ m[8] * static_cast<T>(a.m[10]);
|
||
|
+ m[12] * static_cast<T>(a.m[11]);
|
||
|
|
||
|
result.m[9] = m[1] * static_cast<T>(a.m[8])
|
||
|
+ m[5] * static_cast<T>(a.m[9])
|
||
|
+ m[9] * static_cast<T>(a.m[10]);
|
||
|
+ m[13] * static_cast<T>(a.m[11]);
|
||
|
|
||
|
result.m[10] = m[2] * static_cast<T>(a.m[8])
|
||
|
+ m[6] * static_cast<T>(a.m[9])
|
||
|
+ m[10] * static_cast<T>(a.m[10]);
|
||
|
+ m[14] * static_cast<T>(a.m[11]);
|
||
|
|
||
|
result.m[11] = m[3] * static_cast<T>(a.m[8])
|
||
|
+ m[7] * static_cast<T>(a.m[9])
|
||
|
+ m[11] * static_cast<T>(a.m[10]);
|
||
|
+ m[15] * static_cast<T>(a.m[11]);
|
||
|
|
||
|
|
||
|
result.m[12] = m[0] * static_cast<T>(a.m[12])
|
||
|
+ m[4] * static_cast<T>(a.m[13])
|
||
|
+ m[8] * static_cast<T>(a.m[14]);
|
||
|
+ m[12] * static_cast<T>(a.m[15]);
|
||
|
|
||
|
result.m[13] = m[1] * static_cast<T>(a.m[12])
|
||
|
+ m[5] * static_cast<T>(a.m[13])
|
||
|
+ m[9] * static_cast<T>(a.m[14]);
|
||
|
+ m[13] * static_cast<T>(a.m[15]);
|
||
|
|
||
|
result.m[14] = m[2] * static_cast<T>(a.m[12])
|
||
|
+ m[6] * static_cast<T>(a.m[13])
|
||
|
+ m[10] * static_cast<T>(a.m[14]);
|
||
|
+ m[14] * static_cast<T>(a.m[15]);
|
||
|
|
||
|
result.m[15] = m[3] * static_cast<T>(a.m[12])
|
||
|
+ m[7] * static_cast<T>(a.m[13])
|
||
|
+ m[11] * static_cast<T>(a.m[14]);
|
||
|
+ m[15] * static_cast<T>(a.m[15]);
|
||
|
|
||
|
m = result.m;
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
*/
|
||
|
/**
|
||
|
* matrix vector multiplication
|
||
|
*/
|
||
|
Vector3Template<T> operator * ( const Vector3Template<T> &a )
|
||
|
{
|
||
|
Vector3Template<T> result;
|
||
|
|
||
|
result.x = m[0] * a.x + m[4] * a.y + m[8] * a.z + m[12];
|
||
|
result.y = m[1] * a.x + m[5] * a.y + m[9] * a.z + m[13];
|
||
|
result.z = m[2] * a.x + m[6] * a.y + m[11] * a.z + m[14];
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
T *data()
|
||
|
{
|
||
|
return &m[0];
|
||
|
}
|
||
|
};
|
||
|
|
||
|
typedef Matrix4x4Template<float> Matrix4x4Float;
|
||
|
typedef Matrix4x4Template<double> Matrix4x4Double;
|
||
|
typedef Matrix4x4Template<Scalar> Matrix4x4;
|
||
|
|
||
|
} // namespace bc
|
||
|
|
||
|
#endif // BLUECORE_MATRIX_H
|