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.

303 lines
13 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #ifndef PHYSICS_AIRBOAT_H
  7. #define PHYSICS_AIRBOAT_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "ivp_controller.hxx"
  12. #include "ivp_car_system.hxx"
  13. class IPhysicsObject;
  14. class IVP_Ray_Solver_Template;
  15. class IVP_Ray_Hit;
  16. class IVP_Event_Sim;
  17. #define IVP_RAYCAST_AIRBOAT_MAX_WHEELS 4
  18. //-----------------------------------------------------------------------------
  19. //-----------------------------------------------------------------------------
  20. class IVP_Raycast_Airboat_Wheel
  21. {
  22. public:
  23. // static section
  24. IVP_U_Float_Point hp_cs; // hard point core system projected on y plane
  25. IVP_U_Float_Point raycast_start_cs; // ray cast start position
  26. IVP_U_Float_Point raycast_dir_cs;
  27. IVP_FLOAT raycast_length;
  28. IVP_U_Float_Point spring_direction_cs; // spring direction in core-space
  29. IVP_FLOAT distance_orig_hp_to_hp; // distance hp is moved by projecting it onto the y - plane
  30. IVP_FLOAT spring_len; // == pretension + distance_orig_hp_to_hp
  31. IVP_FLOAT spring_constant; // shock at wheel spring constant
  32. IVP_FLOAT spring_damp_relax; // shock at wheel spring dampening during relaxation
  33. IVP_FLOAT spring_damp_compress; // shock at wheel spring dampening during compression
  34. IVP_FLOAT max_rotation_speed; // max rotational speed of the wheel
  35. IVP_FLOAT wheel_radius; // wheel radius
  36. IVP_FLOAT inv_wheel_radius; // inverse wheel radius
  37. IVP_FLOAT friction_of_wheel; // wheel friction
  38. // dynamic section
  39. IVP_FLOAT torque; // torque applied to wheel
  40. IVP_BOOL wheel_is_fixed; // eg. handbrake (fixed = stationary)
  41. IVP_U_Float_Point axis_direction_cs; // axle direction in core-space
  42. IVP_FLOAT angle_wheel; // wheel angle
  43. IVP_FLOAT wheel_angular_velocity; // angular velocity of wheel
  44. // out
  45. IVP_U_Float_Point surface_speed_of_wheel_on_ground_ws; // actual speed in world-space
  46. IVP_FLOAT pressure; // force from gravity, mass of car, stabilizers, etc. on wheel
  47. IVP_FLOAT raycast_dist; // raycast distance to impact for wheel
  48. };
  49. //-----------------------------------------------------------------------------
  50. //-----------------------------------------------------------------------------
  51. class IVP_Raycast_Airboat_Impact
  52. {
  53. public:
  54. IVP_FLOAT friction_value; // combined (multiply) frictional value of impact surface and wheel
  55. IVP_FLOAT stabilizer_force; // force on wheel due to axle stabilization
  56. IVP_Real_Object *moveable_object_hit_by_ray; // moveable physics object hit by raycast
  57. IVP_U_Float_Point raycast_dir_ws; // raycast direction in world-space
  58. IVP_U_Float_Point spring_direction_ws; // spring direction (raycast for impact direction) in world-space
  59. IVP_U_Float_Point surface_speed_wheel_ws; // wheel speed in world-space
  60. IVP_U_Float_Point projected_surface_speed_wheel_ws; // ???
  61. IVP_U_Float_Point axis_direction_ws; // axle direction in world-space
  62. IVP_U_Float_Point projected_axis_direction_ws; // ???
  63. IVP_FLOAT forces_needed_to_drive_straight; // forces need to keep the vehicle driving straight (attempt and directional wheel friction)
  64. IVP_FLOAT inv_normal_dot_dir; // ???
  65. // Impact information.
  66. IVP_BOOL bImpact; // Had an impact?
  67. IVP_BOOL bImpactWater; // Impact with water?
  68. IVP_BOOL bInWater; // Point in water?
  69. IVP_U_Point vecImpactPointWS; // Impact point in world-space.
  70. IVP_U_Float_Point vecImpactNormalWS; // Impact normal in world-space.
  71. IVP_FLOAT flDepth; // Distance to water surface.
  72. IVP_FLOAT flFriction; // Friction at impact point.
  73. IVP_FLOAT flDampening; // Dampening at surface.
  74. int nSurfaceProps; // Surface property!
  75. };
  76. //-----------------------------------------------------------------------------
  77. //-----------------------------------------------------------------------------
  78. class IVP_Raycast_Airboat_Axle
  79. {
  80. public:
  81. IVP_FLOAT stabilizer_constant; // axle (for wheels) stabilizer constant
  82. };
  83. //-----------------------------------------------------------------------------
  84. //-----------------------------------------------------------------------------
  85. class IVP_Controller_Raycast_Airboat_Vector_of_Cores_1: public IVP_U_Vector<IVP_Core>
  86. {
  87. void *elem_buffer[1];
  88. public:
  89. IVP_Controller_Raycast_Airboat_Vector_of_Cores_1();
  90. };
  91. //-----------------------------------------------------------------------------
  92. //-----------------------------------------------------------------------------
  93. class CPhysics_Airboat : public IVP_Car_System, protected IVP_Controller_Dependent
  94. {
  95. public:
  96. CPhysics_Airboat( IVP_Environment *env, const IVP_Template_Car_System *t, IPhysicsGameTrace *pGameTrace );
  97. virtual ~CPhysics_Airboat();
  98. void update_wheel_positions( void ) {}
  99. void SetWheelFriction( int iWheel, float flFriction );
  100. IPhysicsObject *GetWheel( int index );
  101. virtual const char *get_controller_name() { return "sys:airboat"; }
  102. protected:
  103. void InitAirboat( const IVP_Template_Car_System *pCarSystem );
  104. float GetWaterDepth( Ray_t *pGameRay, IPhysicsObject *pPhysAirboat );
  105. // Purpose: Deconstructor
  106. void PerformFrictionNotification( float flEliminatedEnergy, float dt, int nSurfaceProp, IPhysicsCollisionData *pCollisionData );
  107. void do_raycasts_gameside( int nRaycastCount, IVP_Ray_Solver_Template *pRays, IVP_Raycast_Airboat_Impact *pImpacts );
  108. void pre_raycasts_gameside( int nRaycastCount, IVP_Ray_Solver_Template *pRays, Ray_t *pGameRays, IVP_Raycast_Airboat_Impact *pImpacts );
  109. IVP_Real_Object *m_pWheels[IVP_RAYCAST_AIRBOAT_MAX_WHEELS];
  110. IPhysicsGameTrace *m_pGameTrace;
  111. public:
  112. // Steering
  113. void do_steering_wheel(IVP_POS_WHEEL wheel_pos, IVP_FLOAT s_angle); // called by do_steering()
  114. // Car Adjustment
  115. void change_spring_constant(IVP_POS_WHEEL pos, IVP_FLOAT spring_constant); // [Newton/meter]
  116. void change_spring_dampening(IVP_POS_WHEEL pos, IVP_FLOAT spring_dampening); // when spring is relaxing spring
  117. void change_spring_dampening_compression(IVP_POS_WHEEL pos, IVP_FLOAT spring_dampening); // [Newton/meter] for compressing spring
  118. void change_max_body_force(IVP_POS_WHEEL , IVP_FLOAT mforce) {}
  119. void change_spring_pre_tension(IVP_POS_WHEEL pos, IVP_FLOAT pre_tension_length);
  120. void change_spring_length(IVP_POS_WHEEL pos, IVP_FLOAT spring_length);
  121. void change_stabilizer_constant(IVP_POS_AXIS pos, IVP_FLOAT stabi_constant); // [Newton/meter]
  122. void change_fast_turn_factor( IVP_FLOAT fast_turn_factor_ ); // not implemented for raycasts
  123. void change_wheel_torque(IVP_POS_WHEEL pos, IVP_FLOAT torque);
  124. IVP_FLOAT get_wheel_torque(IVP_POS_WHEEL wheel_nr);
  125. void update_throttle( IVP_FLOAT flThrottle );
  126. void update_body_countertorque() {}
  127. void change_body_downforce(IVP_FLOAT force); // extra force to keep flipped objects flipped over
  128. void fix_wheel( IVP_POS_WHEEL, IVP_BOOL stop_wheel ); // stop wheel completely (e.g. handbrake )
  129. void change_friction_of_wheel( IVP_POS_WHEEL pos, IVP_FLOAT friction );
  130. void set_powerslide( float frontAccel, float rearAccel ) {}
  131. // Car Info
  132. IVP_DOUBLE get_body_speed(IVP_COORDINATE_INDEX idx_z = IVP_INDEX_Z); // km/h in 'z' direction
  133. IVP_DOUBLE get_wheel_angular_velocity(IVP_POS_WHEEL);
  134. IVP_DOUBLE get_orig_front_wheel_distance();
  135. IVP_DOUBLE get_orig_axles_distance();
  136. void get_skid_info( IVP_Wheel_Skid_Info *array_of_skid_info_out);
  137. void get_wheel_position(IVP_U_Point *position_ws_out, IVP_U_Quat *direction_ws_out);
  138. // Methods: 2nd Level, based on primitives
  139. virtual void do_steering(IVP_FLOAT steering_angle_in, bool bAnalog); // default implementation updates this->steering_angle
  140. //
  141. // Booster (the airboat has no booster).
  142. //
  143. virtual bool IsBoosting(void) { return false; }
  144. virtual void set_booster_acceleration( IVP_FLOAT acceleration) {}
  145. virtual void activate_booster(IVP_FLOAT thrust, IVP_FLOAT duration, IVP_FLOAT delay) {}
  146. virtual void update_booster(IVP_FLOAT delta_time) {}
  147. virtual IVP_FLOAT get_booster_delay() { return 0; }
  148. virtual IVP_FLOAT get_booster_time_to_go() { return 0; }
  149. // Debug
  150. void SetCarSystemDebugData( const IVP_CarSystemDebugData_t &carSystemDebugData );
  151. void GetCarSystemDebugData( IVP_CarSystemDebugData_t &carSystemDebugData );
  152. protected:
  153. IVP_Core *m_pCore;
  154. IVP_U_Float_Point m_vecLocalVelocity;
  155. float m_flSpeed;
  156. IVP_Real_Object *m_pAirboatBody; // *car_body
  157. // Wheels/Axles.
  158. short n_wheels;
  159. short n_axis;
  160. short wheels_per_axis;
  161. IVP_Raycast_Airboat_Wheel m_aAirboatWheels[IVP_RAYCAST_AIRBOAT_MAX_WHEELS]; // wheel_of_car
  162. IVP_Raycast_Airboat_Axle m_aAirboatAxles[IVP_RAYCAST_AIRBOAT_MAX_WHEELS/2]; // axis_of_car
  163. // Gravity.
  164. IVP_FLOAT gravity_y_direction; // +/-1
  165. IVP_U_Float_Point normized_gravity_ws;
  166. IVP_FLOAT extra_gravity;
  167. // Orientation.
  168. IVP_COORDINATE_INDEX index_x;
  169. IVP_COORDINATE_INDEX index_y;
  170. IVP_COORDINATE_INDEX index_z;
  171. IVP_BOOL is_left_handed;
  172. // Speed.
  173. IVP_FLOAT max_speed;
  174. //
  175. IVP_FLOAT down_force;
  176. IVP_FLOAT down_force_vertical_offset;
  177. // Steering
  178. IVP_FLOAT m_SteeringAngle;
  179. bool m_bSteeringReversed;
  180. bool m_bAnalogSteering;
  181. IVP_FLOAT m_flPrevSteeringAngle;
  182. IVP_FLOAT m_flSteerTime; // Number of seconds we've steered in this direction.
  183. // Thrust.
  184. IVP_FLOAT m_flThrust;
  185. bool m_bAirborne; // Whether we are airborne or not.
  186. IVP_FLOAT m_flAirTime; // How long we've been airborne (if we are).
  187. bool m_bWeakJump; // Set when we become airborne while going slow.
  188. // Pitch and roll stabilizers.
  189. IVP_FLOAT m_flPitchErrorPrev;
  190. IVP_FLOAT m_flRollErrorPrev;
  191. // Debugging!
  192. IVP_CarSystemDebugData_t m_CarSystemDebugData;
  193. protected:
  194. IVP_Raycast_Airboat_Wheel *get_wheel( IVP_POS_WHEEL i );
  195. IVP_Raycast_Airboat_Axle *get_axle( IVP_POS_AXIS i );
  196. virtual void core_is_going_to_be_deleted_event( IVP_Core * );
  197. virtual IVP_U_Vector<IVP_Core> *get_associated_controlled_cores( void );
  198. virtual void do_simulation_controller(IVP_Event_Sim *,IVP_U_Vector<IVP_Core> *core_list);
  199. virtual IVP_CONTROLLER_PRIORITY get_controller_priority();
  200. private:
  201. // Initialization.
  202. void InitRaycastCarEnvironment( IVP_Environment *pEnvironment, const IVP_Template_Car_System *pCarSystemTemplate );
  203. void InitRaycastCarBody( const IVP_Template_Car_System *pCarSystemTemplate );
  204. void InitRaycastCarWheels( const IVP_Template_Car_System *pCarSystemTemplate );
  205. void InitRaycastCarAxes( const IVP_Template_Car_System *pCarSystemTemplate );
  206. // Raycasts for simulation.
  207. void PreRaycasts( IVP_Ray_Solver_Template *pRaySolverTemplates, const IVP_U_Matrix *m_world_f_core, IVP_Raycast_Airboat_Impact *pImpacts );
  208. bool PostRaycasts( IVP_Ray_Solver_Template *pRaySolverTemplates, const IVP_U_Matrix *matWorldFromCore, IVP_Raycast_Airboat_Impact *pImpacts );
  209. // Simulation.
  210. void DoSimulationPontoons( IVP_Raycast_Airboat_Impact *pImpacts, IVP_Event_Sim *pEventSim );
  211. void DoSimulationPontoonsGround( IVP_Raycast_Airboat_Wheel *pPontoonPoint, IVP_Raycast_Airboat_Impact *pImpact, IVP_Event_Sim *pEventSim );
  212. void DoSimulationPontoonsWater( IVP_Raycast_Airboat_Wheel *pPontoonPoint, IVP_Raycast_Airboat_Impact *pImpact, IVP_Event_Sim *pEventSim );
  213. void DoSimulationDrag( IVP_Raycast_Airboat_Impact *pImpacts, IVP_Event_Sim *pEventSim );
  214. void DoSimulationTurbine( IVP_Event_Sim *pEventSim );
  215. void DoSimulationSteering( IVP_Event_Sim *pEventSim );
  216. void DoSimulationKeepUprightPitch( IVP_Raycast_Airboat_Impact *pImpacts, IVP_Event_Sim *pEventSim );
  217. void DoSimulationKeepUprightRoll( IVP_Raycast_Airboat_Impact *pImpacts, IVP_Event_Sim *pEventSim );
  218. void DoSimulationGravity( IVP_Event_Sim *pEventSim );
  219. int CountSurfaceContactPoints( IVP_Raycast_Airboat_Impact *pImpacts );
  220. void UpdateAirborneState( IVP_Raycast_Airboat_Impact *pImpacts, IVP_Event_Sim *pEventSim );
  221. float ComputeFrontPontoonWaveNoise( int nPontoonIndex, float flSpeedRatio );
  222. void CalcImpactPosition( IVP_Ray_Solver_Template *pRaySolver, IVP_Raycast_Airboat_Wheel *pPontoonPoint,
  223. IVP_Raycast_Airboat_Impact *pImpacts );
  224. IVP_Controller_Raycast_Airboat_Vector_of_Cores_1 vector_of_cores;
  225. };
  226. #endif // PHYSICS_AIRBOAT_H