mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-21 21:49:19 +02:00
EU7 scenery format and models streaming
This commit is contained in:
@@ -12,6 +12,9 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "application/drivermode.h"
|
||||
#include "application/editormode.h"
|
||||
#include "application/scenarioloadermode.h"
|
||||
#include "application/scenarioloaderuilayer.h"
|
||||
#include "scene/eu7/eu7_load_stats.h"
|
||||
#include "scene/eu7/eu7_section_stream.h"
|
||||
#include "launcher/launchermode.h"
|
||||
|
||||
#include "utilities/Globals.h"
|
||||
@@ -707,9 +710,59 @@ void eu07_application::exit()
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
eu07_application::extend_loading_overlay( std::chrono::milliseconds const duration ) {
|
||||
if( duration.count() <= 0 ) {
|
||||
return;
|
||||
}
|
||||
auto const until { std::chrono::steady_clock::now() + duration };
|
||||
if( until > m_loading_overlay_until ) {
|
||||
m_loading_overlay_until = until;
|
||||
}
|
||||
if( m_loading_overlay == nullptr ) {
|
||||
m_loading_overlay = std::make_shared<scenarioloader_ui>();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
eu07_application::loading_overlay_active() const {
|
||||
if( m_modestack.empty() || m_modestack.top() != mode::driver ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if( false == simulation::is_ready ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
eu07_application::sync_loading_overlay_state() {
|
||||
if( m_loading_overlay == nullptr ) {
|
||||
m_loading_overlay = std::make_shared<scenarioloader_ui>();
|
||||
}
|
||||
|
||||
m_loading_overlay->set_progress( 100.f, 0.f );
|
||||
}
|
||||
|
||||
void
|
||||
eu07_application::render_loading_overlay() {
|
||||
sync_loading_overlay_state();
|
||||
if( m_loading_overlay == nullptr ) {
|
||||
m_loading_overlay = std::make_shared<scenarioloader_ui>();
|
||||
}
|
||||
m_loading_overlay->render();
|
||||
}
|
||||
|
||||
void eu07_application::render_ui()
|
||||
{
|
||||
|
||||
if( loading_overlay_active() ) {
|
||||
render_loading_overlay();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_modestack.empty())
|
||||
{
|
||||
return;
|
||||
@@ -721,6 +774,12 @@ void eu07_application::render_ui()
|
||||
void eu07_application::begin_ui_frame()
|
||||
{
|
||||
|
||||
if( loading_overlay_active() ) {
|
||||
sync_loading_overlay_state();
|
||||
m_loading_overlay->begin_ui_frame();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_modestack.empty())
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -9,6 +9,8 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "application/applicationmode.h"
|
||||
#include "scripting/PyInt.h"
|
||||
#include "network/manager.h"
|
||||
@@ -55,6 +57,12 @@ public:
|
||||
render_ui();
|
||||
void
|
||||
begin_ui_frame();
|
||||
void
|
||||
extend_loading_overlay( std::chrono::milliseconds const Duration );
|
||||
[[nodiscard]] bool
|
||||
loading_overlay_active() const;
|
||||
void
|
||||
render_loading_overlay();
|
||||
// switches application to specified mode
|
||||
bool
|
||||
pop_mode();
|
||||
@@ -115,9 +123,12 @@ private:
|
||||
int init_modes();
|
||||
bool init_network();
|
||||
int run_crashgui();
|
||||
void sync_loading_overlay_state();
|
||||
// members
|
||||
|
||||
bool m_screenshot_queued = false;
|
||||
std::chrono::steady_clock::time_point m_loading_overlay_until {};
|
||||
std::shared_ptr<class scenarioloader_ui> m_loading_overlay;
|
||||
|
||||
modeptr_array m_modes { nullptr }; // collection of available application behaviour modes
|
||||
mode_stack m_modestack; // current behaviour mode
|
||||
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
void begin_ui_frame() {
|
||||
if( m_userinterface != nullptr ) {
|
||||
m_userinterface->begin_ui_frame(); } }
|
||||
inline
|
||||
virtual
|
||||
void set_progress( float const Progress = 0.f, float const Subtaskprogress = 0.f ) {
|
||||
if( m_userinterface != nullptr ) {
|
||||
m_userinterface->set_progress( Progress, Subtaskprogress ); } }
|
||||
|
||||
@@ -29,6 +29,8 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "utilities/Timer.h"
|
||||
#include "rendering/renderer.h"
|
||||
#include "utilities/Logs.h"
|
||||
#include "scene/eu7/eu7_section_stream.h"
|
||||
#include "scene/eu7/eu7_pack_bench.h"
|
||||
/*
|
||||
namespace input {
|
||||
|
||||
@@ -402,6 +404,36 @@ bool driver_mode::update()
|
||||
|
||||
Timer::subsystem.sim_total.stop();
|
||||
|
||||
auto const world_presentable {
|
||||
false == scene::eu7::section_stream_active()
|
||||
|| scene::eu7::loading_screen_dismissed() };
|
||||
auto const gameplay_stream {
|
||||
scene::eu7::section_stream_active() && scene::eu7::loading_screen_dismissed() };
|
||||
|
||||
simulation::State.drain_deferred_eu7_trainsets( gameplay_stream ? 3.0 : 12.0 );
|
||||
|
||||
if( scene::eu7::section_stream_active() ) {
|
||||
auto const stream_active {
|
||||
simulation::is_ready || Application.loading_overlay_active() };
|
||||
if( stream_active && scene::eu7::section_stream_needs_bootstrap() ) {
|
||||
scene::eu7::kick_section_stream_bootstrap();
|
||||
}
|
||||
if( stream_active ) {
|
||||
scene::eu7::update_section_stream( Global.pCamera.Pos );
|
||||
scene::eu7::drain_section_stream();
|
||||
}
|
||||
|
||||
if( scene::eu7::pack_bench_stream_phase_active() ) {
|
||||
static double s_last_stream_bench_log { 0.0 };
|
||||
auto const now { Timer::GetTime() };
|
||||
if( now - s_last_stream_bench_log >= 30.0
|
||||
&& scene::eu7::pack_bench_stream().sections_finalized > 0 ) {
|
||||
scene::eu7::log_pack_stream_bench();
|
||||
s_last_stream_bench_log = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulation::Region->update_sounds();
|
||||
audio::renderer.update(Global.iPause ? 0.0 : deltarealtime);
|
||||
|
||||
@@ -410,7 +442,9 @@ bool driver_mode::update()
|
||||
|
||||
GfxRenderer->Update(deltarealtime);
|
||||
|
||||
simulation::is_ready = simulation::is_ready || ((simulation::Train != nullptr) && (simulation::Train->is_cab_initialized)) || (Global.local_start_vehicle == "ghostview");
|
||||
simulation::is_ready = simulation::is_ready
|
||||
|| ( ( simulation::Train != nullptr ) && ( simulation::Train->is_cab_initialized ) )
|
||||
|| ( Global.local_start_vehicle == "ghostview" && world_presentable );
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -461,7 +495,10 @@ void driver_mode::enter()
|
||||
}
|
||||
|
||||
// maintenance method, called when the mode is deactivated
|
||||
void driver_mode::exit() {}
|
||||
void
|
||||
driver_mode::exit() {
|
||||
scene::eu7::flush_pack_stream_bench();
|
||||
}
|
||||
|
||||
void driver_mode::on_key(int const Key, int const Scancode, int const Action, int const Mods)
|
||||
{
|
||||
|
||||
@@ -19,6 +19,15 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "rendering/renderer.h"
|
||||
#include "utilities/Logs.h"
|
||||
#include "utilities/translation.h"
|
||||
#include "scene/eu7/eu7_load_stats.h"
|
||||
#include "scene/eu7/eu7_pack_bench.h"
|
||||
#include "scene/eu7/eu7_section_stream.h"
|
||||
|
||||
namespace {
|
||||
constexpr std::chrono::seconds kEu7LoadTimeout { 90 };
|
||||
constexpr float kDeserializeBarShare { 70.f };
|
||||
constexpr float kPackBarShare { 30.f };
|
||||
} // namespace
|
||||
|
||||
scenarioloader_mode::scenarioloader_mode() {
|
||||
m_userinterface = std::make_shared<scenarioloader_ui>();
|
||||
@@ -30,6 +39,13 @@ bool scenarioloader_mode::init() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void scenarioloader_mode::update_bar_progress( float const progress ) {
|
||||
m_bar_progress = std::max( m_bar_progress, std::clamp( progress, 0.f, 100.f ) );
|
||||
if( m_userinterface != nullptr ) {
|
||||
m_userinterface->set_progress( m_bar_progress, 0.f );
|
||||
}
|
||||
}
|
||||
|
||||
// mode-specific update of simulation data. returns: false on error, true otherwise
|
||||
bool scenarioloader_mode::update() {
|
||||
if (!Global.ready_to_load)
|
||||
@@ -48,17 +64,80 @@ bool scenarioloader_mode::update() {
|
||||
}
|
||||
|
||||
try {
|
||||
if (simulation::State.deserialize_continue(state))
|
||||
return true;
|
||||
if( m_phase == load_phase::deserialize ) {
|
||||
if( simulation::State.deserialize_continue( state ) ) {
|
||||
return true;
|
||||
}
|
||||
m_phase = load_phase::eu7_load;
|
||||
m_eu7_load_started = std::chrono::steady_clock::now();
|
||||
m_eu7_stream_primed = false;
|
||||
}
|
||||
}
|
||||
catch (invalid_scenery_exception &e) {
|
||||
ErrorLog( "Bad init: scenario loading failed" );
|
||||
Application.pop_mode();
|
||||
return true;
|
||||
}
|
||||
|
||||
if( m_phase == load_phase::eu7_load ) {
|
||||
if( scene::eu7::section_stream_active() ) {
|
||||
simulation::State.drain_deferred_eu7_trainsets( 16.0 );
|
||||
|
||||
auto const position { scene::eu7::stream_loading_position() };
|
||||
|
||||
if( false == m_eu7_stream_primed ) {
|
||||
if( scene::eu7::section_stream_needs_bootstrap() ) {
|
||||
scene::eu7::kick_section_stream_bootstrap();
|
||||
}
|
||||
m_eu7_stream_primed = true;
|
||||
}
|
||||
|
||||
scene::eu7::drain_section_stream();
|
||||
|
||||
auto const ring_progress {
|
||||
scene::eu7::section_stream_ring_progress(
|
||||
position,
|
||||
scene::eu7::kSectionStreamBootstrapRadiusKm ) };
|
||||
update_bar_progress(
|
||||
kDeserializeBarShare + ring_progress * kPackBarShare );
|
||||
|
||||
auto const timed_out {
|
||||
std::chrono::steady_clock::now() - m_eu7_load_started >= kEu7LoadTimeout };
|
||||
auto const bootstrap_ready {
|
||||
scene::eu7::section_stream_ready_around(
|
||||
position,
|
||||
scene::eu7::kSectionStreamBootstrapRadiusKm ) };
|
||||
if(
|
||||
bootstrap_ready
|
||||
|| scene::eu7::section_stream_presentable_around(
|
||||
position,
|
||||
scene::eu7::kSectionStreamBootstrapRadiusKm ) ) {
|
||||
WriteLog( "EU7 PACK: pierścień wokół pozycji startowej gotowy do pokazania" );
|
||||
scene::eu7::dismiss_loading_screen();
|
||||
m_phase = load_phase::finished;
|
||||
}
|
||||
else if( timed_out ) {
|
||||
ErrorLog(
|
||||
"EU7 PACK: timeout ładowania pierścienia wokół kamery — wchodzę w jazdę (ring=" +
|
||||
std::to_string( static_cast<int>( ring_progress * 100.f ) ) + "%)" );
|
||||
scene::eu7::dismiss_loading_screen();
|
||||
m_phase = load_phase::finished;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
scene::eu7::dismiss_loading_screen();
|
||||
m_phase = load_phase::finished;
|
||||
}
|
||||
}
|
||||
|
||||
WriteLog( "Scenario loading time: " + std::to_string( std::chrono::duration_cast<std::chrono::seconds>( ( std::chrono::system_clock::now() - timestart ) ).count() ) + " seconds" );
|
||||
// TODO: implement and use next mode cue
|
||||
scene::eu7::log_load_stats();
|
||||
scene::eu7::log_pack_bench();
|
||||
|
||||
update_bar_progress( 100.f );
|
||||
Application.pop_mode();
|
||||
Application.push_mode( eu07_application::mode::driver );
|
||||
|
||||
@@ -74,6 +153,9 @@ void scenarioloader_mode::enter() {
|
||||
// TBD: hide cursor in fullscreen mode?
|
||||
Application.set_cursor( GLFW_CURSOR_NORMAL );
|
||||
|
||||
m_phase = load_phase::deserialize;
|
||||
m_eu7_stream_primed = false;
|
||||
m_bar_progress = 0.f;
|
||||
simulation::is_ready = false;
|
||||
|
||||
Application.set_title( Global.AppName + " (" + Global.SceneryFile + ")" );
|
||||
@@ -85,3 +167,15 @@ void scenarioloader_mode::exit() {
|
||||
simulation::Time.init( Global.starting_timestamp );
|
||||
simulation::Environment.init();
|
||||
}
|
||||
|
||||
void scenarioloader_mode::set_progress(
|
||||
float const Progress,
|
||||
float const Subtaskprogress ) {
|
||||
if( m_phase != load_phase::deserialize ) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto const parser_progress {
|
||||
std::max( Progress, Subtaskprogress ) };
|
||||
update_bar_progress( parser_progress * kDeserializeBarShare / 100.f );
|
||||
}
|
||||
|
||||
@@ -13,8 +13,21 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "simulation/simulation.h"
|
||||
|
||||
class scenarioloader_mode : public application_mode {
|
||||
|
||||
enum class load_phase {
|
||||
deserialize,
|
||||
eu7_load,
|
||||
finished
|
||||
};
|
||||
|
||||
std::shared_ptr<simulation::deserializer_state> state;
|
||||
std::chrono::system_clock::time_point timestart;
|
||||
load_phase m_phase { load_phase::deserialize };
|
||||
std::chrono::steady_clock::time_point m_eu7_load_started {};
|
||||
bool m_eu7_stream_primed { false };
|
||||
float m_bar_progress { 0.f };
|
||||
|
||||
void update_bar_progress( float progress );
|
||||
|
||||
public:
|
||||
// constructors
|
||||
@@ -28,6 +41,7 @@ public:
|
||||
void enter() override;
|
||||
// maintenance method, called when the mode is deactivated
|
||||
void exit() override;
|
||||
void set_progress( float Progress = 0.f, float Subtaskprogress = 0.f ) override;
|
||||
// input handlers
|
||||
void on_key( int const Key, int const Scancode, int const Action, int const Mods ) override { ; }
|
||||
void on_cursor_pos( double const Horizontal, double const Vertical ) override { ; }
|
||||
|
||||
@@ -195,6 +195,10 @@ void scenarioloader_ui::render_()
|
||||
ImGui::SetNextWindowSize(ImVec2(Global.window_size.x + padding * 2, Global.window_size.y + padding * 2));
|
||||
ImGui::Begin("Neo Loading Screen", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoBackground);
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
draw_list->AddRectFilled(
|
||||
ImVec2( 0.f, 0.f ),
|
||||
ImVec2( screen_size.x, screen_size.y ),
|
||||
IM_COL32( 0, 0, 0, 255 ) );
|
||||
ImGui::PushFont(font_loading);
|
||||
ImGui::SetWindowFontScale(1);
|
||||
const float font_scale_mult = 48 / ImGui::GetFontSize();
|
||||
@@ -228,7 +232,14 @@ void scenarioloader_ui::render_()
|
||||
icon_center_y - text_size.y * 0.5f);
|
||||
|
||||
// Draw
|
||||
//draw_list->AddImage(reinterpret_cast<ImTextureID>(loading_tex), icon_pos, ImVec2(icon_pos.x + loading_size.x, icon_pos.y + loading_size.y), ImVec2(0, 0), ImVec2(1, 1));
|
||||
if( loading_tex != static_cast<GLuint>( -1 ) ) {
|
||||
draw_list->AddImage(
|
||||
reinterpret_cast<ImTextureID>( loading_tex ),
|
||||
icon_pos,
|
||||
ImVec2( icon_pos.x + loading_size.x, icon_pos.y + loading_size.y ),
|
||||
ImVec2( 0, 0 ),
|
||||
ImVec2( 1, 1 ) );
|
||||
}
|
||||
draw_list->AddText(text_pos, IM_COL32_WHITE, m_progresstext.c_str());
|
||||
|
||||
// Trivia
|
||||
|
||||
Reference in New Issue
Block a user