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.

140 lines
3.2 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "rope_helpers.h"
  9. #include "basetypes.h"
  10. #include "mathlib/mathlib.h"
  11. #include "rope_shared.h"
  12. #include "rope_physics.h"
  13. #include "networkvar.h"
  14. // memdbgon must be the last include file in a .cpp file!!!
  15. #include "tier0/memdbgon.h"
  16. class CHangRope : public CRopePhysics<512>
  17. {
  18. DECLARE_CLASS( CHangRope, CRopePhysics<512> );
  19. // CRopePhysics overrides.
  20. public:
  21. virtual void GetNodeForces( CSimplePhysics::CNode *pNodes, int iNode, Vector *pAccel )
  22. {
  23. pAccel->Init( ROPE_GRAVITY );
  24. }
  25. virtual void ApplyConstraints( CSimplePhysics::CNode *pNodes, int nNodes )
  26. {
  27. // Apply spring forces.
  28. BaseClass::ApplyConstraints( pNodes, nNodes );
  29. // Lock the endpoints.
  30. pNodes[0].m_vPos = m_vEndPoints[0];
  31. pNodes[nNodes-1].m_vPos = m_vEndPoints[1];
  32. // Calculate how far it is hanging down and adjust if necessary.
  33. float flCurHangDist = 0;
  34. for ( int i=0; i < NumNodes(); i++ )
  35. {
  36. float hang = fabs( m_flStartZ - GetNode(i)->m_vPos.z );
  37. if ( hang > flCurHangDist )
  38. flCurHangDist = hang;
  39. }
  40. // Adjust our spring length accordingly.
  41. if ( flCurHangDist < m_flWantedHangDist )
  42. m_flCurSlack += 1;
  43. else
  44. m_flCurSlack -= 1;
  45. ApplyNewSpringLength();
  46. }
  47. // Helpers.
  48. public:
  49. void ApplyNewSpringLength()
  50. {
  51. ResetSpringLength( (m_flRopeLength + m_flCurSlack + ROPESLACK_FUDGEFACTOR) / (NumNodes() - 1) );
  52. }
  53. // Variables used to adjust the rope slack.
  54. public:
  55. Vector m_vEndPoints[2];
  56. bool m_bAdjustSlack;
  57. float m_flRopeLength;
  58. float m_flCurSlack;
  59. float m_flWantedHangDist;
  60. float m_flStartZ;
  61. };
  62. void CalcRopeStartingConditions(
  63. const Vector &vStartPos,
  64. const Vector &vEndPos,
  65. int const nNodes,
  66. float const desiredHang,
  67. float *pOutputLength,
  68. float *pOutputSlack
  69. )
  70. {
  71. CHangRope rope;
  72. // Initialize the rope as a straight line with no slack as our first approximation.
  73. // We then relax the rope by adding slack until it hangs to the desired height.
  74. //
  75. // The spring length equation is:
  76. // springLength = (ropeLength + slack + ROPESLACK_FUDGEFACTOR) / (nNodes - 1)
  77. //
  78. // We want our rope to be a straight line, so:
  79. // springLength = ropeLength / (nNodes-1)
  80. //
  81. // Therefore our initial slack is -ROPESLACK_FUDGEFACTOR
  82. rope.m_flCurSlack = -ROPESLACK_FUDGEFACTOR;
  83. rope.m_vEndPoints[0] = vStartPos;
  84. rope.m_vEndPoints[1] = vEndPos;
  85. rope.m_flRopeLength = (vEndPos - vStartPos).Length();
  86. rope.m_flWantedHangDist = desiredHang;
  87. rope.m_flStartZ = MIN( vStartPos.z, vEndPos.z ); // Calculate hang as the Z distance from the
  88. // lowest endpoint to the bottom of the rope.
  89. rope.SetNumNodes( nNodes );
  90. // Set the node positions.
  91. for ( int i=0; i < rope.NumNodes(); i++ )
  92. {
  93. CSimplePhysics::CNode *pNode = rope.GetNode( i );
  94. float t = (float)i / (rope.NumNodes() - 1);
  95. VectorLerp( vStartPos, vEndPos, t, pNode->m_vPos );
  96. pNode->m_vPrevPos = pNode->m_vPos;
  97. }
  98. // Now simulate a little and stretch out to let it hang down.
  99. rope.Restart();
  100. rope.Simulate( 3 );
  101. // Set outputs.
  102. *pOutputLength = rope.m_flRopeLength;
  103. *pOutputSlack = rope.m_flCurSlack;
  104. }