829 lines
24 KiB
C++
829 lines
24 KiB
C++
#ifndef _MATRIX44_H
|
|
#define _MATRIX44_H
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
Generic matrix44 class.
|
|
|
|
@author
|
|
- RadonLabs GmbH
|
|
|
|
@since
|
|
- 2005.7.06
|
|
@remarks
|
|
- Áö¿Ï Ãß°¡
|
|
*/
|
|
|
|
#include "_vector4.h"
|
|
#include "_vector3.h"
|
|
#include "quaternion.h"
|
|
#include "euler.h"
|
|
#include "matrixdefs.h"
|
|
|
|
static float _matrix44_ident[16] =
|
|
{
|
|
1.0f, 0.0f, 0.0f, 0.0f,
|
|
0.0f, 1.0f, 0.0f, 0.0f,
|
|
0.0f, 0.0f, 1.0f, 0.0f,
|
|
0.0f, 0.0f, 0.0f, 1.0f,
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
class _matrix44
|
|
{
|
|
public:
|
|
/// constructor 1
|
|
_matrix44();
|
|
/// constructor 2
|
|
_matrix44(const _vector4& v0, const _vector4& v1, const _vector4& v2, const _vector4& v3);
|
|
/// constructor 3
|
|
_matrix44(const _matrix44& m1);
|
|
/// constructor 4
|
|
_matrix44(float _m11, float _m12, float _m13, float _m14,
|
|
float _m21, float _m22, float _m23, float _m24,
|
|
float _m31, float _m32, float _m33, float _m34,
|
|
float _m41, float _m42, float _m43, float _m44);
|
|
/// construct from quaternion
|
|
_matrix44(const quaternion& q);
|
|
/// convert to quaternion
|
|
quaternion get_quaternion() const;
|
|
/// set 1
|
|
void set(const _vector4& v0, const _vector4& v1, const _vector4& v2, const _vector4& v3);
|
|
/// set 2
|
|
void set(const _matrix44& m1);
|
|
/// set 3
|
|
void set(float _m11, float _m12, float _m13, float _m14,
|
|
float _m21, float _m22, float _m23, float _m24,
|
|
float _m31, float _m32, float _m33, float _m34,
|
|
float _m41, float _m42, float _m43, float _m44);
|
|
/// set from quaternion
|
|
void set(const quaternion& q);
|
|
/// set to identity
|
|
void ident();
|
|
/// transpose
|
|
void transpose();
|
|
/// determinant
|
|
float det();
|
|
/// full invert
|
|
void invert(void);
|
|
/// quick invert (if 3x3 rotation and translation)
|
|
void invert_simple(void);
|
|
/// quick multiplication, assumes that M14==M24==M34==0 and M44==1
|
|
void mult_simple(const _matrix44& m1);
|
|
/// transform vector3, projecting back into w=1
|
|
_vector3 transform_coord(const _vector3& v) const;
|
|
/// return x component
|
|
_vector3 x_component() const;
|
|
/// return y component
|
|
_vector3 y_component() const;
|
|
/// return z component
|
|
_vector3 z_component() const;
|
|
/// return translate component
|
|
_vector3 pos_component() const;
|
|
/// rotate around global x
|
|
void rotate_x(const float a);
|
|
/// rotate around global y
|
|
void rotate_y(const float a);
|
|
/// rotate around global z
|
|
void rotate_z(const float a);
|
|
/// rotate about any axis
|
|
void rotate(const _vector3& vec, float a);
|
|
/// translate
|
|
void translate(const _vector3& t);
|
|
/// set absolute translation
|
|
void set_translation(const _vector3& t);
|
|
/// scale
|
|
void scale(const _vector3& s);
|
|
/// lookat in a left-handed coordinate system
|
|
void lookatLh(const _vector3& to, const _vector3& up);
|
|
/// lookat in a right-handed coordinate system
|
|
void lookatRh(const _vector3& to, const _vector3& up);
|
|
/// create left-handed field-of-view perspective projection matrix
|
|
void perspFovLh(float fovY, float aspect, float zn, float zf);
|
|
/// create right-handed field-of-view perspective projection matrix
|
|
void perspFovRh(float fovY, float aspect, float zn, float zf);
|
|
/// create left-handed orthogonal projection matrix
|
|
void orthoLh(float w, float h, float zn, float zf);
|
|
/// create right-handed orthogonal projection matrix
|
|
void orthoRh(float w, float h, float zn, float zf);
|
|
/// restricted lookat
|
|
void billboard(const _vector3& to, const _vector3& up);
|
|
/// inplace matrix mulitply
|
|
void operator *= (const _matrix44& m1);
|
|
/// multiply source vector into target vector, eliminates tmp vector
|
|
void mult(const _vector4& src, _vector4& dst) const;
|
|
/// multiply source vector into target vector, eliminates tmp vector
|
|
void mult(const _vector3& src, _vector3& dst) const;
|
|
|
|
float m[4][4];
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
_matrix44::_matrix44()
|
|
{
|
|
memcpy(&(m[0][0]), _matrix44_ident, sizeof(_matrix44_ident));
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
_matrix44::_matrix44(const _vector4& v0, const _vector4& v1, const _vector4& v2, const _vector4& v3)
|
|
{
|
|
M11 = v0.x; M12 = v0.y; M13 = v0.z; M14 = v0.w;
|
|
M21 = v1.x; M22 = v1.y; M23 = v1.z; M24 = v1.w;
|
|
M31 = v2.x; M32 = v2.y; M33 = v2.z; M34 = v2.w;
|
|
M41 = v3.x; M42 = v3.y; M43 = v3.z; M44 = v3.w;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
_matrix44::_matrix44(const _matrix44& m1)
|
|
{
|
|
memcpy(m, &(m1.m[0][0]), 16 * sizeof(float));
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
_matrix44::_matrix44(float _m11, float _m12, float _m13, float _m14,
|
|
float _m21, float _m22, float _m23, float _m24,
|
|
float _m31, float _m32, float _m33, float _m34,
|
|
float _m41, float _m42, float _m43, float _m44)
|
|
{
|
|
M11 = _m11; M12 = _m12; M13 = _m13; M14 = _m14;
|
|
M21 = _m21; M22 = _m22; M23 = _m23; M24 = _m24;
|
|
M31 = _m31; M32 = _m32; M33 = _m33; M34 = _m34;
|
|
M41 = _m41; M42 = _m42; M43 = _m43; M44 = _m44;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
_matrix44::_matrix44(const quaternion& q)
|
|
{
|
|
float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
|
|
x2 = q.x + q.x; y2 = q.y + q.y; z2 = q.z + q.z;
|
|
xx = q.x * x2; xy = q.x * y2; xz = q.x * z2;
|
|
yy = q.y * y2; yz = q.y * z2; zz = q.z * z2;
|
|
wx = q.w * x2; wy = q.w * y2; wz = q.w * z2;
|
|
|
|
m[0][0] = 1.0f - (yy + zz);
|
|
m[1][0] = xy - wz;
|
|
m[2][0] = xz + wy;
|
|
|
|
m[0][1] = xy + wz;
|
|
m[1][1] = 1.0f - (xx + zz);
|
|
m[2][1] = yz - wx;
|
|
|
|
m[0][2] = xz - wy;
|
|
m[1][2] = yz + wx;
|
|
m[2][2] = 1.0f - (xx + yy);
|
|
|
|
m[3][0] = m[3][1] = m[3][2] = 0.0f;
|
|
m[0][3] = m[1][3] = m[2][3] = 0.0f;
|
|
m[3][3] = 1.0f;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
convert orientation of 4x4 matrix into quaterion,
|
|
4x4 matrix must not be scaled!
|
|
*/
|
|
inline
|
|
quaternion
|
|
_matrix44::get_quaternion() const
|
|
{
|
|
float qa[4];
|
|
float tr = m[0][0] + m[1][1] + m[2][2];
|
|
if (tr > 0.0f)
|
|
{
|
|
float s = n_sqrt (tr + 1.0f);
|
|
qa[3] = s * 0.5f;
|
|
s = 0.5f / s;
|
|
qa[0] = (m[1][2] - m[2][1]) * s;
|
|
qa[1] = (m[2][0] - m[0][2]) * s;
|
|
qa[2] = (m[0][1] - m[1][0]) * s;
|
|
}
|
|
else
|
|
{
|
|
int i, j, k, nxt[3] = {1,2,0};
|
|
i = 0;
|
|
if (m[1][1] > m[0][0]) i=1;
|
|
if (m[2][2] > m[i][i]) i=2;
|
|
j = nxt[i];
|
|
k = nxt[j];
|
|
float s = n_sqrt((m[i][i] - (m[j][j] + m[k][k])) + 1.0f);
|
|
qa[i] = s * 0.5f;
|
|
s = 0.5f / s;
|
|
qa[3] = (m[j][k] - m[k][j])* s;
|
|
qa[j] = (m[i][j] + m[j][i]) * s;
|
|
qa[k] = (m[i][k] + m[k][i]) * s;
|
|
}
|
|
quaternion q(qa[0],qa[1],qa[2],qa[3]);
|
|
return q;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::set(const _vector4& v0, const _vector4& v1, const _vector4& v2, const _vector4& v3)
|
|
{
|
|
M11=v0.x; M12=v0.y; M13=v0.z, M14=v0.w;
|
|
M21=v1.x; M22=v1.y; M23=v1.z; M24=v1.w;
|
|
M31=v2.x; M32=v2.y; M33=v2.z; M34=v2.w;
|
|
M41=v3.x; M42=v3.y; M43=v3.z; M44=v3.w;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::set(const _matrix44& m1)
|
|
{
|
|
memcpy(m, &(m1.m[0][0]), 16*sizeof(float));
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::set(float _m11, float _m12, float _m13, float _m14,
|
|
float _m21, float _m22, float _m23, float _m24,
|
|
float _m31, float _m32, float _m33, float _m34,
|
|
float _m41, float _m42, float _m43, float _m44)
|
|
{
|
|
M11=_m11; M12=_m12; M13=_m13; M14=_m14;
|
|
M21=_m21; M22=_m22; M23=_m23; M24=_m24;
|
|
M31=_m31; M32=_m32; M33=_m33; M34=_m34;
|
|
M41=_m41; M42=_m42; M43=_m43; M44=_m44;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::set(const quaternion& q)
|
|
{
|
|
float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
|
|
x2 = q.x + q.x; y2 = q.y + q.y; z2 = q.z + q.z;
|
|
xx = q.x * x2; xy = q.x * y2; xz = q.x * z2;
|
|
yy = q.y * y2; yz = q.y * z2; zz = q.z * z2;
|
|
wx = q.w * x2; wy = q.w * y2; wz = q.w * z2;
|
|
|
|
m[0][0] = 1.0f - (yy + zz);
|
|
m[1][0] = xy - wz;
|
|
m[2][0] = xz + wy;
|
|
|
|
m[0][1] = xy + wz;
|
|
m[1][1] = 1.0f - (xx + zz);
|
|
m[2][1] = yz - wx;
|
|
|
|
m[0][2] = xz - wy;
|
|
m[1][2] = yz + wx;
|
|
m[2][2] = 1.0f - (xx + yy);
|
|
|
|
m[3][0] = m[3][1] = m[3][2] = 0.0f;
|
|
m[0][3] = m[1][3] = m[2][3] = 0.0f;
|
|
m[3][3] = 1.0f;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::ident()
|
|
{
|
|
memcpy(&(m[0][0]), _matrix44_ident, sizeof(_matrix44_ident));
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::transpose()
|
|
{
|
|
#undef n_swap
|
|
#define n_swap(x,y) { float t=x; x=y; y=t; }
|
|
n_swap(M12, M21);
|
|
n_swap(M13, M31);
|
|
n_swap(M14, M41);
|
|
n_swap(M23, M32);
|
|
n_swap(M24, M42);
|
|
n_swap(M34, M43);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
float
|
|
_matrix44::det()
|
|
{
|
|
return
|
|
(M11 * M22 - M12 * M21) * (M33 * M44 - M34 * M43)
|
|
-(M11 * M23 - M13 * M21) * (M32 * M44 - M34 * M42)
|
|
+(M11 * M24 - M14 * M21) * (M32 * M43 - M33 * M42)
|
|
+(M12 * M23 - M13 * M22) * (M31 * M44 - M34 * M41)
|
|
-(M12 * M24 - M14 * M22) * (M31 * M43 - M33 * M41)
|
|
+(M13 * M24 - M14 * M23) * (M31 * M42 - M32 * M41);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::invert()
|
|
{
|
|
float s = det();
|
|
if (s == 0.0) return;
|
|
s = 1/s;
|
|
this->set(
|
|
s*(M22*(M33*M44 - M34*M43) + M23*(M34*M42 - M32*M44) + M24*(M32*M43 - M33*M42)),
|
|
s*(M32*(M13*M44 - M14*M43) + M33*(M14*M42 - M12*M44) + M34*(M12*M43 - M13*M42)),
|
|
s*(M42*(M13*M24 - M14*M23) + M43*(M14*M22 - M12*M24) + M44*(M12*M23 - M13*M22)),
|
|
s*(M12*(M24*M33 - M23*M34) + M13*(M22*M34 - M24*M32) + M14*(M23*M32 - M22*M33)),
|
|
s*(M23*(M31*M44 - M34*M41) + M24*(M33*M41 - M31*M43) + M21*(M34*M43 - M33*M44)),
|
|
s*(M33*(M11*M44 - M14*M41) + M34*(M13*M41 - M11*M43) + M31*(M14*M43 - M13*M44)),
|
|
s*(M43*(M11*M24 - M14*M21) + M44*(M13*M21 - M11*M23) + M41*(M14*M23 - M13*M24)),
|
|
s*(M13*(M24*M31 - M21*M34) + M14*(M21*M33 - M23*M31) + M11*(M23*M34 - M24*M33)),
|
|
s*(M24*(M31*M42 - M32*M41) + M21*(M32*M44 - M34*M42) + M22*(M34*M41 - M31*M44)),
|
|
s*(M34*(M11*M42 - M12*M41) + M31*(M12*M44 - M14*M42) + M32*(M14*M41 - M11*M44)),
|
|
s*(M44*(M11*M22 - M12*M21) + M41*(M12*M24 - M14*M22) + M42*(M14*M21 - M11*M24)),
|
|
s*(M14*(M22*M31 - M21*M32) + M11*(M24*M32 - M22*M34) + M12*(M21*M34 - M24*M31)),
|
|
s*(M21*(M33*M42 - M32*M43) + M22*(M31*M43 - M33*M41) + M23*(M32*M41 - M31*M42)),
|
|
s*(M31*(M13*M42 - M12*M43) + M32*(M11*M43 - M13*M41) + M33*(M12*M41 - M11*M42)),
|
|
s*(M41*(M13*M22 - M12*M23) + M42*(M11*M23 - M13*M21) + M43*(M12*M21 - M11*M22)),
|
|
s*(M11*(M22*M33 - M23*M32) + M12*(M23*M31 - M21*M33) + M13*(M21*M32 - M22*M31)));
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
inverts a 4x4 matrix consisting of a 3x3 rotation matrix and
|
|
a translation (eg. everything that has [0,0,0,1] as
|
|
the rightmost column) MUCH cheaper then a real 4x4 inversion
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::invert_simple()
|
|
{
|
|
float s = det();
|
|
if (s == 0.0f) return;
|
|
s = 1.0f/s;
|
|
this->set(
|
|
s * ((M22 * M33) - (M23 * M32)),
|
|
s * ((M32 * M13) - (M33 * M12)),
|
|
s * ((M12 * M23) - (M13 * M22)),
|
|
0.0f,
|
|
s * ((M23 * M31) - (M21 * M33)),
|
|
s * ((M33 * M11) - (M31 * M13)),
|
|
s * ((M13 * M21) - (M11 * M23)),
|
|
0.0f,
|
|
s * ((M21 * M32) - (M22 * M31)),
|
|
s * ((M31 * M12) - (M32 * M11)),
|
|
s * ((M11 * M22) - (M12 * M21)),
|
|
0.0f,
|
|
s * (M21*(M33*M42 - M32*M43) + M22*(M31*M43 - M33*M41) + M23*(M32*M41 - M31*M42)),
|
|
s * (M31*(M13*M42 - M12*M43) + M32*(M11*M43 - M13*M41) + M33*(M12*M41 - M11*M42)),
|
|
s * (M41*(M13*M22 - M12*M23) + M42*(M11*M23 - M13*M21) + M43*(M12*M21 - M11*M22)),
|
|
1.0f);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
optimized multiplication, assumes that M14==M24==M34==0 AND M44==1
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::mult_simple(const _matrix44& m1)
|
|
{
|
|
int i;
|
|
for (i=0; i<4; i++)
|
|
{
|
|
float mi0 = m[i][0];
|
|
float mi1 = m[i][1];
|
|
float mi2 = m[i][2];
|
|
m[i][0] = mi0*m1.m[0][0] + mi1*m1.m[1][0] + mi2*m1.m[2][0];
|
|
m[i][1] = mi0*m1.m[0][1] + mi1*m1.m[1][1] + mi2*m1.m[2][1];
|
|
m[i][2] = mi0*m1.m[0][2] + mi1*m1.m[1][2] + mi2*m1.m[2][2];
|
|
}
|
|
m[3][0] += m1.m[3][0];
|
|
m[3][1] += m1.m[3][1];
|
|
m[3][2] += m1.m[3][2];
|
|
m[0][3] = 0.0f;
|
|
m[1][3] = 0.0f;
|
|
m[2][3] = 0.0f;
|
|
m[3][3] = 1.0f;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
Transforms a vector by the matrix, projecting the result back into w=1.
|
|
*/
|
|
inline
|
|
_vector3
|
|
_matrix44::transform_coord(const _vector3& v) const
|
|
{
|
|
float d = 1.0f / (M14*v.x + M24*v.y + M34*v.z + M44);
|
|
return _vector3(
|
|
(M11*v.x + M21*v.y + M31*v.z + M41) * d,
|
|
(M12*v.x + M22*v.y + M32*v.z + M42) * d,
|
|
(M13*v.x + M23*v.y + M33*v.z + M43) * d);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
_vector3
|
|
_matrix44::x_component() const
|
|
{
|
|
_vector3 v(M11,M12,M13);
|
|
return v;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
_vector3
|
|
_matrix44::y_component() const
|
|
{
|
|
_vector3 v(M21,M22,M23);
|
|
return v;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
_vector3
|
|
_matrix44::z_component() const
|
|
{
|
|
_vector3 v(M31,M32,M33);
|
|
return v;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
_vector3
|
|
_matrix44::pos_component() const
|
|
{
|
|
_vector3 v(M41,M42,M43);
|
|
return v;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::rotate_x(const float a)
|
|
{
|
|
float c = n_cos(a);
|
|
float s = n_sin(a);
|
|
int i;
|
|
for (i=0; i<4; i++) {
|
|
float mi1 = m[i][1];
|
|
float mi2 = m[i][2];
|
|
m[i][1] = mi1*c + mi2*-s;
|
|
m[i][2] = mi1*s + mi2*c;
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::rotate_y(const float a)
|
|
{
|
|
float c = n_cos(a);
|
|
float s = n_sin(a);
|
|
int i;
|
|
for (i=0; i<4; i++) {
|
|
float mi0 = m[i][0];
|
|
float mi2 = m[i][2];
|
|
m[i][0] = mi0*c + mi2*s;
|
|
m[i][2] = mi0*-s + mi2*c;
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::rotate_z(const float a)
|
|
{
|
|
float c = n_cos(a);
|
|
float s = n_sin(a);
|
|
int i;
|
|
for (i=0; i<4; i++) {
|
|
float mi0 = m[i][0];
|
|
float mi1 = m[i][1];
|
|
m[i][0] = mi0*c + mi1*-s;
|
|
m[i][1] = mi0*s + mi1*c;
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::translate(const _vector3& t)
|
|
{
|
|
M41 += t.x;
|
|
M42 += t.y;
|
|
M43 += t.z;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::set_translation(const _vector3& t)
|
|
{
|
|
M41 = t.x;
|
|
M42 = t.y;
|
|
M43 = t.z;
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::scale(const _vector3& s)
|
|
{
|
|
int i;
|
|
for (i=0; i<4; i++)
|
|
{
|
|
m[i][0] *= s.x;
|
|
m[i][1] *= s.y;
|
|
m[i][2] *= s.z;
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::lookatRh(const _vector3& at, const _vector3& up)
|
|
{
|
|
_vector3 eye(M41, M42, M43);
|
|
_vector3 zaxis = eye - at;
|
|
zaxis.norm();
|
|
_vector3 xaxis = up * zaxis;
|
|
xaxis.norm();
|
|
_vector3 yaxis = zaxis * xaxis;
|
|
M11 = xaxis.x; M12 = xaxis.y; M13 = xaxis.z; M14 = 0.0f;
|
|
M21 = yaxis.x; M22 = yaxis.y; M23 = yaxis.z; M24 = 0.0f;
|
|
M31 = zaxis.x; M32 = zaxis.y; M33 = zaxis.z; M34 = 0.0f;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::lookatLh(const _vector3& at, const _vector3& up)
|
|
{
|
|
_vector3 eye(M41, M42, M43);
|
|
_vector3 zaxis = at - eye;
|
|
zaxis.norm();
|
|
_vector3 xaxis = up * zaxis;
|
|
xaxis.norm();
|
|
_vector3 yaxis = zaxis * xaxis;
|
|
M11 = xaxis.x; M12 = yaxis.x; M13 = zaxis.x; M14 = 0.0f;
|
|
M21 = xaxis.y; M22 = yaxis.y; M23 = zaxis.y; M24 = 0.0f;
|
|
M31 = xaxis.z; M32 = yaxis.z; M33 = zaxis.z; M34 = 0.0f;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::perspFovLh(float fovY, float aspect, float zn, float zf)
|
|
{
|
|
float h = float(1.0 / tan(fovY * 0.5f));
|
|
float w = h / aspect;
|
|
M11 = w; M12 = 0.0f; M13 = 0.0f; M14 = 0.0f;
|
|
M21 = 0.0f; M22 = h; M23 = 0.0f; M24 = 0.0f;
|
|
M31 = 0.0f; M32 = 0.0f; M33 = zf / (zf - zn); M34 = 1.0f;
|
|
M41 = 0.0f; M42 = 0.0f; M43 = -zn * (zf / (zf - zn)); M44 = 0.0f;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::perspFovRh(float fovY, float aspect, float zn, float zf)
|
|
{
|
|
float h = float(1.0 / tan(fovY * 0.5f));
|
|
float w = h / aspect;
|
|
M11 = w; M12 = 0.0f; M13 = 0.0f; M14 = 0.0f;
|
|
M21 = 0.0f; M22 = h; M23 = 0.0f; M24 = 0.0f;
|
|
M31 = 0.0f; M32 = 0.0f; M33 = zf / (zn - zf); M34 = -1.0f;
|
|
M41 = 0.0f; M42 = 0.0f; M43 = zn * (zf / (zn - zf)); M44 = 0.0f;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::orthoLh(float w, float h, float zn, float zf)
|
|
{
|
|
M11 = 2.0f / w; M12 = 0.0f; M13 = 0.0f; M14 = 0.0f;
|
|
M21 = 0.0f; M22 = 2.0f / h; M23 = 0.0f; M24 = 0.0f;
|
|
M31 = 0.0f; M32 = 0.0f; M33 = 1.0f / (zf - zn); M34 = 0.0f;
|
|
M41 = 0.0f; M42 = 0.0f; M43 = zn / (zn - zf); M44 = 1.0f;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::orthoRh(float w, float h, float zn, float zf)
|
|
{
|
|
M11 = 2.0f / w; M12 = 0.0f; M13 = 0.0f; M14 = 0.0f;
|
|
M21 = 0.0f; M22 = 2.0f / h; M23 = 0.0f; M24 = 0.0f;
|
|
M31 = 0.0f; M32 = 0.0f; M33 = 1.0f / (zn - zf); M34 = 0.0f;
|
|
M41 = 0.0f; M42 = 0.0f; M43 = zn / (zn - zf); M44 = 1.0f;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::billboard(const _vector3& to, const _vector3& up)
|
|
{
|
|
_vector3 from(M41, M42, M43);
|
|
_vector3 z(from - to);
|
|
z.norm();
|
|
_vector3 y(up);
|
|
y.norm();
|
|
_vector3 x(y * z);
|
|
z = x * y;
|
|
|
|
M11=x.x; M12=x.y; M13=x.z; M14=0.0f;
|
|
M21=y.x; M22=y.y; M23=y.z; M24=0.0f;
|
|
M31=z.x; M32=z.y; M33=z.z; M34=0.0f;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::operator *= (const _matrix44& m1)
|
|
{
|
|
int i;
|
|
for (i=0; i<4; i++)
|
|
{
|
|
float mi0 = m[i][0];
|
|
float mi1 = m[i][1];
|
|
float mi2 = m[i][2];
|
|
float mi3 = m[i][3];
|
|
m[i][0] = mi0*m1.m[0][0] + mi1*m1.m[1][0] + mi2*m1.m[2][0] + mi3*m1.m[3][0];
|
|
m[i][1] = mi0*m1.m[0][1] + mi1*m1.m[1][1] + mi2*m1.m[2][1] + mi3*m1.m[3][1];
|
|
m[i][2] = mi0*m1.m[0][2] + mi1*m1.m[1][2] + mi2*m1.m[2][2] + mi3*m1.m[3][2];
|
|
m[i][3] = mi0*m1.m[0][3] + mi1*m1.m[1][3] + mi2*m1.m[2][3] + mi3*m1.m[3][3];
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::rotate(const _vector3& vec, float a)
|
|
{
|
|
_vector3 v(vec);
|
|
v.norm();
|
|
float sa = (float) n_sin(a);
|
|
float ca = (float) n_cos(a);
|
|
|
|
_matrix44 rotM;
|
|
rotM.M11 = ca + (1.0f - ca) * v.x * v.x;
|
|
rotM.M12 = (1.0f - ca) * v.x * v.y - sa * v.z;
|
|
rotM.M13 = (1.0f - ca) * v.z * v.x + sa * v.y;
|
|
rotM.M21 = (1.0f - ca) * v.x * v.y + sa * v.z;
|
|
rotM.M22 = ca + (1.0f - ca) * v.y * v.y;
|
|
rotM.M23 = (1.0f - ca) * v.y * v.z - sa * v.x;
|
|
rotM.M31 = (1.0f - ca) * v.z * v.x - sa * v.y;
|
|
rotM.M32 = (1.0f - ca) * v.y * v.z + sa * v.x;
|
|
rotM.M33 = ca + (1.0f - ca) * v.z * v.z;
|
|
|
|
(*this) *= rotM;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::mult(const _vector4& src, _vector4& dst) const
|
|
{
|
|
dst.x = M11*src.x + M21*src.y + M31*src.z + M41*src.w;
|
|
dst.y = M12*src.x + M22*src.y + M32*src.z + M42*src.w;
|
|
dst.z = M13*src.x + M23*src.y + M33*src.z + M43*src.w;
|
|
dst.w = M14*src.x + M24*src.y + M34*src.z + M44*src.w;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
inline
|
|
void
|
|
_matrix44::mult(const _vector3& src, _vector3& dst) const
|
|
{
|
|
dst.x = M11*src.x + M21*src.y + M31*src.z + M41;
|
|
dst.y = M12*src.x + M22*src.y + M32*src.z + M42;
|
|
dst.z = M13*src.x + M23*src.y + M33*src.z + M43;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
static
|
|
inline
|
|
_matrix44 operator * (const _matrix44& m0, const _matrix44& m1)
|
|
{
|
|
_matrix44 m2(
|
|
m0.m[0][0]*m1.m[0][0] + m0.m[0][1]*m1.m[1][0] + m0.m[0][2]*m1.m[2][0] + m0.m[0][3]*m1.m[3][0],
|
|
m0.m[0][0]*m1.m[0][1] + m0.m[0][1]*m1.m[1][1] + m0.m[0][2]*m1.m[2][1] + m0.m[0][3]*m1.m[3][1],
|
|
m0.m[0][0]*m1.m[0][2] + m0.m[0][1]*m1.m[1][2] + m0.m[0][2]*m1.m[2][2] + m0.m[0][3]*m1.m[3][2],
|
|
m0.m[0][0]*m1.m[0][3] + m0.m[0][1]*m1.m[1][3] + m0.m[0][2]*m1.m[2][3] + m0.m[0][3]*m1.m[3][3],
|
|
|
|
m0.m[1][0]*m1.m[0][0] + m0.m[1][1]*m1.m[1][0] + m0.m[1][2]*m1.m[2][0] + m0.m[1][3]*m1.m[3][0],
|
|
m0.m[1][0]*m1.m[0][1] + m0.m[1][1]*m1.m[1][1] + m0.m[1][2]*m1.m[2][1] + m0.m[1][3]*m1.m[3][1],
|
|
m0.m[1][0]*m1.m[0][2] + m0.m[1][1]*m1.m[1][2] + m0.m[1][2]*m1.m[2][2] + m0.m[1][3]*m1.m[3][2],
|
|
m0.m[1][0]*m1.m[0][3] + m0.m[1][1]*m1.m[1][3] + m0.m[1][2]*m1.m[2][3] + m0.m[1][3]*m1.m[3][3],
|
|
|
|
m0.m[2][0]*m1.m[0][0] + m0.m[2][1]*m1.m[1][0] + m0.m[2][2]*m1.m[2][0] + m0.m[2][3]*m1.m[3][0],
|
|
m0.m[2][0]*m1.m[0][1] + m0.m[2][1]*m1.m[1][1] + m0.m[2][2]*m1.m[2][1] + m0.m[2][3]*m1.m[3][1],
|
|
m0.m[2][0]*m1.m[0][2] + m0.m[2][1]*m1.m[1][2] + m0.m[2][2]*m1.m[2][2] + m0.m[2][3]*m1.m[3][2],
|
|
m0.m[2][0]*m1.m[0][3] + m0.m[2][1]*m1.m[1][3] + m0.m[2][2]*m1.m[2][3] + m0.m[2][3]*m1.m[3][3],
|
|
|
|
m0.m[3][0]*m1.m[0][0] + m0.m[3][1]*m1.m[1][0] + m0.m[3][2]*m1.m[2][0] + m0.m[3][3]*m1.m[3][0],
|
|
m0.m[3][0]*m1.m[0][1] + m0.m[3][1]*m1.m[1][1] + m0.m[3][2]*m1.m[2][1] + m0.m[3][3]*m1.m[3][1],
|
|
m0.m[3][0]*m1.m[0][2] + m0.m[3][1]*m1.m[1][2] + m0.m[3][2]*m1.m[2][2] + m0.m[3][3]*m1.m[3][2],
|
|
m0.m[3][0]*m1.m[0][3] + m0.m[3][1]*m1.m[1][3] + m0.m[3][2]*m1.m[2][3] + m0.m[3][3]*m1.m[3][3]);
|
|
return m2;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
static
|
|
inline
|
|
_vector3 operator * (const _matrix44& m, const _vector3& v)
|
|
{
|
|
return _vector3(
|
|
m.M11*v.x + m.M21*v.y + m.M31*v.z + m.M41,
|
|
m.M12*v.x + m.M22*v.y + m.M32*v.z + m.M42,
|
|
m.M13*v.x + m.M23*v.y + m.M33*v.z + m.M43);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
*/
|
|
static
|
|
inline
|
|
_vector4 operator * (const _matrix44& m, const _vector4& v)
|
|
{
|
|
return _vector4(
|
|
m.M11*v.x + m.M21*v.y + m.M31*v.z + m.M41*v.w,
|
|
m.M12*v.x + m.M22*v.y + m.M32*v.z + m.M42*v.w,
|
|
m.M13*v.x + m.M23*v.y + m.M33*v.z + m.M43*v.w,
|
|
m.M14*v.x + m.M24*v.y + m.M34*v.z + m.M44*v.w);
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
#endif
|