hkSseVector4.inl
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:20k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /* 
  2.  * 
  3.  * Confidential Information of Telekinesys Research Limited (t/a Havok). Not for disclosure or distribution without Havok's
  4.  * prior written consent. This software contains code, techniques and know-how which is confidential and proprietary to Havok.
  5.  * Level 2 and Level 3 source code contains trade secrets of Havok. Havok Software (C) Copyright 1999-2009 Telekinesys Research Limited t/a Havok. All Rights Reserved. Use of this software is subject to the terms of an end user license agreement.
  6.  * 
  7.  */
  8. /* quad, here for inlining */
  9. inline hkQuadReal& hkVector4::getQuad()
  10. {
  11. return m_quad;
  12. }
  13. inline const hkQuadReal& hkVector4::getQuad() const
  14. {
  15. return m_quad;
  16. }
  17. #ifndef HK_DISABLE_VECTOR4_CONSTRUCTORS
  18. /* construct, assign, zero */
  19. inline hkVector4::hkVector4(hkReal a, hkReal b, hkReal c, hkReal d)
  20. {
  21. m_quad = _mm_setr_ps(a,b,c,d);
  22. }
  23. inline hkVector4::hkVector4(const hkQuadReal& q)
  24. {
  25. m_quad = q;
  26. }
  27. inline hkVector4::hkVector4(const hkVector4& v)
  28. {
  29. m_quad = v.m_quad;
  30. }
  31. #endif
  32. inline void hkVector4::operator= (const hkVector4& v)
  33. {
  34. m_quad = v.m_quad;
  35. }
  36. inline void hkVector4::set(hkReal a, hkReal b, hkReal c, hkReal d)
  37. {
  38. m_quad = _mm_setr_ps(a,b,c,d);
  39. }
  40. inline void hkVector4::setAll(hkSimdRealParameter a)
  41. {
  42. m_quad = _mm_shuffle_ps( a.getQuad(), a.getQuad(), _MM_SHUFFLE(0,0,0,0));
  43. }
  44. inline void hkVector4::setAll(hkReal a)
  45. {
  46. m_quad = _mm_set_ps1(a);
  47. }
  48. inline void hkVector4::setAll3(hkReal a)
  49. {
  50. m_quad = _mm_set_ps1(a);
  51. }
  52. inline void hkVector4::setZero4()
  53. {
  54. m_quad = _mm_setzero_ps();
  55. }
  56. void hkVector4::setInt24W( int value )
  57. {
  58. (reinterpret_cast<hkUint32*>(this))[3] = value |= 0x3f000000;
  59. }
  60. // Gets the .w component as an integer with 24 bit resolution (for real experts only)
  61. int hkVector4::getInt24W( ) const 
  62. {
  63. return (reinterpret_cast<const hkUint32*>(this))[3] & ~0x3f000000;
  64. }
  65. inline void hkVector4::storeUncached( void* dest) const
  66. {
  67. _mm_stream_ps( (float*)dest, this->m_quad );
  68. }
  69. inline void hkVector4::zeroElement( int i )
  70. {
  71. HK_ASSERT(0x3bc36625, i>=0 && i<4);
  72. static HK_ALIGN16( const hkUint32 cx[4][4] ) ={ 
  73. { 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff },
  74. { 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff },
  75. { 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff },
  76. { 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000 } };
  77. m_quad = _mm_and_ps( m_quad, reinterpret_cast<const hkQuadReal*>(cx)[i] );
  78. }
  79. /* vector methods */
  80. inline void hkVector4::add4(const hkVector4& v)
  81. {
  82. m_quad = _mm_add_ps( m_quad, v.m_quad );
  83. }
  84. inline void hkVector4::add3clobberW(const hkVector4& v)
  85. {
  86. m_quad = _mm_add_ps( m_quad, v.m_quad );
  87. }
  88. inline void hkVector4::setAdd4(const hkVector4& v0, const hkVector4& v1)
  89. {
  90. m_quad = _mm_add_ps(v0.m_quad, v1.m_quad);
  91. }
  92. inline void hkVector4::sub4(const hkVector4& v)
  93. {
  94. m_quad = _mm_sub_ps( m_quad, v.m_quad );
  95. }
  96. inline void hkVector4::sub3clobberW(const hkVector4& v)
  97. {
  98. m_quad = _mm_sub_ps( m_quad, v.m_quad );
  99. }
  100. inline void hkVector4::setSub4(const hkVector4& v0, const hkVector4& v1)
  101. {
  102. m_quad = _mm_sub_ps(v0.m_quad, v1.m_quad);
  103. }
  104. inline void hkVector4::mul4(const hkVector4& v)
  105. {              
  106. m_quad = _mm_mul_ps( m_quad, v.m_quad );
  107. }
  108. inline void hkVector4::setNeg3(const hkVector4& v)
  109. {
  110. static HK_ALIGN16( const hkUint32 negateMask[4] ) = { 0x80000000, 0x80000000, 0x80000000, 0x00000000 };
  111. m_quad = _mm_xor_ps(v.m_quad, *(const hkQuadReal*)&negateMask);
  112. }
  113. inline void hkVector4::setMul4(const hkVector4& a, const hkVector4& b)
  114. {
  115. m_quad = _mm_mul_ps( a.m_quad, b.m_quad );
  116. }
  117. inline void hkVector4::mul4(hkSimdRealParameter s)
  118. {              
  119. m_quad = _mm_mul_ps( s.broadcast(), m_quad );
  120. }
  121. inline void hkVector4::setMul4(hkSimdRealParameter r, const hkVector4& v1)
  122. {
  123. m_quad = _mm_mul_ps( r.broadcast(), v1.m_quad);
  124. }
  125. inline void hkVector4::addMul4(hkSimdRealParameter r, const hkVector4& v1)
  126. {
  127. m_quad = _mm_add_ps( m_quad,
  128. _mm_mul_ps( r.broadcast(), v1.m_quad) );
  129. }
  130. inline void hkVector4::addMul4(const hkVector4& x, const hkVector4& y)
  131. {
  132. m_quad = _mm_add_ps( m_quad,
  133. _mm_mul_ps( x.m_quad, y.m_quad) );
  134. }
  135. inline void hkVector4::subMul4(hkSimdRealParameter r, const hkVector4& v1)
  136. {
  137. m_quad = _mm_sub_ps( m_quad,
  138. _mm_mul_ps( r.broadcast(), v1.m_quad) );
  139. }
  140. inline void hkVector4::subMul4(const hkVector4& x, const hkVector4& y)
  141. {
  142. m_quad = _mm_sub_ps( m_quad,
  143. _mm_mul_ps( x.m_quad, y.m_quad) );
  144. }
  145. inline void hkVector4::setAddMul4(const hkVector4& a, const hkVector4& b, hkSimdRealParameter r)
  146. {
  147. m_quad = _mm_add_ps( a.m_quad,
  148.  _mm_mul_ps( r.broadcast(), b.m_quad) );
  149. }
  150. inline void hkVector4::setAddMul4(const hkVector4& a, const hkVector4& x, const hkVector4& y)
  151. {
  152. m_quad = _mm_add_ps( a.m_quad,
  153.  _mm_mul_ps( x.m_quad, y.m_quad) );
  154. }
  155. inline void hkVector4::setCross( const hkVector4& v0, const hkVector4& v1 )
  156. {
  157. hkQuadReal cross0;
  158. cross0 = _mm_mul_ps(
  159. _mm_shuffle_ps(v0.m_quad, v0.m_quad, _MM_SHUFFLE(3,0,2,1)),
  160. _mm_shuffle_ps(v1.m_quad, v1.m_quad, _MM_SHUFFLE(3,1,0,2)) );
  161. hkQuadReal cross1;
  162. cross1 = _mm_mul_ps(
  163. _mm_shuffle_ps(v0.m_quad, v0.m_quad, _MM_SHUFFLE(3,1,0,2)),
  164. _mm_shuffle_ps(v1.m_quad, v1.m_quad, _MM_SHUFFLE(3,0,2,1)) );
  165. m_quad = _mm_sub_ps(cross0, cross1);
  166. }
  167. inline void hkVector4::setInterpolate4(const hkVector4& v0, const hkVector4& v1, hkSimdRealParameter _t)
  168. {
  169. static HK_ALIGN16( const float cw[4] ) = { 1.0f, 1.0f, 1.0f, 1.0f };
  170. hkQuadReal t = _t.broadcast();
  171. hkQuadReal s = _mm_sub_ps( *(const hkQuadReal*)&cw, t);
  172. m_quad = _mm_add_ps(
  173. _mm_mul_ps(s, v0.m_quad),
  174. _mm_mul_ps(t, v1.m_quad) );
  175. }
  176. inline hkVector4Comparison hkVector4::compareLessThan4(hkVector4Parameter a) const
  177. {
  178. hkVector4Comparison m; m.m_mask =_mm_cmplt_ps(m_quad, a.m_quad);
  179. return m;
  180. }
  181. inline hkVector4Comparison hkVector4::compareEqual4(hkVector4Parameter a) const
  182. {
  183. hkVector4Comparison m; m.m_mask =_mm_cmpeq_ps(m_quad, a.m_quad);
  184. return m;
  185. }
  186. inline hkVector4Comparison hkVector4::compareLessThanEqual4(const hkVector4 &a) const
  187. {
  188. hkVector4Comparison m; m.m_mask =_mm_cmple_ps(m_quad, a.m_quad);
  189. return m;
  190. }
  191. inline hkVector4Comparison hkVector4::compareLessThanZero4() const
  192. {
  193. hkVector4 zero; zero.setZero4();
  194. hkVector4Comparison m; m.m_mask =_mm_cmplt_ps(m_quad, zero);
  195. return m;
  196. }
  197. inline hkBool32 hkVector4::allLessThan3(hkVector4Parameter a) const
  198. {
  199. return (_mm_movemask_ps( _mm_cmplt_ps(m_quad, a.m_quad) ) & hkVector4Comparison::MASK_XYZ) == hkVector4Comparison::MASK_XYZ;
  200. }
  201. inline hkBool32 hkVector4::allLessThan4(hkVector4Parameter a) const
  202. {
  203. return _mm_movemask_ps( _mm_cmplt_ps(m_quad, a.m_quad) ) == hkVector4Comparison::MASK_XYZW;
  204. }
  205. inline void hkVector4::select32( hkVector4Parameter a, hkVector4Parameter b, const hkVector4Comparison& comp)
  206. {
  207. m_quad = _mm_or_ps( _mm_and_ps(comp.m_mask, b.m_quad), _mm_andnot_ps(comp.m_mask, a.m_quad) );
  208. }
  209. inline void hkVector4::setNeg4(const hkVector4& v)
  210. {
  211. static HK_ALIGN16( const hkUint32 negateMask[4] ) = { 0x80000000, 0x80000000, 0x80000000, 0x80000000 };
  212. m_quad = _mm_xor_ps(v.m_quad, *(const hkQuadReal*)&negateMask);
  213. }
  214. inline void hkVector4::setAbs4(const hkVector4& v)
  215. {
  216. static HK_ALIGN16( const hkUint32 absMask[4] ) = { 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff };
  217. m_quad = _mm_and_ps(v.m_quad, *(const hkQuadReal*)&absMask);
  218. }
  219. inline void hkVector4::setMin4(const hkVector4& a, const hkVector4& b)
  220. {
  221. m_quad = _mm_min_ps(a.getQuad(), b.getQuad());
  222. }
  223. inline void hkVector4::setMax4(const hkVector4& a, const hkVector4& b)
  224. {
  225. m_quad = _mm_max_ps(a.getQuad(), b.getQuad());
  226. }
  227. /* matrix3, rotation, quaternion, transform */
  228. inline void hkVector4::_setMul3(const hkMatrix3& a, const hkVector4& b )
  229. {
  230. const hkQuadReal b0 = _mm_shuffle_ps( b.m_quad, b.m_quad, _MM_SHUFFLE(0,0,0,0));
  231. const hkQuadReal r0 = _mm_mul_ps( a.getColumn(0).m_quad, b0 );
  232. const hkQuadReal b1 = _mm_shuffle_ps( b.m_quad, b.m_quad, _MM_SHUFFLE(1,1,1,1));
  233. const hkQuadReal r1 = _mm_mul_ps( a.getColumn(1).m_quad, b1 );
  234. const hkQuadReal b2 = _mm_shuffle_ps( b.m_quad, b.m_quad, _MM_SHUFFLE(2,2,2,2));
  235. const hkQuadReal r2 = _mm_mul_ps( a.getColumn(2).m_quad, b2 );
  236. m_quad = _mm_add_ps( _mm_add_ps(r0, r1), r2 );
  237. }
  238. inline void hkVector4::_setMul4(const hkMatrix3& r, const hkVector4& v)
  239. {
  240. _setMul3(r,v);
  241. }
  242. inline void hkVector4::_setRotatedDir (const hkRotation& r, const hkVector4& v)
  243. {
  244. _setMul3(r,v);
  245. }
  246. inline void hkVector4::_setRotatedInverseDir(const hkRotation& r, const hkVector4& b)
  247. {
  248. // - horizontal add is 15+a few more shuffles.
  249. hkQuadReal c0 = r.getColumn(0).m_quad;
  250. hkQuadReal c1 = r.getColumn(1).m_quad;
  251. hkQuadReal c2 = r.getColumn(2).m_quad;
  252. HK_TRANSPOSE3(c0,c1,c2);
  253. const hkQuadReal b0 = _mm_shuffle_ps( b.m_quad, b.m_quad, _MM_SHUFFLE(0,0,0,0));
  254. const hkQuadReal r0 = _mm_mul_ps( c0, b0 );
  255. const hkQuadReal b1 = _mm_shuffle_ps( b.m_quad, b.m_quad, _MM_SHUFFLE(1,1,1,1));
  256. const hkQuadReal r1 = _mm_mul_ps( c1, b1 );
  257. const hkQuadReal b2 = _mm_shuffle_ps( b.m_quad, b.m_quad, _MM_SHUFFLE(2,2,2,2));
  258. const hkQuadReal r2 = _mm_mul_ps( c2, b2 );
  259. m_quad = _mm_add_ps( _mm_add_ps(r0, r1), r2 );
  260. }
  261. inline void hkVector4::_setTransformedPos(const hkTransform& t, const hkVector4& b)
  262. {
  263. const hkRotation& r = t.getRotation();
  264. hkQuadReal b0 = _mm_shuffle_ps( b.m_quad, b.m_quad, _MM_SHUFFLE(0,0,0,0));
  265. hkQuadReal r0 = _mm_mul_ps( r.getColumn(0).m_quad, b0 );
  266. hkQuadReal b1 = _mm_shuffle_ps( b.m_quad, b.m_quad, _MM_SHUFFLE(1,1,1,1) );
  267. hkQuadReal r1 = _mm_mul_ps( r.getColumn(1).m_quad, b1 );
  268. hkQuadReal b2 = _mm_shuffle_ps( b.m_quad, b.m_quad, _MM_SHUFFLE(2,2,2,2));
  269. hkQuadReal r2 = _mm_mul_ps( r.getColumn(2).m_quad, b2 );
  270. m_quad = _mm_add_ps( _mm_add_ps(r0, r1), _mm_add_ps(r2, t.getTranslation().m_quad ) );
  271. }
  272. inline void hkVector4::_setMul4xyz1(const hkTransform& t, const hkVector4& v)
  273. {
  274. _setTransformedPos( t, v );
  275. }
  276. inline void hkVector4::_setTransformedInversePos(const hkTransform& a, const hkVector4& b)
  277. {
  278. hkVector4 t0; t0.setSub4( b, a.getTranslation() );
  279. _setRotatedInverseDir(a.getRotation(), t0);
  280. }
  281. inline hkSimdReal hkVector4::dot3(const hkVector4& a) const
  282. {
  283. hkQuadReal x2 = _mm_mul_ps(m_quad,a.m_quad);
  284. hkQuadReal xySum = _mm_add_ss( _mm_shuffle_ps(x2,x2,_MM_SHUFFLE(1,1,1,1)), x2);
  285. return _mm_add_ss( _mm_shuffle_ps(x2,x2,_MM_SHUFFLE(2,2,2,2)), xySum);
  286. }
  287. inline void hkVector4::setDot3(hkVector4Parameter a, hkVector4Parameter b)
  288. {
  289. hkQuadReal x2 = _mm_mul_ps(a.m_quad, b.m_quad);
  290. hkQuadReal xySum = _mm_add_ss( _mm_shuffle_ps(x2,x2,_MM_SHUFFLE(1,1,1,1)), x2);
  291. m_quad = _mm_add_ss( _mm_shuffle_ps(x2,x2,_MM_SHUFFLE(2,2,2,2)), xySum);
  292. }
  293. inline hkReal hkVector4::dot3fpu(const hkVector4& a) const
  294. {
  295. const hkVector4& t = *this;
  296. return (t(0) * a(0)) + ( t(1) * a(1)) + ( t(2) * a(2) );
  297. }
  298. inline hkSimdReal hkVector4::dot4(const hkVector4& a) const
  299. {
  300. hkQuadReal x2 = _mm_mul_ps(m_quad,a.m_quad);
  301. hkQuadReal sum0 = _mm_add_ps( _mm_shuffle_ps(x2,x2,_MM_SHUFFLE(1,0,3,2)), x2); // w+z w+z x+y x+y
  302. hkQuadReal sum1 = _mm_shuffle_ps(sum0,sum0, _MM_SHUFFLE(2,3,0,1)); // x+y x+y w+z w+z
  303. return _mm_add_ps( sum0, sum1 ); // x+y+w+z all 4
  304. }
  305. inline void hkVector4::setDot4(hkVector4Parameter a, hkVector4Parameter b)
  306. {
  307. hkQuadReal x2 = _mm_mul_ps(a.m_quad, b.m_quad);
  308. hkQuadReal sum0 = _mm_add_ps( _mm_shuffle_ps(x2,x2,_MM_SHUFFLE(1,0,3,2)), x2); // w+z w+z x+y x+y
  309. hkQuadReal sum1 = _mm_shuffle_ps(sum0,sum0, _MM_SHUFFLE(2,3,0,1)); // x+y x+y w+z w+z
  310. m_quad = _mm_add_ps( sum0, sum1 ); // x+y+w+z all 4
  311. }
  312. inline hkSimdReal hkVector4::dot4xyz1(const hkVector4& a) const
  313. {
  314. hkQuadReal x2 = _mm_mul_ps(m_quad,a.m_quad);
  315. hkQuadReal xySum = _mm_add_ss( _mm_shuffle_ps(x2,x2,_MM_SHUFFLE(1,1,1,1)), x2);
  316. hkQuadReal zwSum = _mm_add_ss( _mm_shuffle_ps(x2,x2,_MM_SHUFFLE(2,2,2,2)), _mm_shuffle_ps(m_quad, m_quad, _MM_SHUFFLE(3,3,3,3)));
  317. return _mm_add_ps( xySum, zwSum ); // x+y+w+z all 4
  318. }
  319. inline hkSimdReal hkVector4::horizontalAdd3() const
  320. {
  321. hkQuadReal xySum = _mm_add_ss( _mm_shuffle_ps(m_quad,m_quad,_MM_SHUFFLE(1,1,1,1)), m_quad);
  322. return _mm_add_ss( _mm_shuffle_ps(m_quad,m_quad,_MM_SHUFFLE(2,2,2,2)), xySum);
  323. }
  324. inline hkSimdReal hkVector4::horizontalAdd4() const
  325. {
  326. hkQuadReal sum0 = _mm_add_ps( _mm_shuffle_ps(m_quad,m_quad,_MM_SHUFFLE(1,0,3,2)), m_quad); // w+z w+z x+y x+y
  327. hkQuadReal sum1 = _mm_shuffle_ps(sum0,sum0, _MM_SHUFFLE(2,3,0,1)); // x+y x+y w+z w+z
  328. return _mm_add_ps( sum0, sum1 ); // x+y+w+z all 4
  329. }
  330. inline hkSimdReal hkVector4::length3() const
  331. {
  332. return _mm_sqrt_ss( this->dot3(*this).getQuad() );
  333. }
  334. inline hkSimdReal hkVector4::lengthSquared3() const
  335. {
  336. return this->dot3(*this);
  337. }
  338. inline hkSimdReal hkVector4::lengthInverse3() const
  339. {
  340. //HK_ASSERT2(0xf0435654, this->lengthSquared3() > 0, "hkVector4 too small for lengthInverse3");
  341. const hkQuadReal half  = _mm_set_ss(0.5f);
  342. const hkQuadReal three = _mm_set_ss(3.0f);
  343. const hkQuadReal zero  = _mm_set_ss(0.0f);
  344. const hkQuadReal len2 = this->dot3(*this).getQuad();
  345. const hkQuadReal len2EqualsZero = _mm_cmpeq_ss(len2, zero);
  346. const hkQuadReal approx = _mm_rsqrt_ss(len2);
  347. const hkQuadReal refined = _mm_mul_ss(
  348. _mm_mul_ss(half, approx),
  349. _mm_sub_ss(three, _mm_mul_ss( _mm_mul_ss(len2, approx), approx ) ) );
  350. // Ensures that we return 0 if the length is 0
  351. return _mm_andnot_ps(len2EqualsZero, refined);
  352. }
  353. inline hkSimdReal hkVector4::length4() const
  354. {
  355. return _mm_sqrt_ss( this->dot4(*this).getQuad() );
  356. }
  357. inline hkSimdReal hkVector4::lengthSquared4() const
  358. {
  359. return this->dot4(*this);
  360. }
  361. inline hkSimdReal hkVector4::lengthInverse4() const
  362. {
  363. const hkQuadReal half  = _mm_set_ss(0.5f);
  364. const hkQuadReal three = _mm_set_ss(3.0f);
  365. const hkQuadReal zero  = _mm_set_ss(0.0f);
  366. const hkQuadReal len2 = this->dot4(*this).getQuad();
  367. const hkQuadReal len2EqualsZero = _mm_cmpeq_ss(len2, zero);
  368. const hkQuadReal approx = _mm_rsqrt_ss(len2);
  369. const hkQuadReal refined = _mm_mul_ss(
  370. _mm_mul_ss(half, approx),
  371. _mm_sub_ss(three, _mm_mul_ss( _mm_mul_ss(len2, approx), approx ) ) );
  372. // Ensures that we return 0 if the length is 0
  373. return _mm_andnot_ps(len2EqualsZero, refined);
  374. }
  375. inline void hkVector4::normalize3()
  376. {
  377. hkQuadReal lenInv = lengthInverse3().broadcast();
  378. m_quad = _mm_mul_ps(lenInv, m_quad);
  379. //HK_ASSERT2(0xf0435f54, this->lengthSquared3() > 0.5f, "hkVector4 cannot be normalized");
  380. }
  381. inline hkSimdReal hkVector4::normalizeWithLength3()
  382. {
  383. HK_ASSERT2(0xf043f654, this->lengthSquared3() > 0, "hkVector4 too small for lengthInverse3");
  384. const hkQuadReal half  = _mm_set_ss(0.5f);
  385. const hkQuadReal three = _mm_set_ss(3.0f);
  386. hkQuadReal len2 = this->dot3(*this).getQuad();
  387. hkQuadReal approx = _mm_rsqrt_ss(len2);
  388. hkQuadReal lenInv = _mm_mul_ss(
  389. _mm_mul_ss(half, approx),
  390. _mm_sub_ss(three, _mm_mul_ss( _mm_mul_ss(len2, approx), approx ) ) );
  391. lenInv = _mm_shuffle_ps(lenInv, lenInv, _MM_SHUFFLE(0,0,0,0) );
  392. m_quad = _mm_mul_ps(lenInv, m_quad);
  393. return _mm_mul_ss(len2, lenInv); // quicker to return x^2/x
  394. }
  395. inline void hkVector4::normalize4()
  396. {
  397. hkQuadReal lenInv = lengthInverse4().broadcast();
  398. m_quad = _mm_mul_ps(lenInv, m_quad);
  399. }
  400. inline hkSimdReal hkVector4::normalizeWithLength4()
  401. {
  402. const hkQuadReal half  = _mm_set_ss(0.5f);
  403. const hkQuadReal three = _mm_set_ss(3.0f);
  404. hkQuadReal len2 = this->dot4(*this).getQuad();
  405. hkQuadReal approx = _mm_rsqrt_ss(len2);
  406. hkQuadReal lenInv = _mm_mul_ss(
  407. _mm_mul_ss(half, approx),
  408. _mm_sub_ss(three, _mm_mul_ss( _mm_mul_ss(len2, approx), approx ) ) );
  409. lenInv = _mm_shuffle_ps(lenInv, lenInv, _MM_SHUFFLE(0,0,0,0) );
  410. m_quad = _mm_mul_ps(lenInv, m_quad);
  411. return _mm_mul_ss(len2, lenInv); // quicker to return x^2/x
  412. }
  413. inline void hkVector4::fastNormalize3()
  414. {
  415. hkQuadReal len2 = this->dot3(*this).getQuad();
  416. hkSimdReal approx = _mm_rsqrt_ss(len2);
  417. m_quad = _mm_mul_ps(m_quad, approx.broadcast());
  418. }
  419. inline void hkVector4::fastNormalize3NonZero()
  420. {
  421. hkQuadReal len2 = this->dot3(*this).getQuad();
  422. hkSimdReal approx = _mm_rsqrt_ss(len2);
  423. m_quad = _mm_mul_ps(m_quad, approx.broadcast());
  424. }
  425. inline hkSimdReal hkVector4::fastNormalizeWithLength3()
  426. {
  427. hkQuadReal len2 = this->dot3(*this).getQuad();
  428. hkQuadReal approx = _mm_rsqrt_ss(len2);
  429. approx = _mm_shuffle_ps(approx, approx, _MM_SHUFFLE(0,0,0,0) );
  430. m_quad = _mm_mul_ps(m_quad, approx);
  431. return _mm_mul_ss(len2, approx);
  432. }
  433. /* operator () */
  434. inline hkReal& hkVector4::operator() (int a)
  435. {
  436. return reinterpret_cast<hkReal*>(&m_quad)[a];
  437. }
  438. inline const hkReal& hkVector4::operator() (int a) const
  439. {
  440. return reinterpret_cast<const hkReal*>(&m_quad)[a];
  441. }
  442. #define HK_VECTOR4_COMBINE_XYZ_W(xyz, w) 
  443. _mm_shuffle_ps( xyz, _mm_unpackhi_ps(xyz, w), _MM_SHUFFLE(3,0,1,0))
  444. inline void hkVector4::setXYZW(const hkVector4& xyz, const hkVector4& w)
  445. {
  446. m_quad = HK_VECTOR4_COMBINE_XYZ_W(xyz.m_quad, w.m_quad);
  447. }
  448. inline void hkVector4::setW(const hkVector4& w)
  449. {
  450. m_quad = HK_VECTOR4_COMBINE_XYZ_W(m_quad, w.m_quad);
  451. }
  452. inline void hkVector4::setXYZ(const hkVector4& xyz)
  453. {
  454. m_quad = HK_VECTOR4_COMBINE_XYZ_W(xyz.m_quad, m_quad);
  455. }
  456. inline void hkVector4::setXYZ0(const hkVector4& xyz)
  457. {
  458. static HK_ALIGN16( const hkUint32 cw[4] ) = { 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000 };
  459. m_quad = _mm_and_ps( xyz, *(const hkQuadReal*)&cw );
  460. }
  461. inline void hkVector4::setReciprocal4(const hkVector4& vec)
  462. {
  463. m_quad = hkMath::quadReciprocal(vec.m_quad);
  464. }
  465. inline void hkVector4::setSqrtInverse4(const hkVector4& vec)
  466. {
  467. m_quad = hkMath::quadReciprocalSquareRoot(vec.m_quad);
  468. }
  469. inline hkSimdReal hkVector4::getSimdAt(int i) const
  470. {
  471. HK_ASSERT2(0x6d0c31d7, i>=0 && i<4, "index out of bounds for element access");
  472. switch(i)
  473. {
  474. case 0:
  475. return m_quad;
  476. case 1:
  477. return _mm_shuffle_ps(m_quad, m_quad, _MM_SHUFFLE(1,1,1,1));
  478. case 2:
  479. return _mm_shuffle_ps(m_quad, m_quad, _MM_SHUFFLE(2,2,2,2));
  480. case 3:
  481. default:
  482. return _mm_shuffle_ps(m_quad, m_quad, _MM_SHUFFLE(3,3,3,3));
  483. }
  484. }
  485. inline void hkVector4::broadcast(int i)
  486. {
  487. HK_ASSERT2(0x32b298db, i>=0 && i<4, "index out of bounds for broadcast");
  488. if( i == 0 )
  489. {
  490. m_quad = _mm_shuffle_ps(m_quad, m_quad, _MM_SHUFFLE(0,0,0,0));
  491. }
  492. else if( i == 1 )
  493. {
  494. m_quad = _mm_shuffle_ps(m_quad, m_quad, _MM_SHUFFLE(1,1,1,1));
  495. }
  496. else if( i == 2 )
  497. {
  498. m_quad = _mm_shuffle_ps(m_quad, m_quad, _MM_SHUFFLE(2,2,2,2));
  499. }
  500. else if( i == 3 )
  501. {
  502. m_quad = _mm_shuffle_ps(m_quad, m_quad, _MM_SHUFFLE(3,3,3,3));
  503. }
  504. }
  505. inline void hkVector4::setBroadcast(const hkVector4& v, int i)
  506. {
  507. HK_ASSERT2(0x7d6992c5, i>=0 && i<4, "index out of bounds for broadcast");
  508. if( i == 0 )
  509. {
  510. m_quad = _mm_shuffle_ps(v.m_quad, v.m_quad, _MM_SHUFFLE(0,0,0,0));
  511. }
  512. else if( i == 1 )
  513. {
  514. m_quad = _mm_shuffle_ps(v.m_quad, v.m_quad, _MM_SHUFFLE(1,1,1,1));
  515. }
  516. else if( i == 2 )
  517. {
  518. m_quad = _mm_shuffle_ps(v.m_quad, v.m_quad, _MM_SHUFFLE(2,2,2,2));
  519. }
  520. else if( i == 3 )
  521. {
  522. m_quad = _mm_shuffle_ps(v.m_quad, v.m_quad, _MM_SHUFFLE(3,3,3,3));
  523. }
  524. }
  525. inline void hkVector4::setBroadcast3clobberW(const hkVector4& v, int i)
  526. {
  527. setBroadcast( v, i );
  528. }
  529. inline void hkVector4::_setTransformedPos(const hkQsTransform& a, const hkVector4& b)
  530. {
  531. hkVector4 temp(b);
  532. temp.mul4(a.m_scale);
  533. setRotatedDir(a.m_rotation, temp);
  534. add4(a.m_translation);
  535. }
  536. inline void hkVector4::_setTransformedInversePos(const hkQsTransform& a, const hkVector4& b)
  537. {
  538. hkVector4 temp(b);
  539. temp.sub4(a.m_translation);
  540. setRotatedInverseDir(a.m_rotation, temp);
  541. hkVector4 invScale; invScale.setReciprocal4(a.m_scale);
  542. mul4(invScale);
  543. }
  544. #define HK_VECTOR4_load4a
  545. inline void hkVector4::load4a(const hkReal* p)
  546. {
  547. HK_ASSERT2(0x64211c2f, ( ((hkUlong)p) & 0xf ) == 0, "p must be 16-byte aligned.");
  548. m_quad = _mm_load_ps(p);
  549. }
  550. #define HK_VECTOR4_store4a
  551. inline void hkVector4::store4a(hkReal* p) const
  552. {
  553. HK_ASSERT2(0x6b865439, ( ((hkUlong)p) & 0xf ) == 0, "p must be 16-byte aligned.");
  554. _mm_store_ps(p, m_quad);
  555. }
  556. #define HK_VECTOR4_load4
  557. inline void hkVector4::load4(const hkReal* p)
  558. {
  559. m_quad = _mm_loadu_ps(p);
  560. }
  561. /*
  562. * Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20090216)
  563. * Confidential Information of Havok.  (C) Copyright 1999-2009
  564. * Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
  565. * Logo, and the Havok buzzsaw logo are trademarks of Havok.  Title, ownership
  566. * rights, and intellectual property rights in the Havok software remain in
  567. * Havok and/or its suppliers.
  568. * Use of this software for evaluation purposes is subject to and indicates
  569. * acceptance of the End User licence Agreement for this product. A copy of
  570. * the license is included with this software and is also available at www.havok.com/tryhavok.
  571. */