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.

3078 lines
76 KiB

  1. //====== Copyright 1996-2005, Valve Corporation, All rights reserved. =======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #ifndef VECTOR_H
  9. #define VECTOR_H
  10. #ifdef _WIN32
  11. #pragma once
  12. #endif
  13. #include <math.h>
  14. #include <float.h>
  15. // For vec_t, put this somewhere else?
  16. #include "tier0/basetypes.h"
  17. #if defined( _PS3 )
  18. //#include <ssemath.h>
  19. #include <vectormath/c/vectormath_aos.h>
  20. #include "tier0/platform.h"
  21. #include "mathlib/math_pfns.h"
  22. #endif
  23. #ifndef PLATFORM_PPC // we want our linux with xmm support
  24. // For MMX intrinsics
  25. #include <xmmintrin.h>
  26. #endif
  27. #ifndef ALIGN16_POST
  28. #define ALIGN16_POST
  29. #endif
  30. #include "tier0/dbg.h"
  31. #include "tier0/platform.h"
  32. #if !defined( __SPU__ )
  33. #include "tier0/threadtools.h"
  34. #endif
  35. #include "mathlib/vector2d.h"
  36. #include "mathlib/math_pfns.h"
  37. #include "tier0/memalloc.h"
  38. #include "vstdlib/random.h"
  39. // Uncomment this to add extra Asserts to check for NANs, uninitialized vecs, etc.
  40. //#define VECTOR_PARANOIA 1
  41. // Uncomment this to make sure we don't do anything slow with our vectors
  42. //#define VECTOR_NO_SLOW_OPERATIONS 1
  43. // Used to make certain code easier to read.
  44. #define X_INDEX 0
  45. #define Y_INDEX 1
  46. #define Z_INDEX 2
  47. #ifdef VECTOR_PARANOIA
  48. #define CHECK_VALID( _v) Assert( (_v).IsValid() )
  49. #else
  50. #ifdef GNUC
  51. #define CHECK_VALID( _v)
  52. #else
  53. #define CHECK_VALID( _v) 0
  54. #endif
  55. #endif
  56. #define VecToString(v) (static_cast<const char *>(CFmtStr("(%f, %f, %f)", (v).x, (v).y, (v).z))) // ** Note: this generates a temporary, don't hold reference!
  57. class VectorByValue;
  58. //=========================================================
  59. // 3D Vector
  60. //=========================================================
  61. class Vector
  62. {
  63. public:
  64. // Members
  65. vec_t x, y, z;
  66. // Construction/destruction:
  67. Vector(void);
  68. Vector(vec_t X, vec_t Y, vec_t Z);
  69. // Initialization
  70. void Init(vec_t ix=0.0f, vec_t iy=0.0f, vec_t iz=0.0f);
  71. // TODO (Ilya): Should there be an init that takes a single float for consistency?
  72. // Got any nasty NAN's?
  73. bool IsValid() const;
  74. bool IsReasonable( float range = 1000000 ) const; ///< Check for reasonably-sized values (if used as a game world position)
  75. void Invalidate();
  76. // array access...
  77. vec_t operator[](int i) const;
  78. vec_t& operator[](int i);
  79. // Base address...
  80. vec_t* Base();
  81. vec_t const* Base() const;
  82. // Cast to Vector2D...
  83. Vector2D& AsVector2D();
  84. const Vector2D& AsVector2D() const;
  85. // Initialization methods
  86. void Random( vec_t minVal, vec_t maxVal );
  87. inline void Zero(); ///< zero out a vector
  88. // equality
  89. bool operator==(const Vector& v) const;
  90. bool operator!=(const Vector& v) const;
  91. // arithmetic operations
  92. FORCEINLINE Vector& operator+=(const Vector &v);
  93. FORCEINLINE Vector& operator-=(const Vector &v);
  94. FORCEINLINE Vector& operator*=(const Vector &v);
  95. FORCEINLINE Vector& operator*=(float s);
  96. FORCEINLINE Vector& operator/=(const Vector &v);
  97. FORCEINLINE Vector& operator/=(float s);
  98. FORCEINLINE Vector& operator+=(float fl) ; ///< broadcast add
  99. FORCEINLINE Vector& operator-=(float fl) ; ///< broadcast sub
  100. // negate the vector components
  101. void Negate();
  102. // Get the vector's magnitude.
  103. inline vec_t Length() const;
  104. // Get the vector's magnitude squared.
  105. FORCEINLINE vec_t LengthSqr(void) const
  106. {
  107. CHECK_VALID(*this);
  108. return (x*x + y*y + z*z);
  109. }
  110. // Get one over the vector's length
  111. // via fast hardware approximation
  112. inline vec_t LengthRecipFast(void) const
  113. {
  114. return FastRSqrtFast( LengthSqr() );
  115. }
  116. // return true if this vector is (0,0,0) within tolerance
  117. bool IsZero( float tolerance = 0.01f ) const
  118. {
  119. return (x > -tolerance && x < tolerance &&
  120. y > -tolerance && y < tolerance &&
  121. z > -tolerance && z < tolerance);
  122. }
  123. // return true if this vector is exactly (0,0,0) -- only fast if vector is coming from memory, not registers
  124. inline bool IsZeroFast( ) const RESTRICT
  125. {
  126. COMPILE_TIME_ASSERT( sizeof(vec_t) == sizeof(int) );
  127. return ( *reinterpret_cast<const int *>(&x) == 0 &&
  128. *reinterpret_cast<const int *>(&y) == 0 &&
  129. *reinterpret_cast<const int *>(&z) == 0 );
  130. }
  131. vec_t NormalizeInPlace(); ///< Normalize all components
  132. vec_t NormalizeInPlaceSafe( const Vector &vFallback );///< Normalize all components
  133. Vector Normalized() const; ///< Return normalized vector
  134. Vector NormalizedSafe( const Vector &vFallback )const; ///< Return normalized vector, falling back to vFallback if the length of this is 0
  135. bool IsLengthGreaterThan( float val ) const;
  136. bool IsLengthLessThan( float val ) const;
  137. // check if a vector is within the box defined by two other vectors
  138. FORCEINLINE bool WithinAABox( Vector const &boxmin, Vector const &boxmax);
  139. // Get the distance from this vector to the other one.
  140. vec_t DistTo(const Vector &vOther) const;
  141. // Get the distance from this vector to the other one squared.
  142. // NJS: note, VC wasn't inlining it correctly in several deeply nested inlines due to being an 'out of line' inline.
  143. // may be able to tidy this up after switching to VC7
  144. FORCEINLINE vec_t DistToSqr(const Vector &vOther) const
  145. {
  146. Vector delta;
  147. delta.x = x - vOther.x;
  148. delta.y = y - vOther.y;
  149. delta.z = z - vOther.z;
  150. return delta.LengthSqr();
  151. }
  152. // Copy
  153. void CopyToArray(float* rgfl) const;
  154. // Multiply, add, and assign to this (ie: *this = a + b * scalar). This
  155. // is about 12% faster than the actual vector equation (because it's done per-component
  156. // rather than per-vector).
  157. void MulAdd(const Vector& a, const Vector& b, float scalar);
  158. // Dot product.
  159. vec_t Dot(const Vector& vOther) const;
  160. // assignment
  161. Vector& operator=(const Vector &vOther);
  162. // returns 0, 1, 2 corresponding to the component with the largest absolute value
  163. inline int LargestComponent() const;
  164. inline vec_t LargestComponentValue() const;
  165. inline int SmallestComponent() const;
  166. inline vec_t SmallestComponentValue() const;
  167. // 2d
  168. vec_t Length2D(void) const;
  169. vec_t Length2DSqr(void) const;
  170. /// get the component of this vector parallel to some other given vector
  171. inline Vector ProjectOnto( const Vector& onto );
  172. operator VectorByValue &() { return *((VectorByValue *)(this)); }
  173. operator const VectorByValue &() const { return *((const VectorByValue *)(this)); }
  174. #ifndef VECTOR_NO_SLOW_OPERATIONS
  175. // copy constructors
  176. // Vector(const Vector &vOther);
  177. // arithmetic operations
  178. Vector operator-(void) const;
  179. Vector operator+(const Vector& v) const;
  180. Vector operator-(const Vector& v) const;
  181. Vector operator*(const Vector& v) const;
  182. Vector operator/(const Vector& v) const;
  183. Vector operator*(float fl) const;
  184. Vector operator/(float fl) const;
  185. // Cross product between two vectors.
  186. Vector Cross(const Vector &vOther) const;
  187. // Returns a vector with the min or max in X, Y, and Z.
  188. Vector Min(const Vector &vOther) const;
  189. Vector Max(const Vector &vOther) const;
  190. #else
  191. private:
  192. // No copy constructors allowed if we're in optimal mode
  193. Vector(const Vector& vOther);
  194. #endif
  195. };
  196. // Zero the object -- necessary for CNetworkVar and possibly other cases.
  197. inline void EnsureValidValue( Vector &x ) { x.Zero(); }
  198. #define USE_M64S defined( PLATFORM_WINDOWS_PC )
  199. //=========================================================
  200. // 4D Short Vector (aligned on 8-byte boundary)
  201. //=========================================================
  202. class ALIGN8 ShortVector
  203. {
  204. public:
  205. short x, y, z, w;
  206. // Initialization
  207. void Init(short ix = 0, short iy = 0, short iz = 0, short iw = 0 );
  208. #if USE_M64S
  209. __m64 &AsM64() { return *(__m64*)&x; }
  210. const __m64 &AsM64() const { return *(const __m64*)&x; }
  211. #endif
  212. // Setter
  213. void Set( const ShortVector& vOther );
  214. void Set( const short ix, const short iy, const short iz, const short iw );
  215. // array access...
  216. short operator[](int i) const;
  217. short& operator[](int i);
  218. // Base address...
  219. short* Base();
  220. short const* Base() const;
  221. // equality
  222. bool operator==(const ShortVector& v) const;
  223. bool operator!=(const ShortVector& v) const;
  224. // Arithmetic operations
  225. FORCEINLINE ShortVector& operator+=(const ShortVector &v);
  226. FORCEINLINE ShortVector& operator-=(const ShortVector &v);
  227. FORCEINLINE ShortVector& operator*=(const ShortVector &v);
  228. FORCEINLINE ShortVector& operator*=(float s);
  229. FORCEINLINE ShortVector& operator/=(const ShortVector &v);
  230. FORCEINLINE ShortVector& operator/=(float s);
  231. FORCEINLINE ShortVector operator*(float fl) const;
  232. private:
  233. // No copy constructors allowed if we're in optimal mode
  234. // ShortVector(ShortVector const& vOther);
  235. // No assignment operators either...
  236. // ShortVector& operator=( ShortVector const& src );
  237. } ALIGN8_POST;
  238. //=========================================================
  239. // 4D Integer Vector
  240. //=========================================================
  241. class IntVector4D
  242. {
  243. public:
  244. int x, y, z, w;
  245. // Initialization
  246. void Init(int ix = 0, int iy = 0, int iz = 0, int iw = 0 );
  247. #if USE_M64S
  248. __m64 &AsM64() { return *(__m64*)&x; }
  249. const __m64 &AsM64() const { return *(const __m64*)&x; }
  250. #endif
  251. // Setter
  252. void Set( const IntVector4D& vOther );
  253. void Set( const int ix, const int iy, const int iz, const int iw );
  254. // array access...
  255. int operator[](int i) const;
  256. int& operator[](int i);
  257. // Base address...
  258. int* Base();
  259. int const* Base() const;
  260. // equality
  261. bool operator==(const IntVector4D& v) const;
  262. bool operator!=(const IntVector4D& v) const;
  263. // Arithmetic operations
  264. FORCEINLINE IntVector4D& operator+=(const IntVector4D &v);
  265. FORCEINLINE IntVector4D& operator-=(const IntVector4D &v);
  266. FORCEINLINE IntVector4D& operator*=(const IntVector4D &v);
  267. FORCEINLINE IntVector4D& operator*=(float s);
  268. FORCEINLINE IntVector4D& operator/=(const IntVector4D &v);
  269. FORCEINLINE IntVector4D& operator/=(float s);
  270. FORCEINLINE IntVector4D operator*(float fl) const;
  271. private:
  272. // No copy constructors allowed if we're in optimal mode
  273. // IntVector4D(IntVector4D const& vOther);
  274. // No assignment operators either...
  275. // IntVector4D& operator=( IntVector4D const& src );
  276. };
  277. //-----------------------------------------------------------------------------
  278. // Allows us to specifically pass the vector by value when we need to
  279. //-----------------------------------------------------------------------------
  280. class VectorByValue : public Vector
  281. {
  282. public:
  283. // Construction/destruction:
  284. VectorByValue(void) : Vector() {}
  285. VectorByValue(vec_t X, vec_t Y, vec_t Z) : Vector( X, Y, Z ) {}
  286. VectorByValue(const VectorByValue& vOther) { *this = vOther; }
  287. };
  288. //-----------------------------------------------------------------------------
  289. // Utility to simplify table construction. No constructor means can use
  290. // traditional C-style initialization
  291. //-----------------------------------------------------------------------------
  292. class TableVector
  293. {
  294. public:
  295. vec_t x, y, z;
  296. operator Vector &() { return *((Vector *)(this)); }
  297. operator const Vector &() const { return *((const Vector *)(this)); }
  298. // array access...
  299. inline vec_t& operator[](int i)
  300. {
  301. Assert( (i >= 0) && (i < 3) );
  302. return ((vec_t*)this)[i];
  303. }
  304. inline vec_t operator[](int i) const
  305. {
  306. Assert( (i >= 0) && (i < 3) );
  307. return ((vec_t*)this)[i];
  308. }
  309. };
  310. //-----------------------------------------------------------------------------
  311. // Here's where we add all those lovely SSE optimized routines
  312. //-----------------------------------------------------------------------------
  313. class ALIGN16 VectorAligned : public Vector
  314. {
  315. public:
  316. inline VectorAligned(void) {};
  317. inline VectorAligned(vec_t X, vec_t Y, vec_t Z)
  318. {
  319. Init(X,Y,Z);
  320. }
  321. #ifdef VECTOR_NO_SLOW_OPERATIONS
  322. private:
  323. // No copy constructors allowed if we're in optimal mode
  324. VectorAligned(const VectorAligned& vOther);
  325. VectorAligned(const Vector &vOther);
  326. #else
  327. public:
  328. explicit VectorAligned(const Vector &vOther)
  329. {
  330. Init(vOther.x, vOther.y, vOther.z);
  331. }
  332. VectorAligned& operator=(const Vector &vOther)
  333. {
  334. Init(vOther.x, vOther.y, vOther.z);
  335. return *this;
  336. }
  337. VectorAligned& operator=(const VectorAligned &vOther)
  338. {
  339. // we know we're aligned, so use simd
  340. // we can't use the convenient abstract interface coz it gets declared later
  341. #ifdef _X360
  342. XMStoreVector4A(Base(), XMLoadVector4A(vOther.Base()));
  343. #elif _WIN32
  344. _mm_store_ps(Base(), _mm_load_ps( vOther.Base() ));
  345. #else
  346. Init(vOther.x, vOther.y, vOther.z);
  347. #endif
  348. return *this;
  349. }
  350. #endif
  351. float w; // this space is used anyway
  352. #if !defined(NO_MALLOC_OVERRIDE)
  353. void* operator new[] ( size_t nSize)
  354. {
  355. return MemAlloc_AllocAligned(nSize, 16);
  356. }
  357. void* operator new[] ( size_t nSize, const char *pFileName, int nLine)
  358. {
  359. return MemAlloc_AllocAlignedFileLine(nSize, 16, pFileName, nLine);
  360. }
  361. void* operator new[] ( size_t nSize, int /*nBlockUse*/, const char *pFileName, int nLine)
  362. {
  363. return MemAlloc_AllocAlignedFileLine(nSize, 16, pFileName, nLine);
  364. }
  365. void operator delete[] ( void* p)
  366. {
  367. MemAlloc_FreeAligned(p);
  368. }
  369. void operator delete[] ( void* p, const char *pFileName, int nLine)
  370. {
  371. MemAlloc_FreeAligned(p, pFileName, nLine);
  372. }
  373. void operator delete[] ( void* p, int /*nBlockUse*/, const char *pFileName, int nLine)
  374. {
  375. MemAlloc_FreeAligned(p, pFileName, nLine);
  376. }
  377. // please don't allocate a single quaternion...
  378. void* operator new ( size_t nSize )
  379. {
  380. return MemAlloc_AllocAligned(nSize, 16);
  381. }
  382. void* operator new ( size_t nSize, const char *pFileName, int nLine )
  383. {
  384. return MemAlloc_AllocAlignedFileLine(nSize, 16, pFileName, nLine);
  385. }
  386. void* operator new ( size_t nSize, int /*nBlockUse*/, const char *pFileName, int nLine )
  387. {
  388. return MemAlloc_AllocAlignedFileLine(nSize, 16, pFileName, nLine);
  389. }
  390. void operator delete ( void* p)
  391. {
  392. MemAlloc_FreeAligned(p);
  393. }
  394. void operator delete ( void* p, const char *pFileName, int nLine)
  395. {
  396. MemAlloc_FreeAligned(p, pFileName, nLine);
  397. }
  398. void operator delete ( void* p, int /*nBlockUse*/, const char *pFileName, int nLine)
  399. {
  400. MemAlloc_FreeAligned(p, pFileName, nLine);
  401. }
  402. #endif
  403. } ALIGN16_POST;
  404. //-----------------------------------------------------------------------------
  405. // Vector related operations
  406. //-----------------------------------------------------------------------------
  407. // Vector clear
  408. FORCEINLINE void VectorClear( Vector& a );
  409. // Copy
  410. FORCEINLINE void VectorCopy( const Vector& src, Vector& dst );
  411. // Vector arithmetic
  412. FORCEINLINE void VectorAdd( const Vector& a, const Vector& b, Vector& result );
  413. FORCEINLINE void VectorSubtract( const Vector& a, const Vector& b, Vector& result );
  414. FORCEINLINE void VectorMultiply( const Vector& a, vec_t b, Vector& result );
  415. FORCEINLINE void VectorMultiply( const Vector& a, const Vector& b, Vector& result );
  416. FORCEINLINE void VectorDivide( const Vector& a, vec_t b, Vector& result );
  417. FORCEINLINE void VectorDivide( const Vector& a, const Vector& b, Vector& result );
  418. inline void VectorScale ( const Vector& in, vec_t scale, Vector& result );
  419. void VectorMA( const Vector& start, float scale, const Vector& direction, Vector& dest );
  420. // Vector equality with tolerance
  421. bool VectorsAreEqual( const Vector& src1, const Vector& src2, float tolerance = 0.0f );
  422. #define VectorExpand(v) (v).x, (v).y, (v).z
  423. // Normalization
  424. // FIXME: Can't use quite yet
  425. //vec_t VectorNormalize( Vector& v );
  426. // Length
  427. inline vec_t VectorLength( const Vector& v );
  428. // Dot Product
  429. FORCEINLINE vec_t DotProduct(const Vector& a, const Vector& b);
  430. // Cross product
  431. void CrossProduct(const Vector& a, const Vector& b, Vector& result );
  432. // Store the min or max of each of x, y, and z into the result.
  433. void VectorMin( const Vector &a, const Vector &b, Vector &result );
  434. void VectorMax( const Vector &a, const Vector &b, Vector &result );
  435. // Linearly interpolate between two vectors
  436. void VectorLerp(const Vector& src1, const Vector& src2, vec_t t, Vector& dest );
  437. Vector VectorLerp(const Vector& src1, const Vector& src2, vec_t t );
  438. FORCEINLINE Vector ReplicateToVector( float x )
  439. {
  440. return Vector( x, x, x );
  441. }
  442. FORCEINLINE bool PointWithinViewAngle( Vector const &vecSrcPosition,
  443. Vector const &vecTargetPosition,
  444. Vector const &vecLookDirection, float flCosHalfFOV )
  445. {
  446. Vector vecDelta = vecTargetPosition - vecSrcPosition;
  447. float cosDiff = DotProduct( vecLookDirection, vecDelta );
  448. if ( flCosHalfFOV <= 0 ) // >180
  449. {
  450. // signs are different, answer is implicit
  451. if ( cosDiff > 0 )
  452. return true;
  453. // a/sqrt(b) > c == a^2 < b * c ^2
  454. // IFF left and right sides are <= 0
  455. float flLen2 = vecDelta.LengthSqr();
  456. return ( cosDiff * cosDiff <= flLen2 * flCosHalfFOV * flCosHalfFOV );
  457. }
  458. else // flCosHalfFOV > 0
  459. {
  460. // signs are different, answer is implicit
  461. if ( cosDiff < 0 )
  462. return false;
  463. // a/sqrt(b) > c == a^2 > b * c ^2
  464. // IFF left and right sides are >= 0
  465. float flLen2 = vecDelta.LengthSqr();
  466. return ( cosDiff * cosDiff >= flLen2 * flCosHalfFOV * flCosHalfFOV );
  467. }
  468. }
  469. #ifndef VECTOR_NO_SLOW_OPERATIONS
  470. // Cross product
  471. Vector CrossProduct( const Vector& a, const Vector& b );
  472. // Random vector creation
  473. Vector RandomVector( vec_t minVal, vec_t maxVal );
  474. #endif
  475. float RandomVectorInUnitSphere( Vector *pVector );
  476. Vector RandomVectorInUnitSphere();
  477. Vector RandomVectorInUnitSphere( IUniformRandomStream *pRnd );
  478. float RandomVectorInUnitCircle( Vector2D *pVector );
  479. Vector RandomVectorOnUnitSphere();
  480. Vector RandomVectorOnUnitSphere( IUniformRandomStream *pRnd );
  481. //-----------------------------------------------------------------------------
  482. //
  483. // Inlined Vector methods
  484. //
  485. //-----------------------------------------------------------------------------
  486. //-----------------------------------------------------------------------------
  487. // constructors
  488. //-----------------------------------------------------------------------------
  489. inline Vector::Vector(void)
  490. {
  491. #ifdef _DEBUG
  492. #ifdef VECTOR_PARANOIA
  493. // Initialize to NAN to catch errors
  494. x = y = z = VEC_T_NAN;
  495. #endif
  496. #endif
  497. }
  498. inline Vector::Vector(vec_t X, vec_t Y, vec_t Z)
  499. {
  500. x = X; y = Y; z = Z;
  501. CHECK_VALID(*this);
  502. }
  503. //inline Vector::Vector(const float *pFloat)
  504. //{
  505. // Assert( pFloat );
  506. // x = pFloat[0]; y = pFloat[1]; z = pFloat[2];
  507. // CHECK_VALID(*this);
  508. //}
  509. #if 0
  510. //-----------------------------------------------------------------------------
  511. // copy constructor
  512. //-----------------------------------------------------------------------------
  513. inline Vector::Vector(const Vector &vOther)
  514. {
  515. CHECK_VALID(vOther);
  516. x = vOther.x; y = vOther.y; z = vOther.z;
  517. }
  518. #endif
  519. //-----------------------------------------------------------------------------
  520. // initialization
  521. //-----------------------------------------------------------------------------
  522. inline void Vector::Init( vec_t ix, vec_t iy, vec_t iz )
  523. {
  524. x = ix; y = iy; z = iz;
  525. CHECK_VALID(*this);
  526. }
  527. #if !defined(__SPU__)
  528. inline void Vector::Random( vec_t minVal, vec_t maxVal )
  529. {
  530. x = RandomFloat( minVal, maxVal );
  531. y = RandomFloat( minVal, maxVal );
  532. z = RandomFloat( minVal, maxVal );
  533. CHECK_VALID(*this);
  534. }
  535. #endif
  536. // This should really be a single opcode on the PowerPC (move r0 onto the vec reg)
  537. inline void Vector::Zero()
  538. {
  539. x = y = z = 0.0f;
  540. }
  541. inline void VectorClear( Vector& a )
  542. {
  543. a.x = a.y = a.z = 0.0f;
  544. }
  545. //-----------------------------------------------------------------------------
  546. // assignment
  547. //-----------------------------------------------------------------------------
  548. inline Vector& Vector::operator=(const Vector &vOther)
  549. {
  550. CHECK_VALID(vOther);
  551. x=vOther.x; y=vOther.y; z=vOther.z;
  552. return *this;
  553. }
  554. //-----------------------------------------------------------------------------
  555. // Array access
  556. //-----------------------------------------------------------------------------
  557. inline vec_t& Vector::operator[](int i)
  558. {
  559. Assert( (i >= 0) && (i < 3) );
  560. return ((vec_t*)this)[i];
  561. }
  562. inline vec_t Vector::operator[](int i) const
  563. {
  564. Assert( (i >= 0) && (i < 3) );
  565. return ((vec_t*)this)[i];
  566. }
  567. //-----------------------------------------------------------------------------
  568. // Base address...
  569. //-----------------------------------------------------------------------------
  570. inline vec_t* Vector::Base()
  571. {
  572. return (vec_t*)this;
  573. }
  574. inline vec_t const* Vector::Base() const
  575. {
  576. return (vec_t const*)this;
  577. }
  578. //-----------------------------------------------------------------------------
  579. // Cast to Vector2D...
  580. //-----------------------------------------------------------------------------
  581. inline Vector2D& Vector::AsVector2D()
  582. {
  583. return *(Vector2D*)this;
  584. }
  585. inline const Vector2D& Vector::AsVector2D() const
  586. {
  587. return *(const Vector2D*)this;
  588. }
  589. //-----------------------------------------------------------------------------
  590. // IsValid?
  591. //-----------------------------------------------------------------------------
  592. inline bool Vector::IsValid() const
  593. {
  594. return IsFinite(x) && IsFinite(y) && IsFinite(z);
  595. }
  596. //-----------------------------------------------------------------------------
  597. // IsReasonable?
  598. //-----------------------------------------------------------------------------
  599. inline bool Vector::IsReasonable( float range ) const
  600. {
  601. return ( Length() < range );
  602. }
  603. //-----------------------------------------------------------------------------
  604. // Invalidate
  605. //-----------------------------------------------------------------------------
  606. inline void Vector::Invalidate()
  607. {
  608. //#ifdef _DEBUG
  609. //#ifdef VECTOR_PARANOIA
  610. x = y = z = VEC_T_NAN;
  611. //#endif
  612. //#endif
  613. }
  614. //-----------------------------------------------------------------------------
  615. // comparison
  616. //-----------------------------------------------------------------------------
  617. inline bool Vector::operator==( const Vector& src ) const
  618. {
  619. CHECK_VALID(src);
  620. CHECK_VALID(*this);
  621. return (src.x == x) && (src.y == y) && (src.z == z);
  622. }
  623. inline bool Vector::operator!=( const Vector& src ) const
  624. {
  625. CHECK_VALID(src);
  626. CHECK_VALID(*this);
  627. return (src.x != x) || (src.y != y) || (src.z != z);
  628. }
  629. //-----------------------------------------------------------------------------
  630. // Copy
  631. //-----------------------------------------------------------------------------
  632. FORCEINLINE void VectorCopy( const Vector& src, Vector& dst )
  633. {
  634. CHECK_VALID(src);
  635. dst.x = src.x;
  636. dst.y = src.y;
  637. dst.z = src.z;
  638. }
  639. inline void Vector::CopyToArray(float* rgfl) const
  640. {
  641. Assert( rgfl );
  642. CHECK_VALID(*this);
  643. rgfl[0] = x, rgfl[1] = y, rgfl[2] = z;
  644. }
  645. //-----------------------------------------------------------------------------
  646. // standard math operations
  647. //-----------------------------------------------------------------------------
  648. // #pragma message("TODO: these should be SSE")
  649. inline void Vector::Negate()
  650. {
  651. CHECK_VALID(*this);
  652. x = -x; y = -y; z = -z;
  653. }
  654. FORCEINLINE Vector& Vector::operator+=(const Vector& v)
  655. {
  656. CHECK_VALID(*this);
  657. CHECK_VALID(v);
  658. x+=v.x; y+=v.y; z += v.z;
  659. return *this;
  660. }
  661. FORCEINLINE Vector& Vector::operator-=(const Vector& v)
  662. {
  663. CHECK_VALID(*this);
  664. CHECK_VALID(v);
  665. x-=v.x; y-=v.y; z -= v.z;
  666. return *this;
  667. }
  668. FORCEINLINE Vector& Vector::operator*=(float fl)
  669. {
  670. x *= fl;
  671. y *= fl;
  672. z *= fl;
  673. CHECK_VALID(*this);
  674. return *this;
  675. }
  676. FORCEINLINE Vector& Vector::operator*=(const Vector& v)
  677. {
  678. CHECK_VALID(v);
  679. x *= v.x;
  680. y *= v.y;
  681. z *= v.z;
  682. CHECK_VALID(*this);
  683. return *this;
  684. }
  685. // this ought to be an opcode.
  686. FORCEINLINE Vector& Vector::operator+=(float fl)
  687. {
  688. x += fl;
  689. y += fl;
  690. z += fl;
  691. CHECK_VALID(*this);
  692. return *this;
  693. }
  694. FORCEINLINE Vector& Vector::operator-=(float fl)
  695. {
  696. x -= fl;
  697. y -= fl;
  698. z -= fl;
  699. CHECK_VALID(*this);
  700. return *this;
  701. }
  702. FORCEINLINE Vector& Vector::operator/=(float fl)
  703. {
  704. Assert( fl != 0.0f );
  705. float oofl = 1.0f / fl;
  706. x *= oofl;
  707. y *= oofl;
  708. z *= oofl;
  709. CHECK_VALID(*this);
  710. return *this;
  711. }
  712. FORCEINLINE Vector& Vector::operator/=(const Vector& v)
  713. {
  714. CHECK_VALID(v);
  715. Assert( v.x != 0.0f && v.y != 0.0f && v.z != 0.0f );
  716. x /= v.x;
  717. y /= v.y;
  718. z /= v.z;
  719. CHECK_VALID(*this);
  720. return *this;
  721. }
  722. // get the component of this vector parallel to some other given vector
  723. inline Vector Vector::ProjectOnto( const Vector& onto )
  724. {
  725. return onto * ( this->Dot(onto) / ( onto.LengthSqr() ) );
  726. }
  727. //-----------------------------------------------------------------------------
  728. //
  729. // Inlined Short Vector methods
  730. //
  731. //-----------------------------------------------------------------------------
  732. inline void ShortVector::Init( short ix, short iy, short iz, short iw )
  733. {
  734. x = ix; y = iy; z = iz; w = iw;
  735. }
  736. FORCEINLINE void ShortVector::Set( const ShortVector& vOther )
  737. {
  738. x = vOther.x;
  739. y = vOther.y;
  740. z = vOther.z;
  741. w = vOther.w;
  742. }
  743. FORCEINLINE void ShortVector::Set( const short ix, const short iy, const short iz, const short iw )
  744. {
  745. x = ix;
  746. y = iy;
  747. z = iz;
  748. w = iw;
  749. }
  750. //-----------------------------------------------------------------------------
  751. // Array access
  752. //-----------------------------------------------------------------------------
  753. inline short ShortVector::operator[](int i) const
  754. {
  755. Assert( (i >= 0) && (i < 4) );
  756. return ((short*)this)[i];
  757. }
  758. inline short& ShortVector::operator[](int i)
  759. {
  760. Assert( (i >= 0) && (i < 4) );
  761. return ((short*)this)[i];
  762. }
  763. //-----------------------------------------------------------------------------
  764. // Base address...
  765. //-----------------------------------------------------------------------------
  766. inline short* ShortVector::Base()
  767. {
  768. return (short*)this;
  769. }
  770. inline short const* ShortVector::Base() const
  771. {
  772. return (short const*)this;
  773. }
  774. //-----------------------------------------------------------------------------
  775. // comparison
  776. //-----------------------------------------------------------------------------
  777. inline bool ShortVector::operator==( const ShortVector& src ) const
  778. {
  779. return (src.x == x) && (src.y == y) && (src.z == z) && (src.w == w);
  780. }
  781. inline bool ShortVector::operator!=( const ShortVector& src ) const
  782. {
  783. return (src.x != x) || (src.y != y) || (src.z != z) || (src.w != w);
  784. }
  785. //-----------------------------------------------------------------------------
  786. // standard math operations
  787. //-----------------------------------------------------------------------------
  788. FORCEINLINE ShortVector& ShortVector::operator+=(const ShortVector& v)
  789. {
  790. x+=v.x; y+=v.y; z += v.z; w += v.w;
  791. return *this;
  792. }
  793. FORCEINLINE ShortVector& ShortVector::operator-=(const ShortVector& v)
  794. {
  795. x-=v.x; y-=v.y; z -= v.z; w -= v.w;
  796. return *this;
  797. }
  798. FORCEINLINE ShortVector& ShortVector::operator*=(float fl)
  799. {
  800. x = (short)(x * fl);
  801. y = (short)(y * fl);
  802. z = (short)(z * fl);
  803. w = (short)(w * fl);
  804. return *this;
  805. }
  806. FORCEINLINE ShortVector& ShortVector::operator*=(const ShortVector& v)
  807. {
  808. x = (short)(x * v.x);
  809. y = (short)(y * v.y);
  810. z = (short)(z * v.z);
  811. w = (short)(w * v.w);
  812. return *this;
  813. }
  814. FORCEINLINE ShortVector& ShortVector::operator/=(float fl)
  815. {
  816. Assert( fl != 0.0f );
  817. float oofl = 1.0f / fl;
  818. x = (short)(x * oofl);
  819. y = (short)(y * oofl);
  820. z = (short)(z * oofl);
  821. w = (short)(w * oofl);
  822. return *this;
  823. }
  824. FORCEINLINE ShortVector& ShortVector::operator/=(const ShortVector& v)
  825. {
  826. Assert( v.x != 0 && v.y != 0 && v.z != 0 && v.w != 0 );
  827. x = (short)(x / v.x);
  828. y = (short)(y / v.y);
  829. z = (short)(z / v.z);
  830. w = (short)(w / v.w);
  831. return *this;
  832. }
  833. FORCEINLINE void ShortVectorMultiply( const ShortVector& src, float fl, ShortVector& res )
  834. {
  835. Assert( IsFinite(fl) );
  836. res.x = (short)(src.x * fl);
  837. res.y = (short)(src.y * fl);
  838. res.z = (short)(src.z * fl);
  839. res.w = (short)(src.w * fl);
  840. }
  841. FORCEINLINE ShortVector ShortVector::operator*(float fl) const
  842. {
  843. ShortVector res;
  844. ShortVectorMultiply( *this, fl, res );
  845. return res;
  846. }
  847. //-----------------------------------------------------------------------------
  848. //
  849. // Inlined Integer Vector methods
  850. //
  851. //-----------------------------------------------------------------------------
  852. inline void IntVector4D::Init( int ix, int iy, int iz, int iw )
  853. {
  854. x = ix; y = iy; z = iz; w = iw;
  855. }
  856. FORCEINLINE void IntVector4D::Set( const IntVector4D& vOther )
  857. {
  858. x = vOther.x;
  859. y = vOther.y;
  860. z = vOther.z;
  861. w = vOther.w;
  862. }
  863. FORCEINLINE void IntVector4D::Set( const int ix, const int iy, const int iz, const int iw )
  864. {
  865. x = ix;
  866. y = iy;
  867. z = iz;
  868. w = iw;
  869. }
  870. //-----------------------------------------------------------------------------
  871. // Array access
  872. //-----------------------------------------------------------------------------
  873. inline int IntVector4D::operator[](int i) const
  874. {
  875. Assert( (i >= 0) && (i < 4) );
  876. return ((int*)this)[i];
  877. }
  878. inline int& IntVector4D::operator[](int i)
  879. {
  880. Assert( (i >= 0) && (i < 4) );
  881. return ((int*)this)[i];
  882. }
  883. //-----------------------------------------------------------------------------
  884. // Base address...
  885. //-----------------------------------------------------------------------------
  886. inline int* IntVector4D::Base()
  887. {
  888. return (int*)this;
  889. }
  890. inline int const* IntVector4D::Base() const
  891. {
  892. return (int const*)this;
  893. }
  894. //-----------------------------------------------------------------------------
  895. // comparison
  896. //-----------------------------------------------------------------------------
  897. inline bool IntVector4D::operator==( const IntVector4D& src ) const
  898. {
  899. return (src.x == x) && (src.y == y) && (src.z == z) && (src.w == w);
  900. }
  901. inline bool IntVector4D::operator!=( const IntVector4D& src ) const
  902. {
  903. return (src.x != x) || (src.y != y) || (src.z != z) || (src.w != w);
  904. }
  905. //-----------------------------------------------------------------------------
  906. // standard math operations
  907. //-----------------------------------------------------------------------------
  908. FORCEINLINE IntVector4D& IntVector4D::operator+=(const IntVector4D& v)
  909. {
  910. x+=v.x; y+=v.y; z += v.z; w += v.w;
  911. return *this;
  912. }
  913. FORCEINLINE IntVector4D& IntVector4D::operator-=(const IntVector4D& v)
  914. {
  915. x-=v.x; y-=v.y; z -= v.z; w -= v.w;
  916. return *this;
  917. }
  918. FORCEINLINE IntVector4D& IntVector4D::operator*=(float fl)
  919. {
  920. x = (int)(x * fl);
  921. y = (int)(y * fl);
  922. z = (int)(z * fl);
  923. w = (int)(w * fl);
  924. return *this;
  925. }
  926. FORCEINLINE IntVector4D& IntVector4D::operator*=(const IntVector4D& v)
  927. {
  928. x = (int)(x * v.x);
  929. y = (int)(y * v.y);
  930. z = (int)(z * v.z);
  931. w = (int)(w * v.w);
  932. return *this;
  933. }
  934. FORCEINLINE IntVector4D& IntVector4D::operator/=(float fl)
  935. {
  936. Assert( fl != 0.0f );
  937. float oofl = 1.0f / fl;
  938. x = (int)(x * oofl);
  939. y = (int)(y * oofl);
  940. z = (int)(z * oofl);
  941. w = (int)(w * oofl);
  942. return *this;
  943. }
  944. FORCEINLINE IntVector4D& IntVector4D::operator/=(const IntVector4D& v)
  945. {
  946. Assert( v.x != 0 && v.y != 0 && v.z != 0 && v.w != 0 );
  947. x = (int)(x / v.x);
  948. y = (int)(y / v.y);
  949. z = (int)(z / v.z);
  950. w = (int)(w / v.w);
  951. return *this;
  952. }
  953. FORCEINLINE void IntVector4DMultiply( const IntVector4D& src, float fl, IntVector4D& res )
  954. {
  955. Assert( IsFinite(fl) );
  956. res.x = (int)(src.x * fl);
  957. res.y = (int)(src.y * fl);
  958. res.z = (int)(src.z * fl);
  959. res.w = (int)(src.w * fl);
  960. }
  961. FORCEINLINE IntVector4D IntVector4D::operator*(float fl) const
  962. {
  963. IntVector4D res;
  964. IntVector4DMultiply( *this, fl, res );
  965. return res;
  966. }
  967. // =======================
  968. FORCEINLINE void VectorAdd( const Vector& a, const Vector& b, Vector& c )
  969. {
  970. CHECK_VALID(a);
  971. CHECK_VALID(b);
  972. c.x = a.x + b.x;
  973. c.y = a.y + b.y;
  974. c.z = a.z + b.z;
  975. }
  976. FORCEINLINE void VectorSubtract( const Vector& a, const Vector& b, Vector& c )
  977. {
  978. CHECK_VALID(a);
  979. CHECK_VALID(b);
  980. c.x = a.x - b.x;
  981. c.y = a.y - b.y;
  982. c.z = a.z - b.z;
  983. }
  984. FORCEINLINE void VectorMultiply( const Vector& a, vec_t b, Vector& c )
  985. {
  986. CHECK_VALID(a);
  987. Assert( IsFinite(b) );
  988. c.x = a.x * b;
  989. c.y = a.y * b;
  990. c.z = a.z * b;
  991. }
  992. FORCEINLINE void VectorMultiply( const Vector& a, const Vector& b, Vector& c )
  993. {
  994. CHECK_VALID(a);
  995. CHECK_VALID(b);
  996. c.x = a.x * b.x;
  997. c.y = a.y * b.y;
  998. c.z = a.z * b.z;
  999. }
  1000. // for backwards compatability
  1001. inline void VectorScale ( const Vector& in, vec_t scale, Vector& result )
  1002. {
  1003. VectorMultiply( in, scale, result );
  1004. }
  1005. FORCEINLINE void VectorDivide( const Vector& a, vec_t b, Vector& c )
  1006. {
  1007. CHECK_VALID(a);
  1008. Assert( b != 0.0f );
  1009. vec_t oob = 1.0f / b;
  1010. c.x = a.x * oob;
  1011. c.y = a.y * oob;
  1012. c.z = a.z * oob;
  1013. }
  1014. FORCEINLINE void VectorDivide( const Vector& a, const Vector& b, Vector& c )
  1015. {
  1016. CHECK_VALID(a);
  1017. CHECK_VALID(b);
  1018. Assert( (b.x != 0.0f) && (b.y != 0.0f) && (b.z != 0.0f) );
  1019. c.x = a.x / b.x;
  1020. c.y = a.y / b.y;
  1021. c.z = a.z / b.z;
  1022. }
  1023. // FIXME: Remove
  1024. // For backwards compatability
  1025. inline void Vector::MulAdd(const Vector& a, const Vector& b, float scalar)
  1026. {
  1027. CHECK_VALID(a);
  1028. CHECK_VALID(b);
  1029. x = a.x + b.x * scalar;
  1030. y = a.y + b.y * scalar;
  1031. z = a.z + b.z * scalar;
  1032. }
  1033. inline void VectorLerp(const Vector& src1, const Vector& src2, vec_t t, Vector& dest )
  1034. {
  1035. CHECK_VALID(src1);
  1036. CHECK_VALID(src2);
  1037. dest.x = src1.x + (src2.x - src1.x) * t;
  1038. dest.y = src1.y + (src2.y - src1.y) * t;
  1039. dest.z = src1.z + (src2.z - src1.z) * t;
  1040. }
  1041. inline Vector VectorLerp(const Vector& src1, const Vector& src2, vec_t t )
  1042. {
  1043. Vector result;
  1044. VectorLerp( src1, src2, t, result );
  1045. return result;
  1046. }
  1047. //-----------------------------------------------------------------------------
  1048. // Temporary storage for vector results so const Vector& results can be returned
  1049. //-----------------------------------------------------------------------------
  1050. #if !defined(__SPU__)
  1051. inline Vector &AllocTempVector()
  1052. {
  1053. static Vector s_vecTemp[128];
  1054. static CInterlockedInt s_nIndex;
  1055. int nIndex;
  1056. for (;;)
  1057. {
  1058. int nOldIndex = s_nIndex;
  1059. nIndex = ( (nOldIndex + 0x10001) & 0x7F );
  1060. if ( s_nIndex.AssignIf( nOldIndex, nIndex ) )
  1061. {
  1062. break;
  1063. }
  1064. ThreadPause();
  1065. }
  1066. return s_vecTemp[nIndex];
  1067. }
  1068. #endif
  1069. //-----------------------------------------------------------------------------
  1070. // dot, cross
  1071. //-----------------------------------------------------------------------------
  1072. FORCEINLINE vec_t DotProduct(const Vector& a, const Vector& b)
  1073. {
  1074. CHECK_VALID(a);
  1075. CHECK_VALID(b);
  1076. return( a.x*b.x + a.y*b.y + a.z*b.z );
  1077. }
  1078. // for backwards compatability
  1079. inline vec_t Vector::Dot( const Vector& vOther ) const
  1080. {
  1081. CHECK_VALID(vOther);
  1082. return DotProduct( *this, vOther );
  1083. }
  1084. inline int Vector::LargestComponent() const
  1085. {
  1086. float flAbsx = fabs(x);
  1087. float flAbsy = fabs(y);
  1088. float flAbsz = fabs(z);
  1089. if ( flAbsx > flAbsy )
  1090. {
  1091. if ( flAbsx > flAbsz )
  1092. return X_INDEX;
  1093. return Z_INDEX;
  1094. }
  1095. if ( flAbsy > flAbsz )
  1096. return Y_INDEX;
  1097. return Z_INDEX;
  1098. }
  1099. inline int Vector::SmallestComponent() const
  1100. {
  1101. float flAbsx = fabs( x );
  1102. float flAbsy = fabs( y );
  1103. float flAbsz = fabs( z );
  1104. if ( flAbsx < flAbsy )
  1105. {
  1106. if ( flAbsx < flAbsz )
  1107. return X_INDEX;
  1108. return Z_INDEX;
  1109. }
  1110. if ( flAbsy < flAbsz )
  1111. return Y_INDEX;
  1112. return Z_INDEX;
  1113. }
  1114. inline float Vector::LargestComponentValue() const
  1115. {
  1116. float flAbsX = fabs( x );
  1117. float flAbsY = fabs( y );
  1118. float flAbsZ = fabs( z );
  1119. return MAX( MAX( flAbsX, flAbsY ), flAbsZ );
  1120. }
  1121. inline float Vector::SmallestComponentValue() const
  1122. {
  1123. float flAbsX = fabs( x );
  1124. float flAbsY = fabs( y );
  1125. float flAbsZ = fabs( z );
  1126. return MIN( MIN( flAbsX, flAbsY ), flAbsZ );
  1127. }
  1128. inline void CrossProduct(const Vector& a, const Vector& b, Vector& result )
  1129. {
  1130. CHECK_VALID(a);
  1131. CHECK_VALID(b);
  1132. Assert( &a != &result );
  1133. Assert( &b != &result );
  1134. result.x = a.y*b.z - a.z*b.y;
  1135. result.y = a.z*b.x - a.x*b.z;
  1136. result.z = a.x*b.y - a.y*b.x;
  1137. }
  1138. inline vec_t DotProductAbs( const Vector &v0, const Vector &v1 )
  1139. {
  1140. CHECK_VALID(v0);
  1141. CHECK_VALID(v1);
  1142. return FloatMakePositive(v0.x*v1.x) + FloatMakePositive(v0.y*v1.y) + FloatMakePositive(v0.z*v1.z);
  1143. }
  1144. inline vec_t DotProductAbs( const Vector &v0, const float *v1 )
  1145. {
  1146. return FloatMakePositive(v0.x * v1[0]) + FloatMakePositive(v0.y * v1[1]) + FloatMakePositive(v0.z * v1[2]);
  1147. }
  1148. //-----------------------------------------------------------------------------
  1149. // length
  1150. //-----------------------------------------------------------------------------
  1151. inline vec_t VectorLength( const Vector& v )
  1152. {
  1153. CHECK_VALID(v);
  1154. return (vec_t)FastSqrt(v.x*v.x + v.y*v.y + v.z*v.z);
  1155. }
  1156. inline vec_t Vector::Length(void) const
  1157. {
  1158. CHECK_VALID(*this);
  1159. return VectorLength( *this );
  1160. }
  1161. //-----------------------------------------------------------------------------
  1162. // Normalization
  1163. //-----------------------------------------------------------------------------
  1164. /*
  1165. // FIXME: Can't use until we're un-macroed in mathlib.h
  1166. inline vec_t VectorNormalize( Vector& v )
  1167. {
  1168. Assert( v.IsValid() );
  1169. vec_t l = v.Length();
  1170. if (l != 0.0f)
  1171. {
  1172. v /= l;
  1173. }
  1174. else
  1175. {
  1176. // FIXME:
  1177. // Just copying the existing implemenation; shouldn't res.z == 0?
  1178. v.x = v.y = 0.0f; v.z = 1.0f;
  1179. }
  1180. return l;
  1181. }
  1182. */
  1183. // check a point against a box
  1184. bool Vector::WithinAABox( Vector const &boxmin, Vector const &boxmax)
  1185. {
  1186. return (
  1187. ( x >= boxmin.x ) && ( x <= boxmax.x) &&
  1188. ( y >= boxmin.y ) && ( y <= boxmax.y) &&
  1189. ( z >= boxmin.z ) && ( z <= boxmax.z)
  1190. );
  1191. }
  1192. //-----------------------------------------------------------------------------
  1193. // Get the distance from this vector to the other one
  1194. //-----------------------------------------------------------------------------
  1195. inline vec_t Vector::DistTo(const Vector &vOther) const
  1196. {
  1197. Vector delta;
  1198. VectorSubtract( *this, vOther, delta );
  1199. return delta.Length();
  1200. }
  1201. //-----------------------------------------------------------------------------
  1202. // Float equality with tolerance
  1203. //-----------------------------------------------------------------------------
  1204. inline bool FloatsAreEqual( float f1, float f2, float flTolerance )
  1205. {
  1206. // Sergiy: the implementation in Source2 is very inefficient, trying to start with a clean slate here, hopefully will reintegrate back to Source2
  1207. const float flAbsToleranceThreshold = 0.000003814697265625; // 2 ^ -FLOAT_EQUALITY_NOISE_CUTOFF,
  1208. return fabsf( f1 - f2 ) <= flTolerance * ( fabsf( f1 ) + fabsf( f2 ) ) + flAbsToleranceThreshold;
  1209. }
  1210. //-----------------------------------------------------------------------------
  1211. // Vector equality with percentage tolerance
  1212. // are all components within flPercentageTolerance (expressed as a percentage of the larger component, per component)?
  1213. // and all components have the same sign
  1214. //-----------------------------------------------------------------------------
  1215. inline bool VectorsAreWithinPercentageTolerance( const Vector& src1, const Vector& src2, float flPercentageTolerance )
  1216. {
  1217. if ( !FloatsAreEqual( src1.x, src2.x, flPercentageTolerance ) )
  1218. return false;
  1219. if ( !FloatsAreEqual( src1.y, src2.y, flPercentageTolerance ) )
  1220. return false;
  1221. return ( FloatsAreEqual( src1.z, src2.z, flPercentageTolerance ) );
  1222. }
  1223. //-----------------------------------------------------------------------------
  1224. // Vector equality with tolerance
  1225. //-----------------------------------------------------------------------------
  1226. inline bool VectorsAreEqual( const Vector& src1, const Vector& src2, float tolerance )
  1227. {
  1228. if (FloatMakePositive(src1.x - src2.x) > tolerance)
  1229. return false;
  1230. if (FloatMakePositive(src1.y - src2.y) > tolerance)
  1231. return false;
  1232. return (FloatMakePositive(src1.z - src2.z) <= tolerance);
  1233. }
  1234. //-----------------------------------------------------------------------------
  1235. // Computes the closest point to vecTarget no farther than flMaxDist from vecStart
  1236. //-----------------------------------------------------------------------------
  1237. inline void ComputeClosestPoint( const Vector& vecStart, float flMaxDist, const Vector& vecTarget, Vector *pResult )
  1238. {
  1239. Vector vecDelta;
  1240. VectorSubtract( vecTarget, vecStart, vecDelta );
  1241. float flDistSqr = vecDelta.LengthSqr();
  1242. if ( flDistSqr <= flMaxDist * flMaxDist )
  1243. {
  1244. *pResult = vecTarget;
  1245. }
  1246. else
  1247. {
  1248. vecDelta /= FastSqrt( flDistSqr );
  1249. VectorMA( vecStart, flMaxDist, vecDelta, *pResult );
  1250. }
  1251. }
  1252. //-----------------------------------------------------------------------------
  1253. // Takes the absolute value of a vector
  1254. //-----------------------------------------------------------------------------
  1255. inline void VectorAbs( const Vector& src, Vector& dst )
  1256. {
  1257. dst.x = FloatMakePositive(src.x);
  1258. dst.y = FloatMakePositive(src.y);
  1259. dst.z = FloatMakePositive(src.z);
  1260. }
  1261. inline Vector VectorAbs( const Vector& src )
  1262. {
  1263. return Vector( fabsf( src.x ), fabsf( src.y ), fabsf( src.z ) );
  1264. }
  1265. //-----------------------------------------------------------------------------
  1266. //
  1267. // Slow methods
  1268. //
  1269. //-----------------------------------------------------------------------------
  1270. #ifndef VECTOR_NO_SLOW_OPERATIONS
  1271. //-----------------------------------------------------------------------------
  1272. // Returns a vector with the min or max in X, Y, and Z.
  1273. //-----------------------------------------------------------------------------
  1274. inline Vector Vector::Min(const Vector &vOther) const
  1275. {
  1276. return Vector(x < vOther.x ? x : vOther.x,
  1277. y < vOther.y ? y : vOther.y,
  1278. z < vOther.z ? z : vOther.z);
  1279. }
  1280. inline Vector Vector::Max(const Vector &vOther) const
  1281. {
  1282. return Vector(x > vOther.x ? x : vOther.x,
  1283. y > vOther.y ? y : vOther.y,
  1284. z > vOther.z ? z : vOther.z);
  1285. }
  1286. //-----------------------------------------------------------------------------
  1287. // arithmetic operations
  1288. //-----------------------------------------------------------------------------
  1289. inline Vector Vector::operator-(void) const
  1290. {
  1291. return Vector(-x,-y,-z);
  1292. }
  1293. inline Vector Vector::operator+(const Vector& v) const
  1294. {
  1295. Vector res;
  1296. VectorAdd( *this, v, res );
  1297. return res;
  1298. }
  1299. inline Vector Vector::operator-(const Vector& v) const
  1300. {
  1301. Vector res;
  1302. VectorSubtract( *this, v, res );
  1303. return res;
  1304. }
  1305. inline Vector Vector::operator*(float fl) const
  1306. {
  1307. Vector res;
  1308. VectorMultiply( *this, fl, res );
  1309. return res;
  1310. }
  1311. inline Vector Vector::operator*(const Vector& v) const
  1312. {
  1313. Vector res;
  1314. VectorMultiply( *this, v, res );
  1315. return res;
  1316. }
  1317. inline Vector Vector::operator/(float fl) const
  1318. {
  1319. Vector res;
  1320. VectorDivide( *this, fl, res );
  1321. return res;
  1322. }
  1323. inline Vector Vector::operator/(const Vector& v) const
  1324. {
  1325. Vector res;
  1326. VectorDivide( *this, v, res );
  1327. return res;
  1328. }
  1329. inline Vector operator*(float fl, const Vector& v)
  1330. {
  1331. return v * fl;
  1332. }
  1333. //-----------------------------------------------------------------------------
  1334. // cross product
  1335. //-----------------------------------------------------------------------------
  1336. inline Vector Vector::Cross(const Vector& vOther) const
  1337. {
  1338. Vector res;
  1339. CrossProduct( *this, vOther, res );
  1340. return res;
  1341. }
  1342. //-----------------------------------------------------------------------------
  1343. // 2D
  1344. //-----------------------------------------------------------------------------
  1345. inline vec_t Vector::Length2D(void) const
  1346. {
  1347. return (vec_t)FastSqrt(x*x + y*y);
  1348. }
  1349. inline vec_t Vector::Length2DSqr(void) const
  1350. {
  1351. return (x*x + y*y);
  1352. }
  1353. inline Vector CrossProduct(const Vector& a, const Vector& b)
  1354. {
  1355. return Vector( a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x );
  1356. }
  1357. inline void VectorMin( const Vector &a, const Vector &b, Vector &result )
  1358. {
  1359. result.x = fpmin(a.x, b.x);
  1360. result.y = fpmin(a.y, b.y);
  1361. result.z = fpmin(a.z, b.z);
  1362. }
  1363. inline void VectorMax( const Vector &a, const Vector &b, Vector &result )
  1364. {
  1365. result.x = fpmax(a.x, b.x);
  1366. result.y = fpmax(a.y, b.y);
  1367. result.z = fpmax(a.z, b.z);
  1368. }
  1369. // and when you want to return the vector rather than cause a LHS with it...
  1370. inline Vector VectorMin( const Vector &a, const Vector &b )
  1371. {
  1372. return Vector( fpmin(a.x, b.x), fpmin(a.y, b.y), fpmin(a.z, b.z) );
  1373. }
  1374. inline Vector VectorMax( const Vector &a, const Vector &b )
  1375. {
  1376. return Vector( fpmax(a.x, b.x), fpmax(a.y, b.y), fpmax(a.z, b.z) );
  1377. }
  1378. inline float ComputeVolume( const Vector &vecMins, const Vector &vecMaxs )
  1379. {
  1380. Vector vecDelta;
  1381. VectorSubtract( vecMaxs, vecMins, vecDelta );
  1382. return DotProduct( vecDelta, vecDelta );
  1383. }
  1384. #if !defined(__SPU__)
  1385. // Get a random vector.
  1386. inline Vector RandomVector( float minVal, float maxVal )
  1387. {
  1388. Vector random;
  1389. random.Random( minVal, maxVal );
  1390. return random;
  1391. }
  1392. #endif
  1393. #endif //slow
  1394. //-----------------------------------------------------------------------------
  1395. // Helper debugging stuff....
  1396. //-----------------------------------------------------------------------------
  1397. inline bool operator==( float const* f, const Vector& v )
  1398. {
  1399. // AIIIEEEE!!!!
  1400. Assert(0);
  1401. return false;
  1402. }
  1403. inline bool operator==( const Vector& v, float const* f )
  1404. {
  1405. // AIIIEEEE!!!!
  1406. Assert(0);
  1407. return false;
  1408. }
  1409. inline bool operator!=( float const* f, const Vector& v )
  1410. {
  1411. // AIIIEEEE!!!!
  1412. Assert(0);
  1413. return false;
  1414. }
  1415. inline bool operator!=( const Vector& v, float const* f )
  1416. {
  1417. // AIIIEEEE!!!!
  1418. Assert(0);
  1419. return false;
  1420. }
  1421. // return a vector perpendicular to another, with smooth variation. The difference between this and
  1422. // something like VectorVectors is that there are now discontinuities. _unlike_ VectorVectors,
  1423. // you won't get an "u
  1424. void VectorPerpendicularToVector( Vector const &in, Vector *pvecOut );
  1425. inline const Vector VectorPerpendicularToVector( const Vector &in )
  1426. {
  1427. Vector out;
  1428. VectorPerpendicularToVector( in, &out );
  1429. return out;
  1430. }
  1431. //-----------------------------------------------------------------------------
  1432. // AngularImpulse
  1433. //-----------------------------------------------------------------------------
  1434. // AngularImpulse are exponetial maps (an axis scaled by a "twist" angle in degrees)
  1435. typedef Vector AngularImpulse;
  1436. #ifndef VECTOR_NO_SLOW_OPERATIONS
  1437. #if !defined(__SPU__)
  1438. inline AngularImpulse RandomAngularImpulse( float minVal, float maxVal )
  1439. {
  1440. AngularImpulse angImp;
  1441. angImp.Random( minVal, maxVal );
  1442. return angImp;
  1443. }
  1444. #endif
  1445. #endif
  1446. //-----------------------------------------------------------------------------
  1447. // Quaternion
  1448. //-----------------------------------------------------------------------------
  1449. class RadianEuler;
  1450. class DegreeEuler;
  1451. class QAngle;
  1452. class Quaternion // same data-layout as engine's vec4_t,
  1453. { // which is a vec_t[4]
  1454. public:
  1455. inline Quaternion(void) {
  1456. // Initialize to NAN to catch errors
  1457. #ifdef _DEBUG
  1458. #ifdef VECTOR_PARANOIA
  1459. x = y = z = w = VEC_T_NAN;
  1460. #endif
  1461. #endif
  1462. }
  1463. inline Quaternion(vec_t ix, vec_t iy, vec_t iz, vec_t iw) : x(ix), y(iy), z(iz), w(iw) { }
  1464. inline explicit Quaternion( RadianEuler const &angle );
  1465. inline explicit Quaternion( DegreeEuler const &angle );
  1466. inline void Init(vec_t ix=0.0f, vec_t iy=0.0f, vec_t iz=0.0f, vec_t iw=0.0f) { x = ix; y = iy; z = iz; w = iw; }
  1467. inline void Init( const Vector &vImaginaryPart, float flRealPart ){ x = vImaginaryPart.x; y = vImaginaryPart.y; z = vImaginaryPart.z; w = flRealPart; }
  1468. bool IsValid() const;
  1469. void Invalidate();
  1470. bool operator==( const Quaternion &src ) const;
  1471. bool operator!=( const Quaternion &src ) const;
  1472. inline Quaternion Conjugate() const { return Quaternion( -x, -y, -z, w ); }
  1473. //
  1474. const Vector GetForward()const;
  1475. const Vector GetLeft()const;
  1476. const Vector GetUp()const;
  1477. vec_t* Base() { return ( vec_t* )this; }
  1478. const vec_t* Base() const { return (vec_t*)this; }
  1479. // convenience for debugging
  1480. inline void Print() const;
  1481. // Imaginary part
  1482. Vector &ImaginaryPart() { return *( Vector* )this; }
  1483. const Vector &ImaginaryPart() const { return *( Vector* )this; }
  1484. float& RealPart() { return w; }
  1485. float RealPart() const { return w; }
  1486. inline QAngle ToQAngle() const;
  1487. inline struct matrix3x4_t ToMatrix() const;
  1488. // array access...
  1489. vec_t operator[](int i) const;
  1490. vec_t& operator[](int i);
  1491. inline Quaternion operator+( void ) const { return *this; }
  1492. inline Quaternion operator-( void ) const { return Quaternion( -x, -y, -z, -w ); }
  1493. vec_t x, y, z, w;
  1494. };
  1495. // Random Quaternion that is UNIFORMLY distributed over the S^3
  1496. // should be good for random generation of orientation for unit tests and for game
  1497. // NOTE: Nothing trivial like Quaternion(RandomAngle(0,180)) will do the trick ,
  1498. // one needs to take special care to generate a uniformly distributed quaternion.
  1499. const Quaternion RandomQuaternion();
  1500. const Quaternion RandomQuaternion();
  1501. inline const Quaternion Conjugate( const Quaternion &q )
  1502. {
  1503. return Quaternion( -q.x, -q.y, -q.z, q.w );
  1504. }
  1505. //-----------------------------------------------------------------------------
  1506. // Array access
  1507. //-----------------------------------------------------------------------------
  1508. inline vec_t& Quaternion::operator[](int i)
  1509. {
  1510. Assert( (i >= 0) && (i < 4) );
  1511. return ((vec_t*)this)[i];
  1512. }
  1513. inline vec_t Quaternion::operator[](int i) const
  1514. {
  1515. Assert( (i >= 0) && (i < 4) );
  1516. return ((vec_t*)this)[i];
  1517. }
  1518. //-----------------------------------------------------------------------------
  1519. // Equality test
  1520. //-----------------------------------------------------------------------------
  1521. inline bool Quaternion::operator==( const Quaternion &src ) const
  1522. {
  1523. return ( x == src.x ) && ( y == src.y ) && ( z == src.z ) && ( w == src.w );
  1524. }
  1525. inline bool Quaternion::operator!=( const Quaternion &src ) const
  1526. {
  1527. return !operator==( src );
  1528. }
  1529. //-----------------------------------------------------------------------------
  1530. // Debugging only
  1531. //-----------------------------------------------------------------------------
  1532. void Quaternion::Print() const
  1533. {
  1534. #ifndef _CERT
  1535. #if !defined(__SPU__)
  1536. Msg("q{ %.3fi + %.3fj + %.3fk + %.3f }", x, y, z, w );
  1537. #endif
  1538. #endif
  1539. }
  1540. //-----------------------------------------------------------------------------
  1541. // Binaray operators
  1542. //-----------------------------------------------------------------------------
  1543. inline Quaternion operator+( const Quaternion& q1, const Quaternion& q2 )
  1544. {
  1545. return Quaternion( q1.x + q2.x, q1.y + q2.y, q1.z + q2.z, q1.w + q2.w );
  1546. }
  1547. inline Quaternion operator-( const Quaternion& q1, const Quaternion& q2 )
  1548. {
  1549. return Quaternion( q1.x - q2.x, q1.y - q2.y, q1.z - q2.z, q1.w - q2.w );
  1550. }
  1551. inline Quaternion operator*( float s, const Quaternion& q )
  1552. {
  1553. return Quaternion( s * q.x, s * q.y, s * q.z, s * q.w );
  1554. }
  1555. inline Quaternion operator*( const Quaternion& q, float s )
  1556. {
  1557. return Quaternion( q.x * s, q.y * s, q.z * s, q.w * s );
  1558. }
  1559. inline Quaternion operator/( const Quaternion& q, float s )
  1560. {
  1561. Assert( s != 0.0f );
  1562. return Quaternion( q.x / s, q.y / s, q.z / s, q.w / s );
  1563. }
  1564. //-----------------------------------------------------------------------------
  1565. // Quaternion equality with tolerance
  1566. //-----------------------------------------------------------------------------
  1567. inline bool QuaternionsAreEqual( const Quaternion& src1, const Quaternion& src2, float tolerance )
  1568. {
  1569. if (FloatMakePositive(src1.x - src2.x) > tolerance)
  1570. return false;
  1571. if (FloatMakePositive(src1.y - src2.y) > tolerance)
  1572. return false;
  1573. if (FloatMakePositive(src1.z - src2.z) > tolerance)
  1574. return false;
  1575. return (FloatMakePositive(src1.w - src2.w) <= tolerance);
  1576. }
  1577. //-----------------------------------------------------------------------------
  1578. // Here's where we add all those lovely SSE optimized routines
  1579. //-----------------------------------------------------------------------------
  1580. class ALIGN16 QuaternionAligned : public Quaternion
  1581. {
  1582. public:
  1583. inline QuaternionAligned(void) {};
  1584. inline QuaternionAligned(vec_t X, vec_t Y, vec_t Z, vec_t W)
  1585. {
  1586. Init(X,Y,Z,W);
  1587. }
  1588. operator Quaternion * () { return this; }
  1589. operator const Quaternion * () { return this; }
  1590. #ifdef VECTOR_NO_SLOW_OPERATIONS
  1591. private:
  1592. // No copy constructors allowed if we're in optimal mode
  1593. QuaternionAligned(const QuaternionAligned& vOther);
  1594. QuaternionAligned(const Quaternion &vOther);
  1595. #else
  1596. public:
  1597. explicit QuaternionAligned(const Quaternion &vOther)
  1598. {
  1599. Init(vOther.x, vOther.y, vOther.z, vOther.w);
  1600. }
  1601. QuaternionAligned& operator=(const Quaternion &vOther)
  1602. {
  1603. Init(vOther.x, vOther.y, vOther.z, vOther.w);
  1604. return *this;
  1605. }
  1606. QuaternionAligned& operator=(const QuaternionAligned &vOther)
  1607. {
  1608. // we know we're aligned, so use simd
  1609. // we can't use the convenient abstract interface coz it gets declared later
  1610. #ifdef _X360
  1611. XMStoreVector4A(Base(), XMLoadVector4A(vOther.Base()));
  1612. #elif _WIN32
  1613. _mm_store_ps(Base(), _mm_load_ps( vOther.Base() ));
  1614. #else
  1615. Init(vOther.x, vOther.y, vOther.z, vOther.w);
  1616. #endif
  1617. return *this;
  1618. }
  1619. #endif
  1620. #if !defined(NO_MALLOC_OVERRIDE)
  1621. void* operator new[] ( size_t nSize)
  1622. {
  1623. return MemAlloc_AllocAligned(nSize, 16);
  1624. }
  1625. void* operator new[] ( size_t nSize, const char *pFileName, int nLine)
  1626. {
  1627. return MemAlloc_AllocAlignedFileLine(nSize, 16, pFileName, nLine);
  1628. }
  1629. void* operator new[] ( size_t nSize, int /*nBlockUse*/, const char *pFileName, int nLine)
  1630. {
  1631. return MemAlloc_AllocAlignedFileLine(nSize, 16, pFileName, nLine);
  1632. }
  1633. void operator delete[] ( void* p)
  1634. {
  1635. MemAlloc_FreeAligned(p);
  1636. }
  1637. void operator delete[] ( void* p, const char *pFileName, int nLine)
  1638. {
  1639. MemAlloc_FreeAligned(p, pFileName, nLine);
  1640. }
  1641. void operator delete[] ( void* p, int /*nBlockUse*/, const char *pFileName, int nLine)
  1642. {
  1643. MemAlloc_FreeAligned(p, pFileName, nLine);
  1644. }
  1645. // please don't allocate a single quaternion...
  1646. void* operator new ( size_t nSize )
  1647. {
  1648. return MemAlloc_AllocAligned(nSize, 16);
  1649. }
  1650. void* operator new ( size_t nSize, const char *pFileName, int nLine )
  1651. {
  1652. return MemAlloc_AllocAlignedFileLine(nSize, 16, pFileName, nLine);
  1653. }
  1654. void* operator new ( size_t nSize, int /*nBlockUse*/, const char *pFileName, int nLine )
  1655. {
  1656. return MemAlloc_AllocAlignedFileLine(nSize, 16, pFileName, nLine);
  1657. }
  1658. void operator delete ( void* p)
  1659. {
  1660. MemAlloc_FreeAligned(p);
  1661. }
  1662. void operator delete ( void* p, const char *pFileName, int nLine)
  1663. {
  1664. MemAlloc_FreeAligned(p, pFileName, nLine);
  1665. }
  1666. void operator delete ( void* p, int /*nBlockUse*/, const char *pFileName, int nLine)
  1667. {
  1668. MemAlloc_FreeAligned(p, pFileName, nLine);
  1669. }
  1670. #endif
  1671. } ALIGN16_POST;
  1672. //-----------------------------------------------------------------------------
  1673. // Src data hasn't changed, but work data is of a form more friendly for SPU
  1674. //-----------------------------------------------------------------------------
  1675. #if defined( _PS3 )
  1676. //typedef Vector BoneVector;
  1677. typedef VectorAligned BoneVector;
  1678. typedef QuaternionAligned BoneQuaternion;
  1679. typedef QuaternionAligned BoneQuaternionAligned;
  1680. #else
  1681. typedef Vector BoneVector;
  1682. typedef Quaternion BoneQuaternion;
  1683. typedef QuaternionAligned BoneQuaternionAligned;
  1684. #endif
  1685. //-----------------------------------------------------------------------------
  1686. // Radian Euler angle aligned to axis (NOT ROLL/PITCH/YAW)
  1687. //-----------------------------------------------------------------------------
  1688. class QAngle;
  1689. #define VEC_DEG2RAD( a ) (a) * (3.14159265358979323846f / 180.0f)
  1690. #define VEC_RAD2DEG( a ) (a) * (180.0f / 3.14159265358979323846f)
  1691. class RadianEuler
  1692. {
  1693. public:
  1694. inline RadianEuler(void) { }
  1695. inline RadianEuler(vec_t X, vec_t Y, vec_t Z) { x = X; y = Y; z = Z; }
  1696. inline explicit RadianEuler( Quaternion const &q );
  1697. inline explicit RadianEuler( QAngle const &angles );
  1698. inline explicit RadianEuler( DegreeEuler const &angles );
  1699. // Initialization
  1700. inline void Init(vec_t ix=0.0f, vec_t iy=0.0f, vec_t iz=0.0f) { x = ix; y = iy; z = iz; }
  1701. // conversion to qangle
  1702. QAngle ToQAngle( void ) const;
  1703. bool IsValid() const;
  1704. void Invalidate();
  1705. inline vec_t *Base() { return &x; }
  1706. inline const vec_t *Base() const { return &x; }
  1707. // array access...
  1708. vec_t operator[](int i) const;
  1709. vec_t& operator[](int i);
  1710. vec_t x, y, z;
  1711. };
  1712. extern void AngleQuaternion( RadianEuler const &angles, Quaternion &qt );
  1713. extern void QuaternionAngles( Quaternion const &q, RadianEuler &angles );
  1714. inline Quaternion::Quaternion(RadianEuler const &angle)
  1715. {
  1716. AngleQuaternion( angle, *this );
  1717. }
  1718. inline bool Quaternion::IsValid() const
  1719. {
  1720. return IsFinite(x) && IsFinite(y) && IsFinite(z) && IsFinite(w);
  1721. }
  1722. FORCEINLINE float QuaternionLength( const Quaternion &q )
  1723. {
  1724. return sqrtf( q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w );
  1725. }
  1726. FORCEINLINE bool QuaternionIsNormalized( const Quaternion &q, float flTolerance = 1e-6f )
  1727. {
  1728. float flLen = QuaternionLength( q );
  1729. return ( fabs( flLen - 1.0 ) < flTolerance );
  1730. }
  1731. inline void Quaternion::Invalidate()
  1732. {
  1733. //#ifdef _DEBUG
  1734. //#ifdef VECTOR_PARANOIA
  1735. x = y = z = w = VEC_T_NAN;
  1736. //#endif
  1737. //#endif
  1738. }
  1739. inline RadianEuler::RadianEuler(Quaternion const &q)
  1740. {
  1741. QuaternionAngles( q, *this );
  1742. }
  1743. inline void VectorCopy( RadianEuler const& src, RadianEuler &dst )
  1744. {
  1745. CHECK_VALID(src);
  1746. dst.x = src.x;
  1747. dst.y = src.y;
  1748. dst.z = src.z;
  1749. }
  1750. inline void VectorScale( RadianEuler const& src, float b, RadianEuler &dst )
  1751. {
  1752. CHECK_VALID(src);
  1753. Assert( IsFinite(b) );
  1754. dst.x = src.x * b;
  1755. dst.y = src.y * b;
  1756. dst.z = src.z * b;
  1757. }
  1758. inline bool RadianEuler::IsValid() const
  1759. {
  1760. return IsFinite(x) && IsFinite(y) && IsFinite(z);
  1761. }
  1762. inline void RadianEuler::Invalidate()
  1763. {
  1764. //#ifdef _DEBUG
  1765. //#ifdef VECTOR_PARANOIA
  1766. x = y = z = VEC_T_NAN;
  1767. //#endif
  1768. //#endif
  1769. }
  1770. //-----------------------------------------------------------------------------
  1771. // Array access
  1772. //-----------------------------------------------------------------------------
  1773. inline vec_t& RadianEuler::operator[](int i)
  1774. {
  1775. Assert( (i >= 0) && (i < 3) );
  1776. return ((vec_t*)this)[i];
  1777. }
  1778. inline vec_t RadianEuler::operator[](int i) const
  1779. {
  1780. Assert( (i >= 0) && (i < 3) );
  1781. return ((vec_t*)this)[i];
  1782. }
  1783. //-----------------------------------------------------------------------------
  1784. // Degree Euler angle aligned to axis (NOT ROLL/PITCH/YAW)
  1785. //-----------------------------------------------------------------------------
  1786. class DegreeEuler
  1787. {
  1788. public:
  1789. ///\name Initialization
  1790. //@{
  1791. inline DegreeEuler(void) ///< Create with un-initialized components. If VECTOR_PARANOIA is set, will init with NANS.
  1792. {
  1793. // Initialize to NAN to catch errors
  1794. #ifdef VECTOR_PARANOIA
  1795. x = y = z = VEC_T_NAN;
  1796. #endif
  1797. }
  1798. inline DegreeEuler( vec_t X, vec_t Y, vec_t Z ) { x = X; y = Y; z = Z; }
  1799. inline explicit DegreeEuler( Quaternion const &q );
  1800. inline explicit DegreeEuler( QAngle const &angles );
  1801. inline explicit DegreeEuler( RadianEuler const &angles );
  1802. // Initialization
  1803. inline void Init(vec_t ix=0.0f, vec_t iy=0.0f, vec_t iz=0.0f) { x = ix; y = iy; z = iz; }
  1804. inline QAngle ToQAngle() const;
  1805. // conversion to qangle
  1806. bool IsValid() const;
  1807. void Invalidate();
  1808. inline vec_t *Base() { return &x; }
  1809. inline const vec_t *Base() const { return &x; }
  1810. // array access...
  1811. vec_t operator[](int i) const;
  1812. vec_t& operator[](int i);
  1813. vec_t x, y, z;
  1814. };
  1815. //-----------------------------------------------------------------------------
  1816. // DegreeEuler equality with tolerance
  1817. //-----------------------------------------------------------------------------
  1818. inline bool DegreeEulersAreEqual( const DegreeEuler& src1, const DegreeEuler& src2, float tolerance = 0.0f )
  1819. {
  1820. if (FloatMakePositive(src1.x - src2.x) > tolerance)
  1821. return false;
  1822. if (FloatMakePositive(src1.y - src2.y) > tolerance)
  1823. return false;
  1824. return (FloatMakePositive(src1.z - src2.z) <= tolerance);
  1825. }
  1826. /*
  1827. extern void AngleQuaternion( DegreeEuler const &angles, Quaternion &qt );
  1828. extern void QuaternionAngles( Quaternion const &q, DegreeEuler &angles );
  1829. extern void QuaternionVectorsFLU( Quaternion const &q, Vector *pForward, Vector *pLeft, Vector *pUp );
  1830. */
  1831. inline Quaternion::Quaternion( DegreeEuler const &angles )
  1832. {
  1833. RadianEuler radians( angles );
  1834. AngleQuaternion( radians, *this );
  1835. }
  1836. inline DegreeEuler::DegreeEuler( RadianEuler const &angles )
  1837. {
  1838. Init( VEC_RAD2DEG( angles.x ), VEC_RAD2DEG( angles.y ), VEC_RAD2DEG( angles.z ) );
  1839. }
  1840. inline RadianEuler::RadianEuler( DegreeEuler const &angles )
  1841. {
  1842. Init( VEC_DEG2RAD( angles.x ), VEC_DEG2RAD( angles.y ), VEC_DEG2RAD( angles.z ) );
  1843. }
  1844. inline DegreeEuler::DegreeEuler( Quaternion const &q )
  1845. {
  1846. RadianEuler radians( q );
  1847. Init( VEC_RAD2DEG( radians.x ), VEC_RAD2DEG( radians.y ), VEC_RAD2DEG( radians.z ) );
  1848. }
  1849. inline bool DegreeEuler::IsValid() const
  1850. {
  1851. return IsFinite(x) && IsFinite(y) && IsFinite(z);
  1852. }
  1853. inline void DegreeEuler::Invalidate()
  1854. {
  1855. //#ifdef VECTOR_PARANOIA
  1856. x = y = z = VEC_T_NAN;
  1857. //#endif
  1858. }
  1859. //-----------------------------------------------------------------------------
  1860. // Array access
  1861. //-----------------------------------------------------------------------------
  1862. inline vec_t& DegreeEuler::operator[](int i)
  1863. {
  1864. AssertDbg( (i >= 0) && (i < 3) );
  1865. return ((vec_t*)this)[i];
  1866. }
  1867. inline vec_t DegreeEuler::operator[](int i) const
  1868. {
  1869. AssertDbg( (i >= 0) && (i < 3) );
  1870. return ((vec_t*)this)[i];
  1871. }
  1872. //-----------------------------------------------------------------------------
  1873. // Degree Euler QAngle pitch, yaw, roll
  1874. //-----------------------------------------------------------------------------
  1875. class QAngleByValue;
  1876. class QAngle
  1877. {
  1878. public:
  1879. // Members
  1880. vec_t x, y, z;
  1881. // Construction/destruction
  1882. QAngle(void);
  1883. QAngle(vec_t X, vec_t Y, vec_t Z);
  1884. #ifndef _PS3
  1885. // QAngle(RadianEuler const &angles); // evil auto type promotion!!!
  1886. #endif
  1887. // Allow pass-by-value
  1888. operator QAngleByValue &() { return *((QAngleByValue *)(this)); }
  1889. operator const QAngleByValue &() const { return *((const QAngleByValue *)(this)); }
  1890. // Initialization
  1891. void Init(vec_t ix=0.0f, vec_t iy=0.0f, vec_t iz=0.0f);
  1892. void Random( vec_t minVal, vec_t maxVal );
  1893. // Got any nasty NAN's?
  1894. bool IsValid() const;
  1895. void Invalidate();
  1896. // array access...
  1897. vec_t operator[](int i) const;
  1898. vec_t& operator[](int i);
  1899. // Base address...
  1900. vec_t* Base();
  1901. vec_t const* Base() const;
  1902. // equality
  1903. bool operator==(const QAngle& v) const;
  1904. bool operator!=(const QAngle& v) const;
  1905. // arithmetic operations
  1906. QAngle& operator+=(const QAngle &v);
  1907. QAngle& operator-=(const QAngle &v);
  1908. QAngle& operator*=(float s);
  1909. QAngle& operator/=(float s);
  1910. // Get the vector's magnitude.
  1911. vec_t Length() const;
  1912. vec_t LengthSqr() const;
  1913. // negate the QAngle components
  1914. //void Negate();
  1915. // No assignment operators either...
  1916. QAngle& operator=( const QAngle& src );
  1917. void Normalize();
  1918. void NormalizePositive();
  1919. inline struct matrix3x4_t ToMatrix() const;
  1920. inline Quaternion ToQuaternion() const;
  1921. #ifndef VECTOR_NO_SLOW_OPERATIONS
  1922. // copy constructors
  1923. // arithmetic operations
  1924. QAngle operator-(void) const;
  1925. QAngle operator+(const QAngle& v) const;
  1926. QAngle operator-(const QAngle& v) const;
  1927. QAngle operator*(float fl) const;
  1928. QAngle operator/(float fl) const;
  1929. #else
  1930. private:
  1931. // No copy constructors allowed if we're in optimal mode
  1932. QAngle(const QAngle& vOther);
  1933. #endif
  1934. };
  1935. // Zero the object -- necessary for CNetworkVar and possibly other cases.
  1936. inline void EnsureValidValue( QAngle &x ) { x.Init(); }
  1937. //-----------------------------------------------------------------------------
  1938. // Allows us to specifically pass the vector by value when we need to
  1939. //-----------------------------------------------------------------------------
  1940. class QAngleByValue : public QAngle
  1941. {
  1942. public:
  1943. // Construction/destruction:
  1944. QAngleByValue(void) : QAngle() {}
  1945. QAngleByValue(vec_t X, vec_t Y, vec_t Z) : QAngle( X, Y, Z ) {}
  1946. QAngleByValue(const QAngleByValue& vOther) { *this = vOther; }
  1947. };
  1948. inline void VectorAdd( const QAngle& a, const QAngle& b, QAngle& result )
  1949. {
  1950. CHECK_VALID(a);
  1951. CHECK_VALID(b);
  1952. result.x = a.x + b.x;
  1953. result.y = a.y + b.y;
  1954. result.z = a.z + b.z;
  1955. }
  1956. inline void VectorMA( const QAngle &start, float scale, const QAngle &direction, QAngle &dest )
  1957. {
  1958. CHECK_VALID(start);
  1959. CHECK_VALID(direction);
  1960. dest.x = start.x + scale * direction.x;
  1961. dest.y = start.y + scale * direction.y;
  1962. dest.z = start.z + scale * direction.z;
  1963. }
  1964. //-----------------------------------------------------------------------------
  1965. // constructors
  1966. //-----------------------------------------------------------------------------
  1967. inline QAngle::QAngle(void)
  1968. {
  1969. #ifdef _DEBUG
  1970. #ifdef VECTOR_PARANOIA
  1971. // Initialize to NAN to catch errors
  1972. x = y = z = VEC_T_NAN;
  1973. #endif
  1974. #endif
  1975. }
  1976. inline QAngle::QAngle(vec_t X, vec_t Y, vec_t Z)
  1977. {
  1978. x = X; y = Y; z = Z;
  1979. CHECK_VALID(*this);
  1980. }
  1981. //-----------------------------------------------------------------------------
  1982. // initialization
  1983. //-----------------------------------------------------------------------------
  1984. inline void QAngle::Init( vec_t ix, vec_t iy, vec_t iz )
  1985. {
  1986. x = ix; y = iy; z = iz;
  1987. CHECK_VALID(*this);
  1988. }
  1989. extern float AngleNormalize( float angle );
  1990. extern float AngleNormalizePositive( float angle );
  1991. inline void QAngle::Normalize()
  1992. {
  1993. x = AngleNormalize( x );
  1994. y = AngleNormalize( y );
  1995. z = AngleNormalize( z );
  1996. }
  1997. inline void QAngle::NormalizePositive()
  1998. {
  1999. x = AngleNormalizePositive( x );
  2000. y = AngleNormalizePositive( y );
  2001. z = AngleNormalizePositive( z );
  2002. }
  2003. #if !defined(__SPU__)
  2004. inline void QAngle::Random( vec_t minVal, vec_t maxVal )
  2005. {
  2006. x = RandomFloat( minVal, maxVal );
  2007. y = RandomFloat( minVal, maxVal );
  2008. z = RandomFloat( minVal, maxVal );
  2009. CHECK_VALID(*this);
  2010. }
  2011. #endif
  2012. #ifndef VECTOR_NO_SLOW_OPERATIONS
  2013. #if !defined(__SPU__)
  2014. inline QAngle RandomAngle( float minVal, float maxVal )
  2015. {
  2016. Vector random;
  2017. random.Random( minVal, maxVal );
  2018. QAngle ret( random.x, random.y, random.z );
  2019. return ret;
  2020. }
  2021. #endif
  2022. #endif
  2023. inline RadianEuler::RadianEuler(QAngle const &angles)
  2024. {
  2025. Init(
  2026. angles.z * 3.14159265358979323846f / 180.f,
  2027. angles.x * 3.14159265358979323846f / 180.f,
  2028. angles.y * 3.14159265358979323846f / 180.f );
  2029. }
  2030. inline DegreeEuler::DegreeEuler( QAngle const &angles )
  2031. {
  2032. Init( angles.z, angles.x, angles.y );
  2033. }
  2034. inline QAngle RadianEuler::ToQAngle( void) const
  2035. {
  2036. return QAngle( VEC_RAD2DEG( y ), VEC_RAD2DEG( z ), VEC_RAD2DEG( x ) );
  2037. }
  2038. inline QAngle DegreeEuler::ToQAngle() const
  2039. {
  2040. return QAngle( y, z, x );
  2041. }
  2042. //-----------------------------------------------------------------------------
  2043. // assignment
  2044. //-----------------------------------------------------------------------------
  2045. inline QAngle& QAngle::operator=(const QAngle &vOther)
  2046. {
  2047. CHECK_VALID(vOther);
  2048. x=vOther.x; y=vOther.y; z=vOther.z;
  2049. return *this;
  2050. }
  2051. //-----------------------------------------------------------------------------
  2052. // Array access
  2053. //-----------------------------------------------------------------------------
  2054. inline vec_t& QAngle::operator[](int i)
  2055. {
  2056. Assert( (i >= 0) && (i < 3) );
  2057. return ((vec_t*)this)[i];
  2058. }
  2059. inline vec_t QAngle::operator[](int i) const
  2060. {
  2061. Assert( (i >= 0) && (i < 3) );
  2062. return ((vec_t*)this)[i];
  2063. }
  2064. //-----------------------------------------------------------------------------
  2065. // Base address...
  2066. //-----------------------------------------------------------------------------
  2067. inline vec_t* QAngle::Base()
  2068. {
  2069. return (vec_t*)this;
  2070. }
  2071. inline vec_t const* QAngle::Base() const
  2072. {
  2073. return (vec_t const*)this;
  2074. }
  2075. //-----------------------------------------------------------------------------
  2076. // IsValid?
  2077. //-----------------------------------------------------------------------------
  2078. inline bool QAngle::IsValid() const
  2079. {
  2080. return IsFinite(x) && IsFinite(y) && IsFinite(z);
  2081. }
  2082. //-----------------------------------------------------------------------------
  2083. // Invalidate
  2084. //-----------------------------------------------------------------------------
  2085. inline void QAngle::Invalidate()
  2086. {
  2087. //#ifdef _DEBUG
  2088. //#ifdef VECTOR_PARANOIA
  2089. x = y = z = VEC_T_NAN;
  2090. //#endif
  2091. //#endif
  2092. }
  2093. //-----------------------------------------------------------------------------
  2094. // comparison
  2095. //-----------------------------------------------------------------------------
  2096. inline bool QAngle::operator==( const QAngle& src ) const
  2097. {
  2098. CHECK_VALID(src);
  2099. CHECK_VALID(*this);
  2100. return (src.x == x) && (src.y == y) && (src.z == z);
  2101. }
  2102. inline bool QAngle::operator!=( const QAngle& src ) const
  2103. {
  2104. CHECK_VALID(src);
  2105. CHECK_VALID(*this);
  2106. return (src.x != x) || (src.y != y) || (src.z != z);
  2107. }
  2108. //-----------------------------------------------------------------------------
  2109. // Copy
  2110. //-----------------------------------------------------------------------------
  2111. inline void VectorCopy( const QAngle& src, QAngle& dst )
  2112. {
  2113. CHECK_VALID(src);
  2114. dst.x = src.x;
  2115. dst.y = src.y;
  2116. dst.z = src.z;
  2117. }
  2118. //-----------------------------------------------------------------------------
  2119. // standard math operations
  2120. //-----------------------------------------------------------------------------
  2121. inline QAngle& QAngle::operator+=(const QAngle& v)
  2122. {
  2123. CHECK_VALID(*this);
  2124. CHECK_VALID(v);
  2125. x+=v.x; y+=v.y; z += v.z;
  2126. return *this;
  2127. }
  2128. inline QAngle& QAngle::operator-=(const QAngle& v)
  2129. {
  2130. CHECK_VALID(*this);
  2131. CHECK_VALID(v);
  2132. x-=v.x; y-=v.y; z -= v.z;
  2133. return *this;
  2134. }
  2135. inline QAngle& QAngle::operator*=(float fl)
  2136. {
  2137. x *= fl;
  2138. y *= fl;
  2139. z *= fl;
  2140. CHECK_VALID(*this);
  2141. return *this;
  2142. }
  2143. inline QAngle& QAngle::operator/=(float fl)
  2144. {
  2145. Assert( fl != 0.0f );
  2146. float oofl = 1.0f / fl;
  2147. x *= oofl;
  2148. y *= oofl;
  2149. z *= oofl;
  2150. CHECK_VALID(*this);
  2151. return *this;
  2152. }
  2153. //-----------------------------------------------------------------------------
  2154. // length
  2155. //-----------------------------------------------------------------------------
  2156. inline vec_t QAngle::Length( ) const
  2157. {
  2158. CHECK_VALID(*this);
  2159. return (vec_t)FastSqrt( LengthSqr( ) );
  2160. }
  2161. inline vec_t QAngle::LengthSqr( ) const
  2162. {
  2163. CHECK_VALID(*this);
  2164. return x * x + y * y + z * z;
  2165. }
  2166. //-----------------------------------------------------------------------------
  2167. // Vector equality with tolerance
  2168. //-----------------------------------------------------------------------------
  2169. inline bool QAnglesAreEqual( const QAngle& src1, const QAngle& src2, float tolerance = 0.0f )
  2170. {
  2171. if (FloatMakePositive(src1.x - src2.x) > tolerance)
  2172. return false;
  2173. if (FloatMakePositive(src1.y - src2.y) > tolerance)
  2174. return false;
  2175. return (FloatMakePositive(src1.z - src2.z) <= tolerance);
  2176. }
  2177. //-----------------------------------------------------------------------------
  2178. // arithmetic operations (SLOW!!)
  2179. //-----------------------------------------------------------------------------
  2180. #ifndef VECTOR_NO_SLOW_OPERATIONS
  2181. inline QAngle QAngle::operator-(void) const
  2182. {
  2183. QAngle ret(-x,-y,-z);
  2184. return ret;
  2185. }
  2186. inline QAngle QAngle::operator+(const QAngle& v) const
  2187. {
  2188. QAngle res;
  2189. res.x = x + v.x;
  2190. res.y = y + v.y;
  2191. res.z = z + v.z;
  2192. return res;
  2193. }
  2194. inline QAngle QAngle::operator-(const QAngle& v) const
  2195. {
  2196. QAngle res;
  2197. res.x = x - v.x;
  2198. res.y = y - v.y;
  2199. res.z = z - v.z;
  2200. return res;
  2201. }
  2202. inline QAngle QAngle::operator*(float fl) const
  2203. {
  2204. QAngle res;
  2205. res.x = x * fl;
  2206. res.y = y * fl;
  2207. res.z = z * fl;
  2208. return res;
  2209. }
  2210. inline QAngle QAngle::operator/(float fl) const
  2211. {
  2212. QAngle res;
  2213. res.x = x / fl;
  2214. res.y = y / fl;
  2215. res.z = z / fl;
  2216. return res;
  2217. }
  2218. inline QAngle operator*(float fl, const QAngle& v)
  2219. {
  2220. QAngle ret( v * fl );
  2221. return ret;
  2222. }
  2223. #endif // VECTOR_NO_SLOW_OPERATIONS
  2224. //-----------------------------------------------------------------------------
  2225. // NOTE: These are not completely correct. The representations are not equivalent
  2226. // unless the QAngle represents a rotational impulse along a coordinate axis (x,y,z)
  2227. inline void QAngleToAngularImpulse( const QAngle &angles, AngularImpulse &impulse )
  2228. {
  2229. impulse.x = angles.z;
  2230. impulse.y = angles.x;
  2231. impulse.z = angles.y;
  2232. }
  2233. inline void AngularImpulseToQAngle( const AngularImpulse &impulse, QAngle &angles )
  2234. {
  2235. angles.x = impulse.y;
  2236. angles.y = impulse.z;
  2237. angles.z = impulse.x;
  2238. }
  2239. inline QAngle Quaternion::ToQAngle() const
  2240. {
  2241. extern void QuaternionAngles( const Quaternion &q, QAngle &angles );
  2242. QAngle anglesOut;
  2243. QuaternionAngles( *this, anglesOut );
  2244. return anglesOut;
  2245. }
  2246. #if !defined( _X360 ) && !defined( _PS3 )
  2247. FORCEINLINE vec_t InvRSquared( const float* v )
  2248. {
  2249. return 1.0 / MAX( 1.0, v[0] * v[0] + v[1] * v[1] + v[2] * v[2] );
  2250. }
  2251. FORCEINLINE vec_t InvRSquared( const Vector &v )
  2252. {
  2253. return InvRSquared( v.Base() );
  2254. }
  2255. #else
  2256. // call directly
  2257. #if defined(__SPU__)
  2258. FORCEINLINE float _VMX_InvRSquared( Vector &v )
  2259. #else
  2260. FORCEINLINE float _VMX_InvRSquared( const Vector &v )
  2261. #endif
  2262. {
  2263. #if !defined (_PS3)
  2264. XMVECTOR xmV = XMVector3ReciprocalLength( XMLoadVector3( v.Base() ) );
  2265. xmV = XMVector3Dot( xmV, xmV );
  2266. return xmV.x;
  2267. #else //!_PS3
  2268. vector_float_union vRet;
  2269. vec_float4 v0, v1, vIn, vOut;
  2270. vector unsigned char permMask;
  2271. v0 = vec_ld( 0, v.Base() );
  2272. permMask = vec_lvsl( 0, v.Base() );
  2273. v1 = vec_ld( 11, v.Base() );
  2274. vIn = vec_perm(v0, v1, permMask);
  2275. vOut = vec_madd( vIn, vIn, _VEC_ZEROF );
  2276. vec_float4 vTmp = vec_sld( vIn, vIn, 4 );
  2277. vec_float4 vTmp2 = vec_sld( vIn, vIn, 8 );
  2278. vOut = vec_madd( vTmp, vTmp, vOut );
  2279. vOut = vec_madd( vTmp2, vTmp2, vOut );
  2280. vOut = vec_re( vec_add(vOut, _VEC_EPSILONF) );
  2281. vec_st(vOut,0,&vRet.vf);
  2282. float ret = vRet.f[0];
  2283. return ret;
  2284. #endif //!_PS3
  2285. }
  2286. #define InvRSquared(x) _VMX_InvRSquared(x)
  2287. #endif // _X360
  2288. #if !defined( _X360 ) && !defined( _PS3 )
  2289. // FIXME: Change this back to a #define once we get rid of the vec_t version
  2290. float VectorNormalize( Vector& v );
  2291. // FIXME: Obsolete version of VectorNormalize, once we remove all the friggin float*s
  2292. FORCEINLINE float VectorNormalize( float * v )
  2293. {
  2294. return VectorNormalize(*(reinterpret_cast<Vector *>(v)));
  2295. }
  2296. #else
  2297. #if !defined( _PS3 )
  2298. // modified version of Microsoft's XMVector3Length
  2299. // microsoft's version will return INF for very small vectors
  2300. // e.g. Vector vTest(7.98555446e-20,-6.85012984e-21,0); VectorNormalize( vTest );
  2301. // so we clamp to epsilon instead of checking for zero
  2302. XMFINLINE XMVECTOR XMVector3Length_Fixed
  2303. (
  2304. FXMVECTOR V
  2305. )
  2306. {
  2307. // Returns a QNaN on infinite vectors.
  2308. static CONST XMVECTOR g_fl4SmallVectorEpsilon = {1e-24f,1e-24f,1e-24f,1e-24f};
  2309. XMVECTOR D;
  2310. XMVECTOR Rsq;
  2311. XMVECTOR Rcp;
  2312. XMVECTOR Zero;
  2313. XMVECTOR RT;
  2314. XMVECTOR Result;
  2315. XMVECTOR Length;
  2316. XMVECTOR H;
  2317. H = __vspltisw(1);
  2318. D = __vmsum3fp(V, V);
  2319. H = __vcfsx(H, 1);
  2320. Rsq = __vrsqrtefp(D);
  2321. RT = __vmulfp(D, H);
  2322. Rcp = __vmulfp(Rsq, Rsq);
  2323. H = __vnmsubfp(RT, Rcp, H);
  2324. Rsq = __vmaddfp(Rsq, H, Rsq);
  2325. Zero = __vspltisw(0);
  2326. Result = __vcmpgefp( g_fl4SmallVectorEpsilon, D );
  2327. Length = __vmulfp(D, Rsq);
  2328. Result = __vsel(Length, Zero, Result);
  2329. return Result;
  2330. }
  2331. #endif
  2332. // call directly
  2333. FORCEINLINE float _VMX_VectorNormalize( Vector &vec )
  2334. {
  2335. #if !defined _PS3
  2336. float mag = XMVector3Length_Fixed( XMLoadVector3( vec.Base() ) ).x;
  2337. float den = 1.f / (mag + FLT_EPSILON );
  2338. vec.x *= den;
  2339. vec.y *= den;
  2340. vec.z *= den;
  2341. return mag;
  2342. #else // !_PS3
  2343. vec_float4 vIn;
  2344. vec_float4 v0, v1;
  2345. vector unsigned char permMask;
  2346. v0 = vec_ld( 0, vec.Base() );
  2347. permMask = vec_lvsl( 0, vec.Base() );
  2348. v1 = vec_ld( 11, vec.Base() );
  2349. vIn = vec_perm(v0, v1, permMask);
  2350. float mag = vmathV3Length((VmathVector3 *)&vIn);
  2351. float den = 1.f / (mag + FLT_EPSILON );
  2352. vec.x *= den;
  2353. vec.y *= den;
  2354. vec.z *= den;
  2355. return mag;
  2356. #endif // !_PS3
  2357. }
  2358. // FIXME: Change this back to a #define once we get rid of the vec_t version
  2359. FORCEINLINE float VectorNormalize( Vector& v )
  2360. {
  2361. return _VMX_VectorNormalize( v );
  2362. }
  2363. // FIXME: Obsolete version of VectorNormalize, once we remove all the friggin float*s
  2364. FORCEINLINE float VectorNormalize( float *pV )
  2365. {
  2366. return _VMX_VectorNormalize(*(reinterpret_cast<Vector*>(pV)));
  2367. }
  2368. #endif // _X360
  2369. #if !defined( _X360 ) && !defined( _PS3 )
  2370. FORCEINLINE void VectorNormalizeFast (Vector& vec)
  2371. {
  2372. float ool = FastRSqrt( FLT_EPSILON + vec.x * vec.x + vec.y * vec.y + vec.z * vec.z );
  2373. vec.x *= ool;
  2374. vec.y *= ool;
  2375. vec.z *= ool;
  2376. }
  2377. #else
  2378. // call directly
  2379. FORCEINLINE void VectorNormalizeFast( Vector &vec )
  2380. {
  2381. #if !defined (_PS3)
  2382. XMVECTOR xmV = XMVector3LengthEst( XMLoadVector3( vec.Base() ) );
  2383. float den = 1.f / (xmV.x + FLT_EPSILON);
  2384. vec.x *= den;
  2385. vec.y *= den;
  2386. vec.z *= den;
  2387. #else // !_PS3
  2388. vector_float_union vVec;
  2389. vec_float4 vIn, vOut, vOOLen, vDot;
  2390. // load
  2391. vec_float4 v0, v1;
  2392. vector unsigned char permMask;
  2393. v0 = vec_ld( 0, vec.Base() );
  2394. permMask = vec_lvsl( 0, vec.Base() );
  2395. v1 = vec_ld( 11, vec.Base() );
  2396. vIn = vec_perm(v0, v1, permMask);
  2397. // vec.vec
  2398. vOut = vec_madd( vIn, vIn, _VEC_ZEROF );
  2399. vec_float4 vTmp = vec_sld( vIn, vIn, 4 );
  2400. vec_float4 vTmp2 = vec_sld( vIn, vIn, 8 );
  2401. vOut = vec_madd( vTmp, vTmp, vOut );
  2402. vOut = vec_madd( vTmp2, vTmp2, vOut );
  2403. // splat dot to all
  2404. vDot = vec_splat( vOut, 0 );
  2405. vOOLen = vec_rsqrte( vec_add( vDot, _VEC_EPSILONF ) );
  2406. // vec * 1.0/sqrt(vec.vec)
  2407. vOut = vec_madd( vIn, vOOLen, _VEC_ZEROF );
  2408. // store
  2409. vec_st(vOut,0,&vVec.vf);
  2410. // store vec
  2411. vec.x = vVec.f[0];
  2412. vec.y = vVec.f[1];
  2413. vec.z = vVec.f[2];
  2414. #endif // !_PS3
  2415. }
  2416. #endif // _X360
  2417. inline vec_t Vector::NormalizeInPlace()
  2418. {
  2419. return VectorNormalize( *this );
  2420. }
  2421. inline vec_t Vector::NormalizeInPlaceSafe( const Vector &vFallback )
  2422. {
  2423. float flLength = VectorNormalize( *this );
  2424. if ( flLength == 0.0f )
  2425. {
  2426. *this = vFallback;
  2427. }
  2428. return flLength;
  2429. }
  2430. inline Vector Vector::Normalized() const
  2431. {
  2432. Vector norm = *this;
  2433. VectorNormalize( norm );
  2434. return norm;
  2435. }
  2436. inline Vector Vector::NormalizedSafe( const Vector &vFallback )const
  2437. {
  2438. Vector vNorm = *this;
  2439. float flLength = VectorNormalize( vNorm );
  2440. return ( flLength != 0.0f ) ? vNorm : vFallback;
  2441. }
  2442. inline bool Vector::IsLengthGreaterThan( float val ) const
  2443. {
  2444. return LengthSqr() > val*val;
  2445. }
  2446. inline bool Vector::IsLengthLessThan( float val ) const
  2447. {
  2448. return LengthSqr() < val*val;
  2449. }
  2450. inline const Vector ScaleVector( const Vector & a, const Vector & b )
  2451. {
  2452. return Vector( a.x * b.x, a.y * b.y, a.z * b.z );
  2453. }
  2454. inline const Quaternion Exp( const Vector &v )
  2455. {
  2456. float theta = v.Length();
  2457. if ( theta < 0.001f )
  2458. {
  2459. // limit case, cos(theta) ~= 1 - theta^2/2 + theta^4/24
  2460. // sin(theta)/theta ~= 1 - theta^2/6 + theta^4/120
  2461. float theta2_2 = theta * theta * 0.5f, theta4_24 = theta2_2 * theta2_2 * ( 1.0f / 6.0f );
  2462. float k = 1.0f - theta2_2 * ( 1.0f / 3.0f ) + theta4_24 * 0.05f;
  2463. return Quaternion( k * v.x, k * v.y, k * v.z, 1 - theta2_2 + theta4_24 );
  2464. }
  2465. else
  2466. {
  2467. float k = sinf( theta ) / theta;
  2468. return Quaternion( k * v.x, k * v.y, k * v.z, cosf( theta ) );
  2469. }
  2470. }
  2471. inline const Vector QuaternionLog( const Quaternion &q )
  2472. {
  2473. Vector axis = q.ImaginaryPart();
  2474. float sinTheta = axis.Length(), factor;
  2475. if ( sinTheta > 0.001f )
  2476. {
  2477. // there's some substantial rotation; if w < 0, it's an over-180-degree rotation (in real space)
  2478. float theta = asinf( MIN( sinTheta, 1.0f ) );
  2479. factor = ( q.w < 0.0f ? M_PI_F - theta : theta ) / sinTheta;
  2480. }
  2481. else
  2482. {
  2483. // ArcSin[x]/x = 1 + x^2/6 + x^4 * 3/40 + o( x^5 )
  2484. float sinTheta2 = sinTheta * sinTheta;
  2485. float sinTheta4 = sinTheta2 * sinTheta2;
  2486. factor = ( 1 + sinTheta2 * ( 1.0f / 6.0f ) + sinTheta4 * ( 3.0f / 40.0f ) );
  2487. if ( q.w < 0 )
  2488. {
  2489. factor = -factor; // because the axis of rotation is not defined, we'll just consider this rotation to be close enough to identity
  2490. }
  2491. }
  2492. return axis * factor;
  2493. }
  2494. inline float Snap( float a, float flSnap )
  2495. {
  2496. return floorf( a / flSnap + 0.5f ) * flSnap;
  2497. }
  2498. inline const Vector Snap( const Vector &a, float flSnap )
  2499. {
  2500. return Vector( Snap( a.x, flSnap ), Snap( a.y, flSnap ), Snap( a.z, flSnap ) );
  2501. }
  2502. #endif