/* =========================================================================== Doom 3 GPL Source Code Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code"). Doom 3 Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Doom 3 Source Code 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. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Doom 3 Source Code. If not, see . In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. =========================================================================== */ #ifndef __JOINTTRANSFORM_H__ #define __JOINTTRANSFORM_H__ #include "idlib/math/Matrix.h" #include "idlib/math/Quat.h" /* =============================================================================== Joint Quaternion =============================================================================== */ class idJointQuat { public: idQuat q; idVec3 t; }; /* =============================================================================== Joint Matrix idMat3 m; idVec3 t; m[0][0], m[1][0], m[2][0], t[0] m[0][1], m[1][1], m[2][1], t[1] m[0][2], m[1][2], m[2][2], t[2] =============================================================================== */ class idJointMat { public: void SetRotation( const idMat3 &m ); void SetTranslation( const idVec3 &t ); idVec3 operator*( const idVec3 &v ) const; // only rotate idVec3 operator*( const idVec4 &v ) const; // rotate and translate idJointMat & operator*=( const idJointMat &a ); // transform idJointMat & operator/=( const idJointMat &a ); // untransform bool Compare( const idJointMat &a ) const; // exact compare, no epsilon bool Compare( const idJointMat &a, const float epsilon ) const; // compare with epsilon bool operator==( const idJointMat &a ) const; // exact compare, no epsilon bool operator!=( const idJointMat &a ) const; // exact compare, no epsilon idMat3 ToMat3( void ) const; idVec3 ToVec3( void ) const; idJointQuat ToJointQuat( void ) const; const float * ToFloatPtr( void ) const; float * ToFloatPtr( void ); private: float mat[3*4]; }; ID_INLINE void idJointMat::SetRotation( const idMat3 &m ) { // NOTE: idMat3 is transposed because it is column-major mat[0 * 4 + 0] = m[0][0]; mat[0 * 4 + 1] = m[1][0]; mat[0 * 4 + 2] = m[2][0]; mat[1 * 4 + 0] = m[0][1]; mat[1 * 4 + 1] = m[1][1]; mat[1 * 4 + 2] = m[2][1]; mat[2 * 4 + 0] = m[0][2]; mat[2 * 4 + 1] = m[1][2]; mat[2 * 4 + 2] = m[2][2]; } ID_INLINE void idJointMat::SetTranslation( const idVec3 &t ) { mat[0 * 4 + 3] = t[0]; mat[1 * 4 + 3] = t[1]; mat[2 * 4 + 3] = t[2]; } ID_INLINE idVec3 idJointMat::operator*( const idVec3 &v ) const { return idVec3( mat[0 * 4 + 0] * v[0] + mat[0 * 4 + 1] * v[1] + mat[0 * 4 + 2] * v[2], mat[1 * 4 + 0] * v[0] + mat[1 * 4 + 1] * v[1] + mat[1 * 4 + 2] * v[2], mat[2 * 4 + 0] * v[0] + mat[2 * 4 + 1] * v[1] + mat[2 * 4 + 2] * v[2] ); } ID_INLINE idVec3 idJointMat::operator*( const idVec4 &v ) const { return idVec3( mat[0 * 4 + 0] * v[0] + mat[0 * 4 + 1] * v[1] + mat[0 * 4 + 2] * v[2] + mat[0 * 4 + 3] * v[3], mat[1 * 4 + 0] * v[0] + mat[1 * 4 + 1] * v[1] + mat[1 * 4 + 2] * v[2] + mat[1 * 4 + 3] * v[3], mat[2 * 4 + 0] * v[0] + mat[2 * 4 + 1] * v[1] + mat[2 * 4 + 2] * v[2] + mat[2 * 4 + 3] * v[3] ); } ID_INLINE idJointMat &idJointMat::operator*=( const idJointMat &a ) { float dst[3]; dst[0] = mat[0 * 4 + 0] * a.mat[0 * 4 + 0] + mat[1 * 4 + 0] * a.mat[0 * 4 + 1] + mat[2 * 4 + 0] * a.mat[0 * 4 + 2]; dst[1] = mat[0 * 4 + 0] * a.mat[1 * 4 + 0] + mat[1 * 4 + 0] * a.mat[1 * 4 + 1] + mat[2 * 4 + 0] * a.mat[1 * 4 + 2]; dst[2] = mat[0 * 4 + 0] * a.mat[2 * 4 + 0] + mat[1 * 4 + 0] * a.mat[2 * 4 + 1] + mat[2 * 4 + 0] * a.mat[2 * 4 + 2]; mat[0 * 4 + 0] = dst[0]; mat[1 * 4 + 0] = dst[1]; mat[2 * 4 + 0] = dst[2]; dst[0] = mat[0 * 4 + 1] * a.mat[0 * 4 + 0] + mat[1 * 4 + 1] * a.mat[0 * 4 + 1] + mat[2 * 4 + 1] * a.mat[0 * 4 + 2]; dst[1] = mat[0 * 4 + 1] * a.mat[1 * 4 + 0] + mat[1 * 4 + 1] * a.mat[1 * 4 + 1] + mat[2 * 4 + 1] * a.mat[1 * 4 + 2]; dst[2] = mat[0 * 4 + 1] * a.mat[2 * 4 + 0] + mat[1 * 4 + 1] * a.mat[2 * 4 + 1] + mat[2 * 4 + 1] * a.mat[2 * 4 + 2]; mat[0 * 4 + 1] = dst[0]; mat[1 * 4 + 1] = dst[1]; mat[2 * 4 + 1] = dst[2]; dst[0] = mat[0 * 4 + 2] * a.mat[0 * 4 + 0] + mat[1 * 4 + 2] * a.mat[0 * 4 + 1] + mat[2 * 4 + 2] * a.mat[0 * 4 + 2]; dst[1] = mat[0 * 4 + 2] * a.mat[1 * 4 + 0] + mat[1 * 4 + 2] * a.mat[1 * 4 + 1] + mat[2 * 4 + 2] * a.mat[1 * 4 + 2]; dst[2] = mat[0 * 4 + 2] * a.mat[2 * 4 + 0] + mat[1 * 4 + 2] * a.mat[2 * 4 + 1] + mat[2 * 4 + 2] * a.mat[2 * 4 + 2]; mat[0 * 4 + 2] = dst[0]; mat[1 * 4 + 2] = dst[1]; mat[2 * 4 + 2] = dst[2]; dst[0] = mat[0 * 4 + 3] * a.mat[0 * 4 + 0] + mat[1 * 4 + 3] * a.mat[0 * 4 + 1] + mat[2 * 4 + 3] * a.mat[0 * 4 + 2]; dst[1] = mat[0 * 4 + 3] * a.mat[1 * 4 + 0] + mat[1 * 4 + 3] * a.mat[1 * 4 + 1] + mat[2 * 4 + 3] * a.mat[1 * 4 + 2]; dst[2] = mat[0 * 4 + 3] * a.mat[2 * 4 + 0] + mat[1 * 4 + 3] * a.mat[2 * 4 + 1] + mat[2 * 4 + 3] * a.mat[2 * 4 + 2]; mat[0 * 4 + 3] = dst[0]; mat[1 * 4 + 3] = dst[1]; mat[2 * 4 + 3] = dst[2]; mat[0 * 4 + 3] += a.mat[0 * 4 + 3]; mat[1 * 4 + 3] += a.mat[1 * 4 + 3]; mat[2 * 4 + 3] += a.mat[2 * 4 + 3]; return *this; } ID_INLINE idJointMat &idJointMat::operator/=( const idJointMat &a ) { float dst[3]; mat[0 * 4 + 3] -= a.mat[0 * 4 + 3]; mat[1 * 4 + 3] -= a.mat[1 * 4 + 3]; mat[2 * 4 + 3] -= a.mat[2 * 4 + 3]; dst[0] = mat[0 * 4 + 0] * a.mat[0 * 4 + 0] + mat[1 * 4 + 0] * a.mat[1 * 4 + 0] + mat[2 * 4 + 0] * a.mat[2 * 4 + 0]; dst[1] = mat[0 * 4 + 0] * a.mat[0 * 4 + 1] + mat[1 * 4 + 0] * a.mat[1 * 4 + 1] + mat[2 * 4 + 0] * a.mat[2 * 4 + 1]; dst[2] = mat[0 * 4 + 0] * a.mat[0 * 4 + 2] + mat[1 * 4 + 0] * a.mat[1 * 4 + 2] + mat[2 * 4 + 0] * a.mat[2 * 4 + 2]; mat[0 * 4 + 0] = dst[0]; mat[1 * 4 + 0] = dst[1]; mat[2 * 4 + 0] = dst[2]; dst[0] = mat[0 * 4 + 1] * a.mat[0 * 4 + 0] + mat[1 * 4 + 1] * a.mat[1 * 4 + 0] + mat[2 * 4 + 1] * a.mat[2 * 4 + 0]; dst[1] = mat[0 * 4 + 1] * a.mat[0 * 4 + 1] + mat[1 * 4 + 1] * a.mat[1 * 4 + 1] + mat[2 * 4 + 1] * a.mat[2 * 4 + 1]; dst[2] = mat[0 * 4 + 1] * a.mat[0 * 4 + 2] + mat[1 * 4 + 1] * a.mat[1 * 4 + 2] + mat[2 * 4 + 1] * a.mat[2 * 4 + 2]; mat[0 * 4 + 1] = dst[0]; mat[1 * 4 + 1] = dst[1]; mat[2 * 4 + 1] = dst[2]; dst[0] = mat[0 * 4 + 2] * a.mat[0 * 4 + 0] + mat[1 * 4 + 2] * a.mat[1 * 4 + 0] + mat[2 * 4 + 2] * a.mat[2 * 4 + 0]; dst[1] = mat[0 * 4 + 2] * a.mat[0 * 4 + 1] + mat[1 * 4 + 2] * a.mat[1 * 4 + 1] + mat[2 * 4 + 2] * a.mat[2 * 4 + 1]; dst[2] = mat[0 * 4 + 2] * a.mat[0 * 4 + 2] + mat[1 * 4 + 2] * a.mat[1 * 4 + 2] + mat[2 * 4 + 2] * a.mat[2 * 4 + 2]; mat[0 * 4 + 2] = dst[0]; mat[1 * 4 + 2] = dst[1]; mat[2 * 4 + 2] = dst[2]; dst[0] = mat[0 * 4 + 3] * a.mat[0 * 4 + 0] + mat[1 * 4 + 3] * a.mat[1 * 4 + 0] + mat[2 * 4 + 3] * a.mat[2 * 4 + 0]; dst[1] = mat[0 * 4 + 3] * a.mat[0 * 4 + 1] + mat[1 * 4 + 3] * a.mat[1 * 4 + 1] + mat[2 * 4 + 3] * a.mat[2 * 4 + 1]; dst[2] = mat[0 * 4 + 3] * a.mat[0 * 4 + 2] + mat[1 * 4 + 3] * a.mat[1 * 4 + 2] + mat[2 * 4 + 3] * a.mat[2 * 4 + 2]; mat[0 * 4 + 3] = dst[0]; mat[1 * 4 + 3] = dst[1]; mat[2 * 4 + 3] = dst[2]; return *this; } ID_INLINE bool idJointMat::Compare( const idJointMat &a ) const { int i; for ( i = 0; i < 12; i++ ) { if ( mat[i] != a.mat[i] ) { return false; } } return true; } ID_INLINE bool idJointMat::Compare( const idJointMat &a, const float epsilon ) const { int i; for ( i = 0; i < 12; i++ ) { if ( idMath::Fabs( mat[i] - a.mat[i] ) > epsilon ) { return false; } } return true; } ID_INLINE bool idJointMat::operator==( const idJointMat &a ) const { return Compare( a ); } ID_INLINE bool idJointMat::operator!=( const idJointMat &a ) const { return !Compare( a ); } ID_INLINE idMat3 idJointMat::ToMat3( void ) const { return idMat3( mat[0 * 4 + 0], mat[1 * 4 + 0], mat[2 * 4 + 0], mat[0 * 4 + 1], mat[1 * 4 + 1], mat[2 * 4 + 1], mat[0 * 4 + 2], mat[1 * 4 + 2], mat[2 * 4 + 2] ); } ID_INLINE idVec3 idJointMat::ToVec3( void ) const { return idVec3( mat[0 * 4 + 3], mat[1 * 4 + 3], mat[2 * 4 + 3] ); } ID_INLINE const float *idJointMat::ToFloatPtr( void ) const { return mat; } ID_INLINE float *idJointMat::ToFloatPtr( void ) { return mat; } #endif /* !__JOINTTRANSFORM_H__ */