RigsofRods
Soft-body Physics Simulation
MumbleIntegration.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 
25 
26 #ifdef USE_MUMBLE
27 
28 #include "MumbleIntegration.h"
29 
30 #include "Application.h"
31 #include "CameraManager.h"
32 #include "Character.h"
33 #include "GameContext.h"
34 
35 #include <Ogre.h>
36 #include <MyGUI_UString.h>
37 
38 using namespace Ogre;
39 using namespace RoR;
40 
41 MumbleIntegration::MumbleIntegration() : lm(NULL)
42 {
43  initMumble();
44 }
45 
46 MumbleIntegration::~MumbleIntegration()
47 {
48  if (lm != nullptr)
49  delete lm;
50 }
51 
52 void MumbleIntegration::initMumble()
53 {
54 #ifdef _WIN32
55  HANDLE hMapObject = OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, L"MumbleLink");
56  if (hMapObject == NULL)
57  return;
58 
59  lm = (LinkedMem *) MapViewOfFile(hMapObject, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(LinkedMem));
60  if (lm == NULL)
61  {
62  CloseHandle(hMapObject);
63  hMapObject = NULL;
64  return;
65  }
66 #else
67  char memname[256];
68  snprintf(memname, 256, "/MumbleLink.%d", getuid());
69 
70  int shmfd = shm_open(memname, O_RDWR, S_IRUSR | S_IWUSR);
71 
72  if (shmfd < 0)
73  {
74  return;
75  }
76 
77  lm = (LinkedMem *)(mmap(NULL, sizeof(struct LinkedMem), PROT_READ | PROT_WRITE, MAP_SHARED, shmfd,0));
78 
79  if (lm == (void *)(-1))
80  {
81  lm = NULL;
82  return;
83  }
84 #endif // _WIN32
85 }
86 
87 void MumbleIntegration::SetNonPositionalAudio()
88 {
89  if (! lm)
90  return;
91 
92  this->updateMumble(
93  Ogre::Vector3::ZERO,
94  Ogre::Vector3(0.0f, 0.0f, 1.0f),
95  Ogre::Vector3(0.0f, 1.0f, 0.0f),
96  Ogre::Vector3::ZERO,
97  Ogre::Vector3(0.0f, 0.0f, 1.0f),
98  Ogre::Vector3(0.0f, 1.0f, 0.0f));
99 }
100 
101 void MumbleIntegration::Update()
102 {
103  if (App::app_state->getEnum<AppState>() == AppState::SIMULATION &&
104  App::mp_state->getEnum<MpState>() == MpState::CONNECTED)
105  {
106  // calculate orientation of avatar first
108  Ogre::Vector3 avatarDir = Ogre::Vector3(Math::Cos(avatar->getRotation()), 0.0f, Math::Sin(avatar->getRotation()));
109  Ogre::Vector3 upVector = App::GetCameraManager()->GetCameraNode()->getOrientation() * Ogre::Vector3::UNIT_Y;
110  // Direction points down -Z by default (adapted from Ogre::Camera)
111  Ogre::Vector3 cameraDir = App::GetCameraManager()->GetCameraNode()->getOrientation() * -Ogre::Vector3::UNIT_Z;
112  App::GetMumble()->updateMumble(App::GetCameraManager()->GetCameraNode()->getPosition(), cameraDir, upVector,
113  App::GetGameContext()->GetPlayerCharacter()->getPosition() + Vector3(0, 1.8f, 0), avatarDir, Ogre::Vector3(0.0f, 1.0f, 0.0f));
114  }
115  else
116  {
117  this->SetNonPositionalAudio();
118  }
119 }
120 
121 void MumbleIntegration::updateMumble(Ogre::Vector3 cameraPos, Ogre::Vector3 cameraDir, Ogre::Vector3 cameraUp, Ogre::Vector3 avatarPos, Ogre::Vector3 avatarDir, Ogre::Vector3 avatarUp)
122 {
123  if (! lm)
124  return;
125 
126  if (lm->uiVersion != 2)
127  {
128  wcsncpy(lm->name, L"Rigs of Rods", 256);
129  wcsncpy(lm->description, L"This plugin links Rigs of Rods with Mumble", 2048);
130  lm->uiVersion = 2;
131  }
132  lm->uiTick++;
133 
134  // Left handed coordinate system ( http://wiki.mumble.info/index.php?title=Link#Coordinate_system )
135  // X positive towards "right".
136  // Y positive towards "up".
137  // Z positive towards "front".
138  //
139  // 1 unit = 1 meter
140 
141  // OGRE uses right-handed coordinate system ( http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Basic+Tutorial+1&structure=Tutorials )
142  // X positive towards "right".
143  // Y positive towards "up".
144  // Z positive towards "back". => conversion necessary!
145  //
146  // 1 unit = 1 meter (in RoR)
147 
148  // We need unit vectors
149  avatarDir.normalise();
150  avatarUp.normalise();
151  cameraDir.normalise();
152  cameraUp.normalise();
153 
154  // Position of the avatar
155  lm->fAvatarPosition[0] = avatarPos.x;
156  lm->fAvatarPosition[1] = avatarPos.y;
157  lm->fAvatarPosition[2] = -avatarPos.z;
158 
159  // Unit vector pointing out of the avatars eyes
160  lm->fAvatarFront[0] = avatarDir.x;
161  lm->fAvatarFront[1] = avatarDir.y;
162  lm->fAvatarFront[2] = -avatarDir.z;
163 
164  // Unit vector pointing out of the top of the avatars head
165  lm->fAvatarTop[0] = avatarUp.x;
166  lm->fAvatarTop[1] = avatarUp.y;
167  lm->fAvatarTop[2] = -avatarUp.z;
168 
169  // Same as avatar but for the camera.
170  lm->fCameraPosition[0] = cameraPos.x;
171  lm->fCameraPosition[1] = cameraPos.y;
172  lm->fCameraPosition[2] = -cameraPos.z;
173 
174  lm->fCameraFront[0] = cameraDir.x;
175  lm->fCameraFront[1] = cameraDir.y;
176  lm->fCameraFront[2] = -cameraDir.z;
177 
178  lm->fCameraTop[0] = cameraUp.x;
179  lm->fCameraTop[1] = cameraUp.y;
180  lm->fCameraTop[2] = -cameraUp.z;
181 
182  // Identifier which uniquely identifies a certain player in a context (e.g. the ingame Name).
183  MyGUI::UString player_name(RoR::App::mp_player_name->getStr());
184  wcsncpy(lm->identity, player_name.asWStr_c_str(), 256);
185 
186  // Context should be equal for players which should be able to hear each other _positional_ and
187  // differ for those who shouldn't (e.g. it could contain the server+port and team)
188  // This ensures that Mumble users in the same channel playing on different servers
189  // don't hear each other positional since the positional information would be wrong
190 
191  // TODO: Right now we only create contexts based on server identification but
192  // some servers allow players to play on different maps independently
193  // so we should take that into account as well
194 
195  int teamID = 0; // RoR currently doesn't have any kind of team-based gameplay
196  int port = RoR::App::mp_server_port->getInt();
197  port = (port != 0) ? port : 1337;
198  sprintf((char *)lm->context, "%s:%d|%d", RoR::App::mp_server_host->getStr().c_str(), port, teamID);
199  lm->context_len = (int)strnlen((char *)lm->context, 256);
200 }
201 
202 #endif // USE_MUMBLE
GameContext.h
Game state manager and message-queue provider.
RoR::Character::getRotation
Ogre::Radian getRotation() const
Definition: Character.h:54
RoR::App::GetCameraManager
CameraManager * GetCameraManager()
Definition: Application.cpp:275
RoR::App::mp_player_name
CVar * mp_player_name
Definition: Application.cpp:124
RoR::GameContext::GetPlayerCharacter
Character * GetPlayerCharacter()
Definition: GameContext.cpp:873
CameraManager.h
RoR::CameraManager::GetCameraNode
Ogre::SceneNode * GetCameraNode()
Definition: CameraManager.h:63
RoR::App::mp_state
CVar * mp_state
Definition: Application.cpp:115
RoR::CVar::getStr
std::string const & getStr() const
Definition: CVar.h:95
strnlen
#define strnlen(str, len)
Definition: InputEngine.cpp:397
RoR::App::app_state
CVar * app_state
Definition: Application.cpp:79
RoR::Character
Definition: Character.h:40
Character.h
Application.h
Central state/object manager and communications hub.
RoR::App::GetGameContext
GameContext * GetGameContext()
Definition: Application.cpp:280
RoR::App::mp_server_port
CVar * mp_server_port
Definition: Application.cpp:122
RoR::App::mp_server_host
CVar * mp_server_host
Definition: Application.cpp:121
Ogre
Definition: ExtinguishableFireAffector.cpp:35
RoR::CVar::getInt
int getInt() const
Definition: CVar.h:97
RoR::App::GetMumble
MumbleIntegration * GetMumble()
Definition: Application.cpp:273
MumbleIntegration.h
RoR
Definition: AppContext.h:36