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.

771 lines
19 KiB

  1. //========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #ifndef VECTOR4D_H
  9. #define VECTOR4D_H
  10. #ifdef _WIN32
  11. #pragma once
  12. #endif
  13. #include <math.h>
  14. #include <float.h>
  15. #if !defined( PLATFORM_PPC ) && !defined( _PS3 )
  16. #include <xmmintrin.h> // for sse
  17. #endif
  18. #include "tier0/basetypes.h" // For vec_t, put this somewhere else?
  19. #include "tier0/dbg.h"
  20. #include "mathlib/math_pfns.h"
  21. #include "mathlib/vector.h"
  22. #include "vstdlib/random.h"
  23. // forward declarations
  24. class Vector;
  25. class Vector2D;
  26. //=========================================================
  27. // 4D Vector4D
  28. //=========================================================
  29. class Vector4D
  30. {
  31. public:
  32. // Members
  33. vec_t x, y, z, w;
  34. // Construction/destruction
  35. Vector4D();
  36. Vector4D(vec_t X, vec_t Y, vec_t Z, vec_t W);
  37. explicit Vector4D(const float *pFloat);
  38. // Initialization
  39. void Init(vec_t ix=0.0f, vec_t iy=0.0f, vec_t iz=0.0f, vec_t iw=0.0f);
  40. void Init( const Vector& src, vec_t iw=0.0f );
  41. // Got any nasty NAN's?
  42. bool IsValid() const;
  43. // array access...
  44. vec_t operator[](int i) const;
  45. vec_t& operator[](int i);
  46. // Base address...
  47. inline vec_t* Base();
  48. inline vec_t const* Base() const;
  49. // Cast to Vector and Vector2D...
  50. Vector& AsVector3D();
  51. Vector const& AsVector3D() const;
  52. Vector2D& AsVector2D();
  53. Vector2D const& AsVector2D() const;
  54. // Initialization methods
  55. void Random( vec_t minVal, vec_t maxVal );
  56. // equality
  57. bool operator==(const Vector4D& v) const;
  58. bool operator!=(const Vector4D& v) const;
  59. // arithmetic operations
  60. Vector4D& operator+=(const Vector4D &v);
  61. Vector4D& operator-=(const Vector4D &v);
  62. Vector4D& operator*=(const Vector4D &v);
  63. Vector4D& operator*=(float s);
  64. Vector4D& operator/=(const Vector4D &v);
  65. Vector4D& operator/=(float s);
  66. Vector4D operator-( void ) const;
  67. Vector4D operator*( float fl ) const;
  68. Vector4D operator/( float fl ) const;
  69. Vector4D operator*( const Vector4D& v ) const;
  70. Vector4D operator+( const Vector4D& v ) const;
  71. Vector4D operator-( const Vector4D& v ) const;
  72. // negate the Vector4D components
  73. void Negate();
  74. // Get the Vector4D's magnitude.
  75. vec_t Length() const;
  76. // Get the Vector4D's magnitude squared.
  77. vec_t LengthSqr(void) const;
  78. // return true if this vector is (0,0,0,0) within tolerance
  79. bool IsZero( float tolerance = 0.01f ) const
  80. {
  81. return (x > -tolerance && x < tolerance &&
  82. y > -tolerance && y < tolerance &&
  83. z > -tolerance && z < tolerance &&
  84. w > -tolerance && w < tolerance);
  85. }
  86. // Get the distance from this Vector4D to the other one.
  87. vec_t DistTo(const Vector4D &vOther) const;
  88. // Get the distance from this Vector4D to the other one squared.
  89. vec_t DistToSqr(const Vector4D &vOther) const;
  90. // Copy
  91. void CopyToArray(float* rgfl) const;
  92. // Multiply, add, and assign to this (ie: *this = a + b * scalar). This
  93. // is about 12% faster than the actual Vector4D equation (because it's done per-component
  94. // rather than per-Vector4D).
  95. void MulAdd(Vector4D const& a, Vector4D const& b, float scalar);
  96. // Dot product.
  97. vec_t Dot(Vector4D const& vOther) const;
  98. // No copy constructors allowed if we're in optimal mode
  99. #ifdef VECTOR_NO_SLOW_OPERATIONS
  100. private:
  101. #else
  102. public:
  103. #endif
  104. Vector4D(Vector4D const& vOther);
  105. // No assignment operators either...
  106. Vector4D& operator=( Vector4D const& src );
  107. };
  108. const Vector4D vec4_origin( 0.0f, 0.0f, 0.0f, 0.0f );
  109. const Vector4D vec4_invalid( FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX );
  110. //-----------------------------------------------------------------------------
  111. // SSE optimized routines
  112. //-----------------------------------------------------------------------------
  113. class ALIGN16 Vector4DAligned : public Vector4D
  114. {
  115. public:
  116. Vector4DAligned(void) {}
  117. Vector4DAligned( vec_t X, vec_t Y, vec_t Z, vec_t W );
  118. inline void Set( vec_t X, vec_t Y, vec_t Z, vec_t W );
  119. inline void InitZero( void );
  120. inline __m128 &AsM128() { return *(__m128*)&x; }
  121. inline const __m128 &AsM128() const { return *(const __m128*)&x; }
  122. private:
  123. // No copy constructors allowed if we're in optimal mode
  124. Vector4DAligned( Vector4DAligned const& vOther );
  125. // No assignment operators either...
  126. Vector4DAligned& operator=( Vector4DAligned const& src );
  127. } ALIGN16_POST;
  128. //-----------------------------------------------------------------------------
  129. // Vector4D related operations
  130. //-----------------------------------------------------------------------------
  131. // Vector4D clear
  132. void Vector4DClear( Vector4D& a );
  133. // Copy
  134. void Vector4DCopy( Vector4D const& src, Vector4D& dst );
  135. // Vector4D arithmetic
  136. void Vector4DAdd( Vector4D const& a, Vector4D const& b, Vector4D& result );
  137. void Vector4DSubtract( Vector4D const& a, Vector4D const& b, Vector4D& result );
  138. void Vector4DMultiply( Vector4D const& a, vec_t b, Vector4D& result );
  139. void Vector4DMultiply( Vector4D const& a, Vector4D const& b, Vector4D& result );
  140. void Vector4DDivide( Vector4D const& a, vec_t b, Vector4D& result );
  141. void Vector4DDivide( Vector4D const& a, Vector4D const& b, Vector4D& result );
  142. void Vector4DMA( Vector4D const& start, float s, Vector4D const& dir, Vector4D& result );
  143. // Vector4DAligned arithmetic
  144. void Vector4DMultiplyAligned( Vector4DAligned const& a, vec_t b, Vector4DAligned& result );
  145. #define Vector4DExpand( v ) (v).x, (v).y, (v).z, (v).w
  146. // Normalization
  147. vec_t Vector4DNormalize( Vector4D& v );
  148. // Length
  149. vec_t Vector4DLength( Vector4D const& v );
  150. // Dot Product
  151. vec_t DotProduct4D(Vector4D const& a, Vector4D const& b);
  152. // Linearly interpolate between two vectors
  153. void Vector4DLerp(Vector4D const& src1, Vector4D const& src2, vec_t t, Vector4D& dest );
  154. //-----------------------------------------------------------------------------
  155. //
  156. // Inlined Vector4D methods
  157. //
  158. //-----------------------------------------------------------------------------
  159. //-----------------------------------------------------------------------------
  160. // constructors
  161. //-----------------------------------------------------------------------------
  162. inline Vector4D::Vector4D()
  163. {
  164. #ifdef _DEBUG
  165. // Initialize to NAN to catch errors
  166. x = y = z = w = VEC_T_NAN;
  167. #endif
  168. }
  169. inline Vector4D::Vector4D(vec_t X, vec_t Y, vec_t Z, vec_t W )
  170. {
  171. x = X; y = Y; z = Z; w = W;
  172. Assert( IsValid() );
  173. }
  174. inline Vector4D::Vector4D(const float *pFloat)
  175. {
  176. Assert( pFloat );
  177. x = pFloat[0]; y = pFloat[1]; z = pFloat[2]; w = pFloat[3];
  178. Assert( IsValid() );
  179. }
  180. //-----------------------------------------------------------------------------
  181. // copy constructor
  182. //-----------------------------------------------------------------------------
  183. inline Vector4D::Vector4D(const Vector4D &vOther)
  184. {
  185. Assert( vOther.IsValid() );
  186. x = vOther.x; y = vOther.y; z = vOther.z; w = vOther.w;
  187. }
  188. //-----------------------------------------------------------------------------
  189. // initialization
  190. //-----------------------------------------------------------------------------
  191. inline void Vector4D::Init( vec_t ix, vec_t iy, vec_t iz, vec_t iw )
  192. {
  193. x = ix; y = iy; z = iz; w = iw;
  194. Assert( IsValid() );
  195. }
  196. inline void Vector4D::Init( const Vector& src, vec_t iw )
  197. {
  198. x = src.x; y = src.y; z = src.z; w = iw;
  199. Assert( IsValid() );
  200. }
  201. #if !defined(__SPU__)
  202. inline void Vector4D::Random( vec_t minVal, vec_t maxVal )
  203. {
  204. x = RandomFloat( minVal , maxVal );
  205. y = RandomFloat( minVal , maxVal );
  206. z = RandomFloat( minVal , maxVal );
  207. w = RandomFloat( minVal , maxVal );
  208. }
  209. #endif
  210. inline void Vector4DClear( Vector4D& a )
  211. {
  212. a.x = a.y = a.z = a.w = 0.0f;
  213. }
  214. //-----------------------------------------------------------------------------
  215. // assignment
  216. //-----------------------------------------------------------------------------
  217. inline Vector4D& Vector4D::operator=(const Vector4D &vOther)
  218. {
  219. Assert( vOther.IsValid() );
  220. x=vOther.x; y=vOther.y; z=vOther.z; w=vOther.w;
  221. return *this;
  222. }
  223. //-----------------------------------------------------------------------------
  224. // Array access
  225. //-----------------------------------------------------------------------------
  226. inline vec_t& Vector4D::operator[](int i)
  227. {
  228. Assert( (i >= 0) && (i < 4) );
  229. return ((vec_t*)this)[i];
  230. }
  231. inline vec_t Vector4D::operator[](int i) const
  232. {
  233. Assert( (i >= 0) && (i < 4) );
  234. return ((vec_t*)this)[i];
  235. }
  236. //-----------------------------------------------------------------------------
  237. // Cast to Vector and Vector2D...
  238. //-----------------------------------------------------------------------------
  239. inline Vector& Vector4D::AsVector3D()
  240. {
  241. return *(Vector*)this;
  242. }
  243. inline Vector const& Vector4D::AsVector3D() const
  244. {
  245. return *(Vector const*)this;
  246. }
  247. inline Vector2D& Vector4D::AsVector2D()
  248. {
  249. return *(Vector2D*)this;
  250. }
  251. inline Vector2D const& Vector4D::AsVector2D() const
  252. {
  253. return *(Vector2D const*)this;
  254. }
  255. //-----------------------------------------------------------------------------
  256. // Base address...
  257. //-----------------------------------------------------------------------------
  258. inline vec_t* Vector4D::Base()
  259. {
  260. return (vec_t*)this;
  261. }
  262. inline vec_t const* Vector4D::Base() const
  263. {
  264. return (vec_t const*)this;
  265. }
  266. //-----------------------------------------------------------------------------
  267. // IsValid?
  268. //-----------------------------------------------------------------------------
  269. inline bool Vector4D::IsValid() const
  270. {
  271. return IsFinite(x) && IsFinite(y) && IsFinite(z) && IsFinite(w);
  272. }
  273. //-----------------------------------------------------------------------------
  274. // comparison
  275. //-----------------------------------------------------------------------------
  276. inline bool Vector4D::operator==( Vector4D const& src ) const
  277. {
  278. Assert( src.IsValid() && IsValid() );
  279. return (src.x == x) && (src.y == y) && (src.z == z) && (src.w == w);
  280. }
  281. inline bool Vector4D::operator!=( Vector4D const& src ) const
  282. {
  283. Assert( src.IsValid() && IsValid() );
  284. return (src.x != x) || (src.y != y) || (src.z != z) || (src.w != w);
  285. }
  286. //-----------------------------------------------------------------------------
  287. // Copy
  288. //-----------------------------------------------------------------------------
  289. inline void Vector4DCopy( Vector4D const& src, Vector4D& dst )
  290. {
  291. Assert( src.IsValid() );
  292. dst.x = src.x;
  293. dst.y = src.y;
  294. dst.z = src.z;
  295. dst.w = src.w;
  296. }
  297. inline void Vector4D::CopyToArray(float* rgfl) const
  298. {
  299. Assert( IsValid() );
  300. Assert( rgfl );
  301. rgfl[0] = x; rgfl[1] = y; rgfl[2] = z; rgfl[3] = w;
  302. }
  303. //-----------------------------------------------------------------------------
  304. // standard math operations
  305. //-----------------------------------------------------------------------------
  306. inline void Vector4D::Negate()
  307. {
  308. Assert( IsValid() );
  309. x = -x; y = -y; z = -z; w = -w;
  310. }
  311. inline Vector4D& Vector4D::operator+=(const Vector4D& v)
  312. {
  313. Assert( IsValid() && v.IsValid() );
  314. x+=v.x; y+=v.y; z += v.z; w += v.w;
  315. return *this;
  316. }
  317. inline Vector4D& Vector4D::operator-=(const Vector4D& v)
  318. {
  319. Assert( IsValid() && v.IsValid() );
  320. x-=v.x; y-=v.y; z -= v.z; w -= v.w;
  321. return *this;
  322. }
  323. inline Vector4D& Vector4D::operator*=(float fl)
  324. {
  325. x *= fl;
  326. y *= fl;
  327. z *= fl;
  328. w *= fl;
  329. Assert( IsValid() );
  330. return *this;
  331. }
  332. inline Vector4D& Vector4D::operator*=(Vector4D const& v)
  333. {
  334. x *= v.x;
  335. y *= v.y;
  336. z *= v.z;
  337. w *= v.w;
  338. Assert( IsValid() );
  339. return *this;
  340. }
  341. inline Vector4D Vector4D::operator-(void) const
  342. {
  343. return Vector4D(-x,-y,-z,-w);
  344. }
  345. inline Vector4D Vector4D::operator+(const Vector4D& v) const
  346. {
  347. Vector4D res;
  348. Vector4DAdd( *this, v, res );
  349. return res;
  350. }
  351. inline Vector4D Vector4D::operator-(const Vector4D& v) const
  352. {
  353. Vector4D res;
  354. Vector4DSubtract( *this, v, res );
  355. return res;
  356. }
  357. inline Vector4D Vector4D::operator*(float fl) const
  358. {
  359. Vector4D res;
  360. Vector4DMultiply( *this, fl, res );
  361. return res;
  362. }
  363. inline Vector4D Vector4D::operator*(const Vector4D& v) const
  364. {
  365. Vector4D res;
  366. Vector4DMultiply( *this, v, res );
  367. return res;
  368. }
  369. inline Vector4D Vector4D::operator/(float fl) const
  370. {
  371. Vector4D res;
  372. Vector4DDivide( *this, fl, res );
  373. return res;
  374. }
  375. inline Vector4D operator*( float fl, const Vector4D& v )
  376. {
  377. return v * fl;
  378. }
  379. inline Vector4D& Vector4D::operator/=(float fl)
  380. {
  381. Assert( fl != 0.0f );
  382. float oofl = 1.0f / fl;
  383. x *= oofl;
  384. y *= oofl;
  385. z *= oofl;
  386. w *= oofl;
  387. Assert( IsValid() );
  388. return *this;
  389. }
  390. inline Vector4D& Vector4D::operator/=(Vector4D const& v)
  391. {
  392. Assert( v.x != 0.0f && v.y != 0.0f && v.z != 0.0f && v.w != 0.0f );
  393. x /= v.x;
  394. y /= v.y;
  395. z /= v.z;
  396. w /= v.w;
  397. Assert( IsValid() );
  398. return *this;
  399. }
  400. inline void Vector4DAdd( Vector4D const& a, Vector4D const& b, Vector4D& c )
  401. {
  402. Assert( a.IsValid() && b.IsValid() );
  403. c.x = a.x + b.x;
  404. c.y = a.y + b.y;
  405. c.z = a.z + b.z;
  406. c.w = a.w + b.w;
  407. }
  408. inline void Vector4DSubtract( Vector4D const& a, Vector4D const& b, Vector4D& c )
  409. {
  410. Assert( a.IsValid() && b.IsValid() );
  411. c.x = a.x - b.x;
  412. c.y = a.y - b.y;
  413. c.z = a.z - b.z;
  414. c.w = a.w - b.w;
  415. }
  416. inline void Vector4DMultiply( Vector4D const& a, vec_t b, Vector4D& c )
  417. {
  418. Assert( a.IsValid() && IsFinite(b) );
  419. c.x = a.x * b;
  420. c.y = a.y * b;
  421. c.z = a.z * b;
  422. c.w = a.w * b;
  423. }
  424. inline void Vector4DMultiply( Vector4D const& a, Vector4D const& b, Vector4D& c )
  425. {
  426. Assert( a.IsValid() && b.IsValid() );
  427. c.x = a.x * b.x;
  428. c.y = a.y * b.y;
  429. c.z = a.z * b.z;
  430. c.w = a.w * b.w;
  431. }
  432. inline void Vector4DDivide( Vector4D const& a, vec_t b, Vector4D& c )
  433. {
  434. Assert( a.IsValid() );
  435. Assert( b != 0.0f );
  436. vec_t oob = 1.0f / b;
  437. c.x = a.x * oob;
  438. c.y = a.y * oob;
  439. c.z = a.z * oob;
  440. c.w = a.w * oob;
  441. }
  442. inline void Vector4DDivide( Vector4D const& a, Vector4D const& b, Vector4D& c )
  443. {
  444. Assert( a.IsValid() );
  445. Assert( (b.x != 0.0f) && (b.y != 0.0f) && (b.z != 0.0f) && (b.w != 0.0f) );
  446. c.x = a.x / b.x;
  447. c.y = a.y / b.y;
  448. c.z = a.z / b.z;
  449. c.w = a.w / b.w;
  450. }
  451. inline void Vector4DMA( Vector4D const& start, float s, Vector4D const& dir, Vector4D& result )
  452. {
  453. Assert( start.IsValid() && IsFinite(s) && dir.IsValid() );
  454. result.x = start.x + s*dir.x;
  455. result.y = start.y + s*dir.y;
  456. result.z = start.z + s*dir.z;
  457. result.w = start.w + s*dir.w;
  458. }
  459. // FIXME: Remove
  460. // For backwards compatability
  461. inline void Vector4D::MulAdd(Vector4D const& a, Vector4D const& b, float scalar)
  462. {
  463. x = a.x + b.x * scalar;
  464. y = a.y + b.y * scalar;
  465. z = a.z + b.z * scalar;
  466. w = a.w + b.w * scalar;
  467. }
  468. inline void Vector4DLerp(const Vector4D& src1, const Vector4D& src2, vec_t t, Vector4D& dest )
  469. {
  470. dest[0] = src1[0] + (src2[0] - src1[0]) * t;
  471. dest[1] = src1[1] + (src2[1] - src1[1]) * t;
  472. dest[2] = src1[2] + (src2[2] - src1[2]) * t;
  473. dest[3] = src1[3] + (src2[3] - src1[3]) * t;
  474. }
  475. //-----------------------------------------------------------------------------
  476. // dot, cross
  477. //-----------------------------------------------------------------------------
  478. inline vec_t DotProduct4D(const Vector4D& a, const Vector4D& b)
  479. {
  480. Assert( a.IsValid() && b.IsValid() );
  481. return( a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w );
  482. }
  483. // for backwards compatability
  484. inline vec_t Vector4D::Dot( Vector4D const& vOther ) const
  485. {
  486. return DotProduct4D( *this, vOther );
  487. }
  488. //-----------------------------------------------------------------------------
  489. // length
  490. //-----------------------------------------------------------------------------
  491. inline vec_t Vector4DLength( Vector4D const& v )
  492. {
  493. Assert( v.IsValid() );
  494. return (vec_t)FastSqrt(v.x*v.x + v.y*v.y + v.z*v.z + v.w*v.w);
  495. }
  496. inline vec_t Vector4D::LengthSqr(void) const
  497. {
  498. Assert( IsValid() );
  499. return (x*x + y*y + z*z + w*w);
  500. }
  501. inline vec_t Vector4D::Length(void) const
  502. {
  503. return Vector4DLength( *this );
  504. }
  505. //-----------------------------------------------------------------------------
  506. // Normalization
  507. //-----------------------------------------------------------------------------
  508. // FIXME: Can't use until we're un-macroed in mathlib.h
  509. inline vec_t Vector4DNormalize( Vector4D& v )
  510. {
  511. Assert( v.IsValid() );
  512. vec_t l = v.Length();
  513. if (l != 0.0f)
  514. {
  515. v /= l;
  516. }
  517. else
  518. {
  519. v.x = v.y = v.z = v.w = 0.0f;
  520. }
  521. return l;
  522. }
  523. //-----------------------------------------------------------------------------
  524. // Get the distance from this Vector4D to the other one
  525. //-----------------------------------------------------------------------------
  526. inline vec_t Vector4D::DistTo(const Vector4D &vOther) const
  527. {
  528. Vector4D delta;
  529. Vector4DSubtract( *this, vOther, delta );
  530. return delta.Length();
  531. }
  532. inline vec_t Vector4D::DistToSqr(const Vector4D &vOther) const
  533. {
  534. Vector4D delta;
  535. Vector4DSubtract( *this, vOther, delta );
  536. return delta.LengthSqr();
  537. }
  538. //-----------------------------------------------------------------------------
  539. // Vector4DAligned routines
  540. //-----------------------------------------------------------------------------
  541. inline Vector4DAligned::Vector4DAligned( vec_t X, vec_t Y, vec_t Z, vec_t W )
  542. {
  543. x = X; y = Y; z = Z; w = W;
  544. Assert( IsValid() );
  545. }
  546. inline void Vector4DAligned::Set( vec_t X, vec_t Y, vec_t Z, vec_t W )
  547. {
  548. x = X; y = Y; z = Z; w = W;
  549. Assert( IsValid() );
  550. }
  551. inline void Vector4DAligned::InitZero( void )
  552. {
  553. #if !defined( PLATFORM_PPC )
  554. this->AsM128() = _mm_set1_ps( 0.0f );
  555. #elif defined(_PS3)
  556. this->AsM128() =VMX_ZERO;
  557. #else
  558. this->AsM128() = __vspltisw( 0 );
  559. #endif
  560. Assert( IsValid() );
  561. }
  562. inline void Vector4DMultiplyAligned( Vector4DAligned const& a, Vector4DAligned const& b, Vector4DAligned& c )
  563. {
  564. Assert( a.IsValid() && b.IsValid() );
  565. #if !defined( PLATFORM_PPC )
  566. c.x = a.x * b.x;
  567. c.y = a.y * b.y;
  568. c.z = a.z * b.z;
  569. c.w = a.w * b.w;
  570. #elif defined(_PS3)
  571. c.AsM128() = __vec_mul( a.AsM128(), b.AsM128());
  572. #else
  573. c.AsM128() = __vmulfp( a.AsM128(), b.AsM128() );
  574. #endif
  575. }
  576. inline void Vector4DWeightMAD( vec_t w, Vector4DAligned const& vInA, Vector4DAligned& vOutA, Vector4DAligned const& vInB, Vector4DAligned& vOutB )
  577. {
  578. Assert( vInA.IsValid() && vInB.IsValid() && IsFinite(w) );
  579. #if !defined( PLATFORM_PPC )
  580. vOutA.x += vInA.x * w;
  581. vOutA.y += vInA.y * w;
  582. vOutA.z += vInA.z * w;
  583. vOutA.w += vInA.w * w;
  584. vOutB.x += vInB.x * w;
  585. vOutB.y += vInB.y * w;
  586. vOutB.z += vInB.z * w;
  587. vOutB.w += vInB.w * w;
  588. #elif defined(_PS3)
  589. #if ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ == 1 ) && ( __GNUC_PATCHLEVEL__ == 1 )
  590. // GCC 4.1.1
  591. __m128 temp=vec_splats(w);
  592. #else //__GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ == 1
  593. __m128 temp=__m128(w);
  594. #endif //__GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ == 1
  595. vOutA.AsM128() = vec_madd( vInA.AsM128(), temp, vOutA.AsM128() );
  596. vOutB.AsM128() = vec_madd( vInB.AsM128(), temp, vOutB.AsM128() );
  597. #else
  598. __vector4 temp;
  599. temp = __lvlx( &w, 0 );
  600. temp = __vspltw( temp, 0 );
  601. vOutA.AsM128() = __vmaddfp( vInA.AsM128(), temp, vOutA.AsM128() );
  602. vOutB.AsM128() = __vmaddfp( vInB.AsM128(), temp, vOutB.AsM128() );
  603. #endif
  604. }
  605. inline void Vector4DWeightMADSSE( vec_t w, Vector4DAligned const& vInA, Vector4DAligned& vOutA, Vector4DAligned const& vInB, Vector4DAligned& vOutB )
  606. {
  607. Assert( vInA.IsValid() && vInB.IsValid() && IsFinite(w) );
  608. #if !defined( PLATFORM_PPC )
  609. // Replicate scalar float out to 4 components
  610. __m128 packed = _mm_set1_ps( w );
  611. // 4D SSE Vector MAD
  612. vOutA.AsM128() = _mm_add_ps( vOutA.AsM128(), _mm_mul_ps( vInA.AsM128(), packed ) );
  613. vOutB.AsM128() = _mm_add_ps( vOutB.AsM128(), _mm_mul_ps( vInB.AsM128(), packed ) );
  614. #elif defined(_PS3)
  615. #if ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ == 1 ) && ( __GNUC_PATCHLEVEL__ == 1 )
  616. // GCC 4.1.1
  617. __m128 temp=vec_splats(w);
  618. #else //__GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ == 1
  619. __m128 temp=__m128(w);
  620. #endif //__GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ == 1
  621. vOutA.AsM128() = vec_madd( vInA.AsM128(), temp, vOutA.AsM128() );
  622. vOutB.AsM128() = vec_madd( vInB.AsM128(), temp, vOutB.AsM128() );
  623. #else
  624. __vector4 temp;
  625. temp = __lvlx( &w, 0 );
  626. temp = __vspltw( temp, 0 );
  627. vOutA.AsM128() = __vmaddfp( vInA.AsM128(), temp, vOutA.AsM128() );
  628. vOutB.AsM128() = __vmaddfp( vInB.AsM128(), temp, vOutB.AsM128() );
  629. #endif
  630. }
  631. #endif // VECTOR4D_H