RigsofRods
Soft-body Physics Simulation
GfxScene.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 "GfxScene.h"
23 
24 #include "AppContext.h"
25 #include "Actor.h"
26 #include "ActorManager.h"
27 #include "Console.h"
28 #include "DustPool.h"
29 #include "HydraxWater.h"
30 #include "GameContext.h"
31 #include "GUIManager.h"
32 #include "GUIUtils.h"
33 #include "GUI_DirectionArrow.h"
34 #include "OverlayWrapper.h"
35 #include "SkyManager.h"
36 #include "SkyXManager.h"
37 #include "TerrainGeometryManager.h"
38 #include "Terrain.h"
39 #include "TerrainObjectManager.h"
40 #include "Utils.h"
41 
42 #include "imgui_internal.h"
43 
44 #include <Ogre.h>
45 
46 using namespace Ogre;
47 using namespace RoR;
48 
49 void GfxScene::CreateDustPools()
50 {
51  ROR_ASSERT(m_dustpools.size() == 0);
52  m_dustpools["dust"] = new DustPool(m_scene_manager, "tracks/Dust", 20);
53  m_dustpools["clump"] = new DustPool(m_scene_manager, "tracks/Clump", 20);
54  m_dustpools["sparks"] = new DustPool(m_scene_manager, "tracks/Sparks", 10);
55  m_dustpools["drip"] = new DustPool(m_scene_manager, "tracks/Drip", 50);
56  m_dustpools["splash"] = new DustPool(m_scene_manager, "tracks/Splash", 20);
57  m_dustpools["ripple"] = new DustPool(m_scene_manager, "tracks/Ripple", 20);
58 }
59 
60 void GfxScene::ClearScene()
61 {
62  // Delete dustpools
63  for (auto itor : m_dustpools)
64  {
65  itor.second->Discard(m_scene_manager);
66  delete itor.second;
67  }
68  m_dustpools.clear();
69 
70  // Delete game elements
71  m_all_gfx_actors.clear();
72  m_all_gfx_characters.clear();
73 
74  // Wipe scene manager
75  m_scene_manager->clearScene();
76 
77  // Recover from the wipe
80 }
81 
82 void GfxScene::Init()
83 {
84  ROR_ASSERT(!m_scene_manager);
85  m_scene_manager = App::GetAppContext()->GetOgreRoot()->createSceneManager(Ogre::ST_EXTERIOR_CLOSE, "main_scene_manager");
86 
87  m_skidmark_conf.LoadDefaultSkidmarkDefs();
88 }
89 
90 void GfxScene::UpdateScene(float dt_sec)
91 {
92  // Actors - start threaded tasks
93  for (GfxActor* gfx_actor: m_live_gfx_actors)
94  {
95  gfx_actor->UpdateFlexbodies(); // Push flexbody tasks to threadpool
96  gfx_actor->UpdateWheelVisuals(); // Push flexwheel tasks to threadpool
97  }
98 
99  // Var
100  GfxActor* player_gfx_actor = nullptr;
101  if (m_simbuf.simbuf_player_actor != nullptr)
102  {
103  player_gfx_actor = m_simbuf.simbuf_player_actor->GetGfxActor();
104  }
105 
106  // FOV
107  if (m_simbuf.simbuf_camera_behavior != CameraManager::CAMERA_BEHAVIOR_STATIC)
108  {
109  float fov = (m_simbuf.simbuf_camera_behavior == CameraManager::CAMERA_BEHAVIOR_VEHICLE_CINECAM)
111  RoR::App::GetCameraManager()->GetCamera()->setFOVy(Ogre::Degree(fov));
112  }
113 
114  // Particles
115  if (App::gfx_particles_mode->getInt() == 1)
116  {
117  for (GfxActor* gfx_actor: m_all_gfx_actors)
118  {
119  if (!m_simbuf.simbuf_sim_paused && !gfx_actor->GetSimDataBuffer().simbuf_physics_paused)
120  {
121  gfx_actor->UpdateParticles(m_simbuf.simbuf_sim_speed * dt_sec);
122  }
123  }
124  for (auto itor : m_dustpools)
125  {
126  itor.second->update();
127  }
128  }
129 
130  // Realtime reflections on player vehicle
131  // IMPORTANT: Toggles visibility of all meshes -> must be done before any other visibility control is evaluated (i.e. aero propellers)
132  if (player_gfx_actor != nullptr)
133  {
134  // Safe to be called here, only modifies OGRE objects, doesn't read any physics state.
135  m_envmap.UpdateEnvMap(player_gfx_actor->GetSimDataBuffer().simbuf_pos, player_gfx_actor);
136  }
137 
138  // Terrain - animated meshes and paged geometry
140 
141  // Terrain - lightmap; TODO: ported as-is from Terrain::update(), is it needed? ~ only_a_ptr, 05/2018
142  App::GetGameContext()->GetTerrain()->getGeometryManager()->UpdateMainLightPosition(); // TODO: Is this necessary? I'm leaving it here just in case ~ only_a_ptr, 04/2017
143 
144  // Terrain - water
146  if (water)
147  {
148  if (player_gfx_actor != nullptr)
149  {
150  water->SetReflectionPlaneHeight(water->CalcWavesHeight(player_gfx_actor->GetSimDataBuffer().simbuf_pos));
151  }
152  else
153  {
155  }
156  water->FrameStepWater(dt_sec);
157  }
158 
159  // Terrain - sky
160 #ifdef USE_CAELUM
161  SkyManager* sky = App::GetGameContext()->GetTerrain()->getSkyManager();
162  if (sky != nullptr)
163  {
164  sky->DetectSkyUpdate();
165  }
166 #endif
167 
169  if (skyx_man != nullptr)
170  {
171  skyx_man->update(dt_sec); // Light update
172  }
173 
174  // GUI - race
175  if (m_simbuf.simbuf_race_in_progress != m_simbuf.simbuf_race_in_progress_prev)
176  {
177  if (m_simbuf.simbuf_race_in_progress) // Started
178  {
180  }
181  else // Ended
182  {
184  }
185  }
186  if (m_simbuf.simbuf_race_in_progress)
187  {
189  }
190 
191  // GUI - vehicle pressure
192  if (m_simbuf.simbuf_player_actor)
193  {
194  App::GetOverlayWrapper()->UpdatePressureOverlay(m_simbuf.simbuf_player_actor->GetGfxActor());
195  }
196 
197  // HUD - network labels (always update)
198  for (GfxActor* gfx_actor: m_all_gfx_actors)
199  {
200  gfx_actor->UpdateNetLabels(m_simbuf.simbuf_sim_speed * dt_sec);
201  }
202 
203  // Player avatars
204  for (GfxCharacter* a: m_all_gfx_characters)
205  {
206  a->UpdateCharacterInScene();
207  }
208 
209  // Actors - update misc visuals
210  for (GfxActor* gfx_actor: m_all_gfx_actors)
211  {
212  if (gfx_actor->IsActorLive())
213  {
214  gfx_actor->UpdateRods();
215  gfx_actor->UpdateCabMesh();
216  gfx_actor->UpdateWingMeshes();
217  gfx_actor->UpdateAirbrakes();
218  gfx_actor->UpdateCParticles();
219  gfx_actor->UpdateAeroEngines();
220  gfx_actor->UpdatePropAnimations(dt_sec);
221  gfx_actor->UpdateRenderdashRTT();
222  }
223  // Beacon flares must always be updated
224  gfx_actor->UpdateProps(dt_sec, (gfx_actor == player_gfx_actor));
225  // Blinkers (turn signals) must always be updated
226  gfx_actor->UpdateFlares(dt_sec, (gfx_actor == player_gfx_actor));
227  }
228  if (player_gfx_actor != nullptr)
229  {
230  player_gfx_actor->UpdateVideoCameras(dt_sec);
231 
232  // The old-style render-to-texture dashboard (based on OGRE overlays)
233  if (m_simbuf.simbuf_player_actor->ar_driveable == TRUCK && m_simbuf.simbuf_player_actor->ar_engine != nullptr)
234  {
236  }
237  else if (m_simbuf.simbuf_player_actor->ar_driveable == AIRPLANE)
238  {
239  RoR::App::GetOverlayWrapper()->UpdateAerialHUD(player_gfx_actor);
240  }
241  }
242 
243  App::GetGuiManager()->DrawSimGuiBuffered(player_gfx_actor);
244 
246 
247  // Actors - finalize threaded tasks
248  for (GfxActor* gfx_actor: m_live_gfx_actors)
249  {
250  gfx_actor->FinishWheelUpdates();
251  gfx_actor->FinishFlexbodyTasks();
252  }
253 }
254 
255 void GfxScene::SetParticlesVisible(bool visible)
256 {
257  for (auto itor : m_dustpools)
258  {
259  itor.second->setVisible(visible);
260  }
261 }
262 
263 DustPool* GfxScene::GetDustPool(const char* name)
264 {
265  auto found = m_dustpools.find(name);
266  if (found != m_dustpools.end())
267  {
268  return found->second;
269  }
270  else
271  {
272  return nullptr;
273  }
274 }
275 
276 void GfxScene::RegisterGfxActor(RoR::GfxActor* gfx_actor)
277 {
278  m_all_gfx_actors.push_back(gfx_actor);
279 }
280 
281 void GfxScene::BufferSimulationData()
282 {
283  m_simbuf.simbuf_player_actor = App::GetGameContext()->GetPlayerActor();
284  m_simbuf.simbuf_character_pos = App::GetGameContext()->GetPlayerCharacter()->getPosition();
285  m_simbuf.simbuf_sim_paused = App::GetGameContext()->GetActorManager()->IsSimulationPaused();
286  m_simbuf.simbuf_sim_speed = App::GetGameContext()->GetActorManager()->GetSimulationSpeed();
287  m_simbuf.simbuf_camera_behavior = App::GetCameraManager()->GetCurrentBehavior();
288 
289  // Race system
290  m_simbuf.simbuf_race_time = App::GetGameContext()->GetRaceSystem().GetRaceTime();
291  m_simbuf.simbuf_race_best_time = App::GetGameContext()->GetRaceSystem().GetRaceBestTime();
292  m_simbuf.simbuf_race_time_diff = App::GetGameContext()->GetRaceSystem().GetRaceTimeDiff();
293  m_simbuf.simbuf_race_in_progress_prev = m_simbuf.simbuf_race_in_progress;
294  m_simbuf.simbuf_race_in_progress = App::GetGameContext()->GetRaceSystem().IsRaceInProgress();
295  m_simbuf.simbuf_dir_arrow_target = App::GetGameContext()->GetRaceSystem().GetDirArrowTarget();
296  m_simbuf.simbuf_dir_arrow_text = App::GetGameContext()->GetRaceSystem().GetDirArrowText();
297  m_simbuf.simbuf_dir_arrow_visible = App::GetGameContext()->GetRaceSystem().IsDirArrowVisible();
298 
299  m_live_gfx_actors.clear();
300  for (GfxActor* a: m_all_gfx_actors)
301  {
302  if (a->IsActorLive() || !a->IsActorInitialized())
303  {
304  a->UpdateSimDataBuffer();
305  m_live_gfx_actors.push_back(a);
306  a->InitializeActor();
307  }
308  }
309 
310  for (GfxCharacter* a: m_all_gfx_characters)
311  {
312  a->BufferSimulationData();
313  }
314 }
315 
316 void GfxScene::RemoveGfxActor(RoR::GfxActor* remove_me)
317 {
318  auto itor = std::remove(m_all_gfx_actors.begin(), m_all_gfx_actors.end(), remove_me);
319  if (itor != m_all_gfx_actors.end())
320  {
321  m_all_gfx_actors.erase(itor, m_all_gfx_actors.end());
322  }
323 }
324 
325 void GfxScene::RegisterGfxCharacter(RoR::GfxCharacter* gfx_character)
326 {
327  m_all_gfx_characters.push_back(gfx_character);
328 }
329 
330 void GfxScene::RemoveGfxCharacter(RoR::GfxCharacter* remove_me)
331 {
332  auto itor = std::remove(m_all_gfx_characters.begin(), m_all_gfx_characters.end(), remove_me);
333  if (itor != m_all_gfx_characters.end())
334  {
335  m_all_gfx_characters.erase(itor, m_all_gfx_characters.end());
336  }
337 }
338 
339 void GfxScene::DrawNetLabel(Ogre::Vector3 scene_pos, float cam_dist, std::string const& nick, int colornum)
340 {
341 #if USE_SOCKETW
342 
343  // this ensures that the nickname is always in a readable size
344  float font_size = std::max(0.6, cam_dist / 40.0);
345  std::string caption;
346  if (cam_dist > 1000) // 1000 ... vlen
347  {
348  caption =
349  nick + " (" + TOSTRING((float)(ceil(cam_dist / 100) / 10.0) ) + " km)";
350  }
351  else if (cam_dist > 20) // 20 ... vlen ... 1000
352  {
353  caption =
354  nick + " (" + TOSTRING((int)cam_dist) + " m)";
355  }
356  else // 0 ... vlen ... 20
357  {
358  caption = nick;
359  }
360 
361  // draw with DearIMGUI
362 
363  ImVec2 screen_size = ImGui::GetIO().DisplaySize;
364  World2ScreenConverter world2screen(
365  App::GetCameraManager()->GetCamera()->getViewMatrix(true), App::GetCameraManager()->GetCamera()->getProjectionMatrix(), Ogre::Vector2(screen_size.x, screen_size.y));
366 
367  Ogre::Vector3 pos_xyz = world2screen.Convert(scene_pos);
368 
369  // only draw when in front of camera
370  if (pos_xyz.z < 0.f)
371  {
372  // Align position to whole pixels, to minimize jitter.
373  ImVec2 pos((int)pos_xyz.x+0.5, (int)pos_xyz.y+0.5);
374 
375  ImVec2 text_size = ImGui::CalcTextSize(caption.c_str());
377 
378  ImDrawList* drawlist = GetImDummyFullscreenWindow();
379  ImGuiContext* g = ImGui::GetCurrentContext();
380 
381  ImVec2 text_pos(pos.x - ((text_size.x / 2)), pos.y - ((text_size.y / 2)));
382 
383  // Draw background rectangle
384  const float PADDING = 4.f;
385  drawlist->AddRectFilled(
386  text_pos - ImVec2(PADDING, PADDING),
387  text_pos + text_size + ImVec2(PADDING, PADDING),
388  ImColor(theme.semitransparent_window_bg),
389  ImGui::GetStyle().WindowRounding);
390 
391  // draw colored text
392  Ogre::ColourValue color = App::GetNetwork()->GetPlayerColor(colornum);
393  ImVec4 text_color(color.r, color.g, color.b, 1.f);
394  drawlist->AddText(g->Font, g->FontSize, text_pos, ImColor(text_color), caption.c_str());
395  }
396 
397 #endif // USE_SOCKETW
398 }
399 
ROR_ASSERT
#define ROR_ASSERT(_EXPR)
Definition: Application.h:40
GameContext.h
Game state manager and message-queue provider.
RoR::IWater::GetStaticWaterHeight
virtual float GetStaticWaterHeight()=0
Returns static water level configured in 'terrn2'.
RoR::App::GetNetwork
Network * GetNetwork()
Definition: Application.cpp:284
RoR::ActorManager::GetSimulationSpeed
float GetSimulationSpeed() const
Definition: ActorManager.h:93
RoR::IWater::CalcWavesHeight
virtual float CalcWavesHeight(Ogre::Vector3 pos)=0
SkyXManager.h
RoR::App::gfx_fov_internal
CVar * gfx_fov_internal
Definition: Application.cpp:240
OverlayWrapper.h
RoR::GUI::DirectionArrow::CreateArrow
void CreateArrow()
Must be called again after OGRE scenemanager is cleared.
Definition: GUI_DirectionArrow.cpp:50
RoR::TRUCK
@ TRUCK
its a truck (or other land vehicle)
Definition: SimData.h:93
RoR::DustPool
Definition: DustPool.h:33
RoR::GUIManager::GuiTheme
Definition: GUIManager.h:68
RoR::App::GetCameraManager
CameraManager * GetCameraManager()
Definition: Application.cpp:275
RoR::App::GetGuiManager
GUIManager * GetGuiManager()
Definition: Application.cpp:269
RoR::IWater::FrameStepWater
virtual void FrameStepWater(float dt)=0
SkyManager.h
RoR::App::GetAppContext
AppContext * GetAppContext()
Definition: Application.cpp:266
GUIUtils.h
RoR::Terrain::getObjectManager
TerrainObjectManager * getObjectManager()
Definition: Terrain.h:77
RoR::Terrain::getSkyManager
SkyManager * getSkyManager()
Definition: Terrain.cpp:513
RoR::RaceSystem::GetDirArrowText
std::string const & GetDirArrowText() const
Definition: RaceSystem.h:48
TerrainGeometryManager.h
RoR::GameContext::GetPlayerCharacter
Character * GetPlayerCharacter()
Definition: GameContext.cpp:872
RoR::App::gfx_particles_mode
CVar * gfx_particles_mode
Definition: Application.cpp:227
RoR::IWater
< TODO: Mixed gfx+physics (waves) - must be separated ~ only_a_ptr, 02/2018
Definition: IWater.h:32
RoR::App::GetOverlayWrapper
OverlayWrapper * GetOverlayWrapper()
Definition: Application.cpp:268
RoR::OverlayWrapper::UpdateAerialHUD
void UpdateAerialHUD(RoR::GfxActor *ga)
Definition: OverlayWrapper.cpp:741
RoR::OverlayWrapper::UpdateRacingGui
void UpdateRacingGui(RoR::GfxScene *gs)
Definition: OverlayWrapper.cpp:965
AppContext.h
System integration layer; inspired by OgreBites::ApplicationContext.
Console.h
GUI_DirectionArrow.h
Race direction arrow and text info (using OGRE Overlay)
RoR::RaceSystem::IsDirArrowVisible
bool IsDirArrowVisible() const
Definition: RaceSystem.h:49
Utils.h
RoR::RaceSystem::GetRaceTime
float GetRaceTime() const
Definition: RaceSystem.cpp:59
RoR::GUIManager::GuiTheme::semitransparent_window_bg
ImVec4 semitransparent_window_bg
Definition: GUIManager.h:81
TerrainObjectManager.h
RoR::World2ScreenConverter::Convert
Ogre::Vector3 Convert(Ogre::Vector3 world_pos)
Definition: Utils.h:89
RoR::GUIManager::DirectionArrow
GUI::DirectionArrow DirectionArrow
Definition: GUIManager.h:123
GUIManager.h
ActorManager.h
Actor.h
RoR::GameContext::GetRaceSystem
RaceSystem & GetRaceSystem()
Definition: GameContext.h:168
RoR::RaceSystem::GetRaceTimeDiff
float GetRaceTimeDiff() const
Definition: RaceSystem.h:41
RoR::OverlayWrapper::UpdatePressureOverlay
void UpdatePressureOverlay(RoR::GfxActor *ga)
Definition: OverlayWrapper.cpp:646
RoR::GetImDummyFullscreenWindow
ImDrawList * GetImDummyFullscreenWindow(const std::string &name="RoR_TransparentFullscreenWindow")
Definition: GUIUtils.cpp:356
RoR::OverlayWrapper::UpdateLandVehicleHUD
void UpdateLandVehicleHUD(RoR::GfxActor *ga)
Definition: OverlayWrapper.cpp:661
RoR::CameraManager::GetCurrentBehavior
CameraBehaviors GetCurrentBehavior() const
Definition: CameraManager.h:62
RoR::GUIManager::GetTheme
GuiTheme & GetTheme()
Definition: GUIManager.h:154
TOSTRING
#define TOSTRING(x)
Definition: Application.h:56
RoR::CameraManager::GetCamera
Ogre::Camera * GetCamera()
Definition: CameraManager.h:64
RoR::GameContext::GetSceneMouse
SceneMouse & GetSceneMouse()
Definition: GameContext.h:170
RoR::CameraManager::ReCreateCameraNode
void ReCreateCameraNode()
Needed since we call Ogre::SceneManager::ClearScene() after end of sim. session.
Definition: CameraManager.cpp:142
RoR::World2ScreenConverter
< Keeps data close for faster access.
Definition: Utils.h:81
RoR::GfxCharacter
Definition: Character.h:99
RoR::Terrain::getGeometryManager
TerrainGeometryManager * getGeometryManager()
Definition: Terrain.h:75
RoR::GfxActor::UpdateVideoCameras
void UpdateVideoCameras(float dt_sec)
Definition: GfxActor.cpp:422
RoR::TerrainGeometryManager::UpdateMainLightPosition
void UpdateMainLightPosition()
Definition: TerrainGeometryManager.cpp:406
RoR::IWater::SetReflectionPlaneHeight
virtual void SetReflectionPlaneHeight(float centerheight)
Definition: IWater.h:53
RoR::SceneMouse::UpdateVisuals
void UpdateVisuals()
Definition: SceneMouse.cpp:212
GfxScene.h
RoR::App::GetGameContext
GameContext * GetGameContext()
Definition: Application.cpp:280
RoR::Character::getPosition
Ogre::Vector3 getPosition()
Definition: Character.cpp:92
RoR::AIRPLANE
@ AIRPLANE
its an airplane
Definition: SimData.h:94
RoR::RaceSystem::GetDirArrowTarget
Ogre::Vector3 GetDirArrowTarget()
Definition: RaceSystem.h:47
RoR::ActorSB::simbuf_pos
Ogre::Vector3 simbuf_pos
Definition: SimBuffers.h:123
RoR::GUIManager::DrawSimGuiBuffered
void DrawSimGuiBuffered(GfxActor *player_gfx_actor)
Reads data from simbuffer.
Definition: GUIManager.cpp:162
RoR::RaceSystem::GetRaceBestTime
float GetRaceBestTime() const
Definition: RaceSystem.h:44
DustPool.h
RoR::Network::GetPlayerColor
Ogre::ColourValue GetPlayerColor(int color_num)
Definition: Network.cpp:94
RoR::SkyXManager::update
bool update(float dt)
Definition: SkyXManager.cpp:77
RoR::TerrainObjectManager::UpdateTerrainObjects
bool UpdateTerrainObjects(float dt)
Definition: TerrainObjectManager.cpp:1003
RoR::Terrain::getSkyXManager
SkyXManager * getSkyXManager()
Definition: Terrain.h:80
RoR::App::gfx_fov_external
CVar * gfx_fov_external
Definition: Application.cpp:238
RoR::AppContext::GetOgreRoot
Ogre::Root * GetOgreRoot()
Definition: AppContext.h:65
Terrain.h
RoR::GfxActor
Definition: GfxActor.h:52
RoR::CVar::getFloat
float getFloat() const
Definition: CVar.h:96
Ogre
Definition: ExtinguishableFireAffector.cpp:35
RoR::OverlayWrapper::HideRacingOverlay
void HideRacingOverlay()
Definition: OverlayWrapper.cpp:959
RoR::RaceSystem::IsRaceInProgress
bool IsRaceInProgress() const
Definition: RaceSystem.h:36
RoR::ActorManager::IsSimulationPaused
bool IsSimulationPaused() const
Definition: ActorManager.h:94
RoR::GameContext::GetPlayerActor
const ActorPtr & GetPlayerActor()
Definition: GameContext.h:134
RoR::OverlayWrapper::ShowRacingOverlay
void ShowRacingOverlay()
Definition: OverlayWrapper.cpp:953
RoR::GfxActor::GetSimDataBuffer
ActorSB & GetSimDataBuffer()
Definition: GfxActor.h:119
RoR
Definition: AppContext.h:36
RoR::GameContext::GetActorManager
ActorManager * GetActorManager()
Definition: GameContext.h:127
RoR::Terrain::getWater
IWater * getWater()
Definition: Terrain.h:84
HydraxWater.h
RoR::SkyXManager
Definition: SkyXManager.h:32
RoR::GameContext::GetTerrain
const TerrainPtr & GetTerrain()
Definition: GameContext.h:117