Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Vehicle/VehicleEngine.cpp
9913 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/VehicleEngine.h>
8
#include <Jolt/ObjectStream/TypeDeclarations.h>
9
#ifdef JPH_DEBUG_RENDERER
10
#include <Jolt/Renderer/DebugRenderer.h>
11
#endif // JPH_DEBUG_RENDERER
12
13
JPH_NAMESPACE_BEGIN
14
15
JPH_IMPLEMENT_SERIALIZABLE_NON_VIRTUAL(VehicleEngineSettings)
16
{
17
JPH_ADD_ATTRIBUTE(VehicleEngineSettings, mMaxTorque)
18
JPH_ADD_ATTRIBUTE(VehicleEngineSettings, mMinRPM)
19
JPH_ADD_ATTRIBUTE(VehicleEngineSettings, mMaxRPM)
20
JPH_ADD_ATTRIBUTE(VehicleEngineSettings, mNormalizedTorque)
21
}
22
23
VehicleEngineSettings::VehicleEngineSettings()
24
{
25
mNormalizedTorque.Reserve(3);
26
mNormalizedTorque.AddPoint(0.0f, 0.8f);
27
mNormalizedTorque.AddPoint(0.66f, 1.0f);
28
mNormalizedTorque.AddPoint(1.0f, 0.8f);
29
}
30
31
void VehicleEngineSettings::SaveBinaryState(StreamOut &inStream) const
32
{
33
inStream.Write(mMaxTorque);
34
inStream.Write(mMinRPM);
35
inStream.Write(mMaxRPM);
36
mNormalizedTorque.SaveBinaryState(inStream);
37
}
38
39
void VehicleEngineSettings::RestoreBinaryState(StreamIn &inStream)
40
{
41
inStream.Read(mMaxTorque);
42
inStream.Read(mMinRPM);
43
inStream.Read(mMaxRPM);
44
mNormalizedTorque.RestoreBinaryState(inStream);
45
}
46
47
void VehicleEngine::ApplyTorque(float inTorque, float inDeltaTime)
48
{
49
// Accelerate engine using torque
50
mCurrentRPM += cAngularVelocityToRPM * inTorque * inDeltaTime / mInertia;
51
ClampRPM();
52
}
53
54
void VehicleEngine::ApplyDamping(float inDeltaTime)
55
{
56
// Angular damping: dw/dt = -c * w
57
// Solution: w(t) = w(0) * e^(-c * t) or w2 = w1 * e^(-c * dt)
58
// Taylor expansion of e^(-c * dt) = 1 - c * dt + ...
59
// Since dt is usually in the order of 1/60 and c is a low number too this approximation is good enough
60
mCurrentRPM *= max(0.0f, 1.0f - mAngularDamping * inDeltaTime);
61
ClampRPM();
62
}
63
64
#ifdef JPH_DEBUG_RENDERER
65
66
void VehicleEngine::DrawRPM(DebugRenderer *inRenderer, RVec3Arg inPosition, Vec3Arg inForward, Vec3Arg inUp, float inSize, float inShiftDownRPM, float inShiftUpRPM) const
67
{
68
// Function to draw part of a pie
69
auto draw_pie = [this, inRenderer, inSize, inPosition, inForward, inUp](float inMinRPM, float inMaxRPM, Color inColor) {
70
inRenderer->DrawPie(inPosition, inSize, inForward, inUp, ConvertRPMToAngle(inMinRPM), ConvertRPMToAngle(inMaxRPM), inColor, DebugRenderer::ECastShadow::Off);
71
};
72
73
// Draw segment under min RPM
74
draw_pie(0, mMinRPM, Color::sGrey);
75
76
// Draw segment until inShiftDownRPM
77
if (mCurrentRPM < inShiftDownRPM)
78
{
79
draw_pie(mMinRPM, mCurrentRPM, Color::sRed);
80
draw_pie(mCurrentRPM, inShiftDownRPM, Color::sDarkRed);
81
}
82
else
83
{
84
draw_pie(mMinRPM, inShiftDownRPM, Color::sRed);
85
}
86
87
// Draw segment between inShiftDownRPM and inShiftUpRPM
88
if (mCurrentRPM > inShiftDownRPM && mCurrentRPM < inShiftUpRPM)
89
{
90
draw_pie(inShiftDownRPM, mCurrentRPM, Color::sOrange);
91
draw_pie(mCurrentRPM, inShiftUpRPM, Color::sDarkOrange);
92
}
93
else
94
{
95
draw_pie(inShiftDownRPM, inShiftUpRPM, mCurrentRPM <= inShiftDownRPM? Color::sDarkOrange : Color::sOrange);
96
}
97
98
// Draw segment above inShiftUpRPM
99
if (mCurrentRPM > inShiftUpRPM)
100
{
101
draw_pie(inShiftUpRPM, mCurrentRPM, Color::sGreen);
102
draw_pie(mCurrentRPM, mMaxRPM, Color::sDarkGreen);
103
}
104
else
105
{
106
draw_pie(inShiftUpRPM, mMaxRPM, Color::sDarkGreen);
107
}
108
}
109
110
#endif // JPH_DEBUG_RENDERER
111
112
void VehicleEngine::SaveState(StateRecorder &inStream) const
113
{
114
inStream.Write(mCurrentRPM);
115
}
116
117
void VehicleEngine::RestoreState(StateRecorder &inStream)
118
{
119
inStream.Read(mCurrentRPM);
120
}
121
122
JPH_NAMESPACE_END
123
124