TrackedVehicleController.h 7.6 KB

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