Rigs of Rods 2023.09
Soft-body Physics Simulation
Loading...
Searching...
No Matches
ForceFeedback.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-2020 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 "ForceFeedback.h"
23
24#include "Application.h"
25#include "Actor.h"
26#include "Console.h"
27#include "GameContext.h"
28#include "InputEngine.h"
29
30#include <OISForceFeedback.h>
31#include <OgreString.h>
32
33namespace RoR {
34
36{
37 using namespace Ogre;
39 if (!m_device)
40 {
41 return;
42 }
43 LOG(String("ForceFeedback: ")+TOSTRING(m_device->getFFAxesNumber())+" axe(s)");
44
45 m_device->setAutoCenterMode(false);
46 m_device->setMasterGain(0.0);
47
48 //do not load effect now, its too early
49}
50
51void ForceFeedback::SetForces(float roll, float pitch, float wspeed, float dircommand, float stress)
52{
53 if (!m_device) { return; }
54
55 //LOG(String("ForceFeedback: R=")+TOSTRING(roll)+" D="+TOSTRING(dir)+" S="+TOSTRING(wspeed)+" H="+TOSTRING(stress));
56 if (!m_hydro_effect)
57 {
58 //we create effect at the last moment, because it does not works otherwise
59 m_hydro_effect = new OIS::Effect(OIS::Effect::ConstantForce, OIS::Effect::Constant);
60 m_hydro_effect->direction = OIS::Effect::North;
61 m_hydro_effect->trigger_button = 0;
62 m_hydro_effect->trigger_interval = 0;
63 m_hydro_effect->replay_length = OIS::Effect::OIS_INFINITE; // Linux/Win32: Same behaviour as 0.
64 m_hydro_effect->replay_delay = 0;
65 m_hydro_effect->setNumAxes(1);
66 OIS::ConstantEffect* hydroConstForce = dynamic_cast<OIS::ConstantEffect*>(m_hydro_effect->getForceEffect());
67 if (hydroConstForce != nullptr)
68 {
69 hydroConstForce->level = 0; //-10K to +10k
70 hydroConstForce->envelope.attackLength = 0;
71 hydroConstForce->envelope.attackLevel = (unsigned short)hydroConstForce->level;
72 hydroConstForce->envelope.fadeLength = 0;
73 hydroConstForce->envelope.fadeLevel = (unsigned short)hydroConstForce->level;
74 }
75 m_device->upload(m_hydro_effect);
76 }
77
78 OIS::ConstantEffect* hydroConstForce = dynamic_cast<OIS::ConstantEffect*>(m_hydro_effect->getForceEffect());
79 if (hydroConstForce != nullptr)
80 {
81 float stress_gain = App::io_ffb_stress_gain->getFloat();
82 float centering_gain = App::io_ffb_center_gain->getFloat();
83 float ff = -stress * stress_gain + dircommand * 100.0 * centering_gain * wspeed * wspeed;
84 if (ff > 10000)
85 ff = 10000;
86 if (ff < -10000)
87 ff = -10000;
88 hydroConstForce->level = ff; //-10K to +10k
89 }
90 m_device->modify(m_hydro_effect);
91}
92
94{
95 if (!m_device) { return; }
96
97 if (b != m_enabled)
98 {
99 float gain = (b) ? App::io_ffb_master_gain->getFloat() : 0.f;
100 m_device->setMasterGain(gain);
101 }
102 m_enabled = b;
103}
104
106{
107 if (!m_device)
108 {
110 _L("Disabling force feedback - no controller found"));
112 return;
113 }
114
115 ActorPtr player_actor = App::GetGameContext()->GetPlayerActor();
116 if (player_actor && player_actor->ar_driveable == TRUCK)
117 {
118 Ogre::Vector3 ff_vehicle = player_actor->GetFFbBodyForces();
119 this->SetForces(
120 -ff_vehicle.dotProduct(player_actor->GetCameraRoll()) / 10000.0,
121 ff_vehicle.dotProduct(player_actor->GetCameraDir()) / 10000.0,
122 player_actor->ar_wheel_speed,
123 player_actor->ar_hydro_dir_command,
124 player_actor->GetFFbHydroForces());
125 }
126}
127
128} // namespace RoR
Central state/object manager and communications hub.
#define TOSTRING(x)
Definition Application.h:57
void LOG(const char *msg)
Legacy alias - formerly a macro.
#define _L
Game state manager and message-queue provider.
Handles controller inputs from player.
float getFloat() const
Definition CVar.h:96
void setVal(T val)
Definition CVar.h:72
@ 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_WARNING
Definition Console.h:53
OIS::ForceFeedback * m_device
void SetEnabled(bool v)
void Update()
Reads data from simulation.
OIS::Effect * m_hydro_effect
void SetForces(float roll, float pitch, float wspeed, float dircommand, float stress)
Called by Update(); we take here : -roll and pitch inertial forces at the camera: this is not used cu...
const ActorPtr & GetPlayerActor()
OIS::ForceFeedback * getForceFeedbackDevice()
@ TRUCK
its a truck (or other land vehicle)
Definition SimData.h:85
CVar * io_ffb_enabled
InputEngine * GetInputEngine()
CVar * io_ffb_stress_gain
GameContext * GetGameContext()
CVar * io_ffb_center_gain
Console * GetConsole()
CVar * io_ffb_master_gain