TrackedVehicleController.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #pragma once
  4. #include <Physics/Vehicle/VehicleConstraint.h>
  5. #include <Physics/Vehicle/VehicleController.h>
  6. #include <Physics/Vehicle/VehicleEngine.h>
  7. #include <Physics/Vehicle/VehicleTransmission.h>
  8. #include <Physics/Vehicle/VehicleTrack.h>
  9. namespace JPH {
  10. class PhysicsSystem;
  11. /// WheelSettings object specifically for TrackedVehicleController
  12. class WheelSettingsTV : public WheelSettings
  13. {
  14. public:
  15. JPH_DECLARE_SERIALIZABLE_VIRTUAL(WheelSettingsTV)
  16. // See: WheelSettings
  17. virtual void SaveBinaryState(StreamOut &inStream) const override;
  18. virtual void RestoreBinaryState(StreamIn &inStream) override;
  19. float mLongitudinalFriction = 4.0f; ///< Friction in forward direction of tire
  20. float mLateralFriction = 2.0f; ///< Friction in sideway direction of tire
  21. };
  22. /// Wheel object specifically for TrackedVehicleController
  23. class WheelTV : public Wheel
  24. {
  25. public:
  26. /// Constructor
  27. explicit WheelTV(const WheelSettingsTV &inWheel);
  28. /// Override GetSettings and cast to the correct class
  29. const WheelSettingsTV * GetSettings() const { return static_cast<const WheelSettingsTV *>(mSettings.GetPtr()); }
  30. /// Update the angular velocity of the wheel based on the angular velocity of the track
  31. void CalculateAngularVelocity(const VehicleConstraint &inConstraint);
  32. /// Update the wheel rotation based on the current angular velocity
  33. void Update(float inDeltaTime, const VehicleConstraint &inConstraint);
  34. int mTrackIndex = -1; ///< Index in mTracks to which this wheel is attached (calculated on initialization)
  35. float mCombinedLongitudinalFriction = 0.0f; ///< Combined friction coefficient in longitudinal direction (combines terrain and track)
  36. float mCombinedLateralFriction = 0.0f; ///< Combined friction coefficient in lateral direction (combines terrain and track)
  37. float mBrakeImpulse = 0.0f; ///< Amount of impulse that the brakes can apply to the floor (excluding friction), spread out from brake impulse applied on track
  38. };
  39. /// Settings of a vehicle with tank tracks
  40. ///
  41. /// Default settings are based around what I could find about the M1 Abrams tank.
  42. /// Note to avoid issues with very heavy objects vs very light objects the mass of the tank should be a lot lower (say 10x) than that of a real tank. That means that the engine/brake torque is also 10x less.
  43. class TrackedVehicleControllerSettings : public VehicleControllerSettings
  44. {
  45. public:
  46. JPH_DECLARE_SERIALIZABLE_VIRTUAL(TrackedVehicleControllerSettings)
  47. // Constructor
  48. TrackedVehicleControllerSettings();
  49. // See: VehicleControllerSettings
  50. virtual VehicleController * ConstructController(VehicleConstraint &inConstraint) const override;
  51. virtual void SaveBinaryState(StreamOut &inStream) const override;
  52. virtual void RestoreBinaryState(StreamIn &inStream) override;
  53. VehicleEngineSettings mEngine; ///< The properties of the engine
  54. VehicleTransmissionSettings mTransmission; ///< The properties of the transmission (aka gear box)
  55. VehicleTrackSettings mTracks[(int)ETrackSide::Num]; ///< List of tracks and their properties
  56. };
  57. /// Runtime controller class for vehicle with tank tracks
  58. class TrackedVehicleController : public VehicleController
  59. {
  60. public:
  61. /// Constructor
  62. TrackedVehicleController(const TrackedVehicleControllerSettings &inSettings, VehicleConstraint &inConstraint);
  63. /// Set input from driver
  64. /// @param inForward Value between -1 and 1 for auto transmission and value between 0 and 1 indicating desired driving direction and amount the gas pedal is pressed
  65. /// @param inLeftRatio Value between -1 and 1 indicating an extra multiplier to the rotation rate of the left track (used for steering)
  66. /// @param inRightRatio Value between -1 and 1 indicating an extra multiplier to the rotation rate of the right track (used for steering)
  67. /// @param inBrake Value between 0 and 1 indicating how strong the brake pedal is pressed
  68. void SetDriverInput(float inForward, float inLeftRatio, float inRightRatio, float inBrake) { JPH_ASSERT(inLeftRatio != 0.0f && inRightRatio != 0.0f); mForwardInput = inForward; mLeftRatio = inLeftRatio; mRightRatio = inRightRatio; mBrakeInput = inBrake; }
  69. /// Get current engine state
  70. const VehicleEngine & GetEngine() const { return mEngine; }
  71. /// Get current engine state (writable interface, allows you to make changes to the configuration which will take effect the next time step)
  72. VehicleEngine & GetEngine() { return mEngine; }
  73. /// Get current transmission state
  74. const VehicleTransmission & GetTransmission() const { return mTransmission; }
  75. /// Get current transmission state (writable interface, allows you to make changes to the configuration which will take effect the next time step)
  76. VehicleTransmission & GetTransmission() { return mTransmission; }
  77. /// Get the tracks this vehicle has
  78. const VehicleTracks & GetTracks() const { return mTracks; }
  79. /// Get the tracks this vehicle has (writable interface, allows you to make changes to the configuration which will take effect the next time step)
  80. VehicleTracks & GetTracks() { return mTracks; }
  81. #ifdef JPH_DEBUG_RENDERER
  82. /// Debug drawing of RPM meter
  83. void SetRPMMeter(Vec3Arg inPosition, float inSize) { mRPMMeterPosition = inPosition; mRPMMeterSize = inSize; }
  84. #endif // JPH_DEBUG_RENDERER
  85. protected:
  86. /// Synchronize angular velocities of left and right tracks according to their ratios
  87. void SyncLeftRightTracks();
  88. // See: VehicleController
  89. virtual Wheel * ConstructWheel(const WheelSettings &inWheel) const override { JPH_ASSERT(IsKindOf(&inWheel, JPH_RTTI(WheelSettingsTV))); return new WheelTV(static_cast<const WheelSettingsTV &>(inWheel)); }
  90. virtual void PreCollide(float inDeltaTime, PhysicsSystem &inPhysicsSystem) override;
  91. virtual void PostCollide(float inDeltaTime, PhysicsSystem &inPhysicsSystem) override;
  92. virtual bool SolveLongitudinalAndLateralConstraints(float inDeltaTime) override;
  93. virtual void SaveState(StateRecorder &inStream) const override;
  94. virtual void RestoreState(StateRecorder &inStream) override;
  95. #ifdef JPH_DEBUG_RENDERER
  96. virtual void Draw(DebugRenderer *inRenderer) const override;
  97. #endif // JPH_DEBUG_RENDERER
  98. // Control information
  99. float mForwardInput = 0.0f; ///< Value between -1 and 1 for auto transmission and value between 0 and 1 indicating desired driving direction and amount the gas pedal is pressed
  100. float mLeftRatio = 1.0f; ///< Value between -1 and 1 indicating an extra multiplier to the rotation rate of the left track (used for steering)
  101. float mRightRatio = 1.0f; ///< Value between -1 and 1 indicating an extra multiplier to the rotation rate of the right track (used for steering)
  102. float mBrakeInput = 0.0f; ///< Value between 0 and 1 indicating how strong the brake pedal is pressed
  103. // Simluation information
  104. VehicleEngine mEngine; ///< Engine state of the vehicle
  105. VehicleTransmission mTransmission; ///< Transmission state of the vehicle
  106. VehicleTracks mTracks; ///< Tracks of the vehicle
  107. #ifdef JPH_DEBUG_RENDERER
  108. // Debug settings
  109. Vec3 mRPMMeterPosition { 0, 1, 0 }; ///< Position (in local space of the body) of the RPM meter when drawing the constraint
  110. float mRPMMeterSize = 0.5f; ///< Size of the RPM meter when drawing the constraint
  111. #endif // JPH_DEBUG_RENDERER
  112. };
  113. } // JPH