VehicleTransmission.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #include <Jolt.h>
  4. #include <Physics/Vehicle/VehicleTransmission.h>
  5. #include <ObjectStream/TypeDeclarations.h>
  6. namespace JPH {
  7. JPH_IMPLEMENT_SERIALIZABLE_NON_VIRTUAL(VehicleTransmissionSettings)
  8. {
  9. JPH_ADD_ENUM_ATTRIBUTE(VehicleTransmissionSettings, mMode)
  10. JPH_ADD_ATTRIBUTE(VehicleTransmissionSettings, mGearRatios)
  11. JPH_ADD_ATTRIBUTE(VehicleTransmissionSettings, mReverseGearRatios)
  12. JPH_ADD_ATTRIBUTE(VehicleTransmissionSettings, mSwitchTime)
  13. JPH_ADD_ATTRIBUTE(VehicleTransmissionSettings, mClutchReleaseTime)
  14. JPH_ADD_ATTRIBUTE(VehicleTransmissionSettings, mShiftUpRPM)
  15. JPH_ADD_ATTRIBUTE(VehicleTransmissionSettings, mShiftDownRPM)
  16. }
  17. void VehicleTransmissionSettings::SaveBinaryState(StreamOut &inStream) const
  18. {
  19. inStream.Write(mMode);
  20. inStream.Write(mGearRatios);
  21. inStream.Write(mReverseGearRatios);
  22. inStream.Write(mSwitchTime);
  23. inStream.Write(mClutchReleaseTime);
  24. inStream.Write(mShiftUpRPM);
  25. inStream.Write(mShiftDownRPM);
  26. }
  27. void VehicleTransmissionSettings::RestoreBinaryState(StreamIn &inStream)
  28. {
  29. inStream.Read(mMode);
  30. inStream.Read(mGearRatios);
  31. inStream.Read(mReverseGearRatios);
  32. inStream.Read(mSwitchTime);
  33. inStream.Read(mClutchReleaseTime);
  34. inStream.Read(mShiftUpRPM);
  35. inStream.Read(mShiftDownRPM);
  36. }
  37. void VehicleTransmission::Update(float inDeltaTime, float inCurrentRPM, float inForwardInput, bool inEngineCanApplyTorque)
  38. {
  39. // Update current gear and calculate clutch friction
  40. if (mMode == ETransmissionMode::Auto)
  41. {
  42. // Switch gears based on rpm
  43. int old_gear = mCurrentGear;
  44. if (mCurrentGear == 0 // In neutral
  45. || inForwardInput * float(mCurrentGear) < 0.0f) // Changing between forward / reverse
  46. {
  47. // Switch to first gear or reverse depending on input
  48. mCurrentGear = inForwardInput > 0.0f? 1 : (inForwardInput < 0.0f? -1 : 0);
  49. }
  50. else if (inEngineCanApplyTorque && inCurrentRPM > mShiftUpRPM)
  51. {
  52. if (mCurrentGear < 0)
  53. {
  54. // Shift up, reverse
  55. if (mCurrentGear > -(int)mReverseGearRatios.size())
  56. mCurrentGear--;
  57. }
  58. else
  59. {
  60. // Shift up, forward
  61. if (mCurrentGear < (int)mGearRatios.size())
  62. mCurrentGear++;
  63. }
  64. }
  65. else if (inCurrentRPM < mShiftDownRPM)
  66. {
  67. if (mCurrentGear < 0)
  68. {
  69. // Shift down, reverse
  70. int max_gear = inForwardInput != 0.0f? -1 : 0;
  71. if (mCurrentGear < max_gear)
  72. mCurrentGear++;
  73. }
  74. else
  75. {
  76. // Shift down, forward
  77. int min_gear = inForwardInput != 0.0f? 1 : 0;
  78. if (mCurrentGear > min_gear)
  79. mCurrentGear--;
  80. }
  81. }
  82. if (old_gear != mCurrentGear && old_gear != 0)
  83. {
  84. // We've shifted gear, start switch countdown
  85. mGearSwitchTimeLeft = mSwitchTime;
  86. mClutchReleaseTimeLeft = mClutchReleaseTime;
  87. mClutchFriction = 0.0f;
  88. }
  89. else if (mGearSwitchTimeLeft > 0.0f)
  90. {
  91. // If still switching gears, count down
  92. mGearSwitchTimeLeft = max(0.0f, mGearSwitchTimeLeft - inDeltaTime);
  93. mClutchFriction = 0.0f;
  94. }
  95. else if (mClutchReleaseTimeLeft > 0.0f)
  96. {
  97. // After switching the gears we slowly release the clutch
  98. mClutchReleaseTimeLeft = max(0.0f, mClutchReleaseTimeLeft - inDeltaTime);
  99. mClutchFriction = 1.0f - mClutchReleaseTimeLeft / mClutchReleaseTime;
  100. }
  101. else
  102. {
  103. // Clutch has full friction
  104. mClutchFriction = 1.0f;
  105. }
  106. }
  107. }
  108. float VehicleTransmission::GetCurrentRatio() const
  109. {
  110. if (mCurrentGear < 0)
  111. return mReverseGearRatios[-mCurrentGear - 1];
  112. else if (mCurrentGear == 0)
  113. return 0.0f;
  114. else
  115. return mGearRatios[mCurrentGear - 1];
  116. }
  117. void VehicleTransmission::SaveState(StateRecorder &inStream) const
  118. {
  119. inStream.Write(mCurrentGear);
  120. inStream.Write(mClutchFriction);
  121. inStream.Write(mGearSwitchTimeLeft);
  122. inStream.Write(mClutchReleaseTimeLeft);
  123. }
  124. void VehicleTransmission::RestoreState(StateRecorder &inStream)
  125. {
  126. inStream.Read(mCurrentGear);
  127. inStream.Read(mClutchFriction);
  128. inStream.Read(mGearSwitchTimeLeft);
  129. inStream.Read(mClutchReleaseTimeLeft);
  130. }
  131. } // JPH