VehicleTransmission.cpp 4.6 KB

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