VehicleTransmission.cpp 4.5 KB

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