hkSweptTransformUtil.inl
上传用户: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. void HK_CALL hkSweptTransformUtil::_lerp2( const hkSweptTransform& sweptTrans, hkReal t, hkQuaternion& quatOut )
  9. {
  10. hkVector4 rot0 = sweptTrans.m_rotation0.m_vec;
  11. hkVector4 rot1 = sweptTrans.m_rotation1.m_vec;
  12. {
  13. quatOut.m_vec.setAdd4( rot0, rot1 );
  14. #ifdef HK_PS2
  15. quatOut.normalize();
  16. #else
  17. hkReal len2 = quatOut.m_vec.lengthSquared4();
  18. hkReal r = 0.75f - 0.125f * len2;
  19. r = r * (1.5f - 0.5f * len2 * r * r);
  20. quatOut.m_vec.mul4(r);
  21. #endif
  22. }
  23. if ( t < 0.5f )
  24. {
  25. quatOut.m_vec.setInterpolate4( rot0, quatOut.m_vec, 2.0f * t);
  26. }
  27. else
  28. {
  29. quatOut.m_vec.setInterpolate4( quatOut.m_vec, rot1, 2.0f * t - 1.0f);
  30. }
  31. quatOut.m_vec.normalize4();
  32. }
  33. void HK_CALL hkSweptTransformUtil::_lerp2( const hkSweptTransform& sweptTrans, hkReal t, hkTransform& transformOut )
  34. {
  35. hkQuaternion qt;
  36. _lerp2( sweptTrans, t, qt );
  37. transformOut.setRotation( qt );
  38. transformOut.getTranslation().setInterpolate4( sweptTrans.m_centerOfMass0, sweptTrans.m_centerOfMass1, t);
  39. hkVector4 centerShift;
  40. centerShift._setRotatedDir( transformOut.getRotation(), sweptTrans.m_centerOfMassLocal);
  41. transformOut.getTranslation().sub4( centerShift );
  42. }
  43. void HK_CALL hkSweptTransformUtil::calcTransAtT0( const hkSweptTransform& sweptTrans, hkTransform& transformOut )
  44. {
  45. const hkQuaternion& qt = sweptTrans.m_rotation0;
  46. transformOut.setRotation( qt );
  47. hkVector4 centerShift;
  48. centerShift._setRotatedDir( transformOut.getRotation(), sweptTrans.m_centerOfMassLocal);
  49. transformOut.getTranslation().setSub4( sweptTrans.m_centerOfMass0, centerShift );
  50. }
  51. void HK_CALL hkSweptTransformUtil::calcTransAtT1( const hkSweptTransform& sweptTrans, hkTransform& transformOut )
  52. {
  53. const hkQuaternion& qt = sweptTrans.m_rotation1;
  54. transformOut.setRotation( qt );
  55. hkVector4 centerShift;
  56. centerShift._setRotatedDir( transformOut.getRotation(), sweptTrans.m_centerOfMassLocal);
  57. transformOut.getTranslation().setSub4( sweptTrans.m_centerOfMass1, centerShift );
  58. }
  59. void HK_CALL hkSweptTransformUtil::_clipVelocities( const hkMotionState& motionState, hkVector4& linearVelocity, hkVector4& angularVelocity )
  60. {
  61. hkReal linVelSq = linearVelocity.lengthSquared3();
  62. hkReal angVelSq = angularVelocity.lengthSquared3();
  63. const hkReal maxLinear = motionState.m_maxLinearVelocity * motionState.m_maxLinearVelocity;
  64. const hkReal maxAngular = motionState.m_maxAngularVelocity * motionState.m_maxAngularVelocity;
  65. if ( (linVelSq > maxLinear) || (linVelSq!=linVelSq) )
  66. {
  67. hkReal f = motionState.m_maxLinearVelocity * hkMath::sqrtInverse( linVelSq );
  68. linearVelocity.mul4( f );
  69. if ( linVelSq!=linVelSq )
  70. {
  71. linearVelocity = hkTransform::getIdentity().getColumn(0);
  72. HK_WARN(0xf0124242, "Nan velocity detected, something is seriously wrong (probably bad inertia tensors)");
  73. }
  74. }
  75. if ( (angVelSq > maxAngular) || ( angVelSq != angVelSq ))
  76. {
  77. hkReal f = motionState.m_maxAngularVelocity * hkMath::sqrtInverse( angVelSq );
  78. angularVelocity.mul4( f );
  79. if ( angVelSq!=angVelSq )
  80. {
  81. angularVelocity = hkTransform::getIdentity().getColumn(0);
  82. HK_WARN(0xf0143243, "Nan velocity detected, something is seriously wrong (probably bad inertia tensors ");
  83. }
  84. }
  85. }
  86. // Has to be outside of inline function as gcc won't inline functions with statics in them.
  87. static hkQuadReal _stepMotionStateMaxVelf = HK_QUADREAL_CONSTANT(1e6f,1e6f,1e6f,1e6f);
  88. void HK_CALL hkSweptTransformUtil::_stepMotionState( const hkStepInfo& info,
  89.  hkVector4& linearVelocity, hkVector4& angularVelocity,
  90.  hkMotionState& motionState )
  91. {
  92. #ifdef HK_DEBUG
  93. {
  94. if ( motionState.getSweptTransform().getInvDeltaTime() != 0.0f)
  95. {
  96. hkReal motionEndTime = motionState.getSweptTransform().getBaseTime() + 1.0f / motionState.getSweptTransform().getInvDeltaTime();
  97. HK_ASSERT(0xf0f0083, hkMath::equal(info.m_startTime, motionEndTime ) ) ;
  98. }
  99. }
  100. #endif
  101. // check for nans in velocities
  102. // fix nans to 100
  103. {
  104. hkVector4 absLin; absLin.setAbs4( linearVelocity );
  105. hkVector4 absAng; absAng.setAbs4( angularVelocity );
  106. hkVector4 maxVel; maxVel.getQuad() = _stepMotionStateMaxVelf;
  107. int mask = absLin.compareLessThan4( maxVel ).getMask() & absAng.compareLessThan4( maxVel ).getMask();
  108. mask    &= linearVelocity.compareEqual4( linearVelocity ).getMask() & angularVelocity.compareEqual4( angularVelocity ).getMask();
  109. if ( (mask & hkVector4Comparison::MASK_XYZ) != hkVector4Comparison::MASK_XYZ )
  110. {
  111. // velocity to a 'random' non zero velocity
  112. linearVelocity  = hkTransform::getIdentity().getColumn(0);
  113. angularVelocity = hkTransform::getIdentity().getColumn(0);
  114. HK_WARN(0xf0123244, "Nan velocity or velocity > 1e6f detected, something is seriously wrong (probably bad inertia tensors ");
  115. }
  116. }
  117. motionState.getSweptTransform().m_centerOfMass0 = motionState.getSweptTransform().m_centerOfMass1;
  118. motionState.getSweptTransform().m_centerOfMass0(3) = info.m_startTime;
  119. hkReal linVelSq = linearVelocity.lengthSquared3();
  120. if ( linVelSq > motionState.m_maxLinearVelocity * motionState.m_maxLinearVelocity )
  121. {
  122. //HK_WARN_ONCE(0xf0327683, "Object exceeding maximum velocity, velocity clipped" );
  123. hkReal f = motionState.m_maxLinearVelocity * hkMath::sqrtInverse( linVelSq );
  124. linearVelocity.mul4( f );
  125. }
  126. motionState.getSweptTransform().m_centerOfMass1.addMul4(info.m_deltaTime.val(), linearVelocity);
  127. motionState.getSweptTransform().m_centerOfMass1(3) = info.m_invDeltaTime;
  128. hkQuaternion newRotation = motionState.getSweptTransform().m_rotation1;
  129. motionState.getSweptTransform().m_rotation0 = newRotation;
  130. //
  131. // Calculate a new rotation, the fabs angle and angle squared
  132. //
  133. hkReal angle;
  134. {
  135. hkQuaternion dq; dq.m_vec.setMul4( info.m_deltaTime * 0.5f, angularVelocity );
  136. const hkReal pi = HK_REAL_PI;
  137. hkReal dx2 = hkReal(dq.m_vec.lengthSquared3()) * (4.0f/ (pi*pi));
  138. // do a little sin(alpha * 0.5f) approximation
  139. const hkReal a = 0.822948f;
  140. const hkReal b = 0.130529f;
  141. const hkReal c = 0.044408f;
  142. const hkReal maxAnglePerStep = hkMath::min2( 0.9f, info.m_deltaTime.val() * motionState.m_maxAngularVelocity );
  143. // clipping angular velocity to be between [0, PI*0.9/dt]
  144. // info: was "<", is "<=" -- works ok for zero dt now.
  145. if ( dx2 <= maxAnglePerStep * maxAnglePerStep )
  146. {
  147. const hkReal dx4 = dx2 * dx2;
  148. const hkReal w = 1.0f - a*dx2 - b*dx4 - c*dx2*dx4;
  149. dq.m_vec(3) = w;
  150. }
  151. else
  152. {
  153. hkReal factor = maxAnglePerStep * hkMath::sqrtInverse( dx2 );
  154. angularVelocity.mul4( factor );
  155. dq.m_vec.mul4( factor );
  156.              dx2  = maxAnglePerStep*maxAnglePerStep;
  157. const hkReal dx4  = dx2 * dx2;
  158. const hkReal w    = 1.0f - a*dx2 - b*dx4 - c*dx2*dx4;
  159. dq.m_vec(3) = w;
  160. }
  161. newRotation.setMul( dq, newRotation );
  162. newRotation.normalize();
  163. motionState.m_deltaAngle.setAdd4( dq.m_vec, dq.m_vec );
  164. angle = hkMath::sqrt(dx2) * pi;
  165. motionState.m_deltaAngle(3) = angle;
  166. }
  167. motionState.getSweptTransform().m_rotation1 = newRotation;
  168. calcTransAtT1( motionState.getSweptTransform(), motionState.getTransform());
  169. }
  170. void HK_CALL hkSweptTransformUtil::deactivate( hkMotionState& ms )
  171. {
  172. hkSweptTransform& sweptTransform = ms.getSweptTransform();
  173. ms.m_deltaAngle.setZero4();
  174. sweptTransform.m_rotation0 = sweptTransform.m_rotation1;
  175. sweptTransform.m_centerOfMass0 = sweptTransform.m_centerOfMass1;
  176. sweptTransform.m_centerOfMass1(3) = 0.0f;
  177. }
  178. //void HK_CALL hkSweptTransformUtil::calcTimInfo( const hkMotionState& ms0, const hkMotionState& ms1, hkVector4& timOut)
  179. //{
  180. // HK_ASSERT2(0xad44d321, st0.getInvDeltaTime() == st1.getInvDeltaTime(), "Internal error: hkSweptTransform's must correspond to the same deltaTime in order to use void HK_CALL hkSweptTransformUtil::calcTimInfo( const hkMotionState& ms0, const hkMotionState& ms1, hkVector4& timOut)");
  181. //
  182. // const hkSweptTransform& st0 = ms0.getSweptTransform();
  183. // const hkSweptTransform& st1 = ms1.getSweptTransform();
  184. //
  185. // hkVector4 diff0; diff0.setSub4( st0.m_centerOfMass0, st0.m_centerOfMass1 );
  186. // hkVector4 diff1; diff1.setSub4( st1.m_centerOfMass1, st1.m_centerOfMass0 );
  187. //
  188. // timOut.setAdd4( diff0, diff1 );
  189. //
  190. // timOut(3) = ms0.m_deltaAngle(3) * ms0.m_objectRadius + ms1.m_deltaAngle(3) * ms1.m_objectRadius;
  191. //
  192. //}
  193. void HK_CALL hkSweptTransformUtil::calcTimInfo( const hkMotionState& ms0, const hkMotionState& ms1, hkReal deltaTime, hkVector4& timOut)
  194. {
  195. const hkSweptTransform& st0 = ms0.getSweptTransform();
  196. const hkSweptTransform& st1 = ms1.getSweptTransform();
  197. hkVector4 diff0; diff0.setSub4( st0.m_centerOfMass0, st0.m_centerOfMass1 );
  198. hkVector4 diff1; diff1.setSub4( st1.m_centerOfMass1, st1.m_centerOfMass0 );
  199. hkReal f0 = deltaTime * st0.getInvDeltaTime();
  200. hkReal f1 = deltaTime * st1.getInvDeltaTime();
  201. HK_ASSERT2(0xad56daaa, f0 <= 1.01f && f1 <= 1.01f, "Internal error: input for TIM calculation may be corrupted.");
  202. timOut.setMul4( f0, diff0 );
  203. timOut.addMul4( f1, diff1 );
  204. timOut(3) = f0 * ms0.m_deltaAngle(3) * ms0.m_objectRadius  + f1 * ms1.m_deltaAngle(3) * ms1.m_objectRadius;
  205. // we don't project angular velocity just to keep it simple ( no cross products)
  206. }
  207. // Calculates angular distance (angVelocity * dt) travelled by the bodies. 
  208. void HK_CALL hkSweptTransformUtil::calcAngularTimInfo( const hkMotionState& ms0, const hkMotionState& ms1, hkReal deltaTime, hkVector4* HK_RESTRICT deltaAngleOut0, hkVector4* HK_RESTRICT deltaAngleOut1)
  209. {
  210. const hkSweptTransform& st0 = ms0.getSweptTransform();
  211. const hkSweptTransform& st1 = ms1.getSweptTransform();
  212. hkReal f0 = deltaTime * st0.getInvDeltaTime();
  213. hkReal f1 = deltaTime * st1.getInvDeltaTime();
  214. hkVector4 ang0; ang0.setMul4( f0, ms0.m_deltaAngle );
  215. hkVector4 ang1; ang1.setMul4( f1, ms1.m_deltaAngle );
  216. deltaAngleOut0[0] = ang0;
  217. deltaAngleOut1[0] = ang1;
  218. }
  219. void HK_CALL hkSweptTransformUtil::calcCenterOfMassAt( const hkMotionState& ms, hkTime t, hkVector4& centerOut )
  220. {
  221. hkReal iv = ms.getSweptTransform().getInterpolationValue( t );
  222. centerOut.setInterpolate4( ms.getSweptTransform().m_centerOfMass0, ms.getSweptTransform().m_centerOfMass1, iv );
  223. }
  224. void HK_CALL hkSweptTransformUtil::getVelocity( const hkMotionState& ms, hkVector4& linearVelOut, hkVector4& angularVelOut )
  225. {
  226. linearVelOut.setSub4 (ms.getSweptTransform().m_centerOfMass1, ms.getSweptTransform().m_centerOfMass0);
  227. linearVelOut.mul4( ms.getSweptTransform().getInvDeltaTime() );
  228. angularVelOut.setMul4( ms.getSweptTransform().getInvDeltaTime(), ms.m_deltaAngle );
  229. }
  230. /*
  231. * Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20090216)
  232. * Confidential Information of Havok.  (C) Copyright 1999-2009
  233. * Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
  234. * Logo, and the Havok buzzsaw logo are trademarks of Havok.  Title, ownership
  235. * rights, and intellectual property rights in the Havok software remain in
  236. * Havok and/or its suppliers.
  237. * Use of this software for evaluation purposes is subject to and indicates
  238. * acceptance of the End User licence Agreement for this product. A copy of
  239. * the license is included with this software and is also available at www.havok.com/tryhavok.
  240. */