Team Fortress 2 Source Code as on 22/4/2020
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.

2311 lines
55 KiB

  1. //========= Copyright 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. // For rand(). We really need a library!
  18. #include <stdlib.h>
  19. #ifndef _X360
  20. // For MMX intrinsics
  21. #include <xmmintrin.h>
  22. #endif
  23. #include "tier0/dbg.h"
  24. #include "tier0/threadtools.h"
  25. #include "mathlib/vector2d.h"
  26. #include "mathlib/math_pfns.h"
  27. // Uncomment this to add extra Asserts to check for NANs, uninitialized vecs, etc.
  28. //#define VECTOR_PARANOIA 1
  29. // Uncomment this to make sure we don't do anything slow with our vectors
  30. //#define VECTOR_NO_SLOW_OPERATIONS 1
  31. // Used to make certain code easier to read.
  32. #define X_INDEX 0
  33. #define Y_INDEX 1
  34. #define Z_INDEX 2
  35. #ifdef VECTOR_PARANOIA
  36. #define CHECK_VALID( _v) Assert( (_v).IsValid() )
  37. #else
  38. #ifdef GNUC
  39. #define CHECK_VALID( _v)
  40. #else
  41. #define CHECK_VALID( _v) 0
  42. #endif
  43. #endif
  44. #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!
  45. class VectorByValue;
  46. //=========================================================
  47. // 3D Vector
  48. //=========================================================
  49. class Vector
  50. {
  51. public:
  52. // Members
  53. vec_t x, y, z;
  54. // Construction/destruction:
  55. Vector(void);
  56. Vector(vec_t X, vec_t Y, vec_t Z);
  57. explicit Vector(vec_t XYZ); ///< broadcast initialize
  58. // Initialization
  59. void Init(vec_t ix=0.0f, vec_t iy=0.0f, vec_t iz=0.0f);
  60. // TODO (Ilya): Should there be an init that takes a single float for consistency?
  61. // Got any nasty NAN's?
  62. bool IsValid() const;
  63. void Invalidate();
  64. // array access...
  65. vec_t operator[](int i) const;
  66. vec_t& operator[](int i);
  67. // Base address...
  68. vec_t* Base();
  69. vec_t const* Base() const;
  70. // Cast to Vector2D...
  71. Vector2D& AsVector2D();
  72. const Vector2D& AsVector2D() const;
  73. // Initialization methods
  74. void Random( vec_t minVal, vec_t maxVal );
  75. inline void Zero(); ///< zero out a vector
  76. // equality
  77. bool operator==(const Vector& v) const;
  78. bool operator!=(const Vector& v) const;
  79. // arithmetic operations
  80. FORCEINLINE Vector& operator+=(const Vector &v);
  81. FORCEINLINE Vector& operator-=(const Vector &v);
  82. FORCEINLINE Vector& operator*=(const Vector &v);
  83. FORCEINLINE Vector& operator*=(float s);
  84. FORCEINLINE Vector& operator/=(const Vector &v);
  85. FORCEINLINE Vector& operator/=(float s);
  86. FORCEINLINE Vector& operator+=(float fl) ; ///< broadcast add
  87. FORCEINLINE Vector& operator-=(float fl) ; ///< broadcast sub
  88. // negate the vector components
  89. void Negate();
  90. // Get the vector's magnitude.
  91. inline vec_t Length() const;
  92. // Get the vector's magnitude squared.
  93. FORCEINLINE vec_t LengthSqr(void) const
  94. {
  95. CHECK_VALID(*this);
  96. return (x*x + y*y + z*z);
  97. }
  98. // return true if this vector is (0,0,0) within tolerance
  99. bool IsZero( float tolerance = 0.01f ) const
  100. {
  101. return (x > -tolerance && x < tolerance &&
  102. y > -tolerance && y < tolerance &&
  103. z > -tolerance && z < tolerance);
  104. }
  105. vec_t NormalizeInPlace();
  106. Vector Normalized() const;
  107. bool IsLengthGreaterThan( float val ) const;
  108. bool IsLengthLessThan( float val ) const;
  109. // check if a vector is within the box defined by two other vectors
  110. FORCEINLINE bool WithinAABox( Vector const &boxmin, Vector const &boxmax);
  111. // Get the distance from this vector to the other one.
  112. vec_t DistTo(const Vector &vOther) const;
  113. // Get the distance from this vector to the other one squared.
  114. // NJS: note, VC wasn't inlining it correctly in several deeply nested inlines due to being an 'out of line' inline.
  115. // may be able to tidy this up after switching to VC7
  116. FORCEINLINE vec_t DistToSqr(const Vector &vOther) const
  117. {
  118. Vector delta;
  119. delta.x = x - vOther.x;
  120. delta.y = y - vOther.y;
  121. delta.z = z - vOther.z;
  122. return delta.LengthSqr();
  123. }
  124. // Copy
  125. void CopyToArray(float* rgfl) const;
  126. // Multiply, add, and assign to this (ie: *this = a + b * scalar). This
  127. // is about 12% faster than the actual vector equation (because it's done per-component
  128. // rather than per-vector).
  129. void MulAdd(const Vector& a, const Vector& b, float scalar);
  130. // Dot product.
  131. vec_t Dot(const Vector& vOther) const;
  132. // assignment
  133. Vector& operator=(const Vector &vOther);
  134. // 2d
  135. vec_t Length2D(void) const;
  136. vec_t Length2DSqr(void) const;
  137. operator VectorByValue &() { return *((VectorByValue *)(this)); }
  138. operator const VectorByValue &() const { return *((const VectorByValue *)(this)); }
  139. #ifndef VECTOR_NO_SLOW_OPERATIONS
  140. // copy constructors
  141. // Vector(const Vector &vOther);
  142. // arithmetic operations
  143. Vector operator-(void) const;
  144. Vector operator+(const Vector& v) const;
  145. Vector operator-(const Vector& v) const;
  146. Vector operator*(const Vector& v) const;
  147. Vector operator/(const Vector& v) const;
  148. Vector operator*(float fl) const;
  149. Vector operator/(float fl) const;
  150. // Cross product between two vectors.
  151. Vector Cross(const Vector &vOther) const;
  152. // Returns a vector with the min or max in X, Y, and Z.
  153. Vector Min(const Vector &vOther) const;
  154. Vector Max(const Vector &vOther) const;
  155. #else
  156. private:
  157. // No copy constructors allowed if we're in optimal mode
  158. Vector(const Vector& vOther);
  159. #endif
  160. };
  161. FORCEINLINE void NetworkVarConstruct( Vector &v ) { v.Zero(); }
  162. #define USE_M64S ( ( !defined( _X360 ) ) )
  163. //=========================================================
  164. // 4D Short Vector (aligned on 8-byte boundary)
  165. //=========================================================
  166. class ALIGN8 ShortVector
  167. {
  168. public:
  169. short x, y, z, w;
  170. // Initialization
  171. void Init(short ix = 0, short iy = 0, short iz = 0, short iw = 0 );
  172. #ifdef USE_M64S
  173. __m64 &AsM64() { return *(__m64*)&x; }
  174. const __m64 &AsM64() const { return *(const __m64*)&x; }
  175. #endif
  176. // Setter
  177. void Set( const ShortVector& vOther );
  178. void Set( const short ix, const short iy, const short iz, const short iw );
  179. // array access...
  180. short operator[](int i) const;
  181. short& operator[](int i);
  182. // Base address...
  183. short* Base();
  184. short const* Base() const;
  185. // equality
  186. bool operator==(const ShortVector& v) const;
  187. bool operator!=(const ShortVector& v) const;
  188. // Arithmetic operations
  189. FORCEINLINE ShortVector& operator+=(const ShortVector &v);
  190. FORCEINLINE ShortVector& operator-=(const ShortVector &v);
  191. FORCEINLINE ShortVector& operator*=(const ShortVector &v);
  192. FORCEINLINE ShortVector& operator*=(float s);
  193. FORCEINLINE ShortVector& operator/=(const ShortVector &v);
  194. FORCEINLINE ShortVector& operator/=(float s);
  195. FORCEINLINE ShortVector operator*(float fl) const;
  196. private:
  197. // No copy constructors allowed if we're in optimal mode
  198. // ShortVector(ShortVector const& vOther);
  199. // No assignment operators either...
  200. // ShortVector& operator=( ShortVector const& src );
  201. } ALIGN8_POST;
  202. //=========================================================
  203. // 4D Integer Vector
  204. //=========================================================
  205. class IntVector4D
  206. {
  207. public:
  208. int x, y, z, w;
  209. // Initialization
  210. void Init(int ix = 0, int iy = 0, int iz = 0, int iw = 0 );
  211. #ifdef USE_M64S
  212. __m64 &AsM64() { return *(__m64*)&x; }
  213. const __m64 &AsM64() const { return *(const __m64*)&x; }
  214. #endif
  215. // Setter
  216. void Set( const IntVector4D& vOther );
  217. void Set( const int ix, const int iy, const int iz, const int iw );
  218. // array access...
  219. int operator[](int i) const;
  220. int& operator[](int i);
  221. // Base address...
  222. int* Base();
  223. int const* Base() const;
  224. // equality
  225. bool operator==(const IntVector4D& v) const;
  226. bool operator!=(const IntVector4D& v) const;
  227. // Arithmetic operations
  228. FORCEINLINE IntVector4D& operator+=(const IntVector4D &v);
  229. FORCEINLINE IntVector4D& operator-=(const IntVector4D &v);
  230. FORCEINLINE IntVector4D& operator*=(const IntVector4D &v);
  231. FORCEINLINE IntVector4D& operator*=(float s);
  232. FORCEINLINE IntVector4D& operator/=(const IntVector4D &v);
  233. FORCEINLINE IntVector4D& operator/=(float s);
  234. FORCEINLINE IntVector4D operator*(float fl) const;
  235. private:
  236. // No copy constructors allowed if we're in optimal mode
  237. // IntVector4D(IntVector4D const& vOther);
  238. // No assignment operators either...
  239. // IntVector4D& operator=( IntVector4D const& src );
  240. };
  241. //-----------------------------------------------------------------------------
  242. // Allows us to specifically pass the vector by value when we need to
  243. //-----------------------------------------------------------------------------
  244. class VectorByValue : public Vector
  245. {
  246. public:
  247. // Construction/destruction:
  248. VectorByValue(void) : Vector() {}
  249. VectorByValue(vec_t X, vec_t Y, vec_t Z) : Vector( X, Y, Z ) {}
  250. VectorByValue(const VectorByValue& vOther) { *this = vOther; }
  251. };
  252. //-----------------------------------------------------------------------------
  253. // Utility to simplify table construction. No constructor means can use
  254. // traditional C-style initialization
  255. //-----------------------------------------------------------------------------
  256. class TableVector
  257. {
  258. public:
  259. vec_t x, y, z;
  260. operator Vector &() { return *((Vector *)(this)); }
  261. operator const Vector &() const { return *((const Vector *)(this)); }
  262. // array access...
  263. inline vec_t& operator[](int i)
  264. {
  265. Assert( (i >= 0) && (i < 3) );
  266. return ((vec_t*)this)[i];
  267. }
  268. inline vec_t operator[](int i) const
  269. {
  270. Assert( (i >= 0) && (i < 3) );
  271. return ((vec_t*)this)[i];
  272. }
  273. };
  274. //-----------------------------------------------------------------------------
  275. // Here's where we add all those lovely SSE optimized routines
  276. //-----------------------------------------------------------------------------
  277. class ALIGN16 VectorAligned : public Vector
  278. {
  279. public:
  280. inline VectorAligned(void) {};
  281. inline VectorAligned(vec_t X, vec_t Y, vec_t Z)
  282. {
  283. Init(X,Y,Z);
  284. }
  285. #ifdef VECTOR_NO_SLOW_OPERATIONS
  286. private:
  287. // No copy constructors allowed if we're in optimal mode
  288. VectorAligned(const VectorAligned& vOther);
  289. VectorAligned(const Vector &vOther);
  290. #else
  291. public:
  292. explicit VectorAligned(const Vector &vOther)
  293. {
  294. Init(vOther.x, vOther.y, vOther.z);
  295. }
  296. VectorAligned& operator=(const Vector &vOther)
  297. {
  298. Init(vOther.x, vOther.y, vOther.z);
  299. return *this;
  300. }
  301. #endif
  302. float w; // this space is used anyway
  303. } ALIGN16_POST;
  304. //-----------------------------------------------------------------------------
  305. // Vector related operations
  306. //-----------------------------------------------------------------------------
  307. // Vector clear
  308. FORCEINLINE void VectorClear( Vector& a );
  309. // Copy
  310. FORCEINLINE void VectorCopy( const Vector& src, Vector& dst );
  311. // Vector arithmetic
  312. FORCEINLINE void VectorAdd( const Vector& a, const Vector& b, Vector& result );
  313. FORCEINLINE void VectorSubtract( const Vector& a, const Vector& b, Vector& result );
  314. FORCEINLINE void VectorMultiply( const Vector& a, vec_t b, Vector& result );
  315. FORCEINLINE void VectorMultiply( const Vector& a, const Vector& b, Vector& result );
  316. FORCEINLINE void VectorDivide( const Vector& a, vec_t b, Vector& result );
  317. FORCEINLINE void VectorDivide( const Vector& a, const Vector& b, Vector& result );
  318. inline void VectorScale ( const Vector& in, vec_t scale, Vector& result );
  319. // Don't mark this as inline in its function declaration. That's only necessary on its
  320. // definition, and 'inline' here leads to gcc warnings.
  321. void VectorMA( const Vector& start, float scale, const Vector& direction, Vector& dest );
  322. // Vector equality with tolerance
  323. bool VectorsAreEqual( const Vector& src1, const Vector& src2, float tolerance = 0.0f );
  324. #define VectorExpand(v) (v).x, (v).y, (v).z
  325. // Normalization
  326. // FIXME: Can't use quite yet
  327. //vec_t VectorNormalize( Vector& v );
  328. // Length
  329. inline vec_t VectorLength( const Vector& v );
  330. // Dot Product
  331. FORCEINLINE vec_t DotProduct(const Vector& a, const Vector& b);
  332. // Cross product
  333. void CrossProduct(const Vector& a, const Vector& b, Vector& result );
  334. // Store the min or max of each of x, y, and z into the result.
  335. void VectorMin( const Vector &a, const Vector &b, Vector &result );
  336. void VectorMax( const Vector &a, const Vector &b, Vector &result );
  337. // Linearly interpolate between two vectors
  338. void VectorLerp(const Vector& src1, const Vector& src2, vec_t t, Vector& dest );
  339. Vector VectorLerp(const Vector& src1, const Vector& src2, vec_t t );
  340. FORCEINLINE Vector ReplicateToVector( float x )
  341. {
  342. return Vector( x, x, x );
  343. }
  344. // check if a point is in the field of a view of an object. supports up to 180 degree fov.
  345. FORCEINLINE bool PointWithinViewAngle( Vector const &vecSrcPosition,
  346. Vector const &vecTargetPosition,
  347. Vector const &vecLookDirection, float flCosHalfFOV )
  348. {
  349. Vector vecDelta = vecTargetPosition - vecSrcPosition;
  350. float cosDiff = DotProduct( vecLookDirection, vecDelta );
  351. if ( cosDiff < 0 )
  352. return false;
  353. float flLen2 = vecDelta.LengthSqr();
  354. // a/sqrt(b) > c == a^2 > b * c ^2
  355. return ( cosDiff * cosDiff > flLen2 * flCosHalfFOV * flCosHalfFOV );
  356. }
  357. #ifndef VECTOR_NO_SLOW_OPERATIONS
  358. // Cross product
  359. Vector CrossProduct( const Vector& a, const Vector& b );
  360. // Random vector creation
  361. Vector RandomVector( vec_t minVal, vec_t maxVal );
  362. #endif
  363. float RandomVectorInUnitSphere( Vector *pVector );
  364. float RandomVectorInUnitCircle( Vector2D *pVector );
  365. //-----------------------------------------------------------------------------
  366. //
  367. // Inlined Vector methods
  368. //
  369. //-----------------------------------------------------------------------------
  370. //-----------------------------------------------------------------------------
  371. // constructors
  372. //-----------------------------------------------------------------------------
  373. inline Vector::Vector(void)
  374. {
  375. #ifdef _DEBUG
  376. #ifdef VECTOR_PARANOIA
  377. // Initialize to NAN to catch errors
  378. x = y = z = VEC_T_NAN;
  379. #endif
  380. #endif
  381. }
  382. inline Vector::Vector(vec_t X, vec_t Y, vec_t Z)
  383. {
  384. x = X; y = Y; z = Z;
  385. CHECK_VALID(*this);
  386. }
  387. inline Vector::Vector(vec_t XYZ)
  388. {
  389. x = y = z = XYZ;
  390. CHECK_VALID(*this);
  391. }
  392. //inline Vector::Vector(const float *pFloat)
  393. //{
  394. // Assert( pFloat );
  395. // x = pFloat[0]; y = pFloat[1]; z = pFloat[2];
  396. // CHECK_VALID(*this);
  397. //}
  398. #if 0
  399. //-----------------------------------------------------------------------------
  400. // copy constructor
  401. //-----------------------------------------------------------------------------
  402. inline Vector::Vector(const Vector &vOther)
  403. {
  404. CHECK_VALID(vOther);
  405. x = vOther.x; y = vOther.y; z = vOther.z;
  406. }
  407. #endif
  408. //-----------------------------------------------------------------------------
  409. // initialization
  410. //-----------------------------------------------------------------------------
  411. inline void Vector::Init( vec_t ix, vec_t iy, vec_t iz )
  412. {
  413. x = ix; y = iy; z = iz;
  414. CHECK_VALID(*this);
  415. }
  416. inline void Vector::Random( vec_t minVal, vec_t maxVal )
  417. {
  418. x = minVal + ((float)rand() / VALVE_RAND_MAX) * (maxVal - minVal);
  419. y = minVal + ((float)rand() / VALVE_RAND_MAX) * (maxVal - minVal);
  420. z = minVal + ((float)rand() / VALVE_RAND_MAX) * (maxVal - minVal);
  421. CHECK_VALID(*this);
  422. }
  423. // This should really be a single opcode on the PowerPC (move r0 onto the vec reg)
  424. inline void Vector::Zero()
  425. {
  426. x = y = z = 0.0f;
  427. }
  428. inline void VectorClear( Vector& a )
  429. {
  430. a.x = a.y = a.z = 0.0f;
  431. }
  432. //-----------------------------------------------------------------------------
  433. // assignment
  434. //-----------------------------------------------------------------------------
  435. inline Vector& Vector::operator=(const Vector &vOther)
  436. {
  437. CHECK_VALID(vOther);
  438. x=vOther.x; y=vOther.y; z=vOther.z;
  439. return *this;
  440. }
  441. //-----------------------------------------------------------------------------
  442. // Array access
  443. //-----------------------------------------------------------------------------
  444. inline vec_t& Vector::operator[](int i)
  445. {
  446. Assert( (i >= 0) && (i < 3) );
  447. return ((vec_t*)this)[i];
  448. }
  449. inline vec_t Vector::operator[](int i) const
  450. {
  451. Assert( (i >= 0) && (i < 3) );
  452. return ((vec_t*)this)[i];
  453. }
  454. //-----------------------------------------------------------------------------
  455. // Base address...
  456. //-----------------------------------------------------------------------------
  457. inline vec_t* Vector::Base()
  458. {
  459. return (vec_t*)this;
  460. }
  461. inline vec_t const* Vector::Base() const
  462. {
  463. return (vec_t const*)this;
  464. }
  465. //-----------------------------------------------------------------------------
  466. // Cast to Vector2D...
  467. //-----------------------------------------------------------------------------
  468. inline Vector2D& Vector::AsVector2D()
  469. {
  470. return *(Vector2D*)this;
  471. }
  472. inline const Vector2D& Vector::AsVector2D() const
  473. {
  474. return *(const Vector2D*)this;
  475. }
  476. //-----------------------------------------------------------------------------
  477. // IsValid?
  478. //-----------------------------------------------------------------------------
  479. inline bool Vector::IsValid() const
  480. {
  481. return IsFinite(x) && IsFinite(y) && IsFinite(z);
  482. }
  483. //-----------------------------------------------------------------------------
  484. // Invalidate
  485. //-----------------------------------------------------------------------------
  486. inline void Vector::Invalidate()
  487. {
  488. //#ifdef _DEBUG
  489. //#ifdef VECTOR_PARANOIA
  490. x = y = z = VEC_T_NAN;
  491. //#endif
  492. //#endif
  493. }
  494. //-----------------------------------------------------------------------------
  495. // comparison
  496. //-----------------------------------------------------------------------------
  497. inline bool Vector::operator==( const Vector& src ) const
  498. {
  499. CHECK_VALID(src);
  500. CHECK_VALID(*this);
  501. return (src.x == x) && (src.y == y) && (src.z == z);
  502. }
  503. inline bool Vector::operator!=( const Vector& src ) const
  504. {
  505. CHECK_VALID(src);
  506. CHECK_VALID(*this);
  507. return (src.x != x) || (src.y != y) || (src.z != z);
  508. }
  509. //-----------------------------------------------------------------------------
  510. // Copy
  511. //-----------------------------------------------------------------------------
  512. FORCEINLINE void VectorCopy( const Vector& src, Vector& dst )
  513. {
  514. CHECK_VALID(src);
  515. dst.x = src.x;
  516. dst.y = src.y;
  517. dst.z = src.z;
  518. }
  519. inline void Vector::CopyToArray(float* rgfl) const
  520. {
  521. Assert( rgfl );
  522. CHECK_VALID(*this);
  523. rgfl[0] = x, rgfl[1] = y, rgfl[2] = z;
  524. }
  525. //-----------------------------------------------------------------------------
  526. // standard math operations
  527. //-----------------------------------------------------------------------------
  528. // #pragma message("TODO: these should be SSE")
  529. inline void Vector::Negate()
  530. {
  531. CHECK_VALID(*this);
  532. x = -x; y = -y; z = -z;
  533. }
  534. FORCEINLINE Vector& Vector::operator+=(const Vector& v)
  535. {
  536. CHECK_VALID(*this);
  537. CHECK_VALID(v);
  538. x+=v.x; y+=v.y; z += v.z;
  539. return *this;
  540. }
  541. FORCEINLINE Vector& Vector::operator-=(const Vector& v)
  542. {
  543. CHECK_VALID(*this);
  544. CHECK_VALID(v);
  545. x-=v.x; y-=v.y; z -= v.z;
  546. return *this;
  547. }
  548. FORCEINLINE Vector& Vector::operator*=(float fl)
  549. {
  550. x *= fl;
  551. y *= fl;
  552. z *= fl;
  553. CHECK_VALID(*this);
  554. return *this;
  555. }
  556. FORCEINLINE Vector& Vector::operator*=(const Vector& v)
  557. {
  558. CHECK_VALID(v);
  559. x *= v.x;
  560. y *= v.y;
  561. z *= v.z;
  562. CHECK_VALID(*this);
  563. return *this;
  564. }
  565. // this ought to be an opcode.
  566. FORCEINLINE Vector& Vector::operator+=(float fl)
  567. {
  568. x += fl;
  569. y += fl;
  570. z += fl;
  571. CHECK_VALID(*this);
  572. return *this;
  573. }
  574. FORCEINLINE Vector& Vector::operator-=(float fl)
  575. {
  576. x -= fl;
  577. y -= fl;
  578. z -= fl;
  579. CHECK_VALID(*this);
  580. return *this;
  581. }
  582. FORCEINLINE Vector& Vector::operator/=(float fl)
  583. {
  584. Assert( fl != 0.0f );
  585. float oofl = 1.0f / fl;
  586. x *= oofl;
  587. y *= oofl;
  588. z *= oofl;
  589. CHECK_VALID(*this);
  590. return *this;
  591. }
  592. FORCEINLINE Vector& Vector::operator/=(const Vector& v)
  593. {
  594. CHECK_VALID(v);
  595. Assert( v.x != 0.0f && v.y != 0.0f && v.z != 0.0f );
  596. x /= v.x;
  597. y /= v.y;
  598. z /= v.z;
  599. CHECK_VALID(*this);
  600. return *this;
  601. }
  602. //-----------------------------------------------------------------------------
  603. //
  604. // Inlined Short Vector methods
  605. //
  606. //-----------------------------------------------------------------------------
  607. inline void ShortVector::Init( short ix, short iy, short iz, short iw )
  608. {
  609. x = ix; y = iy; z = iz; w = iw;
  610. }
  611. FORCEINLINE void ShortVector::Set( const ShortVector& vOther )
  612. {
  613. x = vOther.x;
  614. y = vOther.y;
  615. z = vOther.z;
  616. w = vOther.w;
  617. }
  618. FORCEINLINE void ShortVector::Set( const short ix, const short iy, const short iz, const short iw )
  619. {
  620. x = ix;
  621. y = iy;
  622. z = iz;
  623. w = iw;
  624. }
  625. //-----------------------------------------------------------------------------
  626. // Array access
  627. //-----------------------------------------------------------------------------
  628. inline short ShortVector::operator[](int i) const
  629. {
  630. Assert( (i >= 0) && (i < 4) );
  631. return ((short*)this)[i];
  632. }
  633. inline short& ShortVector::operator[](int i)
  634. {
  635. Assert( (i >= 0) && (i < 4) );
  636. return ((short*)this)[i];
  637. }
  638. //-----------------------------------------------------------------------------
  639. // Base address...
  640. //-----------------------------------------------------------------------------
  641. inline short* ShortVector::Base()
  642. {
  643. return (short*)this;
  644. }
  645. inline short const* ShortVector::Base() const
  646. {
  647. return (short const*)this;
  648. }
  649. //-----------------------------------------------------------------------------
  650. // comparison
  651. //-----------------------------------------------------------------------------
  652. inline bool ShortVector::operator==( const ShortVector& src ) const
  653. {
  654. return (src.x == x) && (src.y == y) && (src.z == z) && (src.w == w);
  655. }
  656. inline bool ShortVector::operator!=( const ShortVector& src ) const
  657. {
  658. return (src.x != x) || (src.y != y) || (src.z != z) || (src.w != w);
  659. }
  660. //-----------------------------------------------------------------------------
  661. // standard math operations
  662. //-----------------------------------------------------------------------------
  663. FORCEINLINE ShortVector& ShortVector::operator+=(const ShortVector& v)
  664. {
  665. x+=v.x; y+=v.y; z += v.z; w += v.w;
  666. return *this;
  667. }
  668. FORCEINLINE ShortVector& ShortVector::operator-=(const ShortVector& v)
  669. {
  670. x-=v.x; y-=v.y; z -= v.z; w -= v.w;
  671. return *this;
  672. }
  673. FORCEINLINE ShortVector& ShortVector::operator*=(float fl)
  674. {
  675. x *= fl;
  676. y *= fl;
  677. z *= fl;
  678. w *= fl;
  679. return *this;
  680. }
  681. FORCEINLINE ShortVector& ShortVector::operator*=(const ShortVector& v)
  682. {
  683. x *= v.x;
  684. y *= v.y;
  685. z *= v.z;
  686. w *= v.w;
  687. return *this;
  688. }
  689. FORCEINLINE ShortVector& ShortVector::operator/=(float fl)
  690. {
  691. Assert( fl != 0.0f );
  692. float oofl = 1.0f / fl;
  693. x *= oofl;
  694. y *= oofl;
  695. z *= oofl;
  696. w *= oofl;
  697. return *this;
  698. }
  699. FORCEINLINE ShortVector& ShortVector::operator/=(const ShortVector& v)
  700. {
  701. Assert( v.x != 0 && v.y != 0 && v.z != 0 && v.w != 0 );
  702. x /= v.x;
  703. y /= v.y;
  704. z /= v.z;
  705. w /= v.w;
  706. return *this;
  707. }
  708. FORCEINLINE void ShortVectorMultiply( const ShortVector& src, float fl, ShortVector& res )
  709. {
  710. Assert( IsFinite(fl) );
  711. res.x = src.x * fl;
  712. res.y = src.y * fl;
  713. res.z = src.z * fl;
  714. res.w = src.w * fl;
  715. }
  716. FORCEINLINE ShortVector ShortVector::operator*(float fl) const
  717. {
  718. ShortVector res;
  719. ShortVectorMultiply( *this, fl, res );
  720. return res;
  721. }
  722. //-----------------------------------------------------------------------------
  723. //
  724. // Inlined Integer Vector methods
  725. //
  726. //-----------------------------------------------------------------------------
  727. inline void IntVector4D::Init( int ix, int iy, int iz, int iw )
  728. {
  729. x = ix; y = iy; z = iz; w = iw;
  730. }
  731. FORCEINLINE void IntVector4D::Set( const IntVector4D& vOther )
  732. {
  733. x = vOther.x;
  734. y = vOther.y;
  735. z = vOther.z;
  736. w = vOther.w;
  737. }
  738. FORCEINLINE void IntVector4D::Set( const int ix, const int iy, const int iz, const int iw )
  739. {
  740. x = ix;
  741. y = iy;
  742. z = iz;
  743. w = iw;
  744. }
  745. //-----------------------------------------------------------------------------
  746. // Array access
  747. //-----------------------------------------------------------------------------
  748. inline int IntVector4D::operator[](int i) const
  749. {
  750. Assert( (i >= 0) && (i < 4) );
  751. return ((int*)this)[i];
  752. }
  753. inline int& IntVector4D::operator[](int i)
  754. {
  755. Assert( (i >= 0) && (i < 4) );
  756. return ((int*)this)[i];
  757. }
  758. //-----------------------------------------------------------------------------
  759. // Base address...
  760. //-----------------------------------------------------------------------------
  761. inline int* IntVector4D::Base()
  762. {
  763. return (int*)this;
  764. }
  765. inline int const* IntVector4D::Base() const
  766. {
  767. return (int const*)this;
  768. }
  769. //-----------------------------------------------------------------------------
  770. // comparison
  771. //-----------------------------------------------------------------------------
  772. inline bool IntVector4D::operator==( const IntVector4D& src ) const
  773. {
  774. return (src.x == x) && (src.y == y) && (src.z == z) && (src.w == w);
  775. }
  776. inline bool IntVector4D::operator!=( const IntVector4D& src ) const
  777. {
  778. return (src.x != x) || (src.y != y) || (src.z != z) || (src.w != w);
  779. }
  780. //-----------------------------------------------------------------------------
  781. // standard math operations
  782. //-----------------------------------------------------------------------------
  783. FORCEINLINE IntVector4D& IntVector4D::operator+=(const IntVector4D& v)
  784. {
  785. x+=v.x; y+=v.y; z += v.z; w += v.w;
  786. return *this;
  787. }
  788. FORCEINLINE IntVector4D& IntVector4D::operator-=(const IntVector4D& v)
  789. {
  790. x-=v.x; y-=v.y; z -= v.z; w -= v.w;
  791. return *this;
  792. }
  793. FORCEINLINE IntVector4D& IntVector4D::operator*=(float fl)
  794. {
  795. x *= fl;
  796. y *= fl;
  797. z *= fl;
  798. w *= fl;
  799. return *this;
  800. }
  801. FORCEINLINE IntVector4D& IntVector4D::operator*=(const IntVector4D& v)
  802. {
  803. x *= v.x;
  804. y *= v.y;
  805. z *= v.z;
  806. w *= v.w;
  807. return *this;
  808. }
  809. FORCEINLINE IntVector4D& IntVector4D::operator/=(float fl)
  810. {
  811. Assert( fl != 0.0f );
  812. float oofl = 1.0f / fl;
  813. x *= oofl;
  814. y *= oofl;
  815. z *= oofl;
  816. w *= oofl;
  817. return *this;
  818. }
  819. FORCEINLINE IntVector4D& IntVector4D::operator/=(const IntVector4D& v)
  820. {
  821. Assert( v.x != 0 && v.y != 0 && v.z != 0 && v.w != 0 );
  822. x /= v.x;
  823. y /= v.y;
  824. z /= v.z;
  825. w /= v.w;
  826. return *this;
  827. }
  828. FORCEINLINE void IntVector4DMultiply( const IntVector4D& src, float fl, IntVector4D& res )
  829. {
  830. Assert( IsFinite(fl) );
  831. res.x = src.x * fl;
  832. res.y = src.y * fl;
  833. res.z = src.z * fl;
  834. res.w = src.w * fl;
  835. }
  836. FORCEINLINE IntVector4D IntVector4D::operator*(float fl) const
  837. {
  838. IntVector4D res;
  839. IntVector4DMultiply( *this, fl, res );
  840. return res;
  841. }
  842. // =======================
  843. FORCEINLINE void VectorAdd( const Vector& a, const Vector& b, Vector& c )
  844. {
  845. CHECK_VALID(a);
  846. CHECK_VALID(b);
  847. c.x = a.x + b.x;
  848. c.y = a.y + b.y;
  849. c.z = a.z + b.z;
  850. }
  851. FORCEINLINE void VectorSubtract( const Vector& a, const Vector& b, Vector& c )
  852. {
  853. CHECK_VALID(a);
  854. CHECK_VALID(b);
  855. c.x = a.x - b.x;
  856. c.y = a.y - b.y;
  857. c.z = a.z - b.z;
  858. }
  859. FORCEINLINE void VectorMultiply( const Vector& a, vec_t b, Vector& c )
  860. {
  861. CHECK_VALID(a);
  862. Assert( IsFinite(b) );
  863. c.x = a.x * b;
  864. c.y = a.y * b;
  865. c.z = a.z * b;
  866. }
  867. FORCEINLINE void VectorMultiply( const Vector& a, const Vector& b, Vector& c )
  868. {
  869. CHECK_VALID(a);
  870. CHECK_VALID(b);
  871. c.x = a.x * b.x;
  872. c.y = a.y * b.y;
  873. c.z = a.z * b.z;
  874. }
  875. // for backwards compatability
  876. inline void VectorScale ( const Vector& in, vec_t scale, Vector& result )
  877. {
  878. VectorMultiply( in, scale, result );
  879. }
  880. FORCEINLINE void VectorDivide( const Vector& a, vec_t b, Vector& c )
  881. {
  882. CHECK_VALID(a);
  883. Assert( b != 0.0f );
  884. vec_t oob = 1.0f / b;
  885. c.x = a.x * oob;
  886. c.y = a.y * oob;
  887. c.z = a.z * oob;
  888. }
  889. FORCEINLINE void VectorDivide( const Vector& a, const Vector& b, Vector& c )
  890. {
  891. CHECK_VALID(a);
  892. CHECK_VALID(b);
  893. Assert( (b.x != 0.0f) && (b.y != 0.0f) && (b.z != 0.0f) );
  894. c.x = a.x / b.x;
  895. c.y = a.y / b.y;
  896. c.z = a.z / b.z;
  897. }
  898. // FIXME: Remove
  899. // For backwards compatability
  900. inline void Vector::MulAdd(const Vector& a, const Vector& b, float scalar)
  901. {
  902. CHECK_VALID(a);
  903. CHECK_VALID(b);
  904. x = a.x + b.x * scalar;
  905. y = a.y + b.y * scalar;
  906. z = a.z + b.z * scalar;
  907. }
  908. inline void VectorLerp(const Vector& src1, const Vector& src2, vec_t t, Vector& dest )
  909. {
  910. CHECK_VALID(src1);
  911. CHECK_VALID(src2);
  912. dest.x = src1.x + (src2.x - src1.x) * t;
  913. dest.y = src1.y + (src2.y - src1.y) * t;
  914. dest.z = src1.z + (src2.z - src1.z) * t;
  915. }
  916. inline Vector VectorLerp(const Vector& src1, const Vector& src2, vec_t t )
  917. {
  918. Vector result;
  919. VectorLerp( src1, src2, t, result );
  920. return result;
  921. }
  922. //-----------------------------------------------------------------------------
  923. // Temporary storage for vector results so const Vector& results can be returned
  924. //-----------------------------------------------------------------------------
  925. inline Vector &AllocTempVector()
  926. {
  927. static Vector s_vecTemp[128];
  928. static CInterlockedInt s_nIndex;
  929. int nIndex;
  930. for (;;)
  931. {
  932. int nOldIndex = s_nIndex;
  933. nIndex = ( (nOldIndex + 0x10001) & 0x7F );
  934. if ( s_nIndex.AssignIf( nOldIndex, nIndex ) )
  935. {
  936. break;
  937. }
  938. ThreadPause();
  939. }
  940. return s_vecTemp[nIndex];
  941. }
  942. //-----------------------------------------------------------------------------
  943. // dot, cross
  944. //-----------------------------------------------------------------------------
  945. FORCEINLINE vec_t DotProduct(const Vector& a, const Vector& b)
  946. {
  947. CHECK_VALID(a);
  948. CHECK_VALID(b);
  949. return( a.x*b.x + a.y*b.y + a.z*b.z );
  950. }
  951. // for backwards compatability
  952. inline vec_t Vector::Dot( const Vector& vOther ) const
  953. {
  954. CHECK_VALID(vOther);
  955. return DotProduct( *this, vOther );
  956. }
  957. inline void CrossProduct(const Vector& a, const Vector& b, Vector& result )
  958. {
  959. CHECK_VALID(a);
  960. CHECK_VALID(b);
  961. Assert( &a != &result );
  962. Assert( &b != &result );
  963. result.x = a.y*b.z - a.z*b.y;
  964. result.y = a.z*b.x - a.x*b.z;
  965. result.z = a.x*b.y - a.y*b.x;
  966. }
  967. inline vec_t DotProductAbs( const Vector &v0, const Vector &v1 )
  968. {
  969. CHECK_VALID(v0);
  970. CHECK_VALID(v1);
  971. return FloatMakePositive(v0.x*v1.x) + FloatMakePositive(v0.y*v1.y) + FloatMakePositive(v0.z*v1.z);
  972. }
  973. inline vec_t DotProductAbs( const Vector &v0, const float *v1 )
  974. {
  975. return FloatMakePositive(v0.x * v1[0]) + FloatMakePositive(v0.y * v1[1]) + FloatMakePositive(v0.z * v1[2]);
  976. }
  977. //-----------------------------------------------------------------------------
  978. // length
  979. //-----------------------------------------------------------------------------
  980. inline vec_t VectorLength( const Vector& v )
  981. {
  982. CHECK_VALID(v);
  983. return (vec_t)FastSqrt(v.x*v.x + v.y*v.y + v.z*v.z);
  984. }
  985. inline vec_t Vector::Length(void) const
  986. {
  987. CHECK_VALID(*this);
  988. return VectorLength( *this );
  989. }
  990. //-----------------------------------------------------------------------------
  991. // Normalization
  992. //-----------------------------------------------------------------------------
  993. /*
  994. // FIXME: Can't use until we're un-macroed in mathlib.h
  995. inline vec_t VectorNormalize( Vector& v )
  996. {
  997. Assert( v.IsValid() );
  998. vec_t l = v.Length();
  999. if (l != 0.0f)
  1000. {
  1001. v /= l;
  1002. }
  1003. else
  1004. {
  1005. // FIXME:
  1006. // Just copying the existing implemenation; shouldn't res.z == 0?
  1007. v.x = v.y = 0.0f; v.z = 1.0f;
  1008. }
  1009. return l;
  1010. }
  1011. */
  1012. // check a point against a box
  1013. bool Vector::WithinAABox( Vector const &boxmin, Vector const &boxmax)
  1014. {
  1015. return (
  1016. ( x >= boxmin.x ) && ( x <= boxmax.x) &&
  1017. ( y >= boxmin.y ) && ( y <= boxmax.y) &&
  1018. ( z >= boxmin.z ) && ( z <= boxmax.z)
  1019. );
  1020. }
  1021. //-----------------------------------------------------------------------------
  1022. // Get the distance from this vector to the other one
  1023. //-----------------------------------------------------------------------------
  1024. inline vec_t Vector::DistTo(const Vector &vOther) const
  1025. {
  1026. Vector delta;
  1027. VectorSubtract( *this, vOther, delta );
  1028. return delta.Length();
  1029. }
  1030. //-----------------------------------------------------------------------------
  1031. // Vector equality with tolerance
  1032. //-----------------------------------------------------------------------------
  1033. inline bool VectorsAreEqual( const Vector& src1, const Vector& src2, float tolerance )
  1034. {
  1035. if (FloatMakePositive(src1.x - src2.x) > tolerance)
  1036. return false;
  1037. if (FloatMakePositive(src1.y - src2.y) > tolerance)
  1038. return false;
  1039. return (FloatMakePositive(src1.z - src2.z) <= tolerance);
  1040. }
  1041. //-----------------------------------------------------------------------------
  1042. // Computes the closest point to vecTarget no farther than flMaxDist from vecStart
  1043. //-----------------------------------------------------------------------------
  1044. inline void ComputeClosestPoint( const Vector& vecStart, float flMaxDist, const Vector& vecTarget, Vector *pResult )
  1045. {
  1046. Vector vecDelta;
  1047. VectorSubtract( vecTarget, vecStart, vecDelta );
  1048. float flDistSqr = vecDelta.LengthSqr();
  1049. if ( flDistSqr <= flMaxDist * flMaxDist )
  1050. {
  1051. *pResult = vecTarget;
  1052. }
  1053. else
  1054. {
  1055. vecDelta /= FastSqrt( flDistSqr );
  1056. VectorMA( vecStart, flMaxDist, vecDelta, *pResult );
  1057. }
  1058. }
  1059. //-----------------------------------------------------------------------------
  1060. // Takes the absolute value of a vector
  1061. //-----------------------------------------------------------------------------
  1062. inline void VectorAbs( const Vector& src, Vector& dst )
  1063. {
  1064. dst.x = FloatMakePositive(src.x);
  1065. dst.y = FloatMakePositive(src.y);
  1066. dst.z = FloatMakePositive(src.z);
  1067. }
  1068. //-----------------------------------------------------------------------------
  1069. //
  1070. // Slow methods
  1071. //
  1072. //-----------------------------------------------------------------------------
  1073. #ifndef VECTOR_NO_SLOW_OPERATIONS
  1074. //-----------------------------------------------------------------------------
  1075. // Returns a vector with the min or max in X, Y, and Z.
  1076. //-----------------------------------------------------------------------------
  1077. inline Vector Vector::Min(const Vector &vOther) const
  1078. {
  1079. return Vector(x < vOther.x ? x : vOther.x,
  1080. y < vOther.y ? y : vOther.y,
  1081. z < vOther.z ? z : vOther.z);
  1082. }
  1083. inline Vector Vector::Max(const Vector &vOther) const
  1084. {
  1085. return Vector(x > vOther.x ? x : vOther.x,
  1086. y > vOther.y ? y : vOther.y,
  1087. z > vOther.z ? z : vOther.z);
  1088. }
  1089. //-----------------------------------------------------------------------------
  1090. // arithmetic operations
  1091. //-----------------------------------------------------------------------------
  1092. inline Vector Vector::operator-(void) const
  1093. {
  1094. return Vector(-x,-y,-z);
  1095. }
  1096. inline Vector Vector::operator+(const Vector& v) const
  1097. {
  1098. Vector res;
  1099. VectorAdd( *this, v, res );
  1100. return res;
  1101. }
  1102. inline Vector Vector::operator-(const Vector& v) const
  1103. {
  1104. Vector res;
  1105. VectorSubtract( *this, v, res );
  1106. return res;
  1107. }
  1108. inline Vector Vector::operator*(float fl) const
  1109. {
  1110. Vector res;
  1111. VectorMultiply( *this, fl, res );
  1112. return res;
  1113. }
  1114. inline Vector Vector::operator*(const Vector& v) const
  1115. {
  1116. Vector res;
  1117. VectorMultiply( *this, v, res );
  1118. return res;
  1119. }
  1120. inline Vector Vector::operator/(float fl) const
  1121. {
  1122. Vector res;
  1123. VectorDivide( *this, fl, res );
  1124. return res;
  1125. }
  1126. inline Vector Vector::operator/(const Vector& v) const
  1127. {
  1128. Vector res;
  1129. VectorDivide( *this, v, res );
  1130. return res;
  1131. }
  1132. inline Vector operator*(float fl, const Vector& v)
  1133. {
  1134. return v * fl;
  1135. }
  1136. //-----------------------------------------------------------------------------
  1137. // cross product
  1138. //-----------------------------------------------------------------------------
  1139. inline Vector Vector::Cross(const Vector& vOther) const
  1140. {
  1141. Vector res;
  1142. CrossProduct( *this, vOther, res );
  1143. return res;
  1144. }
  1145. //-----------------------------------------------------------------------------
  1146. // 2D
  1147. //-----------------------------------------------------------------------------
  1148. inline vec_t Vector::Length2D(void) const
  1149. {
  1150. return (vec_t)FastSqrt(x*x + y*y);
  1151. }
  1152. inline vec_t Vector::Length2DSqr(void) const
  1153. {
  1154. return (x*x + y*y);
  1155. }
  1156. inline Vector CrossProduct(const Vector& a, const Vector& b)
  1157. {
  1158. 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 );
  1159. }
  1160. inline void VectorMin( const Vector &a, const Vector &b, Vector &result )
  1161. {
  1162. result.x = fpmin(a.x, b.x);
  1163. result.y = fpmin(a.y, b.y);
  1164. result.z = fpmin(a.z, b.z);
  1165. }
  1166. inline void VectorMax( const Vector &a, const Vector &b, Vector &result )
  1167. {
  1168. result.x = fpmax(a.x, b.x);
  1169. result.y = fpmax(a.y, b.y);
  1170. result.z = fpmax(a.z, b.z);
  1171. }
  1172. inline float ComputeVolume( const Vector &vecMins, const Vector &vecMaxs )
  1173. {
  1174. Vector vecDelta;
  1175. VectorSubtract( vecMaxs, vecMins, vecDelta );
  1176. return DotProduct( vecDelta, vecDelta );
  1177. }
  1178. // Get a random vector.
  1179. inline Vector RandomVector( float minVal, float maxVal )
  1180. {
  1181. Vector vRandom;
  1182. vRandom.Random( minVal, maxVal );
  1183. return vRandom;
  1184. }
  1185. #endif //slow
  1186. //-----------------------------------------------------------------------------
  1187. // Helper debugging stuff....
  1188. //-----------------------------------------------------------------------------
  1189. inline bool operator==( float const* f, const Vector& v )
  1190. {
  1191. // AIIIEEEE!!!!
  1192. Assert(0);
  1193. return false;
  1194. }
  1195. inline bool operator==( const Vector& v, float const* f )
  1196. {
  1197. // AIIIEEEE!!!!
  1198. Assert(0);
  1199. return false;
  1200. }
  1201. inline bool operator!=( float const* f, const Vector& v )
  1202. {
  1203. // AIIIEEEE!!!!
  1204. Assert(0);
  1205. return false;
  1206. }
  1207. inline bool operator!=( const Vector& v, float const* f )
  1208. {
  1209. // AIIIEEEE!!!!
  1210. Assert(0);
  1211. return false;
  1212. }
  1213. //-----------------------------------------------------------------------------
  1214. // AngularImpulse
  1215. //-----------------------------------------------------------------------------
  1216. // AngularImpulse are exponetial maps (an axis scaled by a "twist" angle in degrees)
  1217. typedef Vector AngularImpulse;
  1218. #ifndef VECTOR_NO_SLOW_OPERATIONS
  1219. inline AngularImpulse RandomAngularImpulse( float minVal, float maxVal )
  1220. {
  1221. AngularImpulse angImp;
  1222. angImp.Random( minVal, maxVal );
  1223. return angImp;
  1224. }
  1225. #endif
  1226. //-----------------------------------------------------------------------------
  1227. // Quaternion
  1228. //-----------------------------------------------------------------------------
  1229. class RadianEuler;
  1230. class Quaternion // same data-layout as engine's vec4_t,
  1231. { // which is a vec_t[4]
  1232. public:
  1233. inline Quaternion(void) {
  1234. // Initialize to NAN to catch errors
  1235. #ifdef _DEBUG
  1236. #ifdef VECTOR_PARANOIA
  1237. x = y = z = w = VEC_T_NAN;
  1238. #endif
  1239. #endif
  1240. }
  1241. inline Quaternion(vec_t ix, vec_t iy, vec_t iz, vec_t iw) : x(ix), y(iy), z(iz), w(iw) { }
  1242. inline Quaternion(RadianEuler const &angle); // evil auto type promotion!!!
  1243. 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; }
  1244. bool IsValid() const;
  1245. void Invalidate();
  1246. bool operator==( const Quaternion &src ) const;
  1247. bool operator!=( const Quaternion &src ) const;
  1248. vec_t* Base() { return (vec_t*)this; }
  1249. const vec_t* Base() const { return (vec_t*)this; }
  1250. // array access...
  1251. vec_t operator[](int i) const;
  1252. vec_t& operator[](int i);
  1253. vec_t x, y, z, w;
  1254. };
  1255. //-----------------------------------------------------------------------------
  1256. // Array access
  1257. //-----------------------------------------------------------------------------
  1258. inline vec_t& Quaternion::operator[](int i)
  1259. {
  1260. Assert( (i >= 0) && (i < 4) );
  1261. return ((vec_t*)this)[i];
  1262. }
  1263. inline vec_t Quaternion::operator[](int i) const
  1264. {
  1265. Assert( (i >= 0) && (i < 4) );
  1266. return ((vec_t*)this)[i];
  1267. }
  1268. //-----------------------------------------------------------------------------
  1269. // Equality test
  1270. //-----------------------------------------------------------------------------
  1271. inline bool Quaternion::operator==( const Quaternion &src ) const
  1272. {
  1273. return ( x == src.x ) && ( y == src.y ) && ( z == src.z ) && ( w == src.w );
  1274. }
  1275. inline bool Quaternion::operator!=( const Quaternion &src ) const
  1276. {
  1277. return !operator==( src );
  1278. }
  1279. //-----------------------------------------------------------------------------
  1280. // Quaternion equality with tolerance
  1281. //-----------------------------------------------------------------------------
  1282. inline bool QuaternionsAreEqual( const Quaternion& src1, const Quaternion& src2, float tolerance )
  1283. {
  1284. if (FloatMakePositive(src1.x - src2.x) > tolerance)
  1285. return false;
  1286. if (FloatMakePositive(src1.y - src2.y) > tolerance)
  1287. return false;
  1288. if (FloatMakePositive(src1.z - src2.z) > tolerance)
  1289. return false;
  1290. return (FloatMakePositive(src1.w - src2.w) <= tolerance);
  1291. }
  1292. //-----------------------------------------------------------------------------
  1293. // Here's where we add all those lovely SSE optimized routines
  1294. //-----------------------------------------------------------------------------
  1295. class ALIGN16 QuaternionAligned : public Quaternion
  1296. {
  1297. public:
  1298. inline QuaternionAligned(void) {};
  1299. inline QuaternionAligned(vec_t X, vec_t Y, vec_t Z, vec_t W)
  1300. {
  1301. Init(X,Y,Z,W);
  1302. }
  1303. #ifdef VECTOR_NO_SLOW_OPERATIONS
  1304. private:
  1305. // No copy constructors allowed if we're in optimal mode
  1306. QuaternionAligned(const QuaternionAligned& vOther);
  1307. QuaternionAligned(const Quaternion &vOther);
  1308. #else
  1309. public:
  1310. explicit QuaternionAligned(const Quaternion &vOther)
  1311. {
  1312. Init(vOther.x, vOther.y, vOther.z, vOther.w);
  1313. }
  1314. QuaternionAligned& operator=(const Quaternion &vOther)
  1315. {
  1316. Init(vOther.x, vOther.y, vOther.z, vOther.w);
  1317. return *this;
  1318. }
  1319. #endif
  1320. } ALIGN16_POST;
  1321. //-----------------------------------------------------------------------------
  1322. // Radian Euler angle aligned to axis (NOT ROLL/PITCH/YAW)
  1323. //-----------------------------------------------------------------------------
  1324. class QAngle;
  1325. class RadianEuler
  1326. {
  1327. public:
  1328. inline RadianEuler(void) { }
  1329. inline RadianEuler(vec_t X, vec_t Y, vec_t Z) { x = X; y = Y; z = Z; }
  1330. inline RadianEuler(Quaternion const &q); // evil auto type promotion!!!
  1331. inline RadianEuler(QAngle const &angles); // evil auto type promotion!!!
  1332. // Initialization
  1333. inline void Init(vec_t ix=0.0f, vec_t iy=0.0f, vec_t iz=0.0f) { x = ix; y = iy; z = iz; }
  1334. // conversion to qangle
  1335. QAngle ToQAngle( void ) const;
  1336. bool IsValid() const;
  1337. void Invalidate();
  1338. // array access...
  1339. vec_t operator[](int i) const;
  1340. vec_t& operator[](int i);
  1341. vec_t x, y, z;
  1342. };
  1343. extern void AngleQuaternion( RadianEuler const &angles, Quaternion &qt );
  1344. extern void QuaternionAngles( Quaternion const &q, RadianEuler &angles );
  1345. FORCEINLINE void NetworkVarConstruct( Quaternion &q ) { q.x = q.y = q.z = q.w = 0.0f; }
  1346. inline Quaternion::Quaternion(RadianEuler const &angle)
  1347. {
  1348. AngleQuaternion( angle, *this );
  1349. }
  1350. inline bool Quaternion::IsValid() const
  1351. {
  1352. return IsFinite(x) && IsFinite(y) && IsFinite(z) && IsFinite(w);
  1353. }
  1354. inline void Quaternion::Invalidate()
  1355. {
  1356. //#ifdef _DEBUG
  1357. //#ifdef VECTOR_PARANOIA
  1358. x = y = z = w = VEC_T_NAN;
  1359. //#endif
  1360. //#endif
  1361. }
  1362. inline RadianEuler::RadianEuler(Quaternion const &q)
  1363. {
  1364. QuaternionAngles( q, *this );
  1365. }
  1366. inline void VectorCopy( RadianEuler const& src, RadianEuler &dst )
  1367. {
  1368. CHECK_VALID(src);
  1369. dst.x = src.x;
  1370. dst.y = src.y;
  1371. dst.z = src.z;
  1372. }
  1373. inline void VectorScale( RadianEuler const& src, float b, RadianEuler &dst )
  1374. {
  1375. CHECK_VALID(src);
  1376. Assert( IsFinite(b) );
  1377. dst.x = src.x * b;
  1378. dst.y = src.y * b;
  1379. dst.z = src.z * b;
  1380. }
  1381. inline bool RadianEuler::IsValid() const
  1382. {
  1383. return IsFinite(x) && IsFinite(y) && IsFinite(z);
  1384. }
  1385. inline void RadianEuler::Invalidate()
  1386. {
  1387. //#ifdef _DEBUG
  1388. //#ifdef VECTOR_PARANOIA
  1389. x = y = z = VEC_T_NAN;
  1390. //#endif
  1391. //#endif
  1392. }
  1393. //-----------------------------------------------------------------------------
  1394. // Array access
  1395. //-----------------------------------------------------------------------------
  1396. inline vec_t& RadianEuler::operator[](int i)
  1397. {
  1398. Assert( (i >= 0) && (i < 3) );
  1399. return ((vec_t*)this)[i];
  1400. }
  1401. inline vec_t RadianEuler::operator[](int i) const
  1402. {
  1403. Assert( (i >= 0) && (i < 3) );
  1404. return ((vec_t*)this)[i];
  1405. }
  1406. //-----------------------------------------------------------------------------
  1407. // Degree Euler QAngle pitch, yaw, roll
  1408. //-----------------------------------------------------------------------------
  1409. class QAngleByValue;
  1410. class QAngle
  1411. {
  1412. public:
  1413. // Members
  1414. vec_t x, y, z;
  1415. // Construction/destruction
  1416. QAngle(void);
  1417. QAngle(vec_t X, vec_t Y, vec_t Z);
  1418. // QAngle(RadianEuler const &angles); // evil auto type promotion!!!
  1419. // Allow pass-by-value
  1420. operator QAngleByValue &() { return *((QAngleByValue *)(this)); }
  1421. operator const QAngleByValue &() const { return *((const QAngleByValue *)(this)); }
  1422. // Initialization
  1423. void Init(vec_t ix=0.0f, vec_t iy=0.0f, vec_t iz=0.0f);
  1424. void Random( vec_t minVal, vec_t maxVal );
  1425. // Got any nasty NAN's?
  1426. bool IsValid() const;
  1427. void Invalidate();
  1428. // array access...
  1429. vec_t operator[](int i) const;
  1430. vec_t& operator[](int i);
  1431. // Base address...
  1432. vec_t* Base();
  1433. vec_t const* Base() const;
  1434. // equality
  1435. bool operator==(const QAngle& v) const;
  1436. bool operator!=(const QAngle& v) const;
  1437. // arithmetic operations
  1438. QAngle& operator+=(const QAngle &v);
  1439. QAngle& operator-=(const QAngle &v);
  1440. QAngle& operator*=(float s);
  1441. QAngle& operator/=(float s);
  1442. // Get the vector's magnitude.
  1443. vec_t Length() const;
  1444. vec_t LengthSqr() const;
  1445. // negate the QAngle components
  1446. //void Negate();
  1447. // No assignment operators either...
  1448. QAngle& operator=( const QAngle& src );
  1449. #ifndef VECTOR_NO_SLOW_OPERATIONS
  1450. // copy constructors
  1451. // arithmetic operations
  1452. QAngle operator-(void) const;
  1453. QAngle operator+(const QAngle& v) const;
  1454. QAngle operator-(const QAngle& v) const;
  1455. QAngle operator*(float fl) const;
  1456. QAngle operator/(float fl) const;
  1457. #else
  1458. private:
  1459. // No copy constructors allowed if we're in optimal mode
  1460. QAngle(const QAngle& vOther);
  1461. #endif
  1462. };
  1463. FORCEINLINE void NetworkVarConstruct( QAngle &q ) { q.x = q.y = q.z = 0.0f; }
  1464. //-----------------------------------------------------------------------------
  1465. // Allows us to specifically pass the vector by value when we need to
  1466. //-----------------------------------------------------------------------------
  1467. class QAngleByValue : public QAngle
  1468. {
  1469. public:
  1470. // Construction/destruction:
  1471. QAngleByValue(void) : QAngle() {}
  1472. QAngleByValue(vec_t X, vec_t Y, vec_t Z) : QAngle( X, Y, Z ) {}
  1473. QAngleByValue(const QAngleByValue& vOther) { *this = vOther; }
  1474. };
  1475. inline void VectorAdd( const QAngle& a, const QAngle& b, QAngle& result )
  1476. {
  1477. CHECK_VALID(a);
  1478. CHECK_VALID(b);
  1479. result.x = a.x + b.x;
  1480. result.y = a.y + b.y;
  1481. result.z = a.z + b.z;
  1482. }
  1483. inline void VectorMA( const QAngle &start, float scale, const QAngle &direction, QAngle &dest )
  1484. {
  1485. CHECK_VALID(start);
  1486. CHECK_VALID(direction);
  1487. dest.x = start.x + scale * direction.x;
  1488. dest.y = start.y + scale * direction.y;
  1489. dest.z = start.z + scale * direction.z;
  1490. }
  1491. //-----------------------------------------------------------------------------
  1492. // constructors
  1493. //-----------------------------------------------------------------------------
  1494. inline QAngle::QAngle(void)
  1495. {
  1496. #ifdef _DEBUG
  1497. #ifdef VECTOR_PARANOIA
  1498. // Initialize to NAN to catch errors
  1499. x = y = z = VEC_T_NAN;
  1500. #endif
  1501. #endif
  1502. }
  1503. inline QAngle::QAngle(vec_t X, vec_t Y, vec_t Z)
  1504. {
  1505. x = X; y = Y; z = Z;
  1506. CHECK_VALID(*this);
  1507. }
  1508. //-----------------------------------------------------------------------------
  1509. // initialization
  1510. //-----------------------------------------------------------------------------
  1511. inline void QAngle::Init( vec_t ix, vec_t iy, vec_t iz )
  1512. {
  1513. x = ix; y = iy; z = iz;
  1514. CHECK_VALID(*this);
  1515. }
  1516. inline void QAngle::Random( vec_t minVal, vec_t maxVal )
  1517. {
  1518. x = minVal + ((float)rand() / VALVE_RAND_MAX) * (maxVal - minVal);
  1519. y = minVal + ((float)rand() / VALVE_RAND_MAX) * (maxVal - minVal);
  1520. z = minVal + ((float)rand() / VALVE_RAND_MAX) * (maxVal - minVal);
  1521. CHECK_VALID(*this);
  1522. }
  1523. #ifndef VECTOR_NO_SLOW_OPERATIONS
  1524. inline QAngle RandomAngle( float minVal, float maxVal )
  1525. {
  1526. Vector vRandom;
  1527. vRandom.Random( minVal, maxVal );
  1528. QAngle ret( vRandom.x, vRandom.y, vRandom.z );
  1529. return ret;
  1530. }
  1531. #endif
  1532. inline RadianEuler::RadianEuler(QAngle const &angles)
  1533. {
  1534. Init(
  1535. angles.z * 3.14159265358979323846f / 180.f,
  1536. angles.x * 3.14159265358979323846f / 180.f,
  1537. angles.y * 3.14159265358979323846f / 180.f );
  1538. }
  1539. inline QAngle RadianEuler::ToQAngle( void) const
  1540. {
  1541. return QAngle(
  1542. y * 180.f / 3.14159265358979323846f,
  1543. z * 180.f / 3.14159265358979323846f,
  1544. x * 180.f / 3.14159265358979323846f );
  1545. }
  1546. //-----------------------------------------------------------------------------
  1547. // assignment
  1548. //-----------------------------------------------------------------------------
  1549. inline QAngle& QAngle::operator=(const QAngle &vOther)
  1550. {
  1551. CHECK_VALID(vOther);
  1552. x=vOther.x; y=vOther.y; z=vOther.z;
  1553. return *this;
  1554. }
  1555. //-----------------------------------------------------------------------------
  1556. // Array access
  1557. //-----------------------------------------------------------------------------
  1558. inline vec_t& QAngle::operator[](int i)
  1559. {
  1560. Assert( (i >= 0) && (i < 3) );
  1561. return ((vec_t*)this)[i];
  1562. }
  1563. inline vec_t QAngle::operator[](int i) const
  1564. {
  1565. Assert( (i >= 0) && (i < 3) );
  1566. return ((vec_t*)this)[i];
  1567. }
  1568. //-----------------------------------------------------------------------------
  1569. // Base address...
  1570. //-----------------------------------------------------------------------------
  1571. inline vec_t* QAngle::Base()
  1572. {
  1573. return (vec_t*)this;
  1574. }
  1575. inline vec_t const* QAngle::Base() const
  1576. {
  1577. return (vec_t const*)this;
  1578. }
  1579. //-----------------------------------------------------------------------------
  1580. // IsValid?
  1581. //-----------------------------------------------------------------------------
  1582. inline bool QAngle::IsValid() const
  1583. {
  1584. return IsFinite(x) && IsFinite(y) && IsFinite(z);
  1585. }
  1586. //-----------------------------------------------------------------------------
  1587. // Invalidate
  1588. //-----------------------------------------------------------------------------
  1589. inline void QAngle::Invalidate()
  1590. {
  1591. //#ifdef _DEBUG
  1592. //#ifdef VECTOR_PARANOIA
  1593. x = y = z = VEC_T_NAN;
  1594. //#endif
  1595. //#endif
  1596. }
  1597. //-----------------------------------------------------------------------------
  1598. // comparison
  1599. //-----------------------------------------------------------------------------
  1600. inline bool QAngle::operator==( const QAngle& src ) const
  1601. {
  1602. CHECK_VALID(src);
  1603. CHECK_VALID(*this);
  1604. return (src.x == x) && (src.y == y) && (src.z == z);
  1605. }
  1606. inline bool QAngle::operator!=( const QAngle& src ) const
  1607. {
  1608. CHECK_VALID(src);
  1609. CHECK_VALID(*this);
  1610. return (src.x != x) || (src.y != y) || (src.z != z);
  1611. }
  1612. //-----------------------------------------------------------------------------
  1613. // Copy
  1614. //-----------------------------------------------------------------------------
  1615. inline void VectorCopy( const QAngle& src, QAngle& dst )
  1616. {
  1617. CHECK_VALID(src);
  1618. dst.x = src.x;
  1619. dst.y = src.y;
  1620. dst.z = src.z;
  1621. }
  1622. //-----------------------------------------------------------------------------
  1623. // standard math operations
  1624. //-----------------------------------------------------------------------------
  1625. inline QAngle& QAngle::operator+=(const QAngle& v)
  1626. {
  1627. CHECK_VALID(*this);
  1628. CHECK_VALID(v);
  1629. x+=v.x; y+=v.y; z += v.z;
  1630. return *this;
  1631. }
  1632. inline QAngle& QAngle::operator-=(const QAngle& v)
  1633. {
  1634. CHECK_VALID(*this);
  1635. CHECK_VALID(v);
  1636. x-=v.x; y-=v.y; z -= v.z;
  1637. return *this;
  1638. }
  1639. inline QAngle& QAngle::operator*=(float fl)
  1640. {
  1641. x *= fl;
  1642. y *= fl;
  1643. z *= fl;
  1644. CHECK_VALID(*this);
  1645. return *this;
  1646. }
  1647. inline QAngle& QAngle::operator/=(float fl)
  1648. {
  1649. Assert( fl != 0.0f );
  1650. float oofl = 1.0f / fl;
  1651. x *= oofl;
  1652. y *= oofl;
  1653. z *= oofl;
  1654. CHECK_VALID(*this);
  1655. return *this;
  1656. }
  1657. //-----------------------------------------------------------------------------
  1658. // length
  1659. //-----------------------------------------------------------------------------
  1660. inline vec_t QAngle::Length( ) const
  1661. {
  1662. CHECK_VALID(*this);
  1663. return (vec_t)FastSqrt( LengthSqr( ) );
  1664. }
  1665. inline vec_t QAngle::LengthSqr( ) const
  1666. {
  1667. CHECK_VALID(*this);
  1668. return x * x + y * y + z * z;
  1669. }
  1670. //-----------------------------------------------------------------------------
  1671. // Vector equality with tolerance
  1672. //-----------------------------------------------------------------------------
  1673. inline bool QAnglesAreEqual( const QAngle& src1, const QAngle& src2, float tolerance = 0.0f )
  1674. {
  1675. if (FloatMakePositive(src1.x - src2.x) > tolerance)
  1676. return false;
  1677. if (FloatMakePositive(src1.y - src2.y) > tolerance)
  1678. return false;
  1679. return (FloatMakePositive(src1.z - src2.z) <= tolerance);
  1680. }
  1681. //-----------------------------------------------------------------------------
  1682. // arithmetic operations (SLOW!!)
  1683. //-----------------------------------------------------------------------------
  1684. #ifndef VECTOR_NO_SLOW_OPERATIONS
  1685. inline QAngle QAngle::operator-(void) const
  1686. {
  1687. QAngle ret(-x,-y,-z);
  1688. return ret;
  1689. }
  1690. inline QAngle QAngle::operator+(const QAngle& v) const
  1691. {
  1692. QAngle res;
  1693. res.x = x + v.x;
  1694. res.y = y + v.y;
  1695. res.z = z + v.z;
  1696. return res;
  1697. }
  1698. inline QAngle QAngle::operator-(const QAngle& v) const
  1699. {
  1700. QAngle res;
  1701. res.x = x - v.x;
  1702. res.y = y - v.y;
  1703. res.z = z - v.z;
  1704. return res;
  1705. }
  1706. inline QAngle QAngle::operator*(float fl) const
  1707. {
  1708. QAngle res;
  1709. res.x = x * fl;
  1710. res.y = y * fl;
  1711. res.z = z * fl;
  1712. return res;
  1713. }
  1714. inline QAngle QAngle::operator/(float fl) const
  1715. {
  1716. QAngle res;
  1717. res.x = x / fl;
  1718. res.y = y / fl;
  1719. res.z = z / fl;
  1720. return res;
  1721. }
  1722. inline QAngle operator*(float fl, const QAngle& v)
  1723. {
  1724. QAngle ret( v * fl );
  1725. return ret;
  1726. }
  1727. #endif // VECTOR_NO_SLOW_OPERATIONS
  1728. //-----------------------------------------------------------------------------
  1729. // NOTE: These are not completely correct. The representations are not equivalent
  1730. // unless the QAngle represents a rotational impulse along a coordinate axis (x,y,z)
  1731. inline void QAngleToAngularImpulse( const QAngle &angles, AngularImpulse &impulse )
  1732. {
  1733. impulse.x = angles.z;
  1734. impulse.y = angles.x;
  1735. impulse.z = angles.y;
  1736. }
  1737. inline void AngularImpulseToQAngle( const AngularImpulse &impulse, QAngle &angles )
  1738. {
  1739. angles.x = impulse.y;
  1740. angles.y = impulse.z;
  1741. angles.z = impulse.x;
  1742. }
  1743. #if !defined( _X360 )
  1744. FORCEINLINE vec_t InvRSquared( float const *v )
  1745. {
  1746. #if defined(__i386__) || defined(_M_IX86)
  1747. float sqrlen = v[0]*v[0]+v[1]*v[1]+v[2]*v[2] + 1.0e-10f, result;
  1748. _mm_store_ss(&result, _mm_rcp_ss( _mm_max_ss( _mm_set_ss(1.0f), _mm_load_ss(&sqrlen) ) ));
  1749. return result;
  1750. #else
  1751. return 1.f/fpmax(1.f, v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
  1752. #endif
  1753. }
  1754. FORCEINLINE vec_t InvRSquared( const Vector &v )
  1755. {
  1756. return InvRSquared(&v.x);
  1757. }
  1758. #if defined(__i386__) || defined(_M_IX86)
  1759. inline void _SSE_RSqrtInline( float a, float* out )
  1760. {
  1761. __m128 xx = _mm_load_ss( &a );
  1762. __m128 xr = _mm_rsqrt_ss( xx );
  1763. __m128 xt;
  1764. xt = _mm_mul_ss( xr, xr );
  1765. xt = _mm_mul_ss( xt, xx );
  1766. xt = _mm_sub_ss( _mm_set_ss(3.f), xt );
  1767. xt = _mm_mul_ss( xt, _mm_set_ss(0.5f) );
  1768. xr = _mm_mul_ss( xr, xt );
  1769. _mm_store_ss( out, xr );
  1770. }
  1771. #endif
  1772. // FIXME: Change this back to a #define once we get rid of the vec_t version
  1773. FORCEINLINE float VectorNormalize( Vector& vec )
  1774. {
  1775. #ifndef DEBUG // stop crashing my edit-and-continue!
  1776. #if defined(__i386__) || defined(_M_IX86)
  1777. #define DO_SSE_OPTIMIZATION
  1778. #endif
  1779. #endif
  1780. #if defined( DO_SSE_OPTIMIZATION )
  1781. float sqrlen = vec.LengthSqr() + 1.0e-10f, invlen;
  1782. _SSE_RSqrtInline(sqrlen, &invlen);
  1783. vec.x *= invlen;
  1784. vec.y *= invlen;
  1785. vec.z *= invlen;
  1786. return sqrlen * invlen;
  1787. #else
  1788. extern float (FASTCALL *pfVectorNormalize)(Vector& v);
  1789. return (*pfVectorNormalize)(vec);
  1790. #endif
  1791. }
  1792. // FIXME: Obsolete version of VectorNormalize, once we remove all the friggin float*s
  1793. FORCEINLINE float VectorNormalize( float * v )
  1794. {
  1795. return VectorNormalize(*(reinterpret_cast<Vector *>(v)));
  1796. }
  1797. FORCEINLINE void VectorNormalizeFast( Vector &vec )
  1798. {
  1799. VectorNormalize(vec);
  1800. }
  1801. #else
  1802. FORCEINLINE float _VMX_InvRSquared( const Vector &v )
  1803. {
  1804. XMVECTOR xmV = XMVector3ReciprocalLength( XMLoadVector3( v.Base() ) );
  1805. xmV = XMVector3Dot( xmV, xmV );
  1806. return xmV.x;
  1807. }
  1808. // call directly
  1809. FORCEINLINE float _VMX_VectorNormalize( Vector &vec )
  1810. {
  1811. float mag = XMVector3Length( XMLoadVector3( vec.Base() ) ).x;
  1812. float den = 1.f / (mag + FLT_EPSILON );
  1813. vec.x *= den;
  1814. vec.y *= den;
  1815. vec.z *= den;
  1816. return mag;
  1817. }
  1818. #define InvRSquared(x) _VMX_InvRSquared(x)
  1819. // FIXME: Change this back to a #define once we get rid of the vec_t version
  1820. FORCEINLINE float VectorNormalize( Vector& v )
  1821. {
  1822. return _VMX_VectorNormalize( v );
  1823. }
  1824. // FIXME: Obsolete version of VectorNormalize, once we remove all the friggin float*s
  1825. FORCEINLINE float VectorNormalize( float *pV )
  1826. {
  1827. return _VMX_VectorNormalize(*(reinterpret_cast<Vector*>(pV)));
  1828. }
  1829. // call directly
  1830. FORCEINLINE void VectorNormalizeFast( Vector &vec )
  1831. {
  1832. XMVECTOR xmV = XMVector3LengthEst( XMLoadVector3( vec.Base() ) );
  1833. float den = 1.f / (xmV.x + FLT_EPSILON);
  1834. vec.x *= den;
  1835. vec.y *= den;
  1836. vec.z *= den;
  1837. }
  1838. #endif // _X360
  1839. inline vec_t Vector::NormalizeInPlace()
  1840. {
  1841. return VectorNormalize( *this );
  1842. }
  1843. inline Vector Vector::Normalized() const
  1844. {
  1845. Vector norm = *this;
  1846. VectorNormalize( norm );
  1847. return norm;
  1848. }
  1849. inline bool Vector::IsLengthGreaterThan( float val ) const
  1850. {
  1851. return LengthSqr() > val*val;
  1852. }
  1853. inline bool Vector::IsLengthLessThan( float val ) const
  1854. {
  1855. return LengthSqr() < val*val;
  1856. }
  1857. #endif