Team Fortress 2 Source Code as on 22/4/2020
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.

198 lines
4.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "physics_friction.h"
  8. #include "vphysics/friction.h"
  9. #include "ivp_mindist.hxx"
  10. #include "ivp_listener_collision.hxx"
  11. #include "ivp_friction.hxx"
  12. // memdbgon must be the last include file in a .cpp file!!!
  13. #include "tier0/memdbgon.h"
  14. class CFrictionSnapshot : public IPhysicsFrictionSnapshot
  15. {
  16. public:
  17. CFrictionSnapshot( IVP_Real_Object *pObject );
  18. ~CFrictionSnapshot();
  19. bool IsValid();
  20. // Object 0 is this object, Object 1 is the other object
  21. IPhysicsObject *GetObject( int index );
  22. int GetMaterial( int index );
  23. void GetContactPoint( Vector &out );
  24. void GetSurfaceNormal( Vector &out );
  25. float GetNormalForce();
  26. float GetEnergyAbsorbed();
  27. void RecomputeFriction();
  28. void ClearFrictionForce();
  29. void MarkContactForDelete();
  30. void DeleteAllMarkedContacts( bool wakeObjects );
  31. void NextFrictionData();
  32. float GetFrictionCoefficient();
  33. private:
  34. void SetFrictionSynapse( IVP_Synapse_Friction *pSet );
  35. CUtlVector<IVP_Real_Object *> *m_pDeleteList;
  36. IVP_Real_Object *m_pObject;
  37. IVP_Synapse_Friction *m_pFriction;
  38. IVP_Contact_Point *m_pContactPoint;
  39. int m_synapseIndex;
  40. };
  41. CFrictionSnapshot::CFrictionSnapshot( IVP_Real_Object *pObject ) : m_pObject(pObject)
  42. {
  43. m_pDeleteList = NULL;
  44. SetFrictionSynapse( pObject->get_first_friction_synapse() );
  45. }
  46. CFrictionSnapshot::~CFrictionSnapshot()
  47. {
  48. delete m_pDeleteList;
  49. }
  50. void CFrictionSnapshot::DeleteAllMarkedContacts( bool wakeObjects )
  51. {
  52. if ( !m_pDeleteList )
  53. return;
  54. for ( int i = 0; i < m_pDeleteList->Count(); i++ )
  55. {
  56. if ( wakeObjects )
  57. {
  58. m_pDeleteList->Element(i)->ensure_in_simulation();
  59. }
  60. DeleteAllFrictionPairs( m_pObject, m_pDeleteList->Element(i) );
  61. }
  62. m_pFriction = NULL;
  63. }
  64. void CFrictionSnapshot::SetFrictionSynapse( IVP_Synapse_Friction *pSet )
  65. {
  66. if ( pSet )
  67. {
  68. m_pFriction = pSet;
  69. m_pContactPoint = pSet->get_contact_point();
  70. m_synapseIndex = (pSet == m_pContactPoint->get_synapse(0)) ? 0 : 1;
  71. }
  72. else
  73. {
  74. m_pFriction = NULL;
  75. m_pContactPoint = NULL;
  76. m_synapseIndex = 0;
  77. }
  78. }
  79. bool CFrictionSnapshot::IsValid()
  80. {
  81. return m_pFriction != NULL ? true : false;
  82. }
  83. IPhysicsObject *CFrictionSnapshot::GetObject( int index )
  84. {
  85. IVP_Synapse_Friction *pFriction = m_pFriction;
  86. if ( index == 1 )
  87. {
  88. pFriction = m_pContactPoint->get_synapse(!m_synapseIndex);
  89. }
  90. return static_cast<IPhysicsObject *>(pFriction->get_object()->client_data);
  91. }
  92. void CFrictionSnapshot::MarkContactForDelete()
  93. {
  94. IVP_Synapse_Friction *pFriction = m_pContactPoint->get_synapse(!m_synapseIndex);
  95. IVP_Real_Object *pObject = pFriction->get_object();
  96. Assert(pObject != m_pObject);
  97. if ( pObject != m_pObject )
  98. {
  99. if ( !m_pDeleteList )
  100. {
  101. m_pDeleteList = new CUtlVector<IVP_Real_Object *>;
  102. }
  103. m_pDeleteList->AddToTail( pObject );
  104. }
  105. }
  106. int CFrictionSnapshot::GetMaterial( int index )
  107. {
  108. IVP_Material *ivpMats[2];
  109. m_pContactPoint->get_material_info(ivpMats);
  110. // index 1 is the other one
  111. index ^= m_synapseIndex;
  112. return physprops->GetIVPMaterialIndex( ivpMats[index] );
  113. }
  114. void CFrictionSnapshot::GetContactPoint( Vector &out )
  115. {
  116. ConvertPositionToHL( *m_pContactPoint->get_contact_point_ws(), out );
  117. }
  118. void CFrictionSnapshot::GetSurfaceNormal( Vector &out )
  119. {
  120. float sign[2] = {1,-1};
  121. IVP_U_Float_Point normal;
  122. IVP_Contact_Point_API::get_surface_normal_ws(const_cast<IVP_Contact_Point *>(m_pContactPoint), &normal );
  123. ConvertDirectionToHL( normal, out );
  124. out *= sign[m_synapseIndex];
  125. VectorNormalize(out);
  126. }
  127. float CFrictionSnapshot::GetFrictionCoefficient()
  128. {
  129. return m_pContactPoint->get_friction_factor();
  130. }
  131. float CFrictionSnapshot::GetNormalForce()
  132. {
  133. return ConvertDistanceToHL( IVP_Contact_Point_API::get_vert_force( m_pContactPoint ) );
  134. }
  135. float CFrictionSnapshot::GetEnergyAbsorbed()
  136. {
  137. return ConvertEnergyToHL( IVP_Contact_Point_API::get_eliminated_energy( m_pContactPoint ) );
  138. }
  139. void CFrictionSnapshot::RecomputeFriction()
  140. {
  141. m_pContactPoint->recompute_friction();
  142. }
  143. void CFrictionSnapshot::ClearFrictionForce()
  144. {
  145. m_pContactPoint->set_friction_to_neutral();
  146. }
  147. void CFrictionSnapshot::NextFrictionData()
  148. {
  149. SetFrictionSynapse( m_pFriction->get_next() );
  150. }
  151. IPhysicsFrictionSnapshot *CreateFrictionSnapshot( IVP_Real_Object *pObject )
  152. {
  153. return new CFrictionSnapshot( pObject );
  154. }
  155. void DestroyFrictionSnapshot( IPhysicsFrictionSnapshot *pSnapshot )
  156. {
  157. delete pSnapshot;
  158. }
  159. void DeleteAllFrictionPairs( IVP_Real_Object *pObject0, IVP_Real_Object *pObject1 )
  160. {
  161. pObject0->unlink_contact_points_for_object( pObject1 );
  162. }