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.

171 lines
6.1 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "physics_controller_raycast_vehicle.h"
  8. #include "ivp_material.hxx"
  9. #include "ivp_ray_solver.hxx"
  10. #include "ivp_cache_object.hxx"
  11. // memdbgon must be the last include file in a .cpp file!!!
  12. #include "tier0/memdbgon.h"
  13. //-----------------------------------------------------------------------------
  14. // Purpose: Constructor
  15. //-----------------------------------------------------------------------------
  16. CPhysics_Car_System_Raycast_Wheels::CPhysics_Car_System_Raycast_Wheels( IVP_Environment *pEnv,
  17. const IVP_Template_Car_System *pCarSystem )
  18. : IVP_Controller_Raycast_Car( pEnv, pCarSystem )
  19. {
  20. InitCarSystemWheels( pCarSystem );
  21. }
  22. //-----------------------------------------------------------------------------
  23. // Purpose: Deconstructor
  24. //-----------------------------------------------------------------------------
  25. CPhysics_Car_System_Raycast_Wheels::~CPhysics_Car_System_Raycast_Wheels()
  26. {
  27. }
  28. //-----------------------------------------------------------------------------
  29. // Purpose: Setup the car system wheels.
  30. //-----------------------------------------------------------------------------
  31. void CPhysics_Car_System_Raycast_Wheels::InitCarSystemWheels( const IVP_Template_Car_System *pCarSystem )
  32. {
  33. for ( int iWheel = 0; iWheel < pCarSystem->n_wheels; ++iWheel )
  34. {
  35. m_pWheels[iWheel] = pCarSystem->car_wheel[iWheel];
  36. m_pWheels[iWheel]->enable_collision_detection( IVP_FALSE );
  37. }
  38. }
  39. //-----------------------------------------------------------------------------
  40. // Purpose: Get the raycast wheel.
  41. //-----------------------------------------------------------------------------
  42. IPhysicsObject *CPhysics_Car_System_Raycast_Wheels::GetWheel( int index )
  43. {
  44. Assert( index >= 0 );
  45. Assert( index < n_wheels );
  46. return ( IPhysicsObject* )m_pWheels[index]->client_data;
  47. }
  48. //-----------------------------------------------------------------------------
  49. // Purpose: Setup the car system wheels.
  50. //-----------------------------------------------------------------------------
  51. void CPhysics_Car_System_Raycast_Wheels::do_raycasts( IVP_Event_Sim *es,
  52. int n_wheels,
  53. class IVP_Ray_Solver_Template *t_in,
  54. class IVP_Ray_Hit *hits_out,
  55. IVP_FLOAT *friction_of_object_out )
  56. {
  57. t_in[0].ray_flags = IVP_RAY_SOLVER_ALL;
  58. int j = 0;
  59. IVP_Ray_Solver_Min ray_solver0(&t_in[j]);
  60. j++; if ( j >= n_wheels) j--;
  61. IVP_Ray_Solver_Min ray_solver1(&t_in[j]);
  62. j++; if ( j >= n_wheels) j--;
  63. IVP_Ray_Solver_Min ray_solver2(&t_in[j]);
  64. j++; if ( j >= n_wheels) j--;
  65. IVP_Ray_Solver_Min ray_solver3(&t_in[j]);
  66. IVP_Ray_Solver_Min *solvers[4] = { &ray_solver0, &ray_solver1, &ray_solver2, &ray_solver3 };
  67. IVP_Ray_Solver_Group rs_group( n_wheels, (IVP_Ray_Solver **)solvers );
  68. #if 0
  69. // Debug!
  70. IVP_CarSystemDebugData_t carSystemDebugData;
  71. GetCarSystemDebugData( carSystemDebugData );
  72. carSystemDebugData.wheelRaycasts[0][0] = ray_solver0.ray_start_point;
  73. carSystemDebugData.wheelRaycasts[0][1] = ray_solver0.ray_end_point;
  74. carSystemDebugData.wheelRaycasts[1][0] = ray_solver1.ray_start_point;
  75. carSystemDebugData.wheelRaycasts[1][1] = ray_solver1.ray_end_point;
  76. carSystemDebugData.wheelRaycasts[2][0] = ray_solver2.ray_start_point;
  77. carSystemDebugData.wheelRaycasts[2][1] = ray_solver2.ray_end_point;
  78. carSystemDebugData.wheelRaycasts[3][0] = ray_solver3.ray_start_point;
  79. carSystemDebugData.wheelRaycasts[3][1] = ray_solver3.ray_end_point;
  80. #endif
  81. // check which objects are hit
  82. rs_group.check_ray_group_against_all_objects_in_sim(es->environment);
  83. for ( int i = 0; i < n_wheels; i++ )
  84. {
  85. IVP_Ray_Hit *hit = solvers[i]->get_ray_hit();
  86. if (hit)
  87. {
  88. hits_out[i] = *hit;
  89. friction_of_object_out[i] = hit->hit_real_object->l_default_material->get_friction_factor();
  90. #if 0
  91. // Debug!
  92. carSystemDebugData.wheelRaycastImpacts[i] = ( hit->hit_distance / solvers[i]->ray_length );
  93. #endif
  94. }
  95. else
  96. {
  97. memset( &hits_out[i], 0, sizeof(IVP_Ray_Hit) );
  98. friction_of_object_out[i] = 0;
  99. #if 0
  100. // Debug!
  101. carSystemDebugData.wheelRaycastImpacts[i] = 0.0f;
  102. #endif
  103. }
  104. }
  105. #if 0
  106. // Debug!
  107. SetCarSystemDebugData( carSystemDebugData );
  108. #endif
  109. }
  110. void CPhysics_Car_System_Raycast_Wheels::update_wheel_positions( void )
  111. {
  112. // Get the car body object.
  113. IVP_Cache_Object *pCacheObject = car_body->get_cache_object();
  114. // Get the core (vehicle) matrix.
  115. IVP_U_Matrix m_core_f_object;
  116. car_body->calc_m_core_f_object( &m_core_f_object );
  117. for ( int iWheel = 0; iWheel < n_wheels; ++iWheel )
  118. {
  119. // Get the current raycast wheel.
  120. IVP_Raycast_Car_Wheel *pRaycastWheel = get_wheel( IVP_POS_WHEEL( iWheel ) );
  121. // Get the position of the wheel in vehicle core space.
  122. IVP_U_Float_Point hp_cs;
  123. hp_cs.add_multiple( &pRaycastWheel->hp_cs, &pRaycastWheel->spring_direction_cs, pRaycastWheel->raycast_dist - pRaycastWheel->wheel_radius );
  124. // Get the position on vehicle object space (inverse transform).
  125. IVP_U_Float_Point hp_os;
  126. m_core_f_object.vimult4( &hp_cs, &hp_os );
  127. // Transform the wheel position from object space into world space.
  128. IVP_U_Point hp_ws;
  129. pCacheObject->transform_position_to_world_coords( &hp_os, &hp_ws );
  130. // Apply rotational component.
  131. IVP_U_Point wheel_cs( &pRaycastWheel->axis_direction_cs );
  132. IVP_U_Point wheel2_cs( 0 ,0 ,0 );
  133. wheel2_cs.k[index_y] = -1.0;
  134. wheel2_cs.rotate( IVP_COORDINATE_INDEX( index_x ), pRaycastWheel->angle_wheel );
  135. IVP_U_Matrix3 m_core_f_wheel;
  136. m_core_f_wheel.init_normized3_col( &wheel_cs, IVP_COORDINATE_INDEX( index_x ), &wheel2_cs );
  137. IVP_U_Matrix3 m_world_f_wheel;
  138. pCacheObject->m_world_f_object.mmult3( &m_core_f_wheel, &m_world_f_wheel ); // bid hack, assumes cs = os (for rotation);
  139. IVP_U_Quat rot_ws;
  140. rot_ws.set_quaternion( &m_world_f_wheel );
  141. m_pWheels[iWheel]->beam_object_to_new_position( &rot_ws, &hp_ws );
  142. }
  143. pCacheObject->remove_reference();
  144. }