From fc2fc3e27c91da8a53907f371a1f92c300491586 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Sat, 6 May 2017 14:31:53 +0200 Subject: [PATCH 1/4] build 170506. minor diagnostics, performance and rendering enhancements --- Driver.cpp | 200 ++++++--------------------------------------- DynObj.cpp | 22 ++++- DynObj.h | 1 + McZapkie/MOVER.h | 2 + McZapkie/Mover.cpp | 12 +++ Train.cpp | 8 ++ Train.h | 1 + World.cpp | 15 ++-- renderer.cpp | 8 +- 9 files changed, 80 insertions(+), 189 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index c5d51c01..cb32ce0b 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -386,13 +386,7 @@ void TSpeedPos::Set(TTrack *track, double dist, int flag) void TController::TableClear() { // wyczyszczenie tablicy -#ifdef EU07_USE_OLD_SPEEDTABLE - iFirst = iLast = 0; - for (int i = 0; i < iSpeedTableSize; ++i) // czyszczenie tabeli prÄ™dkoÅ›ci - sSpeedTable[i].Clear(); -#else sSpeedTable.clear(); -#endif iLast = -1; iTableDirection = 0; // nieznany tLast = nullptr; @@ -413,41 +407,20 @@ TEvent * TController::CheckTrackEvent(double fDirection, TTrack *Track) bool TController::TableAddNew() { // zwiÄ™kszenie użytej tabelki o jeden rekord -#ifdef EU07_USE_OLD_SPEEDTABLE - iLast = ( iLast + 1 ) % iSpeedTableSize; - // TODO: jeszcze sprawdzić, czy siÄ™ na iFirst nie naÅ‚oży - // TODO: wstawić tu wywoÅ‚anie odtykacza - teraz jest to w TableTraceRoute() - // TODO: jeÅ›li ostatnia pozycja zajÄ™ta, ustawiać dodatkowe flagi - teraz jest to w - // TableTraceRoute() - // TODO: przydaÅ‚o by siÄ™ też posortować tabelkÄ™ wg odlegÅ‚oÅ›ci (ale nie w tym miejscu) -#else sSpeedTable.emplace_back(); // add a new slot iLast = sSpeedTable.size() - 1; -#endif return true; // false gdy siÄ™ naÅ‚oży }; bool TController::TableNotFound(TEvent const *Event) const { // sprawdzenie, czy nie zostaÅ‚ już dodany do tabelki (np. podwójne W4 robi problemy) -#ifdef EU07_USE_OLD_SPEEDTABLE - int j = (iLast + 1) % iSpeedTableSize; // j, aby sprawdzić też ostatniÄ… pozycjÄ™ - for (int i = iFirst; i != j; i = (i + 1) % iSpeedTableSize) - if ((sSpeedTable[i].iFlags & (spEnabled | spEvent)) == (spEnabled | - spEvent)) // o ile używana pozycja - if (sSpeedTable[i].evEvent == e) - { - if (Global::iWriteLogEnabled & 8) - WriteLog("TableNotFound: Event already in SpeedTable: " + sSpeedTable[i].evEvent->asName); - return false; // już jest, drugi raz dodawać nie ma po co - } - return true; // nie ma, czyli można dodać -#else - auto lookup = std::find_if( - sSpeedTable.begin(), - sSpeedTable.end(), - [Event]( TSpeedPos const &speedpoint ){ - return ( ( true == TestFlag( speedpoint.iFlags, spEnabled | spEvent ) ) - && ( speedpoint.evEvent == Event ) ); } ); + auto lookup = + std::find_if( + sSpeedTable.begin(), + sSpeedTable.end(), + [Event]( TSpeedPos const &speedpoint ){ + return ( ( true == TestFlag( speedpoint.iFlags, spEnabled | spEvent ) ) + && ( speedpoint.evEvent == Event ) ); } ); if( ( Global::iWriteLogEnabled & 8 ) && ( lookup != sSpeedTable.end() ) ) { @@ -455,7 +428,6 @@ bool TController::TableNotFound(TEvent const *Event) const } return lookup == sSpeedTable.end(); -#endif }; void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) @@ -480,9 +452,6 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) fTrackLength = pTrack->Length() - fTrackLength; // przeskanowana zostanie odlegÅ‚ość do Point2 } fLastVel = pTrack->VelocityGet(); // aktualna prÄ™dkość -#ifdef EU07_USE_OLD_SPEEDTABLE - iFirst = iLast = 0; -#endif sSpeedTable.clear(); iLast = -1; tLast = nullptr; //żaden nie sprawdzony @@ -491,65 +460,21 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) } else { // kontynuacja skanowania od ostatnio sprawdzonego toru (w ostatniej pozycji zawsze jest tor) - // WriteLog("TableTraceRoute: check last track"); -#ifdef EU07_USE_OLD_SPEEDTABLE - if( sSpeedTable[ iLast ].iFlags & spEndOfTable ) // zatkanie - { // jeÅ›li zapeÅ‚niÅ‚a siÄ™ tabelka - if ((iLast + 1) % iSpeedTableSize == iFirst) // jeÅ›li nadal jest zapeÅ‚niona - { - TablePurger(); // nic siÄ™ nie da zrobić - return; - } - if ((iLast + 2) % iSpeedTableSize == iFirst) // musi być jeszcze miejsce wolne na - // ewentualny event, bo tor jeszcze nie - // sprawdzony - { - TablePurger(); - return; // już lepiej, ale jeszcze nie tym razem - } - sSpeedTable[iLast].iFlags &= 0xBE; // kontynuować próby doskanowania - } -#endif - // znaleziono semafor lub tarczÄ™ lub tor z prÄ™dkoÅ›ciÄ… zero, trzeba sprawdzić czy to nadaÅ‚ semafor -#ifdef EU07_USE_OLD_SPEEDTABLE - if( ( sSemNextStop != nullptr ) - && ( sSemNextStop->fVelNext < 1.0 ) ) { -#else if( ( SemNextStopIndex != -1 ) && ( sSpeedTable[SemNextStopIndex].fVelNext < 1.0 ) ) { -#endif + // znaleziono semafor lub tarczÄ™ lub tor z prÄ™dkoÅ›ciÄ… zero, trzeba sprawdzić czy to nadaÅ‚ semafor // jeÅ›li jest nastÄ™pny semafor to sprawdzamy czy to on nadaÅ‚ zero -#ifdef EU07_USE_OLD_SPEEDTABLE - if( ( OrderCurrentGet() & Obey_train ) - && ( sSemNextStop->iFlags & spSemaphor ) ) { -#else if( ( OrderCurrentGet() & Obey_train ) && ( sSpeedTable[SemNextStopIndex].iFlags & spSemaphor ) ) { -#endif return; } else { -#ifdef EU07_USE_OLD_SPEEDTABLE - if( ( OrderCurrentGet() < 0x40 ) - && ( sSemNextStop->iFlags & ( spSemaphor | spShuntSemaphor | spOutsideStation ) ) ) { -#else if( ( OrderCurrentGet() < 0x40 ) && ( sSpeedTable[SemNextStopIndex].iFlags & ( spSemaphor | spShuntSemaphor | spOutsideStation ) ) ) { -#endif return; } } } -#ifdef EU07_USE_OLD_SPEEDTABLE - pTrack = sSpeedTable[iLast].trTrack; // ostatnio sprawdzony tor - if (!pTrack) - return; // koniec toru, to nie ma co sprawdzać (nie ma prawa tak być) - fLastDir = (sSpeedTable[iLast].iFlags & spReverse) ? -1.0 : 1.0; // flaga ustawiona, gdy Point2 toru jest bli�ej - fCurrentDistance = sSpeedTable[iLast].fDist; // aktualna odleg�o�� do jego Point1 - fTrackLength = (sSpeedTable[iLast].iFlags & (spElapsed | spEnd)) ? 0.0 : pTrack->Length(); // nie dolicza� d�ugo�ci gdy: - // 32-miniÄ™ty poczÄ…tek, - // 64-jazda do koÅ„ca toru -#else auto const &lastspeedpoint = sSpeedTable[ iLast ]; pTrack = lastspeedpoint.trTrack; assert( pTrack != nullptr ); @@ -565,7 +490,6 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) ( lastspeedpoint.iFlags & ( spElapsed | spEnd ) != 0 ) ? 0.0 : pTrack->Length() ); -#endif } if( fCurrentDistance >= fDistance ) { @@ -594,59 +518,10 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) if( Global::iWriteLogEnabled & 8 ) { WriteLog( "Speed table for " + OwnerName() + " found new event, " + pEvent->asName ); } -#ifdef EU07_USE_OLD_SPEEDTABLE - if( sSpeedTable[ iLast ].Set( pEvent, fCurrentDistance, OrderCurrentGet() ) ) // dodanie odczytu sygnaÅ‚u - { - fDistance = fCurrentDistance; // jeÅ›li sygnaÅ‚ stop, to nie ma - // potrzeby dalej skanować - sSemNextStop = &sSpeedTable[iLast]; - if (!sSemNext) - sSemNext = &sSpeedTable[iLast]; - if (Global::iWriteLogEnabled & 8) - WriteLog("Signal stop. Next Semaphor ", false); - if (sSemNextStop) - { - if (Global::iWriteLogEnabled & 8) - WriteLog(sSemNextStop->GetName()); - } - else - { - if (Global::iWriteLogEnabled & 8) - WriteLog("none"); - } - } - else { - if( sSpeedTable[ iLast ].IsProperSemaphor( OrderCurrentGet() ) && - sSemNext == NULL ) - sSemNext = - &sSpeedTable[ iLast ]; // sprawdzamy czy pierwszy na drodze - if( Global::iWriteLogEnabled & 8 ) - WriteLog( "Signal forward. Next Semaphor ", false ); - if( sSemNext ) { - if( Global::iWriteLogEnabled & 8 ) - WriteLog( sSemNext->GetName() ); - } - else { - if( Global::iWriteLogEnabled & 8 ) - WriteLog( "none" ); - } - } -#else auto &newspeedpoint = sSpeedTable[ iLast ]; if( newspeedpoint.Set( pEvent, fCurrentDistance, OrderCurrentGet() ) ) { fDistance = fCurrentDistance; // jeÅ›li sygnaÅ‚ stop, to nie ma potrzeby dalej skanować -#ifdef EU07_USE_OLD_SPEEDTABLE - sSemNextStop = &newspeedpoint; - if( sSemNext == nullptr ) { - sSemNext = &newspeedpoint; - } - if( Global::iWriteLogEnabled & 8 ) { - WriteLog( "(stop signal from " - + ( sSemNextStop ? sSemNextStop->GetName() : "unknown semaphor" ) - + ")" ); - } -#else SemNextStopIndex = iLast; if( SemNextIndex == -1 ) { SemNextIndex = iLast; @@ -656,20 +531,8 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) + ( SemNextStopIndex != -1 ? sSpeedTable[SemNextStopIndex].GetName() : "unknown semaphor" ) + ")" ); } -#endif } else { -#ifdef EU07_USE_OLD_SPEEDTABLE - if( ( true == newspeedpoint.IsProperSemaphor( OrderCurrentGet() ) ) - && ( sSemNext == nullptr ) ) { - sSemNext = &newspeedpoint; // sprawdzamy czy pierwszy na drodze - } - if( Global::iWriteLogEnabled & 8 ) { - WriteLog( "(forward signal for " - + ( sSemNext ? sSemNext->GetName() : "unknown semaphor" ) - + ")" ); - } -#else if( ( true == newspeedpoint.IsProperSemaphor( OrderCurrentGet() ) ) && ( SemNextIndex == -1 ) ) { SemNextIndex = iLast; // sprawdzamy czy pierwszy na drodze @@ -679,15 +542,13 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) + ( SemNextIndex != -1 ? sSpeedTable[SemNextIndex].GetName() : "unknown semaphor" ) + ")" ); } -#endif } -#endif } } // event dodajemy najpierw, żeby móc sprawdzić, czy tor zostaÅ‚ dodany po odczytaniu prÄ™dkoÅ›ci nastÄ™pnego - if ((pTrack->VelocityGet() == 0.0) // zatrzymanie - || (pTrack->iAction) // jeÅ›li tor ma wÅ‚asnoÅ›ci istotne dla skanowania - || (pTrack->VelocityGet() != fLastVel)) // nastÄ™puje zmiana prÄ™dkoÅ›ci + if( ( pTrack->VelocityGet() == 0.0 ) // zatrzymanie + || ( pTrack->iAction ) // jeÅ›li tor ma wÅ‚asnoÅ›ci istotne dla skanowania + || ( pTrack->VelocityGet() != fLastVel ) ) // nastÄ™puje zmiana prÄ™dkoÅ›ci { // odcinek dodajemy do tabelki, gdy jest istotny dla ruchu if (TableAddNew()) { // teraz dodatkowo zapamiÄ™tanie wybranego segmentu dla skrzyżowania @@ -723,12 +584,14 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) || ( ( tLast != nullptr ) && ( tLast->fRadius != 0.0 ) )) // koniec Å‚uku też jest istotny { // albo dla liczenia odlegÅ‚oÅ›ci przy pomocy ciÄ™ciw - te usuwać po przejechaniu - if (TableAddNew()) + if (TableAddNew()) { + // dodanie odcinka do tabelki sSpeedTable[iLast].Set( pTrack, fCurrentDistance, ( fLastDir < 0 ? spEnabled | spCurve | spReverse : - spEnabled | spCurve ) ); // dodanie odcinka do tabelki + spEnabled | spCurve ) ); + } } } @@ -766,28 +629,6 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) } } } -#ifdef EU07_USE_OLD_SPEEDTABLE - if( ( ( iLast + 3 ) % iSpeedTableSize == iFirst ) ? - true : - ((iLast + 2) % iSpeedTableSize == iFirst)) // czy tabelka siÄ™ nie zatka? - { // jest ryzyko nieznalezienia ograniczenia - ograniczyć prÄ™dkość do pozwalajÄ…cej - // na zatrzymanie na koÅ„cu przeskanowanej drogi - TablePurger(); // usunąć pilnie zbÄ™dne pozycje - if (((iLast + 3) % iSpeedTableSize == iFirst) ? - true : - ((iLast + 2) % iSpeedTableSize == iFirst)) // czy tabelka siÄ™ nie zatka? - { // jeÅ›li odtykacz nie pomógÅ‚ (TODO: zwiÄ™kszyć rozmiar tabelki) - if (TableAddNew()) - sSpeedTable[iLast].Set( - pTrack, fCurrentDistance, - fLastDir < 0 ? - 0x10045 : - 0x10041); // zapisanie toru jako koÅ„cowego (ogranicza prÄ™dkosć) - // zapisać w logu, że należy poprawić sceneriÄ™? - return; // nie skanujemy dalej, bo nie ma miejsca - } - } -#endif // zwiÄ™kszenie skanowanej odlegÅ‚oÅ›ci tylko jeÅ›li istnieje dalszy tor fTrackLength = pTrack->Length(); } @@ -796,12 +637,14 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) if( ( iLast == -1 ) || ( false == TestFlag( sSpeedTable[iLast].iFlags, spEnabled | spEnd ) ) ) { // only if we haven't already marked end of the track - if( TableAddNew() ) + if( TableAddNew() ) { + // zapisanie ostatniego sprawdzonego toru sSpeedTable[iLast].Set( tLast, fCurrentDistance, ( fLastDir < 0 ? spEnabled | spEnd | spReverse : - spEnabled | spEnd )); // zapisanie ostatniego sprawdzonego toru + spEnabled | spEnd )); + } } // to ostatnia pozycja, bo NULL nic nie da, a może siÄ™ podpiąć obrotnica, czy jakieÅ› transportery return; @@ -1459,6 +1302,9 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN void TController::TablePurger() { // odtykacz: usuwa mniej istotne pozycje ze Å›rodka tabelki, aby uniknąć zatkania //(np. brak ograniczenia pomiÄ™dzy zwrotnicami, usuniÄ™te sygnaÅ‚y, miniÄ™te odcinki Å‚uku) + if( sSpeedTable.size() < 2 ) { + return; + } // simplest approach should be good enough for start -- just copy whatever is still relevant, then swap // do a trial run first, to see if we need to bother at all std::size_t trimcount{ 0 }; @@ -1502,7 +1348,7 @@ void TController::TablePurger() WriteLog( "Speed table garbage collection for " + OwnerName() + " cut away " + std::to_string( trimcount ) + ( trimcount == 1 ? " record" : " records" ) ); } // update the data - sSpeedTable = trimmedtable; + std::swap( sSpeedTable, trimmedtable ); iLast = sSpeedTable.size() - 1; }; diff --git a/DynObj.cpp b/DynObj.cpp index 299fc598..c0b3345d 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -45,6 +45,11 @@ http://mozilla.org/MPL/2.0/. #define M_2PI 6.283185307179586476925286766559; const float maxrot = (float)(M_PI / 3.0); // 60° +std::string const TDynamicObject::MED_labels[] = { + "masa: ", "amax: ", "Fzad: ", "FmPN: ", "FmED: ", "FrED: ", "FzPN: ", "nPrF: " +}; + + //--------------------------------------------------------------------------- void TAnimPant::AKP_4E() { // ustawienie wymiarów dla pantografu AKP-4E @@ -5275,10 +5280,19 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName, //--------------------------------------------------------------------------- void TDynamicObject::RadioStop() { // zatrzymanie pojazdu - if (Mechanik) // o ile ktoÅ› go prowadzi - if (MoverParameters->SecuritySystem.RadioStop && - MoverParameters->Radio) // jeÅ›li pojazd ma RadioStop i jest on aktywny - Mechanik->PutCommand("Emergency_brake", 1.0, 1.0, &vPosition, stopRadio); + if( Mechanik ) { + // o ile ktoÅ› go prowadzi + if( ( MoverParameters->SecuritySystem.RadioStop ) + && ( MoverParameters->Radio ) ) { + // jeÅ›li pojazd ma RadioStop i jest on aktywny + Mechanik->PutCommand( "Emergency_brake", 1.0, 1.0, &vPosition, stopRadio ); + // add onscreen notification for human driver + // TODO: do it selectively for the 'local' driver once the multiplayer is in + if( false == Mechanik->AIControllFlag ) { + Global::tranTexts.AddLine( "!! RADIO-STOP !!", 0.0, 10.0, false ); + } + } + } }; //--------------------------------------------------------------------------- diff --git a/DynObj.h b/DynObj.h index b0efde63..34682611 100644 --- a/DynObj.h +++ b/DynObj.h @@ -546,6 +546,7 @@ public: // modele skÅ‚adowe pojazdu std::string TextureTest(std::string const &name); void OverheadTrack(float o); double MED[9][8]; // lista zmiennych do debugowania hamulca ED + static std::string const MED_labels[ 8 ]; }; //--------------------------------------------------------------------------- diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index b381f0c8..a7cea124 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -773,6 +773,7 @@ public: double Ftmax = 0.0; /*- dla lokomotyw z silnikami indukcyjnymi -*/ double eimc[26]; + static std::vector const eimc_labels; /*-dla wagonow*/ double MaxLoad = 0.0; /*masa w T lub ilosc w sztukach - ladownosc*/ std::string LoadAccepted; std::string LoadQuantity; /*co moze byc zaladowane, jednostki miary*/ @@ -939,6 +940,7 @@ public: /*- zmienne dla lokomotyw z silnikami indukcyjnymi -*/ double eimv[21]; + static std::vector const eimv_labels; /*-zmienne dla drezyny*/ double PulseForce = 0.0; /*przylozona sila*/ diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 63d3095b..ff60e7cf 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -22,6 +22,18 @@ http://mozilla.org/MPL/2.0/. const double dEpsilon = 0.01; // 1cm (zależy od typu sprzÄ™gu...) const double CouplerTune = 0.1; // skalowanie tlumiennosci +std::vector const TMoverParameters::eimc_labels = { + "dfic: ", "dfmax:", "p: ", "scfu: ", "cim: ", "icif: ", "Uzmax:", "Uzh: ", "DU: ", "I0: ", + "fcfu: ", "F0: ", "a1: ", "Pmax: ", "Fh: ", "Ph: ", "Vh0: ", "Vh1: ", "Imax: ", "abed: ", + "eped: " +}; + +std::vector const TMoverParameters::eimv_labels = { + "Fkrt:", "Fmax:", "ks: ", "df: ", "fp: ", "Us: ", "pole:", "Ic: ", "If: ", "M: ", + "Fr: ", "Ipoj:", "Pm: ", "Pe: ", "eta: ", "fkr: ", "Uzsm:", "Pmax:", "Fzad:", "Imax:", + "Fful:" +}; + inline long Trunc(float f) { return (long)f; diff --git a/Train.cpp b/Train.cpp index f199dcc6..d7444fe8 100644 --- a/Train.cpp +++ b/Train.cpp @@ -205,6 +205,11 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = { { user_command::radiotoggle, &TTrain::OnCommand_radiotoggle } }; +std::vector const TTrain::fPress_labels = { + + "ch1: ", "ch2: ", "ch3: ", "ch4: ", "ch5: ", "ch6: ", "ch7: ", "ch8: ", "ch9: ", "ch0: " +}; + TTrain::TTrain() { ActiveUniversal4 = false; @@ -2767,7 +2772,10 @@ void TTrain::OnCommand_radiotoggle( TTrain *Train, command_data const &Command ) if( Command.action == GLFW_PRESS ) { WriteLog( "Radio switch is missing, or wasn't defined" ); } +/* + // NOTE: we ignore the lack of 3d model to allow system reset after receiving radio-stop signal return; +*/ } if( Command.action == GLFW_PRESS ) { diff --git a/Train.h b/Train.h index 60e212fb..31482dba 100644 --- a/Train.h +++ b/Train.h @@ -484,6 +484,7 @@ public: // reszta może by?publiczna public: float fPress[20][3]; // cisnienia dla wszystkich czlonow + static std::vector const fPress_labels; float fEIMParams[9][10]; // parametry dla silnikow asynchronicznych int RadioChannel() { return iRadioChannel; }; inline TDynamicObject *Dynamic() { return DynamicObject; }; diff --git a/World.cpp b/World.cpp index 4a760c3f..52050a68 100644 --- a/World.cpp +++ b/World.cpp @@ -2131,21 +2131,22 @@ TWorld::Update_UI() { // induction motor data if( tmp->MoverParameters->EngineType == ElectricInductionMotor ) { - UITable->text_lines.emplace_back( " eimc: eimv: press:", Global::UITextColor ); + UITable->text_lines.emplace_back( " eimc: eimv: press:", Global::UITextColor ); for( int i = 0; i <= 20; ++i ) { std::string parameters = - to_string(tmp->MoverParameters->eimc[i], 2, 9) - + " " + to_string( tmp->MoverParameters->eimv[ i ], 2, 9 ); + tmp->MoverParameters->eimc_labels[ i ] + to_string( tmp->MoverParameters->eimc[ i ], 2, 9 ) + + " | " + + tmp->MoverParameters->eimv_labels[ i ] + to_string( tmp->MoverParameters->eimv[ i ], 2, 9 ); - if( i <= 10 ) { - parameters += " " + to_string( Train->fPress[ i ][ 0 ], 2, 9 ); + if( i < 10 ) { + parameters += " | " + Train->fPress_labels[i] + to_string( Train->fPress[ i ][ 0 ], 2, 9 ); } else if( i == 12 ) { - parameters += " med:"; + parameters += " med:"; } else if( i >= 13 ) { - parameters += " " + to_string( tmp->MED[ 0 ][ i - 13 ], 2, 9 ); + parameters += " | " + tmp->MED_labels[ i - 13 ] + to_string( tmp->MED[ 0 ][ i - 13 ], 2, 9 ); } UITable->text_lines.emplace_back( parameters, Global::UITextColor ); diff --git a/renderer.cpp b/renderer.cpp index 92e0eff5..15348ec3 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -167,8 +167,14 @@ opengl_renderer::Render( world_environment *Environment ) { ::glDisable( GL_DEPTH_TEST ); ::glDepthMask( GL_FALSE ); ::glPushMatrix(); +/* ::glTranslatef( Global::pCameraPosition.x, Global::pCameraPosition.y, Global::pCameraPosition.z ); - +*/ + glm::mat4 worldcamera; + World.Camera.SetMatrix( worldcamera ); + glLoadIdentity(); + glMultMatrixf( glm::value_ptr( glm::mat4( glm::mat3( worldcamera ) ) ) ); + // setup fog if( Global::fFogEnd > 0 ) { // fog setup From 3203ad1f6cd5387c54534ff9737e12a4fc5c928d Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Sun, 7 May 2017 15:30:28 +0200 Subject: [PATCH 2/4] build 170507. vs2015 compliance --- Driver.h | 4 ++-- uilayer.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Driver.h b/Driver.h index dcbd3b81..d33a2510 100644 --- a/Driver.h +++ b/Driver.h @@ -173,8 +173,8 @@ class TController double fLastVel = 0.0; // prÄ™dkość na poprzednio sprawdzonym torze TTrack *tLast = nullptr; // ostatni analizowany tor TEvent *eSignSkip = nullptr; // można pominąć ten SBL po zatrzymaniu - std::size_t SemNextIndex{ -1 }; - std::size_t SemNextStopIndex{ -1 }; + std::size_t SemNextIndex{ std::size_t(-1) }; + std::size_t SemNextStopIndex{ std::size_t( -1 ) }; private: // parametry aktualnego skÅ‚adu double fLength = 0.0; // dÅ‚ugość skÅ‚adu (do wyciÄ…gania z ograniczeÅ„) double fMass = 0.0; // caÅ‚kowita masa do liczenia stycznej skÅ‚adowej grawitacji diff --git a/uilayer.h b/uilayer.h index 65bcfefe..8966ec8b 100644 --- a/uilayer.h +++ b/uilayer.h @@ -76,7 +76,7 @@ private: // members: - GLuint m_fontbase{ -1 }; // numer DL dla znaków w napisach + GLuint m_fontbase{ (GLuint)-1 }; // numer DL dla znaków w napisach float m_progress{ 0.0f }; // percentage of filled progres bar, to indicate lengthy operations. float m_subtaskprogress{ 0.0f }; // percentage of filled progres bar, to indicate lengthy operations. texture_manager::size_type m_background; // path to texture used as the background. size depends on mAspect. From 54fc93f6e54f5a23af0e30daec9facbec052c74a Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Mon, 8 May 2017 22:41:56 +0200 Subject: [PATCH 3/4] build 170508. fixes for local brake use and 3-way crossroad setup --- Driver.cpp | 5 +++-- Ground.cpp | 34 +++++++++++++++++++++++++++++++--- Ground.h | 10 +++++----- Track.cpp | 42 ++++++++++++++---------------------------- World.cpp | 4 ++-- renderer.cpp | 24 +++++++++++++++++++++++- renderer.h | 8 ++++++++ uilayer.cpp | 2 +- 8 files changed, 87 insertions(+), 42 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index cb32ce0b..b032d8e4 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -2232,8 +2232,9 @@ bool TController::IncBrake() OK = mvOccupied->IncLocalBrakeLevel( std::floor( 1.5 + std::abs( AccDesired ) ) ); break; case Pneumatic: - if ((mvOccupied->Couplers[0].Connected == NULL) && - (mvOccupied->Couplers[1].Connected == NULL)) + // NOTE: can't perform just test whether connected vehicle == nullptr, due to virtual couplers formed with nearby vehicles + if ((mvOccupied->Couplers[0].CouplingFlag == 0) && + (mvOccupied->Couplers[1].CouplingFlag == 0)) OK = mvOccupied->IncLocalBrakeLevel( 1 + static_cast( std::floor( 0.5 + std::fabs(AccDesired))) ); // hamowanie lokalnym bo luzem jedzie else diff --git a/Ground.cpp b/Ground.cpp index c01957bb..4fd4ff9e 100644 --- a/Ground.cpp +++ b/Ground.cpp @@ -304,7 +304,7 @@ void TGroundNode::RenderVBO() { // renderowanie obiektu z VBO - faza nieprzezroc double distancesquared = SquareMagnitude( pCenter - Global::pCameraPosition ) / Global::ZoomFactor; if( ( distancesquared > ( fSquareRadius * Global::fDistanceFactor ) ) - || ( distancesquared < ( fSquareMinRadius / Global::fDistanceFactor ) ) ) { + || ( distancesquared < ( fSquareMinRadius / Global::fDistanceFactor ) ) ) { return; } @@ -318,6 +318,10 @@ void TGroundNode::RenderVBO() { // renderowanie obiektu z VBO - faza nieprzezroc Model->Render( &pCenter ); return; } + case TP_MEMCELL: { + GfxRenderer.Render( MemCell ); + return; + } } if( ( iFlags & 0x10 ) || ( fLineThickness < 0 ) ) { @@ -577,6 +581,10 @@ void TGroundNode::RenderDL() Model->Render( &pCenter ); return; } + case TP_MEMCELL: { + GfxRenderer.Render( MemCell ); + return; + } } // TODO: sprawdzic czy jest potrzebny warunek fLineThickness < 0 @@ -847,7 +855,12 @@ void TSubRect::NodeAdd(TGroundNode *Node) // Node->nNext3=nMeshed; //dopisanie do listy sortowania // nMeshed=Node; break; - case TP_MEMCELL: +#ifdef EU07_SCENERY_EDITOR + case TP_MEMCELL: { + m_memcells.emplace_back( Node ); + break; + } +#endif case TP_TRACTIONPOWERSOURCE: // a te w ogóle pomijamy // case TP_ISOLATED: //lista torów w obwodzie izolowanym - na razie ignorowana break; @@ -1173,7 +1186,14 @@ void TSubRect::RenderDL() node->RenderDL(); // nieprzezroczyste z mieszanych modeli for (int j = 0; j < iTracks; ++j) tTracks[j]->RenderDyn(); // nieprzezroczyste fragmenty pojazdów na torach - +#ifdef EU07_SCENERY_EDITOR + // memcells + if( DebugModeFlag ) { + for( auto const memcell : m_memcells ) { + memcell->RenderDL(); + } + } +#endif /* float width = 100.0f; float height = 25.0f; @@ -1246,6 +1266,14 @@ void TSubRect::RenderVBO() node->RenderVBO(); // nieprzezroczyste z mieszanych modeli for (int j = 0; j < iTracks; ++j) tTracks[j]->RenderDyn(); // nieprzezroczyste fragmenty pojazdów na torach +#ifdef EU07_SCENERY_EDITOR + // memcells + if( DebugModeFlag ) { + for( auto const memcell : m_memcells ) { + memcell->RenderVBO(); + } + } +#endif }; void TSubRect::RenderAlphaVBO() diff --git a/Ground.h b/Ground.h index 0c5722d7..707c127f 100644 --- a/Ground.h +++ b/Ground.h @@ -172,7 +172,6 @@ class TGroundNode : public Resource void Compile(bool many = false); void Release(); - bool GetTraction(); void RenderHidden(); // obsÅ‚uga dźwiÄ™ków i wyzwalaczy zdarzeÅ„ void RenderDL(); // renderowanie nieprzezroczystych w Display Lists @@ -201,16 +200,17 @@ class TSubRect : public Resource, public CMesh TGroundNode *nRootMesh = nullptr; // obiekty renderujÄ…ce wg tekstury (wtórne, lista po nNext2) TGroundNode *nMeshed = nullptr; // lista obiektów dla których istniejÄ… obiekty renderujÄ…ce grupowo public: - TGroundNode * - nRootNode = nullptr; // wszystkie obiekty w sektorze, z wyjÄ…tkiem renderujÄ…cych i pojazdów (nNext2) - TGroundNode * - nRenderHidden = nullptr; // lista obiektów niewidocznych, "renderowanych" również z tyÅ‚u (nNext3) + TGroundNode * nRootNode = nullptr; // wszystkie obiekty w sektorze, z wyjÄ…tkiem renderujÄ…cych i pojazdów (nNext2) + TGroundNode * nRenderHidden = nullptr; // lista obiektów niewidocznych, "renderowanych" również z tyÅ‚u (nNext3) TGroundNode *nRenderRect = nullptr; // z poziomu sektora - nieprzezroczyste (nNext3) TGroundNode *nRenderRectAlpha = nullptr; // z poziomu sektora - przezroczyste (nNext3) TGroundNode *nRenderWires = nullptr; // z poziomu sektora - druty i inne linie (nNext3) TGroundNode *nRender = nullptr; // indywidualnie - nieprzezroczyste (nNext3) TGroundNode *nRenderMixed = nullptr; // indywidualnie - nieprzezroczyste i przezroczyste (nNext3) TGroundNode *nRenderAlpha = nullptr; // indywidualnie - przezroczyste (nNext3) +#ifdef EU07_SCENERY_EDITOR + std::deque< TGroundNode* > m_memcells; // collection of memcells present in the sector +#endif int iNodeCount = 0; // licznik obiektów, do pomijania pustych sektorów public: void LoadNodes(); // utworzenie VBO sektora diff --git a/Track.cpp b/Track.cpp index 3864b93b..7c77ea1d 100644 --- a/Track.cpp +++ b/Track.cpp @@ -176,7 +176,7 @@ void TTrack::Init() break; case tt_Cross: // tylko dla skrzyżowania dróg SwitchExtension = std::make_shared( this, 6 ); // 6 po³¹czeñ - SwitchExtension->vPoints = NULL; // brak tablicy punktów + SwitchExtension->vPoints = nullptr; // brak tablicy punktów SwitchExtension->iPoints = 0; SwitchExtension->bPoints = false; // tablica punktów nie wypeÅ‚niona SwitchExtension->iRoads = 4; // domyÅ›lnie 4 @@ -647,31 +647,26 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name) if (eType != tt_Cross) SwitchExtension->Segments[1]->Init(p3, p3 + cp3, p4 + cp4, p4, segsize, r3, r4); else - SwitchExtension->Segments[1]->Init(p4, p4 + cp4, p3 + cp3, p3, segsize, r4, - r3); // odwrócony + SwitchExtension->Segments[1]->Init(p4, p4 + cp4, p3 + cp3, p3, segsize, r4, r3); // odwrócony } else SwitchExtension->Segments[1]->Init(p3, p4, segsize, r3, r4); if (eType == tt_Cross) { // Ra 2014-07: dla skrzyżowaÅ„ bÄ™dÄ… dodatkowe segmenty - SwitchExtension->Segments[2]->Init(p2, cp2 + p2, cp4 + p4, p4, segsize, r2, - r4); // z punktu 2 do 4 - if (LengthSquared3(p3 - p1) < - 0.01) // gdy mniej niż 10cm, to mamy skrzyżowanie trzech dróg + SwitchExtension->Segments[2]->Init(p2, cp2 + p2, cp4 + p4, p4, segsize, r2, r4); // z punktu 2 do 4 + if (LengthSquared3(p3 - p1) < 0.01) // gdy mniej niż 10cm, to mamy skrzyżowanie trzech dróg SwitchExtension->iRoads = 3; else // dla 4 dróg bÄ™dÄ… dodatkowe 3 segmenty { - SwitchExtension->Segments[3]->Init(p4, p4 + cp4, p1 + cp1, p1, segsize, r4, - r1); // z punktu 4 do 1 - SwitchExtension->Segments[4]->Init(p1, p1 + cp1, p3 + cp3, p3, segsize, r1, - r3); // z punktu 1 do 3 - SwitchExtension->Segments[5]->Init(p3, p3 + cp3, p2 + cp2, p2, segsize, r3, - r2); // z punktu 3 do 2 + SwitchExtension->Segments[3]->Init(p4, p4 + cp4, p1 + cp1, p1, segsize, r4, r1); // z punktu 4 do 1 + SwitchExtension->Segments[4]->Init(p1, p1 + cp1, p3 + cp3, p3, segsize, r1, r3); // z punktu 1 do 3 + SwitchExtension->Segments[5]->Init(p3, p3 + cp3, p2 + cp2, p2, segsize, r3, r2); // z punktu 3 do 2 } } Switch(0); // na staÅ‚e w poÅ‚ożeniu 0 - nie ma poczÄ…tkowego stanu zwrotnicy we wpisie + if( eType == tt_Switch ) // Ra: zamienić później na iloczyn wektorowy { vector3 v1, v2; @@ -1673,24 +1668,15 @@ void TTrack::Compile(GLuint tex) SwitchExtension->Segments[5]->RenderLoft( rpts2, -3, fTexLength, 0, 1, &b, render); // tylko jeÅ›li jest z lewej } - else // to bÄ™dzie ewentualnie dla prostego na skrzyżowaniu trzech dróg - { // punkt 3 pokrywa siÄ™ z punktem 1, jak w zwrotnicy; połączenie 1->2 nie musi być - // prostoliniowe + else + // to bÄ™dzie ewentualnie dla prostego na skrzyżowaniu trzech dróg + { // punkt 3 pokrywa siÄ™ z punktem 1, jak w zwrotnicy; połączenie 1->2 nie musi być prostoliniowe if ((fTexHeight1 >= 0.0) ? true : (side != 0.0)) // OK - SwitchExtension->Segments[2]->RenderLoft(rpts2, -3, fTexLength, 0, 1, &b, - render); // z P2 do P4 + SwitchExtension->Segments[2]->RenderLoft(rpts2, -3, fTexLength, 0, 1, &b, render); // z P2 do P4 if ((fTexHeight1 >= 0.0) ? true : (side != 0.0)) // OK - SwitchExtension->Segments[1]->RenderLoft( - rpts2, -3, fTexLength, 0, 1, &b, render); // z P4 do P3=P1 (odwrócony) + SwitchExtension->Segments[1]->RenderLoft(rpts2, -3, fTexLength, 0, 1, &b, render); // z P4 do P3=P1 (odwrócony) if ((fTexHeight1 >= 0.0) ? true : (side != 0.0)) // OK - SwitchExtension->Segments[0]->RenderLoft(rpts2, -3, fTexLength, 0, 1, &b, - render); // z P1 do P2 - /* - if ((fTexHeight1>=0.0)?true:(slop!=0.0)) - Segment->RenderLoft(rpts1,3,fTexLength); - if ((fTexHeight1>=0.0)?true:(side!=0.0)) - Segment->RenderLoft(rpts2,3,fTexLength); - */ + SwitchExtension->Segments[0]->RenderLoft(rpts2, -3, fTexLength, 0, 1, &b, render); // z P1 do P2 } } // renderowanie nawierzchni na koÅ„cu diff --git a/World.cpp b/World.cpp index 52050a68..cb003bfe 100644 --- a/World.cpp +++ b/World.cpp @@ -702,8 +702,8 @@ void TWorld::OnKeyDown(int cKey) Global::iTextMode = GLFW_KEY_F1; // to wyÅ›wietlić zegar i informacjÄ™ } } - else if( Global::ctrlState && cKey == GLFW_KEY_PAUSE ) //[Ctrl]+[Break] - { // hamowanie wszystkich pojazdów w okolicy + else if( ( cKey == GLFW_KEY_PAUSE ) && ( Global::ctrlState ) ) { + //[Ctrl]+[Break] hamowanie wszystkich pojazdów w okolicy if (Controlled->MoverParameters->Radio) Ground.RadioStop(Camera.Pos); } diff --git a/renderer.cpp b/renderer.cpp index 15348ec3..c3c7e85f 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -112,6 +112,10 @@ opengl_renderer::Init( GLFWwindow *Window ) { m_moontextureid = GetTextureId( "fx\\moon", szTexturePath ); WriteLog( "...gfx data pre-loading done" ); + // prepare debug mode objects + m_quadric = gluNewQuadric(); + gluQuadricNormals( m_quadric, GLU_FLAT ); + return true; } @@ -585,7 +589,25 @@ opengl_renderer::Render( TSubModel *Submodel ) { if( Submodel->Next ) if( Submodel->iAlpha & Submodel->iFlags & 0x1F000000 ) Render( Submodel->Next ); // dalsze rekurencyjnie -}; +} + +void +opengl_renderer::Render( TMemCell *Memcell ) { + + ::glPushAttrib( GL_ENABLE_BIT ); +// ::glDisable( GL_LIGHTING ); + ::glDisable( GL_TEXTURE_2D ); +// ::glEnable( GL_BLEND ); + ::glPushMatrix(); + + auto const position = Memcell->Position(); + ::glTranslated( position.x, position.y + 0.5, position.z ); + ::glColor3f( 0.36f, 0.75f, 0.35f ); + ::gluSphere( m_quadric, 0.35, 4, 2 ); + + ::glPopMatrix(); + ::glPopAttrib(); +} bool opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) { diff --git a/renderer.h b/renderer.h index 2ac84e34..7f779308 100644 --- a/renderer.h +++ b/renderer.h @@ -15,6 +15,7 @@ http://mozilla.org/MPL/2.0/. #include "dumb3d.h" #include "frustum.h" #include "world.h" +#include "memcell.h" struct opengl_light { @@ -110,6 +111,9 @@ class opengl_renderer { public: // types +// destructor + ~opengl_renderer() { gluDeleteQuadric( m_quadric ); } + // methods bool Init( GLFWwindow *Window ); @@ -128,6 +132,8 @@ public: Render( TModel3d *Model, material_data const *Material, Math3D::vector3 const &Position, Math3D::vector3 const &Angle ); void Render( TSubModel *Submodel ); + void + Render( TMemCell *Memcell ); bool Render_Alpha( TDynamicObject *Dynamic ); bool @@ -196,6 +202,8 @@ private: texture_manager::size_type m_glaretextureid{ -1 }; texture_manager::size_type m_suntextureid{ -1 }; texture_manager::size_type m_moontextureid{ -1 }; + GLUquadricObj *m_quadric; // helper object for drawing debug mode scene elements + }; extern opengl_renderer GfxRenderer; diff --git a/uilayer.cpp b/uilayer.cpp index a7e3f8ec..dcad5b58 100644 --- a/uilayer.cpp +++ b/uilayer.cpp @@ -140,7 +140,7 @@ ui_layer::render_panels() { glPushAttrib( GL_ENABLE_BIT ); glDisable( GL_TEXTURE_2D ); - float const width = std::min( 4.0f / 3.0f, static_cast(Global::iWindowWidth) / Global::iWindowHeight ) * Global::iWindowHeight; + float const width = std::min( 4.0f / 3.0f, static_cast(Global::iWindowWidth) / std::max( 1, Global::iWindowHeight ) ) * Global::iWindowHeight; float const height = Global::iWindowHeight / 768.0; for( auto const &panel : m_panels ) { From 6655011af77e255073a0513a4b0de62a3d87b4f1 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Tue, 9 May 2017 20:26:22 +0200 Subject: [PATCH 4/4] build 170509. minor fixes for pantograph logic and speed table calculations --- Driver.cpp | 11 +++++++++++ DynObj.cpp | 7 +++++++ 2 files changed, 18 insertions(+) diff --git a/Driver.cpp b/Driver.cpp index b032d8e4..6cde0078 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -226,6 +226,15 @@ bool TSpeedPos::Update(vector3 *p, vector3 *dir, double &len) } } } + else { + if( fDist < 50.0 ) { + // old sceneries use trick of placing 'helper' semaphores underground, which can lead to vehicles running over them instead of stopping in front of them + // to account for it at short distances we redo distance calculation on 2d plane + fDist = glm::dot( + glm::vec3( v.x, 0.0, v.z ), + glm::vec3( dir->x, 0.0, dir->z ) ); + } + } } if (fDist > 0.0) // nie może być 0.0, a przypadkiem mogÅ‚o by siÄ™ trafić i byÅ‚o by źle @@ -391,6 +400,8 @@ void TController::TableClear() iTableDirection = 0; // nieznany tLast = nullptr; fLastVel = -1.0; + SemNextIndex = -1; + SemNextStopIndex = -1; eSignSkip = nullptr; // nic nie pomijamy }; diff --git a/DynObj.cpp b/DynObj.cpp index c0b3345d..28336bae 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -2943,8 +2943,11 @@ bool TDynamicObject::Update(double dt, double dt1) // drop pantographs // NOTE: this isn't universal behaviour // TODO: have this dependant on .fiz-driven flag + // NOTE: moved to pantspeed calculation part a little later in the function. all remarks and todo still apply +/* MoverParameters->PantFront( false, ( MoverParameters->TrainType == dt_EZT ? command_range::unit : command_range::local ) ); MoverParameters->PantRear( false, ( MoverParameters->TrainType == dt_EZT ? command_range::unit : command_range::local ) ); +*/ } } @@ -3226,6 +3229,10 @@ bool TDynamicObject::Update(double dt, double dt1) else { pantspeedfactor = 0.0; } + if( ( false == MoverParameters->Battery ) + && ( false == MoverParameters->ConverterFlag ) ) { + pantspeedfactor = 0.0; + } pantspeedfactor = std::max( 0.0, pantspeedfactor ); k = p->fAngleL; if( ( pantspeedfactor > 0.0 )