43 #include "imgui_internal.h"
50 void GfxScene::CreateDustPools()
53 m_dustpools[
"dust"] =
new DustPool(m_scene_manager,
"tracks/Dust", 20);
54 m_dustpools[
"clump"] =
new DustPool(m_scene_manager,
"tracks/Clump", 20);
55 m_dustpools[
"sparks"] =
new DustPool(m_scene_manager,
"tracks/Sparks", 10);
56 m_dustpools[
"drip"] =
new DustPool(m_scene_manager,
"tracks/Drip", 50);
57 m_dustpools[
"splash"] =
new DustPool(m_scene_manager,
"tracks/Splash", 20);
58 m_dustpools[
"ripple"] =
new DustPool(m_scene_manager,
"tracks/Ripple", 20);
61 void GfxScene::ClearScene()
64 for (
auto itor : m_dustpools)
66 itor.second->Discard(m_scene_manager);
72 m_all_gfx_actors.clear();
73 m_all_gfx_characters.clear();
76 m_scene_manager->clearScene();
77 m_gfx_freebeams_grouping_node =
nullptr;
82 m_gfx_freebeams_grouping_node = m_scene_manager->getRootSceneNode()->createChildSceneNode(
"FreeBeam Visuals");
89 m_gfx_freebeams_grouping_node = m_scene_manager->getRootSceneNode()->createChildSceneNode(
"FreeBeam Visuals");
91 m_skidmark_conf.LoadDefaultSkidmarkDefs();
94 void GfxScene::UpdateScene(
float dt)
100 for (
GfxActor* gfx_actor: m_live_gfx_actors)
102 gfx_actor->UpdateFlexbodies();
103 gfx_actor->UpdateWheelVisuals();
107 GfxActor* player_gfx_actor =
nullptr;
108 if (m_simbuf.simbuf_player_actor !=
nullptr)
110 player_gfx_actor = m_simbuf.simbuf_player_actor->GetGfxActor();
114 if (m_simbuf.simbuf_camera_behavior != CameraManager::CAMERA_BEHAVIOR_STATIC)
116 float fov = (m_simbuf.simbuf_camera_behavior == CameraManager::CAMERA_BEHAVIOR_VEHICLE_CINECAM)
125 for (
GfxActor* gfx_actor: m_all_gfx_actors)
127 float dt_actor = (!gfx_actor->GetSimDataBuffer().simbuf_physics_paused) ? dt : 0.f;
128 gfx_actor->UpdateParticles(dt_actor);
132 for (
auto itor : m_dustpools)
134 itor.second->update();
140 if (player_gfx_actor !=
nullptr)
156 if (player_gfx_actor !=
nullptr)
172 sky->DetectSkyUpdate();
177 if (skyx_man !=
nullptr)
183 if (m_simbuf.simbuf_race_in_progress != m_simbuf.simbuf_race_in_progress_prev)
185 if (m_simbuf.simbuf_race_in_progress)
194 if (m_simbuf.simbuf_race_in_progress)
200 if (m_simbuf.simbuf_player_actor)
206 for (
GfxActor* gfx_actor: m_all_gfx_actors)
208 gfx_actor->UpdateNetLabels(dt);
214 a->UpdateCharacterInScene();
218 for (
GfxActor* gfx_actor: m_all_gfx_actors)
220 float dt_actor = (!gfx_actor->GetSimDataBuffer().simbuf_physics_paused) ? dt : 0.f;
221 if (gfx_actor->IsActorLive())
223 gfx_actor->UpdateRods();
224 gfx_actor->UpdateCabMesh();
225 gfx_actor->UpdateWingMeshes();
226 gfx_actor->UpdateAirbrakes();
227 gfx_actor->UpdateCParticles();
228 gfx_actor->UpdateExhausts();
229 gfx_actor->UpdateAeroEngines();
230 gfx_actor->UpdatePropAnimations(dt_actor);
231 gfx_actor->UpdateRenderdashRTT();
234 gfx_actor->UpdateProps(dt_actor, (gfx_actor == player_gfx_actor));
236 gfx_actor->UpdateFlares(dt_actor, (gfx_actor == player_gfx_actor));
238 if (player_gfx_actor !=
nullptr)
244 if (m_simbuf.simbuf_player_actor->ar_driveable ==
TRUCK && m_simbuf.simbuf_player_actor->ar_engine !=
nullptr)
248 else if (m_simbuf.simbuf_player_actor->ar_driveable ==
AIRPLANE)
258 this->UpdateFreeBeamGfx(dt);
261 for (
GfxActor* gfx_actor: m_live_gfx_actors)
263 gfx_actor->FinishWheelUpdates();
264 gfx_actor->FinishFlexbodyTasks();
268 void GfxScene::SetParticlesVisible(
bool visible)
270 for (
auto itor : m_dustpools)
272 itor.second->setVisible(visible);
278 auto found = m_dustpools.find(name);
279 if (found != m_dustpools.end())
281 return found->second;
291 m_all_gfx_actors.push_back(gfx_actor);
294 void GfxScene::BufferSimulationData()
306 m_simbuf.simbuf_race_in_progress_prev = m_simbuf.simbuf_race_in_progress;
312 m_live_gfx_actors.clear();
315 if (a->IsActorLive() || !a->IsActorInitialized())
317 a->UpdateSimDataBuffer();
318 m_live_gfx_actors.push_back(a);
319 a->InitializeActor();
325 a->BufferSimulationData();
331 auto itor = std::remove(m_all_gfx_actors.begin(), m_all_gfx_actors.end(), remove_me);
332 if (itor != m_all_gfx_actors.end())
334 m_all_gfx_actors.erase(itor, m_all_gfx_actors.end());
361 m_all_gfx_characters.push_back(gfx_character);
366 auto itor = std::remove(m_all_gfx_characters.begin(), m_all_gfx_characters.end(), remove_me);
367 if (itor != m_all_gfx_characters.end())
369 m_all_gfx_characters.erase(itor, m_all_gfx_characters.end());
373 void GfxScene::DrawNetLabel(Ogre::Vector3 scene_pos,
float cam_dist, std::string
const& nick,
int colornum)
378 float font_size = std::max(0.6, cam_dist / 40.0);
383 nick +
" (" +
TOSTRING((
float)(ceil(cam_dist / 100) / 10.0) ) +
" km)";
385 else if (cam_dist > 20)
388 nick +
" (" +
TOSTRING((
int)cam_dist) +
" m)";
397 ImVec2 screen_size = ImGui::GetIO().DisplaySize;
401 Ogre::Vector3 pos_xyz = world2screen.
Convert(scene_pos);
407 ImVec2 pos((
int)pos_xyz.x+0.5, (
int)pos_xyz.y+0.5);
409 ImVec2 text_size = ImGui::CalcTextSize(caption.c_str());
413 ImGuiContext* g = ImGui::GetCurrentContext();
415 ImVec2 text_pos(pos.x - ((text_size.x / 2)), pos.y - ((text_size.y / 2)));
418 const float PADDING = 4.f;
419 drawlist->AddRectFilled(
420 text_pos - ImVec2(PADDING, PADDING),
421 text_pos + text_size + ImVec2(PADDING, PADDING),
423 ImGui::GetStyle().WindowRounding);
427 ImVec4 text_color(color.r, color.g, color.b, 1.f);
428 drawlist->AddText(g->Font, g->FontSize, text_pos, ImColor(text_color), caption.c_str());
431 #endif // USE_SOCKETW
434 void GfxScene::AdjustParticleSystemTimeFactor(Ogre::ParticleSystem* psys)
436 float speed_factor = 0.f;
439 speed_factor = m_simbuf.simbuf_sim_speed;
442 psys->setSpeedFactor(speed_factor);
447 auto itor = std::find_if(m_gfx_freebeams.begin(), m_gfx_freebeams.end(),
448 [rq](
const FreeBeamGfx& obj) { return obj.fbx_id == rq->fbr_id; });
449 if (itor != m_gfx_freebeams.end())
452 fmt::format(
"FreeBeamGfx with ID %d already exists, ignoring request.",rq->
fbr_id));
469 m_gfx_freebeams.push_back(obj);
474 auto itor = std::find_if(m_gfx_freebeams.begin(), m_gfx_freebeams.end(),
475 [rq](
const FreeBeamGfx& obj) { return obj.fbx_id == rq->fbr_id; });
476 if (itor == m_gfx_freebeams.end())
484 this->RemoveFreeBeamGfx(rq->
fbr_id);
485 this->AddFreeBeamGfx(rq);
490 auto itor = std::find_if(m_gfx_freebeams.begin(), m_gfx_freebeams.end(),
491 [
id](
const FreeBeamGfx& obj) { return obj.fbx_id == id; });
492 if (itor == m_gfx_freebeams.end())
495 fmt::format(
"FreeBeamGfx with ID %d not found, ignoring request.",
id));
500 m_scene_manager->destroyEntity((Ogre::Entity*)obj.
fbx_scenenode->getAttachedObject(0));
501 m_gfx_freebeams_grouping_node->removeChild(obj.
fbx_scenenode);
502 m_gfx_freebeams.erase(itor);
505 void GfxScene::UpdateFreeBeamGfx(
float dt)
512 ActorManager::FreeForceVec_t::iterator itor;
542 freebeam.fbx_scenenode->setPosition(basenode_pos.midPoint(targetnode_pos));
543 freebeam.fbx_scenenode->setOrientation(GfxScene::SpecialGetRotationTo(Ogre::Vector3::UNIT_Y, (basenode_pos - targetnode_pos)));
544 freebeam.fbx_scenenode->setScale(freebeam.fbx_diameter, basenode_pos.distance(targetnode_pos), freebeam.fbx_diameter);
550 auto itor_secondary = std::find_if(m_gfx_freebeams.begin(), m_gfx_freebeams.end(),
551 [
id](
const FreeBeamGfx& obj) { return obj.fbx_freeforce_secondary == id; });
552 if (itor_secondary != m_gfx_freebeams.end())
559 auto itor_primary = std::find_if(m_gfx_freebeams.begin(), m_gfx_freebeams.end(),
560 [
id](
const FreeBeamGfx& obj) { return obj.fbx_freeforce_primary == id; });
561 if (itor_primary != m_gfx_freebeams.end())
564 this->RemoveFreeBeamGfx(itor_primary->fbx_id);
571 auto itor = std::find_if(m_gfx_freebeams.begin(), m_gfx_freebeams.end(),
572 [
id](
const FreeBeamGfx& obj) { return obj.fbx_freeforce_primary == id || obj.fbx_freeforce_secondary == id; });
573 if (itor != m_gfx_freebeams.end())
576 this->RemoveFreeBeamGfx(itor->fbx_id);
585 Ogre::Vector3 v0 = src;
586 Ogre::Vector3 v1 = dest;
592 Ogre::Real d = v0.dotProduct(v1);
596 return Ogre::Quaternion::IDENTITY;
598 if (d < (1e-6f - 1.0f))
601 Ogre::Vector3 axis = Ogre::Vector3::UNIT_X.crossProduct(src);
602 if (axis.isZeroLength())
603 axis = Ogre::Vector3::UNIT_Y.crossProduct(src);
605 q.FromAngleAxis(Ogre::Radian(Ogre::Math::PI), axis);
611 return Ogre::Quaternion::IDENTITY;
613 Ogre::Vector3 c = v0.crossProduct(v1);
614 Ogre::Real invs = 1 / s;