mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
imgui user interface implementation
This commit is contained in:
@@ -125,7 +125,7 @@ class TAnimAdvanced
|
||||
class TAnimModel : public scene::basic_node {
|
||||
|
||||
friend opengl_renderer;
|
||||
friend editor_ui;
|
||||
friend itemproperties_panel;
|
||||
|
||||
public:
|
||||
// constructors
|
||||
|
||||
@@ -33,6 +33,7 @@ class scenario_time;
|
||||
class TMoverParameters;
|
||||
class ui_layer;
|
||||
class editor_ui;
|
||||
class itemproperties_panel;
|
||||
class event_manager;
|
||||
class memory_table;
|
||||
class powergridsource_table;
|
||||
@@ -42,6 +43,7 @@ struct light_array;
|
||||
|
||||
namespace scene {
|
||||
struct node_data;
|
||||
class basic_node;
|
||||
}
|
||||
|
||||
namespace Mtable
|
||||
|
||||
24
Driver.cpp
24
Driver.cpp
@@ -321,7 +321,7 @@ bool TSpeedPos::Update()
|
||||
return false;
|
||||
};
|
||||
|
||||
std::string TSpeedPos::GetName()
|
||||
std::string TSpeedPos::GetName() const
|
||||
{
|
||||
if (iFlags & spTrack) // jeśli tor
|
||||
return trTrack->name();
|
||||
@@ -331,7 +331,7 @@ std::string TSpeedPos::GetName()
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string TSpeedPos::TableText()
|
||||
std::string TSpeedPos::TableText() const
|
||||
{ // pozycja tabelki pr?dko?ci
|
||||
if (iFlags & spEnabled)
|
||||
{ // o ile pozycja istotna
|
||||
@@ -1639,7 +1639,7 @@ TController::~TController()
|
||||
CloseLog();
|
||||
};
|
||||
|
||||
std::string TController::Order2Str(TOrders Order)
|
||||
std::string TController::Order2Str(TOrders Order) const
|
||||
{ // zamiana kodu rozkazu na opis
|
||||
if (Order & Change_direction)
|
||||
return "Change_direction"; // może być nałożona na inną i wtedy ma priorytet
|
||||
@@ -1674,9 +1674,9 @@ std::string TController::Order2Str(TOrders Order)
|
||||
return "Undefined!";
|
||||
}
|
||||
|
||||
std::string TController::OrderCurrent()
|
||||
std::string TController::OrderCurrent() const
|
||||
{ // pobranie aktualnego rozkazu celem wyświetlenia
|
||||
return std::to_string(OrderPos) + ". " + Order2Str(OrderList[OrderPos]);
|
||||
return "[" + std::to_string(OrderPos) + "] " + Order2Str(OrderList[OrderPos]);
|
||||
};
|
||||
|
||||
void TController::OrdersClear()
|
||||
@@ -2244,7 +2244,7 @@ void TController::SetVelocity(double NewVel, double NewVelNext, TStopReason r)
|
||||
VelNext = NewVelNext; // prędkość przy następnym obiekcie
|
||||
}
|
||||
|
||||
double TController::BrakeAccFactor()
|
||||
double TController::BrakeAccFactor() const
|
||||
{
|
||||
double Factor = 1.0;
|
||||
if( ( ActualProximityDist > fMinProximityDist )
|
||||
@@ -4916,7 +4916,7 @@ TController::UpdateSituation(double dt) {
|
||||
&& ( pVehicles[0]->fTrackBlock < 50.0 ) ) {
|
||||
// crude detection of edge case, if approaching another vehicle coast slowly until min distance
|
||||
// this should allow to bunch up trainsets more on sidings
|
||||
VelDesired = min_speed( VelDesired, 5.0 );
|
||||
VelDesired = min_speed( 5.0, VelDesired );
|
||||
}
|
||||
else {
|
||||
// hamowanie tak, aby stanąć
|
||||
@@ -4934,7 +4934,7 @@ TController::UpdateSituation(double dt) {
|
||||
else {
|
||||
// outside of max safe range
|
||||
AccDesired = AccPreferred;
|
||||
if( vel > min_speed( 10.0, VelDesired ) ) {
|
||||
if( vel > min_speed( (ActualProximityDist > 10.0 ? 10.0 : 5.0 ), VelDesired ) ) {
|
||||
// allow to coast at reasonably low speed
|
||||
auto const brakingdistance { fBrakeDist * braking_distance_multiplier( VelNext ) };
|
||||
auto const slowdowndistance { (
|
||||
@@ -6026,7 +6026,7 @@ TCommandType TController::BackwardScan()
|
||||
return TCommandType::cm_Unknown; // nic
|
||||
};
|
||||
|
||||
std::string TController::NextStop()
|
||||
std::string TController::NextStop() const
|
||||
{ // informacja o następnym zatrzymaniu, wyświetlane pod [F1]
|
||||
if (asNextStop == "[End of route]")
|
||||
return ""; // nie zawiera nazwy stacji, gdy dojechał do końca
|
||||
@@ -6130,7 +6130,7 @@ TController::TrainTimetable() const {
|
||||
return TrainParams;
|
||||
}
|
||||
|
||||
std::string TController::Relation()
|
||||
std::string TController::Relation() const
|
||||
{ // zwraca relację pociągu
|
||||
return TrainParams->ShowRelation();
|
||||
};
|
||||
@@ -6150,7 +6150,7 @@ int TController::StationIndex() const
|
||||
return TrainParams->StationIndex;
|
||||
};
|
||||
|
||||
bool TController::IsStop()
|
||||
bool TController::IsStop() const
|
||||
{ // informuje, czy jest zatrzymanie na najbliższej stacji
|
||||
return TrainParams->IsStop();
|
||||
};
|
||||
@@ -6181,7 +6181,7 @@ void TController::ControllingSet()
|
||||
mvControlling = pVehicle->ControlledFind()->MoverParameters; // poszukiwanie członu sterowanego
|
||||
};
|
||||
|
||||
std::string TController::TableText( std::size_t const Index )
|
||||
std::string TController::TableText( std::size_t const Index ) const
|
||||
{ // pozycja tabelki prędkości
|
||||
if( Index < sSpeedTable.size() ) {
|
||||
return sSpeedTable[ Index ].TableText();
|
||||
|
||||
18
Driver.h
18
Driver.h
@@ -154,8 +154,8 @@ class TSpeedPos
|
||||
fDist -= dist; }
|
||||
bool Set(TEvent *e, double d, TOrders order = Wait_for_orders);
|
||||
void Set(TTrack *t, double d, int f);
|
||||
std::string TableText();
|
||||
std::string GetName();
|
||||
std::string TableText() const;
|
||||
std::string GetName() const;
|
||||
bool IsProperSemaphor(TOrders order = Wait_for_orders);
|
||||
};
|
||||
|
||||
@@ -205,7 +205,7 @@ public:
|
||||
double fVelMax = -1.0; // maksymalna prędkość składu (sprawdzany każdy pojazd)
|
||||
public:
|
||||
double fBrakeDist = 0.0; // przybliżona droga hamowania
|
||||
double BrakeAccFactor();
|
||||
double BrakeAccFactor() const;
|
||||
double fBrakeReaction = 1.0; //opóźnienie zadziałania hamulca - czas w s / (km/h)
|
||||
double fAccThreshold = 0.0; // próg opóźnienia dla zadziałania hamulca
|
||||
double AbsAccS_pub = 0.0; // próg opóźnienia dla zadziałania hamulca
|
||||
@@ -349,11 +349,11 @@ private:
|
||||
void OrdersClear();
|
||||
void OrdersDump();
|
||||
TController( bool AI, TDynamicObject *NewControll, bool InitPsyche, bool primary = true );
|
||||
std::string OrderCurrent();
|
||||
std::string OrderCurrent() const;
|
||||
void WaitingSet(double Seconds);
|
||||
|
||||
private:
|
||||
std::string Order2Str(TOrders Order);
|
||||
std::string Order2Str(TOrders Order) const;
|
||||
void DirectionForward(bool forward);
|
||||
int OrderDirectionChange(int newdir, TMoverParameters *Vehicle);
|
||||
void Lights(int head, int rear);
|
||||
@@ -395,11 +395,11 @@ private:
|
||||
void TakeControl(bool yes);
|
||||
Mtable::TTrainParameters const * TrainTimetable() const;
|
||||
std::string TrainName() const;
|
||||
std::string Relation();
|
||||
std::string Relation() const;
|
||||
int StationCount() const;
|
||||
int StationIndex() const;
|
||||
bool IsStop();
|
||||
std::string NextStop();
|
||||
bool IsStop() const;
|
||||
std::string NextStop() const;
|
||||
inline
|
||||
bool Primary() const {
|
||||
return ( ( iDrivigFlags & movePrimary ) != 0 ); };
|
||||
@@ -411,7 +411,7 @@ private:
|
||||
TrackBlock() const;
|
||||
void MoveTo(TDynamicObject *to);
|
||||
void DirectionInitial();
|
||||
std::string TableText(std::size_t const Index);
|
||||
std::string TableText(std::size_t const Index) const;
|
||||
int CrossRoute(TTrack *tr);
|
||||
/*
|
||||
void RouteSwitch(int d);
|
||||
|
||||
2
Track.h
2
Track.h
@@ -128,7 +128,7 @@ class TTrack : public scene::basic_node {
|
||||
|
||||
friend opengl_renderer;
|
||||
// NOTE: temporary arrangement
|
||||
friend editor_ui;
|
||||
friend itemproperties_panel;
|
||||
|
||||
private:
|
||||
TIsolated * pIsolated = nullptr; // obwód izolowany obsługujący zajęcia/zwolnienia grupy torów
|
||||
|
||||
@@ -153,6 +153,8 @@ eu07_application::exit() {
|
||||
SafeDelete( simulation::Train );
|
||||
SafeDelete( simulation::Region );
|
||||
|
||||
ui_layer::shutdown();
|
||||
|
||||
glfwDestroyWindow( m_window );
|
||||
glfwTerminate();
|
||||
|
||||
|
||||
@@ -327,24 +327,12 @@ driver_mode::on_key( int const Key, int const Scancode, int const Action, int co
|
||||
|| ( Key == GLFW_KEY_RIGHT_ALT ) ) ) {
|
||||
// if the alt key was pressed toggle control picking mode and set matching cursor behaviour
|
||||
if( Action == GLFW_PRESS ) {
|
||||
|
||||
if( Global.ControlPicking ) {
|
||||
// switch off
|
||||
Application.get_cursor_pos( m_input.mouse_pickmodepos.x, m_input.mouse_pickmodepos.y );
|
||||
Application.set_cursor( GLFW_CURSOR_DISABLED );
|
||||
Application.set_cursor_pos( 0, 0 );
|
||||
}
|
||||
else {
|
||||
// enter picking mode
|
||||
Application.set_cursor_pos( m_input.mouse_pickmodepos.x, m_input.mouse_pickmodepos.y );
|
||||
Application.set_cursor( GLFW_CURSOR_NORMAL );
|
||||
}
|
||||
// actually toggle the mode
|
||||
Global.ControlPicking = !Global.ControlPicking;
|
||||
// toggle picking mode
|
||||
set_picking( !Global.ControlPicking );
|
||||
}
|
||||
}
|
||||
|
||||
if( Action != GLFW_RELEASE ) {
|
||||
if( Action == GLFW_PRESS ) {
|
||||
|
||||
OnKeyDown( Key );
|
||||
|
||||
@@ -737,7 +725,7 @@ driver_mode::OnKeyDown(int cKey) {
|
||||
// if (cKey!=VK_F4)
|
||||
return; // nie są przekazywane do pojazdu wcale
|
||||
}
|
||||
|
||||
/*
|
||||
if ((Global.iTextMode == GLFW_KEY_F12) ? (cKey >= '0') && (cKey <= '9') : false)
|
||||
{ // tryb konfiguracji debugmode (przestawianie kamery już wyłączone
|
||||
if (!Global.shiftState) // bez [Shift]
|
||||
@@ -757,14 +745,21 @@ driver_mode::OnKeyDown(int cKey) {
|
||||
// else if (cKey=='3') Global.iWriteLogEnabled^=4; //wypisywanie nazw torów
|
||||
}
|
||||
}
|
||||
else if( cKey == GLFW_KEY_ESCAPE ) {
|
||||
else */
|
||||
if( cKey == GLFW_KEY_ESCAPE ) {
|
||||
// toggle pause
|
||||
if( Global.iPause & 1 ) // jeśli pauza startowa
|
||||
Global.iPause &= ~1; // odpauzowanie, gdy po wczytaniu miało nie startować
|
||||
else if( !( Global.iMultiplayer & 2 ) ) // w multiplayerze pauza nie ma sensu
|
||||
if( Global.iPause & 1 ) {
|
||||
// jeśli pauza startowa
|
||||
// odpauzowanie, gdy po wczytaniu miało nie startować
|
||||
Global.iPause &= ~1;
|
||||
}
|
||||
else if( ( Global.iMultiplayer & 2 ) == 0 ) {
|
||||
// w multiplayerze pauza nie ma sensu
|
||||
Global.iPause ^= 2; // zmiana stanu zapauzowania
|
||||
if( Global.iPause ) {// jak pauza
|
||||
Global.iTextMode = GLFW_KEY_F1; // to wyświetlić zegar i informację
|
||||
if( ( Global.iPause & 2 )
|
||||
&& ( false == Global.ControlPicking ) ) {
|
||||
set_picking( true );
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -992,3 +987,21 @@ driver_mode::InOutKey( bool const Near )
|
||||
// update window title to reflect the situation
|
||||
Application.set_title( Global.AppName + " (" + ( train != nullptr ? train->Occupied()->Name : "" ) + " @ " + Global.SceneryFile + ")" );
|
||||
}
|
||||
|
||||
void
|
||||
driver_mode::set_picking( bool const Picking ) {
|
||||
|
||||
if( Picking ) {
|
||||
// enter picking mode
|
||||
Application.set_cursor_pos( m_input.mouse_pickmodepos.x, m_input.mouse_pickmodepos.y );
|
||||
Application.set_cursor( GLFW_CURSOR_NORMAL );
|
||||
}
|
||||
else {
|
||||
// switch off
|
||||
Application.get_cursor_pos( m_input.mouse_pickmodepos.x, m_input.mouse_pickmodepos.y );
|
||||
Application.set_cursor( GLFW_CURSOR_DISABLED );
|
||||
Application.set_cursor_pos( 0, 0 );
|
||||
}
|
||||
// actually toggle the mode
|
||||
Global.ControlPicking = Picking;
|
||||
}
|
||||
|
||||
@@ -73,6 +73,7 @@ private:
|
||||
void InOutKey( bool const Near = true );
|
||||
void FollowView( bool wycisz = true );
|
||||
void DistantView( bool const Near = false );
|
||||
void set_picking( bool const Picking );
|
||||
|
||||
// members
|
||||
drivermode_input m_input;
|
||||
|
||||
@@ -28,21 +28,18 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
driver_ui::driver_ui() {
|
||||
|
||||
clear_texts();
|
||||
/*
|
||||
UIHeader = std::make_shared<ui_panel>( 20, 20 ); // header ui panel
|
||||
UITable = std::make_shared<ui_panel>( 20, 100 ); // schedule or scan table
|
||||
UITranscripts = std::make_shared<ui_panel>( 85, 600 ); // voice transcripts
|
||||
*/
|
||||
// make 4 empty lines for the ui header, to cut down on work down the road
|
||||
UIHeader.text_lines.emplace_back( "", Global.UITextColor );
|
||||
UIHeader.text_lines.emplace_back( "", Global.UITextColor );
|
||||
UIHeader.text_lines.emplace_back( "", Global.UITextColor );
|
||||
UIHeader.text_lines.emplace_back( "", Global.UITextColor );
|
||||
clear_panels();
|
||||
// bind the panels with ui object. maybe not the best place for this but, eh
|
||||
push_back( &UIHeader );
|
||||
push_back( &UITable );
|
||||
push_back( &UITranscripts );
|
||||
push_back( &m_aidpanel );
|
||||
push_back( &m_timetablepanel );
|
||||
push_back( &m_debugpanel );
|
||||
push_back( &m_transcriptspanel );
|
||||
|
||||
m_timetablepanel.size_min = { 435, 110 };
|
||||
m_timetablepanel.size_max = { 435, Global.iWindowHeight * 0.95 };
|
||||
|
||||
m_transcriptspanel.size_min = { 435, 85 };
|
||||
m_transcriptspanel.size_max = { Global.iWindowWidth * 0.95, Global.iWindowHeight * 0.95 };
|
||||
}
|
||||
|
||||
// potentially processes provided input key. returns: true if key was processed, false otherwise
|
||||
@@ -55,9 +52,6 @@ driver_ui::on_key( int const Key, int const Action ) {
|
||||
|
||||
case GLFW_KEY_F1:
|
||||
case GLFW_KEY_F2:
|
||||
case GLFW_KEY_F3:
|
||||
case GLFW_KEY_F8:
|
||||
case GLFW_KEY_F9:
|
||||
case GLFW_KEY_F10:
|
||||
case GLFW_KEY_F12: { // ui mode selectors
|
||||
|
||||
@@ -67,15 +61,7 @@ driver_ui::on_key( int const Key, int const Action ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if( Action == GLFW_RELEASE ) { return true; } // recognized, but ignored
|
||||
/*
|
||||
EditorModeFlag = ( Key == GLFW_KEY_F11 );
|
||||
if( ( true == EditorModeFlag )
|
||||
&& ( false == Global.ControlPicking ) ) {
|
||||
set_cursor( GLFW_CURSOR_NORMAL );
|
||||
Global.ControlPicking = true;
|
||||
}
|
||||
*/
|
||||
if( Action != GLFW_PRESS ) { return true; } // recognized, but ignored
|
||||
}
|
||||
|
||||
default: { // everything else
|
||||
@@ -87,91 +73,35 @@ driver_ui::on_key( int const Key, int const Action ) {
|
||||
|
||||
case GLFW_KEY_F1: {
|
||||
// basic consist info
|
||||
if( Global.iTextMode == Key ) { ++Global.iScreenMode[ Key - GLFW_KEY_F1 ]; }
|
||||
if( Global.iScreenMode[ Key - GLFW_KEY_F1 ] > 1 ) {
|
||||
// wyłączenie napisów
|
||||
Global.iTextMode = 0;
|
||||
Global.iScreenMode[ Key - GLFW_KEY_F1 ] = 0;
|
||||
}
|
||||
else {
|
||||
Global.iTextMode = Key;
|
||||
}
|
||||
auto state = (
|
||||
( m_aidpanel.is_open == false ) ? 0 :
|
||||
( m_aidpanel.is_expanded == false ) ? 1 :
|
||||
2 );
|
||||
state = clamp_circular( ++state, 3 );
|
||||
|
||||
m_aidpanel.is_open = ( state > 0 );
|
||||
m_aidpanel.is_expanded = ( state > 1 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
case GLFW_KEY_F2: {
|
||||
// parametry pojazdu
|
||||
if( Global.iTextMode == Key ) { ++Global.iScreenMode[ Key - GLFW_KEY_F1 ]; }
|
||||
if( Global.iScreenMode[ Key - GLFW_KEY_F1 ] > 1 ) {
|
||||
// wyłączenie napisów
|
||||
Global.iTextMode = 0;
|
||||
Global.iScreenMode[ Key - GLFW_KEY_F1 ] = 0;
|
||||
}
|
||||
else {
|
||||
Global.iTextMode = Key;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
case GLFW_KEY_F3: {
|
||||
// timetable
|
||||
if( Global.iTextMode == Key ) { ++Global.iScreenMode[ Key - GLFW_KEY_F1 ]; }
|
||||
if( Global.iScreenMode[ Key - GLFW_KEY_F1 ] > 1 ) {
|
||||
// wyłączenie napisów
|
||||
Global.iTextMode = 0;
|
||||
Global.iScreenMode[ Key - GLFW_KEY_F1 ] = 0;
|
||||
}
|
||||
else {
|
||||
Global.iTextMode = Key;
|
||||
}
|
||||
auto state = (
|
||||
( m_timetablepanel.is_open == false ) ? 0 :
|
||||
( m_timetablepanel.is_expanded == false ) ? 1 :
|
||||
2 );
|
||||
state = clamp_circular( ++state, 3 );
|
||||
|
||||
m_timetablepanel.is_open = ( state > 0 );
|
||||
m_timetablepanel.is_expanded = ( state > 1 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
case GLFW_KEY_F8: {
|
||||
// renderer debug data
|
||||
Global.iTextMode = Key;
|
||||
return true;
|
||||
}
|
||||
|
||||
case GLFW_KEY_F9: {
|
||||
// wersja
|
||||
Global.iTextMode = Key;
|
||||
return true;
|
||||
}
|
||||
|
||||
case GLFW_KEY_F10: {
|
||||
// quit
|
||||
if( Global.iTextMode == Key ) {
|
||||
Global.iTextMode =
|
||||
( Global.iPause && ( Key != GLFW_KEY_F1 ) ?
|
||||
GLFW_KEY_F1 :
|
||||
0 ); // wyłączenie napisów, chyba że pauza
|
||||
}
|
||||
else {
|
||||
Global.iTextMode = Key;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
case GLFW_KEY_F11: {
|
||||
// scenario inspector
|
||||
Global.iTextMode = Key;
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
case GLFW_KEY_F12: {
|
||||
// coś tam jeszcze
|
||||
Global.iTextMode = Key;
|
||||
return true;
|
||||
}
|
||||
|
||||
case GLFW_KEY_Y: {
|
||||
// potentially quit
|
||||
if( Global.iTextMode != GLFW_KEY_F10 ) { return false; } // not in quit mode
|
||||
|
||||
if( Action == GLFW_RELEASE ) { return true; } // recognized, but ignored
|
||||
|
||||
glfwSetWindowShouldClose( m_window, 1 );
|
||||
// debug panel
|
||||
m_debugpanel.is_open = !m_debugpanel.is_open;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -187,13 +117,9 @@ driver_ui::on_key( int const Key, int const Action ) {
|
||||
void
|
||||
driver_ui::update() {
|
||||
|
||||
UITable.text_lines.clear();
|
||||
std::string uitextline1, uitextline2, uitextline3, uitextline4;
|
||||
set_tooltip( "" );
|
||||
|
||||
auto const *train { simulation::Train };
|
||||
auto const *controlled { ( train ? train->Dynamic() : nullptr ) };
|
||||
auto const &camera { Global.pCamera };
|
||||
|
||||
if( ( train != nullptr ) && ( false == FreeFlyModeFlag ) ) {
|
||||
if( false == DebugModeFlag ) {
|
||||
@@ -214,691 +140,28 @@ driver_ui::update() {
|
||||
"" ) );
|
||||
}
|
||||
|
||||
switch( Global.iTextMode ) {
|
||||
|
||||
case( GLFW_KEY_F1 ) : {
|
||||
// f1, default mode: current time and timetable excerpt
|
||||
auto const &time = simulation::Time.data();
|
||||
uitextline1 =
|
||||
"Time: "
|
||||
+ to_string( time.wHour ) + ":"
|
||||
+ ( time.wMinute < 10 ? "0" : "" ) + to_string( time.wMinute ) + ":"
|
||||
+ ( time.wSecond < 10 ? "0" : "" ) + to_string( time.wSecond );
|
||||
if( Global.iPause ) {
|
||||
uitextline1 += " (paused)";
|
||||
}
|
||||
|
||||
if( ( controlled != nullptr )
|
||||
&& ( controlled->Mechanik != nullptr ) ) {
|
||||
|
||||
auto const *mover = controlled->MoverParameters;
|
||||
auto const *driver = controlled->Mechanik;
|
||||
|
||||
uitextline2 = "Throttle: " + to_string( driver->Controlling()->MainCtrlPos, 0, 2 ) + "+" + std::to_string( driver->Controlling()->ScndCtrlPos );
|
||||
if( mover->ActiveDir > 0 ) { uitextline2 += " D"; }
|
||||
else if( mover->ActiveDir < 0 ) { uitextline2 += " R"; }
|
||||
else { uitextline2 += " N"; }
|
||||
|
||||
uitextline3 = "Brakes:" + to_string( mover->fBrakeCtrlPos, 1, 5 ) + "+" + to_string( mover->LocalBrakePosA * LocalBrakePosNo, 0 ) + ( mover->SlippingWheels ? " !" : " " );
|
||||
|
||||
uitextline4 = (
|
||||
true == TestFlag( mover->SecuritySystem.Status, s_aware ) ?
|
||||
"!ALERTER! " :
|
||||
" " );
|
||||
uitextline4 += (
|
||||
true == TestFlag( mover->SecuritySystem.Status, s_active ) ?
|
||||
"!SHP! " :
|
||||
" " );
|
||||
|
||||
if( Global.iScreenMode[ Global.iTextMode - GLFW_KEY_F1 ] == 1 ) {
|
||||
// detail mode on second key press
|
||||
auto const speedlimit { static_cast<int>( std::floor( driver->VelDesired ) ) };
|
||||
uitextline2 +=
|
||||
" Speed: " + std::to_string( static_cast<int>( std::floor( mover->Vel ) ) ) + " km/h"
|
||||
+ " (limit: " + std::to_string( speedlimit ) + " km/h";
|
||||
auto const nextspeedlimit { static_cast<int>( std::floor( driver->VelNext ) ) };
|
||||
if( nextspeedlimit != speedlimit ) {
|
||||
uitextline2 +=
|
||||
", new limit: " + std::to_string( nextspeedlimit ) + " km/h"
|
||||
+ " in " + to_string( driver->ActualProximityDist * 0.001, 1 ) + " km";
|
||||
}
|
||||
uitextline2 += ")";
|
||||
auto const reverser { ( mover->ActiveDir > 0 ? 1 : -1 ) };
|
||||
auto const grade { controlled->VectorFront().y * 100 * ( controlled->DirectionGet() == reverser ? 1 : -1 ) * reverser };
|
||||
if( std::abs( grade ) >= 0.25 ) {
|
||||
uitextline2 += " Grade: " + to_string( grade, 1 ) + "%";
|
||||
}
|
||||
uitextline3 +=
|
||||
" Pressure: " + to_string( mover->BrakePress * 100.0, 2 ) + " kPa"
|
||||
+ " (train pipe: " + to_string( mover->PipePress * 100.0, 2 ) + " kPa)";
|
||||
|
||||
auto const stoptime { static_cast<int>( -1.0 * controlled->Mechanik->fStopTime ) };
|
||||
if( stoptime > 0 ) {
|
||||
uitextline4 += " Loading/unloading in progress (" + to_string( stoptime ) + ( stoptime > 1 ? " seconds" : " second" ) + " left)";
|
||||
}
|
||||
else {
|
||||
auto const trackblockdistance{ std::abs( controlled->Mechanik->TrackBlock() ) };
|
||||
if( trackblockdistance <= 75.0 ) {
|
||||
uitextline4 += " Another vehicle ahead (distance: " + to_string( trackblockdistance, 1 ) + " m)";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case( GLFW_KEY_F2 ) : {
|
||||
// timetable
|
||||
auto *vehicle {
|
||||
( FreeFlyModeFlag ?
|
||||
std::get<TDynamicObject *>( simulation::Region->find_vehicle( camera.Pos, 20, false, false ) ) :
|
||||
controlled ) }; // w trybie latania lokalizujemy wg mapy
|
||||
|
||||
if( vehicle == nullptr ) { break; }
|
||||
// if the nearest located vehicle doesn't have a direct driver, try to query its owner
|
||||
auto const owner = (
|
||||
( ( vehicle->Mechanik != nullptr ) && ( vehicle->Mechanik->Primary() ) ) ?
|
||||
vehicle->Mechanik :
|
||||
vehicle->ctOwner );
|
||||
if( owner == nullptr ){ break; }
|
||||
|
||||
auto const *table = owner->TrainTimetable();
|
||||
if( table == nullptr ) { break; }
|
||||
|
||||
auto const &time = simulation::Time.data();
|
||||
uitextline1 =
|
||||
"Time: "
|
||||
+ to_string( time.wHour ) + ":"
|
||||
+ ( time.wMinute < 10 ? "0" : "" ) + to_string( time.wMinute ) + ":"
|
||||
+ ( time.wSecond < 10 ? "0" : "" ) + to_string( time.wSecond );
|
||||
if( Global.iPause ) {
|
||||
uitextline1 += " (paused)";
|
||||
}
|
||||
|
||||
uitextline2 = Bezogonkow( owner->Relation(), true ) + " (" + Bezogonkow( owner->TrainName(), true ) + ")";
|
||||
auto const nextstation = Bezogonkow( owner->NextStop(), true );
|
||||
if( !nextstation.empty() ) {
|
||||
// jeśli jest podana relacja, to dodajemy punkt następnego zatrzymania
|
||||
uitextline3 = " -> " + nextstation;
|
||||
}
|
||||
|
||||
if( Global.iScreenMode[ Global.iTextMode - GLFW_KEY_F1 ] == 1 ) {
|
||||
|
||||
if( 0 == table->StationCount ) {
|
||||
// only bother if there's stations to list
|
||||
UITable.text_lines.emplace_back( "(no timetable)", Global.UITextColor );
|
||||
}
|
||||
else {
|
||||
// header
|
||||
UITable.text_lines.emplace_back( "+-----+------------------------------------+-------+-----+", Global.UITextColor );
|
||||
|
||||
TMTableLine const *tableline;
|
||||
for( int i = owner->iStationStart; i <= std::min( owner->iStationStart + 10, table->StationCount ); ++i ) {
|
||||
// wyświetlenie pozycji z rozkładu
|
||||
tableline = table->TimeTable + i; // linijka rozkładu
|
||||
|
||||
std::string vmax =
|
||||
" "
|
||||
+ to_string( tableline->vmax, 0 );
|
||||
vmax = vmax.substr( vmax.size() - 3, 3 ); // z wyrównaniem do prawej
|
||||
std::string const station = (
|
||||
Bezogonkow( tableline->StationName, true )
|
||||
+ " " )
|
||||
.substr( 0, 34 );
|
||||
std::string const location = (
|
||||
( tableline->km > 0.0 ?
|
||||
to_string( tableline->km, 2 ) :
|
||||
"" )
|
||||
+ " " )
|
||||
.substr( 0, 34 - tableline->StationWare.size() );
|
||||
std::string const arrival = (
|
||||
tableline->Ah >= 0 ?
|
||||
to_string( int( 100 + tableline->Ah ) ).substr( 1, 2 ) + ":" + to_string( int( 100 + tableline->Am ) ).substr( 1, 2 ) :
|
||||
" | " );
|
||||
std::string const departure = (
|
||||
tableline->Dh >= 0 ?
|
||||
to_string( int( 100 + tableline->Dh ) ).substr( 1, 2 ) + ":" + to_string( int( 100 + tableline->Dm ) ).substr( 1, 2 ) :
|
||||
" | " );
|
||||
auto const candeparture = (
|
||||
( owner->iStationStart < table->StationIndex )
|
||||
&& ( i < table->StationIndex )
|
||||
&& ( ( time.wHour * 60 + time.wMinute ) >= ( tableline->Dh * 60 + tableline->Dm ) ) );
|
||||
auto traveltime =
|
||||
" "
|
||||
+ ( i < 2 ? "" :
|
||||
tableline->Ah >= 0 ? to_string( CompareTime( table->TimeTable[ i - 1 ].Dh, table->TimeTable[ i - 1 ].Dm, tableline->Ah, tableline->Am ), 0 ) :
|
||||
to_string( std::max( 0.0, CompareTime( table->TimeTable[ i - 1 ].Dh, table->TimeTable[ i - 1 ].Dm, tableline->Dh, tableline->Dm ) - 0.5 ), 0 ) );
|
||||
traveltime = traveltime.substr( traveltime.size() - 3, 3 ); // z wyrównaniem do prawej
|
||||
|
||||
UITable.text_lines.emplace_back(
|
||||
( "| " + vmax + " | " + station + " | " + arrival + " | " + traveltime + " |" ),
|
||||
( candeparture ?
|
||||
glm::vec4( 0.0f, 1.0f, 0.0f, 1.0f ) :// czas minął i odjazd był, to nazwa stacji będzie na zielono
|
||||
Global.UITextColor ) );
|
||||
UITable.text_lines.emplace_back(
|
||||
( "| | " + location + tableline->StationWare + " | " + departure + " | |" ),
|
||||
( candeparture ?
|
||||
glm::vec4( 0.0f, 1.0f, 0.0f, 1.0f ) :// czas minął i odjazd był, to nazwa stacji będzie na zielono
|
||||
Global.UITextColor ) );
|
||||
// divider/footer
|
||||
UITable.text_lines.emplace_back( "+-----+------------------------------------+-------+-----+", Global.UITextColor );
|
||||
}
|
||||
if( owner->iStationStart + 10 < table->StationCount ) {
|
||||
// if we can't display entire timetable, add a scrolling indicator at the bottom
|
||||
UITable.text_lines.emplace_back( " ... ", Global.UITextColor );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case( GLFW_KEY_F3 ) : {
|
||||
|
||||
auto const *vehicle {
|
||||
( FreeFlyModeFlag ?
|
||||
std::get<TDynamicObject *>( simulation::Region->find_vehicle( camera.Pos, 20, false, false ) ) :
|
||||
controlled ) }; // w trybie latania lokalizujemy wg mapy
|
||||
|
||||
if( vehicle != nullptr ) {
|
||||
// jeśli domyślny ekran po pierwszym naciśnięciu
|
||||
auto const *mover { vehicle->MoverParameters };
|
||||
|
||||
uitextline1 = "Vehicle name: " + mover->Name;
|
||||
|
||||
if( ( vehicle->Mechanik == nullptr ) && ( vehicle->ctOwner ) ) {
|
||||
// for cars other than leading unit indicate the leader
|
||||
uitextline1 += ", owned by " + vehicle->ctOwner->OwnerName();
|
||||
}
|
||||
uitextline1 += "; Status: " + mover->EngineDescription( 0 );
|
||||
|
||||
// informacja o sprzęgach
|
||||
uitextline1 +=
|
||||
"; C0:" +
|
||||
( vehicle->PrevConnected ?
|
||||
vehicle->PrevConnected->name() + ":" + to_string( mover->Couplers[ 0 ].CouplingFlag ) + (
|
||||
mover->Couplers[ 0 ].CouplingFlag == 0 ?
|
||||
" (" + to_string( mover->Couplers[ 0 ].CoupleDist, 1 ) + " m)" :
|
||||
"" ) :
|
||||
"none" );
|
||||
uitextline1 +=
|
||||
" C1:" +
|
||||
( vehicle->NextConnected ?
|
||||
vehicle->NextConnected->name() + ":" + to_string( mover->Couplers[ 1 ].CouplingFlag ) + (
|
||||
mover->Couplers[ 1 ].CouplingFlag == 0 ?
|
||||
" (" + to_string( mover->Couplers[ 1 ].CoupleDist, 1 ) + " m)" :
|
||||
"" ) :
|
||||
"none" );
|
||||
|
||||
// equipment flags
|
||||
uitextline2 = ( mover->Battery ? "B" : "." );
|
||||
uitextline2 += ( mover->Mains ? "M" : "." );
|
||||
uitextline2 += ( mover->PantRearUp ? ( mover->PantRearVolt > 0.0 ? "O" : "o" ) : "." );
|
||||
uitextline2 += ( mover->PantFrontUp ? ( mover->PantFrontVolt > 0.0 ? "P" : "p" ) : "." );
|
||||
uitextline2 += ( mover->PantPressLockActive ? "!" : ( mover->PantPressSwitchActive ? "*" : "." ) );
|
||||
uitextline2 += ( mover->WaterPump.is_active ? "W" : ( false == mover->WaterPump.breaker ? "-" : ( mover->WaterPump.is_enabled ? "w" : "." ) ) );
|
||||
uitextline2 += ( true == mover->WaterHeater.is_damaged ? "!" : ( mover->WaterHeater.is_active ? "H" : ( false == mover->WaterHeater.breaker ? "-" : ( mover->WaterHeater.is_enabled ? "h" : "." ) ) ) );
|
||||
uitextline2 += ( mover->FuelPump.is_active ? "F" : ( mover->FuelPump.is_enabled ? "f" : "." ) );
|
||||
uitextline2 += ( mover->OilPump.is_active ? "O" : ( mover->OilPump.is_enabled ? "o" : "." ) );
|
||||
uitextline2 += ( false == mover->ConverterAllowLocal ? "-" : ( mover->ConverterAllow ? ( mover->ConverterFlag ? "X" : "x" ) : "." ) );
|
||||
uitextline2 += ( mover->ConvOvldFlag ? "!" : "." );
|
||||
uitextline2 += ( mover->CompressorFlag ? "C" : ( false == mover->CompressorAllowLocal ? "-" : ( ( mover->CompressorAllow || mover->CompressorStart == start_t::automatic ) ? "c" : "." ) ) );
|
||||
uitextline2 += ( mover->CompressorGovernorLock ? "!" : "." );
|
||||
|
||||
auto const *train { simulation::Train };
|
||||
if( ( train != nullptr ) && ( train->Dynamic() == vehicle ) ) {
|
||||
uitextline2 += ( mover->Radio ? " R: " : " r: " ) + std::to_string( train->RadioChannel() );
|
||||
}
|
||||
uitextline2 += " Bdelay: ";
|
||||
if( ( mover->BrakeDelayFlag & bdelay_G ) == bdelay_G )
|
||||
uitextline2 += "G";
|
||||
if( ( mover->BrakeDelayFlag & bdelay_P ) == bdelay_P )
|
||||
uitextline2 += "P";
|
||||
if( ( mover->BrakeDelayFlag & bdelay_R ) == bdelay_R )
|
||||
uitextline2 += "R";
|
||||
if( ( mover->BrakeDelayFlag & bdelay_M ) == bdelay_M )
|
||||
uitextline2 += "+Mg";
|
||||
|
||||
uitextline2 += ", Load: " + to_string( mover->Load, 0 ) + " (" + to_string( mover->LoadFlag, 0 ) + ")";
|
||||
|
||||
uitextline2 +=
|
||||
"; Pant: "
|
||||
+ to_string( mover->PantPress, 2 )
|
||||
+ ( mover->bPantKurek3 ? "-ZG" : "|ZG" );
|
||||
|
||||
uitextline2 +=
|
||||
"; Ft: " + to_string(
|
||||
mover->Ft * 0.001f * (
|
||||
mover->ActiveCab ? mover->ActiveCab :
|
||||
vehicle->ctOwner ? vehicle->ctOwner->Controlling()->ActiveCab :
|
||||
1 ), 1 )
|
||||
+ ", Fb: " + to_string( mover->Fb * 0.001f, 1 )
|
||||
+ ", Fr: " + to_string( mover->Adhesive( mover->RunningTrack.friction ), 2 )
|
||||
+ ( mover->SlippingWheels ? " (!)" : "" );
|
||||
|
||||
if( vehicle->Mechanik ) {
|
||||
uitextline2 += "; Ag: " + to_string( vehicle->Mechanik->fAccGravity, 2 ) + " (" + ( vehicle->Mechanik->fAccGravity > 0.01 ? "\\" : ( vehicle->Mechanik->fAccGravity < -0.01 ? "/" : "-" ) ) + ")";
|
||||
}
|
||||
|
||||
uitextline2 +=
|
||||
"; TC:"
|
||||
+ to_string( mover->TotalCurrent, 0 );
|
||||
auto const frontcouplerhighvoltage =
|
||||
to_string( mover->Couplers[ side::front ].power_high.voltage, 0 )
|
||||
+ "@"
|
||||
+ to_string( mover->Couplers[ side::front ].power_high.current, 0 );
|
||||
auto const rearcouplerhighvoltage =
|
||||
to_string( mover->Couplers[ side::rear ].power_high.voltage, 0 )
|
||||
+ "@"
|
||||
+ to_string( mover->Couplers[ side::rear ].power_high.current, 0 );
|
||||
uitextline2 += ", HV: ";
|
||||
if( mover->Couplers[ side::front ].power_high.local == false ) {
|
||||
uitextline2 +=
|
||||
"(" + frontcouplerhighvoltage + ")-"
|
||||
+ ":F" + ( vehicle->DirectionGet() ? "<<" : ">>" ) + "R:"
|
||||
+ "-(" + rearcouplerhighvoltage + ")";
|
||||
}
|
||||
else {
|
||||
uitextline2 +=
|
||||
frontcouplerhighvoltage
|
||||
+ ":F" + ( vehicle->DirectionGet() ? "<<" : ">>" ) + "R:"
|
||||
+ rearcouplerhighvoltage;
|
||||
}
|
||||
|
||||
uitextline3 +=
|
||||
"TrB: " + to_string( mover->BrakePress, 2 )
|
||||
+ ", " + to_hex_str( mover->Hamulec->GetBrakeStatus(), 2 );
|
||||
|
||||
uitextline3 +=
|
||||
"; LcB: " + to_string( mover->LocBrakePress, 2 )
|
||||
+ "; hat: " + to_string( mover->BrakeCtrlPos2, 2 )
|
||||
+ "; pipes: " + to_string( mover->PipePress, 2 )
|
||||
+ "/" + to_string( mover->ScndPipePress, 2 )
|
||||
+ "/" + to_string( mover->EqvtPipePress, 2 )
|
||||
+ ", MT: " + to_string( mover->CompressedVolume, 3 )
|
||||
+ ", BT: " + to_string( mover->Volume, 3 )
|
||||
+ ", CtlP: " + to_string( mover->CntrlPipePress, 3 )
|
||||
+ ", CtlT: " + to_string( mover->Hamulec->GetCRP(), 3 );
|
||||
|
||||
if( mover->ManualBrakePos > 0 ) {
|
||||
|
||||
uitextline3 += "; manual brake on";
|
||||
}
|
||||
|
||||
if( vehicle->Mechanik ) {
|
||||
// o ile jest ktoś w środku
|
||||
std::string flags = "cpapcplhhndoiefgvdpseil "; // flagi AI (definicja w Driver.h)
|
||||
for( int i = 0, j = 1; i < 23; ++i, j <<= 1 )
|
||||
if( false == ( vehicle->Mechanik->DrivigFlags() & j ) ) // jak bit ustawiony
|
||||
flags[ i ] = '.';// std::toupper( flags[ i ] ); // ^= 0x20; // to zmiana na wielką literę
|
||||
|
||||
uitextline4 = flags;
|
||||
|
||||
uitextline4 +=
|
||||
"Driver: Vd=" + to_string( vehicle->Mechanik->VelDesired, 0 )
|
||||
+ " Ad=" + to_string( vehicle->Mechanik->AccDesired, 2 )
|
||||
+ " Ah=" + to_string( vehicle->Mechanik->fAccThreshold, 2 )
|
||||
+ "@" + to_string( vehicle->Mechanik->fBrake_a0[ 0 ], 2 )
|
||||
+ "+" + to_string( vehicle->Mechanik->fBrake_a1[ 0 ], 2 )
|
||||
+ " Bd=" + to_string( vehicle->Mechanik->fBrakeDist, 0 )
|
||||
+ " Pd=" + to_string( vehicle->Mechanik->ActualProximityDist, 0 )
|
||||
+ " Vn=" + to_string( vehicle->Mechanik->VelNext, 0 )
|
||||
+ " VSl=" + to_string( vehicle->Mechanik->VelSignalLast, 0 )
|
||||
+ " VLl=" + to_string( vehicle->Mechanik->VelLimitLast, 0 )
|
||||
+ " VRd=" + to_string( vehicle->Mechanik->VelRoad, 0 )
|
||||
+ " VRst=" + to_string( vehicle->Mechanik->VelRestricted, 0 );
|
||||
|
||||
if( ( vehicle->Mechanik->VelNext == 0.0 )
|
||||
&& ( vehicle->Mechanik->eSignNext ) ) {
|
||||
// jeśli ma zapamiętany event semafora, nazwa eventu semafora
|
||||
uitextline4 += " (" + Bezogonkow( vehicle->Mechanik->eSignNext->asName ) + ")";
|
||||
}
|
||||
|
||||
// biezaca komenda dla AI
|
||||
uitextline4 += ", command: " + vehicle->Mechanik->OrderCurrent();
|
||||
}
|
||||
|
||||
if( Global.iScreenMode[ Global.iTextMode - GLFW_KEY_F1 ] == 1 ) {
|
||||
// f2 screen, track scan mode
|
||||
if( vehicle->Mechanik == nullptr ) {
|
||||
//żeby była tabelka, musi być AI
|
||||
break;
|
||||
}
|
||||
|
||||
std::size_t i = 0; std::size_t const speedtablesize = clamp( static_cast<int>( vehicle->Mechanik->TableSize() ) - 1, 0, 30 );
|
||||
do {
|
||||
std::string scanline = vehicle->Mechanik->TableText( i );
|
||||
if( scanline.empty() ) { break; }
|
||||
UITable.text_lines.emplace_back( Bezogonkow( scanline ), Global.UITextColor );
|
||||
++i;
|
||||
} while( i < speedtablesize ); // TController:iSpeedTableSize TODO: change when the table gets recoded
|
||||
}
|
||||
}
|
||||
else {
|
||||
// wyświetlenie współrzędnych w scenerii oraz kąta kamery, gdy nie mamy wskaźnika
|
||||
uitextline1 =
|
||||
"Camera position: "
|
||||
+ to_string( camera.Pos.x, 2 ) + " "
|
||||
+ to_string( camera.Pos.y, 2 ) + " "
|
||||
+ to_string( camera.Pos.z, 2 )
|
||||
+ ", azimuth: "
|
||||
+ to_string( 180.0 - glm::degrees( camera.Yaw ), 0 ) // ma być azymut, czyli 0 na północy i rośnie na wschód
|
||||
+ " "
|
||||
+ std::string( "S SEE NEN NWW SW" )
|
||||
.substr( 0 + 2 * floor( fmod( 8 + ( camera.Yaw + 0.5 * M_PI_4 ) / M_PI_4, 8 ) ), 2 );
|
||||
// current luminance level
|
||||
uitextline2 = "Light level: " + to_string( Global.fLuminance, 3 );
|
||||
if( Global.FakeLight ) { uitextline2 += "(*)"; }
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case( GLFW_KEY_F8 ) : {
|
||||
// gfx renderer data
|
||||
uitextline1 =
|
||||
"FoV: " + to_string( Global.FieldOfView / Global.ZoomFactor, 1 )
|
||||
+ ", Draw range x " + to_string( Global.fDistanceFactor, 1 )
|
||||
// + "; sectors: " + std::to_string( GfxRenderer.m_drawcount )
|
||||
// + ", FPS: " + to_string( Timer::GetFPS(), 2 );
|
||||
+ ", FPS: " + std::to_string( static_cast<int>(std::round(GfxRenderer.Framerate())) );
|
||||
if( Global.iSlowMotion ) {
|
||||
uitextline1 += " (slowmotion " + to_string( Global.iSlowMotion ) + ")";
|
||||
}
|
||||
|
||||
uitextline2 =
|
||||
std::string( "Rendering mode: " )
|
||||
+ ( Global.bUseVBO ?
|
||||
"VBO" :
|
||||
"Display Lists" )
|
||||
+ " ";
|
||||
if( false == Global.LastGLError.empty() ) {
|
||||
uitextline2 +=
|
||||
"Last openGL error: "
|
||||
+ Global.LastGLError;
|
||||
}
|
||||
// renderer stats
|
||||
uitextline3 = GfxRenderer.info_times();
|
||||
uitextline4 = GfxRenderer.info_stats();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case( GLFW_KEY_F9 ) : {
|
||||
// informacja o wersji
|
||||
uitextline1 = "MaSzyna " + Global.asVersion; // informacja o wersji
|
||||
if( Global.iMultiplayer ) {
|
||||
uitextline1 += " (multiplayer mode is active)";
|
||||
}
|
||||
uitextline3 =
|
||||
"vehicles: " + to_string( Timer::subsystem.sim_dynamics.average(), 2 ) + " msec"
|
||||
+ " update total: " + to_string( Timer::subsystem.sim_total.average(), 2 ) + " msec";
|
||||
// current event queue
|
||||
auto const time { Timer::GetTime() };
|
||||
auto const *event { simulation::Events.begin() };
|
||||
auto eventtableindex{ 0 };
|
||||
while( ( event != nullptr )
|
||||
&& ( eventtableindex < 30 ) ) {
|
||||
|
||||
if( ( false == event->m_ignored )
|
||||
&& ( true == event->bEnabled ) ) {
|
||||
|
||||
auto const delay { " " + to_string( std::max( 0.0, event->fStartTime - time ), 1 ) };
|
||||
auto const eventline =
|
||||
"Delay: " + delay.substr( delay.length() - 6 )
|
||||
+ ", Event: " + event->asName
|
||||
+ ( event->Activator ? " (by: " + event->Activator->asName + ")" : "" )
|
||||
+ ( event->evJoined ? " (joint event)" : "" );
|
||||
|
||||
UITable.text_lines.emplace_back( eventline, Global.UITextColor );
|
||||
++eventtableindex;
|
||||
}
|
||||
event = event->evNext;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case( GLFW_KEY_F10 ) : {
|
||||
|
||||
uitextline1 = "Press [Y] key to quit / Aby zakonczyc program, przycisnij klawisz [Y].";
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case( GLFW_KEY_F12 ) : {
|
||||
// opcje włączenia i wyłączenia logowania
|
||||
uitextline1 = "[0] Debugmode " + std::string( DebugModeFlag ? "(on)" : "(off)" );
|
||||
uitextline2 = "[1] log.txt " + std::string( ( Global.iWriteLogEnabled & 1 ) ? "(on)" : "(off)" );
|
||||
uitextline3 = "[2] Console " + std::string( ( Global.iWriteLogEnabled & 2 ) ? "(on)" : "(off)" );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
// uncovered cases, nothing to do here...
|
||||
// ... unless we're in debug mode
|
||||
if( DebugModeFlag ) {
|
||||
|
||||
auto const *vehicle {
|
||||
( FreeFlyModeFlag ?
|
||||
std::get<TDynamicObject *>( simulation::Region->find_vehicle( camera.Pos, 20, false, false ) ) :
|
||||
controlled ) }; // w trybie latania lokalizujemy wg mapy
|
||||
if( vehicle == nullptr ) {
|
||||
break;
|
||||
}
|
||||
auto const *mover { vehicle->MoverParameters };
|
||||
uitextline1 =
|
||||
"vel: " + to_string( vehicle->GetVelocity(), 2 ) + "/" + to_string( mover->nrot* M_PI * mover->WheelDiameter * 3.6, 2 )
|
||||
+ " km/h;" + ( mover->SlippingWheels ? " (!)" : " " )
|
||||
+ " dist: " + to_string( mover->DistCounter, 2 ) + " km"
|
||||
+ "; pos: [" + to_string( vehicle->GetPosition().x, 2 ) + ", " + to_string( vehicle->GetPosition().y, 2 ) + ", " + to_string( vehicle->GetPosition().z, 2 ) + "]"
|
||||
+ ", PM=" + to_string( mover->WheelFlat, 1 )
|
||||
+ " mm; enpwr=" + to_string( mover->EnginePower, 1 )
|
||||
+ "; enrot=" + to_string( mover->enrot * 60, 0 )
|
||||
+ " tmrot=" + to_string( std::abs( mover->nrot ) * mover->Transmision.Ratio * 60, 0 )
|
||||
+ "; ventrot=" + to_string( mover->RventRot * 60, 1 )
|
||||
+ "; fanrot=" + to_string( mover->dizel_heat.rpmw, 1 ) + ", " + to_string( mover->dizel_heat.rpmw2, 1 );
|
||||
|
||||
uitextline2 =
|
||||
"HamZ=" + to_string( mover->fBrakeCtrlPos, 2 )
|
||||
+ "; HamP=" + to_string( mover->LocalBrakePosA, 2 )
|
||||
+ "; NasJ=" + std::to_string( mover->MainCtrlPos ) + "(" + std::to_string( mover->MainCtrlActualPos ) + ")"
|
||||
+ ( ( mover->ShuntMode && mover->EngineType == TEngineType::DieselElectric ) ?
|
||||
"; NasB=" + to_string( mover->AnPos, 2 ) :
|
||||
"; NasB=" + std::to_string( mover->ScndCtrlPos ) + "(" + std::to_string( mover->ScndCtrlActualPos ) + ")" )
|
||||
+ "; I=" +
|
||||
( mover->TrainType == dt_EZT ?
|
||||
std::to_string( int( mover->ShowCurrent( 0 ) ) ) :
|
||||
std::to_string( int( mover->Im ) ) )
|
||||
+ "; U=" + to_string( int( mover->RunningTraction.TractionVoltage + 0.5 ) )
|
||||
+ "; R=" +
|
||||
( std::abs( mover->RunningShape.R ) > 10000.0 ?
|
||||
"~0.0" :
|
||||
to_string( mover->RunningShape.R, 1 ) )
|
||||
+ " An=" + to_string( mover->AccN, 2 ); // przyspieszenie poprzeczne
|
||||
|
||||
if( tprev != simulation::Time.data().wSecond ) {
|
||||
tprev = simulation::Time.data().wSecond;
|
||||
Acc = ( mover->Vel - VelPrev ) / 3.6;
|
||||
VelPrev = mover->Vel;
|
||||
}
|
||||
uitextline2 += "; As=" + to_string( Acc, 2 ); // przyspieszenie wzdłużne
|
||||
// uitextline2 += " eAngle=" + to_string( std::cos( mover->eAngle ), 2 );
|
||||
uitextline2 += "; oilP=" + to_string( mover->OilPump.pressure_present, 3 );
|
||||
uitextline2 += " oilT=" + to_string( mover->dizel_heat.To, 2 );
|
||||
uitextline2 += "; waterT=" + to_string( mover->dizel_heat.temperatura1, 2 );
|
||||
uitextline2 += ( mover->WaterCircuitsLink ? "-" : "|" );
|
||||
uitextline2 += to_string( mover->dizel_heat.temperatura2, 2 );
|
||||
uitextline2 += "; engineT=" + to_string( mover->dizel_heat.Ts, 2 );
|
||||
|
||||
uitextline3 =
|
||||
"cyl.ham. " + to_string( mover->BrakePress, 2 )
|
||||
+ "; prz.gl. " + to_string( mover->PipePress, 2 )
|
||||
+ "; zb.gl. " + to_string( mover->CompressedVolume, 2 )
|
||||
// youBy - drugi wezyk
|
||||
+ "; p.zas. " + to_string( mover->ScndPipePress, 2 );
|
||||
|
||||
// McZapkie: warto wiedziec w jakim stanie sa przelaczniki
|
||||
if( mover->ConvOvldFlag )
|
||||
uitextline3 += " C! ";
|
||||
else if( mover->FuseFlag )
|
||||
uitextline3 += " F! ";
|
||||
else if( !mover->Mains )
|
||||
uitextline3 += " () ";
|
||||
else {
|
||||
switch(
|
||||
mover->ActiveDir *
|
||||
( mover->Imin == mover->IminLo ?
|
||||
1 :
|
||||
2 ) ) {
|
||||
case 2: { uitextline3 += " >> "; break; }
|
||||
case 1: { uitextline3 += " -> "; break; }
|
||||
case 0: { uitextline3 += " -- "; break; }
|
||||
case -1: { uitextline3 += " <- "; break; }
|
||||
case -2: { uitextline3 += " << "; break; }
|
||||
}
|
||||
}
|
||||
// McZapkie: predkosc szlakowa
|
||||
if( mover->RunningTrack.Velmax == -1 ) {
|
||||
uitextline3 += " Vtrack=Vmax";
|
||||
}
|
||||
else {
|
||||
uitextline3 += " Vtrack " + to_string( mover->RunningTrack.Velmax, 2 );
|
||||
}
|
||||
|
||||
if( ( mover->EnginePowerSource.SourceType == TPowerSource::CurrentCollector )
|
||||
|| ( mover->TrainType == dt_EZT ) ) {
|
||||
uitextline3 +=
|
||||
"; pant. " + to_string( mover->PantPress, 2 )
|
||||
+ ( mover->bPantKurek3 ? "=" : "^" ) + "ZG";
|
||||
}
|
||||
|
||||
// McZapkie: komenda i jej parametry
|
||||
if( mover->CommandIn.Command != ( "" ) ) {
|
||||
uitextline4 =
|
||||
"C:" + mover->CommandIn.Command
|
||||
+ " V1=" + to_string( mover->CommandIn.Value1, 0 )
|
||||
+ " V2=" + to_string( mover->CommandIn.Value2, 0 );
|
||||
}
|
||||
if( ( vehicle->Mechanik )
|
||||
&& ( vehicle->Mechanik->AIControllFlag == AIdriver ) ) {
|
||||
uitextline4 +=
|
||||
"AI: Vd=" + to_string( vehicle->Mechanik->VelDesired, 0 )
|
||||
+ " ad=" + to_string(vehicle->Mechanik->AccDesired, 2)
|
||||
+ "/" + to_string(vehicle->Mechanik->AccDesired*vehicle->Mechanik->BrakeAccFactor(), 2)
|
||||
+ " atrain=" + to_string(vehicle->Mechanik->fBrake_a0[0], 2)
|
||||
+ "+" + to_string(vehicle->Mechanik->fBrake_a1[0], 2)
|
||||
+ " aS=" + to_string(vehicle->Mechanik->AbsAccS_pub, 2)
|
||||
+ " Pd=" + to_string( vehicle->Mechanik->ActualProximityDist, 0 )
|
||||
+ " Vn=" + to_string( vehicle->Mechanik->VelNext, 0 );
|
||||
}
|
||||
|
||||
// induction motor data
|
||||
if( mover->EngineType == TEngineType::ElectricInductionMotor ) {
|
||||
|
||||
UITable.text_lines.emplace_back( " eimc: eimv: press:", Global.UITextColor );
|
||||
for( int i = 0; i <= 20; ++i ) {
|
||||
|
||||
std::string parameters =
|
||||
mover->eimc_labels[ i ] + to_string( mover->eimc[ i ], 2, 9 )
|
||||
+ " | "
|
||||
+ mover->eimv_labels[ i ] + to_string( mover->eimv[ i ], 2, 9 );
|
||||
|
||||
if( i < 10 ) {
|
||||
parameters += " | " + train->fPress_labels[i] + to_string( train->fPress[ i ][ 0 ], 2, 9 );
|
||||
}
|
||||
else if( i == 12 ) {
|
||||
parameters += " med:";
|
||||
}
|
||||
else if( i >= 13 ) {
|
||||
parameters += " | " + vehicle->MED_labels[ i - 13 ] + to_string( vehicle->MED[ 0 ][ i - 13 ], 2, 9 );
|
||||
}
|
||||
|
||||
UITable.text_lines.emplace_back( parameters, Global.UITextColor );
|
||||
}
|
||||
}
|
||||
if (mover->EngineType == TEngineType::DieselEngine) {
|
||||
std::string parameters = "param value";
|
||||
UITable.text_lines.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "efill: " + to_string(mover->dizel_fill, 2, 9);
|
||||
UITable.text_lines.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "etorq: " + to_string(mover->dizel_Torque, 2, 9);
|
||||
UITable.text_lines.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "creal: " + to_string(mover->dizel_engage, 2, 9);
|
||||
UITable.text_lines.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "cdesi: " + to_string(mover->dizel_engagestate, 2, 9);
|
||||
UITable.text_lines.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "cdelt: " + to_string(mover->dizel_engagedeltaomega, 2, 9);
|
||||
UITable.text_lines.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "gears: " + to_string(mover->dizel_automaticgearstatus, 2, 9);
|
||||
UITable.text_lines.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "hydro value";
|
||||
UITable.text_lines.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "hTCnI: " + to_string(mover->hydro_TC_nIn, 2, 9);
|
||||
UITable.text_lines.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "hTCnO: " + to_string(mover->hydro_TC_nOut, 2, 9);
|
||||
UITable.text_lines.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "hTCTM: " + to_string(mover->hydro_TC_TMRatio, 2, 9);
|
||||
UITable.text_lines.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "hTCTI: " + to_string(mover->hydro_TC_TorqueIn, 2, 9);
|
||||
UITable.text_lines.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "hTCTO: " + to_string(mover->hydro_TC_TorqueOut, 2, 9);
|
||||
UITable.text_lines.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "hTCfl: " + to_string(mover->hydro_TC_Fill, 2, 9);
|
||||
UITable.text_lines.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "hTCLR: " + to_string(mover->hydro_TC_LockupRate, 2, 9);
|
||||
UITable.text_lines.emplace_back(parameters, Global.UITextColor);
|
||||
//parameters = "hTCXX: " + to_string(mover->hydro_TC_nIn, 2, 9);
|
||||
//UITable.text_lines.emplace_back(parameters, Global.UITextColor);
|
||||
}
|
||||
|
||||
} // if( DebugModeFlag && Controlled )
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef EU07_USE_OLD_UI_CODE
|
||||
if( Controlled && DebugModeFlag && !Global.iTextMode ) {
|
||||
|
||||
uitextline1 +=
|
||||
( "; d_omega " ) + to_string( Controlled->MoverParameters->dizel_engagedeltaomega, 3 );
|
||||
|
||||
if( Controlled->MoverParameters->EngineType == ElectricInductionMotor ) {
|
||||
|
||||
for( int i = 0; i <= 8; i++ ) {
|
||||
for( int j = 0; j <= 9; j++ ) {
|
||||
glRasterPos2f( 0.05f + 0.03f * i, 0.16f - 0.01f * j );
|
||||
uitextline4 = to_string( Train->fEIMParams[ i ][ j ], 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// update the ui header texts
|
||||
auto &headerdata = UIHeader.text_lines;
|
||||
headerdata[ 0 ].data = uitextline1;
|
||||
headerdata[ 1 ].data = uitextline2;
|
||||
headerdata[ 2 ].data = uitextline3;
|
||||
headerdata[ 3 ].data = uitextline4;
|
||||
|
||||
// stenogramy dźwięków (ukryć, gdy tabelka skanowania lub rozkład?)
|
||||
auto &transcripts = UITranscripts.text_lines;
|
||||
transcripts.clear();
|
||||
for( auto const &transcript : ui::Transcripts.aLines ) {
|
||||
|
||||
if( Global.fTimeAngleDeg >= transcript.fShow ) {
|
||||
|
||||
cParser parser( transcript.asText );
|
||||
while( true == parser.getTokens( 1, false, "|" ) ) {
|
||||
|
||||
std::string transcriptline; parser >> transcriptline;
|
||||
transcripts.emplace_back( transcriptline, glm::vec4( 1.0f, 1.0f, 0.0f, 1.0f ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ui_layer::update();
|
||||
}
|
||||
|
||||
// render() subclass details
|
||||
void
|
||||
driver_ui::render_() {
|
||||
|
||||
auto const pausemask { 1 | 2 };
|
||||
if( ( Global.iPause & pausemask ) != 0 ) {
|
||||
// pause/quit modal
|
||||
auto const popupheader{ "Simulation Paused" };
|
||||
ImGui::OpenPopup( popupheader );
|
||||
if( ImGui::BeginPopupModal( popupheader, nullptr, ImGuiWindowFlags_AlwaysAutoResize ) ) {
|
||||
if( ImGui::Button( "Resume", ImVec2( 120, 0 ) ) ) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
Global.iPause &= ~pausemask;
|
||||
}
|
||||
if( ImGui::Button( "Quit", ImVec2( 120, 0 ) ) ) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
glfwSetWindowShouldClose( m_window, 1 );
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#pragma once
|
||||
|
||||
#include "uilayer.h"
|
||||
#include "driveruipanels.h"
|
||||
|
||||
class driver_ui : public ui_layer {
|
||||
|
||||
@@ -25,12 +26,14 @@ public:
|
||||
update() override;
|
||||
|
||||
private:
|
||||
// methods
|
||||
// render() subclass details
|
||||
void
|
||||
render_() override;
|
||||
// members
|
||||
ui_panel UIHeader { 20, 20 }; // header ui panel
|
||||
ui_panel UITable { 20, 100 };// schedule or scan table
|
||||
ui_panel UITranscripts { 85, 600 }; // voice transcripts
|
||||
int tprev { 0 }; // poprzedni czas
|
||||
double VelPrev { 0.0 }; // poprzednia prędkość
|
||||
double Acc { 0.0 }; // przyspieszenie styczne
|
||||
drivingaid_panel m_aidpanel { "Driving Aid", true };
|
||||
timetable_panel m_timetablepanel { "Timetable", false };
|
||||
debug_panel m_debugpanel { "Debug Data", false };
|
||||
transcripts_panel m_transcriptspanel { "Transcripts", true }; // voice transcripts
|
||||
|
||||
};
|
||||
|
||||
896
driveruipanels.cpp
Normal file
896
driveruipanels.cpp
Normal file
@@ -0,0 +1,896 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "driveruipanels.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "translation.h"
|
||||
#include "simulation.h"
|
||||
#include "simulationtime.h"
|
||||
#include "event.h"
|
||||
#include "camera.h"
|
||||
#include "mtable.h"
|
||||
#include "train.h"
|
||||
#include "driver.h"
|
||||
#include "animmodel.h"
|
||||
#include "dynobj.h"
|
||||
#include "model3d.h"
|
||||
#include "renderer.h"
|
||||
#include "utilities.h"
|
||||
#include "logs.h"
|
||||
|
||||
void
|
||||
drivingaid_panel::update() {
|
||||
|
||||
if( false == is_open ) { return; }
|
||||
|
||||
text_lines.clear();
|
||||
|
||||
auto const *train { simulation::Train };
|
||||
auto const *controlled { ( train ? train->Dynamic() : nullptr ) };
|
||||
|
||||
if( ( controlled == nullptr )
|
||||
|| ( controlled->Mechanik == nullptr ) ) { return; }
|
||||
|
||||
auto const *mover = controlled->MoverParameters;
|
||||
auto const *driver = controlled->Mechanik;
|
||||
|
||||
{ // throttle, velocity, speed limits and grade
|
||||
auto textline =
|
||||
"Throttle: " + to_string( driver->Controlling()->MainCtrlPos, 0, 2 )
|
||||
+ "+" + std::to_string( driver->Controlling()->ScndCtrlPos )
|
||||
+ " "
|
||||
+ ( mover->ActiveDir > 0 ? 'D' :
|
||||
mover->ActiveDir < 0 ? 'R' :
|
||||
'N' );
|
||||
|
||||
if( is_expanded ) {
|
||||
|
||||
auto const speedlimit { static_cast<int>( std::floor( driver->VelDesired ) ) };
|
||||
textline +=
|
||||
" Speed: " + std::to_string( static_cast<int>( std::floor( mover->Vel ) ) ) + " km/h"
|
||||
+ " (limit: " + std::to_string( speedlimit ) + " km/h";
|
||||
auto const nextspeedlimit { static_cast<int>( std::floor( driver->VelNext ) ) };
|
||||
if( nextspeedlimit != speedlimit ) {
|
||||
textline +=
|
||||
", new limit: " + std::to_string( nextspeedlimit ) + " km/h"
|
||||
+ " in " + to_string( driver->ActualProximityDist * 0.001, 1 ) + " km";
|
||||
}
|
||||
textline += ")";
|
||||
auto const reverser { ( mover->ActiveDir > 0 ? 1 : -1 ) };
|
||||
auto const grade { controlled->VectorFront().y * 100 * ( controlled->DirectionGet() == reverser ? 1 : -1 ) * reverser };
|
||||
if( std::abs( grade ) >= 0.25 ) {
|
||||
textline += " Grade: " + to_string( grade, 1 ) + "%%";
|
||||
}
|
||||
}
|
||||
|
||||
text_lines.emplace_back( textline, Global.UITextColor );
|
||||
}
|
||||
|
||||
{ // brakes, air pressure
|
||||
auto textline =
|
||||
"Brakes:" + to_string( mover->fBrakeCtrlPos, 1, 5 )
|
||||
+ "+" + to_string( mover->LocalBrakePosA * LocalBrakePosNo, 0 )
|
||||
+ ( mover->SlippingWheels ? " !" : " " );
|
||||
if( textline.size() > 16 ) {
|
||||
textline.erase( 16 );
|
||||
}
|
||||
|
||||
if( is_expanded ) {
|
||||
|
||||
textline +=
|
||||
" Pressure: " + to_string( mover->BrakePress * 100.0, 2 ) + " kPa"
|
||||
+ " (train pipe: " + to_string( mover->PipePress * 100.0, 2 ) + " kPa)";
|
||||
}
|
||||
|
||||
text_lines.emplace_back( textline, Global.UITextColor );
|
||||
}
|
||||
|
||||
{ // alerter, hints
|
||||
std::string textline =
|
||||
( true == TestFlag( mover->SecuritySystem.Status, s_aware ) ?
|
||||
"!ALERTER! " :
|
||||
" " );
|
||||
textline +=
|
||||
( true == TestFlag( mover->SecuritySystem.Status, s_active ) ?
|
||||
"!SHP! " :
|
||||
" " );
|
||||
|
||||
if( is_expanded ) {
|
||||
|
||||
auto const stoptime { static_cast<int>( -1.0 * controlled->Mechanik->fStopTime ) };
|
||||
if( stoptime > 0 ) {
|
||||
textline += " Loading/unloading in progress (" + to_string( stoptime ) + ( stoptime > 1 ? " seconds" : " second" ) + " left)";
|
||||
}
|
||||
else {
|
||||
auto const trackblockdistance { std::abs( controlled->Mechanik->TrackBlock() ) };
|
||||
if( trackblockdistance <= 75.0 ) {
|
||||
textline += " Another vehicle ahead (distance: " + to_string( trackblockdistance, 1 ) + " m)";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
text_lines.emplace_back( textline, Global.UITextColor );
|
||||
}
|
||||
|
||||
auto const sizex = ( is_expanded ? 660 : 130 );
|
||||
size = { sizex, 85 };
|
||||
}
|
||||
|
||||
void
|
||||
timetable_panel::update() {
|
||||
|
||||
if( false == is_open ) { return; }
|
||||
|
||||
text_lines.clear();
|
||||
|
||||
auto const *train { simulation::Train };
|
||||
auto const *controlled { ( train ? train->Dynamic() : nullptr ) };
|
||||
auto const &camera { Global.pCamera };
|
||||
auto const &time { simulation::Time.data() };
|
||||
|
||||
{ // current time
|
||||
auto textline =
|
||||
"Time: "
|
||||
+ to_string( time.wHour ) + ":"
|
||||
+ ( time.wMinute < 10 ? "0" : "" ) + to_string( time.wMinute ) + ":"
|
||||
+ ( time.wSecond < 10 ? "0" : "" ) + to_string( time.wSecond );
|
||||
|
||||
text_lines.emplace_back( textline, Global.UITextColor );
|
||||
}
|
||||
|
||||
auto *vehicle {
|
||||
( FreeFlyModeFlag ?
|
||||
std::get<TDynamicObject *>( simulation::Region->find_vehicle( camera.Pos, 20, false, false ) ) :
|
||||
controlled ) }; // 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
|
||||
auto const *owner = (
|
||||
( ( vehicle->Mechanik != nullptr ) && ( vehicle->Mechanik->Primary() ) ) ?
|
||||
vehicle->Mechanik :
|
||||
vehicle->ctOwner );
|
||||
if( owner == nullptr ) { return; }
|
||||
|
||||
auto const *table = owner->TrainTimetable();
|
||||
if( table == nullptr ) { return; }
|
||||
|
||||
{ // destination
|
||||
auto textline = Bezogonkow( owner->Relation(), true );
|
||||
if( false == textline.empty() ) {
|
||||
textline += " (" + Bezogonkow( owner->TrainName(), true ) + ")";
|
||||
}
|
||||
|
||||
text_lines.emplace_back( textline, Global.UITextColor );
|
||||
}
|
||||
|
||||
{ // next station
|
||||
auto const nextstation = Bezogonkow( owner->NextStop(), true );
|
||||
if( false == nextstation.empty() ) {
|
||||
// jeśli jest podana relacja, to dodajemy punkt następnego zatrzymania
|
||||
auto textline = " -> " + nextstation;
|
||||
|
||||
text_lines.emplace_back( textline, Global.UITextColor );
|
||||
}
|
||||
}
|
||||
|
||||
if( is_expanded ) {
|
||||
|
||||
text_lines.emplace_back( "", Global.UITextColor );
|
||||
|
||||
if( 0 == table->StationCount ) {
|
||||
// only bother if there's stations to list
|
||||
text_lines.emplace_back( "(no timetable)", Global.UITextColor );
|
||||
}
|
||||
else {
|
||||
auto const readycolor { glm::vec4( 84.0f / 255.0f, 164.0f / 255.0f, 132.0f / 255.0f, 1.f ) };
|
||||
// header
|
||||
text_lines.emplace_back( "+-----+------------------------------------+-------+-----+", Global.UITextColor );
|
||||
|
||||
TMTableLine const *tableline;
|
||||
for( int i = owner->iStationStart; i <= table->StationCount; ++i ) {
|
||||
// wyświetlenie pozycji z rozkładu
|
||||
tableline = table->TimeTable + i; // linijka rozkładu
|
||||
|
||||
std::string vmax =
|
||||
" "
|
||||
+ to_string( tableline->vmax, 0 );
|
||||
vmax = vmax.substr( vmax.size() - 3, 3 ); // z wyrównaniem do prawej
|
||||
std::string const station = (
|
||||
Bezogonkow( tableline->StationName, true )
|
||||
+ " " )
|
||||
.substr( 0, 34 );
|
||||
std::string const location = (
|
||||
( tableline->km > 0.0 ?
|
||||
to_string( tableline->km, 2 ) :
|
||||
"" )
|
||||
+ " " )
|
||||
.substr( 0, 34 - tableline->StationWare.size() );
|
||||
std::string const arrival = (
|
||||
tableline->Ah >= 0 ?
|
||||
to_string( int( 100 + tableline->Ah ) ).substr( 1, 2 ) + ":" + to_string( int( 100 + tableline->Am ) ).substr( 1, 2 ) :
|
||||
" | " );
|
||||
std::string const departure = (
|
||||
tableline->Dh >= 0 ?
|
||||
to_string( int( 100 + tableline->Dh ) ).substr( 1, 2 ) + ":" + to_string( int( 100 + tableline->Dm ) ).substr( 1, 2 ) :
|
||||
" | " );
|
||||
auto const candeparture = (
|
||||
( owner->iStationStart < table->StationIndex )
|
||||
&& ( i < table->StationIndex )
|
||||
&& ( ( time.wHour * 60 + time.wMinute ) >= ( tableline->Dh * 60 + tableline->Dm ) ) );
|
||||
auto traveltime =
|
||||
" "
|
||||
+ ( i < 2 ? "" :
|
||||
tableline->Ah >= 0 ? to_string( CompareTime( table->TimeTable[ i - 1 ].Dh, table->TimeTable[ i - 1 ].Dm, tableline->Ah, tableline->Am ), 0 ) :
|
||||
to_string( std::max( 0.0, CompareTime( table->TimeTable[ i - 1 ].Dh, table->TimeTable[ i - 1 ].Dm, tableline->Dh, tableline->Dm ) - 0.5 ), 0 ) );
|
||||
traveltime = traveltime.substr( traveltime.size() - 3, 3 ); // z wyrównaniem do prawej
|
||||
|
||||
text_lines.emplace_back(
|
||||
( "| " + vmax + " | " + station + " | " + arrival + " | " + traveltime + " |" ),
|
||||
( candeparture ?
|
||||
readycolor :// czas minął i odjazd był, to nazwa stacji będzie na zielono
|
||||
Global.UITextColor ) );
|
||||
text_lines.emplace_back(
|
||||
( "| | " + location + tableline->StationWare + " | " + departure + " | |" ),
|
||||
( candeparture ?
|
||||
readycolor :// czas minął i odjazd był, to nazwa stacji będzie na zielono
|
||||
Global.UITextColor ) );
|
||||
// divider/footer
|
||||
text_lines.emplace_back( "+-----+------------------------------------+-------+-----+", Global.UITextColor );
|
||||
}
|
||||
}
|
||||
} // is_expanded
|
||||
}
|
||||
|
||||
void
|
||||
debug_panel::update() {
|
||||
|
||||
if( false == is_open ) { return; }
|
||||
|
||||
// input item bindings
|
||||
m_input.train = simulation::Train;
|
||||
m_input.controlled = ( m_input.train ? m_input.train->Dynamic() : nullptr );
|
||||
m_input.camera = &( Global.pCamera );
|
||||
m_input.vehicle =
|
||||
( FreeFlyModeFlag ?
|
||||
std::get<TDynamicObject *>( simulation::Region->find_vehicle( m_input.camera->Pos, 20, false, false ) ) :
|
||||
m_input.controlled ); // w trybie latania lokalizujemy wg mapy
|
||||
m_input.mover =
|
||||
( m_input.vehicle != nullptr ?
|
||||
m_input.vehicle->MoverParameters :
|
||||
nullptr );
|
||||
m_input.mechanik = (
|
||||
m_input.vehicle != nullptr ?
|
||||
m_input.vehicle->Mechanik :
|
||||
nullptr );
|
||||
|
||||
// header section
|
||||
text_lines.clear();
|
||||
|
||||
auto textline = "Version " + Global.asVersion;
|
||||
|
||||
text_lines.emplace_back( textline, Global.UITextColor );
|
||||
|
||||
// sub-sections
|
||||
m_vehiclelines.clear();
|
||||
m_enginelines.clear();
|
||||
m_ailines.clear();
|
||||
m_scantablelines.clear();
|
||||
m_scenariolines.clear();
|
||||
m_eventqueuelines.clear();
|
||||
m_cameralines.clear();
|
||||
m_rendererlines.clear();
|
||||
|
||||
update_section_vehicle( m_vehiclelines );
|
||||
update_section_engine( m_enginelines );
|
||||
update_section_ai( m_ailines );
|
||||
update_section_scantable( m_scantablelines );
|
||||
update_section_scenario( m_scenariolines );
|
||||
update_section_eventqueue( m_eventqueuelines );
|
||||
update_section_camera( m_cameralines );
|
||||
update_section_renderer( m_rendererlines );
|
||||
}
|
||||
|
||||
void
|
||||
debug_panel::render() {
|
||||
|
||||
if( false == is_open ) { return; }
|
||||
|
||||
auto flags =
|
||||
ImGuiWindowFlags_NoFocusOnAppearing
|
||||
| ImGuiWindowFlags_NoCollapse
|
||||
| ( size.x > 0 ? ImGuiWindowFlags_NoResize : 0 );
|
||||
|
||||
if( size.x > 0 ) {
|
||||
ImGui::SetNextWindowSize( ImVec2( size.x, size.y ) );
|
||||
}
|
||||
if( size_min.x > 0 ) {
|
||||
ImGui::SetNextWindowSizeConstraints( ImVec2( size_min.x, size_min.y ), ImVec2( size_max.x, size_max.y ) );
|
||||
}
|
||||
if( true == ImGui::Begin( name.c_str(), &is_open, flags ) ) {
|
||||
// header section
|
||||
for( auto const &line : text_lines ) {
|
||||
ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), line.data.c_str() );
|
||||
}
|
||||
// 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 );
|
||||
render_section( "Scenario Event Queue", m_eventqueuelines );
|
||||
render_section( "Camera", m_cameralines );
|
||||
render_section( "Gfx Renderer", m_rendererlines );
|
||||
// toggles
|
||||
ImGui::Separator();
|
||||
ImGui::Checkbox( "Debug Mode", &DebugModeFlag );
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void
|
||||
debug_panel::update_section_vehicle( std::vector<text_line> &Output ) {
|
||||
|
||||
if( m_input.vehicle == nullptr ) { return; }
|
||||
if( m_input.mover == nullptr ) { return; }
|
||||
|
||||
auto const &vehicle { *m_input.vehicle };
|
||||
auto const &mover { *m_input.mover };
|
||||
|
||||
// f3 data
|
||||
auto textline = "Vehicle name: " + mover.Name;
|
||||
|
||||
if( ( vehicle.Mechanik == nullptr ) && ( vehicle.ctOwner ) ) {
|
||||
// for cars other than leading unit indicate the leader
|
||||
textline += ", owned by " + vehicle.ctOwner->OwnerName();
|
||||
}
|
||||
textline += "\nStatus: " + mover.EngineDescription( 0 );
|
||||
if( mover.WheelFlat > 0.01 ) {
|
||||
textline += " Flat: " + to_string( mover.WheelFlat, 1 ) + " mm";
|
||||
}
|
||||
|
||||
// informacja o sprzęgach
|
||||
textline +=
|
||||
"\nC0:" +
|
||||
( vehicle.PrevConnected ?
|
||||
vehicle.PrevConnected->name() + ":" + to_string( mover.Couplers[ 0 ].CouplingFlag ) + (
|
||||
mover.Couplers[ 0 ].CouplingFlag == 0 ?
|
||||
" (" + to_string( mover.Couplers[ 0 ].CoupleDist, 1 ) + " m)" :
|
||||
"" ) :
|
||||
"none" );
|
||||
textline +=
|
||||
" C1:" +
|
||||
( vehicle.NextConnected ?
|
||||
vehicle.NextConnected->name() + ":" + to_string( mover.Couplers[ 1 ].CouplingFlag ) + (
|
||||
mover.Couplers[ 1 ].CouplingFlag == 0 ?
|
||||
" (" + to_string( mover.Couplers[ 1 ].CoupleDist, 1 ) + " m)" :
|
||||
"" ) :
|
||||
"none" );
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
|
||||
// equipment flags
|
||||
textline = ( mover.Battery ? "B" : "." );
|
||||
textline += ( mover.Mains ? "M" : "." );
|
||||
textline += ( mover.PantRearUp ? ( mover.PantRearVolt > 0.0 ? "O" : "o" ) : "." );
|
||||
textline += ( mover.PantFrontUp ? ( mover.PantFrontVolt > 0.0 ? "P" : "p" ) : "." );
|
||||
textline += ( mover.PantPressLockActive ? "!" : ( mover.PantPressSwitchActive ? "*" : "." ) );
|
||||
textline += ( mover.WaterPump.is_active ? "W" : ( false == mover.WaterPump.breaker ? "-" : ( mover.WaterPump.is_enabled ? "w" : "." ) ) );
|
||||
textline += ( true == mover.WaterHeater.is_damaged ? "!" : ( mover.WaterHeater.is_active ? "H" : ( false == mover.WaterHeater.breaker ? "-" : ( mover.WaterHeater.is_enabled ? "h" : "." ) ) ) );
|
||||
textline += ( mover.FuelPump.is_active ? "F" : ( mover.FuelPump.is_enabled ? "f" : "." ) );
|
||||
textline += ( mover.OilPump.is_active ? "O" : ( mover.OilPump.is_enabled ? "o" : "." ) );
|
||||
textline += ( false == mover.ConverterAllowLocal ? "-" : ( mover.ConverterAllow ? ( mover.ConverterFlag ? "X" : "x" ) : "." ) );
|
||||
textline += ( mover.ConvOvldFlag ? "!" : "." );
|
||||
textline += ( mover.CompressorFlag ? "C" : ( false == mover.CompressorAllowLocal ? "-" : ( ( mover.CompressorAllow || mover.CompressorStart == start_t::automatic ) ? "c" : "." ) ) );
|
||||
textline += ( mover.CompressorGovernorLock ? "!" : "." );
|
||||
|
||||
if( ( m_input.train != nullptr ) && ( m_input.train->Dynamic() == m_input.vehicle ) ) {
|
||||
textline += ( mover.Radio ? " R: " : " r: " ) + std::to_string( m_input.train->RadioChannel() );
|
||||
}
|
||||
textline += " Bdelay: ";
|
||||
if( ( mover.BrakeDelayFlag & bdelay_G ) == bdelay_G )
|
||||
textline += "G";
|
||||
if( ( mover.BrakeDelayFlag & bdelay_P ) == bdelay_P )
|
||||
textline += "P";
|
||||
if( ( mover.BrakeDelayFlag & bdelay_R ) == bdelay_R )
|
||||
textline += "R";
|
||||
if( ( mover.BrakeDelayFlag & bdelay_M ) == bdelay_M )
|
||||
textline += "+Mg";
|
||||
|
||||
textline += ", Load: " + to_string( mover.Load, 0 ) + " (" + to_string( mover.LoadFlag, 0 ) + ")";
|
||||
|
||||
textline +=
|
||||
"\nFt: " + to_string(
|
||||
mover.Ft * 0.001f * (
|
||||
mover.ActiveCab ? mover.ActiveCab :
|
||||
vehicle.ctOwner ? vehicle.ctOwner->Controlling()->ActiveCab :
|
||||
1 ), 1 )
|
||||
+ ", Fb: " + to_string( mover.Fb * 0.001f, 1 )
|
||||
+ ", Fr: " + to_string( mover.Adhesive( mover.RunningTrack.friction ), 2 )
|
||||
+ ( mover.SlippingWheels ? " (!)" : "" );
|
||||
|
||||
textline +=
|
||||
"\nPant: "
|
||||
+ to_string( mover.PantPress, 2 )
|
||||
+ ( mover.bPantKurek3 ? "-ZG" : "|ZG" );
|
||||
textline +=
|
||||
" TC:"
|
||||
+ to_string( mover.TotalCurrent, 0 );
|
||||
auto const frontcouplerhighvoltage =
|
||||
to_string( mover.Couplers[ side::front ].power_high.voltage, 0 )
|
||||
+ "@"
|
||||
+ to_string( mover.Couplers[ side::front ].power_high.current, 0 );
|
||||
auto const rearcouplerhighvoltage =
|
||||
to_string( mover.Couplers[ side::rear ].power_high.voltage, 0 )
|
||||
+ "@"
|
||||
+ to_string( mover.Couplers[ side::rear ].power_high.current, 0 );
|
||||
textline += ", HV: ";
|
||||
if( mover.Couplers[ side::front ].power_high.local == false ) {
|
||||
textline +=
|
||||
"(" + frontcouplerhighvoltage + ")-"
|
||||
+ ":F" + ( vehicle.DirectionGet() ? "<<" : ">>" ) + "R:"
|
||||
+ "-(" + rearcouplerhighvoltage + ")";
|
||||
}
|
||||
else {
|
||||
textline +=
|
||||
frontcouplerhighvoltage
|
||||
+ ":F" + ( vehicle.DirectionGet() ? "<<" : ">>" ) + "R:"
|
||||
+ rearcouplerhighvoltage;
|
||||
}
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
|
||||
textline =
|
||||
"TrB: " + to_string( mover.BrakePress, 2 )
|
||||
+ ", " + to_hex_str( mover.Hamulec->GetBrakeStatus(), 2 );
|
||||
|
||||
textline +=
|
||||
"; LcB: " + to_string( mover.LocBrakePress, 2 )
|
||||
+ "; hat: " + to_string( mover.BrakeCtrlPos2, 2 )
|
||||
+ "\npipes: " + to_string( mover.PipePress, 2 )
|
||||
+ "/" + to_string( mover.ScndPipePress, 2 )
|
||||
+ "/" + to_string( mover.EqvtPipePress, 2 )
|
||||
+ "\nMT: " + to_string( mover.CompressedVolume, 3 )
|
||||
+ ", BT: " + to_string( mover.Volume, 3 )
|
||||
+ ", CtlP: " + to_string( mover.CntrlPipePress, 3 )
|
||||
+ ", CtlT: " + to_string( mover.Hamulec->GetCRP(), 3 );
|
||||
|
||||
if( mover.ManualBrakePos > 0 ) {
|
||||
|
||||
textline += "; manual brake on";
|
||||
}
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
|
||||
// debug mode f1 data
|
||||
textline =
|
||||
"vel: " + to_string( vehicle.GetVelocity(), 2 ) + "/" + to_string( mover.nrot* M_PI * mover.WheelDiameter * 3.6, 2 )
|
||||
+ " km/h;"
|
||||
+ " dist: " + to_string( mover.DistCounter, 2 ) + " km"
|
||||
+ "\npos: [" + to_string( vehicle.GetPosition().x, 2 ) + ", " + to_string( vehicle.GetPosition().y, 2 ) + ", " + to_string( vehicle.GetPosition().z, 2 ) + "]"
|
||||
+ "\nenpwr=" + to_string( mover.EnginePower, 1 )
|
||||
+ "; enrot=" + to_string( mover.enrot * 60, 0 )
|
||||
+ " tmrot=" + to_string( std::abs( mover.nrot ) * mover.Transmision.Ratio * 60, 0 )
|
||||
+ "; ventrot=" + to_string( mover.RventRot * 60, 1 )
|
||||
+ "; fanrot=" + to_string( mover.dizel_heat.rpmw, 1 ) + ", " + to_string( mover.dizel_heat.rpmw2, 1 );
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
|
||||
textline =
|
||||
"HamZ=" + to_string( mover.fBrakeCtrlPos, 2 )
|
||||
+ "; HamP=" + to_string( mover.LocalBrakePosA, 2 )
|
||||
+ "; NasJ=" + std::to_string( mover.MainCtrlPos ) + "(" + std::to_string( mover.MainCtrlActualPos ) + ")"
|
||||
+ ( ( mover.ShuntMode && mover.EngineType == TEngineType::DieselElectric ) ?
|
||||
"; NasB=" + to_string( mover.AnPos, 2 ) :
|
||||
"; NasB=" + std::to_string( mover.ScndCtrlPos ) + "(" + std::to_string( mover.ScndCtrlActualPos ) + ")" )
|
||||
+ "\nI=" +
|
||||
( mover.TrainType == dt_EZT ?
|
||||
std::to_string( int( mover.ShowCurrent( 0 ) ) ) :
|
||||
std::to_string( int( mover.Im ) ) )
|
||||
+ "; U=" + to_string( int( mover.RunningTraction.TractionVoltage + 0.5 ) )
|
||||
+ "; R=" +
|
||||
( std::abs( mover.RunningShape.R ) > 10000.0 ?
|
||||
"~0.0" :
|
||||
to_string( mover.RunningShape.R, 1 ) )
|
||||
+ " An=" + to_string( mover.AccN, 2 ); // przyspieszenie poprzeczne
|
||||
|
||||
if( tprev != simulation::Time.data().wSecond ) {
|
||||
tprev = simulation::Time.data().wSecond;
|
||||
Acc = ( mover.Vel - VelPrev ) / 3.6;
|
||||
VelPrev = mover.Vel;
|
||||
}
|
||||
textline += "; As=" + to_string( Acc, 2 ); // przyspieszenie wzdłużne
|
||||
// uitextline2 += " eAngle=" + to_string( std::cos( mover.eAngle ), 2 );
|
||||
textline += "\noilP=" + to_string( mover.OilPump.pressure_present, 3 );
|
||||
textline += " oilT=" + to_string( mover.dizel_heat.To, 2 );
|
||||
textline += "; waterT=" + to_string( mover.dizel_heat.temperatura1, 2 );
|
||||
textline += ( mover.WaterCircuitsLink ? "-" : "|" );
|
||||
textline += to_string( mover.dizel_heat.temperatura2, 2 );
|
||||
textline += "; engineT=" + to_string( mover.dizel_heat.Ts, 2 );
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
|
||||
textline =
|
||||
"cyl.ham. " + to_string( mover.BrakePress, 2 )
|
||||
+ "; prz.gl. " + to_string( mover.PipePress, 2 )
|
||||
+ "; zb.gl. " + to_string( mover.CompressedVolume, 2 )
|
||||
// youBy - drugi wezyk
|
||||
+ "; p.zas. " + to_string( mover.ScndPipePress, 2 );
|
||||
|
||||
// McZapkie: warto wiedziec w jakim stanie sa przelaczniki
|
||||
if( mover.ConvOvldFlag )
|
||||
textline += " C! ";
|
||||
else if( mover.FuseFlag )
|
||||
textline += " F! ";
|
||||
else if( !mover.Mains )
|
||||
textline += " () ";
|
||||
else {
|
||||
switch(
|
||||
mover.ActiveDir *
|
||||
( mover.Imin == mover.IminLo ?
|
||||
1 :
|
||||
2 ) ) {
|
||||
case 2: { textline += " >> "; break; }
|
||||
case 1: { textline += " -> "; break; }
|
||||
case 0: { textline += " -- "; break; }
|
||||
case -1: { textline += " <- "; break; }
|
||||
case -2: { textline += " << "; break; }
|
||||
}
|
||||
}
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
|
||||
// McZapkie: komenda i jej parametry
|
||||
if( mover.CommandIn.Command != ( "" ) ) {
|
||||
textline =
|
||||
"C:" + mover.CommandIn.Command
|
||||
+ " V1=" + to_string( mover.CommandIn.Value1, 0 )
|
||||
+ " V2=" + to_string( mover.CommandIn.Value2, 0 );
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
debug_panel::update_section_engine( std::vector<text_line> &Output ) {
|
||||
|
||||
if( m_input.train == nullptr ) { return; }
|
||||
if( m_input.vehicle == nullptr ) { return; }
|
||||
if( m_input.mover == nullptr ) { return; }
|
||||
|
||||
auto const &train { *m_input.train };
|
||||
auto const &vehicle{ *m_input.vehicle };
|
||||
auto const &mover{ *m_input.mover };
|
||||
|
||||
// engine data
|
||||
// induction motor data
|
||||
if( mover.EngineType == TEngineType::ElectricInductionMotor ) {
|
||||
|
||||
Output.emplace_back( " eimc: eimv: press:", Global.UITextColor );
|
||||
for( int i = 0; i <= 20; ++i ) {
|
||||
|
||||
std::string parameters =
|
||||
mover.eimc_labels[ i ] + to_string( mover.eimc[ i ], 2, 9 )
|
||||
+ " | "
|
||||
+ mover.eimv_labels[ i ] + to_string( mover.eimv[ i ], 2, 9 );
|
||||
|
||||
if( i < 10 ) {
|
||||
parameters += " | " + train.fPress_labels[i] + to_string( train.fPress[ i ][ 0 ], 2, 9 );
|
||||
}
|
||||
else if( i == 12 ) {
|
||||
parameters += " med:";
|
||||
}
|
||||
else if( i >= 13 ) {
|
||||
parameters += " | " + vehicle.MED_labels[ i - 13 ] + to_string( vehicle.MED[ 0 ][ i - 13 ], 2, 9 );
|
||||
}
|
||||
|
||||
Output.emplace_back( parameters, Global.UITextColor );
|
||||
}
|
||||
}
|
||||
if ( mover.EngineType == TEngineType::DieselEngine) {
|
||||
std::string parameters = "param value";
|
||||
Output.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "efill: " + to_string( mover.dizel_fill, 2, 9);
|
||||
Output.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "etorq: " + to_string( mover.dizel_Torque, 2, 9);
|
||||
Output.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "creal: " + to_string( mover.dizel_engage, 2, 9);
|
||||
Output.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "cdesi: " + to_string( mover.dizel_engagestate, 2, 9);
|
||||
Output.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "cdelt: " + to_string( mover.dizel_engagedeltaomega, 2, 9);
|
||||
Output.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "gears: " + to_string( mover.dizel_automaticgearstatus, 2, 9);
|
||||
Output.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "hydro value";
|
||||
Output.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "hTCnI: " + to_string( mover.hydro_TC_nIn, 2, 9);
|
||||
Output.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "hTCnO: " + to_string( mover.hydro_TC_nOut, 2, 9);
|
||||
Output.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "hTCTM: " + to_string( mover.hydro_TC_TMRatio, 2, 9);
|
||||
Output.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "hTCTI: " + to_string( mover.hydro_TC_TorqueIn, 2, 9);
|
||||
Output.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "hTCTO: " + to_string( mover.hydro_TC_TorqueOut, 2, 9);
|
||||
Output.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "hTCfl: " + to_string( mover.hydro_TC_Fill, 2, 9);
|
||||
Output.emplace_back(parameters, Global.UITextColor);
|
||||
parameters = "hTCLR: " + to_string( mover.hydro_TC_LockupRate, 2, 9);
|
||||
Output.emplace_back(parameters, Global.UITextColor);
|
||||
//parameters = "hTCXX: " + to_string(mover->hydro_TC_nIn, 2, 9);
|
||||
//engine_lines.emplace_back(parameters, Global.UITextColor);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
debug_panel::update_section_ai( std::vector<text_line> &Output ) {
|
||||
|
||||
if( m_input.mover == nullptr ) { return; }
|
||||
if( m_input.mechanik == nullptr ) { return; }
|
||||
|
||||
auto const &mover{ *m_input.mover };
|
||||
auto const &mechanik{ *m_input.mechanik };
|
||||
|
||||
// biezaca komenda dla AI
|
||||
auto textline = "Current order: " + mechanik.OrderCurrent();
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
|
||||
if( ( mechanik.VelNext == 0.0 )
|
||||
&& ( mechanik.eSignNext ) ) {
|
||||
// jeśli ma zapamiętany event semafora, nazwa eventu semafora
|
||||
Output.emplace_back( "Current signal: " + Bezogonkow( mechanik.eSignNext->asName ), Global.UITextColor );
|
||||
}
|
||||
|
||||
// distances
|
||||
textline =
|
||||
"Distances:\n proximity: " + to_string( mechanik.ActualProximityDist, 0 )
|
||||
+ ", braking: " + to_string( mechanik.fBrakeDist, 0 );
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
|
||||
// velocity factors
|
||||
textline =
|
||||
"Velocity:\n desired: " + to_string( mechanik.VelDesired, 0 )
|
||||
+ ", next: " + to_string( mechanik.VelNext, 0 );
|
||||
|
||||
std::vector< std::pair< double, std::string > > const restrictions{
|
||||
{ mechanik.VelSignalLast, "signal" },
|
||||
{ mechanik.VelLimitLast, "limit" },
|
||||
{ mechanik.VelRoad, "road" },
|
||||
{ mechanik.VelRestricted, "restricted" },
|
||||
{ mover.RunningTrack.Velmax, "track" } };
|
||||
|
||||
std::string restrictionstext;
|
||||
for( auto const &restriction : restrictions ) {
|
||||
if( restriction.first < 0.0 ) { continue; }
|
||||
if( false == restrictionstext.empty() ) {
|
||||
restrictionstext += ", ";
|
||||
}
|
||||
restrictionstext +=
|
||||
to_string( restriction.first, 0 )
|
||||
+ " (" + restriction.second + ")";
|
||||
}
|
||||
|
||||
if( false == restrictionstext.empty() ) {
|
||||
textline += "\n restrictions: " + restrictionstext;
|
||||
}
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
|
||||
// acceleration
|
||||
textline =
|
||||
"Acceleration:\n desired: " + to_string( mechanik.AccDesired, 2 )
|
||||
+ ", corrected: " + to_string( mechanik.AccDesired * mechanik.BrakeAccFactor(), 2 )
|
||||
+ "\n current: " + to_string( mechanik.AbsAccS_pub, 2 )
|
||||
+ ", slope: " + to_string( mechanik.fAccGravity, 2 ) + " (" + ( mechanik.fAccGravity > 0.01 ? "\\" : ( mechanik.fAccGravity < -0.01 ? "/" : "-" ) ) + ")"
|
||||
+ "\n brake threshold: " + to_string( mechanik.fAccThreshold, 2 )
|
||||
+ ", delays: " + to_string( mechanik.fBrake_a0[ 0 ], 2 )
|
||||
+ "+" + to_string( mechanik.fBrake_a1[ 0 ], 2 );
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
|
||||
// ai driving flags
|
||||
std::vector<std::string> const drivingflagnames {
|
||||
"StopCloser", "StopPoint", "Active", "Press", "Connect", "Primary", "Late", "StopHere",
|
||||
"StartHorn", "StartHornNow", "StartHornDone", "Oerlikons", "IncSpeed", "TrackEnd", "SwitchFound", "GuardSignal",
|
||||
"Visibility", "DoorOpened", "PushPull", "SemaphorFound", "SemaphorWasElapsed", "TrainInsideStation", "SpeedLimitFound" };
|
||||
|
||||
textline = "Driving flags:";
|
||||
for( int idx = 0, flagbit = 1; idx < drivingflagnames.size(); ++idx, flagbit <<= 1 ) {
|
||||
if( mechanik.DrivigFlags() & flagbit ) {
|
||||
textline += "\n " + drivingflagnames[ idx ];
|
||||
}
|
||||
}
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
}
|
||||
|
||||
void
|
||||
debug_panel::update_section_scantable( std::vector<text_line> &Output ) {
|
||||
|
||||
if( m_input.mechanik == nullptr ) { return; }
|
||||
|
||||
auto const &mechanik{ *m_input.mechanik };
|
||||
|
||||
std::size_t i = 0; std::size_t const speedtablesize = clamp( static_cast<int>( mechanik.TableSize() ) - 1, 0, 30 );
|
||||
do {
|
||||
auto const scanline = mechanik.TableText( i );
|
||||
if( scanline.empty() ) { break; }
|
||||
Output.emplace_back( Bezogonkow( scanline ), Global.UITextColor );
|
||||
++i;
|
||||
} while( i < speedtablesize );
|
||||
if( Output.empty() ) {
|
||||
Output.emplace_back( "(no points of interest)", Global.UITextColor );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
debug_panel::update_section_scenario( std::vector<text_line> &Output ) {
|
||||
|
||||
auto textline =
|
||||
"vehicles: " + to_string( Timer::subsystem.sim_dynamics.average(), 2 ) + " msec"
|
||||
+ " update total: " + to_string( Timer::subsystem.sim_total.average(), 2 ) + " msec";
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
// current luminance level
|
||||
textline = "Light level: " + to_string( Global.fLuminance, 3 );
|
||||
if( Global.FakeLight ) { textline += "(*)"; }
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
}
|
||||
|
||||
void
|
||||
debug_panel::update_section_eventqueue( std::vector<text_line> &Output ) {
|
||||
|
||||
std::string textline;
|
||||
|
||||
// current event queue
|
||||
auto const time { Timer::GetTime() };
|
||||
auto const *event { simulation::Events.begin() };
|
||||
auto eventtableindex{ 0 };
|
||||
while( ( event != nullptr )
|
||||
&& ( eventtableindex < 30 ) ) {
|
||||
|
||||
if( ( false == event->m_ignored )
|
||||
&& ( true == event->bEnabled ) ) {
|
||||
|
||||
auto const delay { " " + to_string( std::max( 0.0, event->fStartTime - time ), 1 ) };
|
||||
textline =
|
||||
"Delay: " + delay.substr( delay.length() - 6 )
|
||||
+ ", Event: " + event->asName
|
||||
+ ( event->Activator ? " (by: " + event->Activator->asName + ")" : "" )
|
||||
+ ( event->evJoined ? " (joint event)" : "" );
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
++eventtableindex;
|
||||
}
|
||||
event = event->evNext;
|
||||
}
|
||||
if( Output.empty() ) {
|
||||
textline = "(no queued events)";
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
debug_panel::update_section_camera( std::vector<text_line> &Output ) {
|
||||
|
||||
if( m_input.camera == nullptr ) { return; }
|
||||
|
||||
auto const &camera{ *m_input.camera };
|
||||
|
||||
// camera data
|
||||
auto textline =
|
||||
"Position: ["
|
||||
+ to_string( camera.Pos.x, 2 ) + ", "
|
||||
+ to_string( camera.Pos.y, 2 ) + ", "
|
||||
+ to_string( camera.Pos.z, 2 ) + "]";
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
|
||||
textline =
|
||||
"Azimuth: "
|
||||
+ to_string( 180.0 - glm::degrees( camera.Yaw ), 0 ) // ma być azymut, czyli 0 na północy i rośnie na wschód
|
||||
+ " "
|
||||
+ std::string( "S SEE NEN NWW SW" )
|
||||
.substr( 0 + 2 * floor( fmod( 8 + ( camera.Yaw + 0.5 * M_PI_4 ) / M_PI_4, 8 ) ), 2 );
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
}
|
||||
|
||||
void
|
||||
debug_panel::update_section_renderer( std::vector<text_line> &Output ) {
|
||||
|
||||
// gfx renderer data
|
||||
auto textline =
|
||||
"FoV: " + to_string( Global.FieldOfView / Global.ZoomFactor, 1 )
|
||||
+ ", Draw range x " + to_string( Global.fDistanceFactor, 1 )
|
||||
// + "; sectors: " + std::to_string( GfxRenderer.m_drawcount )
|
||||
// + ", FPS: " + to_string( Timer::GetFPS(), 2 );
|
||||
+ ", FPS: " + std::to_string( static_cast<int>(std::round(GfxRenderer.Framerate())) );
|
||||
if( Global.iSlowMotion ) {
|
||||
textline += " (slowmotion " + to_string( Global.iSlowMotion ) + ")";
|
||||
}
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
|
||||
textline =
|
||||
std::string( "Rendering mode: " )
|
||||
+ ( Global.bUseVBO ?
|
||||
"VBO" :
|
||||
"Display Lists" )
|
||||
+ " ";
|
||||
if( false == Global.LastGLError.empty() ) {
|
||||
textline +=
|
||||
"Last openGL error: "
|
||||
+ Global.LastGLError;
|
||||
}
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
|
||||
// renderer stats
|
||||
Output.emplace_back( GfxRenderer.info_times(), Global.UITextColor );
|
||||
Output.emplace_back( GfxRenderer.info_stats(), Global.UITextColor );
|
||||
}
|
||||
|
||||
void
|
||||
debug_panel::render_section( std::string const &Header, std::vector<text_line> const &Lines ) {
|
||||
|
||||
if( Lines.empty() ) { return; }
|
||||
if( false == ImGui::CollapsingHeader( Header.c_str() ) ) { return; }
|
||||
|
||||
for( auto const &line : Lines ) {
|
||||
ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), line.data.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
transcripts_panel::update() {
|
||||
|
||||
if( false == is_open ) { return; }
|
||||
|
||||
text_lines.clear();
|
||||
|
||||
for( auto const &transcript : ui::Transcripts.aLines ) {
|
||||
if( Global.fTimeAngleDeg >= transcript.fShow ) {
|
||||
// NOTE: legacy transcript lines use | as new line mark
|
||||
text_lines.emplace_back( ExchangeCharInString( transcript.asText, '|', ' ' ), colors::white );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
transcripts_panel::render() {
|
||||
|
||||
if( false == is_open ) { return; }
|
||||
if( true == text_lines.empty() ) { return; }
|
||||
|
||||
auto flags =
|
||||
ImGuiWindowFlags_NoFocusOnAppearing
|
||||
| ImGuiWindowFlags_NoCollapse
|
||||
| ( size.x > 0 ? ImGuiWindowFlags_NoResize : 0 );
|
||||
|
||||
if( size.x > 0 ) {
|
||||
ImGui::SetNextWindowSize( ImVec2( size.x, size.y ) );
|
||||
}
|
||||
if( size_min.x > 0 ) {
|
||||
ImGui::SetNextWindowSizeConstraints( ImVec2( size_min.x, size_min.y ), ImVec2( size_max.x, size_max.y ) );
|
||||
}
|
||||
if( true == ImGui::Begin( name.c_str(), &is_open, flags ) ) {
|
||||
// header section
|
||||
for( auto const &line : text_lines ) {
|
||||
ImGui::TextWrapped( line.data.c_str() );
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
93
driveruipanels.h
Normal file
93
driveruipanels.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "uilayer.h"
|
||||
#include "classes.h"
|
||||
|
||||
class drivingaid_panel : public ui_panel {
|
||||
|
||||
public:
|
||||
drivingaid_panel( std::string const Name, bool const Isopen )
|
||||
: ui_panel( Name, Isopen )
|
||||
{}
|
||||
|
||||
void update() override;
|
||||
|
||||
bool is_expanded { false };
|
||||
};
|
||||
|
||||
class timetable_panel : public ui_panel {
|
||||
|
||||
public:
|
||||
timetable_panel( std::string const Name, bool const Isopen )
|
||||
: ui_panel( Name, Isopen ) {}
|
||||
|
||||
void update() override;
|
||||
|
||||
bool is_expanded{ false };
|
||||
};
|
||||
|
||||
class debug_panel : public ui_panel {
|
||||
|
||||
public:
|
||||
debug_panel( std::string const Name, bool const Isopen )
|
||||
: ui_panel( Name, Isopen ) {}
|
||||
|
||||
void update() override;
|
||||
void render() override;
|
||||
|
||||
private:
|
||||
// types
|
||||
struct input_data {
|
||||
TTrain const *train;
|
||||
TDynamicObject const *controlled;
|
||||
TCamera const *camera;
|
||||
TDynamicObject const *vehicle;
|
||||
TMoverParameters const *mover;
|
||||
TController const *mechanik;
|
||||
};
|
||||
// methods
|
||||
// generate and send section data to provided output
|
||||
void update_section_vehicle( std::vector<text_line> &Output );
|
||||
void update_section_engine( std::vector<text_line> &Output );
|
||||
void update_section_ai( std::vector<text_line> &Output );
|
||||
void update_section_scantable( std::vector<text_line> &Output );
|
||||
void update_section_scenario( std::vector<text_line> &Output );
|
||||
void update_section_eventqueue( std::vector<text_line> &Output );
|
||||
void update_section_camera( std::vector<text_line> &Output );
|
||||
void update_section_renderer( std::vector<text_line> &Output );
|
||||
// renders provided lines, under specified collapsing header
|
||||
void render_section( std::string const &Header, std::vector<text_line> const &Lines );
|
||||
// members
|
||||
input_data m_input;
|
||||
std::vector<text_line>
|
||||
m_vehiclelines,
|
||||
m_enginelines,
|
||||
m_ailines,
|
||||
m_scantablelines,
|
||||
m_cameralines,
|
||||
m_scenariolines,
|
||||
m_eventqueuelines,
|
||||
m_rendererlines;
|
||||
int tprev { 0 }; // poprzedni czas
|
||||
double VelPrev { 0.0 }; // poprzednia prędkość
|
||||
double Acc { 0.0 }; // przyspieszenie styczne
|
||||
};
|
||||
|
||||
class transcripts_panel : public ui_panel {
|
||||
|
||||
public:
|
||||
transcripts_panel( std::string const Name, bool const Isopen )
|
||||
: ui_panel( Name, Isopen ) {}
|
||||
|
||||
void update() override;
|
||||
void render() override;
|
||||
};
|
||||
@@ -45,9 +45,6 @@ editor_mode::init() {
|
||||
|
||||
Camera.Init( { 0, 15, 0 }, { glm::radians( -30.0 ), glm::radians( 180.0 ), 0 }, TCameraType::tp_Free );
|
||||
|
||||
m_userinterface->set_progress( "Scenario editor is active. Press F11 to return to driver mode" );
|
||||
m_userinterface->set_progress( 0, 100 );
|
||||
|
||||
return m_input.init();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,27 +11,13 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "editoruilayer.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "camera.h"
|
||||
#include "animmodel.h"
|
||||
#include "track.h"
|
||||
#include "event.h"
|
||||
#include "renderer.h"
|
||||
#include "utilities.h"
|
||||
#include "logs.h"
|
||||
|
||||
editor_ui::editor_ui() {
|
||||
|
||||
clear_texts();
|
||||
/*
|
||||
UIHeader = std::make_shared<ui_panel>( 20, 20 ); // header ui panel
|
||||
*/
|
||||
// make 4 empty lines for the ui header, to cut down on work down the road
|
||||
UIHeader.text_lines.emplace_back( "", Global.UITextColor );
|
||||
UIHeader.text_lines.emplace_back( "", Global.UITextColor );
|
||||
UIHeader.text_lines.emplace_back( "", Global.UITextColor );
|
||||
UIHeader.text_lines.emplace_back( "", Global.UITextColor );
|
||||
clear_panels();
|
||||
// bind the panels with ui object. maybe not the best place for this but, eh
|
||||
push_back( &UIHeader );
|
||||
push_back( &m_itempropertiespanel );
|
||||
}
|
||||
|
||||
// potentially processes provided input key. returns: true if key was processed, false otherwise
|
||||
@@ -45,11 +31,8 @@ editor_ui::on_key( int const Key, int const Action ) {
|
||||
void
|
||||
editor_ui::update() {
|
||||
|
||||
std::string uitextline1, uitextline2, uitextline3, uitextline4;
|
||||
set_tooltip( "" );
|
||||
|
||||
auto const &camera { Global.pCamera };
|
||||
|
||||
if( ( true == Global.ControlPicking )
|
||||
&& ( true == DebugModeFlag ) ) {
|
||||
|
||||
@@ -60,141 +43,8 @@ editor_ui::update() {
|
||||
"" ) );
|
||||
}
|
||||
|
||||
// scenario inspector
|
||||
auto const *node { m_node };
|
||||
|
||||
if( node == nullptr ) {
|
||||
auto const mouseposition { camera.Pos + GfxRenderer.Mouse_Position() };
|
||||
uitextline1 = "mouse location: [" + to_string( mouseposition.x, 2 ) + ", " + to_string( mouseposition.y, 2 ) + ", " + to_string( mouseposition.z, 2 ) + "]";
|
||||
goto update;
|
||||
}
|
||||
|
||||
uitextline1 =
|
||||
"node name: " + node->name()
|
||||
+ "; location: [" + to_string( node->location().x, 2 ) + ", " + to_string( node->location().y, 2 ) + ", " + to_string( node->location().z, 2 ) + "]"
|
||||
+ " (distance: " + to_string( glm::length( glm::dvec3{ node->location().x, 0.0, node->location().z } -glm::dvec3{ camera.Pos.x, 0.0, camera.Pos.z } ), 1 ) + " m)";
|
||||
// subclass-specific data
|
||||
// TBD, TODO: specialized data dump method in each node subclass, or data imports in the panel for provided subclass pointer?
|
||||
if( typeid( *node ) == typeid( TAnimModel ) ) {
|
||||
|
||||
auto const *subnode = static_cast<TAnimModel const *>( node );
|
||||
|
||||
uitextline2 = "angle: " + to_string( clamp_circular( subnode->vAngle.y, 360.f ), 2 ) + " deg";
|
||||
uitextline2 += "; lights: ";
|
||||
if( subnode->iNumLights > 0 ) {
|
||||
uitextline2 += '[';
|
||||
for( int lightidx = 0; lightidx < subnode->iNumLights; ++lightidx ) {
|
||||
uitextline2 += to_string( subnode->lsLights[ lightidx ] );
|
||||
if( lightidx < subnode->iNumLights - 1 ) {
|
||||
uitextline2 += ", ";
|
||||
}
|
||||
}
|
||||
uitextline2 += ']';
|
||||
}
|
||||
else {
|
||||
uitextline2 += "none";
|
||||
}
|
||||
// 3d shape
|
||||
auto modelfile { (
|
||||
( subnode->pModel != nullptr ) ?
|
||||
subnode->pModel->NameGet() :
|
||||
"none" ) };
|
||||
if( modelfile.find( szModelPath ) == 0 ) {
|
||||
// don't include 'models/' in the path
|
||||
modelfile.erase( 0, std::string{ szModelPath }.size() );
|
||||
}
|
||||
// texture
|
||||
auto texturefile { (
|
||||
( subnode->Material()->replacable_skins[ 1 ] != null_handle ) ?
|
||||
GfxRenderer.Material( subnode->Material()->replacable_skins[ 1 ] ).name :
|
||||
"none" ) };
|
||||
if( texturefile.find( szTexturePath ) == 0 ) {
|
||||
// don't include 'textures/' in the path
|
||||
texturefile.erase( 0, std::string{ szTexturePath }.size() );
|
||||
}
|
||||
uitextline3 = "mesh: " + modelfile;
|
||||
uitextline4 = "skin: " + texturefile;
|
||||
}
|
||||
else if( typeid( *node ) == typeid( TTrack ) ) {
|
||||
|
||||
auto const *subnode = static_cast<TTrack const *>( node );
|
||||
// basic attributes
|
||||
uitextline2 =
|
||||
"isolated: " + ( ( subnode->pIsolated != nullptr ) ? subnode->pIsolated->asName : "none" )
|
||||
+ "; velocity: " + to_string( subnode->SwitchExtension ? subnode->SwitchExtension->fVelocity : subnode->fVelocity )
|
||||
+ "; width: " + to_string( subnode->fTrackWidth ) + " m"
|
||||
+ "; friction: " + to_string( subnode->fFriction, 2 )
|
||||
+ "; quality: " + to_string( subnode->iQualityFlag );
|
||||
// textures
|
||||
auto texturefile { (
|
||||
( subnode->m_material1 != null_handle ) ?
|
||||
GfxRenderer.Material( subnode->m_material1 ).name :
|
||||
"none" ) };
|
||||
if( texturefile.find( szTexturePath ) == 0 ) {
|
||||
texturefile.erase( 0, std::string{ szTexturePath }.size() );
|
||||
}
|
||||
auto texturefile2{ (
|
||||
( subnode->m_material2 != null_handle ) ?
|
||||
GfxRenderer.Material( subnode->m_material2 ).name :
|
||||
"none" ) };
|
||||
if( texturefile2.find( szTexturePath ) == 0 ) {
|
||||
texturefile2.erase( 0, std::string{ szTexturePath }.size() );
|
||||
}
|
||||
uitextline2 += "; skins: [" + texturefile + ", " + texturefile2 + "]";
|
||||
// paths
|
||||
uitextline3 = "paths: ";
|
||||
for( auto const &path : subnode->m_paths ) {
|
||||
uitextline3 +=
|
||||
"["
|
||||
+ to_string( path.points[ segment_data::point::start ].x, 3 ) + ", "
|
||||
+ to_string( path.points[ segment_data::point::start ].y, 3 ) + ", "
|
||||
+ to_string( path.points[ segment_data::point::start ].z, 3 ) + "]->"
|
||||
+ "["
|
||||
+ to_string( path.points[ segment_data::point::end ].x, 3 ) + ", "
|
||||
+ to_string( path.points[ segment_data::point::end ].y, 3 ) + ", "
|
||||
+ to_string( path.points[ segment_data::point::end ].z, 3 ) + "] ";
|
||||
}
|
||||
// events
|
||||
std::vector< std::pair< std::string, TTrack::event_sequence const * > > const eventsequences {
|
||||
{ "ev0", &subnode->m_events0 }, { "ev0all", &subnode->m_events0all },
|
||||
{ "ev1", &subnode->m_events1 }, { "ev1all", &subnode->m_events1all },
|
||||
{ "ev2", &subnode->m_events2 }, { "ev2all", &subnode->m_events2all } };
|
||||
|
||||
for( auto const &eventsequence : eventsequences ) {
|
||||
|
||||
if( eventsequence.second->empty() ) { continue; }
|
||||
|
||||
uitextline4 += eventsequence.first + ": [";
|
||||
for( auto const &event : *( eventsequence.second ) ) {
|
||||
if( uitextline4.back() != '[' ) {
|
||||
uitextline4 += ", ";
|
||||
}
|
||||
if( event.second ) {
|
||||
uitextline4 += event.second->asName;
|
||||
}
|
||||
}
|
||||
uitextline4 += "] ";
|
||||
}
|
||||
|
||||
}
|
||||
else if( typeid( *node ) == typeid( TMemCell ) ) {
|
||||
|
||||
auto const *subnode = static_cast<TMemCell const *>( node );
|
||||
|
||||
uitextline2 =
|
||||
"data: [" + subnode->Text() + "]"
|
||||
+ " [" + to_string( subnode->Value1(), 2 ) + "]"
|
||||
+ " [" + to_string( subnode->Value2(), 2 ) + "]";
|
||||
uitextline3 = "track: " + ( subnode->asTrackName.empty() ? "none" : subnode->asTrackName );
|
||||
}
|
||||
|
||||
update:
|
||||
// update the ui header texts
|
||||
auto &headerdata = UIHeader.text_lines;
|
||||
headerdata[ 0 ].data = uitextline1;
|
||||
headerdata[ 1 ].data = uitextline2;
|
||||
headerdata[ 2 ].data = uitextline3;
|
||||
headerdata[ 3 ].data = uitextline4;
|
||||
ui_layer::update();
|
||||
m_itempropertiespanel.update( m_node );
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -10,6 +10,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#pragma once
|
||||
|
||||
#include "uilayer.h"
|
||||
#include "editoruipanels.h"
|
||||
|
||||
namespace scene {
|
||||
|
||||
@@ -34,6 +35,6 @@ public:
|
||||
|
||||
private:
|
||||
// members
|
||||
ui_panel UIHeader { 20, 20 }; // header ui panel
|
||||
itemproperties_panel m_itempropertiespanel { "Node Properties", true };
|
||||
scene::basic_node * m_node { nullptr }; // currently bound scene node, if any
|
||||
};
|
||||
|
||||
196
editoruipanels.cpp
Normal file
196
editoruipanels.cpp
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "editoruipanels.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "camera.h"
|
||||
#include "animmodel.h"
|
||||
#include "track.h"
|
||||
#include "event.h"
|
||||
#include "renderer.h"
|
||||
#include "utilities.h"
|
||||
|
||||
void
|
||||
itemproperties_panel::update( scene::basic_node const *Node ) {
|
||||
|
||||
if( false == is_open ) { return; }
|
||||
|
||||
text_lines.clear();
|
||||
std::string textline;
|
||||
|
||||
// scenario inspector
|
||||
auto const *node { Node };
|
||||
auto const &camera { Global.pCamera };
|
||||
|
||||
if( node == nullptr ) {
|
||||
auto const mouseposition { camera.Pos + GfxRenderer.Mouse_Position() };
|
||||
textline = "mouse location: [" + to_string( mouseposition.x, 2 ) + ", " + to_string( mouseposition.y, 2 ) + ", " + to_string( mouseposition.z, 2 ) + "]";
|
||||
text_lines.emplace_back( textline, Global.UITextColor );
|
||||
return;
|
||||
}
|
||||
|
||||
textline =
|
||||
"node name: " + node->name()
|
||||
+ "\nlocation: [" + to_string( node->location().x, 2 ) + ", " + to_string( node->location().y, 2 ) + ", " + to_string( node->location().z, 2 ) + "]"
|
||||
+ " (distance: " + to_string( glm::length( glm::dvec3{ node->location().x, 0.0, node->location().z } -glm::dvec3{ camera.Pos.x, 0.0, camera.Pos.z } ), 1 ) + " m)";
|
||||
text_lines.emplace_back( textline, Global.UITextColor );
|
||||
|
||||
// subclass-specific data
|
||||
// TBD, TODO: specialized data dump method in each node subclass, or data imports in the panel for provided subclass pointer?
|
||||
if( typeid( *node ) == typeid( TAnimModel ) ) {
|
||||
|
||||
auto const *subnode = static_cast<TAnimModel const *>( node );
|
||||
|
||||
textline = "angle: " + to_string( clamp_circular( subnode->vAngle.y, 360.f ), 2 ) + " deg";
|
||||
textline += "; lights: ";
|
||||
if( subnode->iNumLights > 0 ) {
|
||||
textline += '[';
|
||||
for( int lightidx = 0; lightidx < subnode->iNumLights; ++lightidx ) {
|
||||
textline += to_string( subnode->lsLights[ lightidx ] );
|
||||
if( lightidx < subnode->iNumLights - 1 ) {
|
||||
textline += ", ";
|
||||
}
|
||||
}
|
||||
textline += ']';
|
||||
}
|
||||
else {
|
||||
textline += "none";
|
||||
}
|
||||
text_lines.emplace_back( textline, Global.UITextColor );
|
||||
|
||||
// 3d shape
|
||||
auto modelfile { (
|
||||
( subnode->pModel != nullptr ) ?
|
||||
subnode->pModel->NameGet() :
|
||||
"none" ) };
|
||||
if( modelfile.find( szModelPath ) == 0 ) {
|
||||
// don't include 'models/' in the path
|
||||
modelfile.erase( 0, std::string{ szModelPath }.size() );
|
||||
}
|
||||
// texture
|
||||
auto texturefile { (
|
||||
( subnode->Material()->replacable_skins[ 1 ] != null_handle ) ?
|
||||
GfxRenderer.Material( subnode->Material()->replacable_skins[ 1 ] ).name :
|
||||
"none" ) };
|
||||
if( texturefile.find( szTexturePath ) == 0 ) {
|
||||
// don't include 'textures/' in the path
|
||||
texturefile.erase( 0, std::string{ szTexturePath }.size() );
|
||||
}
|
||||
text_lines.emplace_back( "mesh: " + modelfile, Global.UITextColor );
|
||||
text_lines.emplace_back( "skin: " + texturefile, Global.UITextColor );
|
||||
}
|
||||
else if( typeid( *node ) == typeid( TTrack ) ) {
|
||||
|
||||
auto const *subnode = static_cast<TTrack const *>( node );
|
||||
// basic attributes
|
||||
textline =
|
||||
"isolated: " + ( ( subnode->pIsolated != nullptr ) ? subnode->pIsolated->asName : "none" )
|
||||
+ "\nvelocity: " + to_string( subnode->SwitchExtension ? subnode->SwitchExtension->fVelocity : subnode->fVelocity )
|
||||
+ "\nwidth: " + to_string( subnode->fTrackWidth ) + " m"
|
||||
+ "\nfriction: " + to_string( subnode->fFriction, 2 )
|
||||
+ "\nquality: " + to_string( subnode->iQualityFlag );
|
||||
text_lines.emplace_back( textline, Global.UITextColor );
|
||||
// textures
|
||||
auto texturefile { (
|
||||
( subnode->m_material1 != null_handle ) ?
|
||||
GfxRenderer.Material( subnode->m_material1 ).name :
|
||||
"none" ) };
|
||||
if( texturefile.find( szTexturePath ) == 0 ) {
|
||||
texturefile.erase( 0, std::string{ szTexturePath }.size() );
|
||||
}
|
||||
auto texturefile2{ (
|
||||
( subnode->m_material2 != null_handle ) ?
|
||||
GfxRenderer.Material( subnode->m_material2 ).name :
|
||||
"none" ) };
|
||||
if( texturefile2.find( szTexturePath ) == 0 ) {
|
||||
texturefile2.erase( 0, std::string{ szTexturePath }.size() );
|
||||
}
|
||||
textline = "skins:\n " + texturefile + "\n " + texturefile2;
|
||||
text_lines.emplace_back( textline, Global.UITextColor );
|
||||
// paths
|
||||
textline = "paths: ";
|
||||
for( auto const &path : subnode->m_paths ) {
|
||||
textline +=
|
||||
"\n ["
|
||||
+ to_string( path.points[ segment_data::point::start ].x, 3 ) + ", "
|
||||
+ to_string( path.points[ segment_data::point::start ].y, 3 ) + ", "
|
||||
+ to_string( path.points[ segment_data::point::start ].z, 3 ) + "]->"
|
||||
+ "["
|
||||
+ to_string( path.points[ segment_data::point::end ].x, 3 ) + ", "
|
||||
+ to_string( path.points[ segment_data::point::end ].y, 3 ) + ", "
|
||||
+ to_string( path.points[ segment_data::point::end ].z, 3 ) + "] ";
|
||||
}
|
||||
text_lines.emplace_back( textline, Global.UITextColor );
|
||||
// events
|
||||
textline.clear();
|
||||
|
||||
std::vector< std::pair< std::string, TTrack::event_sequence const * > > const eventsequences {
|
||||
{ "ev0", &subnode->m_events0 }, { "ev0all", &subnode->m_events0all },
|
||||
{ "ev1", &subnode->m_events1 }, { "ev1all", &subnode->m_events1all },
|
||||
{ "ev2", &subnode->m_events2 }, { "ev2all", &subnode->m_events2all } };
|
||||
|
||||
for( auto const &eventsequence : eventsequences ) {
|
||||
|
||||
if( eventsequence.second->empty() ) { continue; }
|
||||
|
||||
textline += ( textline.empty() ? "" : "\n" ) + eventsequence.first + ": [";
|
||||
for( auto const &event : *( eventsequence.second ) ) {
|
||||
if( textline.back() != '[' ) {
|
||||
textline += ", ";
|
||||
}
|
||||
textline += (
|
||||
event.second ?
|
||||
event.second->asName :
|
||||
event.first + " (missing)" );
|
||||
}
|
||||
textline += "] ";
|
||||
}
|
||||
text_lines.emplace_back( textline, Global.UITextColor );
|
||||
}
|
||||
else if( typeid( *node ) == typeid( TMemCell ) ) {
|
||||
|
||||
auto const *subnode = static_cast<TMemCell const *>( node );
|
||||
|
||||
textline =
|
||||
"data: [" + subnode->Text() + "]"
|
||||
+ " [" + to_string( subnode->Value1(), 2 ) + "]"
|
||||
+ " [" + to_string( subnode->Value2(), 2 ) + "]";
|
||||
text_lines.emplace_back( textline, Global.UITextColor );
|
||||
textline = "track: " + ( subnode->asTrackName.empty() ? "none" : subnode->asTrackName );
|
||||
text_lines.emplace_back( textline, Global.UITextColor );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
itemproperties_panel::render() {
|
||||
|
||||
if( false == is_open ) { return; }
|
||||
if( true == text_lines.empty() ) { return; }
|
||||
|
||||
auto flags =
|
||||
ImGuiWindowFlags_NoFocusOnAppearing
|
||||
| ImGuiWindowFlags_NoCollapse
|
||||
| ( size.x > 0 ? ImGuiWindowFlags_NoResize : 0 );
|
||||
|
||||
if( size.x > 0 ) {
|
||||
ImGui::SetNextWindowSize( ImVec2( size.x, size.y ) );
|
||||
}
|
||||
if( size_min.x > 0 ) {
|
||||
ImGui::SetNextWindowSizeConstraints( ImVec2( size_min.x, size_min.y ), ImVec2( size_max.x, size_max.y ) );
|
||||
}
|
||||
if( true == ImGui::Begin( name.c_str(), nullptr, flags ) ) {
|
||||
// header section
|
||||
for( auto const &line : text_lines ) {
|
||||
ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), line.data.c_str() );
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
24
editoruipanels.h
Normal file
24
editoruipanels.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "uilayer.h"
|
||||
#include "classes.h"
|
||||
|
||||
class itemproperties_panel : public ui_panel {
|
||||
|
||||
public:
|
||||
itemproperties_panel( std::string const Name, bool const Isopen )
|
||||
: ui_panel( Name, Isopen )
|
||||
{}
|
||||
|
||||
void update( scene::basic_node const *Node );
|
||||
void render() override;
|
||||
};
|
||||
@@ -49,6 +49,9 @@
|
||||
<Filter Include="Source Files\application\input">
|
||||
<UniqueIdentifier>{0630616b-1afe-4fb6-96d1-3755834ba8aa}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\imgui">
|
||||
<UniqueIdentifier>{33f7f4ae-692b-4989-a71a-004e0d48ed4f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="AirCoupler.cpp">
|
||||
@@ -306,6 +309,24 @@
|
||||
<ClCompile Include="scenenodegroups.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ref\imgui\imgui.cpp">
|
||||
<Filter>Source Files\imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ref\imgui\imgui_draw.cpp">
|
||||
<Filter>Source Files\imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ref\imgui\examples\imgui_impl_opengl2.cpp">
|
||||
<Filter>Source Files\imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ref\imgui\examples\imgui_impl_glfw.cpp">
|
||||
<Filter>Source Files\imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="driveruipanels.cpp">
|
||||
<Filter>Source Files\application\mode_driver</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="editoruipanels.cpp">
|
||||
<Filter>Source Files\application\mode_editor</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Globals.h">
|
||||
@@ -578,6 +599,12 @@
|
||||
<ClInclude Include="scenenodegroups.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="driveruipanels.h">
|
||||
<Filter>Header Files\application\mode_driver</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="editoruipanels.h">
|
||||
<Filter>Header Files\application\mode_editor</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="maszyna.rc">
|
||||
|
||||
@@ -33,7 +33,7 @@ double TTrainParameters::WatchMTable(double DistCounter)
|
||||
return dist;
|
||||
}
|
||||
|
||||
std::string TTrainParameters::NextStop()
|
||||
std::string TTrainParameters::NextStop() const
|
||||
{ // pobranie nazwy następnego miejsca zatrzymania
|
||||
if (StationIndex <= StationCount)
|
||||
return NextStationName; // nazwa następnego przystanku;
|
||||
@@ -41,7 +41,7 @@ std::string TTrainParameters::NextStop()
|
||||
return "[End of route]"; //że niby koniec
|
||||
}
|
||||
|
||||
bool TTrainParameters::IsStop()
|
||||
bool TTrainParameters::IsStop() const
|
||||
{ // zapytanie, czy zatrzymywać na następnym punkcie rozkładu
|
||||
if ((StationIndex < StationCount))
|
||||
return TimeTable[StationIndex].Ah >= 0; //-1 to brak postoju
|
||||
@@ -129,7 +129,7 @@ bool TTrainParameters::IsTimeToGo(double hh, double mm)
|
||||
return false; // dalej nie jechać
|
||||
}
|
||||
|
||||
std::string TTrainParameters::ShowRelation()
|
||||
std::string TTrainParameters::ShowRelation() const
|
||||
/*zwraca informację o relacji*/
|
||||
{
|
||||
// if (Relation1=TimeTable[1].StationName) and (Relation2=TimeTable[StationCount].StationName)
|
||||
|
||||
6
mtable.h
6
mtable.h
@@ -69,10 +69,10 @@ class TTrainParameters
|
||||
int Direction; /*kierunek jazdy w/g kilometrazu*/
|
||||
double CheckTrainLatency();
|
||||
/*todo: str hh:mm to int i z powrotem*/
|
||||
std::string ShowRelation();
|
||||
std::string ShowRelation() const;
|
||||
double WatchMTable(double DistCounter);
|
||||
std::string NextStop();
|
||||
bool IsStop();
|
||||
std::string NextStop() const;
|
||||
bool IsStop() const;
|
||||
bool IsTimeToGo(double hh, double mm);
|
||||
bool UpdateMTable(double hh, double mm, std::string const &NewName);
|
||||
bool UpdateMTable( scenario_time const &Time, std::string const &NewName );
|
||||
|
||||
28
renderer.cpp
28
renderer.cpp
@@ -409,6 +409,9 @@ opengl_renderer::Render() {
|
||||
m_debugstats = debug_stats();
|
||||
Render_pass( rendermode::color );
|
||||
Timer::subsystem.gfx_color.stop();
|
||||
// add user interface
|
||||
setup_units( true, false, false );
|
||||
Application.render_ui();
|
||||
|
||||
Timer::subsystem.gfx_swap.start();
|
||||
glfwSwapBuffers( m_window );
|
||||
@@ -416,15 +419,19 @@ opengl_renderer::Render() {
|
||||
|
||||
m_drawcount = m_cellqueue.size();
|
||||
m_debugtimestext
|
||||
+= "frame: " + to_string( Timer::subsystem.gfx_color.average(), 2 ) + " msec (" + std::to_string( m_cellqueue.size() ) + " sectors) "
|
||||
+= "gpu side: " + to_string( Timer::subsystem.gfx_swap.average(), 2 ) + " msec "
|
||||
+= "(" + to_string( Timer::subsystem.gfx_color.average() + Timer::subsystem.gfx_swap.average(), 2 ) + " msec total)";
|
||||
+= "color: " + to_string( Timer::subsystem.gfx_color.average(), 2 ) + " msec (" + std::to_string( m_cellqueue.size() ) + " sectors)\n"
|
||||
+= "gpu side: " + to_string( Timer::subsystem.gfx_swap.average(), 2 ) + " msec\n"
|
||||
+= "frame total: " + to_string( Timer::subsystem.gfx_color.average() + Timer::subsystem.gfx_swap.average(), 2 ) + " msec";
|
||||
|
||||
m_debugstatstext =
|
||||
"drawcalls: " + to_string( m_debugstats.drawcalls )
|
||||
+ "; dyn: " + to_string( m_debugstats.dynamics ) + " mod: " + to_string( m_debugstats.models ) + " sub: " + to_string( m_debugstats.submodels )
|
||||
+ "; trk: " + to_string( m_debugstats.paths ) + " shp: " + to_string( m_debugstats.shapes )
|
||||
+ " trc: " + to_string( m_debugstats.traction ) + " lin: " + to_string( m_debugstats.lines );
|
||||
"drawcalls: " + to_string( m_debugstats.drawcalls ) + "\n"
|
||||
+ " vehicles: " + to_string( m_debugstats.dynamics ) + "\n"
|
||||
+ " models: " + to_string( m_debugstats.models ) + "\n"
|
||||
+ " submodels: " + to_string( m_debugstats.submodels ) + "\n"
|
||||
+ " paths: " + to_string( m_debugstats.paths ) + "\n"
|
||||
+ " shapes: " + to_string( m_debugstats.shapes ) + "\n"
|
||||
+ " traction: " + to_string( m_debugstats.traction ) + "\n"
|
||||
+ " lines: " + to_string( m_debugstats.lines );
|
||||
|
||||
++m_framestamp;
|
||||
|
||||
@@ -463,7 +470,7 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
||||
Render_pass( rendermode::cabshadows );
|
||||
}
|
||||
Timer::subsystem.gfx_shadows.stop();
|
||||
m_debugtimestext += "shadows: " + to_string( Timer::subsystem.gfx_shadows.average(), 2 ) + " msec (" + std::to_string( m_cellqueue.size() ) + " sectors) ";
|
||||
m_debugtimestext += "shadows: " + to_string( Timer::subsystem.gfx_shadows.average(), 2 ) + " msec (" + std::to_string( m_cellqueue.size() ) + " sectors)\n";
|
||||
#ifdef EU07_USE_DEBUG_SHADOWMAP
|
||||
UILayer.set_texture( m_shadowdebugtexture );
|
||||
#endif
|
||||
@@ -584,7 +591,6 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
||||
::glMatrixMode( GL_MODELVIEW );
|
||||
}
|
||||
}
|
||||
Application.render_ui();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1413,10 +1419,6 @@ opengl_renderer::Render( world_environment *Environment ) {
|
||||
|
||||
// skydome
|
||||
Environment->m_skydome.Render();
|
||||
if( true == Global.bUseVBO ) {
|
||||
// skydome uses a custom vbo which could potentially confuse the main geometry system. hardly elegant but, eh
|
||||
gfx::opengl_vbogeometrybank::reset();
|
||||
}
|
||||
// stars
|
||||
if( Environment->m_stars.m_stars != nullptr ) {
|
||||
// setup
|
||||
|
||||
@@ -118,6 +118,9 @@ void CSkyDome::Update( glm::vec3 const &Sun ) {
|
||||
// render skydome to screen
|
||||
void CSkyDome::Render() {
|
||||
|
||||
// cache entry state
|
||||
::glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
|
||||
|
||||
if( m_vertexbuffer == -1 ) {
|
||||
// build the buffers
|
||||
::glGenBuffers( 1, &m_vertexbuffer );
|
||||
@@ -146,8 +149,7 @@ void CSkyDome::Render() {
|
||||
::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indexbuffer );
|
||||
::glDrawElements( GL_TRIANGLES, static_cast<GLsizei>( m_indices.size() ), GL_UNSIGNED_SHORT, reinterpret_cast<void const*>( 0 ) );
|
||||
// cleanup
|
||||
::glDisableClientState( GL_COLOR_ARRAY );
|
||||
::glDisableClientState( GL_VERTEX_ARRAY );
|
||||
::glPopClientAttrib();
|
||||
}
|
||||
|
||||
bool CSkyDome::SetSunPosition( glm::vec3 const &Direction ) {
|
||||
|
||||
20
stdafx.h
20
stdafx.h
@@ -77,13 +77,20 @@
|
||||
#define GLFW_DLL
|
||||
#endif // _windows
|
||||
#endif // build_static
|
||||
#ifndef __ANDROID__
|
||||
#include "GL/glew.h"
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
#include "GL/wglew.h"
|
||||
#endif
|
||||
#define GLFW_INCLUDE_GLU
|
||||
//m7todo: jest tu bo nie chcia³o mi siê wpychaæ do wszystkich plików
|
||||
#ifndef __ANDROID__
|
||||
#include <GLFW/glfw3.h>
|
||||
#endif
|
||||
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#define GLM_FORCE_CTOR_INIT
|
||||
@@ -96,3 +103,16 @@
|
||||
#include <glm/gtx/norm.hpp>
|
||||
|
||||
#include "openglmatrixstack.h"
|
||||
|
||||
// imgui.h comes with its own operator new which gets wrecked by dbg_new, so we temporarily disable the latter
|
||||
#ifdef _MSC_VER
|
||||
#ifdef _DEBUG
|
||||
#undef new
|
||||
#endif // _DEBUG
|
||||
#endif
|
||||
#include "imgui.h"
|
||||
#ifdef _MSC_VER
|
||||
#ifdef _DEBUG
|
||||
#define new DBG_NEW
|
||||
#endif // _DEBUG
|
||||
#endif
|
||||
|
||||
194
uilayer.cpp
194
uilayer.cpp
@@ -27,61 +27,107 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "utilities.h"
|
||||
#include "logs.h"
|
||||
|
||||
#include "imgui_impl_glfw.h"
|
||||
#include "imgui_impl_opengl2.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
GLFWAPI HWND glfwGetWin32Window( GLFWwindow* window ); //m7todo: potrzebne do directsound
|
||||
}
|
||||
|
||||
GLFWwindow * ui_layer::m_window { nullptr };
|
||||
ImGuiIO *ui_layer::m_imguiio { nullptr };
|
||||
GLint ui_layer::m_textureunit { GL_TEXTURE0 };
|
||||
GLuint ui_layer::m_fontbase { (GLuint)-1 }; // numer DL dla znaków w napisach
|
||||
bool ui_layer::m_cursorvisible { true };
|
||||
|
||||
|
||||
ui_layer::~ui_layer() {
|
||||
/*
|
||||
// this should be invoked manually, or we risk trying to delete the lists after the context is gone
|
||||
if( m_fontbase != -1 )
|
||||
::glDeleteLists( m_fontbase, 96 );
|
||||
*/
|
||||
ui_panel::ui_panel( std::string const Name, bool const Isopen )
|
||||
: name( Name ), is_open( Isopen )
|
||||
{}
|
||||
|
||||
void
|
||||
ui_panel::render() {
|
||||
|
||||
if( false == is_open ) { return; }
|
||||
if( true == text_lines.empty() ) { return; }
|
||||
|
||||
auto flags =
|
||||
ImGuiWindowFlags_NoFocusOnAppearing
|
||||
| ImGuiWindowFlags_NoCollapse
|
||||
| ( size.x > 0 ? ImGuiWindowFlags_NoResize : 0 );
|
||||
|
||||
if( size.x > 0 ) {
|
||||
ImGui::SetNextWindowSize( ImVec2( size.x, size.y ) );
|
||||
}
|
||||
if( size_min.x > 0 ) {
|
||||
ImGui::SetNextWindowSizeConstraints( ImVec2( size_min.x, size_min.y ), ImVec2( size_max.x, size_max.y ) );
|
||||
}
|
||||
if( true == ImGui::Begin( name.c_str(), &is_open, flags ) ) {
|
||||
for( auto const &line : text_lines ) {
|
||||
ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), line.data.c_str() );
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
ui_layer::~ui_layer() {}
|
||||
|
||||
bool
|
||||
ui_layer::init( GLFWwindow *Window ) {
|
||||
|
||||
m_window = Window;
|
||||
HFONT font; // Windows Font ID
|
||||
m_fontbase = ::glGenLists(96); // storage for 96 characters
|
||||
HDC hDC = ::GetDC( glfwGetWin32Window( m_window ) );
|
||||
font = ::CreateFont( -MulDiv( 10, ::GetDeviceCaps( hDC, LOGPIXELSY ), 72 ), // height of font
|
||||
0, // width of font
|
||||
0, // angle of escapement
|
||||
0, // orientation angle
|
||||
(Global.bGlutFont ? FW_MEDIUM : FW_HEAVY), // font weight
|
||||
FALSE, // italic
|
||||
FALSE, // underline
|
||||
FALSE, // strikeout
|
||||
DEFAULT_CHARSET, // character set identifier
|
||||
OUT_DEFAULT_PRECIS, // output precision
|
||||
CLIP_DEFAULT_PRECIS, // clipping precision
|
||||
(Global.bGlutFont ? CLEARTYPE_QUALITY : PROOF_QUALITY), // output quality
|
||||
DEFAULT_PITCH | FF_DONTCARE, // family and pitch
|
||||
"Lucida Console"); // font name
|
||||
::SelectObject(hDC, font); // selects the font we want
|
||||
if( TRUE == ::wglUseFontBitmaps( hDC, 32, 96, m_fontbase ) ) {
|
||||
// builds 96 characters starting at character 32
|
||||
WriteLog( "Display Lists font used" ); //+AnsiString(glGetError())
|
||||
WriteLog( "Font init OK" ); //+AnsiString(glGetError())
|
||||
Global.DLFont = true;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
ErrorLog( "Font init failed" );
|
||||
// return false;
|
||||
// NOTE: we report success anyway, given some cards can't produce fonts in this manner
|
||||
Global.DLFont = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
m_imguiio = &ImGui::GetIO();
|
||||
// m_imguiio->Fonts->AddFontFromFileTTF( "c:/windows/fonts/lucon.ttf", 13.0f );
|
||||
|
||||
ImGui_ImplGlfw_InitForOpenGL( m_window, false );
|
||||
ImGui_ImplOpenGL2_Init();
|
||||
|
||||
init_colors();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ui_layer::init_colors() {
|
||||
|
||||
// configure ui colours
|
||||
auto *style = &ImGui::GetStyle();
|
||||
auto *colors = style->Colors;
|
||||
auto const background { ImVec4( 38.0f / 255.0f, 38.0f / 255.0f, 38.0f / 255.0f, 0.65f ) };
|
||||
auto const accent { ImVec4( 44.0f / 255.0f, 88.0f / 255.0f, 72.0f / 255.0f, 0.75f ) };
|
||||
auto const itembase { ImVec4( accent.x, accent.y, accent.z, 0.35f ) };
|
||||
auto const itemhover { ImVec4( accent.x, accent.y, accent.z, 0.65f ) };
|
||||
auto const itemactive { ImVec4( accent.x, accent.y, accent.z, 0.95f ) };
|
||||
|
||||
colors[ ImGuiCol_WindowBg ] = background;
|
||||
colors[ ImGuiCol_PopupBg ] = background;
|
||||
colors[ ImGuiCol_FrameBg ] = itembase;
|
||||
colors[ ImGuiCol_FrameBgHovered ] = itemhover;
|
||||
colors[ ImGuiCol_FrameBgActive ] = itemactive;
|
||||
colors[ ImGuiCol_TitleBg ] = background;
|
||||
colors[ ImGuiCol_TitleBgActive ] = background;
|
||||
colors[ ImGuiCol_TitleBgCollapsed ] = background;
|
||||
colors[ ImGuiCol_CheckMark ] = colors[ ImGuiCol_Text ];
|
||||
colors[ ImGuiCol_Button ] = itembase;
|
||||
colors[ ImGuiCol_ButtonHovered ] = itemhover;
|
||||
colors[ ImGuiCol_ButtonActive ] = itemactive;
|
||||
colors[ ImGuiCol_Header ] = itembase;
|
||||
colors[ ImGuiCol_HeaderHovered ] = itemhover;
|
||||
colors[ ImGuiCol_HeaderActive ] = itemactive;
|
||||
colors[ ImGuiCol_ResizeGrip ] = itembase;
|
||||
colors[ ImGuiCol_ResizeGripHovered ] = itemhover;
|
||||
colors[ ImGuiCol_ResizeGripActive ] = itemactive;
|
||||
}
|
||||
|
||||
void
|
||||
ui_layer::shutdown() {
|
||||
|
||||
ImGui_ImplOpenGL2_Shutdown();
|
||||
ImGui_ImplGlfw_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -90,9 +136,18 @@ ui_layer::on_key( int const Key, int const Action ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
ui_layer::update() {
|
||||
|
||||
for( auto *panel : m_panels ) {
|
||||
panel->update();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ui_layer::render() {
|
||||
|
||||
// legacy ui code
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho( 0, std::max( 1, Global.iWindowWidth ), std::max( 1, Global.iWindowHeight ), 0, -1, 1 );
|
||||
@@ -120,10 +175,27 @@ ui_layer::render() {
|
||||
|
||||
glDisable( GL_BLEND );
|
||||
|
||||
glPopAttrib();
|
||||
|
||||
// imgui ui code
|
||||
::glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
|
||||
|
||||
::glClientActiveTexture( m_textureunit );
|
||||
::glBindBuffer( GL_ARRAY_BUFFER, 0 );
|
||||
|
||||
ImGui_ImplOpenGL2_NewFrame();
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
render_panels();
|
||||
render_tooltip();
|
||||
// template method implementation
|
||||
render_();
|
||||
|
||||
glPopAttrib();
|
||||
ImGui::Render();
|
||||
ImGui_ImplOpenGL2_RenderDrawData( ImGui::GetDrawData() );
|
||||
|
||||
::glPopClientAttrib();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -207,30 +279,14 @@ ui_layer::render_progress() {
|
||||
::glRasterPos2f(
|
||||
( 0.5f * ( Global.iWindowWidth - width ) + origin.x * heightratio ) + ( ( size.x * heightratio - textwidth ) * 0.5f * heightratio ),
|
||||
( 0.5f * ( Global.iWindowHeight - height ) + origin.y * heightratio ) + ( charsize ) + ( ( size.y * heightratio - textheight ) * 0.5f * heightratio ) );
|
||||
print( m_progresstext );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ui_layer::render_panels() {
|
||||
|
||||
if( m_panels.empty() ) { return; }
|
||||
|
||||
float const width = std::min( 4.f / 3.f, static_cast<float>(Global.iWindowWidth) / std::max( 1, Global.iWindowHeight ) ) * Global.iWindowHeight;
|
||||
float const height = Global.iWindowHeight / 768.f;
|
||||
|
||||
for( auto const &panel : m_panels ) {
|
||||
|
||||
int lineidx = 0;
|
||||
for( auto const &line : panel->text_lines ) {
|
||||
|
||||
::glColor4fv( glm::value_ptr( line.color ) );
|
||||
::glRasterPos2f(
|
||||
0.5f * ( Global.iWindowWidth - width ) + panel->origin_x * height,
|
||||
panel->origin_y * height + 20.f * lineidx );
|
||||
print( line.data );
|
||||
++lineidx;
|
||||
}
|
||||
for( auto *panel : m_panels ) {
|
||||
panel->render();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,12 +296,7 @@ ui_layer::render_tooltip() {
|
||||
if( m_tooltip.empty() ) { return; }
|
||||
if( false == m_cursorvisible ) { return; }
|
||||
|
||||
glm::dvec2 mousepos;
|
||||
glfwGetCursorPos( m_window, &mousepos.x, &mousepos.y );
|
||||
|
||||
::glColor4fv( glm::value_ptr( colors::white ) );
|
||||
::glRasterPos2f( mousepos.x + 20.0f, mousepos.y + 25.0f );
|
||||
print( m_tooltip );
|
||||
ImGui::SetTooltip( m_tooltip.c_str() );
|
||||
}
|
||||
|
||||
void
|
||||
@@ -295,21 +346,6 @@ ui_layer::render_texture() {
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ui_layer::print( std::string const &Text )
|
||||
{
|
||||
if( (false == Global.DLFont)
|
||||
|| (true == Text.empty()) )
|
||||
return;
|
||||
|
||||
::glPushAttrib( GL_LIST_BIT );
|
||||
|
||||
::glListBase( m_fontbase - 32 );
|
||||
::glCallLists( Text.size(), GL_UNSIGNED_BYTE, Text.c_str() );
|
||||
|
||||
::glPopAttrib();
|
||||
}
|
||||
|
||||
void
|
||||
ui_layer::quad( glm::vec4 const &Coordinates, glm::vec4 const &Color ) {
|
||||
|
||||
|
||||
49
uilayer.h
49
uilayer.h
@@ -14,25 +14,35 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
// GuiLayer -- basic user interface class. draws requested information on top of openGL screen
|
||||
|
||||
struct ui_panel {
|
||||
class ui_panel {
|
||||
|
||||
public:
|
||||
// constructor
|
||||
ui_panel( std::string const Name, bool const Isopen );
|
||||
// methods
|
||||
virtual void update() {};
|
||||
virtual void render();
|
||||
// temporary access
|
||||
// types
|
||||
struct text_line {
|
||||
|
||||
std::string data;
|
||||
glm::vec4 color;
|
||||
|
||||
text_line( std::string const &Data, glm::vec4 const &Color):
|
||||
data(Data), color(Color)
|
||||
text_line( std::string const &Data, glm::vec4 const &Color)
|
||||
: data(Data), color(Color)
|
||||
{}
|
||||
};
|
||||
|
||||
ui_panel( const int X, const int Y):
|
||||
origin_x(X), origin_y(Y)
|
||||
{}
|
||||
|
||||
// members
|
||||
bool is_open;
|
||||
glm::ivec2 size { -1, -1 };
|
||||
glm::ivec2 size_min { -1, -1 };
|
||||
glm::ivec2 size_max { -1, -1 };
|
||||
std::vector<text_line> text_lines;
|
||||
int origin_x;
|
||||
int origin_y;
|
||||
|
||||
protected:
|
||||
// members
|
||||
std::string name;
|
||||
};
|
||||
|
||||
class ui_layer {
|
||||
@@ -51,6 +61,9 @@ public:
|
||||
static
|
||||
void
|
||||
set_unit( GLint const Textureunit ) { m_textureunit = Textureunit; }
|
||||
static
|
||||
void
|
||||
shutdown();
|
||||
// potentially processes provided input key. returns: true if the input was processed, false otherwise
|
||||
virtual
|
||||
bool
|
||||
@@ -58,7 +71,7 @@ public:
|
||||
// updates state of UI elements
|
||||
virtual
|
||||
void
|
||||
update() {}
|
||||
update();
|
||||
// draws requested UI elements
|
||||
void
|
||||
render();
|
||||
@@ -79,17 +92,25 @@ public:
|
||||
void
|
||||
set_tooltip( std::string const &Tooltip ) { m_tooltip = Tooltip; }
|
||||
void
|
||||
clear_texts() { m_panels.clear(); }
|
||||
clear_panels() { m_panels.clear(); }
|
||||
void
|
||||
push_back( ui_panel *Panel ) { m_panels.emplace_back( Panel ); }
|
||||
|
||||
protected:
|
||||
// members
|
||||
static GLFWwindow *m_window;
|
||||
static ImGuiIO *m_imguiio;
|
||||
static bool m_cursorvisible;
|
||||
|
||||
private:
|
||||
// methods
|
||||
static
|
||||
void
|
||||
init_colors();
|
||||
// render() subclass details
|
||||
virtual
|
||||
void
|
||||
render_() {};
|
||||
// draws background quad with specified earlier texture
|
||||
void
|
||||
render_background();
|
||||
@@ -102,15 +123,11 @@ private:
|
||||
render_panels();
|
||||
void
|
||||
render_tooltip();
|
||||
// prints specified text, using display lists font
|
||||
void
|
||||
print( std::string const &Text );
|
||||
// draws a quad between coordinates x,y and z,w with uv-coordinates spanning 0-1
|
||||
void
|
||||
quad( glm::vec4 const &Coordinates, glm::vec4 const &Color );
|
||||
// members
|
||||
static GLint m_textureunit;
|
||||
static GLuint m_fontbase; // numer DL dla znaków w napisach
|
||||
|
||||
// progress bar config. TODO: put these together into an object
|
||||
float m_progress { 0.0f }; // percentage of filled progres bar, to indicate lengthy operations.
|
||||
|
||||
Reference in New Issue
Block a user