/////////////////////////////////////////////////////////////////////////////// // // ## ###### // ###### ### Based on: // ## ############### // ########## # # # Shark 3D Engine (www.shark3d.com) // ######## // ######### # # # Copyright (c) 1996-2001 Spinor GmbH. // ## ########## // ## // /////////////////////////////////////////////////////////////////////////////// // // G A M E.O.N.E - LOW LEVEL LIB V1.0 // Copyright (C) 2001 LEVEL ONE ENTERTAINMENT, // Licensed under the terms of LGPL. //:--------------------------------------------------------------------------- //:Description // // LOW LEVEL 3D TRANSFORM UTIL HEADERFILE // //:--------------------------------------------------------------------------- #ifndef _LL3D_TRANSF_H #define _LL3D_TRANSF_H #include "ll3d_vec3.h" namespace ll3d { template struct CTranslQuat; /* * Structure defining a transformation in 3-dimensional space, * consisting of a scaling and rotation descibed by an quanternion * and a translation. */ template struct CTranslQuat { // Translation vector. // See also CTranslQuat::ApplyToPoint. CVec3 m_Transl; // Quanternion containing a rotation and scaling. // See also CTranslQuat::ApplyToPoint. CQuat m_Quat; // Does not initialize the structure. CTranslQuat(); CTranslQuat(const CTranslQuat &r); CTranslQuat(const CVec3 &Transl, const CQuat &Quat); CTranslQuat(T s); CTranslQuat &operator=(const CTranslQuat &r); CTranslQuat &operator=(T s); bool operator==(const CTranslQuat &r) const; bool operator!=(const CTranslQuat &r) const; bool operator==(T s) const; bool operator!=(T s) const; bool IsNull() const;// Are all components zero? bool IsFinite() const;// Are all components finit values? // Apply the position on a point. // In contrast to CTranslQuat::ApplyToVector, // both the the matrix and the translation is applied. // x.ApplyToPoint(v) = x.m_Transl + x.m_Quat.GetMat() * v CVec3 ApplyToPoint(const CVec3 &v) const; // Apply the position on a vector, // for example a directional vector or the difference between two points. // In contrast to CTranslQuat::ApplyToPoint, // only the matrix is applied but no translation. // x.ApplyToVector(v) = x.m_Quat.GetMat() * v CVec3 ApplyToVector(const CVec3 &v) const; // Returns the inverse position. // x.GetInv().m_Transl = - x.m_Quat.GetInvMat() * x.m_Transl // x.GetInv().m_Quat = x.m_Quat.GetInv() CTranslQuat GetInv() const; // Returns the concatenation of two positions. // Like for matrices, this operation is associative, // but not commutative. // x.Concat(y).ApplyToPoint(p) // = x.ApplyToPoint(y.ApplyToPoint(p)) // x.Concat(y).ApplyToVector(p) // = x.ApplyToVector(y.ApplyToVector(p)) // x.Concat(y).m_Transl // = x.m_Transl + x.m_Quat.GetMat() * y.m_Transl // x.Concat(y).m_Quat // = x.m_Quat * y.m_Quat CTranslQuat Concat(const CTranslQuat &r) const; // Return the concatenation of this // with the inverse of the second position. // x.ConcatInv(y) = x.Concat(y.GetInv()) // x.ConcatInv(y).Concat(y) = x CTranslQuat ConcatInv(const CTranslQuat &r) const; // Returns the concatenation of the inverse this // with the second position. // This is the relative transformation from x to y. // x.InvConcat(y) = x.GetInv().Concat(y)) // x.Concat(x.InvConcat(y)) = y CTranslQuat InvConcat(const CTranslQuat &r) const; }; /* * Implementation CTranslQuat */ template inline CTranslQuat::CTranslQuat() { } template inline CTranslQuat::CTranslQuat(const CTranslQuat &r) : m_Transl(r.m_Transl), m_Quat(r.m_Quat) { } template inline CTranslQuat::CTranslQuat(const CVec3 &Transl, const CQuat &Quat) : m_Transl(Transl), m_Quat(Quat) { } template inline CTranslQuat::CTranslQuat(T s) : m_Transl(0), m_Quat(s) { } template inline CTranslQuat &CTranslQuat::operator=( const CTranslQuat &r) { m_Transl = r.m_Transl; m_Quat = r.m_Quat; return *this; } template inline CTranslQuat &CTranslQuat::operator=(T s) { m_Transl = 0; m_Quat = s; return *this; } template inline bool CTranslQuat::operator==( const CTranslQuat &r) const { return m_Transl == r.m_Transl && m_Quat == r.m_Quat; } template inline bool CTranslQuat::operator!=( const CTranslQuat &r) const { return m_Transl != r.m_Transl || m_Quat != r.m_Quat; } template inline bool CTranslQuat::operator==(T s) const { return m_Transl.IsNull() && m_Quat == s; } template inline bool CTranslQuat::operator!=(T s) const { return !m_Transl.IsNull() || m_Quat != s; } /////////////////////////////////////////////////////////////////////////////// template inline bool CTranslQuat::IsNull() const { return m_Transl.IsNull() && m_Quat.IsNull(); } template inline bool CTranslQuat::IsFinite() const { return m_Transl.IsFinite() && m_Quat.IsFinite(); } /////////////////////////////////////////////////////////////////////////////// template inline CVec3 CTranslQuat::ApplyToPoint( const CVec3 &v) const { return m_Transl + m_Quat.GetMat() * v; } template inline CVec3 CTranslQuat::ApplyToVector( const CVec3 &v) const { return m_Quat.GetMat() * v; } template inline CTranslQuat CTranslQuat::GetInv() const { CQuat InvQuat = m_Quat.GetInv(); CMat3x3 InvMat = InvQuat.GetMat(); CVec3 InvTransl = - InvMat * m_Transl; return CTranslQuat(InvTransl, InvQuat); } template inline CTranslQuat CTranslQuat::Concat( const CTranslQuat &r) const { CMat3x3 Mat = m_Quat.GetMat(); CQuat TotQuat = m_Quat * r.m_Quat; CVec3 TotTransl = m_Transl + Mat * r.m_Transl; return CTranslQuat(TotTransl, TotQuat); } template inline CTranslQuat CTranslQuat::ConcatInv( const CTranslQuat &r) const { CQuat TotQuat = m_Quat * r.m_Quat.GetInv(); CMat3x3 TotMat = TotQuat.GetMat(); CVec3 TotTransl = m_Transl - TotMat * r.m_Transl; return CTranslQuat(TotTransl, TotQuat); } template inline CTranslQuat CTranslQuat::InvConcat( const CTranslQuat &r) const { CMat3x3 InvMat = m_Quat.GetInvMat(); CQuat TotQuat = m_Quat.GetInv() * r.m_Quat; CVec3 TotTransl = InvMat * (r.m_Transl - m_Transl); return CTranslQuat(TotTransl, TotQuat); } }//namespace ll3d #endif //_LL3D_TRANSF_H