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