diff --git a/Driver.cpp b/Driver.cpp index 0dc78d53..6896add6 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -6296,7 +6296,7 @@ std::string TController::Relation() const return TrainParams->ShowRelation(); }; -std::string TController::TrainName() const +const std::string& TController::TrainName() const { // zwraca numer pociągu return TrainParams->TrainName; }; diff --git a/Driver.h b/Driver.h index 7aad9018..c3db2516 100644 --- a/Driver.h +++ b/Driver.h @@ -380,9 +380,9 @@ private: // timetable // methods public: - std::string TrainName() const; + const std::string &TrainName() const; private: - std::string Relation() const; + std::string Relation() const; Mtable::TTrainParameters const * TrainTimetable() const; int StationIndex() const; int StationCount() const; diff --git a/DynObj.h b/DynObj.h index 0f75ce5b..13a8cdbd 100644 --- a/DynObj.h +++ b/DynObj.h @@ -159,7 +159,7 @@ struct material_data { class TDynamicObject { // klasa pojazdu - friend opengl_renderer; + friend opengl_renderer; public: static bool bDynamicRemove; // moved from ground @@ -185,7 +185,7 @@ public: // parametry położenia pojazdu dostępne publicznie std::string asTrack; // nazwa toru początkowego; wywalić? std::string asDestination; // dokąd pojazd ma być kierowany "(stacja):(tor)" - Math3D::matrix4x4 mMatrix; // macierz przekształcenia do renderowania modeli + Math3D::matrix4x4 mMatrix; // macierz przekształcenia do renderowania modeli TMoverParameters *MoverParameters; // parametry fizyki ruchu oraz przeliczanie TDynamicObject *NextConnected; // pojazd podłączony od strony sprzęgu 1 (kabina -1) TDynamicObject *PrevConnected; // pojazd podłączony od strony sprzęgu 0 (kabina 1) @@ -362,7 +362,7 @@ private: sound_source rsEngageSlippery { sound_placement::engine }; // moved from cab void position( glm::vec3 const Location ); - void render( TMoverParameters const &Vehicle, double const Deltatime ); + void render( TMoverParameters const &Vehicle, double const Deltatime ); }; // methods @@ -450,10 +450,10 @@ private: exchange_data m_exchange; // state of active load exchange procedure, if any exchange_sounds m_exchangesounds; // sounds associated with the load exchange - bool renderme; // yB - czy renderowac + bool renderme; // yB - czy renderowac float ModCamRot; int iInventory[ 2 ] { 0, 0 }; // flagi bitowe posiadanych submodeli (np. świateł) - bool btnOn; // ABu: czy byly uzywane buttony, jesli tak, to po renderingu wylacz + bool btnOn; // ABu: czy byly uzywane buttony, jesli tak, to po renderingu wylacz // bo ten sam model moze byc jeszcze wykorzystany przez inny obiekt! public: diff --git a/Event.cpp b/Event.cpp index c6196db8..ba7a7f85 100644 --- a/Event.cpp +++ b/Event.cpp @@ -2230,3 +2230,15 @@ event_manager::export_as_text( std::ostream &Output ) const { } } } + +std::vector event_manager::find_eventlaunchers(glm::vec2 center, float radius) const { + std::vector results; + + for (auto &launcher : m_launchers.sequence()) { + glm::dvec3 location = launcher->location(); + if (glm::distance2(glm::vec2(location.x, location.z), center) < radius) + results.push_back(launcher); + } + + return results; +} diff --git a/Event.h b/Event.h index 0ed2fad2..b4cf44e3 100644 --- a/Event.h +++ b/Event.h @@ -615,6 +615,9 @@ public: // sends basic content of the class in legacy (text) format to provided stream void export_as_text( std::ostream &Output ) const; + // returns all eventlaunchers in radius ignoring height + std::vector + find_eventlaunchers(glm::vec2 center, float radius) const; private: // types diff --git a/driveruilayer.cpp b/driveruilayer.cpp index 7d97298d..9e9b8b92 100644 --- a/driveruilayer.cpp +++ b/driveruilayer.cpp @@ -44,7 +44,7 @@ driver_ui::driver_ui() { } void driver_ui::render_menu_contents() { - ui_layer::render_menu_contents(); + ui_layer::render_menu_contents(); if (ImGui::BeginMenu(locale::strings[locale::string::ui_mode_windows].c_str())) { diff --git a/driveruipanels.cpp b/driveruipanels.cpp index 4002a01f..692ab742 100644 --- a/driveruipanels.cpp +++ b/driveruipanels.cpp @@ -175,7 +175,7 @@ timetable_panel::update() { auto *vehicle { ( false == FreeFlyModeFlag ? controlled : camera.m_owner != nullptr ? camera.m_owner : - std::get( simulation::Region->find_vehicle( camera.Pos, 20, false, false ) ) ) }; // w trybie latania lokalizujemy wg mapy + std::get( simulation::Region->find_vehicle( camera.Pos, 20, false, false ) ) ) }; // w trybie latania lokalizujemy wg mapy if( vehicle == nullptr ) { return; } // if the nearest located vehicle doesn't have a direct driver, try to query its owner @@ -313,7 +313,7 @@ debug_panel::update() { m_scenariolines.clear(); m_eventqueuelines.clear(); m_cameralines.clear(); - m_rendererlines.clear(); + m_rendererlines.clear(); update_section_vehicle( m_vehiclelines ); update_section_engine( m_enginelines ); @@ -322,7 +322,7 @@ debug_panel::update() { update_section_scenario( m_scenariolines ); update_section_eventqueue( m_eventqueuelines ); update_section_camera( m_cameralines ); - update_section_renderer( m_rendererlines ); + update_section_renderer( m_rendererlines ); } void @@ -348,17 +348,17 @@ debug_panel::render() { } // sections ImGui::Separator(); - render_section( "Vehicle", m_vehiclelines ); - render_section( "Vehicle Engine", m_enginelines ); - render_section( "Vehicle AI", m_ailines ); - render_section( "Vehicle Scan Table", m_scantablelines ); - render_section( "Scenario", m_scenariolines ); - if( true == render_section( "Scenario Event Queue", m_eventqueuelines ) ) { + render_section( "Vehicle", m_vehiclelines ); + render_section( "Vehicle Engine", m_enginelines ); + render_section( "Vehicle AI", m_ailines ); + render_section( "Vehicle Scan Table", m_scantablelines ); + render_section( "Scenario", m_scenariolines ); + if( true == render_section( "Scenario Event Queue", m_eventqueuelines ) ) { // event queue filter ImGui::Checkbox( "By This Vehicle Only", &m_eventqueueactivevehicleonly ); } - render_section( "Camera", m_cameralines ); - render_section( "Gfx Renderer", m_rendererlines ); + render_section( "Camera", m_cameralines ); + render_section( "Gfx Renderer", m_rendererlines ); // toggles ImGui::Separator(); ImGui::Checkbox( "Debug Mode", &DebugModeFlag ); @@ -367,7 +367,7 @@ debug_panel::render() { ImGui::Indent(); ImGui::Checkbox( "Draw normal traction", - &GfxRenderer.settings.force_normal_traction_render ); + &GfxRenderer.settings.force_normal_traction_render ); ImGui::Unindent(); } } @@ -839,7 +839,7 @@ debug_panel::update_section_camera( std::vector &Output ) { void debug_panel::update_section_renderer( std::vector &Output ) { - // gfx renderer data + // gfx renderer data auto textline = "FoV: " + to_string( Global.FieldOfView / Global.ZoomFactor, 1 ) + ", Draw range x " + to_string( Global.fDistanceFactor, 1 ) @@ -861,7 +861,7 @@ debug_panel::update_section_renderer( std::vector &Output ) { Output.emplace_back( textline, Global.UITextColor ); - // renderer stats + // renderer stats Output.emplace_back( GfxRenderer.info_times(), Global.UITextColor ); Output.emplace_back( GfxRenderer.info_stats(), Global.UITextColor ); } diff --git a/driveruipanels.h b/driveruipanels.h index 9df28d76..f118110a 100644 --- a/driveruipanels.h +++ b/driveruipanels.h @@ -46,7 +46,7 @@ public: : ui_panel( Name, Isopen ) {} void update() override; - void render() override; + void render() override; private: // types @@ -98,5 +98,5 @@ public: : ui_panel( Name, Isopen ) {} void update() override; - void render() override; + void render() override; }; diff --git a/editoruipanels.cpp b/editoruipanels.cpp index 3345c773..517d36cc 100644 --- a/editoruipanels.cpp +++ b/editoruipanels.cpp @@ -262,7 +262,7 @@ itemproperties_panel::render() { ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), line.data.c_str() ); } // group section - render_group(); + render_group(); } ImGui::End(); } diff --git a/editoruipanels.h b/editoruipanels.h index efd6f8cd..9b2b723a 100644 --- a/editoruipanels.h +++ b/editoruipanels.h @@ -20,12 +20,12 @@ public: {} void update( scene::basic_node const *Node ); - void render() override; + void render() override; private: // methods void update_group(); - bool render_group(); + bool render_group(); // members scene::basic_node const *m_node { nullptr }; // scene node bound to the panel diff --git a/imgui/imgui.cpp b/imgui/imgui.cpp index e6a9bc1a..f410ad83 100644 --- a/imgui/imgui.cpp +++ b/imgui/imgui.cpp @@ -209,7 +209,7 @@ CODE // At this point you've got the texture data and you need to upload that your your graphic system: // After we have created the texture, store its pointer/identifier (_in whichever format your engine uses_) in 'io.Fonts->TexID'. - // This will be passed back to your via the renderer. Basically ImTextureID == void*. Read FAQ below for details about ImTextureID. + // This will be passed back to your via the renderer. Basically ImTextureID == void*. Read FAQ below for details about ImTextureID. MyTexture* texture = MyEngine::CreateTextureFromMemoryPixels(pixels, width, height, TEXTURE_TYPE_RGBA32) io.Fonts->TexID = (void*)texture; @@ -235,7 +235,7 @@ CODE MyGameRender(); // may use any ImGui functions as well! // Render imgui, swap buffers - // (You want to try calling EndFrame/Render as late as you can, to be able to use imgui in your own game rendering code) + // (You want to try calling EndFrame/Render as late as you can, to be able to use imgui in your own game rendering code) ImGui::EndFrame(); ImGui::Render(); ImDrawData* draw_data = ImGui::GetDrawData(); @@ -250,7 +250,7 @@ CODE void void MyImGuiRenderFunction(ImDrawData* draw_data) { - // TODO: Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + // TODO: Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled // TODO: Setup viewport using draw_data->DisplaySize // TODO: Setup orthographic projection matrix cover draw_data->DisplayPos to draw_data->DisplayPos + draw_data->DisplaySize // TODO: Setup shader: vertex { float2 pos, float2 uv, u32 color }, fragment shader sample color from 1 texture, multiply by vertex color. @@ -453,9 +453,9 @@ CODE - 2015/08/05 (1.44) - split imgui.cpp into extra files: imgui_demo.cpp imgui_draw.cpp imgui_internal.h that you need to add to your project. - 2015/07/18 (1.44) - fixed angles in ImDrawList::PathArcTo(), PathArcToFast() (introduced in 1.43) being off by an extra PI for no justifiable reason - 2015/07/14 (1.43) - add new ImFontAtlas::AddFont() API. For the old AddFont***, moved the 'font_no' parameter of ImFontAtlas::AddFont** functions to the ImFontConfig structure. - you need to render your textured triangles with bilinear filtering to benefit from sub-pixel positioning of text. + you need to render your textured triangles with bilinear filtering to benefit from sub-pixel positioning of text. - 2015/07/08 (1.43) - switched rendering data to use indexed rendering. this is saving a fair amount of CPU/GPU and enables us to get anti-aliasing for a marginal cost. - this necessary change will break your rendering function! the fix should be very easy. sorry for that :( + this necessary change will break your rendering function! the fix should be very easy. sorry for that :( - if you are using a vanilla copy of one of the imgui_impl_XXXX.cpp provided in the example, you just need to update your copy and you can ignore the rest. - the signature of the io.RenderDrawListsFn handler has changed! old: ImGui_XXXX_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) @@ -463,8 +463,8 @@ CODE argument: 'cmd_lists' becomes 'draw_data->CmdLists', 'cmd_lists_count' becomes 'draw_data->CmdListsCount' ImDrawList: 'commands' becomes 'CmdBuffer', 'vtx_buffer' becomes 'VtxBuffer', 'IdxBuffer' is new. ImDrawCmd: 'vtx_count' becomes 'ElemCount', 'clip_rect' becomes 'ClipRect', 'user_callback' becomes 'UserCallback', 'texture_id' becomes 'TextureId'. - - each ImDrawList now contains both a vertex buffer and an index buffer. For each command, render ElemCount/3 triangles using indices from the index buffer. - - if you REALLY cannot render indexed primitives, you can call the draw_data->DeIndexAllBuffers() method to de-index the buffers. This is slow and a waste of CPU/GPU. Prefer using indexed rendering! + - each ImDrawList now contains both a vertex buffer and an index buffer. For each command, render ElemCount/3 triangles using indices from the index buffer. + - if you REALLY cannot render indexed primitives, you can call the draw_data->DeIndexAllBuffers() method to de-index the buffers. This is slow and a waste of CPU/GPU. Prefer using indexed rendering! - refer to code in the examples/ folder or ask on the GitHub if you are unsure of how to upgrade. please upgrade! - 2015/07/10 (1.43) - changed SameLine() parameters from int to float. - 2015/07/02 (1.42) - renamed SetScrollPosHere() to SetScrollFromCursorPos(). Kept inline redirection function (will obsolete). @@ -497,7 +497,7 @@ CODE became: unsigned char* pixels; int width, height; io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); <..Upload texture to GPU>; io.Fonts->TexId = YourTextureIdentifier; you now more flexibility to load multiple TTF fonts and manage the texture buffer for internal needs. it is now recommended that you sample the font texture with bilinear interpolation. - (1.30) - added texture identifier in ImDrawCmd passed to your render function (we can now render images). make sure to set io.Fonts->TexID. + (1.30) - added texture identifier in ImDrawCmd passed to your render function (we can now render images). make sure to set io.Fonts->TexID. (1.30) - removed IO.PixelCenterOffset (unnecessary, can be handled in user projection matrix) (1.30) - removed ImGui::IsItemFocused() in favor of ImGui::IsItemActive() which handles all widgets - 2014/12/10 (1.18) - removed SetNewWindowDefaultPos() in favor of new generic API SetNextWindowPos(pos, ImGuiSetCondition_FirstUseEver) @@ -539,15 +539,15 @@ CODE Please read documentations or tutorials on your graphics API to understand how to display textures on the screen before moving onward. Long explanation: - - Dear ImGui's job is to create "meshes", defined in a renderer-agnostic format made of draw commands and vertices. - At the end of the frame those meshes (ImDrawList) will be displayed by your rendering function. They are made up of textured polygons and the code - to render them is generally fairly short (a few dozen lines). In the examples/ folder we provide functions for popular graphics API (OpenGL, DirectX, etc.). - - Each rendering function decides on a data type to represent "textures". The concept of what is a "texture" is entirely tied to your underlying engine/graphics API. + - Dear ImGui's job is to create "meshes", defined in a renderer-agnostic format made of draw commands and vertices. + At the end of the frame those meshes (ImDrawList) will be displayed by your rendering function. They are made up of textured polygons and the code + to render them is generally fairly short (a few dozen lines). In the examples/ folder we provide functions for popular graphics API (OpenGL, DirectX, etc.). + - Each rendering function decides on a data type to represent "textures". The concept of what is a "texture" is entirely tied to your underlying engine/graphics API. We carry the information to identify a "texture" in the ImTextureID type. ImTextureID is nothing more that a void*, aka 4/8 bytes worth of data: just enough to store 1 pointer or 1 integer of your choice. - Dear ImGui doesn't know or understand what you are storing in ImTextureID, it merely pass ImTextureID values until they reach your rendering function. + Dear ImGui doesn't know or understand what you are storing in ImTextureID, it merely pass ImTextureID values until they reach your rendering function. - In the examples/ bindings, for each graphics API binding we decided on a type that is likely to be a good representation for specifying - an image from the end-user perspective. This is what the _examples_ rendering functions are using: + an image from the end-user perspective. This is what the _examples_ rendering functions are using: OpenGL: ImTextureID = GLuint (see ImGui_ImplGlfwGL3_RenderDrawData() function in imgui_impl_glfw_gl3.cpp) DirectX9: ImTextureID = LPDIRECT3DTEXTURE9 (see ImGui_ImplDX9_RenderDrawData() function in imgui_impl_dx9.cpp) @@ -560,9 +560,9 @@ CODE - If you have a custom engine built over e.g. OpenGL, instead of passing GLuint around you may decide to use a high-level data type to carry information about the texture as well as how to display it (shaders, etc.). The decision of what to use as ImTextureID can always be made better knowing how your codebase is designed. If your engine has high-level data types for "textures" and "material" then you may want to use them. - If you are starting with OpenGL or DirectX or Vulkan and haven't built much of a rendering engine over them, keeping the default ImTextureID + If you are starting with OpenGL or DirectX or Vulkan and haven't built much of a rendering engine over them, keeping the default ImTextureID representation suggested by the example bindings is probably the best choice. - (Advanced users may also decide to keep a low-level type in ImTextureID, and use ImDrawList callback and pass information to their renderer) + (Advanced users may also decide to keep a low-level type in ImTextureID, and use ImDrawList callback and pass information to their renderer) User code may do: @@ -570,7 +570,7 @@ CODE MyTexture* texture = g_CoffeeTableTexture; ImGui::Image((void*)texture, ImVec2(texture->Width, texture->Height)); - The renderer function called after ImGui::Render() will receive that same value that the user code passed: + The renderer function called after ImGui::Render() will receive that same value that the user code passed: // Cast ImTextureID / void* stored in the draw command as our texture type MyTexture* texture = (MyTexture*)pcmd->TextureId; @@ -596,11 +596,11 @@ CODE glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image_width, image_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data); - // Now that we have an OpenGL texture, assuming our imgui rendering function (imgui_impl_xxx.cpp file) takes GLuint as ImTextureID, we can display it: + // Now that we have an OpenGL texture, assuming our imgui rendering function (imgui_impl_xxx.cpp file) takes GLuint as ImTextureID, we can display it: ImGui::Image((void*)(intptr_t)my_opengl_texture, ImVec2(my_image_width, my_image_height)); C/C++ tip: a void* is pointer-sized storage. You may safely store any pointer or integer into it by casting your value to ImTexture / void*, and vice-versa. - Because both end-points (user code and rendering function) are under your control, you know exactly what is stored inside the ImTexture / void*. + Because both end-points (user code and rendering function) are under your control, you know exactly what is stored inside the ImTexture / void*. Examples: GLuint my_tex = XXX; @@ -736,7 +736,7 @@ CODE ImGuiIO& io = ImGui::GetIO(); io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels); io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8() - (default is ProggyClean.ttf, rendered at size 13, embedded in dear imgui's source code) + (default is ProggyClean.ttf, rendered at size 13, embedded in dear imgui's source code) New programmers: remember that in C/C++ and most programming languages if you want to use a backslash \ within a string literal, you need to write it double backslash "\\": @@ -1002,7 +1002,7 @@ ImGuiStyle::ImGuiStyle() ButtonTextAlign = ImVec2(0.5f,0.5f);// Alignment of button text when button is larger than text. DisplayWindowPadding = ImVec2(20,20); // Window position are clamped to be visible within the display area by at least this amount. Only applies to regular windows. DisplaySafeAreaPadding = ImVec2(3,3); // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows. - MouseCursorScale = 1.0f; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later. + MouseCursorScale = 1.0f; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later. AntiAliasedLines = true; // Enable anti-aliasing on lines/borders. Disable if you are really short on CPU/GPU. AntiAliasedFill = true; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. @@ -2154,7 +2154,7 @@ void ImGui::RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, cons if (clip_rect) // If we had no explicit clipping rectangle then pos==clip_min need_clipping |= (pos.x < clip_min->x) || (pos.y < clip_min->y); - // Align whole block. We should defer that to the better rendering function when we'll have support for individual line alignment. + // Align whole block. We should defer that to the better rendering function when we'll have support for individual line alignment. if (align.x > 0.0f) pos.x = ImMax(pos.x, pos.x + (pos_max.x - pos.x - text_size.x) * align.x); if (align.y > 0.0f) pos.y = ImMax(pos.y, pos.y + (pos_max.y - pos.y - text_size.y) * align.y); @@ -3145,7 +3145,7 @@ void ImGui::NewFrame() g.OverlayDrawList.PushClipRectFullScreen(); g.OverlayDrawList.Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0); - // Mark rendering data as invalid to prevent user who may have a handle on it to use it + // Mark rendering data as invalid to prevent user who may have a handle on it to use it g.DrawData.Clear(); // Drag and drop keep the source ID alive so even if the source disappear our state is consistent @@ -3243,7 +3243,7 @@ void ImGui::NewFrame() g.CurrentPopupStack.resize(0); ClosePopupsOverWindow(g.NavWindow); - // Create implicit window - we will only render it if the user has added something to it. + // Create implicit window - we will only render it if the user has added something to it. // We don't use "Debug" to avoid colliding with user trying to create a "Debug" window with custom flags. SetNextWindowSize(ImVec2(400,400), ImGuiCond_FirstUseEver); Begin("Debug##Default"); @@ -3375,9 +3375,9 @@ static void AddDrawListToDrawData(ImVector* out_list, ImDrawList* d // If this assert triggers because you are drawing lots of stuff manually: // A) Make sure you are coarse clipping, because ImDrawList let all your vertices pass. You can use the Metrics window to inspect draw list contents. // B) If you need/want meshes with more than 64K vertices, uncomment the '#define ImDrawIdx unsigned int' line in imconfig.h to set the index size to 4 bytes. - // You'll need to handle the 4-bytes indices to your renderer. For example, the OpenGL example code detect index size at compile-time by doing: + // You'll need to handle the 4-bytes indices to your renderer. For example, the OpenGL example code detect index size at compile-time by doing: // glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); - // Your own engine or render API may use different parameters or function calls to specify index sizes. 2 and 4 bytes indices are generally supported by most API. + // Your own engine or render API may use different parameters or function calls to specify index sizes. 2 and 4 bytes indices are generally supported by most API. // C) If for some reason you cannot use 4 bytes indices or don't want to, a workaround is to call BeginChild()/EndChild() before reaching the 64K limit to split your draw commands in multiple draw lists. if (sizeof(ImDrawIdx) == 2) IM_ASSERT(draw_list->_VtxCurrentIdx < (1 << 16) && "Too many vertices in ImDrawList using 16-bit indices. Read comment above"); @@ -3389,12 +3389,12 @@ static void AddWindowToDrawData(ImVector* out_render_list, ImGuiWin { ImGuiContext& g = *GImGui; g.IO.MetricsRenderWindows++; - AddDrawListToDrawData(out_render_list, window->DrawList); + AddDrawListToDrawData(out_render_list, window->DrawList); for (int i = 0; i < window->DC.ChildWindows.Size; i++) { ImGuiWindow* child = window->DC.ChildWindows[i]; if (IsWindowActiveAndVisible(child)) // clipped children may have been marked not active - AddWindowToDrawData(out_render_list, child); + AddWindowToDrawData(out_render_list, child); } } @@ -3573,21 +3573,21 @@ void ImGui::Render() ImGui::EndFrame(); g.FrameCountRendered = g.FrameCount; - // Gather ImDrawList to render (for each active window) + // Gather ImDrawList to render (for each active window) g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = g.IO.MetricsRenderWindows = 0; g.DrawDataBuilder.Clear(); - ImGuiWindow* windows_to_render_front_most[2]; - windows_to_render_front_most[0] = (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus)) ? g.NavWindowingTarget->RootWindow : NULL; - windows_to_render_front_most[1] = g.NavWindowingTarget ? g.NavWindowingList : NULL; + ImGuiWindow* windows_to_render_front_most[2]; + windows_to_render_front_most[0] = (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus)) ? g.NavWindowingTarget->RootWindow : NULL; + windows_to_render_front_most[1] = g.NavWindowingTarget ? g.NavWindowingList : NULL; for (int n = 0; n != g.Windows.Size; n++) { ImGuiWindow* window = g.Windows[n]; - if (IsWindowActiveAndVisible(window) && (window->Flags & ImGuiWindowFlags_ChildWindow) == 0 && window != windows_to_render_front_most[0] && window != windows_to_render_front_most[1]) + if (IsWindowActiveAndVisible(window) && (window->Flags & ImGuiWindowFlags_ChildWindow) == 0 && window != windows_to_render_front_most[0] && window != windows_to_render_front_most[1]) AddWindowToDrawDataSelectLayer(window); } - for (int n = 0; n < IM_ARRAYSIZE(windows_to_render_front_most); n++) - if (windows_to_render_front_most[n] && IsWindowActiveAndVisible(windows_to_render_front_most[n])) // NavWindowingTarget is always temporarily displayed as the front-most window - AddWindowToDrawDataSelectLayer(windows_to_render_front_most[n]); + for (int n = 0; n < IM_ARRAYSIZE(windows_to_render_front_most); n++) + if (windows_to_render_front_most[n] && IsWindowActiveAndVisible(windows_to_render_front_most[n])) // NavWindowingTarget is always temporarily displayed as the front-most window + AddWindowToDrawDataSelectLayer(windows_to_render_front_most[n]); g.DrawDataBuilder.FlattenIntoSingleLayer(); // Draw software mouse cursor if requested @@ -5034,7 +5034,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) //window->DrawList->AddRect(window->InnerRect.Min, window->InnerRect.Max, IM_COL32_WHITE); // Inner clipping rectangle - // Force round operator last to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result. + // Force round operator last to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result. window->InnerClipRect.Min.x = ImFloor(0.5f + window->InnerMainRect.Min.x + ImMax(0.0f, ImFloor(window->WindowPadding.x*0.5f - window->WindowBorderSize))); window->InnerClipRect.Min.y = ImFloor(0.5f + window->InnerMainRect.Min.y); window->InnerClipRect.Max.x = ImFloor(0.5f + window->InnerMainRect.Max.x - ImMax(0.0f, ImFloor(window->WindowPadding.x*0.5f - window->WindowBorderSize))); @@ -5070,7 +5070,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->HiddenFramesRegular = 1; } - // Don't render if style alpha is 0.0 at the time of Begin(). This is arbitrary and inconsistent but has been there for a long while (may remove at some point) + // Don't render if style alpha is 0.0 at the time of Begin(). This is arbitrary and inconsistent but has been there for a long while (may remove at some point) if (style.Alpha <= 0.0f) window->HiddenFramesRegular = 1; @@ -7514,7 +7514,7 @@ static void ImGui::NavUpdateWindowing() g.NavWindowingHighlightAlpha = 1.0f; } - // Single press toggles NavLayer, long press with L/R apply actual focus on release (until then the window was merely rendered front-most) + // Single press toggles NavLayer, long press with L/R apply actual focus on release (until then the window was merely rendered front-most) if (!IsNavInputDown(ImGuiNavInput_Menu)) { g.NavWindowingToggleLayer &= (g.NavWindowingHighlightAlpha < 1.0f); // Once button was held long enough we don't consider it a tap-to-toggle-layer press anymore. @@ -7924,7 +7924,7 @@ void ImGui::EndColumns() window->DrawList->AddLine(ImVec2(xi, ImMax(y1 + 1.0f, window->ClipRect.Min.y)), ImVec2(xi, ImMin(y2, window->ClipRect.Max.y)), col); } - // Apply dragging after drawing the column lines, so our rendered lines are in sync with how items were displayed during the frame. + // Apply dragging after drawing the column lines, so our rendered lines are in sync with how items were displayed during the frame. if (dragging_column != -1) { if (!columns->IsBeingResized) diff --git a/scene.h b/scene.h index dfc71b91..269f0ce7 100644 --- a/scene.h +++ b/scene.h @@ -63,7 +63,7 @@ struct scratch_data { // TBD, TODO: replace with quadtree scheme? class basic_cell { - friend opengl_renderer; + friend opengl_renderer; public: // constructors @@ -150,7 +150,7 @@ public: // sets center point of the cell void center( glm::dvec3 Center ); - // generates renderable version of held non-instanced geometry in specified geometry bank + // generates renderable version of held non-instanced geometry in specified geometry bank void create_geometry( gfx::geometrybank_handle const &Bank ); void create_map_geometry(std::vector &Bank); @@ -193,7 +193,7 @@ private: } m_directories; // animation of owned items (legacy code, clean up along with track refactoring) bool m_geometrycreated { false }; - unsigned int m_framestamp { 0 }; // id of last rendered gfx frame + unsigned int m_framestamp { 0 }; // id of last rendered gfx frame TTrack *tTrackAnim = nullptr; // obiekty do przeliczenia animacji command_relay m_relay; }; @@ -201,7 +201,7 @@ private: // basic scene partitioning structure, holds terrain geometry and collection of cells class basic_section { - friend opengl_renderer; + friend opengl_renderer; public: // constructors @@ -274,7 +274,7 @@ public: // sets center point of the section void center( glm::dvec3 Center ); - // generates renderable version of held non-instanced geometry + // generates renderable version of held non-instanced geometry void create_geometry(); void create_map_geometry(const gfx::geometrybank_handle handle); @@ -303,7 +303,7 @@ private: cell_array m_cells; // partitioning scheme shapenode_sequence m_shapes; // large pieces of opaque geometry and (legacy) terrain // TODO: implement dedicated, higher fidelity, fixed resolution terrain mesh item - // gfx renderer data + // gfx renderer data gfx::geometrybank_handle m_geometrybank; bool m_geometrycreated { false }; @@ -313,7 +313,7 @@ private: // top-level of scene spatial structure, holds collection of sections class basic_region { - friend opengl_renderer; + friend opengl_renderer; public: // constructors diff --git a/uilayer.cpp b/uilayer.cpp index b28c23da..35b034b2 100644 --- a/uilayer.cpp +++ b/uilayer.cpp @@ -314,7 +314,7 @@ void ui_layer::render_panels() { for (auto *panel : m_panels) { - panel->render(); + panel->render(); } } diff --git a/uilayer.h b/uilayer.h index 597582a1..29b39b82 100644 --- a/uilayer.h +++ b/uilayer.h @@ -24,8 +24,8 @@ public: ui_panel( std::string const &Identifier, bool const Isopen ); // methods virtual void update() {}; - virtual void render(); - virtual void render_contents(); + virtual void render(); + virtual void render_contents(); // temporary access // types struct text_line { @@ -47,7 +47,7 @@ public: std::deque text_lines; int window_flags = -1; - std::string get_name() { return name; } + const std::string& get_name() { return name; } protected: // members @@ -60,13 +60,13 @@ public: bool is_expanded { false }; - void render_contents() override; + void render_contents() override; }; class ui_log_panel : public ui_panel { using ui_panel::ui_panel; - void render_contents() override; + void render_contents() override; }; class ui_layer { @@ -107,7 +107,7 @@ public: update(); // draws requested UI elements void - render(); + render(); // static void @@ -146,19 +146,19 @@ protected: private: // methods - // render() subclass details + // render() subclass details virtual void - render_() {}; + render_() {}; // draws background quad with specified earlier texture void - render_background(); + render_background(); // draws a progress bar in defined earlier state void - render_progress(); + render_progress(); void - render_tooltip(); - void render_panels(); + render_tooltip(); + void render_panels(); void render_menu(); diff --git a/widgets/map.cpp b/widgets/map.cpp index 5f354f28..65da10b1 100644 --- a/widgets/map.cpp +++ b/widgets/map.cpp @@ -58,74 +58,12 @@ float ui::map_panel::get_vehicle_rotation() { const TDynamicObject *vehicle = simulation::Train->Dynamic(); glm::vec3 front = glm::dvec3(vehicle->VectorFront()) * (vehicle->DirectionGet() > 0 ? 1.0 : -1.0); - glm::vec2 f2(front.x, front.z); glm::vec2 north_ptr(0.0f, 1.0f); - return glm::atan(f2.y, f2.x) - glm::atan(north_ptr.y, north_ptr.x); + return glm::atan(front.z, front.x) - glm::atan(north_ptr.y, north_ptr.x); } -void ui::map_panel::render_contents() -{ - if (!init_done) - return; - - scene::basic_region *Region = simulation::Region; - - float prevzoom = zoom; - - if (ImGui::Button("-")) - zoom /= 2; - ImGui::SameLine(); - if (ImGui::Button("+")) - zoom *= 2; - ImGui::SameLine(); - - float x = zoom / prevzoom; - translate *= x; - - glm::mat4 transform; - transform[0][0] = -1.0f; - - static int mode = 0; - ImGui::RadioButton("manual", &mode, 0); ImGui::SameLine(); - ImGui::RadioButton("cam", &mode, 1); ImGui::SameLine(); - ImGui::RadioButton("vehicle", &mode, 2); - - ImVec2 size = ImGui::GetContentRegionAvail(); - - float aspectx = size.y / size.x; - float aspectz = size.x / size.y; - - if (aspectx > aspectz) - transform = glm::scale(transform, glm::vec3(aspectx, 1.0f, 1.0f)); - else - transform = glm::scale(transform, glm::vec3(1.0f, 1.0f, aspectz)); - - if (mode == 2 && simulation::Train && simulation::Train->Dynamic()) - { - float rot = get_vehicle_rotation(); - - transform = glm::rotate(transform, rot, glm::vec3(0.0f, 1.0f, 0.0f)); - - glm::dvec3 vpos = simulation::Train->Dynamic()->GetPosition(); - translate = glm::vec2(vpos.x, vpos.z) * -zoom; - } - else if (mode == 1) - { - float rot; - if (FreeFlyModeFlag) - rot = glm::pi() - Global.pCamera.Angle.y; - else - rot = get_vehicle_rotation() - Global.pCamera.Angle.y; - - transform = glm::rotate(transform, rot, glm::vec3(0.0f, 1.0f, 0.0f)); - - glm::dvec3 vpos = Global.pCamera.Pos; - translate = glm::vec2(vpos.x, vpos.z) * -zoom; - } - - transform = glm::translate(transform, glm::vec3(translate.x, 0.0f, translate.y)); - transform = glm::scale(transform, glm::vec3(zoom)); - +void ui::map_panel::render_map_texture(glm::mat4 transform, glm::vec2 surface_size) { + cFrustum frustum; frustum.calculate(transform, glm::mat4()); m_section_handles.clear(); @@ -134,10 +72,10 @@ void ui::map_panel::render_contents() { for (int column = 0; column < scene::EU07_REGIONSIDESECTIONCOUNT; column++) { - scene::basic_section *s = Region->get_section(row * scene::EU07_REGIONSIDESECTIONCOUNT + column); - if (s && frustum.sphere_inside(s->area().center, s->area().radius) > 0.f) + scene::basic_section *section = simulation::Region->get_section(row * scene::EU07_REGIONSIDESECTIONCOUNT + column); + if (section && frustum.sphere_inside(section->area().center, section->area().radius) > 0.f) { - const gfx::geometrybank_handle handle = s->get_map_geometry(); + const gfx::geometrybank_handle handle = section->get_map_geometry(); if (handle != null_handle) m_section_handles.push_back(handle); } @@ -162,46 +100,152 @@ void ui::map_panel::render_contents() m_shader->bind(); glLineWidth(1.5f); - glViewport(0, 0, size.x, size.y); + glViewport(0, 0, surface_size.x, surface_size.y); GfxRenderer.Draw_Geometry(m_section_handles.begin(), m_section_handles.end()); if (Global.iMultisampling) - m_fb->blit_from(m_msaa_fb.get(), size.x, size.y, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT0); + m_fb->blit_from(m_msaa_fb.get(), surface_size.x, surface_size.y, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT0); gl::framebuffer::unbind(); m_shader->unbind(); +} - ImVec2 origin = ImGui::GetCursorPos(); - ImGui::ImageButton(reinterpret_cast(m_tex->id), size, ImVec2(0, size.y / fb_size), ImVec2(size.x / fb_size, 0), 0); - if (mode == 0 && ImGui::IsItemHovered() && ImGui::IsMouseDragging()) - { - ImVec2 ivdelta = ImGui::GetMouseDragDelta(); - ImGui::ResetMouseDragDelta(); - - glm::vec2 delta(ivdelta.x, ivdelta.y); - delta.x /= size.x; - delta.y /= size.y; - - translate -= delta * 2.0f; - } - +void ui::map_panel::render_labels(glm::mat4 transform, ImVec2 origin, glm::vec2 surface_size) +{ ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.7f, 1.0f, 0.7f, 1.0f)); for (TDynamicObject *vehicle : simulation::Vehicles.sequence()) { - if (vehicle->Prev()) + if (vehicle->Prev() || !vehicle->Mechanik) + continue; + if (vehicle->Mechanik->TrainName().empty()) continue; - glm::vec4 pos = transform * glm::vec4(glm::vec3(vehicle->GetPosition()), 1.0f); - if (glm::abs(pos.x) > 1.0f || glm::abs(pos.z) > 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) continue; - glm::vec2 textpos = (glm::vec2(pos.x, -pos.z) / 2.0f + 0.5f) * glm::vec2(size.x, size.y); + glm::vec2 gui_pos = (glm::vec2(ndc_pos.x, -ndc_pos.z) / 2.0f + 0.5f) * glm::vec2(surface_size.x, surface_size.y); + + TDynamicObject *veh = vehicle; const char *desc = vehicle->Mechanik->TrainName().c_str(); ImVec2 textsize = ImGui::CalcTextSize(desc); - ImGui::SetCursorPos(ImVec2(origin.x + textpos.x - textsize.x / 2.0f, - origin.y + textpos.y - textsize.y / 2.0f)); + ImGui::SetCursorPos(ImVec2(origin.x + gui_pos.x - textsize.x / 2.0f, + origin.y + gui_pos.y - textsize.y / 2.0f)); ImGui::TextUnformatted(desc); } ImGui::PopStyleColor(); } + +void ui::map_panel::render_contents() +{ + if (!init_done) + return; + + float prev_zoom = zoom; + + if (ImGui::Button("-")) + zoom /= 2; + ImGui::SameLine(); + + if (ImGui::Button("+")) + zoom *= 2; + ImGui::SameLine(); + + float x = zoom / prev_zoom; + translate *= x; + + glm::mat4 transform; + transform[0][0] = -1.0f; + + static enum { + MODE_MANUAL = 0, + MODE_CAMERA, + MODE_VEHICLE + } mode = MODE_MANUAL; + + ImGui::RadioButton("manual", (int*)&mode, 0); ImGui::SameLine(); + ImGui::RadioButton("cam", (int*)&mode, 1); ImGui::SameLine(); + ImGui::RadioButton("vehicle", (int*)&mode, 2); + + ImVec2 surface_size_im = ImGui::GetContentRegionAvail(); + glm::vec2 surface_size(surface_size_im.x, surface_size_im.y); + + float aspect = surface_size.y / surface_size.x; + + if (aspect > 1.0f / aspect) + transform = glm::scale(transform, glm::vec3(aspect, 1.0f, 1.0f)); + else + transform = glm::scale(transform, glm::vec3(1.0f, 1.0f, 1.0f / aspect)); + + if (mode == MODE_VEHICLE && simulation::Train) + { + float rotation = get_vehicle_rotation(); + + transform = glm::rotate(transform, rotation, glm::vec3(0.0f, 1.0f, 0.0f)); + + glm::dvec3 position = simulation::Train->Dynamic()->GetPosition(); + translate = glm::vec2(position.x, position.z) * -zoom; + } + if (mode == MODE_CAMERA) + { + float initial_rotation; + if (!FreeFlyModeFlag) + initial_rotation = get_vehicle_rotation(); + else + initial_rotation = glm::pi(); + + float rotation = initial_rotation - Global.pCamera.Angle.y; + + transform = glm::rotate(transform, rotation, glm::vec3(0.0f, 1.0f, 0.0f)); + + glm::dvec3 position = Global.pCamera.Pos; + translate = glm::vec2(position.x, position.z) * -zoom; + } + + transform = glm::translate(transform, glm::vec3(translate.x, 0.0f, translate.y)); + transform = glm::scale(transform, glm::vec3(zoom)); + + render_map_texture(transform, surface_size); + + ImVec2 window_origin = ImGui::GetCursorPos(); + ImVec2 screen_origin = ImGui::GetCursorScreenPos(); + ImGui::ImageButton(reinterpret_cast(m_tex->id), surface_size_im, ImVec2(0, surface_size.y / fb_size), ImVec2(surface_size.x / fb_size, 0), 0); + + if (ImGui::IsItemHovered()) + { + if (mode == 0 && ImGui::IsMouseDragging(0)) { + WriteLog("drag"); + ImVec2 delta_im = ImGui::GetMouseDragDelta(); + ImGui::ResetMouseDragDelta(); + + glm::vec2 delta(delta_im.x, delta_im.y); + delta.x /= surface_size.x; + delta.y /= surface_size.y; + + translate -= delta * 2.0f; + } + if (ImGui::IsMouseClicked(1)) { + WriteLog("click"); + ImVec2 screen_pos = ImGui::GetMousePos(); + glm::vec2 surface_pos(screen_pos.x - screen_origin.x, screen_pos.y - screen_origin.y); + glm::vec2 ndc_pos = surface_pos / surface_size * 2.0f - 1.0f; + glm::vec3 world_pos = glm::inverse(transform) * glm::vec4(ndc_pos.x, 0.0f, -ndc_pos.y, 1.0f); + + std::vector launchers = simulation::Events.find_eventlaunchers(glm::vec2(world_pos.x, world_pos.z), 10.0f); + + for (auto launcher : launchers) { + command_relay relay; + if (!Global.shiftState && launcher->Event1) + relay.post(user_command::queueevent, (double)simulation::Events.GetEventId(launcher->Event1), 0.0, GLFW_PRESS, 0); + else if (launcher->Event2) + relay.post(user_command::queueevent, (double)simulation::Events.GetEventId(launcher->Event2), 0.0, GLFW_PRESS, 0); + } + + + WriteLog(std::to_string(world_pos.x) + "," + std::to_string(world_pos.z)); + } + } + + render_labels(transform, window_origin, surface_size); +} diff --git a/widgets/map.h b/widgets/map.h index 425b71ab..ae157391 100644 --- a/widgets/map.h +++ b/widgets/map.h @@ -10,7 +10,7 @@ namespace ui { class map_panel : public ui_panel { std::unique_ptr m_shader; std::unique_ptr m_msaa_fb; - std::unique_ptr m_msaa_rb; + std::unique_ptr m_msaa_rb; std::unique_ptr m_fb; std::unique_ptr m_tex; @@ -25,7 +25,8 @@ class map_panel : public ui_panel { glm::vec2 translate; float zoom = 1.0f / 1000.0f; float get_vehicle_rotation(); - cFrustum frustum; + void render_map_texture(glm::mat4 transform, glm::vec2 surface_size); + void render_labels(glm::mat4 transform, ImVec2 origin, glm::vec2 surface_size); bool init_done = false;