Rigs of Rods 2023.09
Soft-body Physics Simulation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
Engine.cpp
Go to the documentation of this file.
1/*
2 This source file is part of Rigs of Rods
3 Copyright 2005-2012 Pierre-Michel Ricordel
4 Copyright 2007-2012 Thomas Fischer
5 Copyright 2013-2023 Petr Ohlidal
6
7 For more information, see http://www.rigsofrods.org/
8
9 Rigs of Rods is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License version 3, as
11 published by the Free Software Foundation.
12
13 Rigs of Rods is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include "Engine.h"
23
24#include "AppContext.h"
25#include "ApproxMath.h" // frand()
26#include "Actor.h"
27#include "ActorManager.h"
28#include "Console.h"
29#include "InputEngine.h"
30#include "ScriptEngine.h"
31#include "SoundScriptManager.h"
32#include "TorqueCurve.h"
33
34using namespace Ogre;
35using namespace RoR;
36
37Engine::Engine(float _min_rpm, float _max_rpm, float torque, float reverse_gear, float neutral_gear, std::vector<float> forward_gears, float diff_ratio, ActorPtr actor) :
38 m_air_pressure(0.0f)
39 , m_auto_cur_acc(0.0f)
40 , m_auto_mode(SimGearboxMode::AUTO)
41 , m_autoselect(DRIVE)
42 , m_braking_torque(-torque / 5.0f)
43 , m_clutch_force(10000.0f)
44 , m_clutch_time(0.2f)
45 , m_contact(false)
46 , m_cur_acc(0.0f)
47 , m_cur_clutch(0.0f)
48 , m_cur_clutch_torque(0.0f)
49 , m_cur_engine_rpm(0.0f)
50 , m_cur_engine_torque(0.0f)
51 , m_cur_gear(0)
52 , m_cur_gear_range(0)
53 , m_cur_wheel_revolutions(0.0f)
54 , m_ref_wheel_revolutions(0.0f)
55 , m_diff_ratio(diff_ratio)
56 , m_tcase_ratio(1.0f)
57 , m_engine_torque(torque)
58 , m_engine_has_air(true)
59 , m_engine_has_turbo(true)
60 , m_hydropump_state(0.0f)
61 , m_engine_idle_rpm(std::min(std::abs(_min_rpm), 800.0f))
62 , m_engine_inertia(10.0f)
63 , m_kickdown_delay_counter(0)
64 , m_max_idle_mixture(0.1f)
65 , m_engine_max_rpm(std::abs(_max_rpm))
66 , m_min_idle_mixture(0.0f)
67 , m_engine_shiftup_rpm(std::abs(_min_rpm))
68 , m_num_gears((int)forward_gears.size())
69 , m_post_shift_time(0.2f)
70 , m_post_shift_clock(0.0f)
71 , m_post_shifting(0)
72 , m_engine_is_priming(false)
73 , m_engine_is_running(false)
74 , m_shift_behaviour(0.0f)
75 , m_shift_time(0.5f)
76 , m_shift_clock(0.0f)
77 , m_shifting(0)
78 , m_shift_val(0)
79 , m_engine_stall_rpm(300.0f)
80 , m_starter(0)
81 , m_torque_curve(new TorqueCurve())
82 , m_actor(actor)
83 , m_engine_turbo_mode(OLD)
84 , m_engine_type('t')
85 , m_upshift_delay_counter(0)
86 , m_engine_is_electric(false)
87 , m_turbo_inertia_factor(1)
88 , m_num_turbos(1)
89 , m_max_turbo_rpm(200000.0f)
90 , m_turbo_engine_rpm_operation(0.0f)
91 , m_turbo_ver(1)
92 , m_min_bov_psi(11)
93 , m_min_wastegate_psi(20)
94 , m_turbo_has_wastegate(false)
95 , m_turbo_has_bov(false)
96 , m_turbo_flutters(false)
97 , m_turbo_wg_threshold_p(0)
98 , m_turbo_wg_threshold_n(0)
99 , m_turbo_has_antilag(false)
100 , m_antilag_rand_chance(0.9975)
101 , m_antilag_min_rpm(3000)
102 , m_antilag_power_factor(170)
103{
107
108 for (int i = 0; i < MAXTURBO; i++)
109 {
111 m_cur_turbo_rpm[i] = 0;
112 }
113
114 // Assemble gear vector in format [R|N|1...]
115 m_gear_ratios.push_back(-reverse_gear * diff_ratio);
116 m_gear_ratios.push_back(neutral_gear * diff_ratio);
117 for (float gear : forward_gears)
118 m_gear_ratios.push_back(gear * diff_ratio);
119}
120
122{
123 // delete NULL is safe
124 delete m_torque_curve;
125 m_torque_curve = NULL;
126}
127
128void Engine::SetTurboOptions(int type, float tinertiaFactor, int nturbos, float param1, float param2, float param3, float param4, float param5, float param6, float param7, float param8, float param9, float param10, float param11)
129{
130 m_engine_has_turbo = true;
132
133 if (nturbos > MAXTURBO)
134 {
135 m_num_turbos = 4;
136 LOG("Turbo: No more than 4 turbos allowed"); //TODO: move this under RigParser
137 }
138 else
139 m_num_turbos = nturbos;
140
141 m_turbo_ver = type;
142 m_turbo_inertia_factor = tinertiaFactor;
143
144 if (param2 != 9999)
146
147 if (m_turbo_ver == 1)
148 {
149 for (int i = 0; i < m_num_turbos; i++)
150 m_engine_addi_torque[i] = param1 / m_num_turbos; //Additional torque
151 }
152 else
153 {
154 float turbo_max_psi = param1; //maxPSI
155 m_max_turbo_rpm = turbo_max_psi * 10000;
156
157 //Duh
158 if (param3 == 1)
159 m_turbo_has_bov = true;
160 else
161 m_turbo_has_bov = false;
162
163 if (param3 != 9999)
164 m_min_bov_psi = param4;
165
166 if (param5 == 1)
168 else
169 m_turbo_has_wastegate = false;
170
171 if (param6 != 9999)
172 m_min_wastegate_psi = param6 * 10000;
173
174 if (param7 != 9999)
175 {
176 m_turbo_wg_threshold_n = 1 - param7;
177 m_turbo_wg_threshold_p = 1 + param7;
178 }
179
180 if (param8 == 1)
181 m_turbo_has_antilag = true;
182 else
183 m_turbo_has_antilag = false;
184
185 if (param9 != 9999)
186 m_antilag_rand_chance = param9;
187
188 if (param10 != 9999)
189 m_antilag_min_rpm = param10;
190
191 if (param11 != 9999)
192 m_antilag_power_factor = param11;
193 }
194}
195
196void Engine::SetEngineOptions(float einertia, char etype, float eclutch, float ctime, float stime, float pstime, float irpm, float srpm, float maximix, float minimix, float ebraking)
197{
198 m_engine_inertia = einertia;
199 m_engine_type = etype;
200 m_clutch_force = eclutch;
201
202 if (ctime > 0)
203 m_clutch_time = ctime;
204 if (stime > 0)
205 m_shift_time = stime;
206 if (pstime > 0)
207 m_post_shift_time = pstime;
208 if (irpm > 0)
209 m_engine_idle_rpm = irpm;
210 if (srpm > 0)
211 m_engine_stall_rpm = srpm;
212 if (maximix > 0)
213 m_max_idle_mixture = maximix;
214 if (minimix > 0)
215 m_min_idle_mixture = minimix;
216 if (ebraking > 0)
217 m_braking_torque = -ebraking;
218
219 m_shift_time = std::max(0.0f, m_shift_time);
220 m_post_shift_time = std::max(0.0f, m_post_shift_time);
221 m_clutch_time = Math::Clamp(m_clutch_time, 0.0f, 0.9f * m_shift_time);
222
223 m_engine_stall_rpm = Math::Clamp(m_engine_stall_rpm, 0.0f, 0.9f * m_engine_idle_rpm);
224
225 if (etype == 'c')
226 {
227 // it's a car!
228 m_engine_has_air = false;
229 m_engine_has_turbo = false;
230 m_engine_is_electric = false;
231 // set default clutch force
232 if (m_clutch_force < 0.0f)
233 {
234 m_clutch_force = 5000.0f;
235 }
236 }
237 else if (etype == 'e') //electric
238 {
240 m_engine_has_air = false;
241 m_engine_has_turbo = false;
242 if (m_clutch_force < 0.0f)
243 {
244 m_clutch_force = 5000.0f;
245 }
246 }
247 else
248 {
249 m_engine_is_electric = false;
250 // it's a truck
251 if (m_clutch_force < 0.0f)
252 {
253 m_clutch_force = 10000.0f;
254 }
255 }
256}
257
258void Engine::UpdateEngine(float dt, int doUpdate)
259{
260 float acc = m_cur_acc;
261
262 acc = std::max(getIdleMixture(), acc);
263 acc = std::max(getPrimeMixture(), acc);
264
265 if (doUpdate)
266 {
268 }
269
271 {
272 // air pressure
274 if (m_air_pressure > 50000.0f)
275 {
277 m_air_pressure = 0.0f;
278 }
279 }
280
282 {
284 {
285 // update turbo speed (lag)
286 float turbotorque = 0.0f;
287 float turboInertia = 0.000003f;
288
289 // braking (compression)
290 turbotorque -= m_cur_turbo_rpm[0] / 200000.0f;
291
292 // powering (exhaust) with limiter
293 if (m_cur_turbo_rpm[0] < 200000.0f && m_engine_is_running && m_cur_acc > 0.06f)
294 {
295 turbotorque += 1.5f * m_cur_acc * (m_cur_engine_rpm / m_engine_max_rpm);
296 }
297 else
298 {
299 turbotorque += 0.1f * (m_cur_engine_rpm / m_engine_max_rpm);
300 }
301
302 // integration
303 m_cur_turbo_rpm[0] += dt * turbotorque / turboInertia;
304 }
305 else
306 {
307 for (int i = 0; i < m_num_turbos; i++)
308 {
309 // update turbo speed (lag)
310 // reset each of the values for each turbo
311 float turbotorque = 0.0f;
312 float turboBOVtorque = 0.0f;
313
314 float turboInertia = 0.000003f * m_turbo_inertia_factor;
315
316 // braking (compression)
317 turbotorque -= m_cur_turbo_rpm[i] / m_max_turbo_rpm;
318 turboBOVtorque -= m_turbo_bov_rpm[i] / m_max_turbo_rpm;
319
320 // powering (exhaust) with limiter
322 {
323 if (m_cur_turbo_rpm[i] <= m_max_turbo_rpm && m_engine_is_running && acc > 0.06f)
324 {
326 {
328 {
330 }
331 else
332 {
333 m_turbo_flutters = true;
334 turbotorque -= (m_cur_turbo_rpm[i] / m_max_turbo_rpm) * 1.5;
335 }
336
338 {
341 {
342 m_turbo_flutters = false;
344 }
345 }
346 }
347 else
349 }
350 else
351 {
353 }
354
355 //Update waste gate, it's like a BOV on the exhaust part of the turbo, acts as a limiter
357 {
358 if (m_cur_turbo_rpm[i] > m_min_wastegate_psi * 0.95)
359 turboInertia = turboInertia * 0.7; //Kill inertia so it flutters
360 else
361 turboInertia = turboInertia * 1.3; //back to normal inertia
362 }
363 }
364
365 //simulate compressor surge
366 if (!m_turbo_has_bov)
367 {
368 if (m_cur_turbo_rpm[i] > 13 * 10000 && m_cur_acc < 0.06f)
369 {
370 turbotorque += (turbotorque * 2.5);
371 }
372 }
373
374 // anti lag
375 if (m_turbo_has_antilag && m_cur_acc < 0.5)
376 {
377 float f = frand();
379 {
381 {
382 turbotorque -= (turbotorque * (f * m_antilag_power_factor));
384 }
385 }
386 else
387 {
389 }
390 }
391
392 // update main turbo rpm
393 m_cur_turbo_rpm[i] += dt * turbotorque / turboInertia;
394
395 //Update BOV
396 //It's basicly an other turbo which is limmited to the main one's rpm, but it doesn't affect its rpm. It only affects the power going into the engine.
397 //This one is used to simulate the pressure between the engine and the compressor.
398 //I should make the whole turbo code work this way. -Max98
399 if (m_turbo_has_bov)
400 {
402 turboBOVtorque += 1.5f * acc * (((m_cur_engine_rpm) / (m_engine_max_rpm)));
403 else
404 turboBOVtorque += 0.07f * (((m_cur_engine_rpm) / (m_engine_max_rpm)));
405
406 if (m_cur_acc < 0.06 && m_cur_turbo_rpm[i] > m_min_bov_psi * 10000)
407 {
409 m_turbo_bov_rpm[i] += dt * turboBOVtorque / (turboInertia * 0.1);
410 }
411 else
412 {
415 m_turbo_bov_rpm[i] += dt * turboBOVtorque / (turboInertia * 0.05);
416 else
417 m_turbo_bov_rpm[i] += dt * turboBOVtorque / turboInertia;
418 }
419 }
420 }
421 }
422 }
423
424 // update engine speed
425 float totaltorque = 0.0f;
426
427 // engine braking
429 {
430 totaltorque += m_braking_torque * m_cur_engine_rpm / m_engine_max_rpm * (1.0f - m_cur_acc);
431 }
432 else if (!m_contact || !m_starter)
433 {
434 totaltorque += m_braking_torque;
435 }
436
437 // braking by hydropump
438 if (m_cur_engine_rpm > 100.0f)
439 {
440 totaltorque -= 8.0f * m_hydropump_state / (m_cur_engine_rpm * 0.105f * dt);
441 }
442
444 {
446 totaltorque += m_cur_engine_torque;
447 }
448
449 // engine stall
451 {
453 {
454 this->stopEngine();
455 }
456 }
457
458 // engine start
460 {
462 {
463 if (m_starter)
464 m_engine_is_running = true;
465 }
466 else
467 {
469 {
470 if (m_starter)
471 {
472 totaltorque += m_engine_torque * exp(-2.7f * m_cur_engine_rpm / m_engine_idle_rpm) - m_braking_torque;
473 }
474 }
475 else
476 {
477 m_engine_is_running = true;
479 }
480 }
481 }
482
483 // clutch
484 if (m_cur_gear)
485 {
486 totaltorque -= m_cur_clutch_torque / m_gear_ratios[m_cur_gear + 1];
487 }
488
489 // integration
490 m_cur_engine_rpm += dt * totaltorque / m_engine_inertia;
491
492 // update clutch torque
493 if (m_cur_gear)
494 {
495 float force_threshold = 1.5f * std::max(m_engine_torque, getEnginePower()) * std::abs(m_gear_ratios[2]);
496 float gearboxspinner = m_cur_engine_rpm / m_gear_ratios[m_cur_gear + 1];
498 m_cur_clutch_torque = Math::Clamp(m_cur_clutch_torque, -force_threshold, +force_threshold);
499 m_cur_clutch_torque *= 1.0f - approx_exp(-std::abs(gearboxspinner - m_cur_wheel_revolutions));
500 }
501 else
502 {
503 m_cur_clutch_torque = 0.0f;
504 }
505
506 m_cur_engine_rpm = std::max(0.0f, m_cur_engine_rpm);
507
509 {
510 // auto-shift
511 if (m_shifting)
512 {
513 m_shift_clock += dt;
514
515 if (m_shift_val)
516 {
517 float declutchTime = std::min(m_shift_time - m_clutch_time, m_clutch_time);
518 if (m_shift_clock <= declutchTime)
519 {
520 // depress the clutch
521 float ratio = pow(1.0f - (m_shift_clock / declutchTime), 2);
522 m_cur_clutch = std::min(ratio, m_cur_clutch);
523 m_cur_acc = std::min(ratio, m_auto_cur_acc);
524 }
525 else
526 {
527 // engage a gear
529 if (m_autoselect != NEUTRAL)
530 {
532 m_cur_gear = std::max(-1, m_cur_gear);
533 m_cur_gear = std::min(m_cur_gear, m_num_gears);
534 }
535 m_shift_val = 0;
536 }
537 }
538
540 {
541 // we're done m_shifting
544 m_shifting = 0;
545 m_post_shifting = 1;
546 m_post_shift_clock = 0.0f;
547 }
549 {
550 // release the clutch <-- Done below
551 float timer = m_shift_clock - (m_shift_time - m_clutch_time);
552 float ratio = sqrt(timer / m_clutch_time);
553 m_cur_acc = (m_auto_cur_acc / 2.0f) * ratio;
554 }
555 }
556
557 if (m_post_shifting)
558 {
559 m_post_shift_clock += dt;
561 {
562 m_post_shifting = 0;
563 }
564 else if (m_auto_cur_acc > 0.0f)
565 {
567 m_cur_acc = (m_auto_cur_acc / 2.0f) + (m_auto_cur_acc / 2.0f) * ratio;
568 }
569 else if (m_cur_gear)
570 {
571 float gearboxspinner = m_cur_engine_rpm / m_gear_ratios[m_cur_gear + 1];
572 if (m_cur_wheel_revolutions > gearboxspinner)
573 {
574 float ratio = sqrt(m_post_shift_clock / m_post_shift_time);
575 m_cur_clutch = std::max(m_cur_clutch, ratio);
576 }
577 }
578 }
579
580 // auto clutch
581 float declutchRPM = m_engine_shiftup_rpm * 0.75f + m_engine_stall_rpm * 0.25f;
582 if (m_cur_gear == 0 || m_cur_engine_rpm < declutchRPM)
583 {
584 m_cur_clutch = 0.0f;
585 }
586 else if (m_cur_engine_rpm < m_engine_shiftup_rpm && m_engine_shiftup_rpm > declutchRPM)
587 {
588 float clutch = (m_cur_engine_rpm - declutchRPM) / (m_engine_shiftup_rpm - declutchRPM);
589 m_cur_clutch = std::min(clutch * clutch, m_cur_clutch);
590 }
592 {
593 float threshold = 1.5f * getEnginePower(m_cur_engine_rpm) * std::abs(m_gear_ratios[2]);
594 float gearboxspinner = m_cur_engine_rpm / m_gear_ratios[m_cur_gear + 1];
595 float clutchTorque = (gearboxspinner - m_cur_wheel_revolutions) * m_clutch_force;
596 float reTorque = Math::Clamp(clutchTorque, -threshold, +threshold) / m_gear_ratios[m_cur_gear + 1];
597
598 float range = (m_engine_max_rpm - m_engine_shiftup_rpm) * 0.4f * sqrt(std::max(0.2f, acc));
599 float powerRatio = std::min((m_cur_engine_rpm - m_engine_shiftup_rpm) / range, 1.0f);
600 float engineTorque = getEnginePower() * std::min(m_cur_acc, 0.9f) * powerRatio;
601
602 float torqueDiff = std::min(engineTorque, std::abs(reTorque));
603 float clutch = torqueDiff / reTorque;
604 m_cur_clutch = std::max(m_cur_clutch, clutch);
605 }
606
607 m_cur_clutch = std::max(0.0f, m_cur_clutch);
608 m_cur_clutch = std::min(m_cur_clutch, 1.0f);
609 }
610
611 if (doUpdate && !m_shifting && !m_post_shifting)
612 {
613 // gear hack
614 float velocity = m_actor->ar_nodes[0].Velocity.length();
615
616 Vector3 hdir = m_actor->GetCameraDir();
617 if (hdir != Vector3::ZERO)
618 {
619 velocity = hdir.dotProduct(m_actor->ar_nodes[0].Velocity);
620 }
621
622 if (m_actor->ar_wheels[0].wh_radius != 0)
623 {
625 }
626
628 {
630 {
631 if ((m_autoselect == DRIVE && m_cur_gear < m_num_gears && m_cur_clutch > 0.99f) || (m_autoselect == TWO && m_cur_gear < std::min(2, m_num_gears)))
632 {
634 shift(1);
635 }
636 }
639 {
640 shift(-1);
641 }
642
643 int newGear = m_cur_gear;
644
645 m_rpms.push_front(m_cur_engine_rpm);
646 m_accs.push_front(acc);
647 m_brakes.push_front(m_actor->ar_brake);
648
649 float avgRPM50 = 0.0f;
650 float avgRPM200 = 0.0f;
651 float avgAcc50 = 0.0f;
652 float avgAcc200 = 0.0f;
653 float avgBrake50 = 0.0f;
654 float avgBrake200 = 0.0f;
655
656 for (unsigned int i = 0; i < m_accs.size(); i++)
657 {
658 if (i < 50)
659 {
660 avgRPM50 += m_rpms[i];
661 avgAcc50 += m_accs[i];
662 avgBrake50 += m_brakes[i];
663 }
664
665 avgRPM200 += m_rpms[i];
666 avgAcc200 += m_accs[i];
667 avgBrake200 += m_brakes[i];
668 }
669
670 avgRPM50 /= std::min(m_rpms.size(), (std::deque<float>::size_type)50);
671 avgAcc50 /= std::min(m_accs.size(), (std::deque<float>::size_type)50);
672 avgBrake50 /= std::min(m_brakes.size(), (std::deque<float>::size_type)50);
673
674 avgRPM200 /= m_rpms.size();
675 avgAcc200 /= m_accs.size();
676 avgBrake200 /= m_brakes.size();
677
678 if (avgAcc50 > 0.8f || avgAcc200 > 0.8f || avgBrake50 > 0.8f || avgBrake200 > 0.8f)
679 {
680 m_shift_behaviour = std::min(m_shift_behaviour + 0.01f, 1.0f);
681 }
682 else if (acc < 0.5f && avgAcc50 < 0.5f && avgAcc200 < 0.5f && m_actor->ar_brake < 0.5f && avgBrake50 < 0.5f && avgBrake200 < 0.5)
683 {
684 m_shift_behaviour /= 1.01;
685 }
686
688 {
692 {
693 newGear--;
694 }
695 }
696 else if (avgAcc50 > 0.6f && acc < 0.8f && acc > avgAcc50 + 0.1f && m_cur_engine_rpm < m_engine_shiftup_rpm + m_half_rpm_range)
697 {
701 {
702 newGear--;
703 }
704 }
705 else if (avgAcc50 > 0.4f && acc < 0.8f && acc > avgAcc50 + 0.1f && m_cur_engine_rpm < m_engine_shiftup_rpm + m_half_rpm_range)
706 {
710 {
711 newGear--;
712 }
713 }
714 else if (m_cur_gear < (m_autoselect == TWO ? std::min(2, m_num_gears) : m_num_gears) &&
715 avgBrake200 < 0.2f && acc < std::min(avgAcc200 + 0.1f, 1.0f) && m_cur_engine_rpm > avgRPM200 - m_full_rpm_range / 20.0f)
716 {
718 {
720 {
721 newGear++;
722 }
723 }
724 else if (avgAcc200 < 0.4f && avgAcc200 > 0.2f && m_cur_engine_rpm > m_engine_shiftup_rpm + m_one_third_rpm_range)
725 {
727 {
728 newGear++;
729 }
730 }
731 else if (avgAcc200 < 0.2f && m_cur_engine_rpm > m_engine_shiftup_rpm + m_one_third_rpm_range / 2.0f && m_cur_engine_rpm < m_engine_shiftup_rpm + m_half_rpm_range)
732 {
734 {
735 newGear++;
736 }
737 }
738
739 if (newGear > m_cur_gear)
740 {
743 {
744 newGear = m_cur_gear;
745 }
746 }
747 else
748 {
750 }
751 }
752
753 if (newGear < m_cur_gear && m_kickdown_delay_counter > 0)
754 {
755 newGear = m_cur_gear;
756 }
758
759 if (newGear < m_cur_gear && std::abs(m_cur_wheel_revolutions * (m_gear_ratios[newGear + 1] - m_gear_ratios[m_cur_gear + 1])) > m_one_third_rpm_range / 6.0f ||
760 newGear > m_cur_gear && std::abs(m_cur_wheel_revolutions * (m_gear_ratios[newGear + 1] - m_gear_ratios[m_cur_gear + 1])) > m_one_third_rpm_range / 3.0f)
761 {
762 if (std::abs(m_actor->getGForces().y) < 0.25f)
763 shiftTo(newGear);
764 }
765
766 if (m_accs.size() > 200)
767 {
768 m_rpms.pop_back();
769 m_accs.pop_back();
770 m_brakes.pop_back();
771 }
772 // avoid over-revving
774 {
776 {
777 float clutch = 0.0f + 1.0f / (1.0f + std::abs(m_cur_wheel_revolutions * m_gear_ratios[m_cur_gear + 1] - m_engine_max_rpm * 1.25f) / 2.0f);
778 m_cur_clutch = std::min(clutch, m_cur_clutch);
779 }
780 if (m_cur_gear * m_cur_wheel_revolutions < -10.0f)
781 {
782 float clutch = 0.0f + 1.0f / (1.0f + std::abs(-10.0f - m_cur_gear * m_cur_wheel_revolutions) / 2.0f);
783 m_cur_clutch = std::min(clutch, m_cur_clutch);
784 }
785 }
786 }
787 }
788}
789
791{
792#ifdef USE_OPENAL
794 {
795 for (int i = 0; i < m_num_turbos; i++)
796 {
798 }
799 }
800
804
805 // reverse gear beep
806 if (m_cur_gear == -1 && m_engine_is_running)
807 {
809 }
810 else
811 {
813 }
814#endif // USE_OPENAL
815}
816
818{
819 m_auto_mode = static_cast<SimGearboxMode>(
820 (static_cast<int>(m_auto_mode) + 1) % (static_cast<int>(SimGearboxMode::MANUAL_RANGES) + 1));
821
823 {
824 if (m_cur_gear > 0)
826 if (m_cur_gear < 0)
828 if (m_cur_gear == 0)
830 }
831 else
832 {
834 }
835
837 {
839 }
840}
841
846
848{
849 this->m_auto_mode = mode;
850}
851
852void Engine::setAcc(float val)
853{
854 m_cur_acc = val;
855}
856
858{
860 {
861 return m_cur_turbo_rpm[0] / 10000.0f;
862 }
863
864 float turboPSI = 0;
865
866 if (m_turbo_has_bov)
867 {
868 for (int i = 0; i < m_num_turbos; i++)
869 turboPSI += m_turbo_bov_rpm[i] / 10000.0f;
870 }
871 else
872 {
873 for (int i = 0; i < m_num_turbos; i++)
874 turboPSI += m_cur_turbo_rpm[i] / 10000.0f;
875 }
876
877 return turboPSI;
878}
879
881{
882 return m_cur_acc;
883}
884
885void Engine::pushNetworkState(float rpm, float acc, float clutch, int gear, bool running, bool contact, char automode, char autoselect)
886{
887 m_cur_engine_rpm = rpm;
888 m_cur_acc = acc;
889 m_cur_clutch = clutch;
890 m_cur_gear = gear;
891 m_engine_is_running = running;
892 m_contact = contact;
893 if (automode != -1)
894 {
895 m_auto_mode = static_cast<SimGearboxMode>(automode);
896 }
897 if (autoselect != -1)
898 {
899 m_autoselect = (autoswitch)autoselect;
900 }
901}
902
904{
906 {
907 return m_cur_acc * (1.0f - m_cur_turbo_rpm[0] /* doesn't matter */ / m_max_turbo_rpm);// * m_engine_torque / 5000.0f;
908 }
909
910 return -1;
911}
912
914{
915 return m_cur_clutch_torque;
916}
917
918void Engine::setRPM(float rpm)
919{
920 m_cur_engine_rpm = rpm;
921}
922
924{
926}
927
928void Engine::setHydroPump(float work)
929{
930 m_hydropump_state = work;
931}
932
933void Engine::setWheelSpin(float rpm)
934{
936}
937
938void Engine::setTCaseRatio(float ratio)
939{
940 if (ratio < 1.0f)
941 return;
942
943 for (std::vector<float>::iterator it = m_gear_ratios.begin(); it != m_gear_ratios.end(); ++it)
944 {
945 (*it) /= m_tcase_ratio;
946 }
947
948 m_tcase_ratio = ratio;
949
950 for (std::vector<float>::iterator it = m_gear_ratios.begin(); it != m_gear_ratios.end(); ++it)
951 {
952 (*it) *= m_tcase_ratio;
953 }
954}
955
957{
958 // Pos: -1=reverse, 0 = neutral, 1 = 1st gear, 2 = 2nd gear, etc.
959 // --------------------------------------------------------------
960
961 if (pos < -1 || pos > m_num_gears)
962 return 0.f;
963
964 // Strip off the DiffRatio and TCaseRatio from the internal gear ratio
965 return (m_gear_ratios[pos + 1] / m_tcase_ratio) / m_diff_ratio;
966}
967
968// for hydros acceleration
970{
971 float minWorkingRPM = m_engine_idle_rpm * 1.1f; // minWorkingRPM > m_engine_idle_rpm avoids commands deadlocking the engine
972
973 float rpmRatio = (m_cur_engine_rpm - minWorkingRPM) / (m_engine_max_rpm - minWorkingRPM);
974 rpmRatio = std::max(0.0f, rpmRatio); // Avoids a negative rpmRatio when m_cur_engine_rpm < minWorkingRPM
975 rpmRatio = std::min(rpmRatio, 1.0f); // Avoids a rpmRatio > 1.0f when m_cur_engine_rpm > m_engine_max_rpm
976
977 float crankfactor = 5.0f * rpmRatio;
978
979 return crankfactor;
980}
981
983{
985 if (m_contact)
986 {
988 }
989 else
990 {
992 }
993}
994
996{
997 this->offStart();
998 m_contact = true;
1000 m_engine_is_running = true;
1002 {
1003 m_cur_gear = 1;
1004 }
1006 {
1008 }
1011}
1012
1014{
1015 m_air_pressure = 0.0f;
1017 m_contact = false;
1018 m_cur_acc = 0.0f;
1019 m_cur_clutch = 0.0f;
1020 m_cur_clutch_torque = 0.0f;
1021 m_cur_engine_rpm = 0.0f;
1022 m_cur_gear = 0;
1023 m_post_shifting = 0;
1024 m_engine_is_running = false;
1025 m_shifting = 0;
1026 m_shift_val = 0;
1028 {
1030 }
1031 for (int i = 0; i < m_num_turbos; i++)
1032 {
1033 m_cur_turbo_rpm[i] = 0.0f;
1034 m_turbo_bov_rpm[i] = 0.0f;
1035 }
1036}
1037
1039{
1040 return m_cur_gear;
1041}
1042
1043// low level gear changing
1045{
1046 m_cur_gear = v;
1047}
1048
1050{
1051 return m_cur_gear_range;
1052}
1053
1055{
1056 m_cur_gear_range = v;
1057}
1058
1068
1070{
1071 return (-m_braking_torque * std::pow(m_cur_engine_rpm / m_engine_max_rpm, 2.0f)) / getEnginePower();
1072}
1073
1074// high level controls
1075void Engine::autoSetAcc(float val)
1076{
1077 m_auto_cur_acc = val;
1078 if (!m_shifting)
1079 {
1080 setAcc(val);
1081 }
1082}
1083
1084void Engine::shift(int val)
1085{
1086 if (!val || m_cur_gear + val < -1 || m_cur_gear + val > getNumGears())
1087 return;
1089 {
1090 m_shift_val = val;
1091 m_shifting = 1;
1092 m_shift_clock = 0.0f;
1093 }
1094 else
1095 {
1096 if (m_cur_clutch > 0.25f)
1097 {
1099 }
1100 else
1101 {
1103 m_cur_gear += val;
1104 }
1105 }
1106}
1107
1108void Engine::shiftTo(int newGear)
1109{
1110 shift(newGear - m_cur_gear);
1111}
1112
1114{
1115 if (m_autoselect == MANUALMODE)
1116 return;
1117
1119 {
1121 }
1122
1123 if (m_autoselect == REAR)
1124 {
1125 m_cur_gear = -1;
1126 }
1127 else if (m_autoselect == NEUTRAL)
1128 {
1129 m_cur_gear = 0;
1130 }
1131 else if (m_autoselect == ONE)
1132 {
1133 m_cur_gear = 1;
1134 }
1135 else
1136 {
1137 // search for an appropriate gear
1138 int newGear = 1;
1139
1140 while (newGear < m_num_gears && m_cur_wheel_revolutions > 0.0f && m_cur_wheel_revolutions * m_gear_ratios[newGear + 1] > m_engine_max_rpm - 100.0f)
1141 {
1142 newGear++;
1143 }
1144
1145 m_cur_gear = newGear;
1146
1147 if (m_autoselect == TWO)
1148 {
1149 m_cur_gear = std::min(m_cur_gear, 2);
1150 }
1151 }
1152}
1153
1155{
1156 m_autoselect = (autoswitch)mode;
1159 updateShifts();
1160}
1161
1163{
1164 if (m_autoselect != REAR)
1165 {
1167 updateShifts();
1168 }
1169}
1170
1172{
1175 {
1177 updateShifts();
1178 }
1179}
1180
1182{
1183 return (int)m_autoselect;
1184}
1185
1187{
1189 {
1190 val = std::max(0.0f, val);
1191 m_cur_clutch = 1.0 - val;
1192 }
1193}
1194
1196{
1197 if (!m_engine_has_turbo)
1198 return 0.0f;
1199 if (m_engine_turbo_mode != NEW)
1200 return 0.0f;
1201
1202 float atValue = 0.0f; // torque (turbo integreation)
1203
1204 if (m_turbo_ver == 1)
1205 {
1206 for (int i = 0; i < m_num_turbos; i++)
1207 {
1209 }
1210 }
1211 else
1212 {
1213 atValue = (((getTurboPSI() * 6.8) * m_engine_torque) / 100); //1psi = 6% more power
1214 }
1215
1216 return atValue;
1217}
1218
1220{
1221 // engine power with limiter
1222 float tqValue = 1.0f; // ratio (0-1)
1223
1224 if (m_torque_curve)
1225 {
1226 tqValue = m_torque_curve->getEngineTorque(rpm);
1227 }
1228
1229 return (m_engine_torque * tqValue) + getTurboPower();
1230}
1231
1233{
1235 return m_max_idle_mixture;
1236 return m_min_idle_mixture;
1237}
1238
1240{
1242 {
1243 float crankfactor = getCrankFactor();
1244
1245 if (crankfactor < 0.9f)
1246 {
1247 // crankfactor is between 0.0f and 0.9f
1248 return 1.0f;
1249 }
1250 else if (crankfactor < 1.0f)
1251 {
1252 // crankfactor is between 0.9f and 1.0f
1253 return 10.0f * (1.0f - crankfactor);
1254 }
1255 }
1256
1257 return 0.0f;
1258}
1259
1261{
1264
1267 {
1268 float acclModifier = 0.0f;
1270 {
1271 acclModifier += 0.25f;
1272 }
1274 {
1275 acclModifier += 0.50f;
1276 }
1277 accl *= acclModifier;
1278 }
1279
1280 if (App::GetInputEngine()->getEventValue(EV_TRUCK_BRAKE_MODIFIER_25) ||
1282 {
1283 float brakeModifier = 0.0f;
1284 if (App::GetInputEngine()->getEventValue(EV_TRUCK_BRAKE_MODIFIER_25))
1285 {
1286 brakeModifier += 0.25f;
1287 }
1288 if (App::GetInputEngine()->getEventValue(EV_TRUCK_BRAKE_MODIFIER_50))
1289 {
1290 brakeModifier += 0.50f;
1291 }
1292 brake *= brakeModifier;
1293 }
1294
1295 // arcade controls are only working with auto-clutch!
1296 if (!App::io_arcade_controls->getBool() || (this->getAutoMode() >= SimGearboxMode::MANUAL))
1297 {
1298 // classic mode, realistic
1299 this->autoSetAcc(accl);
1300 m_actor->ar_brake = brake;
1301 }
1302 else
1303 {
1304 // start engine
1305 if (this->hasContact() && !this->isRunning() && (accl > 0 || brake > 0))
1306 {
1307 this->startEngine();
1308 }
1309
1310 // arcade controls: hey - people wanted it x| ... <- and it's convenient
1311 if (this->getGear() >= 0)
1312 {
1313 // neutral or drive forward, everything is as its used to be: brake is brake and accel. is accel.
1314 this->autoSetAcc(accl);
1315 m_actor->ar_brake = brake;
1316 }
1317 else
1318 {
1319 // reverse gear, reverse controls: brake is accel. and accel. is brake.
1320 this->autoSetAcc(brake);
1321 m_actor->ar_brake = accl;
1322 }
1323
1324 // only when the truck really is not moving anymore
1325 if (fabs(m_actor->ar_avg_wheel_speed) <= 1.0f)
1326 {
1327 Ogre::Vector3 hdir = m_actor->getDirection();
1328 float velocity = hdir.dotProduct(m_actor->ar_nodes[0].Velocity);
1329
1330 // switching point, does the user want to drive forward from backward or the other way round? change gears?
1331 if (velocity < 1.0f && brake > 0.5f && accl < 0.5f && this->getGear() > 0)
1332 {
1333 // we are on the brake, jump to reverse gear
1334 if (this->getAutoMode() == SimGearboxMode::AUTO)
1335 {
1337 }
1338 else
1339 {
1340 this->setGear(-1);
1341 }
1342 }
1343 else if (velocity > -1.0f && brake < 0.5f && accl > 0.5f && this->getGear() < 0)
1344 {
1345 // we are on the gas pedal, jump to first gear when we were in rear gear
1346 if (this->getAutoMode() == SimGearboxMode::AUTO)
1347 {
1349 }
1350 else
1351 {
1352 this->setGear(1);
1353 }
1354 }
1355 }
1356 }
1357
1358 // gear management
1359 if (this->getAutoMode() == SimGearboxMode::AUTO)
1360 {
1361 if (App::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_AUTOSHIFT_UP))
1362 {
1363 this->autoShiftUp();
1364 }
1365 if (App::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_AUTOSHIFT_DOWN))
1366 {
1367 this->autoShiftDown();
1368 }
1369 }
1370
1371 if (App::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_TOGGLE_CONTACT))
1372 {
1373 this->toggleContact();
1374 }
1375
1376 if (App::GetInputEngine()->getEventBoolValue(EV_TRUCK_STARTER) && this->hasContact() && !this->isRunning())
1377 {
1378 m_starter = true;
1381 }
1382 else
1383 {
1384 m_starter = false;
1386 }
1387
1388 if (App::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_SWITCH_SHIFT_MODES))
1389 {
1390 // toggle Auto shift
1391 this->toggleAutoMode();
1392
1393 // force gui update
1395
1397 ToLocalizedString(this->getAutoMode()), "cog.png");
1398 }
1399
1400 // joy clutch
1404 {
1405 float clutchModifier = 0.0f;
1407 {
1408 clutchModifier += 0.25f;
1409 }
1411 {
1412 clutchModifier += 0.50f;
1413 }
1414 clutch *= clutchModifier;
1415 }
1416 this->setManualClutch(clutch);
1417
1418 SimGearboxMode shiftmode = this->getAutoMode();
1419
1420 if (shiftmode <= SimGearboxMode::MANUAL) // auto, semi auto and sequential shifting
1421 {
1422 if (App::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_SHIFT_UP))
1423 {
1424 this->shift(1);
1425 }
1426 else if (App::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_SHIFT_DOWN))
1427 {
1428 if (shiftmode > SimGearboxMode::SEMI_AUTO ||
1429 shiftmode == SimGearboxMode::SEMI_AUTO && (!App::io_arcade_controls->getBool()) ||
1430 shiftmode == SimGearboxMode::SEMI_AUTO && this->getGear() > 0 ||
1431 shiftmode == SimGearboxMode::AUTO)
1432 {
1433 this->shift(-1);
1434 }
1435 }
1436 else if (shiftmode != SimGearboxMode::AUTO)
1437 {
1438 if (App::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_SHIFT_NEUTRAL))
1439 {
1440 this->shiftTo(0);
1441 }
1442 else if (App::GetInputEngine()->getEventBoolValue(EV_TRUCK_SHIFT_GEAR_REVERSE))
1443 {
1444 this->shiftTo(-1);
1445 }
1446 else
1447 {
1448 for (int i = 1; i < 19; i++)
1449 {
1450 if (App::GetInputEngine()->getEventBoolValue(EV_TRUCK_SHIFT_GEAR01 + i - 1))
1451 {
1452 this->shiftTo(i);
1453 }
1454 }
1455 }
1456 }
1457 }
1458 else //if (shiftmode > SimGearboxMode::MANUAL) // h-shift or h-shift with ranges shifting
1459 {
1460 bool gear_changed = false;
1461 bool found = false;
1462 int curgear = this->getGear();
1463 int curgearrange = this->getGearRange();
1464 int gearoffset = std::max(0, curgear - curgearrange * 6);
1465
1466 // one can select range only if in neutral
1467 if (shiftmode == SimGearboxMode::MANUAL_RANGES && curgear == 0)
1468 {
1469 if (App::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_SHIFT_LOWRANGE) && curgearrange != 0)
1470 {
1471 this->setGearRange(0);
1472 gear_changed = true;
1473 }
1474 else if (App::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_SHIFT_MIDRANGE) && curgearrange != 1 && this->getNumGearsRanges() > 1)
1475 {
1476 this->setGearRange(1);
1477 gear_changed = true;
1478 }
1479 else if (App::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_SHIFT_HIGHRANGE) && curgearrange != 2 && this->getNumGearsRanges() > 2)
1480 {
1481 this->setGearRange(2);
1482 gear_changed = true;
1483 }
1484 else if (App::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_CYCLE_GEAR_RANGES))
1485 {
1486 this->setGearRange((curgearrange + 1) % this->getNumGearsRanges());
1487 gear_changed = true;
1489 fmt::format(_L("Range cycled (current: {}/available: {})"),
1490 this->getGearRange(), this->getNumGearsRanges()), "cog.png");
1491 }
1492
1493 if (gear_changed)
1494 {
1495 switch (this->getGearRange())
1496 {
1497 case 0:
1499 break;
1500 case 1:
1502 break;
1503 case 2:
1505 break;
1506 default:
1507 break;
1508 }
1509 }
1510 }
1511 //zaxxon
1512 if (curgear == -1)
1513 {
1515 }
1516 else if (curgear > 0 && curgear < 19)
1517 {
1518 gear_changed = !App::GetInputEngine()->getEventBoolValue(EV_TRUCK_SHIFT_GEAR01 + gearoffset - 1); // range mode
1519 }
1520
1521 if (gear_changed || curgear == 0)
1522 {
1523 if (App::GetInputEngine()->getEventBoolValue(EV_TRUCK_SHIFT_GEAR_REVERSE))
1524 {
1525 this->shiftTo(-1);
1526 found = true;
1527 }
1528 else if (App::GetInputEngine()->getEventBoolValue(EV_TRUCK_SHIFT_NEUTRAL))
1529 {
1530 this->shiftTo(0);
1531 found = true;
1532 }
1533 else
1534 {
1535 if (shiftmode == SimGearboxMode::MANUAL_STICK)
1536 {
1537 for (int i = 1; i < 19 && !found; i++)
1538 {
1539 if (App::GetInputEngine()->getEventBoolValue(EV_TRUCK_SHIFT_GEAR01 + i - 1))
1540 {
1541 this->shiftTo(i);
1542 found = true;
1543 }
1544 }
1545 }
1546 else // SimGearboxMode::MANUALMANUAL_RANGES
1547 {
1548 for (int i = 1; i < 7 && !found; i++)
1549 {
1550 if (App::GetInputEngine()->getEventBoolValue(EV_TRUCK_SHIFT_GEAR01 + i - 1))
1551 {
1552 this->shiftTo(i + curgearrange * 6);
1553 found = true;
1554 }
1555 }
1556 }
1557 }
1558 if (!found)
1559 {
1560 this->shiftTo(0);
1561 }
1562 } // end of if (gear_changed)
1563 } // end of shitmode > SimGearboxMode::MANUAL
1564}
System integration layer; inspired by OgreBites::ApplicationContext.
void LOG(const char *msg)
Legacy alias - formerly a macro.
float frand()
Definition ApproxMath.h:31
float approx_exp(const float x)
Definition ApproxMath.h:68
#define MAXTURBO
Definition Engine.h:256
#define _L
Handles controller inputs from player.
static const float RAD_PER_SEC_TO_RPM
Convert radian/second to RPM (60/2*PI)
#define SOUND_START(_ACTOR_, _TRIG_)
#define SOUND_STOP(_ACTOR_, _TRIG_)
#define SOUND_PLAY_ONCE(_ACTOR_, _TRIG_)
#define SOUND_MODULATE(_ACTOR_, _MOD_, _VALUE_)
torquecurve loader.
wheel_t ar_wheels[MAX_WHEELS]
Definition Actor.h:384
node_t * ar_nodes
Definition Actor.h:330
Ogre::Vector3 getDirection()
average actor velocity, calculated using the actor positions of the last two frames
Definition Actor.cpp:365
ActorInstanceID_t ar_instance_id
Static attr; session-unique ID.
Definition Actor.h:429
float ar_avg_wheel_speed
Physics state; avg wheel speed in m/s.
Definition Actor.h:455
Ogre::Real ar_brake
Physics state; braking intensity.
Definition Actor.h:452
void RequestUpdateHudFeatures()
Definition Actor.h:310
Ogre::Vector3 GetCameraDir()
Definition Actor.h:306
Ogre::Vector3 getGForces()
Definition Actor.h:91
@ CONSOLE_MSGTYPE_INFO
Generic message.
Definition Console.h:60
void putMessage(MessageArea area, MessageType type, std::string const &msg, std::string icon="")
Definition Console.cpp:103
@ CONSOLE_SYSTEM_NOTICE
Definition Console.h:51
float getCrankFactor()
Definition Engine.cpp:969
float m_tcase_ratio
Engine.
Definition Engine.h:214
float m_engine_addi_torque[MAXTURBO]
Definition Engine.h:262
int m_turbo_ver
Definition Engine.h:257
void setWheelSpin(float rpm)
Definition Engine.cpp:933
float m_engine_shiftup_rpm
Shift down RPM ('engine' attr #1)
Definition Engine.h:221
void autoShiftSet(int mode)
Definition Engine.cpp:1154
void pushNetworkState(float engine_rpm, float acc, float clutch, int gear, bool running, bool contact, char auto_mode, char auto_select=-1)
Definition Engine.cpp:885
float m_antilag_power_factor
Definition Engine.h:275
std::deque< float > m_rpms
Definition Engine.h:251
char m_engine_type
't' = truck (default), 'c' = car ('engoption' attr #2)
Definition Engine.h:208
void UpdateInputEvents(float dt)
Definition Engine.cpp:1260
float m_cur_engine_torque
Engine.
Definition Engine.h:212
bool m_turbo_has_antilag
Definition Engine.h:272
bool m_turbo_has_bov
Definition Engine.h:264
float m_one_third_rpm_range
Definition Engine.h:246
float m_hydropump_state
Engine.
Definition Engine.h:216
SimGearboxMode getAutoMode()
Definition Engine.cpp:842
int m_post_shifting
Definition Engine.h:237
float getAccToHoldRPM()
estimate required throttle input to hold the current rpm
Definition Engine.cpp:1069
void setGearRange(int v)
low level gear changing (bypasses shifting logic)
Definition Engine.cpp:1054
void startEngine()
Quick engine start. Plays sounds.
Definition Engine.cpp:995
float m_cur_wheel_revolutions
Gears; measured wheel revolutions.
Definition Engine.h:190
int m_engine_turbo_mode
Engine attribute.
Definition Engine.h:206
float m_diff_ratio
Global gear ratio ('engine' attr #4)
Definition Engine.h:213
int m_max_turbo_rpm
Definition Engine.h:261
int m_shift_val
Definition Engine.h:239
float m_post_shift_clock
Definition Engine.h:234
float m_engine_inertia
('engoption' attr #1)
Definition Engine.h:219
float m_antilag_rand_chance
Definition Engine.h:274
float m_min_wastegate_psi
Definition Engine.h:268
float getTurboPower()
Definition Engine.cpp:1195
float m_cur_engine_rpm
Engine.
Definition Engine.h:211
void setPrime(bool p)
Definition Engine.cpp:923
float m_engine_idle_rpm
('engoption' attr #8)
Definition Engine.h:222
bool m_turbo_has_wastegate
Definition Engine.h:267
float getSmoke()
Definition Engine.cpp:903
void autoShiftDown()
Definition Engine.cpp:1171
bool m_engine_has_air
Engine attribute.
Definition Engine.h:204
float m_max_idle_mixture
Maximum throttle to maintain the idle RPM ('engoption' attr #9)
Definition Engine.h:218
void setHydroPump(float work)
Definition Engine.cpp:928
void SetEngineOptions(float einertia, char etype, float eclutch, float ctime, float stime, float pstime, float irpm, float srpm, float maximix, float minimix, float ebraking)
Definition Engine.cpp:196
float getTorque()
Definition Engine.cpp:913
void setTCaseRatio(float ratio)
Set current transfer case gear (reduction) ratio.
Definition Engine.cpp:938
void UpdateEngine(float dt, int doUpdate)
Definition Engine.cpp:258
float m_auto_cur_acc
Definition Engine.h:244
float getEnginePower()
Definition Engine.h:106
int getNumGears() const
Definition Engine.h:62
bool m_contact
Ignition switch is in ON/RUN position.
Definition Engine.h:229
std::deque< float > m_accs
Definition Engine.h:252
float m_cur_turbo_rpm[MAXTURBO]
Definition Engine.h:258
std::deque< float > m_brakes
Definition Engine.h:253
TorqueCurve * m_torque_curve
Definition Engine.h:225
void offStart()
Quick start of vehicle engine.
Definition Engine.cpp:1013
float m_turbo_wg_threshold_n
Definition Engine.h:271
float m_braking_torque
Engine attribute.
Definition Engine.h:209
int m_cur_gear
Gears; Current gear {-1 = reverse, 0 = neutral, 1...21 = forward}.
Definition Engine.h:191
int m_cur_gear_range
Gears.
Definition Engine.h:192
float m_turbo_bov_rpm[MAXTURBO]
Definition Engine.h:265
int m_kickdown_delay_counter
Definition Engine.h:250
float m_air_pressure
Definition Engine.h:226
float m_half_rpm_range
Definition Engine.h:247
float m_turbo_wg_threshold_p
Definition Engine.h:270
float m_turbo_engine_rpm_operation
Definition Engine.h:263
Engine(float min_rpm, float max_rpm, float torque, float reverse_gear, float neutral_gear, std::vector< float > gears, float dratio, ActorPtr actor)
Definition Engine.cpp:37
int m_min_bov_psi
Definition Engine.h:266
float m_shift_time
Time (in seconds) that it takes to shift ('engoption' attr #4)
Definition Engine.h:235
float m_cur_clutch
Definition Engine.h:199
autoswitch m_autoselect
Definition Engine.h:243
float m_full_rpm_range
Definition Engine.h:245
float getPrimeMixture()
Definition Engine.cpp:1239
bool m_turbo_flutters
Definition Engine.h:269
float m_antilag_min_rpm
Definition Engine.h:273
float m_clutch_time
Time (in seconds) the clutch takes to apply ('engoption' attr #5)
Definition Engine.h:198
void setGear(int v)
low level gear changing (bypasses shifting logic)
Definition Engine.cpp:1044
float m_shift_clock
Definition Engine.h:236
ActorPtr m_actor
Definition Engine.h:186
bool m_engine_has_turbo
Engine attribute.
Definition Engine.h:205
std::vector< float > m_gear_ratios
[R|N|1|...] ('engine' attrs #4[global],#5[R],#6[N],#7[1]...)
Definition Engine.h:194
void autoSetAcc(float val)
Definition Engine.cpp:1075
float m_cur_clutch_torque
Definition Engine.h:200
float m_ref_wheel_revolutions
Gears; estimated wheel revolutions based on current vehicle speed along the longi....
Definition Engine.h:189
float m_min_idle_mixture
Minimum throttle to maintain the idle RPM ('engoption' attr #10)
Definition Engine.h:217
void stopEngine()
stall engine
Definition Engine.cpp:1059
int m_num_gears
Num. forward gears.
Definition Engine.h:193
int getAutoShift()
Definition Engine.cpp:1181
bool m_starter
Ignition switch is in START position.
Definition Engine.h:230
SimGearboxMode m_auto_mode
Definition Engine.h:242
int m_upshift_delay_counter
Definition Engine.h:249
void SetTurboOptions(int type, float tinertiaFactor, int nturbos, float param1, float param2, float param3, float param4, float param5, float param6, float param7, float param8, float param9, float param10, float param11)
Definition Engine.cpp:128
float m_clutch_force
('engoption' attr #3)
Definition Engine.h:197
void autoShiftUp()
Definition Engine.cpp:1162
void setAutoMode(SimGearboxMode mode)
Definition Engine.cpp:847
void setManualClutch(float val)
Definition Engine.cpp:1186
bool m_engine_is_priming
Engine.
Definition Engine.h:224
int getGear()
Definition Engine.cpp:1038
void shift(int val)
Changes gear by a relative offset. Plays sounds.
Definition Engine.cpp:1084
bool m_engine_is_electric
Engine attribute.
Definition Engine.h:203
float getIdleMixture()
Definition Engine.cpp:1232
float m_post_shift_time
Time (in seconds) until full torque is transferred ('engoption' attr #6)
Definition Engine.h:233
bool m_engine_is_running
Engine state.
Definition Engine.h:207
void toggleContact()
Ignition.
Definition Engine.cpp:982
void toggleAutoMode()
Definition Engine.cpp:817
void updateShifts()
Changes gears. Plays sounds.
Definition Engine.cpp:1113
float m_engine_max_rpm
Shift up RPM ('engine' attr #2)
Definition Engine.h:220
float m_engine_stall_rpm
('engoption' attr #7)
Definition Engine.h:223
int getNumGearsRanges() const
Definition Engine.h:63
void setAcc(float val)
Definition Engine.cpp:852
float getAcc()
Definition Engine.cpp:880
float m_shift_behaviour
Definition Engine.h:248
void UpdateEngineAudio()
Definition Engine.cpp:790
float m_cur_acc
Engine.
Definition Engine.h:210
float m_turbo_inertia_factor
Definition Engine.h:259
float m_engine_torque
Torque in N/m ('engine' attr #3)
Definition Engine.h:215
int m_num_turbos
Definition Engine.h:260
void shiftTo(int val)
Changes gear to given value. Plays sounds.
Definition Engine.cpp:1108
bool isRunning()
Definition Engine.h:101
void setRPM(float rpm)
Definition Engine.cpp:918
int getGearRange()
Definition Engine.cpp:1049
float getGearRatio(int pos)
-1=R, 0=N, 1... ('engine' attrs #5[R],#6[N],#7[1]...)
Definition Engine.cpp:956
int m_shifting
Definition Engine.h:238
float getTurboPSI()
Definition Engine.cpp:857
bool hasContact()
Ignition.
Definition Engine.h:102
bool getEventBoolValue(int eventID)
float getEventValue(int eventID, bool pure=false, InputSourceType valueSource=InputSourceType::IST_ANY)
valueSource: IST_ANY=digital and analog devices, IST_DIGITAL=only digital, IST_ANALOG=only analog
This class loads and processes a torque curve for a vehicle.
Definition TorqueCurve.h:43
Ogre::Real getEngineTorque(Ogre::Real rpm)
Returns the calculated engine torque based on the given RPM, interpolating the torque curve spline.
@ SS_TRIG_TURBOBACKFIRE
@ SS_TRIG_TURBOWASTEGATE
@ SS_TRIG_AIR_PURGE
@ SS_TRIG_GEARSLIDE
@ SS_TRIG_REVERSE_GEAR
@ EV_TRUCK_ACCELERATE
accelerate the truck
@ EV_TRUCK_MANUAL_CLUTCH_MODIFIER_50
manual clutch with 50 percent pedal input
@ EV_TRUCK_SHIFT_GEAR01
shift directly into this gear
@ EV_TRUCK_SHIFT_MIDRANGE
select middle range (7-12) for H-shaft
@ EV_TRUCK_SHIFT_HIGHRANGE
select high range (13-18) for H-shaft
@ EV_TRUCK_SHIFT_LOWRANGE
select low range (1-6) for H-shaft
@ EV_TRUCK_MANUAL_CLUTCH_MODIFIER_25
manual clutch with 25 percent pedal input
@ EV_TRUCK_AUTOSHIFT_UP
shift automatic transmission one gear up
@ EV_TRUCK_ACCELERATE_MODIFIER_50
accelerate with 50 percent pedal input
@ EV_TRUCK_MANUAL_CLUTCH
manual clutch (for manual transmission)
@ EV_TRUCK_SHIFT_UP
shift one gear up in manual transmission mode
@ EV_TRUCK_TOGGLE_CONTACT
toggle ignition
@ EV_TRUCK_AUTOSHIFT_DOWN
shift automatic transmission one gear down
@ EV_TRUCK_SHIFT_NEUTRAL
shift to neutral gear in manual transmission mode
@ EV_TRUCK_SWITCH_SHIFT_MODES
toggle between transmission modes
@ EV_TRUCK_BRAKE
brake
@ EV_TRUCK_SHIFT_GEAR_REVERSE
shift directly into this gear
@ EV_TRUCK_CYCLE_GEAR_RANGES
cycle through the ranges
@ EV_TRUCK_STARTER
hold to start the engine
@ EV_TRUCK_SHIFT_DOWN
shift one gear down in manual transmission mode
@ EV_TRUCK_BRAKE_MODIFIER_25
brake with 25 percent pedal input
@ EV_TRUCK_BRAKE_MODIFIER_50
brake with 50 percent pedal input
@ EV_TRUCK_ACCELERATE_MODIFIER_25
accelerate with 25 percent pedal input
void TRIGGER_EVENT_ASYNC(scriptEvents type, int arg1, int arg2ex=0, int arg3ex=0, int arg4ex=0, std::string arg5ex="", std::string arg6ex="", std::string arg7ex="", std::string arg8ex="")
Asynchronously (via MSG_SIM_SCRIPT_EVENT_TRIGGERED) invoke script function eventCallbackEx(),...
SimGearboxMode
std::string ToLocalizedString(SimGearboxMode e)
@ MANUAL_STICK
Fully manual: stick shift.
@ MANUAL_RANGES
Fully manual: stick shift with ranges.
@ SEMI_AUTO
Manual shift with auto clutch.
@ MANUAL
Fully manual: sequential shift.
@ AUTO
Automatic shift.
InputEngine * GetInputEngine()
Console * GetConsole()
CVar * io_arcade_controls
@ SE_TRUCK_ENGINE_DIED
triggered when the vehicle's engine dies (from underrev, water, etc), the argument refers to the acto...
Ogre::Vector3 Velocity
Definition SimData.h:268
Ogre::Real wh_radius
Definition SimData.h:411