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

其他游戏

开发平台:

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_QUATERNION_H
  9. #define HK_MATH_QUATERNION_H
  10. #ifndef HK_MATH_MATH_H
  11. # error Please include Common/Base/hkBase.h instead of this file.
  12. #endif
  13. /// Stores a unit quaternion.
  14. /// "Unitness" is not enforced, but certain functions (such as division
  15. /// and inversion ) DO assume that the quaternions are unit quaternions.<br>
  16. ///
  17. /// <p><b>NOTE</b> - The constructor taking(hkVector4, hkReal) does not set real,imag
  18. ///    but assumes [angle,axis] format.</p>
  19. /// <p><b>NOTE</b> - getAxis() returns a valid value only if the angle of the rotation
  20. ///    is nonzero, since the axis is undefined for a rotation of zero degrees
  21. ///    and it is not possible to return it even if the Quaternion was created
  22. ///    from an angle and axis. It was decided that returning an arbitrary
  23. ///    axis would be confusing, so it is up to you to check that the
  24. ///    stored axis is nonzero before attempting to get the axis.
  25. ///    Otherwise, a division by zero Will occur.</p>
  26. /// <br>
  27. /// <b>Conventions adopted:</b><br>
  28. /// <ul><li>When specified by an (angle,axis) pair, the standard mathematical convention is
  29. /// followed, with the angle taken to be such that Quaternion(PI/2, Vector4(0,0,1))
  30. /// will rotate the X vector (1,0,0) to the Y vector (0,0,1). If you are converting to/from a system
  31. /// where such a quaternion would rotate X to -Y, then you will need to flip the angle or axis
  32. /// to convert successfully.</li>
  33. ///
  34. /// <li>p/q is assumed to be p * ( q-inverse ). This
  35. /// is an arbitrary decision since ( q-inverse ) * p is also plausible.<br>
  36. /// </li>
  37. /// <li>The angle extracted by getAngle() is ALWAYS in the range 0 -> PI, since we
  38. /// wish to resolve the ambiguity of storing R(a,v) as either q(a,v) or -q(a,v)
  39. /// It would be nice to assume the real part of q was always positive,
  40. /// but operations involving conversion from transform to quaternion or
  41. /// quaternion multiplication may not preserve this. The best we can do
  42. /// (without more code checking) is to let R(a,v) be stored as either,
  43. /// and overload the == operator to check both possibilities.
  44. /// Note that the storage is (imag, real)
  45. /// ((xyz), w  )</li></ul>
  46. class hkQuaternion
  47. {
  48. public:
  49. HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR(HK_MEMORY_CLASS_MATH, hkQuaternion);
  50. /// Empty constructor.
  51. inline hkQuaternion() { }
  52. /// Constructs a quaternion directly from its component elements.
  53. /// The imaginary part is (ix,iy,iz) and the real part r.
  54. inline hkQuaternion(hkReal ix, hkReal iy, hkReal iz, hkReal r);
  55. /// Constructs a quaternion from the rotation matrix r.
  56. explicit inline hkQuaternion(const hkRotation& r);
  57. /// Constructs a quaternion from an axis and an angle.  The rotation
  58. /// will take place about that axis by angle radians.
  59. /// N.B. The axis MUST be normalized.
  60. inline hkQuaternion(const hkVector4& axis, hkReal angle);
  61. /// Copy this quaternion.
  62. inline void operator= (const hkQuaternion& q);
  63. /// Set this quaternion with imaginary part (ix,iy,iz) and real part r.
  64. inline void set(hkReal ix, hkReal iy, hkReal iz, hkReal r);
  65. /// Get a reference to an identity quaternion.
  66. /// Note that setIdentity will likely be faster as it does not incur a memory access.
  67. static inline const hkQuaternion& HK_CALL getIdentity();
  68. /// Sets this quaternion to the unit quaternion. (this = (0, 0, 0, 1))
  69. inline void setIdentity();
  70. /// Sets this quaternion to be the inverse of the quaternion q. (this = q^-1)
  71. inline void setInverse( const hkQuaternion &q );
  72. /// Normalizes the quaternion. (this = q/|q|)
  73. inline void normalize();
  74. /// Sets this quaternion to the product of r by q. (this = r * q)
  75. inline void setMul(hkSimdRealParameter r, const hkQuaternion& q);
  76. /// Adds the product of r and q to this quaternion. (this += r * q)
  77. inline void addMul(hkSimdRealParameter r, const hkQuaternion& q);
  78. /// Sets this quaternion to the product of q0 and q1. (this = q0 * q1)
  79. inline void setMul(const hkQuaternion& q0, const hkQuaternion& q1);
  80. /// Multiplies this quaternion by q. (this *= q)
  81. inline void mul(const hkQuaternion& q);
  82. /// Set this quaternion to be the product of q0 and the inverse of q1.
  83. /// (this = (q0 * q1^-1)
  84. inline void setMulInverse(const hkQuaternion& q0, const hkQuaternion& q1);
  85. /// Set this quaternion to be the product of inverse q0 and q1.
  86. /// (this = (q0^-1 * q1)
  87. inline void setInverseMul(const hkQuaternion& q0, const hkQuaternion& q1);
  88. /// returns an estimate for an angle to get from 'this' to 'to'
  89. /// This function has a pretty good accuracy for angles less than 20 degrees
  90. /// and underestimates the angle for bigger values.
  91. inline void estimateAngleTo(const hkQuaternion& to, hkVector4& angleOut) const;
  92. /// Sets this quaternion to be the shortest rotation which brings 'from' to 'to'
  93. /// NOTE: The vectors 'from ' and 'to' must be normalized.
  94. inline void setShortestRotation(const hkVector4& from, const hkVector4& to);
  95. /// Sets this quaternion to be the shortest rotation which brings 'from' to 'to'
  96. /// NOTE: The vectors 'from ' and 'to' must be normalized.
  97. /// This version is damped and the result interpolates from 'from' to to' as gain goes from 0 to 1
  98. /// This is similar to scaling the angle of rotation according to the gain.
  99. inline void setShortestRotationDamped(hkReal gain, const hkVector4& from, const hkVector4& to);
  100. /// Sets/initializes this quaternion given a rotation axis and angle.
  101. /// N.B. The axis MUST be normalized.
  102. void setAxisAngle(const hkVector4& axis, hkReal angle);
  103. /// Sets/initializes this quaternion from a given rotation matrix.
  104. /// The rotation r must be orthonormal.
  105. void set(const hkRotation& r);
  106. /// Sets/initializes this quaternion from a given rotation matrix.
  107. void setAndNormalize(const hkRotation& r);
  108. /// Removes the component of this quaternion that represents a rotation (twist) around the given axis.
  109. /// In more accurate terms, it converts this quaternion (q) to the smallest (smallest angle) 
  110. /// rotation (q') that still satisfies q * axis = q' * axis.
  111. /// This is done by applying calculating axis' = q * axis. Then, from axis and axis' a perpendicular 
  112. /// vector (v) is calculated, as well as the angle between axis and axis' (ang). The result of the 
  113. /// operation is the rotation specified by the angle (ang) and the axis (v).
  114. void removeAxisComponent (const hkVector4& axis);
  115. /// Decomposes the quaternion and returns the amount of rotation around the given axis, and the rest
  116. /// (this) == Quaternion(axis, angle) * rest ,  where "rest" is the rest of rotation. This is done
  117. /// by calculating "rest" using removeAxisComponent() and then calculating (axis,angle) as 
  118. /// this * inv (rest).
  119. void decomposeRestAxis (const hkVector4& axis, hkQuaternion& restOut, hkReal& angleOut) const;
  120. /// Calculates the spherical linear interpolation between q0 and q1
  121. /// parameterized by t.  If t is 0 then the result will be q0.
  122. void setSlerp(const hkQuaternion& q0, const hkQuaternion& q1, hkReal t);
  123. /* access access */
  124. /// Sets the real component of this quaternion.
  125. inline void setReal(hkReal r);
  126. /// Returns the real component of this quaternion.
  127. inline hkReal getReal() const;
  128. /// Sets the imaginary component of this quaternion.
  129. inline void setImag(const hkVector4& );
  130. /// Returns a read only reference to the imaginary component of this quaternion.
  131. HK_ALWAYS_INLINE const hkVector4& getImag() const;
  132. /// This method extracts the angle of rotation, always returning it as a real in
  133. /// the range [0,PI].
  134. /// NOTE - The standard mathematical convention is followed, with the angle taken to be 
  135. /// such that Quaternion((0,0,1), PI/2,) will rotate the X vector (1,0,0) to the Y vector (0,0,1).
  136. /// If you are converting to/from a system where such a quaternion would rotate X to -Y, 
  137. /// then you will need to flip the angle or axis to convert successfully.n
  138. /// code
  139. /// hkQuaternion q((1,0,0), -0.7);
  140. /// hkReal ang = q.getAngle() ;
  141. /// // ang is now 0.7 radians (and a call to getAxis() will return (-1,0,0) )
  142. /// endcode
  143. inline hkReal getAngle()const;
  144.     /// Return the normalized axis of rotation IF DEFINED.
  145. /// The axis is not defined for a zero rotation (getAngle() returns 0.0f, or getReal() returns 1 or -1)
  146. /// The direction of the axis is determined by the sign of the angle returned by getAngle(), so that
  147. /// getAxis() and getAngle() return consistent values. N.B. getAngle() always returns a *positive* value.
  148. ///
  149. /// NOTE - The standard mathematical convention is followed, with the angle taken to be 
  150. /// such that Quaternion((0,0,1), PI/2) will rotate the X vector (1,0,0) to the Y vector (0,0,1).
  151. /// If you are converting to/from a system where such a quaternion would rotate X to -Y, 
  152. /// then you will need to flip the angle or axis to convert successfully.n
  153. ///
  154. /// NOTE - getAxis() returns a valid value ONLY if the angle of the rotation
  155. /// is (numerically) nonzero, since the axis is undefined for a rotation of zero degrees
  156. /// and it is not possible to return it even if the Quaternion was created
  157. /// from an angle and axis. It was decided that returning an arbitrary
  158. /// axis would be confusing, so it is up to the user to check that the
  159. /// stored axis is nonzero before attempting to get the axis.
  160. /// Otherwise, a division by zero will occur.  The function hasValidAxis()
  161. /// may be called to determine if calls to getAxis() will return a valid vector.
  162. /// eg. hkQuaternion((1,0,0), 1.5 PI) will return:
  163. /// 0.5 PI as angle
  164. /// (-1,0,0) as axis.
  165. inline void getAxis(hkVector4 &axis) const;
  166. /// Determines if the quaternion has a valid axis of rotation.  See getAxis()
  167. inline hkBool hasValidAxis() const;
  168. /// Read only access to the i'th component of this quaternion. (stored as (ix,iy,iz,real))
  169. inline const hkReal& operator()(int i) const;
  170. /// Checks that all elements are valid numbers, and length is 1.0 (within 1e-3)
  171. hkBool isOk() const;
  172. public:
  173. hkVector4 m_vec;
  174. protected:
  175. void setFlippedRotation(const hkVector4& from);
  176. };
  177. inline const hkQuaternion& HK_CALL hkQuaternion::getIdentity()
  178. {
  179. extern const hkQuaternion hkQuaternionIdentity;
  180. return hkQuaternionIdentity;
  181. }
  182. #endif //HK_MATH_QUATERNION_H
  183. /*
  184. * Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20090216)
  185. * Confidential Information of Havok.  (C) Copyright 1999-2009
  186. * Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
  187. * Logo, and the Havok buzzsaw logo are trademarks of Havok.  Title, ownership
  188. * rights, and intellectual property rights in the Havok software remain in
  189. * Havok and/or its suppliers.
  190. * Use of this software for evaluation purposes is subject to and indicates
  191. * acceptance of the End User licence Agreement for this product. A copy of
  192. * the license is included with this software and is also available at www.havok.com/tryhavok.
  193. */