Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

400 lines
17 KiB

  1. //====== Copyright 1996-2005, Valve Corporation, All rights reserved. =======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //===========================================================================//
  8. #ifndef TRANSFORM_H
  9. #define TRANSFORM_H
  10. #ifdef COMPILER_MSVC
  11. #pragma once
  12. #endif
  13. #include "tier0/memalloc.h"
  14. #include "mathlib/vector.h"
  15. #include "mathlib/mathlib.h"
  16. //-----------------------------------------------------------------------------
  17. // Matrix 3x4_t
  18. //-----------------------------------------------------------------------------
  19. class CTransformUnaligned;
  20. //-----------------------------------------------------------------------------
  21. // Represents a position + orientation using quaternions
  22. //-----------------------------------------------------------------------------
  23. class ALIGN16 CTransform
  24. {
  25. public:
  26. CTransform() {}
  27. CTransform( const Vector &v, const Quaternion &q ) : m_vPosition(v), m_orientation(q) {}
  28. CTransform( const Vector &v, const QAngle &a ) : m_vPosition(v)
  29. {
  30. AngleQuaternion( a, m_orientation );
  31. }
  32. VectorAligned m_vPosition;
  33. QuaternionAligned m_orientation;
  34. bool IsValid() const
  35. {
  36. return m_vPosition.IsValid() && m_orientation.IsValid();
  37. }
  38. bool operator==(const CTransform& v) const; ///< exact equality check
  39. bool operator!=(const CTransform& v) const;
  40. // for API compatibility with matrix3x4_t
  41. inline void InitFromQAngles( const QAngle &angles, const Vector &vPosition = vec3_origin );
  42. inline void InitFromMatrix( const matrix3x4_t &transform );
  43. inline void InitFromQuaternion( const Quaternion &orientation, const Vector &vPosition = vec3_origin );
  44. inline Quaternion ToQuaternion() const;
  45. inline QAngle ToQAngle() const;
  46. inline matrix3x4_t ToMatrix() const;
  47. inline void SetToIdentity();
  48. inline void SetOrigin( Vector const &vPos ) { m_vPosition = vPos; }
  49. inline void SetAngles( QAngle const &vAngles );
  50. inline Vector GetOrigin( void ) const { return m_vPosition; }
  51. inline void GetBasisVectorsFLU( Vector *pForward, Vector *pLeft, Vector *pUp ) const;
  52. inline Vector GetForward() const;
  53. inline Vector TransformVector( const Vector &v0 ) const;
  54. inline Vector RotateVector( const Vector &v0 ) const;
  55. inline Vector TransformVectorByInverse( const Vector &v0 ) const;
  56. inline Vector RotateVectorByInverse( const Vector &v0 ) const;
  57. inline Vector RotateExtents( const Vector &vBoxExtents ) const; // these are extents and must remain positive/symmetric after rotation
  58. inline void TransformAABB( const Vector &vecMinsIn, const Vector &vecMaxsIn, Vector &vecMinsOut, Vector &vecMaxsOut ) const;
  59. inline void TransformAABBByInverse( const Vector &vecMinsIn, const Vector &vecMaxsIn, Vector &vecMinsOut, Vector &vecMaxsOut ) const;
  60. inline void RotateAABB( const Vector &vecMinsIn, const Vector &vecMaxsIn, Vector &vecMinsOut, Vector &vecMaxsOut ) const;
  61. inline void RotateAABBByInverse( const Vector &vecMinsIn, const Vector &vecMaxsIn, Vector &vecMinsOut, Vector &vecMaxsOut ) const;
  62. //inline void TransformPlane( const cplane_t &inPlane, cplane_t &outPlane ) const;
  63. //inline void InverseTransformPlane( const cplane_t &inPlane, cplane_t &outPlane ) const;
  64. /// Computes an inverse. Uses the 'TR' naming to be consistent with the same method in matrix3x4_t (which only works with orthonormal matrices)
  65. inline void InverseTR( CTransform &out ) const;
  66. public:
  67. CTransform &operator=( const CTransformUnaligned &i );
  68. } ALIGN16_POST;
  69. extern const CTransform g_TransformIdentity;
  70. //-----------------------------------------------------------------------------
  71. // Represents an unaligned position + orientation using quaternions,
  72. // used only for copying data around
  73. //-----------------------------------------------------------------------------
  74. class CTransformUnaligned
  75. {
  76. public:
  77. CTransformUnaligned() {}
  78. CTransformUnaligned( const Vector &v, const Quaternion &q ) : m_vPosition(v), m_orientation(q) {}
  79. CTransformUnaligned( const CTransform &transform ) : m_vPosition(transform.m_vPosition), m_orientation(transform.m_orientation) {}
  80. CTransform AsTransform() const { return CTransform( m_vPosition, m_orientation ); }
  81. Vector m_vPosition;
  82. Quaternion m_orientation;
  83. bool IsValid() const
  84. {
  85. return m_vPosition.IsValid() && m_orientation.IsValid();
  86. }
  87. public:
  88. CTransformUnaligned &operator=( const CTransform &i );
  89. };
  90. //-----------------------------------------------------------------------------
  91. // Inline methods
  92. //-----------------------------------------------------------------------------
  93. inline CTransform &CTransform::operator=( const CTransformUnaligned &i )
  94. {
  95. m_vPosition = i.m_vPosition;
  96. m_orientation = i.m_orientation;
  97. return *this;
  98. }
  99. inline CTransformUnaligned &CTransformUnaligned::operator=( const CTransform &i )
  100. {
  101. m_vPosition = i.m_vPosition;
  102. m_orientation = i.m_orientation;
  103. return *this;
  104. }
  105. //-----------------------------------------------------------------------------
  106. // Other methods
  107. //-----------------------------------------------------------------------------
  108. void ConcatTransforms( const CTransform &in1, const CTransform &in2, CTransform &out );
  109. void TransformSlerp( const CTransform &p, const CTransform &q, float t, CTransform &qt );
  110. void TransformLerp( const CTransform &p, const CTransform &q, float t, CTransform &qt );
  111. void TransformMatrix( const CTransform &in, matrix3x4_t &out );
  112. void TransformMatrix( const CTransform &in, const Vector &vScaleIn, matrix3x4_t &out );
  113. inline void TransformMatrix( const CTransform &in, float flScale, matrix3x4_t &out )
  114. {
  115. QuaternionMatrix( in.m_orientation, in.m_vPosition, Vector( flScale, flScale, flScale ), out );
  116. }
  117. inline float TransformNormalize( CTransform &in )
  118. {
  119. return QuaternionNormalize( in.m_orientation );
  120. }
  121. void TransformMatrix( const CTransformUnaligned &in, matrix3x4_t &out );
  122. void MatrixTransform( const matrix3x4_t &in, CTransform &out );
  123. void MatrixTransform( const matrix3x4_t &in, CTransformUnaligned &out );
  124. void MatrixTransform( const matrix3x4_t &in, CTransform &out, Vector &vScaleOut );
  125. inline void MatrixTransform( const matrix3x4_t &in, CTransform &out, float &flScale )
  126. {
  127. Vector vScale;
  128. MatrixTransform( in, out, vScale );
  129. flScale = vScale.LargestComponentValue();
  130. }
  131. void AngleTransform( const QAngle &angles, const Vector &origin, CTransform &out );
  132. void SetIdentityTransform( CTransform &out );
  133. void TransformVectorsFLU( const CTransform &in, Vector* pForward, Vector *pLeft, Vector *pUp );
  134. void TransformVectorsForward( const CTransform &in, Vector* pForward );
  135. inline const CTransform GetIdentityTransform()
  136. {
  137. CTransform out;
  138. SetIdentityTransform( out );
  139. return out;
  140. }
  141. inline const CTransform MatrixTransform( const matrix3x4_t &in )
  142. {
  143. CTransform out ;
  144. MatrixTransform( in, out );
  145. return out;
  146. }
  147. inline const matrix3x4_t TransformMatrix( const CTransform &in )
  148. {
  149. matrix3x4_t out;
  150. TransformMatrix( in, out );
  151. return out;
  152. }
  153. inline const matrix3x4_t TransformMatrix( const CTransformUnaligned &in )
  154. {
  155. matrix3x4_t out;
  156. TransformMatrix( in, out );
  157. return out;
  158. }
  159. inline const CTransform ConcatTransforms( const CTransform &in1, const CTransform &in2 )
  160. {
  161. CTransform result;
  162. ConcatTransforms( in1, in2, result );
  163. return result;
  164. }
  165. void TransformInvert( const CTransform &in, CTransform &out );
  166. void AxisAngleTransform( const Vector &vecAxis, float flAngleDegrees, CTransform &out );
  167. void VectorIRotate( const Vector &v, const CTransform &t, Vector &out );
  168. void VectorITransform( const Vector &v, const CTransform &t, Vector &out );
  169. inline Vector TransformPoint( const CTransformUnaligned & tm, const Vector & p )
  170. {
  171. return Vector(
  172. tm.m_vPosition.x + ( 1.0f - 2.0f * tm.m_orientation.y * tm.m_orientation.y - 2.0f * tm.m_orientation.z * tm.m_orientation.z ) * p.x + ( 2.0f * tm.m_orientation.x * tm.m_orientation.y - 2.0f * tm.m_orientation.w * tm.m_orientation.z ) * p.y + ( 2.0f * tm.m_orientation.x * tm.m_orientation.z + 2.0f * tm.m_orientation.w * tm.m_orientation.y ) * p.z,
  173. tm.m_vPosition.y + ( 2.0f * tm.m_orientation.x * tm.m_orientation.y + 2.0f * tm.m_orientation.w * tm.m_orientation.z ) * p.x + ( 1.0f - 2.0f * tm.m_orientation.x * tm.m_orientation.x - 2.0f * tm.m_orientation.z * tm.m_orientation.z ) * p.y + ( 2.0f * tm.m_orientation.y * tm.m_orientation.z - 2.0f * tm.m_orientation.w * tm.m_orientation.x ) * p.z,
  174. tm.m_vPosition.z + ( 2.0f * tm.m_orientation.x * tm.m_orientation.z - 2.0f * tm.m_orientation.w * tm.m_orientation.y ) * p.x + ( 2.0f * tm.m_orientation.y * tm.m_orientation.z + 2.0f * tm.m_orientation.w * tm.m_orientation.x ) * p.y + ( 1.0f - 2.0f * tm.m_orientation.x * tm.m_orientation.x - 2.0f * tm.m_orientation.y * tm.m_orientation.y ) * p.z
  175. );
  176. }
  177. // TODO: implement in SIMD?
  178. inline Vector TransformPoint( const CTransform & tm, const Vector & p )
  179. {
  180. return Vector(
  181. tm.m_vPosition.x + ( 1.0f - 2.0f * tm.m_orientation.y * tm.m_orientation.y - 2.0f * tm.m_orientation.z * tm.m_orientation.z ) * p.x + ( 2.0f * tm.m_orientation.x * tm.m_orientation.y - 2.0f * tm.m_orientation.w * tm.m_orientation.z ) * p.y + ( 2.0f * tm.m_orientation.x * tm.m_orientation.z + 2.0f * tm.m_orientation.w * tm.m_orientation.y ) * p.z,
  182. tm.m_vPosition.y + ( 2.0f * tm.m_orientation.x * tm.m_orientation.y + 2.0f * tm.m_orientation.w * tm.m_orientation.z ) * p.x + ( 1.0f - 2.0f * tm.m_orientation.x * tm.m_orientation.x - 2.0f * tm.m_orientation.z * tm.m_orientation.z ) * p.y + ( 2.0f * tm.m_orientation.y * tm.m_orientation.z - 2.0f * tm.m_orientation.w * tm.m_orientation.x ) * p.z,
  183. tm.m_vPosition.z + ( 2.0f * tm.m_orientation.x * tm.m_orientation.z - 2.0f * tm.m_orientation.w * tm.m_orientation.y ) * p.x + ( 2.0f * tm.m_orientation.y * tm.m_orientation.z + 2.0f * tm.m_orientation.w * tm.m_orientation.x ) * p.y + ( 1.0f - 2.0f * tm.m_orientation.x * tm.m_orientation.x - 2.0f * tm.m_orientation.y * tm.m_orientation.y ) * p.z
  184. );
  185. }
  186. template < class T >
  187. inline void TransformPoint( const T & tm, const Vector & p, Vector & out )
  188. {
  189. out.x = tm.m_vPosition.x + ( 1.0f - 2.0f * tm.m_orientation.y * tm.m_orientation.y - 2.0f * tm.m_orientation.z * tm.m_orientation.z ) * p.x + ( 2.0f * tm.m_orientation.x * tm.m_orientation.y - 2.0f * tm.m_orientation.w * tm.m_orientation.z ) * p.y + ( 2.0f * tm.m_orientation.x * tm.m_orientation.z + 2.0f * tm.m_orientation.w * tm.m_orientation.y ) * p.z;
  190. out.y = tm.m_vPosition.y + ( 2.0f * tm.m_orientation.x * tm.m_orientation.y + 2.0f * tm.m_orientation.w * tm.m_orientation.z ) * p.x + ( 1.0f - 2.0f * tm.m_orientation.x * tm.m_orientation.x - 2.0f * tm.m_orientation.z * tm.m_orientation.z ) * p.y + ( 2.0f * tm.m_orientation.y * tm.m_orientation.z - 2.0f * tm.m_orientation.w * tm.m_orientation.x ) * p.z;
  191. out.z = tm.m_vPosition.z + ( 2.0f * tm.m_orientation.x * tm.m_orientation.z - 2.0f * tm.m_orientation.w * tm.m_orientation.y ) * p.x + ( 2.0f * tm.m_orientation.y * tm.m_orientation.z + 2.0f * tm.m_orientation.w * tm.m_orientation.x ) * p.y + ( 1.0f - 2.0f * tm.m_orientation.x * tm.m_orientation.x - 2.0f * tm.m_orientation.y * tm.m_orientation.y ) * p.z;
  192. }
  193. template < class T >
  194. inline void RotatePoint( const T & tm, const Vector & p, Vector & out )
  195. {
  196. out.x = ( 1.0f - 2.0f * tm.m_orientation.y * tm.m_orientation.y - 2.0f * tm.m_orientation.z * tm.m_orientation.z ) * p.x + ( 2.0f * tm.m_orientation.x * tm.m_orientation.y - 2.0f * tm.m_orientation.w * tm.m_orientation.z ) * p.y + ( 2.0f * tm.m_orientation.x * tm.m_orientation.z + 2.0f * tm.m_orientation.w * tm.m_orientation.y ) * p.z;
  197. out.y = ( 2.0f * tm.m_orientation.x * tm.m_orientation.y + 2.0f * tm.m_orientation.w * tm.m_orientation.z ) * p.x + ( 1.0f - 2.0f * tm.m_orientation.x * tm.m_orientation.x - 2.0f * tm.m_orientation.z * tm.m_orientation.z ) * p.y + ( 2.0f * tm.m_orientation.y * tm.m_orientation.z - 2.0f * tm.m_orientation.w * tm.m_orientation.x ) * p.z;
  198. out.z = ( 2.0f * tm.m_orientation.x * tm.m_orientation.z - 2.0f * tm.m_orientation.w * tm.m_orientation.y ) * p.x + ( 2.0f * tm.m_orientation.y * tm.m_orientation.z + 2.0f * tm.m_orientation.w * tm.m_orientation.x ) * p.y + ( 1.0f - 2.0f * tm.m_orientation.x * tm.m_orientation.x - 2.0f * tm.m_orientation.y * tm.m_orientation.y ) * p.z;
  199. }
  200. inline const CTransform TransformInvert( const CTransform &in )
  201. {
  202. CTransform out ;
  203. TransformInvert( in, out );
  204. return out;
  205. }
  206. // Transform equality test
  207. bool TransformsAreEqual( const CTransform &src1, const CTransform &src2, float flPosTolerance = 1e-2, float flRotTolerance = 1e-1f );
  208. // Computes world-space transforms given local-space transforms + parent info
  209. // The start of the pTransforms array (nRootTransformCount # of transforms) must be filled with
  210. // the root transforms which have no parent. The end of the pTransforms array (nTransformCount # of transforms)
  211. // must be filled with local-space transforms which are relative to other transforms, including possibly the
  212. // root transforms. Therefore, (nRootTransformCount + nTransformCount) # of transforms must be passed into pTransforms.
  213. // Only nTransformCount parent indices should be passed in.
  214. // Parent indices are relative to the entire array, so a parent index of 0 indicates the first element
  215. // of the array, which is always a root transform. -1 parent index is *illegal*
  216. // Parent indices must always be sorted so that the index transforms earlier in the array.
  217. // The transforms are modified in-place.
  218. void TransformToWorldSpace( int nRootTransformCount, int nTransformCount, const int *pParentIndices, CTransform *pTransforms );
  219. void TransformToParentSpace( int nRootTransformCount, int nTransformCount, const int *pParentIndices, CTransform *pTransforms );
  220. inline void CTransform::InitFromQAngles( const QAngle &angles, const Vector &vPosition )
  221. {
  222. AngleQuaternion( angles, m_orientation );
  223. m_vPosition = vPosition;
  224. }
  225. inline void CTransform::InitFromMatrix( const matrix3x4_t &transform )
  226. {
  227. m_orientation = MatrixQuaternion( transform );
  228. m_vPosition = transform.GetOrigin();
  229. }
  230. inline void CTransform::InitFromQuaternion( const Quaternion &orientation, const Vector &vPosition )
  231. {
  232. m_orientation = orientation;
  233. m_vPosition = vPosition;
  234. }
  235. inline void CTransform::SetAngles( QAngle const &vAngles )
  236. {
  237. AngleQuaternion( vAngles, m_orientation );
  238. }
  239. inline Quaternion CTransform::ToQuaternion() const
  240. {
  241. return m_orientation;
  242. }
  243. inline QAngle CTransform::ToQAngle() const
  244. {
  245. QAngle angles;
  246. QuaternionAngles( m_orientation, angles );
  247. return angles;
  248. }
  249. inline matrix3x4_t CTransform::ToMatrix() const
  250. {
  251. return TransformMatrix( *this );
  252. }
  253. inline void CTransform::SetToIdentity()
  254. {
  255. m_vPosition = vec3_origin;
  256. m_orientation = quat_identity;
  257. }
  258. inline void CTransform::GetBasisVectorsFLU( Vector *pForward, Vector *pLeft, Vector *pUp ) const
  259. {
  260. TransformVectorsFLU( *this, pForward, pLeft, pUp );
  261. }
  262. inline Vector CTransform::GetForward() const
  263. {
  264. Vector vForward;
  265. TransformVectorsForward( *this, &vForward );
  266. return vForward;
  267. }
  268. inline Vector CTransform::TransformVector( const Vector &v0 ) const
  269. {
  270. return TransformPoint( *this, v0 );
  271. }
  272. inline Vector CTransform::RotateVector( const Vector &v0 ) const
  273. {
  274. Vector vOut;
  275. RotatePoint( *this, v0, vOut );
  276. return vOut;
  277. }
  278. inline Vector CTransform::TransformVectorByInverse( const Vector &v0 ) const
  279. {
  280. Vector vOut;
  281. VectorITransform( v0, *this, vOut );
  282. return vOut;
  283. }
  284. inline Vector CTransform::RotateVectorByInverse( const Vector &v0 ) const
  285. {
  286. Vector vOut;
  287. VectorIRotate( v0, *this, vOut );
  288. return vOut;
  289. }
  290. inline bool CTransform::operator==(const CTransform& t) const
  291. {
  292. return t.m_vPosition == m_vPosition && t.m_orientation == m_orientation;
  293. }
  294. inline bool CTransform::operator!=(const CTransform& t) const
  295. {
  296. return t.m_vPosition != m_vPosition || t.m_orientation != m_orientation;
  297. }
  298. // PERFORMANCE: No native versions of these but implement them on matrix for convenient access
  299. inline void CTransform::TransformAABB( const Vector &vecMinsIn, const Vector &vecMaxsIn, Vector &vecMinsOut, Vector &vecMaxsOut ) const
  300. {
  301. ToMatrix().TransformAABB( vecMinsIn, vecMaxsIn, vecMinsOut, vecMaxsOut );
  302. }
  303. inline void CTransform::TransformAABBByInverse( const Vector &vecMinsIn, const Vector &vecMaxsIn, Vector &vecMinsOut, Vector &vecMaxsOut ) const
  304. {
  305. ToMatrix().TransformAABBByInverse( vecMinsIn, vecMaxsIn, vecMinsOut, vecMaxsOut );
  306. }
  307. inline void CTransform::RotateAABB( const Vector &vecMinsIn, const Vector &vecMaxsIn, Vector &vecMinsOut, Vector &vecMaxsOut ) const
  308. {
  309. ToMatrix().RotateAABB( vecMinsIn, vecMaxsIn, vecMinsOut, vecMaxsOut );
  310. }
  311. inline void CTransform::RotateAABBByInverse( const Vector &vecMinsIn, const Vector &vecMaxsIn, Vector &vecMinsOut, Vector &vecMaxsOut ) const
  312. {
  313. ToMatrix().RotateAABBByInverse( vecMinsIn, vecMaxsIn, vecMinsOut, vecMaxsOut );
  314. }
  315. inline void CTransform::InverseTR( CTransform &out ) const
  316. {
  317. matrix3x4_t xForm = ToMatrix();
  318. out = xForm.InverseTR().ToCTransform();
  319. }
  320. // transform conversion operators on matrix3x4_t
  321. inline void matrix3x4_t::InitFromCTransform( const CTransform &transform )
  322. {
  323. TransformMatrix( transform, *this );
  324. }
  325. inline CTransform matrix3x4_t::ToCTransform() const
  326. {
  327. return MatrixTransform( *this );
  328. }
  329. #endif // TRANSFORM