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
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
38using namespace Ogre;
39using namespace RoR;
40
41MumbleIntegration::MumbleIntegration() : lm(NULL)
42{
43 initMumble();
44}
45
46MumbleIntegration::~MumbleIntegration()
47{
48 if (lm != nullptr)
49 delete lm;
50}
51
52void 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
87void 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
101void 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
107 Character* avatar = App::GetGameContext()->GetPlayerCharacter();
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
121void 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
Central state/object manager and communications hub.
Game state manager and message-queue provider.
#define strnlen(str, len)
std::string const & getStr() const
Definition CVar.h:95
int getInt() const
Definition CVar.h:97
Ogre::Radian getRotation() const
Definition Character.h:53
CVar * mp_player_name
CVar * mp_server_port
CVar * mp_server_host