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

其他游戏

开发平台:

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. #ifndef HK_MATH_VECTOR4_H
  9. #define HK_MATH_VECTOR4_H
  10. #ifndef HK_MATH_MATH_H
  11. # error Please include Common/Base/hkBase.h instead of this file.
  12. #endif
  13. /// Stores four hkReals in a SIMD friendly format.
  14. /// Although an hkVector4 - as its name suggests - actually stores four hkReals, 
  15. /// it can be used to represent either a point or vector (x,y,z) in 3-space, ie. a 3-vector.
  16. /// The final, or w, value of the hkVector4 defaults to zero.
  17. /// Note that some methods have the suffix '3' or '4' - for instance, there is dot3()
  18. /// method and a dot4() method. This suffix indicates whether the method operates
  19. /// on the first three, or all four, elements of the hkVector4. 
  20. /// As you can see, some methods have a '4' version but no '3' version because
  21. /// there is no generic hardware support for that operation. Other methods,
  22. /// such as setMul(), have no suffixes because there is no ambiguity regarding
  23. /// the elements on which they operate. 
  24. class hkVector4
  25. {
  26. public:
  27. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR(HK_MEMORY_CLASS_MATH, hkVector4);
  28. #ifndef HK_DISABLE_VECTOR4_CONSTRUCTORS
  29. /// Empty constructor.
  30. HK_FORCE_INLINE hkVector4() { }
  31. /// Creates a new hkVector4 from the specified three or four reals, with the obvious definition.
  32. HK_FORCE_INLINE hkVector4(hkReal x, hkReal y, hkReal z, hkReal w=0);
  33. /// Creates a new hkVector4, copying all 4 values from q.
  34. HK_FORCE_INLINE hkVector4(const hkQuadReal& q);
  35. #ifndef HK_PLATFORM_PS3_SPU // This constructor causes the compiler NOT to pass const hkVector4's by register.
  36. /// Creates a new hkVector4, copying all 4 values from v.
  37. HK_FORCE_INLINE hkVector4( const hkVector4& v);
  38. #endif
  39. #endif
  40. /// Copies all 4 values from v.
  41. HK_ALWAYS_INLINE void operator= ( const hkVector4& v );
  42. /// Copies all 4 values from v.
  43. HK_ALWAYS_INLINE void operator= ( const hkQuadReal& v ); 
  44. /// Sets the hkVector4's components using the specified three or four reals, with the obvious definition.
  45. HK_ALWAYS_INLINE void set(hkReal x, hkReal y, hkReal z, hkReal w=0);
  46. #if HK_CONFIG_SIMD == HK_CONFIG_SIMD_ENABLED
  47. /// Sets all the hkVector4's components to the same value x.
  48. HK_FORCE_INLINE void setAll(hkSimdRealParameter x);
  49. #endif
  50. /// Sets all the hkVector4's components to the same value x.
  51. HK_ALWAYS_INLINE void setAll(hkReal x);
  52. /// Sets the xyz hkVector4's components to the same value x. The w component will be destroyed.
  53. HK_ALWAYS_INLINE void setAll3(hkReal x);
  54. /// Sets all values to zero.
  55. HK_ALWAYS_INLINE void setZero4();
  56. /// Sets the .w component as an integer with 24 bit resolution (for real experts only).
  57. HK_FORCE_INLINE void setInt24W( int value );
  58. /// Gets the .w component as an integer with 24 bit resolution (for real experts only).
  59. HK_FORCE_INLINE int getInt24W( ) const ;
  60. /// Sets this to be a, bypassing the processors cache.
  61. HK_FORCE_INLINE void storeUncached( void* dest) const;
  62. /* vector methods */
  63. /// Modifies this hkVector4 by adding the value of a to it.  All four components are modified.
  64. HK_ALWAYS_INLINE void add4(const hkVector4& a);
  65. /// Modifies this hkVector4 by adding the value of a to it.  Three components are modified, the w component is unspecified.
  66. HK_ALWAYS_INLINE void add3clobberW(const hkVector4& a);
  67. /// Sets this hkVector4 to be the sum of a and b. All four components are modified.
  68. HK_ALWAYS_INLINE void setAdd4(const hkVector4& a, const hkVector4& b);
  69. /// Modifies this hkVector4 by subtracting the value of a from it.  All four components are modified.
  70. HK_ALWAYS_INLINE void sub4(const hkVector4& a);
  71. /// Modifies this hkVector4 by subtracting the value of a from it.  All three components are modified, the .w component is unspecified.
  72. HK_FORCE_INLINE void sub3clobberW(const hkVector4& a);
  73. /// Sets this hkVector4 to be the difference of a and b. All four components are modified.
  74. HK_ALWAYS_INLINE void setSub4(const hkVector4& a, const hkVector4& b);
  75. /// Modifies this hkVector4 by setting it to be the product of itself and the vector a.  All four components are multiplied by a.
  76. HK_ALWAYS_INLINE void mul4(const hkVector4& a);
  77. /// Sets this hkVector4 to be the product of a and b. All four components are modified.
  78. HK_ALWAYS_INLINE void setMul4(hkVector4Parameter a, hkVector4Parameter b);
  79. /// Modifies this hkVector4 by setting it to be the product of itself with the real value a.  All four components are multiplied by a.
  80. HK_ALWAYS_INLINE void mul4(hkSimdRealParameter a);
  81. /// Sets this hkVector4 to be the product of the real value r and the vector b. All four components are modified.
  82. HK_ALWAYS_INLINE void setMul4(hkSimdRealParameter r, const hkVector4& a);
  83. /// Modifies this hkVector4 by adding the product of real r and vector a to it.  All four components are modified.
  84. HK_ALWAYS_INLINE void addMul4(hkSimdRealParameter r, const hkVector4& a);
  85. /// Modifies this hkVector4 by adding the component-wise product of a and b to it.  All four components are modified.
  86. HK_ALWAYS_INLINE void addMul4(hkVector4Parameter a, hkVector4Parameter b);
  87. /// Modifies this hkVector4 by subtracting the product of real r and vector a from it.  All four components are modified.
  88. HK_ALWAYS_INLINE void subMul4(hkSimdRealParameter r, const hkVector4& a);
  89. /// Modifies this hkVector4 by subtracting the component-wise product of a and b from it.  All four components are modified.
  90. HK_ALWAYS_INLINE void subMul4(hkVector4Parameter a, hkVector4Parameter b);
  91. /// Shortcut for *this = a, this->addMul(r,b).  All four components are modified.
  92. HK_ALWAYS_INLINE void setAddMul4(const hkVector4& a, const hkVector4& b, hkSimdRealParameter r);
  93. /// Shortcut for *this = a, this->addMul(x,y).  All four components are modified.
  94. HK_ALWAYS_INLINE void setAddMul4(const hkVector4& a, const hkVector4& x, const hkVector4& y);
  95. /// Sets this hkVector4 to be the cross product of a and b. (this = a cross b).
  96. HK_FORCE_INLINE void setCross( const hkVector4& a, const hkVector4& b );
  97. /// Sets this hkVector4 to a linear interpolation of the vectors a and b.
  98. /// The parameter t specifies the relative position along the line segment defined by
  99. /// a and b.  With t = 0, the start of the line segment - the point a - will be returned.
  100. /// The interpolation is calculated using the following formula: (1 - t) * a + t * b.
  101. HK_ALWAYS_INLINE void setInterpolate4( const hkVector4& a, const hkVector4& b, hkSimdRealParameter t);
  102. /* equality */
  103. /// Compares the x, y, z elements of the vectors and returns nonzero if equal to given epsilon.
  104. HK_FORCE_INLINE hkBool32 equals3(const hkVector4 &a, hkReal epsilon = 1e-3f ) const;
  105. /// Compares all elements of the vectors, including the w component, and returns nonzero if to given epsilon.
  106. HK_FORCE_INLINE hkBool32 equals4(const hkVector4 &a, hkReal epsilon = 1e-3f ) const;
  107. /// Elementwise compare.  Use the mask methods to examine the result.
  108. HK_FORCE_INLINE hkVector4Comparison compareLessThan4(hkVector4Parameter a) const;
  109. /// Elementwise compare.  Use the mask methods to examine the result.
  110. HK_FORCE_INLINE hkVector4Comparison compareEqual4(hkVector4Parameter a) const;
  111. /// Elementwise compare.  Use the mask methods to examine the result.
  112. HK_FORCE_INLINE hkVector4Comparison compareLessThanEqual4(hkVector4Parameter a) const;
  113. /// Elementwise compare.  Use the mask methods to examine the result.
  114. HK_FORCE_INLINE hkVector4Comparison compareLessThanZero4() const;
  115. /// Elementwise compare.  Use the mask methods to examine the result.
  116. HK_FORCE_INLINE hkVector4Comparison compareGreaterThan4(hkVector4Parameter a) const;
  117. /// Elementwise compare.  Use the mask methods to examine the result.
  118. HK_FORCE_INLINE hkVector4Comparison compareGreaterThanEqual4(hkVector4Parameter a) const;
  119. /// Return nonzero if x,y,z components of this are less than the corresponding elements of a.
  120. HK_FORCE_INLINE hkBool32 allLessThan3(hkVector4Parameter a) const;
  121. /// Return nonzero if all components of this are less than the corresponding elements of a.
  122. HK_FORCE_INLINE hkBool32 allLessThan4(hkVector4Parameter a) const;
  123. /// Each 32 bit component is set to the component of b if the corresponding bit in comp is set, otherwise a. i.e.
  124. /// this.x = comp.getMask( hkVector4Comparison::MASK_X ) ? b.x : a.x; and so on for each component.
  125. HK_FORCE_INLINE void select32( hkVector4Parameter a, hkVector4Parameter b, const hkVector4Comparison& comp);
  126. /* neg, abs, min, max */
  127. /// Sets this vectors components to -v.x,-v.y,-v.z,+v.w
  128. HK_FORCE_INLINE void setNeg3(const hkVector4& v);
  129. /// Sets this vector to the value of v with the signs of all the elements flipped.
  130. HK_FORCE_INLINE void setNeg4(const hkVector4& v);
  131. /// Sets this vector to the value of v with the signs of all the elements flipped if cond is true.
  132. HK_FORCE_INLINE void setNeg4If( int cond );
  133. /// Gets the absolute value of all elements in v and stores the result in this vector.
  134. HK_FORCE_INLINE void setAbs4(const hkVector4& v);
  135. /// Finds the element wise minimum of the elements in a and b and stores the result in this vector.
  136. HK_FORCE_INLINE void setMin4(const hkVector4& a, const hkVector4& b);
  137. /// Finds the element wise maximum of the elements in a and b and stores the result in this vector.
  138. HK_FORCE_INLINE void setMax4(const hkVector4& a, const hkVector4& b);
  139. /* matrix3, rotation, quaternion, transform */
  140. /// Sets this object to be the product of the matrix a and the vector b.
  141. /// The w component of the result is undefined.  (this = a * b)
  142. void setMul3(const hkMatrix3& a, const hkVector4& b ); 
  143. /// Sets this vector to the vector b rotated by the rotation matrix a. (this = a * b)
  144. void setRotatedDir(const hkRotation& a, const hkVector4& b);
  145. /// Sets this vector to the vector b rotated by the inverse of the rotation matrix a. (this = a^-1 * b)
  146. /// This operation depends on a being orthonormal.
  147. void setRotatedInverseDir(const hkRotation& a, const hkVector4& b);
  148. /// Sets this vector to the vector b rotated by the quaternion a. (this = q b q^-1)
  149. HK_FORCE_INLINE void setRotatedDir(const hkQuaternion& q, const hkVector4& b);
  150. /// Sets this vector to the vector b rotated by the inverse of quaternion a. (this = q^-1 b q)
  151. HK_FORCE_INLINE void setRotatedInverseDir(const hkQuaternion& q, const hkVector4& b);
  152. /// Sets this vector to the vector b transformed by a. (this = a * b)
  153. void setTransformedPos(const hkTransform& a, const hkVector4& b);
  154. /// Sets this vector to the vector b transformed by the inverse of the transform a. 
  155. /// (this = a^-1 * b)
  156. void setTransformedInversePos(const hkTransform& a, const hkVector4& b);
  157. /// Sets this vector to the vector b transformed by a. (this = a * b): use _setTransformedPos if you want the inline version
  158. void setTransformedPos(const hkQsTransform& a, const hkVector4& b);
  159. /// Sets this vector to the vector b "inversely transformed" by the Qs transform a. 
  160. /// Notice that this is not the same as this := Inv(a) * b whenever scale is present
  161. /// Note:  use _setTransformedPos if you want the inline version
  162. void setTransformedInversePos(const hkQsTransform& a, const hkVector4& b);
  163. /* HK_FORCE_INLINE versions of above */
  164. /// Sets this object to be the product of the 3x3 matrix a and the 3 vector b.
  165. /// The w component of the result is undefined.  (this = a * b)
  166. HK_FORCE_INLINE void _setMul3(const hkMatrix3& a, const hkVector4& b ); 
  167. /// Sets this object to be the product of the 4x3 matrix a and the 3 vector.
  168. /// The w component of the result is defined.  (this = a * b)
  169. void _setMul4(const hkMatrix3& a, const hkVector4& b ); 
  170. /// Sets this object to be the product of the matrix a and the vector b.  
  171. /// (this = a * (bx,by,bz,1.f))
  172. HK_FORCE_INLINE void _setMul4xyz1(const hkTransform& a, const hkVector4& b ); 
  173. /// Inlined.  Sets this vector to the vector b rotated by the rotation matrix a. (this = a * b)
  174. HK_FORCE_INLINE void _setRotatedDir(const hkRotation& a, const hkVector4& b);
  175. /// Inlined.  Sets this vector to the vector b rotated by the inverse of the rotation matrix a. (this = a^-1 * b)
  176. HK_FORCE_INLINE void _setRotatedInverseDir(const hkRotation& a, const hkVector4& b);
  177. /// Inlined.  Sets this vector to the vector b transformed by a. (this = a * b)
  178. HK_FORCE_INLINE void _setTransformedPos(const hkTransform& a, const hkVector4& b);
  179. /// Inlined.  Sets this vector to the vector b transformed by the inverse of the transform a. 
  180. /// (this = a^-1 * b)
  181. HK_FORCE_INLINE void _setTransformedInversePos(const hkTransform& a, const hkVector4& b);
  182. /// Sets this vector to the vector b transformed by a. (this = a * b)
  183. HK_FORCE_INLINE void _setTransformedPos(const hkQsTransform& a, const hkVector4& b);
  184. /// Sets this vector to the vector b "inversely transformed" by the Qs transform a. 
  185. /// Notice that this is not the same as this := Inv(a) * b whenever scale is present
  186. HK_FORCE_INLINE void _setTransformedInversePos(const hkQsTransform& a, const hkVector4& b);
  187. /* length and distance */
  188. /// Returns the dot product of the 3-vector represented by the x, y and z components.
  189. HK_FORCE_INLINE hkSimdReal dot3(const hkVector4& a) const;
  190. /// Sets the x component only to the 3 element (x,y,z) dot product of a and b.
  191. /// The x,y,z values are destroyed.
  192. HK_FORCE_INLINE void setDot3(hkVector4Parameter a, hkVector4Parameter b);
  193. /// Returns the dot product of the 3-vector represented by the x, y and z components, is only using the FPU
  194. HK_FORCE_INLINE hkReal dot3fpu(const hkVector4& a) const;
  195. /// Returns the dot product of the 4-vector represented by the x, y, z and w components.
  196. HK_FORCE_INLINE hkSimdReal dot4(const hkVector4& a) const;
  197. /// Sets all 4 elements to the 4 element dot product of a and b.
  198. HK_FORCE_INLINE void setDot4(hkVector4Parameter a, hkVector4Parameter b);
  199. /// Returns this.x * a.x + this.y * a.y + this.z * a.z + this.w * 1.0f
  200. /// Note: the w component of a is replaced by 1.0f
  201. HK_FORCE_INLINE hkSimdReal dot4xyz1(const hkVector4& a) const;
  202. /// Returns x + y + z.
  203. HK_FORCE_INLINE hkSimdReal horizontalAdd3() const;
  204. /// Returns x + y + z + w.
  205. HK_FORCE_INLINE hkSimdReal horizontalAdd4() const;
  206. /// Returns the length of the 3-vector represented by the x, y, and z components
  207. HK_FORCE_INLINE hkSimdReal length3() const;
  208. /// Returns the squared length of the 3-vector represented by the x, y, and z components.
  209. /// This avoids the square root calculation.
  210. HK_FORCE_INLINE hkSimdReal lengthSquared3() const;
  211. /// Returns the inverse length of the 3-vector represented by the x, y, and z components.
  212. HK_FORCE_INLINE hkSimdReal lengthInverse3() const;
  213. /// Returns the length of the distance between this point and the point p.
  214. HK_FORCE_INLINE hkSimdReal distanceTo3( hkVector4Parameter p ) const;
  215. /// Returns the length of the 4-vector represented by the x, y, z and w components.
  216. HK_FORCE_INLINE hkSimdReal length4() const;
  217. /// Returns the squared length of the 4-vector represented by the x, y, z and w components.
  218. /// This avoids the square root calculation.
  219. HK_FORCE_INLINE hkSimdReal lengthSquared4() const;
  220. /// Returns the inverse length of the 4-vector represented by the x, y, z and w components.
  221. HK_FORCE_INLINE hkSimdReal lengthInverse4() const;
  222. /// Normalizes the 3-vector represented by the x, y, and z components.
  223. /// The w component of the result is undefined.
  224. HK_FORCE_INLINE void normalize3();
  225. /// Normalizes the 3-vector represented by the x, y, and z components, returning the original length.
  226. /// The w component of the result is undefined.
  227. HK_FORCE_INLINE hkSimdReal normalizeWithLength3();
  228. /// Normalizes the 4-vector represented by the x, y, z and w components.
  229. HK_FORCE_INLINE void normalize4();
  230. /// Normalizes the 4-vector represented by the x, y, z and w components, returning the original length.
  231. HK_FORCE_INLINE hkSimdReal normalizeWithLength4();
  232. /// Fast/low accuracy normalize of the 3-vector represented by the x, y, and z components. 
  233. /// The w component of the result is undefined.
  234. HK_FORCE_INLINE void fastNormalize3();
  235. /// Fast/low accuracy normalize of the 3-vector represented by the x, y, z components.
  236. /// Returns the original length.  The w component of the result is undefined.
  237. HK_FORCE_INLINE hkSimdReal fastNormalizeWithLength3();
  238. /// Fast/low accuracy normalize of the 3-vector represented by the x, y, z components.
  239. /// The w component of the result is undefined. Assumes that the input is non zero.
  240. HK_FORCE_INLINE void fastNormalize3NonZero();
  241. //HK_FORCE_INLINE hkSimdReal fastLengthInverse3();
  242. /// Normalizes the vector if the length of the 3-vector is not exactly zero. 
  243. /// Returns HK_SUCCESS if normalization occurred (length not zero)
  244. /// or HK_FAILURE if the 3-vector's length was exactly zero.
  245. HK_FORCE_INLINE hkResult normalize3IfNotZero ();
  246. /* element access */
  247. /// Gives read/write access to element i.  (0,1,2,3) correspond to the (x,y,z,w) components respectively.
  248. HK_FORCE_INLINE hkReal& operator() (int i);
  249. /// Gives read only access to element i.  (0,1,2,3) correspond to the (x,y,z,w) components respectively.
  250. HK_FORCE_INLINE const hkReal& operator() (int i) const;
  251. /// Set the xyz,w components.
  252. HK_FORCE_INLINE void setXYZW(const hkVector4& xyz, const hkVector4& w);
  253. /// Set the w component to be v.w
  254. HK_FORCE_INLINE void setW(const hkVector4& v);
  255. /// Set the xyz components. W component is unchanged.
  256. HK_FORCE_INLINE void setXYZ(const hkVector4& v);
  257. /// Set the xyz components. W component is set to zero.
  258. HK_FORCE_INLINE void setXYZ0(const hkVector4& xyz);
  259. /// Sets each element to the reciprocal of the corresponding element of v.
  260. HK_FORCE_INLINE void setReciprocal4(const hkVector4& v);
  261. /// Sets the xyz components to the reciprocal of the corresponding element of v, w set to 1.
  262. HK_FORCE_INLINE void setReciprocal3(const hkVector4& v);
  263. /// Sets each element to its inverse square root.
  264. HK_FORCE_INLINE void setSqrtInverse4(const hkVector4& v);
  265. /// Gives read only access to element i.  (0,1,2,3) correspond to the (x,y,z,w) components respectively.
  266. /// Using this method instead of operator() can give the compiler greater opportunity for optimization.
  267. HK_ALWAYS_INLINE hkSimdReal getSimdAt(int i) const;
  268. /// Faster version of setAll( this->getSimdAt(i) )
  269. HK_ALWAYS_INLINE void broadcast(int i);
  270. /// this.xyzw = v(i)
  271. HK_ALWAYS_INLINE void setBroadcast(hkVector4Parameter v, int i);
  272. /// this.xyz = v(i), w is unspecified, faster, especially on PlayStation(R)2
  273. HK_ALWAYS_INLINE void setBroadcast3clobberW(hkVector4Parameter v, int i);
  274. /// returns the index of the axis that is closest to this vector.
  275. HK_FORCE_INLINE int getMajorAxis() const;
  276. /// Gives read/write access to the internal 128bit quad representation of the hkVector4.
  277. HK_ALWAYS_INLINE hkQuadReal& getQuad();
  278. /// Gives read only access to the internal 128bit quad representation of the hkVector4.
  279. HK_ALWAYS_INLINE const hkQuadReal& getQuad() const;
  280. /// Checks that the first 3 elements are valid numbers.
  281. hkBool isOk3() const;
  282. /// Checks that all elements are valid numbers.
  283. hkBool isOk4() const;
  284. /// Checks that the length of the vector is one
  285. hkBool isNormalized3(hkReal eps = 1e-4f) const;
  286. /// Checks that the length of the vector is one
  287. hkBool isNormalized4(hkReal eps = 1e-4f) const;
  288. /// Sets element i of this vector to zero.
  289. /// Calling this->zeroElement(0) zeroes the x component, 
  290. /// this->zeroElement(1) the y, this->zeroElement(2) the z, and this->zeroElement(3) the w.
  291. HK_FORCE_INLINE void zeroElement( int i );
  292. ///Gets an hkVector4 with all components set to zero.
  293. HK_ALWAYS_INLINE static const hkVector4& HK_CALL getZero();
  294. /// Load from 4 byte aligned address. Last element is undefined.
  295. void load3(const hkReal* p);
  296. /// Load from 4 byte aligned address.
  297. void load4(const hkReal* p);
  298. /// Load from 16 byte aligned address.
  299. void load4a(const hkReal* p);
  300. /// Store to 4 byte aligned address. Last element is undefined.
  301. void store3(hkReal* p) const;
  302. /// Store to 4 byte aligned address.
  303. void store4(hkReal* p) const;
  304. /// Store to 16 byte aligned address.
  305. void store4a(hkReal* p) const;
  306. private:
  307. #if HK_CONFIG_SIMD == HK_CONFIG_SIMD_ENABLED || defined(HK_PLATFORM_RVL)
  308. hkQuadReal m_quad;
  309. public:
  310. operator hkQuadReal() const
  311. {
  312. return m_quad;
  313. }
  314. #else
  315. HK_ALIGN16( hkReal x );
  316. hkReal y;
  317. hkReal z;
  318. hkReal w;
  319. #endif
  320. };
  321. #endif //HK_MATH_VECTOR4_H
  322. /*
  323. * Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20090216)
  324. * Confidential Information of Havok.  (C) Copyright 1999-2009
  325. * Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
  326. * Logo, and the Havok buzzsaw logo are trademarks of Havok.  Title, ownership
  327. * rights, and intellectual property rights in the Havok software remain in
  328. * Havok and/or its suppliers.
  329. * Use of this software for evaluation purposes is subject to and indicates
  330. * acceptance of the End User licence Agreement for this product. A copy of
  331. * the license is included with this software and is also available at www.havok.com/tryhavok.
  332. */