16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-18 00:49:19 +02:00

renderer changes, time and environment window

This commit is contained in:
milek7
2019-03-09 14:18:10 +01:00
parent 748e7b1dda
commit 3693c1660e
30 changed files with 299 additions and 93 deletions

View File

@@ -127,6 +127,7 @@ set(SOURCES
"widgets/map.cpp" "widgets/map.cpp"
"widgets/map_objects.cpp" "widgets/map_objects.cpp"
"widgets/popup.cpp" "widgets/popup.cpp"
"widgets/time.cpp"
"ref/glad/src/glad.c" "ref/glad/src/glad.c"

View File

@@ -29,6 +29,7 @@ struct global_settings {
std::mt19937 random_engine; std::mt19937 random_engine;
std::mt19937 local_random_engine; std::mt19937 local_random_engine;
bool ready_to_load { false }; bool ready_to_load { false };
std::time_t starting_timestamp = 0; // starting time, in local timezone
uint32_t random_seed = 0; uint32_t random_seed = 0;
TCamera pCamera; // parametry kamery TCamera pCamera; // parametry kamery
TCamera pDebugCamera; TCamera pDebugCamera;
@@ -73,8 +74,7 @@ struct global_settings {
float FrictionWeatherFactor { 1.f }; float FrictionWeatherFactor { 1.f };
bool bLiveTraction{ true }; bool bLiveTraction{ true };
float Overcast{ 0.1f }; // NOTE: all this weather stuff should be moved elsewhere float Overcast{ 0.1f }; // NOTE: all this weather stuff should be moved elsewhere
glm::vec3 FogColor = { 0.6f, 0.7f, 0.8f }; glm::vec3 FogColor = { 0.6f, 0.7f, 0.8f };
double fFogStart{ 1700 };
double fFogEnd{ 2000 }; double fFogEnd{ 2000 };
std::string Season{}; // season of the year, based on simulation date std::string Season{}; // season of the year, based on simulation date
std::string Weather{ "cloudy:" }; // current weather std::string Weather{ "cloudy:" }; // current weather

View File

@@ -63,7 +63,7 @@ void UpdateTimers(bool pause)
QueryPerformanceCounter((LARGE_INTEGER *)&count); QueryPerformanceCounter((LARGE_INTEGER *)&count);
#elif __linux__ #elif __linux__
timespec ts; timespec ts;
clock_gettime(CLOCK_MONOTONIC_RAW, &ts); clock_gettime(CLOCK_MONOTONIC, &ts);
count = (uint64_t)ts.tv_sec * 1000000000 + (uint64_t)ts.tv_nsec; count = (uint64_t)ts.tv_sec * 1000000000 + (uint64_t)ts.tv_nsec;
fr = 1000000000; fr = 1000000000;
#endif #endif

View File

@@ -767,6 +767,12 @@ bool eu07_application::init_network() {
if (!Global.random_seed) if (!Global.random_seed)
Global.random_seed = std::random_device{}(); Global.random_seed = std::random_device{}();
Global.random_engine.seed(Global.random_seed); Global.random_engine.seed(Global.random_seed);
// TODO: sort out this timezone mess
std::time_t utc_now = std::time(nullptr);
std::time_t local_now = utc_now + (std::mktime(std::localtime(&utc_now)) - std::mktime(std::gmtime(&utc_now)));
Global.starting_timestamp = local_now;
Global.ready_to_load = true; Global.ready_to_load = true;
} }

View File

@@ -227,6 +227,9 @@ commanddescription_sequence Commands_descriptions = {
{ "timejump", command_target::simulation, command_mode::oneoff }, { "timejump", command_target::simulation, command_mode::oneoff },
{ "timejumplarge", command_target::simulation, command_mode::oneoff }, { "timejumplarge", command_target::simulation, command_mode::oneoff },
{ "timejumpsmall", command_target::simulation, command_mode::oneoff }, { "timejumpsmall", command_target::simulation, command_mode::oneoff },
{ "setdatetime", command_target::simulation, command_mode::oneoff },
{ "setweather", command_target::simulation, command_mode::oneoff },
{ "settemperature", command_target::simulation, command_mode::oneoff },
{ "vehiclemove", command_target::vehicle, command_mode::oneoff }, { "vehiclemove", command_target::vehicle, command_mode::oneoff },
{ "vehiclemoveforwards", command_target::vehicle, command_mode::oneoff }, { "vehiclemoveforwards", command_target::vehicle, command_mode::oneoff },
{ "vehiclemovebackwards", command_target::vehicle, command_mode::oneoff }, { "vehiclemovebackwards", command_target::vehicle, command_mode::oneoff },

View File

@@ -221,6 +221,9 @@ enum class user_command {
timejump, timejump,
timejumplarge, timejumplarge,
timejumpsmall, timejumpsmall,
setdatetime,
setweather,
settemperature,
vehiclemove, vehiclemove,
vehiclemoveforwards, vehiclemoveforwards,
vehiclemovebackwards, vehiclemovebackwards,

View File

@@ -28,6 +28,7 @@ driver_ui::driver_ui() {
push_back( &m_transcriptspanel ); push_back( &m_transcriptspanel );
//push_back( &m_vehiclelist ); //push_back( &m_vehiclelist );
push_back( &m_timepanel );
push_back( &m_mappanel ); push_back( &m_mappanel );
push_back( &m_logpanel ); push_back( &m_logpanel );
m_logpanel.is_open = false; m_logpanel.is_open = false;
@@ -52,6 +53,10 @@ void driver_ui::render_menu_contents() {
ImGui::MenuItem(m_timetablepanel.title.c_str(), "F2", &m_timetablepanel.is_open); ImGui::MenuItem(m_timetablepanel.title.c_str(), "F2", &m_timetablepanel.is_open);
ImGui::MenuItem(m_debugpanel.get_name().c_str(), "F12", &m_debugpanel.is_open); ImGui::MenuItem(m_debugpanel.get_name().c_str(), "F12", &m_debugpanel.is_open);
ImGui::MenuItem(m_mappanel.get_name().c_str(), "Tab", &m_mappanel.is_open); ImGui::MenuItem(m_mappanel.get_name().c_str(), "Tab", &m_mappanel.is_open);
if (ImGui::MenuItem(m_timepanel.get_name().c_str()))
m_timepanel.open();
ImGui::EndMenu(); ImGui::EndMenu();
} }
} }

View File

@@ -15,6 +15,7 @@ http://mozilla.org/MPL/2.0/.
#include "widgets/vehiclelist.h" #include "widgets/vehiclelist.h"
#include "widgets/map.h" #include "widgets/map.h"
#include "widgets/time.h"
class driver_ui : public ui_layer { class driver_ui : public ui_layer {
@@ -58,4 +59,5 @@ private:
command_relay m_relay; command_relay m_relay;
ui::vehiclelist_panel m_vehiclelist; ui::vehiclelist_panel m_vehiclelist;
ui::map_panel m_mappanel; ui::map_panel m_mappanel;
ui::time_panel m_timepanel;
}; };

View File

@@ -16,11 +16,13 @@ void network::client_hello::deserialize(std::istream &stream)
void network::server_hello::serialize(std::ostream &stream) const void network::server_hello::serialize(std::ostream &stream) const
{ {
sn_utils::ls_uint32(stream, seed); sn_utils::ls_uint32(stream, seed);
sn_utils::ls_int64(stream, timestamp);
} }
void network::server_hello::deserialize(std::istream &stream) void network::server_hello::deserialize(std::istream &stream)
{ {
seed = sn_utils::ld_uint32(stream); seed = sn_utils::ld_uint32(stream);
timestamp = sn_utils::ld_int64(stream);
} }
void ::network::request_command::serialize(std::ostream &stream) const void ::network::request_command::serialize(std::ostream &stream) const

View File

@@ -39,6 +39,7 @@ struct server_hello : public message
server_hello() : message(SERVER_HELLO) {} server_hello() : message(SERVER_HELLO) {}
uint32_t seed; uint32_t seed;
int64_t timestamp;
virtual void serialize(std::ostream &stream) const override; virtual void serialize(std::ostream &stream) const override;
virtual void deserialize(std::istream &stream) override; virtual void deserialize(std::istream &stream) override;

View File

@@ -122,6 +122,7 @@ void network::server::handle_message(std::shared_ptr<connection> conn, const mes
server_hello reply; server_hello reply;
reply.seed = Global.random_seed; reply.seed = Global.random_seed;
reply.timestamp = Global.starting_timestamp;
conn->state = connection::CATCHING_UP; conn->state = connection::CATCHING_UP;
conn->backbuffer = backbuffer; conn->backbuffer = backbuffer;
conn->backbuffer_pos = 0; conn->backbuffer_pos = 0;
@@ -229,6 +230,7 @@ void network::client::handle_message(std::shared_ptr<connection> conn, const mes
if (!Global.ready_to_load) { if (!Global.ready_to_load) {
Global.random_seed = cmd.seed; Global.random_seed = cmd.seed;
Global.random_engine.seed(Global.random_seed); Global.random_engine.seed(Global.random_seed);
Global.starting_timestamp = cmd.timestamp;
Global.ready_to_load = true; Global.ready_to_load = true;
} else if (Global.random_seed != cmd.seed) { } else if (Global.random_seed != cmd.seed) {
ErrorLog("net: seed mismatch", logtype::net); ErrorLog("net: seed mismatch", logtype::net);

View File

@@ -90,24 +90,28 @@ basic_precipitation::init() {
create( 18 ); create( 18 );
// TODO: select texture based on current overcast level
// TODO: when the overcast level dynamic change is in check the current level during render and pick the appropriate texture on the fly
std::string const densitysuffix { (
Global.Overcast < 1.35 ?
"_light" :
"_medium" ) };
if( Global.Weather == "rain:" ) {
m_moverateweathertypefactor = 2.f;
m_texture = GfxRenderer.Fetch_Texture( "fx/rain" + densitysuffix );
}
else if( Global.Weather == "snow:" ) {
m_moverateweathertypefactor = 1.25f;
m_texture = GfxRenderer.Fetch_Texture( "fx/snow" + densitysuffix );
}
return true; return true;
} }
void
basic_precipitation::update_weather() {
// TODO: select texture based on current overcast level
// TODO: when the overcast level dynamic change is in check the current level during render and pick the appropriate texture on the fly
std::string const densitysuffix { (
Global.Overcast < 1.35 ?
"_light" :
"_medium" ) };
if( Global.Weather == "rain:" ) {
m_moverateweathertypefactor = 2.f;
m_texture = GfxRenderer.Fetch_Texture( "fx/rain" + densitysuffix );
}
else if( Global.Weather == "snow:" ) {
m_moverateweathertypefactor = 1.25f;
m_texture = GfxRenderer.Fetch_Texture( "fx/snow" + densitysuffix );
}
}
void void
basic_precipitation::update() { basic_precipitation::update() {

View File

@@ -26,11 +26,14 @@ public:
// methods // methods
bool bool
init(); init();
void
update_weather();
void void
update(); update();
void void
render(); render();
float get_textureoffset(); float
get_textureoffset();
glm::dvec3 m_cameramove{ 0.0 }; glm::dvec3 m_cameramove{ 0.0 };

View File

@@ -195,9 +195,26 @@ bool opengl_renderer::Init(GLFWwindow *Window)
m_empty_cubemap = std::make_unique<gl::cubemap>(); m_empty_cubemap = std::make_unique<gl::cubemap>();
m_empty_cubemap->alloc(Global.gfx_format_color, 16, 16, GL_RGB, GL_FLOAT); m_empty_cubemap->alloc(Global.gfx_format_color, 16, 16, GL_RGB, GL_FLOAT);
m_current_viewport = &default_viewport; m_viewports.push_back(std::make_unique<viewport_config>());
if (!init_viewport(default_viewport)) viewport_config &default_viewport = *m_viewports.front().get();
return false; default_viewport.width = Global.gfx_framebuffer_width;
default_viewport.height = Global.gfx_framebuffer_height;
/*
default_viewport.camera_transform = glm::rotate(glm::mat4(), 0.5f, glm::vec3(1.0f, 0.0f, 0.f));
m_viewports.push_back(std::make_unique<viewport_config>());
viewport_config &vp2 = *m_viewports.back().get();
vp2.width = Global.gfx_framebuffer_width;
vp2.height = Global.gfx_framebuffer_height;
vp2.camera_transform = glm::rotate(glm::mat4(), -0.5f, glm::vec3(1.0f, 0.0f, 0.f));
*/
for (auto &viewport : m_viewports) {
if (!init_viewport(*viewport.get()))
return false;
}
m_pick_tex = std::make_unique<opengl_texture>(); m_pick_tex = std::make_unique<opengl_texture>();
m_pick_tex->alloc_rendertarget(GL_RGB8, GL_RGB, EU07_PICKBUFFERSIZE, EU07_PICKBUFFERSIZE); m_pick_tex->alloc_rendertarget(GL_RGB8, GL_RGB, EU07_PICKBUFFERSIZE, EU07_PICKBUFFERSIZE);
@@ -271,17 +288,17 @@ bool opengl_renderer::Init(GLFWwindow *Window)
return true; return true;
} }
bool opengl_renderer::init_viewport(viewport_data &vp) bool opengl_renderer::init_viewport(viewport_config &vp)
{ {
int samples = 1 << Global.iMultisampling; int samples = 1 << Global.iMultisampling;
if (!Global.gfx_skippipeline) if (!Global.gfx_skippipeline)
{ {
vp.msaa_rbc = std::make_unique<gl::renderbuffer>(); vp.msaa_rbc = std::make_unique<gl::renderbuffer>();
vp.msaa_rbc->alloc(Global.gfx_format_color, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height, samples); vp.msaa_rbc->alloc(Global.gfx_format_color, vp.width, vp.height, samples);
vp.msaa_rbd = std::make_unique<gl::renderbuffer>(); vp.msaa_rbd = std::make_unique<gl::renderbuffer>();
vp.msaa_rbd->alloc(Global.gfx_format_depth, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height, samples); vp.msaa_rbd->alloc(Global.gfx_format_depth, vp.width, vp.height, samples);
vp.msaa_fb = std::make_unique<gl::framebuffer>(); vp.msaa_fb = std::make_unique<gl::framebuffer>();
vp.msaa_fb->attach(*vp.msaa_rbc, GL_COLOR_ATTACHMENT0); vp.msaa_fb->attach(*vp.msaa_rbc, GL_COLOR_ATTACHMENT0);
@@ -290,17 +307,17 @@ bool opengl_renderer::init_viewport(viewport_data &vp)
if (Global.gfx_postfx_motionblur_enabled) if (Global.gfx_postfx_motionblur_enabled)
{ {
vp.msaa_rbv = std::make_unique<gl::renderbuffer>(); vp.msaa_rbv = std::make_unique<gl::renderbuffer>();
vp.msaa_rbv->alloc(Global.gfx_postfx_motionblur_format, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height, samples); vp.msaa_rbv->alloc(Global.gfx_postfx_motionblur_format, vp.width, vp.height, samples);
vp.msaa_fb->attach(*vp.msaa_rbv, GL_COLOR_ATTACHMENT1); vp.msaa_fb->attach(*vp.msaa_rbv, GL_COLOR_ATTACHMENT1);
vp.main_tex = std::make_unique<opengl_texture>(); vp.main_tex = std::make_unique<opengl_texture>();
vp.main_tex->alloc_rendertarget(Global.gfx_format_color, GL_RGB, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height, 1, GL_CLAMP_TO_EDGE); vp.main_tex->alloc_rendertarget(Global.gfx_format_color, GL_RGB, vp.width, vp.height, 1, GL_CLAMP_TO_EDGE);
vp.main_fb = std::make_unique<gl::framebuffer>(); vp.main_fb = std::make_unique<gl::framebuffer>();
vp.main_fb->attach(*vp.main_tex, GL_COLOR_ATTACHMENT0); vp.main_fb->attach(*vp.main_tex, GL_COLOR_ATTACHMENT0);
vp.main_texv = std::make_unique<opengl_texture>(); vp.main_texv = std::make_unique<opengl_texture>();
vp.main_texv->alloc_rendertarget(Global.gfx_postfx_motionblur_format, GL_RG, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height); vp.main_texv->alloc_rendertarget(Global.gfx_postfx_motionblur_format, GL_RG, vp.width, vp.height);
vp.main_fb->attach(*vp.main_texv, GL_COLOR_ATTACHMENT1); vp.main_fb->attach(*vp.main_texv, GL_COLOR_ATTACHMENT1);
vp.main_fb->setup_drawing(2); vp.main_fb->setup_drawing(2);
@@ -314,7 +331,7 @@ bool opengl_renderer::init_viewport(viewport_data &vp)
return false; return false;
vp.main2_tex = std::make_unique<opengl_texture>(); vp.main2_tex = std::make_unique<opengl_texture>();
vp.main2_tex->alloc_rendertarget(Global.gfx_format_color, GL_RGB, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height); vp.main2_tex->alloc_rendertarget(Global.gfx_format_color, GL_RGB, vp.width, vp.height);
vp.main2_fb = std::make_unique<gl::framebuffer>(); vp.main2_fb = std::make_unique<gl::framebuffer>();
vp.main2_fb->attach(*vp.main2_tex, GL_COLOR_ATTACHMENT0); vp.main2_fb->attach(*vp.main2_tex, GL_COLOR_ATTACHMENT0);
@@ -412,7 +429,10 @@ bool opengl_renderer::Render()
m_renderpass.draw_mode = rendermode::none; // force setup anew m_renderpass.draw_mode = rendermode::none; // force setup anew
m_debugstats = debug_stats(); m_debugstats = debug_stats();
Render_pass(default_viewport, rendermode::color); for (auto &viewport : m_viewports) {
Render_pass(*viewport.get(), rendermode::color);
}
//Render_pass(*m_viewports.front().get(), rendermode::color);
m_drawcount = m_cellqueue.size(); m_drawcount = m_cellqueue.size();
m_debugtimestext.clear(); m_debugtimestext.clear();
@@ -475,9 +495,9 @@ void opengl_renderer::draw_debug_ui()
} }
// runs jobs needed to generate graphics for specified render pass // runs jobs needed to generate graphics for specified render pass
void opengl_renderer::Render_pass(viewport_data &vp, rendermode const Mode) void opengl_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
{ {
setup_pass(m_renderpass, Mode); setup_pass(vp, m_renderpass, Mode);
switch (m_renderpass.draw_mode) switch (m_renderpass.draw_mode)
{ {
@@ -520,7 +540,7 @@ void opengl_renderer::Render_pass(viewport_data &vp, rendermode const Mode)
Render_pass(vp, rendermode::shadows); Render_pass(vp, rendermode::shadows);
if (!FreeFlyModeFlag) if (!FreeFlyModeFlag)
Render_pass(vp, rendermode::cabshadows); Render_pass(vp, rendermode::cabshadows);
setup_pass(m_renderpass, Mode); // restore draw mode. TBD, TODO: render mode stack setup_pass(vp, m_renderpass, Mode); // restore draw mode. TBD, TODO: render mode stack
Timer::subsystem.gfx_shadows.stop(); Timer::subsystem.gfx_shadows.stop();
glDebug("render shadowmap end"); glDebug("render shadowmap end");
@@ -530,7 +550,7 @@ void opengl_renderer::Render_pass(viewport_data &vp, rendermode const Mode)
{ {
// potentially update environmental cube map // potentially update environmental cube map
if (Render_reflections(vp)) if (Render_reflections(vp))
setup_pass(m_renderpass, Mode); // restore color pass settings setup_pass(vp, m_renderpass, Mode); // restore color pass settings
setup_env_map(vp.env_tex.get()); setup_env_map(vp.env_tex.get());
} }
@@ -851,7 +871,7 @@ void opengl_renderer::Render_pass(viewport_data &vp, rendermode const Mode)
} }
// creates dynamic environment cubemap // creates dynamic environment cubemap
bool opengl_renderer::Render_reflections(viewport_data &vp) bool opengl_renderer::Render_reflections(viewport_config &vp)
{ {
if (Global.ReflectionUpdatesPerSecond == 0) if (Global.ReflectionUpdatesPerSecond == 0)
return false; return false;
@@ -943,7 +963,8 @@ glm::mat4 opengl_renderer::ortho_frustumtest_projection(float l, float r, float
return glm::ortho(l, r, b, t, znear, zfar); return glm::ortho(l, r, b, t, znear, zfar);
} }
void opengl_renderer::setup_pass(renderpass_config &Config, rendermode const Mode, float const Znear, float const Zfar, bool const Ignoredebug) void opengl_renderer::setup_pass(viewport_config &Viewport, renderpass_config &Config, rendermode const Mode,
float const Znear, float const Zfar, bool const Ignoredebug)
{ {
Config.draw_mode = Mode; Config.draw_mode = Mode;
@@ -1001,10 +1022,14 @@ void opengl_renderer::setup_pass(renderpass_config &Config, rendermode const Mod
float const fovy = glm::radians(Global.FieldOfView / Global.ZoomFactor); float const fovy = glm::radians(Global.FieldOfView / Global.ZoomFactor);
float const aspect = std::max(1.f, (float)Global.iWindowWidth) / std::max(1.f, (float)Global.iWindowHeight); float const aspect = std::max(1.f, (float)Global.iWindowWidth) / std::max(1.f, (float)Global.iWindowHeight);
Config.viewport_camera.position() = Global.pCamera.Pos;
switch (Mode) switch (Mode)
{ {
case rendermode::color: case rendermode::color:
{ {
viewmatrix = glm::dmat4(Viewport.camera_transform);
// modelview // modelview
if ((false == DebugCameraFlag) || (true == Ignoredebug)) if ((false == DebugCameraFlag) || (true == Ignoredebug))
{ {
@@ -1016,6 +1041,7 @@ void opengl_renderer::setup_pass(renderpass_config &Config, rendermode const Mod
camera.position() = Global.pDebugCamera.Pos; camera.position() = Global.pDebugCamera.Pos;
Global.pDebugCamera.SetMatrix(viewmatrix); Global.pDebugCamera.SetMatrix(viewmatrix);
} }
// projection // projection
auto const zfar = Config.draw_range * Global.fDistanceFactor * Zfar; auto const zfar = Config.draw_range * Global.fDistanceFactor * Zfar;
auto const znear = (Znear > 0.f ? Znear * zfar : 0.1f * Global.ZoomFactor); auto const znear = (Znear > 0.f ? Znear * zfar : 0.1f * Global.ZoomFactor);
@@ -1030,7 +1056,7 @@ void opengl_renderer::setup_pass(renderpass_config &Config, rendermode const Mod
// ...setup chunk of frustum we're interested in... // ...setup chunk of frustum we're interested in...
auto const zfar = std::min(1.f, Global.shadowtune.depth / (Global.BaseDrawRange * Global.fDistanceFactor) * std::max(1.f, Global.ZoomFactor * 0.5f)); auto const zfar = std::min(1.f, Global.shadowtune.depth / (Global.BaseDrawRange * Global.fDistanceFactor) * std::max(1.f, Global.ZoomFactor * 0.5f));
renderpass_config worldview; renderpass_config worldview;
setup_pass(worldview, rendermode::color, 0.f, zfar, true); setup_pass(Viewport, worldview, rendermode::color, 0.f, zfar, true);
auto &frustumchunkshapepoints = worldview.pass_camera.frustum_points(); auto &frustumchunkshapepoints = worldview.pass_camera.frustum_points();
// ...modelview matrix: determine the centre of frustum chunk in world space... // ...modelview matrix: determine the centre of frustum chunk in world space...
glm::vec3 frustumchunkmin, frustumchunkmax; glm::vec3 frustumchunkmin, frustumchunkmax;
@@ -1110,9 +1136,12 @@ void opengl_renderer::setup_pass(renderpass_config &Config, rendermode const Mod
case rendermode::pickcontrols: case rendermode::pickcontrols:
case rendermode::pickscenery: case rendermode::pickscenery:
{ {
viewmatrix = glm::dmat4(Viewport.camera_transform);
// modelview // modelview
camera.position() = Global.pCamera.Pos; camera.position() = Global.pCamera.Pos;
Global.pCamera.SetMatrix(viewmatrix); Global.pCamera.SetMatrix(viewmatrix);
// projection // projection
float znear = 0.1f * Global.ZoomFactor; float znear = 0.1f * Global.ZoomFactor;
float zfar = Config.draw_range * Global.fDistanceFactor; float zfar = Config.draw_range * Global.fDistanceFactor;
@@ -1998,7 +2027,7 @@ void opengl_renderer::Render(scene::shape_node const &Shape, bool const Ignorera
case rendermode::shadows: case rendermode::shadows:
{ {
// 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees // 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees
distancesquared = Math3D::SquareMagnitude((data.area.center - Global.pCamera.Pos) / Global.ZoomFactor) / Global.fDistanceFactor; distancesquared = Math3D::SquareMagnitude((data.area.center - m_renderpass.viewport_camera.position()) / (double)Global.ZoomFactor) / Global.fDistanceFactor;
break; break;
} }
default: default:
@@ -2052,7 +2081,7 @@ void opengl_renderer::Render(TAnimModel *Instance)
case rendermode::shadows: case rendermode::shadows:
{ {
// 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees // 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees
distancesquared = Math3D::SquareMagnitude((Instance->location() - Global.pCamera.Pos) / Global.ZoomFactor) / Global.fDistanceFactor; distancesquared = Math3D::SquareMagnitude((Instance->location() - m_renderpass.viewport_camera.position()) / (double)Global.ZoomFactor) / Global.fDistanceFactor;
break; break;
} }
default: default:
@@ -2110,7 +2139,7 @@ bool opengl_renderer::Render(TDynamicObject *Dynamic)
{ {
case rendermode::shadows: case rendermode::shadows:
{ {
squaredistance = glm::length2(glm::vec3{glm::dvec3{Dynamic->vPosition - Global.pCamera.Pos}} / Global.ZoomFactor) / Global.fDistanceFactor; squaredistance = glm::length2(glm::vec3{glm::dvec3{Dynamic->vPosition - m_renderpass.viewport_camera.position()}} / Global.ZoomFactor) / Global.fDistanceFactor;
break; break;
} }
default: default:
@@ -3430,7 +3459,7 @@ void opengl_renderer::Update_Pick_Control()
pickbufferpos = glm::ivec2{mousepos.x * EU07_PICKBUFFERSIZE / std::max(1, Global.iWindowWidth), mousepos.y * EU07_PICKBUFFERSIZE / std::max(1, Global.iWindowHeight)}; pickbufferpos = glm::ivec2{mousepos.x * EU07_PICKBUFFERSIZE / std::max(1, Global.iWindowWidth), mousepos.y * EU07_PICKBUFFERSIZE / std::max(1, Global.iWindowHeight)};
pickbufferpos = glm::clamp(pickbufferpos, glm::ivec2(0, 0), glm::ivec2(EU07_PICKBUFFERSIZE - 1, EU07_PICKBUFFERSIZE - 1)); pickbufferpos = glm::clamp(pickbufferpos, glm::ivec2(0, 0), glm::ivec2(EU07_PICKBUFFERSIZE - 1, EU07_PICKBUFFERSIZE - 1));
Render_pass(default_viewport, rendermode::pickcontrols); Render_pass(*m_viewports.front().get(), rendermode::pickcontrols);
m_pick_fb->bind(); m_pick_fb->bind();
m_picking_pbo->request_read(pickbufferpos.x, pickbufferpos.y, 1, 1); m_picking_pbo->request_read(pickbufferpos.x, pickbufferpos.y, 1, 1);
m_pick_fb->unbind(); m_pick_fb->unbind();
@@ -3469,7 +3498,7 @@ void opengl_renderer::Update_Pick_Node()
pickbufferpos = glm::ivec2{mousepos.x * EU07_PICKBUFFERSIZE / std::max(1, Global.iWindowWidth), mousepos.y * EU07_PICKBUFFERSIZE / std::max(1, Global.iWindowHeight)}; pickbufferpos = glm::ivec2{mousepos.x * EU07_PICKBUFFERSIZE / std::max(1, Global.iWindowWidth), mousepos.y * EU07_PICKBUFFERSIZE / std::max(1, Global.iWindowHeight)};
pickbufferpos = glm::clamp(pickbufferpos, glm::ivec2(0, 0), glm::ivec2(EU07_PICKBUFFERSIZE - 1, EU07_PICKBUFFERSIZE - 1)); pickbufferpos = glm::clamp(pickbufferpos, glm::ivec2(0, 0), glm::ivec2(EU07_PICKBUFFERSIZE - 1, EU07_PICKBUFFERSIZE - 1));
Render_pass(default_viewport, rendermode::pickscenery); Render_pass(*m_viewports.front().get(), rendermode::pickscenery);
m_pick_fb->bind(); m_pick_fb->bind();
m_picking_node_pbo->request_read(pickbufferpos.x, pickbufferpos.y, 1, 1); m_picking_node_pbo->request_read(pickbufferpos.x, pickbufferpos.y, 1, 1);
m_pick_fb->unbind(); m_pick_fb->unbind();

View File

@@ -235,7 +235,12 @@ class opengl_renderer
float draw_range{0.0f}; float draw_range{0.0f};
}; };
struct viewport_data { struct viewport_config {
int width;
int height;
glm::mat4 camera_transform;
std::unique_ptr<gl::framebuffer> msaa_fb; std::unique_ptr<gl::framebuffer> msaa_fb;
std::unique_ptr<gl::renderbuffer> msaa_rbc; std::unique_ptr<gl::renderbuffer> msaa_rbc;
std::unique_ptr<gl::renderbuffer> msaa_rbv; std::unique_ptr<gl::renderbuffer> msaa_rbv;
@@ -264,16 +269,16 @@ class opengl_renderer
// methods // methods
std::unique_ptr<gl::program> make_shader(std::string v, std::string f); std::unique_ptr<gl::program> make_shader(std::string v, std::string f);
bool Init_caps(); bool Init_caps();
void setup_pass(renderpass_config &Config, rendermode const Mode, float const Znear = 0.f, float const Zfar = 1.f, bool const Ignoredebug = false); void setup_pass(viewport_config &Viewport, renderpass_config &Config, rendermode const Mode, float const Znear = 0.f, float const Zfar = 1.f, bool const Ignoredebug = false);
void setup_matrices(); void setup_matrices();
void setup_drawing(bool const Alpha = false); void setup_drawing(bool const Alpha = false);
void setup_shadow_map(opengl_texture *tex, renderpass_config conf); void setup_shadow_map(opengl_texture *tex, renderpass_config conf);
void setup_env_map(gl::cubemap *tex); void setup_env_map(gl::cubemap *tex);
void setup_environment_light(TEnvironmentType const Environment = e_flat); void setup_environment_light(TEnvironmentType const Environment = e_flat);
// runs jobs needed to generate graphics for specified render pass // runs jobs needed to generate graphics for specified render pass
void Render_pass(viewport_data &vp, rendermode const Mode); void Render_pass(viewport_config &vp, rendermode const Mode);
// creates dynamic environment cubemap // creates dynamic environment cubemap
bool Render_reflections(viewport_data &vp); bool Render_reflections(viewport_config &vp);
bool Render(world_environment *Environment); bool Render(world_environment *Environment);
void Render(scene::basic_region *Region); void Render(scene::basic_region *Region);
void Render(section_sequence::iterator First, section_sequence::iterator Last); void Render(section_sequence::iterator First, section_sequence::iterator Last);
@@ -302,7 +307,7 @@ class opengl_renderer
glm::vec3 pick_color(std::size_t const Index); glm::vec3 pick_color(std::size_t const Index);
std::size_t pick_index(glm::ivec3 const &Color); std::size_t pick_index(glm::ivec3 const &Color);
bool init_viewport(viewport_data &vp); bool init_viewport(viewport_config &vp);
void draw(const gfx::geometry_handle &handle); void draw(const gfx::geometry_handle &handle);
void draw(std::vector<gfx::geometrybank_handle>::iterator begin, std::vector<gfx::geometrybank_handle>::iterator end); void draw(std::vector<gfx::geometrybank_handle>::iterator begin, std::vector<gfx::geometrybank_handle>::iterator end);
@@ -350,7 +355,7 @@ class opengl_renderer
float m_fogrange = 2000.0f; float m_fogrange = 2000.0f;
renderpass_config m_renderpass; // parameters for current render pass renderpass_config m_renderpass; // parameters for current render pass
viewport_data *m_current_viewport; // active viewport viewport_config *m_current_viewport; // active viewport
section_sequence m_sectionqueue; // list of sections in current render pass section_sequence m_sectionqueue; // list of sections in current render pass
cell_sequence m_cellqueue; cell_sequence m_cellqueue;
renderpass_config m_colorpass; // parametrs of most recent color pass renderpass_config m_colorpass; // parametrs of most recent color pass
@@ -395,7 +400,7 @@ class opengl_renderer
std::unique_ptr<gl::vao> m_empty_vao; std::unique_ptr<gl::vao> m_empty_vao;
viewport_data default_viewport; std::vector<std::unique_ptr<viewport_config>> m_viewports;
std::unique_ptr<gl::postfx> m_pfx_motionblur; std::unique_ptr<gl::postfx> m_pfx_motionblur;
std::unique_ptr<gl::postfx> m_pfx_tonemapping; std::unique_ptr<gl::postfx> m_pfx_tonemapping;

View File

@@ -91,6 +91,6 @@ scenarioloader_mode::enter() {
void void
scenarioloader_mode::exit() { scenarioloader_mode::exit() {
simulation::Time.init(); simulation::Time.init(Global.starting_timestamp);
simulation::Environment.init(); simulation::Environment.init();
} }

View File

@@ -130,7 +130,7 @@ void state_manager::process_commands() {
if (commanddata.command == user_command::queueevent) { if (commanddata.command == user_command::queueevent) {
uint32_t id = std::round(commanddata.param1); uint32_t id = std::round(commanddata.param1);
basic_event *ev = Events.FindEventById(id); basic_event *ev = Events.FindEventById(id); // TODO: depends on vector position
Events.AddToQuery(ev, nullptr); Events.AddToQuery(ev, nullptr);
} }
@@ -139,7 +139,26 @@ void state_manager::process_commands() {
int light = std::round(commanddata.param1); int light = std::round(commanddata.param1);
float state = commanddata.param2; float state = commanddata.param2;
if (id < simulation::Instances.sequence().size()) if (id < simulation::Instances.sequence().size())
simulation::Instances.sequence()[id]->LightSet(light, state); simulation::Instances.sequence()[id]->LightSet(light, state); // TODO: depends on vector position
}
if (commanddata.command == user_command::setdatetime) {
int yearday = std::round(commanddata.param1);
int minute = std::round(commanddata.param2 * 60.0);
simulation::Time.set_time(yearday, minute);
simulation::Environment.compute_season(yearday);
}
if (commanddata.command == user_command::setweather) {
Global.fFogEnd = commanddata.param1;
Global.Overcast = commanddata.param2;
simulation::Environment.compute_weather();
}
if (commanddata.command == user_command::settemperature) {
Global.AirTemperature = commanddata.param1;
} }
if (DebugModeFlag) { if (DebugModeFlag) {

View File

@@ -35,7 +35,7 @@ world_environment::toggle_daylight() {
// calculates current season of the year based on set simulation date // calculates current season of the year based on set simulation date
void void
world_environment::compute_season( int const Yearday ) const { world_environment::compute_season( int const Yearday ) {
using dayseasonpair = std::pair<int, std::string>; using dayseasonpair = std::pair<int, std::string>;
@@ -59,7 +59,7 @@ world_environment::compute_season( int const Yearday ) const {
// calculates current weather // calculates current weather
void void
world_environment::compute_weather() const { world_environment::compute_weather() {
Global.Weather = ( Global.Weather = (
Global.Overcast <= 0.25 ? "clear:" : Global.Overcast <= 0.25 ? "clear:" :
@@ -67,6 +67,8 @@ world_environment::compute_weather() const {
( Global.Season != "winter:" ? ( Global.Season != "winter:" ?
"rain:" : "rain:" :
"snow:" ) ); "snow:" ) );
m_precipitation.update_weather();
} }
void void
@@ -161,7 +163,11 @@ world_environment::update() {
else if( Global.Weather == "snow:" ) { else if( Global.Weather == "snow:" ) {
// reduce friction due to snow // reduce friction due to snow
Global.FrictionWeatherFactor = 0.75f; Global.FrictionWeatherFactor = 0.75f;
m_precipitationsound.stop();
} }
else {
m_precipitationsound.stop();
}
} }
void void

View File

@@ -33,9 +33,9 @@ public:
// switches between static and dynamic daylight calculation // switches between static and dynamic daylight calculation
void toggle_daylight(); void toggle_daylight();
// calculates current season of the year based on set simulation date // calculates current season of the year based on set simulation date
void compute_season( int const Yearday ) const; void compute_season( int const Yearday );
// calculates current weather // calculates current weather
void compute_weather() const; void compute_weather();
private: private:
// members // members

View File

@@ -150,10 +150,9 @@ state_serializer::deserialize_atmo( cParser &Input, scene::scratch_data &Scratch
// atmosphere color; legacy parameter, no longer used // atmosphere color; legacy parameter, no longer used
Input.getTokens( 3 ); Input.getTokens( 3 );
// fog range // fog range
Input.getTokens( 2 ); Input.getTokens( 1 ); // fog start ignored
Input Input.getTokens( 1 );
>> Global.fFogStart Input >> Global.fFogEnd;
>> Global.fFogEnd;
if( Global.fFogEnd > 0.0 ) { if( Global.fFogEnd > 0.0 ) {
// fog colour; optional legacy parameter, no longer used // fog colour; optional legacy parameter, no longer used
@@ -297,9 +296,24 @@ state_serializer::deserialize_firstinit( cParser &Input, scene::scratch_data &Sc
simulation::Events.InitLaunchers(); simulation::Events.InitLaunchers();
simulation::Memory.InitCells(); simulation::Memory.InitCells();
init_time();
Scratchpad.initialized = true; Scratchpad.initialized = true;
} }
void state_serializer::init_time() {
auto &time = simulation::Time.data();
if( true == Global.ScenarioTimeCurrent ) {
// calculate time shift required to match scenario time with local clock
auto const *localtime = std::gmtime( &Global.starting_timestamp );
Global.ScenarioTimeOffset = ( ( localtime->tm_hour * 60 + localtime->tm_min ) - ( time.wHour * 60 + time.wMinute ) ) / 60.f;
}
else if( false == std::isnan( Global.ScenarioTimeOverride ) ) {
// scenario time override takes precedence over scenario time offset
Global.ScenarioTimeOffset = ( ( Global.ScenarioTimeOverride * 60 ) - ( time.wHour * 60 + time.wMinute ) ) / 60.f;
}
}
void void
state_serializer::deserialize_group( cParser &Input, scene::scratch_data &Scratchpad ) { state_serializer::deserialize_group( cParser &Input, scene::scratch_data &Scratchpad ) {
@@ -583,17 +597,6 @@ state_serializer::deserialize_time( cParser &Input, scene::scratch_data &Scratch
>> time.wHour >> time.wHour
>> time.wMinute; >> time.wMinute;
if( true == Global.ScenarioTimeCurrent ) {
// calculate time shift required to match scenario time with local clock
auto timenow = std::time( 0 );
auto const *localtime = std::localtime( &timenow );
Global.ScenarioTimeOffset = ( ( localtime->tm_hour * 60 + localtime->tm_min ) - ( time.wHour * 60 + time.wMinute ) ) / 60.f;
}
else if( false == std::isnan( Global.ScenarioTimeOverride ) ) {
// scenario time override takes precedence over scenario time offset
Global.ScenarioTimeOffset = ( ( Global.ScenarioTimeOverride * 60 ) - ( time.wHour * 60 + time.wMinute ) ) / 60.f;
}
// remaining sunrise and sunset parameters are no longer used, as they're now calculated dynamically // remaining sunrise and sunset parameters are no longer used, as they're now calculated dynamically
// anything else left in the section has no defined meaning // anything else left in the section has no defined meaning
skip_until( Input, "endtime" ); skip_until( Input, "endtime" );

View File

@@ -73,6 +73,7 @@ private:
TAnimModel * deserialize_model( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ); TAnimModel * deserialize_model( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
TDynamicObject * deserialize_dynamic( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ); TDynamicObject * deserialize_dynamic( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
sound_source * deserialize_sound( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ); sound_source * deserialize_sound( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
void init_time();
// skips content of stream until specified token // skips content of stream until specified token
void skip_until( cParser &Input, std::string const &Token ); void skip_until( cParser &Input, std::string const &Token );
// transforms provided location by specifed rotation and offset // transforms provided location by specifed rotation and offset

View File

@@ -20,7 +20,7 @@ scenario_time Time;
} // simulation } // simulation
void void
scenario_time::init() { scenario_time::init(std::time_t timestamp) {
char monthdaycounts[ 2 ][ 13 ] = { char monthdaycounts[ 2 ][ 13 ] = {
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } }; { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } };
@@ -32,10 +32,7 @@ scenario_time::init() {
auto const requestedminute { requestedtime % 60 }; auto const requestedminute { requestedtime % 60 };
// cache requested elements, if any // cache requested elements, if any
#ifdef __linux__ std::tm *tms = std::gmtime(&timestamp);
timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
tm *tms = localtime(&ts.tv_sec);
m_time.wYear = tms->tm_year; m_time.wYear = tms->tm_year;
m_time.wMonth = tms->tm_mon; m_time.wMonth = tms->tm_mon;
m_time.wDayOfWeek = tms->tm_wday; m_time.wDayOfWeek = tms->tm_wday;
@@ -43,16 +40,7 @@ scenario_time::init() {
m_time.wHour = tms->tm_hour; m_time.wHour = tms->tm_hour;
m_time.wMinute = tms->tm_min; m_time.wMinute = tms->tm_min;
m_time.wSecond = tms->tm_sec; m_time.wSecond = tms->tm_sec;
m_time.wMilliseconds = ts.tv_nsec / 1000000; m_time.wMilliseconds = 0;
/*
time_t local = mktime(localtime(&ts.tv_sec));
time_t utc = mktime(gmtime(&ts.tv_sec));
m_timezonebias = (double)(local - utc) / 3600.0f;
*/
#elif _WIN32
::GetLocalTime( &m_time );
#endif
if( Global.fMoveLight > 0.0 ) { if( Global.fMoveLight > 0.0 ) {
// day and month of the year can be overriden by scenario setup // day and month of the year can be overriden by scenario setup
@@ -94,7 +82,7 @@ scenario_time::init() {
zonebias += timezoneinfo.StandardBias; zonebias += timezoneinfo.StandardBias;
} }
m_timezonebias = ( zonebias / 60.0 ); m_timezonebias = ( zonebias / 60.0 );
} }
void void
@@ -197,6 +185,12 @@ scenario_time::julian_day() const {
return JD; return JD;
} }
void scenario_time::set_time(int yearday, int minute) {
daymonth(m_time.wDay, m_time.wMonth, m_time.wYear, yearday);
m_time.wHour = minute / 60;
m_time.wMinute = minute % 60;
}
// calculates day of week for provided date // calculates day of week for provided date
int int
scenario_time::day_of_week( int const Day, int const Month, int const Year ) const { scenario_time::day_of_week( int const Day, int const Month, int const Year ) const {

View File

@@ -20,7 +20,7 @@ public:
scenario_time() { scenario_time() {
m_time.wHour = 10; m_time.wMinute = 30; } m_time.wHour = 10; m_time.wMinute = 30; }
void void
init(); init(time_t timestamp);
void void
update( double const Deltatime ); update( double const Deltatime );
inline inline
@@ -45,6 +45,8 @@ public:
double double
zone_bias() const { zone_bias() const {
return m_timezonebias; } return m_timezonebias; }
void
set_time(int yearday, int minute);
/** Returns std::string in format: `"mm:ss"`. */ /** Returns std::string in format: `"mm:ss"`. */
operator std::string(); operator std::string();

View File

@@ -38,6 +38,18 @@ int32_t sn_utils::ld_int32(std::istream &s)
return reinterpret_cast<int32_t&>(v); return reinterpret_cast<int32_t&>(v);
} }
// deserialize little endian int64
int64_t sn_utils::ld_int64(std::istream &s)
{
uint8_t buf[8];
s.read((char*)buf, 8);
uint64_t v = ((uint64_t)buf[7] << 56) | ((uint64_t)buf[6] << 48) |
((uint64_t)buf[5] << 40) | ((uint64_t)buf[4] << 32) |
((uint64_t)buf[3] << 24) | ((uint64_t)buf[2] << 16) |
((uint64_t)buf[1] << 8) | (uint64_t)buf[0];
return reinterpret_cast<int64_t&>(v);
}
// deserialize little endian ieee754 float32 // deserialize little endian ieee754 float32
float sn_utils::ld_float32(std::istream &s) float sn_utils::ld_float32(std::istream &s)
{ {
@@ -133,6 +145,20 @@ void sn_utils::ls_int32(std::ostream &s, int32_t v)
s.write((char*)buf, 4); s.write((char*)buf, 4);
} }
void sn_utils::ls_int64(std::ostream &s, int64_t v)
{
uint8_t buf[8];
buf[0] = v;
buf[1] = v >> 8;
buf[2] = v >> 16;
buf[3] = v >> 24;
buf[4] = v >> 32;
buf[5] = v >> 40;
buf[6] = v >> 48;
buf[7] = v >> 56;
s.write((char*)buf, 8);
}
void sn_utils::ls_float32(std::ostream &s, float t) void sn_utils::ls_float32(std::ostream &s, float t)
{ {
uint32_t v = reinterpret_cast<uint32_t&>(t); uint32_t v = reinterpret_cast<uint32_t&>(t);

View File

@@ -10,6 +10,7 @@ public:
static uint16_t ld_uint16(std::istream&); static uint16_t ld_uint16(std::istream&);
static uint32_t ld_uint32(std::istream&); static uint32_t ld_uint32(std::istream&);
static int32_t ld_int32(std::istream&); static int32_t ld_int32(std::istream&);
static int64_t ld_int64(std::istream&);
static float ld_float32(std::istream&); static float ld_float32(std::istream&);
static double ld_float64(std::istream&); static double ld_float64(std::istream&);
static std::string d_str(std::istream&); static std::string d_str(std::istream&);
@@ -21,6 +22,7 @@ public:
static void ls_uint16(std::ostream&, uint16_t); static void ls_uint16(std::ostream&, uint16_t);
static void ls_uint32(std::ostream&, uint32_t); static void ls_uint32(std::ostream&, uint32_t);
static void ls_int32(std::ostream&, int32_t); static void ls_int32(std::ostream&, int32_t);
static void ls_int64(std::ostream&, int64_t);
static void ls_float32(std::ostream&, float); static void ls_float32(std::ostream&, float);
static void ls_float64(std::ostream&, double); static void ls_float64(std::ostream&, double);
static void s_str(std::ostream&, std::string); static void s_str(std::ostream&, std::string);

View File

@@ -79,6 +79,14 @@ init() {
"Map", "Map",
"Mode windows", "Mode windows",
"Time and environment",
"Time",
"Day in year",
"Visibility",
"Overcast and precipitation",
"Temperature",
"Apply",
"Straight |", "Straight |",
"Divert /", "Divert /",
@@ -242,6 +250,14 @@ init() {
u8"Mapa", u8"Mapa",
u8"Okna trybu", u8"Okna trybu",
u8"Czas i środowisko",
u8"Czas",
u8"Dzień w roku",
u8"Widoczność",
u8"Zachmurzenie i opady",
u8"Temperatura",
u8"Zastosuj",
u8"Prosto |", u8"Prosto |",
u8"W bok /", u8"W bok /",

View File

@@ -68,6 +68,14 @@ enum string {
ui_map, ui_map,
ui_mode_windows, ui_mode_windows,
time_window,
time_time,
time_yearday,
time_visibility,
time_weather,
time_temperature,
time_apply,
map_straight, map_straight,
map_divert, map_divert,

View File

@@ -133,8 +133,10 @@ void ui::map_panel::render_labels(glm::mat4 transform, ImVec2 origin, glm::vec2
for (TDynamicObject *vehicle : simulation::Vehicles.sequence()) { for (TDynamicObject *vehicle : simulation::Vehicles.sequence()) {
if (vehicle->Prev() || !vehicle->Mechanik) if (vehicle->Prev() || !vehicle->Mechanik)
continue; continue;
if (vehicle->Mechanik->TrainName().empty())
continue; std::string label = vehicle->Mechanik->TrainName();
if (label.empty() || label == "none")
label = ToUpper(vehicle->name());
glm::vec4 ndc_pos = transform * glm::vec4(glm::vec3(vehicle->GetPosition()), 1.0f); glm::vec4 ndc_pos = transform * glm::vec4(glm::vec3(vehicle->GetPosition()), 1.0f);
if (glm::abs(ndc_pos.x) > 1.0f || glm::abs(ndc_pos.z) > 1.0f) if (glm::abs(ndc_pos.x) > 1.0f || glm::abs(ndc_pos.z) > 1.0f)
@@ -144,11 +146,10 @@ void ui::map_panel::render_labels(glm::mat4 transform, ImVec2 origin, glm::vec2
TDynamicObject *veh = vehicle; TDynamicObject *veh = vehicle;
const char *desc = vehicle->Mechanik->TrainName().c_str(); ImVec2 textsize = ImGui::CalcTextSize(label.c_str());
ImVec2 textsize = ImGui::CalcTextSize(desc);
ImGui::SetCursorPos(ImVec2(origin.x + gui_pos.x - textsize.x / 2.0f, ImGui::SetCursorPos(ImVec2(origin.x + gui_pos.x - textsize.x / 2.0f,
origin.y + gui_pos.y - textsize.y / 2.0f)); origin.y + gui_pos.y - textsize.y / 2.0f));
ImGui::TextUnformatted(desc); ImGui::TextUnformatted(label.c_str());
} }
ImGui::PopStyleColor(); ImGui::PopStyleColor();

41
widgets/time.cpp Normal file
View File

@@ -0,0 +1,41 @@
#include "stdafx.h"
#include "widgets/time.h"
#include "simulationtime.h"
#include "Globals.h"
ui::time_panel::time_panel()
: ui_panel(LOC_STR(time_window), false)
{
size.x = 450;
}
void ui::time_panel::render_contents()
{
ImGui::SliderFloat(LOC_STR(time_time), &time, 0.0f, 24.0f, "%.1f");
ImGui::SliderInt(LOC_STR(time_yearday), &yearday, 1, 365);
ImGui::SliderFloat(LOC_STR(time_visibility), &fog, 50.0f, 3000.0f, "%.0f");
ImGui::SliderFloat(LOC_STR(time_weather), &overcast, 0.0f, 2.0f, "%.1f");
ImGui::SliderFloat(LOC_STR(time_temperature), &temperature, -20.0f, 40.0f, "%.0f");
if (ImGui::Button(LOC_STR(time_apply))) {
m_relay.post(user_command::setdatetime, (double)yearday, time, 1, 0);
m_relay.post(user_command::setweather, fog, overcast, 1, 0);
m_relay.post(user_command::settemperature, temperature, 0.0, 1, 0);
is_open = false;
}
}
void ui::time_panel::open()
{
auto &data = simulation::Time.data();
time = (float)data.wHour + (float)data.wMinute / 60.0f;
yearday = simulation::Time.year_day();
fog = Global.fFogEnd;
overcast = Global.Overcast;
temperature = Global.AirTemperature;
is_open = true;
}

21
widgets/time.h Normal file
View File

@@ -0,0 +1,21 @@
#include "uilayer.h"
#include "translation.h"
#include "command.h"
namespace ui {
class time_panel : public ui_panel {
command_relay m_relay;
float time;
int yearday;
float fog;
float overcast;
float temperature;
public:
time_panel();
void render_contents() override;
void open();
};
}