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.

695 lines
17 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #ifndef VECTOR2D_H
  9. #define VECTOR2D_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 RandomFloat()
  18. #include "vstdlib/random.h"
  19. #include "tier0/dbg.h"
  20. #include "mathlib/math_pfns.h"
  21. #ifndef M_PI
  22. #define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
  23. #endif
  24. #ifndef M_PI_F
  25. #define M_PI_F ((float)(M_PI))
  26. #endif
  27. #ifndef DEG2RAD
  28. #define DEG2RAD( x ) ( (float)(x) * (float)(M_PI_F / 180.f) )
  29. #endif
  30. extern void inline SinCos( float radians, float * RESTRICT sine, float * RESTRICT cosine );
  31. //=========================================================
  32. // 2D Vector2D
  33. //=========================================================
  34. class Vector2D
  35. {
  36. public:
  37. // Members
  38. vec_t x, y;
  39. // Construction/destruction
  40. Vector2D();
  41. Vector2D(vec_t X, vec_t Y);
  42. explicit Vector2D(const float *pFloat);
  43. // Initialization
  44. void Init(vec_t ix=0.0f, vec_t iy=0.0f);
  45. // Got any nasty NAN's?
  46. bool IsValid() const;
  47. // array access...
  48. vec_t operator[](int i) const;
  49. vec_t& operator[](int i);
  50. // Base address...
  51. vec_t* Base();
  52. vec_t const* Base() const;
  53. // Initialization methods
  54. void Random( float minVal, float maxVal );
  55. // equality
  56. bool operator==(const Vector2D& v) const;
  57. bool operator!=(const Vector2D& v) const;
  58. // arithmetic operations
  59. Vector2D& operator+=(const Vector2D &v);
  60. Vector2D& operator-=(const Vector2D &v);
  61. Vector2D& operator*=(const Vector2D &v);
  62. Vector2D& operator*=(float s);
  63. Vector2D& operator/=(const Vector2D &v);
  64. Vector2D& operator/=(float s);
  65. // negate the Vector2D components
  66. void Negate();
  67. // Get the Vector2D's magnitude.
  68. vec_t Length() const;
  69. // Get the Vector2D's magnitude squared.
  70. vec_t LengthSqr(void) const;
  71. // return true if this vector is (0,0) within tolerance
  72. bool IsZero( float tolerance = 0.01f ) const
  73. {
  74. return (x > -tolerance && x < tolerance &&
  75. y > -tolerance && y < tolerance);
  76. }
  77. // Normalize in place and return the old length.
  78. vec_t NormalizeInPlace();
  79. // Compare length.
  80. bool IsLengthGreaterThan( float val ) const;
  81. bool IsLengthLessThan( float val ) const;
  82. // Get the distance from this Vector2D to the other one.
  83. vec_t DistTo(const Vector2D &vOther) const;
  84. // Get the distance from this Vector2D to the other one squared.
  85. vec_t DistToSqr(const Vector2D &vOther) const;
  86. // Copy
  87. void CopyToArray(float* rgfl) const;
  88. // Multiply, add, and assign to this (ie: *this = a + b * scalar). This
  89. // is about 12% faster than the actual Vector2D equation (because it's done per-component
  90. // rather than per-Vector2D).
  91. void MulAdd(const Vector2D& a, const Vector2D& b, float scalar);
  92. // Dot product.
  93. vec_t Dot(const Vector2D& vOther) const;
  94. // assignment
  95. Vector2D& operator=(const Vector2D &vOther);
  96. #ifndef VECTOR_NO_SLOW_OPERATIONS
  97. // copy constructors
  98. Vector2D(const Vector2D &vOther);
  99. // arithmetic operations
  100. Vector2D operator-(void) const;
  101. Vector2D operator+(const Vector2D& v) const;
  102. Vector2D operator-(const Vector2D& v) const;
  103. Vector2D operator*(const Vector2D& v) const;
  104. Vector2D operator/(const Vector2D& v) const;
  105. Vector2D operator*(float fl) const;
  106. Vector2D operator/(float fl) const;
  107. // Cross product between two vectors.
  108. Vector2D Cross(const Vector2D &vOther) const;
  109. // Returns a Vector2D with the min or max in X, Y, and Z.
  110. Vector2D Min(const Vector2D &vOther) const;
  111. Vector2D Max(const Vector2D &vOther) const;
  112. #else
  113. private:
  114. // No copy constructors allowed if we're in optimal mode
  115. Vector2D(const Vector2D& vOther);
  116. #endif
  117. };
  118. //-----------------------------------------------------------------------------
  119. const Vector2D vec2_origin(0,0);
  120. const Vector2D vec2_invalid( FLT_MAX, FLT_MAX );
  121. //-----------------------------------------------------------------------------
  122. // Vector2D related operations
  123. //-----------------------------------------------------------------------------
  124. // Vector2D clear
  125. void Vector2DClear( Vector2D& a );
  126. // Copy
  127. void Vector2DCopy( const Vector2D& src, Vector2D& dst );
  128. // Vector2D arithmetic
  129. void Vector2DAdd( const Vector2D& a, const Vector2D& b, Vector2D& result );
  130. void Vector2DSubtract( const Vector2D& a, const Vector2D& b, Vector2D& result );
  131. void Vector2DMultiply( const Vector2D& a, vec_t b, Vector2D& result );
  132. void Vector2DMultiply( const Vector2D& a, const Vector2D& b, Vector2D& result );
  133. void Vector2DDivide( const Vector2D& a, vec_t b, Vector2D& result );
  134. void Vector2DDivide( const Vector2D& a, const Vector2D& b, Vector2D& result );
  135. void Vector2DMA( const Vector2D& start, float s, const Vector2D& dir, Vector2D& result );
  136. // Store the min or max of each of x, y, and z into the result.
  137. void Vector2DMin( const Vector2D &a, const Vector2D &b, Vector2D &result );
  138. void Vector2DMax( const Vector2D &a, const Vector2D &b, Vector2D &result );
  139. #define Vector2DExpand( v ) (v).x, (v).y
  140. // Normalization
  141. vec_t Vector2DNormalize( Vector2D& v );
  142. // Length
  143. vec_t Vector2DLength( const Vector2D& v );
  144. // Dot Product
  145. vec_t DotProduct2D(const Vector2D& a, const Vector2D& b);
  146. // Linearly interpolate between two vectors
  147. void Vector2DLerp(const Vector2D& src1, const Vector2D& src2, vec_t t, Vector2D& dest );
  148. //-----------------------------------------------------------------------------
  149. //
  150. // Inlined Vector2D methods
  151. //
  152. //-----------------------------------------------------------------------------
  153. //-----------------------------------------------------------------------------
  154. // constructors
  155. //-----------------------------------------------------------------------------
  156. inline Vector2D::Vector2D()
  157. {
  158. #ifdef _DEBUG
  159. // Initialize to NAN to catch errors
  160. x = y = VEC_T_NAN;
  161. #endif
  162. }
  163. inline Vector2D::Vector2D(vec_t X, vec_t Y)
  164. {
  165. x = X; y = Y;
  166. Assert( IsValid() );
  167. }
  168. inline Vector2D::Vector2D(const float *pFloat)
  169. {
  170. Assert( pFloat );
  171. x = pFloat[0]; y = pFloat[1];
  172. Assert( IsValid() );
  173. }
  174. //-----------------------------------------------------------------------------
  175. // copy constructor
  176. //-----------------------------------------------------------------------------
  177. inline Vector2D::Vector2D(const Vector2D &vOther)
  178. {
  179. Assert( vOther.IsValid() );
  180. x = vOther.x; y = vOther.y;
  181. }
  182. //-----------------------------------------------------------------------------
  183. // initialization
  184. //-----------------------------------------------------------------------------
  185. inline void Vector2D::Init( vec_t ix, vec_t iy )
  186. {
  187. x = ix; y = iy;
  188. Assert( IsValid() );
  189. }
  190. #if !defined(__SPU__)
  191. inline void Vector2D::Random( float minVal, float maxVal )
  192. {
  193. x = RandomFloat( minVal , maxVal );
  194. y = RandomFloat( minVal , maxVal );
  195. }
  196. #endif
  197. inline void Vector2DClear( Vector2D& a )
  198. {
  199. a.x = a.y = 0.0f;
  200. }
  201. //-----------------------------------------------------------------------------
  202. // assignment
  203. //-----------------------------------------------------------------------------
  204. inline Vector2D& Vector2D::operator=(const Vector2D &vOther)
  205. {
  206. Assert( vOther.IsValid() );
  207. x=vOther.x; y=vOther.y;
  208. return *this;
  209. }
  210. //-----------------------------------------------------------------------------
  211. // Array access
  212. //-----------------------------------------------------------------------------
  213. inline vec_t& Vector2D::operator[](int i)
  214. {
  215. Assert( (i >= 0) && (i < 2) );
  216. return ((vec_t*)this)[i];
  217. }
  218. inline vec_t Vector2D::operator[](int i) const
  219. {
  220. Assert( (i >= 0) && (i < 2) );
  221. return ((vec_t*)this)[i];
  222. }
  223. //-----------------------------------------------------------------------------
  224. // Base address...
  225. //-----------------------------------------------------------------------------
  226. inline vec_t* Vector2D::Base()
  227. {
  228. return (vec_t*)this;
  229. }
  230. inline vec_t const* Vector2D::Base() const
  231. {
  232. return (vec_t const*)this;
  233. }
  234. //-----------------------------------------------------------------------------
  235. // IsValid?
  236. //-----------------------------------------------------------------------------
  237. inline bool Vector2D::IsValid() const
  238. {
  239. return IsFinite(x) && IsFinite(y);
  240. }
  241. //-----------------------------------------------------------------------------
  242. // comparison
  243. //-----------------------------------------------------------------------------
  244. inline bool Vector2D::operator==( const Vector2D& src ) const
  245. {
  246. Assert( src.IsValid() && IsValid() );
  247. return (src.x == x) && (src.y == y);
  248. }
  249. inline bool Vector2D::operator!=( const Vector2D& src ) const
  250. {
  251. Assert( src.IsValid() && IsValid() );
  252. return (src.x != x) || (src.y != y);
  253. }
  254. //-----------------------------------------------------------------------------
  255. // Copy
  256. //-----------------------------------------------------------------------------
  257. inline void Vector2DCopy( const Vector2D& src, Vector2D& dst )
  258. {
  259. Assert( src.IsValid() );
  260. dst.x = src.x;
  261. dst.y = src.y;
  262. }
  263. inline void Vector2D::CopyToArray(float* rgfl) const
  264. {
  265. Assert( IsValid() );
  266. Assert( rgfl );
  267. rgfl[0] = x; rgfl[1] = y;
  268. }
  269. //-----------------------------------------------------------------------------
  270. // standard math operations
  271. //-----------------------------------------------------------------------------
  272. inline void Vector2D::Negate()
  273. {
  274. Assert( IsValid() );
  275. x = -x; y = -y;
  276. }
  277. inline Vector2D& Vector2D::operator+=(const Vector2D& v)
  278. {
  279. Assert( IsValid() && v.IsValid() );
  280. x+=v.x; y+=v.y;
  281. return *this;
  282. }
  283. inline Vector2D& Vector2D::operator-=(const Vector2D& v)
  284. {
  285. Assert( IsValid() && v.IsValid() );
  286. x-=v.x; y-=v.y;
  287. return *this;
  288. }
  289. inline Vector2D& Vector2D::operator*=(float fl)
  290. {
  291. x *= fl;
  292. y *= fl;
  293. Assert( IsValid() );
  294. return *this;
  295. }
  296. inline Vector2D& Vector2D::operator*=(const Vector2D& v)
  297. {
  298. x *= v.x;
  299. y *= v.y;
  300. Assert( IsValid() );
  301. return *this;
  302. }
  303. inline Vector2D& Vector2D::operator/=(float fl)
  304. {
  305. Assert( fl != 0.0f );
  306. float oofl = 1.0f / fl;
  307. x *= oofl;
  308. y *= oofl;
  309. Assert( IsValid() );
  310. return *this;
  311. }
  312. inline Vector2D& Vector2D::operator/=(const Vector2D& v)
  313. {
  314. Assert( v.x != 0.0f && v.y != 0.0f );
  315. x /= v.x;
  316. y /= v.y;
  317. Assert( IsValid() );
  318. return *this;
  319. }
  320. inline void Vector2DAdd( const Vector2D& a, const Vector2D& b, Vector2D& c )
  321. {
  322. Assert( a.IsValid() && b.IsValid() );
  323. c.x = a.x + b.x;
  324. c.y = a.y + b.y;
  325. }
  326. inline void Vector2DSubtract( const Vector2D& a, const Vector2D& b, Vector2D& c )
  327. {
  328. Assert( a.IsValid() && b.IsValid() );
  329. c.x = a.x - b.x;
  330. c.y = a.y - b.y;
  331. }
  332. inline void Vector2DMultiply( const Vector2D& a, vec_t b, Vector2D& c )
  333. {
  334. Assert( a.IsValid() && IsFinite(b) );
  335. c.x = a.x * b;
  336. c.y = a.y * b;
  337. }
  338. inline void Vector2DMultiply( const Vector2D& a, const Vector2D& b, Vector2D& c )
  339. {
  340. Assert( a.IsValid() && b.IsValid() );
  341. c.x = a.x * b.x;
  342. c.y = a.y * b.y;
  343. }
  344. inline void Vector2DDivide( const Vector2D& a, vec_t b, Vector2D& c )
  345. {
  346. Assert( a.IsValid() );
  347. Assert( b != 0.0f );
  348. vec_t oob = 1.0f / b;
  349. c.x = a.x * oob;
  350. c.y = a.y * oob;
  351. }
  352. inline void Vector2DDivide( const Vector2D& a, const Vector2D& b, Vector2D& c )
  353. {
  354. Assert( a.IsValid() );
  355. Assert( (b.x != 0.0f) && (b.y != 0.0f) );
  356. c.x = a.x / b.x;
  357. c.y = a.y / b.y;
  358. }
  359. inline void Vector2DRotate( const Vector2D& vIn, float flDegrees, Vector2D& vOut )
  360. {
  361. float c, s;
  362. SinCos( DEG2RAD( flDegrees ), &s, &c );
  363. vOut.x = vIn.x*c - vIn.y*s;
  364. vOut.y = vIn.x*s + vIn.y*c;
  365. }
  366. inline void Vector2DMA( const Vector2D& start, float s, const Vector2D& dir, Vector2D& result )
  367. {
  368. Assert( start.IsValid() && IsFinite(s) && dir.IsValid() );
  369. result.x = start.x + s*dir.x;
  370. result.y = start.y + s*dir.y;
  371. }
  372. // FIXME: Remove
  373. // For backwards compatability
  374. inline void Vector2D::MulAdd(const Vector2D& a, const Vector2D& b, float scalar)
  375. {
  376. x = a.x + b.x * scalar;
  377. y = a.y + b.y * scalar;
  378. }
  379. inline void Vector2DLerp(const Vector2D& src1, const Vector2D& src2, vec_t t, Vector2D& dest )
  380. {
  381. dest[0] = src1[0] + (src2[0] - src1[0]) * t;
  382. dest[1] = src1[1] + (src2[1] - src1[1]) * t;
  383. }
  384. //-----------------------------------------------------------------------------
  385. // dot, cross
  386. //-----------------------------------------------------------------------------
  387. inline vec_t DotProduct2D(const Vector2D& a, const Vector2D& b)
  388. {
  389. Assert( a.IsValid() && b.IsValid() );
  390. return( a.x*b.x + a.y*b.y );
  391. }
  392. // for backwards compatability
  393. inline vec_t Vector2D::Dot( const Vector2D& vOther ) const
  394. {
  395. return DotProduct2D( *this, vOther );
  396. }
  397. //-----------------------------------------------------------------------------
  398. // length
  399. //-----------------------------------------------------------------------------
  400. inline vec_t Vector2DLength( const Vector2D& v )
  401. {
  402. Assert( v.IsValid() );
  403. return (vec_t)FastSqrt(v.x*v.x + v.y*v.y);
  404. }
  405. inline vec_t Vector2D::LengthSqr(void) const
  406. {
  407. Assert( IsValid() );
  408. return (x*x + y*y);
  409. }
  410. inline vec_t Vector2D::NormalizeInPlace()
  411. {
  412. return Vector2DNormalize( *this );
  413. }
  414. inline bool Vector2D::IsLengthGreaterThan( float val ) const
  415. {
  416. return LengthSqr() > val*val;
  417. }
  418. inline bool Vector2D::IsLengthLessThan( float val ) const
  419. {
  420. return LengthSqr() < val*val;
  421. }
  422. inline vec_t Vector2D::Length(void) const
  423. {
  424. return Vector2DLength( *this );
  425. }
  426. inline void Vector2DMin( const Vector2D &a, const Vector2D &b, Vector2D &result )
  427. {
  428. result.x = (a.x < b.x) ? a.x : b.x;
  429. result.y = (a.y < b.y) ? a.y : b.y;
  430. }
  431. inline void Vector2DMax( const Vector2D &a, const Vector2D &b, Vector2D &result )
  432. {
  433. result.x = (a.x > b.x) ? a.x : b.x;
  434. result.y = (a.y > b.y) ? a.y : b.y;
  435. }
  436. //-----------------------------------------------------------------------------
  437. // Normalization
  438. //-----------------------------------------------------------------------------
  439. inline vec_t Vector2DNormalize( Vector2D& v )
  440. {
  441. Assert( v.IsValid() );
  442. vec_t l = v.Length();
  443. if (l != 0.0f)
  444. {
  445. v /= l;
  446. }
  447. else
  448. {
  449. v.x = v.y = 0.0f;
  450. }
  451. return l;
  452. }
  453. //-----------------------------------------------------------------------------
  454. // Get the distance from this Vector2D to the other one
  455. //-----------------------------------------------------------------------------
  456. inline vec_t Vector2D::DistTo(const Vector2D &vOther) const
  457. {
  458. Vector2D delta;
  459. Vector2DSubtract( *this, vOther, delta );
  460. return delta.Length();
  461. }
  462. inline vec_t Vector2D::DistToSqr(const Vector2D &vOther) const
  463. {
  464. Vector2D delta;
  465. Vector2DSubtract( *this, vOther, delta );
  466. return delta.LengthSqr();
  467. }
  468. //-----------------------------------------------------------------------------
  469. // Computes the closest point to vecTarget no farther than flMaxDist from vecStart
  470. //-----------------------------------------------------------------------------
  471. inline void ComputeClosestPoint2D( const Vector2D& vecStart, float flMaxDist, const Vector2D& vecTarget, Vector2D *pResult )
  472. {
  473. Vector2D vecDelta;
  474. Vector2DSubtract( vecTarget, vecStart, vecDelta );
  475. float flDistSqr = vecDelta.LengthSqr();
  476. if ( flDistSqr <= flMaxDist * flMaxDist )
  477. {
  478. *pResult = vecTarget;
  479. }
  480. else
  481. {
  482. vecDelta /= FastSqrt( flDistSqr );
  483. Vector2DMA( vecStart, flMaxDist, vecDelta, *pResult );
  484. }
  485. }
  486. //-----------------------------------------------------------------------------
  487. //
  488. // Slow methods
  489. //
  490. //-----------------------------------------------------------------------------
  491. #ifndef VECTOR_NO_SLOW_OPERATIONS
  492. //-----------------------------------------------------------------------------
  493. // Returns a Vector2D with the min or max in X, Y, and Z.
  494. //-----------------------------------------------------------------------------
  495. inline Vector2D Vector2D::Min(const Vector2D &vOther) const
  496. {
  497. return Vector2D(x < vOther.x ? x : vOther.x,
  498. y < vOther.y ? y : vOther.y);
  499. }
  500. inline Vector2D Vector2D::Max(const Vector2D &vOther) const
  501. {
  502. return Vector2D(x > vOther.x ? x : vOther.x,
  503. y > vOther.y ? y : vOther.y);
  504. }
  505. //-----------------------------------------------------------------------------
  506. // arithmetic operations
  507. //-----------------------------------------------------------------------------
  508. inline Vector2D Vector2D::operator-(void) const
  509. {
  510. return Vector2D(-x,-y);
  511. }
  512. inline Vector2D Vector2D::operator+(const Vector2D& v) const
  513. {
  514. Vector2D res;
  515. Vector2DAdd( *this, v, res );
  516. return res;
  517. }
  518. inline Vector2D Vector2D::operator-(const Vector2D& v) const
  519. {
  520. Vector2D res;
  521. Vector2DSubtract( *this, v, res );
  522. return res;
  523. }
  524. inline Vector2D Vector2D::operator*(float fl) const
  525. {
  526. Vector2D res;
  527. Vector2DMultiply( *this, fl, res );
  528. return res;
  529. }
  530. inline Vector2D Vector2D::operator*(const Vector2D& v) const
  531. {
  532. Vector2D res;
  533. Vector2DMultiply( *this, v, res );
  534. return res;
  535. }
  536. inline Vector2D Vector2D::operator/(float fl) const
  537. {
  538. Vector2D res;
  539. Vector2DDivide( *this, fl, res );
  540. return res;
  541. }
  542. inline Vector2D Vector2D::operator/(const Vector2D& v) const
  543. {
  544. Vector2D res;
  545. Vector2DDivide( *this, v, res );
  546. return res;
  547. }
  548. inline Vector2D operator*(float fl, const Vector2D& v)
  549. {
  550. return v * fl;
  551. }
  552. #endif //slow
  553. #endif // VECTOR2D_H