From 435dc24d3eeae95d2c268f3640906cc67278de13 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Sat, 9 Sep 2017 00:55:16 +0200 Subject: [PATCH 1/3] build 170908. minor refactoring and diagnostics enhancements, virtual coupling fix, support for pantograph compressor submodels --- Driver.cpp | 10 ++-- DynObj.cpp | 136 ++++++++++++++++++++++++--------------------- Event.cpp | 120 ++++++++++++++++++++------------------- Ground.cpp | 16 +++--- McZapkie/MOVER.h | 1 - McZapkie/Mover.cpp | 88 ++++++++++++++--------------- Timer.cpp | 17 +++--- Track.cpp | 2 +- Track.h | 2 +- Train.cpp | 70 +++++++++++++++-------- Train.h | 2 + TrkFoll.cpp | 8 +-- version.h | 2 +- 13 files changed, 257 insertions(+), 217 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 3c9b9780..a0e2a58f 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -46,12 +46,12 @@ ProjectEventOnTrack( TEvent const *Event, TTrack const *Track, double const Dire ( 1.0 - nearestpoint ) * segment->GetLength() ); // measure from point2 }; -double GetDistanceToEvent(TTrack* track, TEvent* event, double scan_dir, double start_dist, int iter = 0, bool back = false) +double GetDistanceToEvent(TTrack const *track, TEvent const *event, double scan_dir, double start_dist, int iter = 0, bool back = false) { if( track == nullptr ) { return start_dist; } auto const segment = track->CurrentSegment(); - vector3 const pos_event = event->PositionGet(); + auto const pos_event = event->PositionGet(); double len1, len2; double sd = scan_dir; double seg_len = scan_dir > 0 ? 0.0 : 1.0; @@ -63,7 +63,7 @@ double GetDistanceToEvent(TTrack* track, TEvent* event, double scan_dir, double len1 = len2; seg_len += scan_dir > 0 ? dzielnik : -dzielnik; len2 = (pos_event - segment->FastGetPoint(seg_len)).LengthSquared(); - krok++; + ++krok; } while ((len1 > len2) && (seg_len >= dzielnik && (seg_len <= (1 - dzielnik)))); //trzeba sprawdzić czy seg_len nie osiągnął skrajnych wartości, bo wtedy // trzeba sprawdzić tor obok @@ -71,7 +71,7 @@ double GetDistanceToEvent(TTrack* track, TEvent* event, double scan_dir, double sd = -sd; // jeśli tylko jeden krok tzn, że event przy poprzednim sprawdzaym torze if (((seg_len <= dzielnik) || (seg_len > (1 - dzielnik))) && (iter < 3)) { // przejście na inny tor - track = track->Neightbour(int(sd), sd); + track = track->Connected(int(sd), sd); start_dist += (1 == krok) ? 0 : back ? -segment->GetLength() : segment->GetLength(); return GetDistanceToEvent(track, event, sd, start_dist, ++iter, 1 == krok ? true : false); } @@ -616,7 +616,7 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) fCurrentDistance += fTrackLength; // doliczenie kolejnego odcinka do przeskanowanej długości tLast = pTrack; // odhaczenie, że sprawdzony fLastVel = pTrack->VelocityGet(); // prędkość na poprzednio sprawdzonym odcinku - pTrack = pTrack->Neightbour( + pTrack = pTrack->Connected( ( pTrack->eType == tt_Cross ? (sSpeedTable[iLast].iFlags >> 28) : static_cast(fLastDir) ), diff --git a/DynObj.cpp b/DynObj.cpp index f3c24d7f..68c8adb0 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -1262,71 +1262,65 @@ int TDynamicObject::Dettach(int dir) .CouplingFlag; // sprzęg po rozłączaniu (czego się nie da odpiąć } -void TDynamicObject::CouplersDettach(double MinDist, int MyScanDir) -{ // funkcja rozłączajaca podłączone sprzęgi, - // jeśli odległość przekracza (MinDist) +void TDynamicObject::CouplersDettach(double MinDist, int MyScanDir) { + // funkcja rozłączajaca podłączone sprzęgi, jeśli odległość przekracza (MinDist) // MinDist - dystans minimalny, dla ktorego mozna rozłączać - if (MyScanDir > 0) - { - if (PrevConnected) // pojazd od strony sprzęgu 0 - { - if (MoverParameters->Couplers[0].CoupleDist > MinDist) { - // sprzęgi wirtualne zawsze przekraczają - - if ((PrevConnectedNo ? PrevConnected->NextConnected : - PrevConnected->PrevConnected) == this) - { // Ra: nie rozłączamy znalezionego, jeżeli nie do nas - // podłączony (może jechać w - // innym kierunku) - PrevConnected->MoverParameters->Couplers[PrevConnectedNo].Connected = NULL; - if (PrevConnectedNo == 0) - { - PrevConnected->PrevConnectedNo = 2; // sprzęg 0 nie podłączony - PrevConnected->PrevConnected = NULL; - } - else if (PrevConnectedNo == 1) - { - PrevConnected->NextConnectedNo = 2; // sprzęg 1 nie podłączony - PrevConnected->NextConnected = NULL; - } + if (MyScanDir > 0) { + // pojazd od strony sprzęgu 0 + if( ( PrevConnected != nullptr ) + && ( MoverParameters->Couplers[ TMoverParameters::side::front ].CoupleDist > MinDist ) ) { + // sprzęgi wirtualne zawsze przekraczają + if( ( PrevConnectedNo == TMoverParameters::side::front ? + PrevConnected->PrevConnected : + PrevConnected->NextConnected ) + == this ) { + // Ra: nie rozłączamy znalezionego, jeżeli nie do nas podłączony + // (może jechać w innym kierunku) + PrevConnected->MoverParameters->Couplers[PrevConnectedNo].Connected = nullptr; + if( PrevConnectedNo == TMoverParameters::side::front ) { + // sprzęg 0 nie podłączony + PrevConnected->PrevConnectedNo = 2; + PrevConnected->PrevConnected = nullptr; + } + else if( PrevConnectedNo == TMoverParameters::side::rear ) { + // sprzęg 1 nie podłączony + PrevConnected->NextConnectedNo = 2; + PrevConnected->NextConnected = nullptr; } - - // za to zawsze odłączamy siebie - PrevConnected = NULL; - PrevConnectedNo = 2; // sprzęg 0 nie podłączony - MoverParameters->Couplers[0].Connected = nullptr; } + // za to zawsze odłączamy siebie + PrevConnected = nullptr; + PrevConnectedNo = 2; // sprzęg 0 nie podłączony + MoverParameters->Couplers[ TMoverParameters::side::front ].Connected = nullptr; } } - else - { - if (NextConnected) // pojazd od strony sprzęgu 1 - { - if (MoverParameters->Couplers[1].CoupleDist > MinDist) { - // sprzęgi wirtualne zawsze przekraczają - - if ((NextConnectedNo ? NextConnected->NextConnected : - NextConnected->PrevConnected) == this) - { // Ra: nie rozłączamy znalezionego, jeżeli nie do nas - // podłączony (może jechać w - // innym kierunku) - NextConnected->MoverParameters->Couplers[NextConnectedNo].Connected = NULL; - if (NextConnectedNo == 0) - { - NextConnected->PrevConnectedNo = 2; // sprzęg 0 nie podłączony - NextConnected->PrevConnected = NULL; - } - else if (NextConnectedNo == 1) - { - NextConnected->NextConnectedNo = 2; // sprzęg 1 nie podłączony - NextConnected->NextConnected = NULL; - } + else { + // pojazd od strony sprzęgu 1 + if( ( NextConnected != nullptr ) + && ( MoverParameters->Couplers[ TMoverParameters::side::rear ].CoupleDist > MinDist ) ) { + // sprzęgi wirtualne zawsze przekraczają + if( ( NextConnectedNo == TMoverParameters::side::front ? + NextConnected->PrevConnected : + NextConnected->NextConnected ) + == this) { + // Ra: nie rozłączamy znalezionego, jeżeli nie do nas podłączony + // (może jechać w innym kierunku) + NextConnected->MoverParameters->Couplers[ NextConnectedNo ].Connected = nullptr; + if( NextConnectedNo == TMoverParameters::side::front ) { + // sprzęg 0 nie podłączony + NextConnected->PrevConnectedNo = 2; + NextConnected->PrevConnected = nullptr; + } + else if( NextConnectedNo == TMoverParameters::side::rear ) { + // sprzęg 1 nie podłączony + NextConnected->NextConnectedNo = 2; + NextConnected->NextConnected = nullptr; } - - NextConnected = NULL; - NextConnectedNo = 2; // sprzęg 1 nie podłączony - MoverParameters->Couplers[1].Connected = nullptr; } + // za to zawsze odłączamy siebie + NextConnected = nullptr; + NextConnectedNo = 2; // sprzęg 1 nie podłączony + MoverParameters->Couplers[1].Connected = nullptr; } } } @@ -1428,6 +1422,18 @@ void TDynamicObject::ABuScanObjects( int Direction, double Distance ) if( foundobject->MoverParameters->Couplers[ foundcoupler ].CouplingFlag == coupling::faux ) { // Ra: wpinamy się wirtualnym tylko jeśli znaleziony ma wirtualny sprzęg + if( ( foundcoupler == TMoverParameters::side::front ? + foundobject->PrevConnected : + foundobject->NextConnected ) + != this ) { + // but first break existing connection of the target, + // otherwise we risk leaving the target's connected vehicle with active one-side connection + foundobject->CouplersDettach( + 1.0, + ( foundcoupler == TMoverParameters::side::front ? + 1 : + -1 ) ); + } foundobject->MoverParameters->Attach( foundcoupler, mycoupler, this->MoverParameters, coupling::faux ); if( foundcoupler == TMoverParameters::side::front ) { @@ -2577,15 +2583,19 @@ bool TDynamicObject::Update(double dt, double dt1) tp.CategoryFlag = MyTrack->iCategoryFlag & 15; tp.DamageFlag = MyTrack->iDamageFlag; tp.QualityFlag = MyTrack->iQualityFlag; - if ((MoverParameters->Couplers[0].CouplingFlag > 0) && - (MoverParameters->Couplers[1].CouplingFlag > 0)) - { + + // couplers + if( ( MoverParameters->Couplers[ 0 ].CouplingFlag != coupling::faux ) + && ( MoverParameters->Couplers[ 1 ].CouplingFlag != coupling::faux ) ) { + MoverParameters->InsideConsist = true; } - else - { + else { + MoverParameters->InsideConsist = false; } + // + // napiecie sieci trakcyjnej // Ra 15-01: przeliczenie poboru prądu powinno być robione wcześniej, żeby na // tym etapie były diff --git a/Event.cpp b/Event.cpp index 42ee01c3..5461c74d 100644 --- a/Event.cpp +++ b/Event.cpp @@ -140,10 +140,7 @@ void TEvent::Conditions(cParser *parser, std::string s) void TEvent::Load(cParser *parser, vector3 *org) { - int i; - int ti; std::string token; - //string str; bEnabled = true; // zmieniane na false dla eventów używanych do skanowania sygnałów @@ -247,47 +244,47 @@ void TEvent::Load(cParser *parser, vector3 *org) *parser >> token; Conditions(parser, token); // sprawdzanie warunków break; - case tp_CopyValues: - Params[9].asText = NULL; + case tp_CopyValues: { + Params[9].asText = nullptr; iFlags = update_memstring | update_memval1 | update_memval2; // normalanie trzy - i = 0; + int paramidx { 0 }; parser->getTokens(); *parser >> token; // nazwa drugiej komórki (źródłowej) - while (token.compare("endevent") != 0) - { - switch (++i) + while (token.compare("endevent") != 0) { + + switch (++paramidx) { // znaczenie kolejnych parametrów case 1: // nazwa drugiej komórki (źródłowej) Params[9].asText = new char[token.size() + 1]; // usuwane i zamieniane na wskaźnik strcpy(Params[9].asText, token.c_str()); break; case 2: // maska wartości - iFlags = stol_def(token, - (update_memstring | update_memval1 | update_memval2)); + iFlags = stol_def(token, (update_memstring | update_memval1 | update_memval2)); break; } parser->getTokens(); *parser >> token; } break; - case tp_WhoIs: + } + case tp_WhoIs: { iFlags = update_memstring | update_memval1 | update_memval2; // normalanie trzy - i = 0; + int paramidx { 0 }; parser->getTokens(); *parser >> token; // nazwa drugiej komórki (źródłowej) - while (token.compare("endevent") != 0) - { - switch (++i) - { // znaczenie kolejnych parametrów - case 1: // maska wartości - iFlags = stol_def(token, - (update_memstring | update_memval1 | update_memval2)); - break; + while( token.compare( "endevent" ) != 0 ) { + switch( ++paramidx ) { // znaczenie kolejnych parametrów + case 1: // maska wartości + iFlags = stol_def( token, ( update_memstring | update_memval1 | update_memval2 ) ); + break; + default: + break; } parser->getTokens(); *parser >> token; } break; + } case tp_GetValues: case tp_LogValues: parser->getTokens(); //"endevent" @@ -384,25 +381,27 @@ void TEvent::Load(cParser *parser, vector3 *org) parser->getTokens(); *parser >> token; break; - case tp_Lights: - i = 0; - do - { + case tp_Lights: { + int paramidx { 0 }; + do { parser->getTokens(); *parser >> token; - if (token.compare("endevent") != 0) - { - // str = AnsiString(token.c_str()); - if (i < 8) - Params[i].asdouble = atof(token.c_str()); // teraz może mieć ułamek - i++; + if( token.compare( "endevent" ) != 0 ) { + + if( paramidx < 8 ) { + Params[ paramidx ].asdouble = atof( token.c_str() ); // teraz może mieć ułamek + ++paramidx; + } + else { + ErrorLog( "Bad event: lights event \"" + asName + "\" with more than 8 parameters" ); + } } - } while (token.compare("endevent") != 0); + } while( token.compare( "endevent" ) != 0 ); break; + } case tp_Visible: // zmiana wyświetlania obiektu parser->getTokens(); *parser >> token; - // str = AnsiString(token.c_str()); Params[0].asInt = atoi(token.c_str()); parser->getTokens(); *parser >> token; @@ -410,7 +409,6 @@ void TEvent::Load(cParser *parser, vector3 *org) case tp_Velocity: parser->getTokens(); *parser >> token; - // str = AnsiString(token.c_str()); Params[0].asdouble = atof(token.c_str()) * 0.28; parser->getTokens(); *parser >> token; @@ -544,38 +542,46 @@ void TEvent::Load(cParser *parser, vector3 *org) parser->getTokens(); *parser >> token; break; - case tp_Multiple: - i = 0; - ti = 0; // flaga dla else + case tp_Multiple: { + int paramidx { 0 }; + bool ti { false }; // flaga dla else parser->getTokens(); *parser >> token; - // str = AnsiString(token.c_str()); - while (token != "endevent" && token != "condition" && - token != "randomdelay") - { - if ((token.substr(0, 5) != "none_") ? (i < 8) : false) - { // eventy rozpoczynające się od "none_" są ignorowane - if (token != "else") - { - Params[i].asText = new char[token.size() + 1]; - strcpy(Params[i].asText, token.c_str()); - if (ti) - iFlags |= conditional_else << i; // oflagowanie dla eventów "else" - i++; + + while( ( token != "endevent" ) + && ( token != "condition" ) + && ( token != "randomdelay" ) ) { + + if( token != "else" ) { + if( token.substr( 0, 5 ) != "none_" ) { + // eventy rozpoczynające się od "none_" są ignorowane + if( paramidx < 8 ) { + Params[ paramidx ].asText = new char[ token.size() + 1 ]; + strcpy( Params[ paramidx ].asText, token.c_str() ); + if( ti ) { + // oflagowanie dla eventów "else" + iFlags |= conditional_else << paramidx; + } + ++paramidx; + } + else { + ErrorLog( "Bad event: multi-event \"" + asName + "\" with more than 8 events; discarding link to event \"" + token + "\"" ); + } + } + else { + WriteLog( "Multi-event \"" + asName + "\" ignored link to event \"" + token + "\"" ); } - else - ti = !ti; // zmiana flagi dla słowa "else" } - else if (i >= 8) - ErrorLog("Bad event: \"" + token + "\" ignored in multiple \"" + asName + "\"!"); - else - WriteLog("Event \"" + token + "\" ignored in multiple \"" + asName + "\"!"); + else { + // zmiana flagi dla słowa "else" + ti = !ti; + } parser->getTokens(); *parser >> token; - // str = AnsiString(token.c_str()); } Conditions(parser, token); // sprawdzanie warunków break; + } case tp_Voltage: // zmiana napięcia w zasilaczu (TractionPowerSource) case tp_Friction: // zmiana przyczepnosci na scenerii parser->getTokens(); diff --git a/Ground.cpp b/Ground.cpp index 8c2a349d..482ced09 100644 --- a/Ground.cpp +++ b/Ground.cpp @@ -2175,11 +2175,11 @@ bool TGround::Init(std::string File) { // możliwość przedefiniowania parametrów w scenerii Global::ConfigParse(parser); // parsowanie dodatkowych ustawień } - else if (str != "") - { // pomijanie od nierozpoznanej komendy do jej zakończenia - if ((token.length() > 2) && (atof(token.c_str()) == 0.0)) - { // jeśli nie liczba, to spróbować pominąć komendę - WriteLog("Unrecognized command: " + str); + else if (str != "") { + // pomijanie od nierozpoznanej komendy do jej zakończenia + if ((token.length() > 2) && (atof(token.c_str()) == 0.0)) { + // jeśli nie liczba, to spróbować pominąć komendę + WriteLog( "Unrecognized command: \"" + str + "\" encountered in file \"" + parser.Name() + "\" (line " + std::to_string( parser.Line() - 1 ) + ")" ); str = "end" + str; do { @@ -2188,8 +2188,10 @@ bool TGround::Init(std::string File) parser >> token; } while ((token != "") && (token.compare(str.c_str()) != 0)); } - else // jak liczba to na pewno błąd - Error("Unrecognized command: " + str); + else { + // jak liczba to na pewno błąd + ErrorLog( "Unrecognized command: \"" + str + "\" encountered in file \"" + parser.Name() + "\" (line " + std::to_string( parser.Line() - 1 ) + ")" ); + } } token = ""; diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index bcb743c9..642c7bfb 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -813,7 +813,6 @@ public: voltage }; #endif - int ScanCounter = 0; /*pomocnicze do skanowania sprzegow*/ bool EventFlag = false; /*!o true jesli cos nietypowego sie wydarzy*/ int SoundFlag = 0; /*!o patrz stale sound_ */ double DistCounter = 0.0; /*! licznik kilometrow */ diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 088e0074..8f00004a 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -473,7 +473,7 @@ bool TMoverParameters::Attach(int ConnectNo, int ConnectToNr, TMoverParameters * coupler.Connected = ConnectTo; // tak podpiąć (do siebie) zawsze można, najwyżej będzie wirtualny CouplerDist( ConnectNo ); // przeliczenie odległości pomiędzy sprzęgami - if (CouplingType == ctrain_virtual) + if (CouplingType == coupling::faux) return false; // wirtualny więcej nic nie robi auto &othercoupler = ConnectTo->Couplers[ coupler.ConnectedNr ]; @@ -555,21 +555,29 @@ bool TMoverParameters::Dettach(int ConnectNo) return false; // jeszcze nie rozłączony }; -void TMoverParameters::SetCoupleDist() -{ // przeliczenie odległości sprzęgów - if (Couplers[0].Connected) - { - CouplerDist(0); - if (CategoryFlag & 2) - { // Ra: dla samochodów zderzanie kul to za mało +// przeliczenie odległości sprzęgów +void TMoverParameters::SetCoupleDist() { +/* + double const MaxDist = 100.0; // 2x average max proximity distance. TODO: rearrange ito something more elegant +*/ + for( int coupleridx = 0; coupleridx <= 1; ++coupleridx ) { + + if( Couplers[ coupleridx ].Connected == nullptr ) { continue; } + + CouplerDist( coupleridx ); + if( CategoryFlag & 2 ) { + // Ra: dla samochodów zderzanie kul to za mało + // NOTE: whatever calculation was supposed to be here, ain't } - } - if (Couplers[1].Connected) - { - CouplerDist(1); - if (CategoryFlag & 2) - { // Ra: dla samochodów zderzanie kul to za mało +/* + if( ( Couplers[ coupleridx ].CouplingFlag == coupling::faux ) + && ( Couplers[ coupleridx ].CoupleDist > MaxDist ) ) { + // zerwij kontrolnie wirtualny sprzeg + // Connected.Couplers[CNext].Connected:=nil; //Ra: ten podłączony niekoniecznie jest wirtualny + Couplers[ coupleridx ].Connected = nullptr; + Couplers[ coupleridx ].ConnectedNr = 2; } +*/ } }; @@ -3725,14 +3733,12 @@ void TMoverParameters::ComputeTotalForce(double dt, double dt1, bool FullVer) else { Voltage = 0; } - //if (Mains && /*(abs(CabNo) < 2) &&*/ ( - // EngineType == ElectricInductionMotor)) // potem ulepszyc! pantogtrafy! - // Voltage = RunningTraction.TractionVoltage; if (Power > 0) FTrain = TractionForce(dt); else FTrain = 0; + Fb = BrakeForce(RunningTrack); Fwheels = FTrain - Fb * Sign(V); if( ( Vel > 0.001 ) // crude trap, to prevent braked stationary vehicles from passing fb > mass * adhesive test @@ -3966,7 +3972,7 @@ double TMoverParameters::Adhesive(double staticfriction) // WriteLog(FloatToStr(adhesive)); // tutaj jest na poziomie 0.2 - 0.3 return adhesion; */ - /* //wersja druga + //wersja druga if( true == SlippingWheels ) { if( true == SandDose ) { adhesion = 0.48; } @@ -3977,12 +3983,15 @@ double TMoverParameters::Adhesive(double staticfriction) if( true == SandDose ) { adhesion = std::max( staticfriction * ( 100.0 + Vel ) / ( 50.0 + Vel ) * 1.1, 0.48 ); } else { adhesion = staticfriction * ( 100.0 + Vel ) / ( 50.0 + Vel ); } } - adhesion *= ( 11.0 - 2 * Random() ) / 10.0; */ +// adhesion *= ( 0.9 + 0.2 * Random() ); +/* //wersja3 by youBy - uwzględnia naturalne mikropoślizgi i wpływ piasecznicy, usuwa losowość z pojazdu double Vwheels = nrot * M_PI * WheelDiameter; // predkosc liniowa koła wynikająca z obrotowej double deltaV = V - Vwheels; //poślizg - różnica prędkości w punkcie styku koła i szyny deltaV = std::max(0.0, std::abs(deltaV) - 0.25); //mikropoślizgi do ok. 0,25 m/s nie zrywają przyczepności - adhesion = staticfriction * (28 + Vwheels) / (14 + Vwheels) * ((SandDose? sandfactor : 1) - (1 - adh_factor)*(deltaV / (deltaV + slipfactor))); + Vwheels = std::abs( Vwheels ); + adhesion = staticfriction * (28 + Vwheels) / (14 + Vwheels) * ((SandDose? sandfactor : 1) - (1 - adh_factor)*(deltaV / (deltaV + slipfactor))); +*/ return adhesion; } @@ -4052,24 +4061,11 @@ double TMoverParameters::CouplerForce(int CouplerN, double dt) // blablabla // ABu: proby znalezienia problemu ze zle odbijajacymi sie skladami //if (Couplers[CouplerN].CouplingFlag=ctrain_virtual) and (newdist>0) then - if ((Couplers[CouplerN].CouplingFlag == ctrain_virtual) && (Couplers[CouplerN].CoupleDist > 0)) - { - CF = 0; // kontrola zderzania sie - OK - ScanCounter++; - if ((newdist > MaxDist) || ((ScanCounter > MaxCount) && (newdist > MinDist))) - //if (tempdist>MaxDist) or ((ScanCounter>MaxCount)and(tempdist>MinDist)) then - { // zerwij kontrolnie wirtualny sprzeg - // Connected.Couplers[CNext].Connected:=nil; //Ra: ten podłączony niekoniecznie jest - // wirtualny -// Couplers[CouplerN].Connected = NULL; - ScanCounter = static_cast(Random(500.0)); // Q: TODO: cy dobrze przetlumaczone? - // WriteLog(FloatToStr(ScanCounter)); - } - } - else - { - if (Couplers[CouplerN].CouplingFlag == ctrain_virtual) - { + if( ( Couplers[ CouplerN ].CouplingFlag != coupling::faux ) + || ( Couplers[ CouplerN ].CoupleDist < 0 ) ) { + + if( Couplers[ CouplerN ].CouplingFlag == coupling::faux ) { + BetaAvg = Couplers[CouplerN].beta; Fmax = (Couplers[CouplerN].FmaxC + Couplers[CouplerN].FmaxB) * CouplerTune; } @@ -4145,18 +4141,20 @@ double TMoverParameters::CouplerForce(int CouplerN, double dt) //***if -tempdist>(DmaxB+Connected^.Couplers[CNext].DmaxB)/10 then {zderzenie} { Couplers[CouplerN].CheckCollision = true; - if ((Couplers[CouplerN].CouplerType == Automatic) && - (Couplers[CouplerN].CouplingFlag == - 0)) // sprzeganie wagonow z samoczynnymi sprzegami} + if( ( Couplers[ CouplerN ].CouplerType == Automatic ) + && ( Couplers[ CouplerN ].CouplingFlag == coupling::faux ) ) { + // sprzeganie wagonow z samoczynnymi sprzegami} // CouplingFlag:=ctrain_coupler+ctrain_pneumatic+ctrain_controll+ctrain_passenger+ctrain_scndpneumatic; - Couplers[CouplerN].CouplingFlag = - ctrain_coupler | ctrain_pneumatic | ctrain_controll; // EN57 + // EN57 + Couplers[ CouplerN ].CouplingFlag = coupling::coupler | coupling::brakehose | coupling::mainhose | coupling::control; + } } } } - if (Couplers[CouplerN].CouplingFlag != ctrain_virtual) + if( Couplers[ CouplerN ].CouplingFlag != coupling::faux ) { // uzgadnianie prawa Newtona - Couplers[CouplerN].Connected->Couplers[1 - CouplerN].CForce = -CF; + Couplers[ CouplerN ].Connected->Couplers[ 1 - CouplerN ].CForce = -CF; + } return CF; } diff --git a/Timer.cpp b/Timer.cpp index 1ddd600b..e78b50a7 100644 --- a/Timer.cpp +++ b/Timer.cpp @@ -66,9 +66,9 @@ void ResetTimers() }; LONGLONG fr, count, oldCount; -// LARGE_INTEGER fr,count; -void UpdateTimers(bool pause) -{ + +void UpdateTimers(bool pause) { + QueryPerformanceFrequency((LARGE_INTEGER *)&fr); QueryPerformanceCounter((LARGE_INTEGER *)&count); DeltaRenderTime = double(count - oldCount) / double(fr); @@ -78,18 +78,14 @@ void UpdateTimers(bool pause) fSoundTimer += DeltaTime; if (fSoundTimer > 0.1) fSoundTimer = 0.0; - /* - double CurrentTime= double(count)/double(fr);//GetTickCount(); - DeltaTime= (CurrentTime-OldTime); - OldTime= CurrentTime; - */ + if (DeltaTime > 1.0) DeltaTime = 1.0; } else DeltaTime = 0.0; // wszystko stoi, bo czas nie płynie - oldCount = count; + oldCount = count; // Keep track of the time lapse and frame count #if _WIN32_WINNT >= _WIN32_WINNT_VISTA double fTime = ::GetTickCount64() * 0.001f; // Get current time in seconds @@ -106,6 +102,7 @@ void UpdateTimers(bool pause) } fSimulationTime += DeltaTime; }; -}; + +}; // namespace timer //--------------------------------------------------------------------------- diff --git a/Track.cpp b/Track.cpp index 6814d710..ed464b22 100644 --- a/Track.cpp +++ b/Track.cpp @@ -2340,7 +2340,7 @@ void TTrack::ConnectionsLog() } }; -TTrack * TTrack::Neightbour(int s, double &d) +TTrack * TTrack::Connected(int s, double &d) const { // zwraca wskaźnik na sąsiedni tor, w kierunku określonym znakiem (s), odwraca (d) w razie // niezgodności kierunku torów TTrack *t; // nie zmieniamy kierunku (d), jeśli nie ma toru dalej diff --git a/Track.h b/Track.h index 323bfb69..91ea6138 100644 --- a/Track.h +++ b/Track.h @@ -205,7 +205,7 @@ public: return trNext; }; inline TTrack *CurrentPrev() const { return trPrev; }; - TTrack * Neightbour(int s, double &d); + TTrack *Connected(int s, double &d) const; bool SetConnections(int i); bool Switch(int i, double t = -1.0, double d = -1.0); bool SwitchForced(int i, TDynamicObject *o); diff --git a/Train.cpp b/Train.cpp index c6f54547..5cd946e8 100644 --- a/Train.cpp +++ b/Train.cpp @@ -1430,10 +1430,14 @@ void TTrain::OnCommand_pantographcompressorvalvetoggle( TTrain *Train, command_d if( Train->mvControlled->bPantKurek3 == false ) { // connect pantographs with primary tank Train->mvControlled->bPantKurek3 = true; + // visual feedback: + Train->ggPantCompressorValve.UpdateValue( 0.0 ); } else { // connect pantograps with pantograph compressor Train->mvControlled->bPantKurek3 = false; + // visual feedback: + Train->ggPantCompressorValve.UpdateValue( 1.0 ); } } } @@ -1456,10 +1460,14 @@ void TTrain::OnCommand_pantographcompressoractivate( TTrain *Train, command_data if( Command.action != GLFW_RELEASE ) { // press or hold to activate Train->mvControlled->PantCompFlag = true; + // visual feedback: + Train->ggPantCompressorButton.UpdateValue( 1.0 ); } else { // release to disable Train->mvControlled->PantCompFlag = false; + // visual feedback: + Train->ggPantCompressorButton.UpdateValue( 0.0 ); } } @@ -4627,35 +4635,38 @@ bool TTrain::Update( double const Deltatime ) ggBrakeCtrl.UpdateValue(mvOccupied->fBrakeCtrlPos); ggBrakeCtrl.Update(); } - if (ggLocalBrake.SubModel) - { - if (DynamicObject->Mechanik ? - (DynamicObject->Mechanik->AIControllFlag ? false : (Global::iFeedbackMode == 4 || (Global::bMWDmasterEnable && Global::bMWDBreakEnable))) : - false) // nie blokujemy AI - { // Ra: nie najlepsze miejsce, ale na początek gdzieś to dać trzeba - // Firleju: dlatego kasujemy i zastepujemy funkcją w Console - if ((mvOccupied->BrakeLocHandle == FD1)) - { - double b = Console::AnalogCalibrateGet(1); - b *= 10.0; - b = clamp( b, 0.0, LocalBrakePosNo); // przycięcie zmiennej do granic - ggLocalBrake.UpdateValue(b); // przesów bez zaokrąglenia - if (Global::bMWDdebugEnable && Global::iMWDDebugMode & 4) WriteLog("FD1 break position = " + to_string(b)); - mvOccupied->LocalBrakePos = - int(1.09 * b); // sposób zaokrąglania jest do ustalenia + + if( ggLocalBrake.SubModel ) { + + if( ( DynamicObject->Mechanik != nullptr ) + && ( false == DynamicObject->Mechanik->AIControllFlag ) // nie blokujemy AI + && ( mvOccupied->BrakeLocHandle == FD1 ) + && ( ( Global::iFeedbackMode == 4 ) + || ( Global::bMWDmasterEnable && Global::bMWDBreakEnable ) ) ) { + // Ra: nie najlepsze miejsce, ale na początek gdzieś to dać trzeba + // Firleju: dlatego kasujemy i zastepujemy funkcją w Console + auto const b = clamp( + Console::AnalogCalibrateGet( 1 ) * 10.0, + 0.0, + ManualBrakePosNo ); + ggLocalBrake.UpdateValue( b ); // przesów bez zaokrąglenia + mvOccupied->LocalBrakePos = int( 1.09 * b ); // sposób zaokrąglania jest do ustalenia + if( ( true == Global::bMWDdebugEnable ) + && ( ( Global::iMWDDebugMode & 4 ) != 0 ) ) { + WriteLog( "FD1 break position = " + to_string( b ) ); } - else // standardowa prodedura z kranem powiązanym z klawiaturą - ggLocalBrake.UpdateValue(double(mvOccupied->LocalBrakePos)); } - else // standardowa prodedura z kranem powiązanym z klawiaturą - ggLocalBrake.UpdateValue(double(mvOccupied->LocalBrakePos)); + else { + // standardowa prodedura z kranem powiązanym z klawiaturą + ggLocalBrake.UpdateValue( double( mvOccupied->LocalBrakePos ) ); + } ggLocalBrake.Update(); } - if (ggManualBrake.SubModel != NULL) - { + if (ggManualBrake.SubModel != nullptr) { ggManualBrake.UpdateValue(double(mvOccupied->ManualBrakePos)); ggManualBrake.Update(); } + ggAlarmChain.Update(); ggBrakeProfileCtrl.Update(); ggBrakeProfileG.Update(); ggBrakeProfileR.Update(); @@ -5629,6 +5640,8 @@ bool TTrain::Update( double const Deltatime ) ggPantRearButtonOff.Update(); ggPantSelectedDownButton.Update(); ggPantAllDownButton.Update(); + ggPantCompressorButton.Update(); + ggPantCompressorValve.Update(); ggUpperLightButton.Update(); ggLeftLightButton.Update(); @@ -6503,6 +6516,8 @@ void TTrain::clear_cab_controls() ggPantRearButtonOff.Clear(); ggPantSelectedDownButton.Clear(); ggPantAllDownButton.Clear(); + ggPantCompressorButton.Clear(); + ggPantCompressorValve.Clear(); ggZbS.Clear(); ggI1B.Clear(); ggI2B.Clear(); @@ -6649,6 +6664,15 @@ void TTrain::set_cab_controls() { 0.0 : 1.0 ) ); } + // auxiliary compressor + ggPantCompressorValve.PutValue( + mvControlled->bPantKurek3 ? + 0.0 : // default setting is pantographs connected with primary tank + 1.0 ); + ggPantCompressorButton.PutValue( + mvControlled->PantCompFlag ? + 1.0 : + 0.0 ); // converter if( mvOccupied->ConvSwitchType != "impulse" ) { ggConverterButton.PutValue( @@ -7067,6 +7091,8 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con { "pantalloff_sw:", ggPantAllDownButton }, { "pantselected_sw:", ggPantSelectedButton }, { "pantselectedoff_sw:", ggPantSelectedDownButton }, + { "pantcompressor_sw:", ggPantCompressorButton }, + { "pantcompressorvalve_sw:", ggPantCompressorValve }, { "trainheating_sw:", ggTrainHeatingButton }, { "signalling_sw:", ggSignallingButton }, { "door_signalling_sw:", ggDoorSignallingButton }, diff --git a/Train.h b/Train.h index 90a5ac6d..166f2cc1 100644 --- a/Train.h +++ b/Train.h @@ -299,6 +299,8 @@ public: // reszta może by?publiczna TGauge ggPantAllDownButton; TGauge ggPantSelectedButton; TGauge ggPantSelectedDownButton; + TGauge ggPantCompressorButton; + TGauge ggPantCompressorValve; // Winger 020304 - wlacznik ogrzewania TGauge ggTrainHeatingButton; TGauge ggSignallingButton; diff --git a/TrkFoll.cpp b/TrkFoll.cpp index c48ecac6..ceddcb1c 100644 --- a/TrkFoll.cpp +++ b/TrkFoll.cpp @@ -206,10 +206,10 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary) dir = fDirection; if (pCurrentTrack->eType == tt_Cross) { - if (!SetCurrentTrack(pCurrentTrack->Neightbour(iSegment, fDirection), 0)) + if (!SetCurrentTrack(pCurrentTrack->Connected(iSegment, fDirection), 0)) return false; // wyjście z błędem } - else if (!SetCurrentTrack(pCurrentTrack->Neightbour(-1, fDirection), + else if (!SetCurrentTrack(pCurrentTrack->Connected(-1, fDirection), 0)) // ustawia fDirection return false; // wyjście z błędem if (dir == fDirection) //(pCurrentTrack->iPrevDirection) @@ -243,10 +243,10 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary) dir = fDirection; if (pCurrentTrack->eType == tt_Cross) { - if (!SetCurrentTrack(pCurrentTrack->Neightbour(iSegment, fDirection), 1)) + if (!SetCurrentTrack(pCurrentTrack->Connected(iSegment, fDirection), 1)) return false; // wyjście z błędem } - else if (!SetCurrentTrack(pCurrentTrack->Neightbour(1, fDirection), + else if (!SetCurrentTrack(pCurrentTrack->Connected(1, fDirection), 1)) // ustawia fDirection return false; // wyjście z błędem if (dir != fDirection) //(pCurrentTrack->iNextDirection) diff --git a/version.h b/version.h index 998e22bf..49b29887 100644 --- a/version.h +++ b/version.h @@ -1,5 +1,5 @@ #pragma once #define VERSION_MAJOR 17 -#define VERSION_MINOR 905 +#define VERSION_MINOR 908 #define VERSION_REVISION 0 From 24221163cc33c05c2c15a284aa0da2a2944cd8f3 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Sat, 9 Sep 2017 17:33:21 +0200 Subject: [PATCH 2/3] maintenance: removed deprecated settings --- EU07.cpp | 61 +++++++++++++++++-------------------- Globals.cpp | 86 ----------------------------------------------------- Globals.h | 36 +--------------------- Ground.cpp | 3 ++ World.cpp | 85 ---------------------------------------------------- World.h | 1 - 6 files changed, 32 insertions(+), 240 deletions(-) diff --git a/EU07.cpp b/EU07.cpp index 78d26c69..5879c7e3 100644 --- a/EU07.cpp +++ b/EU07.cpp @@ -309,10 +309,7 @@ int main(int argc, char *argv[]) { std::string token(argv[i]); - if (token == "-modifytga") - Global::iModifyTGA = -1; - else if (token == "-e3d") - { + if (token == "-e3d") { if (Global::iConvertModels > 0) Global::iConvertModels = -Global::iConvertModels; else @@ -328,8 +325,12 @@ int main(int argc, char *argv[]) } else { - std::cout << "usage: " << std::string(argv[0]) << " [-s sceneryfilepath] " - << "[-v vehiclename] [-modifytga] [-e3d]" << std::endl; + std::cout + << "usage: " << std::string(argv[0]) + << " [-s sceneryfilepath]" + << " [-v vehiclename]" + << " [-e3d]" + << std::endl; return -1; } } @@ -438,37 +439,31 @@ int main(int argc, char *argv[]) if( !joyGetNumDevs() ) WriteLog( "No joystick" ); */ - if( Global::iModifyTGA < 0 ) { // tylko modyfikacja TGA, bez uruchamiania symulacji - Global::iMaxTextureSize = 64; //żeby nie zamulać pamięci - World.ModifyTGA(); // rekurencyjne przeglądanie katalogów - } - else { - if( Global::iConvertModels < 0 ) { - Global::iConvertModels = -Global::iConvertModels; - World.CreateE3D( "models\\" ); // rekurencyjne przeglądanie katalogów - World.CreateE3D( "dynamic\\", true ); - } // po zrobieniu E3D odpalamy normalnie scenerię, by ją zobaczyć + if( Global::iConvertModels < 0 ) { + Global::iConvertModels = -Global::iConvertModels; + World.CreateE3D( "models\\" ); // rekurencyjne przeglądanie katalogów + World.CreateE3D( "dynamic\\", true ); + } // po zrobieniu E3D odpalamy normalnie scenerię, by ją zobaczyć - Console::On(); // włączenie konsoli + Console::On(); // włączenie konsoli - try { - while( ( false == glfwWindowShouldClose( window ) ) - && ( true == World.Update() ) - && ( true == GfxRenderer.Render() ) ) { - glfwPollEvents(); - input::Keyboard.poll(); - if( true == Global::InputMouse ) { input::Mouse.poll(); } - if( true == Global::InputGamepad ) { input::Gamepad.poll(); } - } + try { + while( ( false == glfwWindowShouldClose( window ) ) + && ( true == World.Update() ) + && ( true == GfxRenderer.Render() ) ) { + glfwPollEvents(); + input::Keyboard.poll(); + if( true == Global::InputMouse ) { input::Mouse.poll(); } + if( true == Global::InputGamepad ) { input::Gamepad.poll(); } } - catch( std::bad_alloc const &Error ) { - - ErrorLog( "Critical error, memory allocation failure: " + std::string( Error.what() ) ); - return -1; - } - - Console::Off(); // wyłączenie konsoli (komunikacji zwrotnej) } + catch( std::bad_alloc const &Error ) { + + ErrorLog( "Critical error, memory allocation failure: " + std::string( Error.what() ) ); + return -1; + } + + Console::Off(); // wyłączenie konsoli (komunikacji zwrotnej) TPythonInterpreter::killInstance(); delete pConsole; diff --git a/Globals.cpp b/Globals.cpp index 780b5697..67a39d47 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -55,11 +55,8 @@ double Global::fTimeAngleDeg = 0.0; // godzina w postaci kąta float Global::fClockAngleDeg[6]; // kąty obrotu cylindrów dla zegara cyfrowego std::string Global::szTexturesTGA = ".tga"; // lista tekstur od TGA std::string Global::szTexturesDDS = ".dds"; // lista tekstur od DDS -int Global::iKeyLast = 0; // ostatnio naciśnięty klawisz w celu logowania int Global::iPause = 0; // 0x10; // globalna pauza ruchu bool Global::bActive = true; // czy jest aktywnym oknem -int Global::iErorrCounter = 0; // licznik sprawdzań do śledzenia błędów OpenGL -int Global::iTextures = 0; // licznik użytych tekstur TWorld *Global::pWorld = NULL; cParser *Global::pParser = NULL; TCamera *Global::pCamera = NULL; // parametry kamery @@ -74,8 +71,6 @@ double Global::pCameraRotation; double Global::pCameraRotationDeg; std::vector Global::FreeCameraInit; std::vector Global::FreeCameraInitAngle; -float Global::Background[3] = {0.2f, 0.4f, 0.33f}; -GLfloat Global::AtmoColor[] = {0.423f, 0.702f, 1.0f}; GLfloat Global::FogColor[] = {0.6f, 0.7f, 0.8f}; double Global::fFogStart = 1700; double Global::fFogEnd = 2000; @@ -122,10 +117,6 @@ bool Global::bEnableTraction = true; bool Global::bLoadTraction = true; bool Global::bLiveTraction = true; float Global::AnisotropicFiltering = 8.0f; // requested level of anisotropic filtering. TODO: move it to renderer object -int Global::iDefaultFiltering = 9; // domyślne rozmywanie tekstur TGA bez alfa -int Global::iBallastFiltering = 9; // domyślne rozmywanie tekstur podsypki -int Global::iRailProFiltering = 5; // domyślne rozmywanie tekstur szyn -int Global::iDynamicFiltering = 5; // domyślne rozmywanie tekstur pojazdów bool Global::bUseVBO = true; // czy jest VBO w karcie graficznej (czy użyć) std::string Global::LastGLError; GLint Global::iMaxTextureSize = 4096; // maksymalny rozmiar tekstury @@ -138,7 +129,6 @@ bool Global::bGlutFont = false; // czy tekst generowany przez GLUT32.DLL //int Global::iConvertModels = 7; // tworzenie plików binarnych, +2-optymalizacja transformów int Global::iConvertModels{ 0 }; // temporary override, to prevent generation of .e3d not compatible with old exe int Global::iSlowMotionMask = -1; // maska wyłączanych właściwości dla zwiększenia FPS -int Global::iModifyTGA = 7; // czy korygować pliki TGA dla szybszego wczytywania // bool Global::bTerrainCompact=true; //czy zapisać teren w pliku TAnimModel *Global::pTerrainCompact = NULL; // do zapisania terenu w pliku std::string Global::asTerrainModel = ""; // nazwa obiektu terenu do zapisania w pliku @@ -146,17 +136,12 @@ double Global::fFpsAverage = 20.0; // oczekiwana wartosć FPS double Global::fFpsDeviation = 5.0; // odchylenie standardowe FPS double Global::fFpsMin = 30.0; // dolna granica FPS, przy której promień scenerii będzie zmniejszany double Global::fFpsMax = 65.0; // górna granica FPS, przy której promień scenerii będzie zwiększany -double Global::fFpsRadiusMax = 3000.0; // maksymalny promień renderowania -int Global::iFpsRadiusMax = 225; // maksymalny promień renderowania -double Global::fRadiusFactor = 1.1; // współczynnik jednorazowej zmiany promienia scenerii // parametry testowe (do testowania scenerii i obiektów) bool Global::bWireFrame = false; bool Global::bSoundEnabled = true; int Global::iWriteLogEnabled = 3; // maska bitowa: 1-zapis do pliku, 2-okienko, 4-nazwy torów bool Global::MultipleLogs{ false }; -bool Global::bManageNodes = true; -bool Global::bDecompressDDS = false; // czy programowa dekompresja DDS // parametry do kalibracji // kolejno współczynniki dla potęg 0, 1, 2, 3 wartości odczytanej z urządzenia @@ -180,10 +165,8 @@ int Global::iPoKeysPWM[7] = {0, 1, 2, 3, 4, 5, 6}; // bool Global::bTimeChange=false; //Ra: ZiomalCl wyłączył starą wersję nocy // bool Global::bRenderAlpha=true; //Ra: wywaliłam tę flagę bool Global::bnewAirCouplers = true; -bool Global::bDoubleAmbient = false; // podwójna jasność ambient double Global::fTimeSpeed = 1.0; // przyspieszenie czasu, zmienna do testów bool Global::bHideConsole = false; // hunter-271211: ukrywanie konsoli -int Global::iBpp = 32; // chyba już nie używa się kart, na których 16bpp coś poprawi //randomizacja std::mt19937 Global::random_engine = std::mt19937(std::time(NULL)); // maciek001: konfiguracja wstępna portu COM @@ -276,13 +259,6 @@ void Global::ConfigParse(cParser &Parser) Parser.getTokens(1, false); Parser >> Global::fDistanceFactor; } - else if (token == "bpp") - { - - Parser.getTokens(); - Parser >> token; - Global::iBpp = (token == "32" ? 32 : 16); - } else if (token == "fullscreen") { @@ -409,18 +385,6 @@ void Global::ConfigParse(cParser &Parser) Parser >> token; Global::asSky = (token == "yes" ? "1" : "0"); } - else if (token == "managenodes") - { - - Parser.getTokens(); - Parser >> Global::bManageNodes; - } - else if (token == "decompressdds") - { - - Parser.getTokens(); - Parser >> Global::bDecompressDDS; - } else if (token == "defaultext") { // ShaXbee - domyslne rozszerzenie tekstur @@ -444,30 +408,6 @@ void Global::ConfigParse(cParser &Parser) Parser.getTokens(); Parser >> Global::bnewAirCouplers; } - else if (token == "defaultfiltering") - { - - Parser.getTokens(1, false); - Parser >> Global::iDefaultFiltering; - } - else if (token == "ballastfiltering") - { - - Parser.getTokens(1, false); - Parser >> Global::iBallastFiltering; - } - else if (token == "railprofiltering") - { - - Parser.getTokens(1, false); - Parser >> Global::iRailProFiltering; - } - else if (token == "dynamicfiltering") - { - - Parser.getTokens(1, false); - Parser >> Global::iDynamicFiltering; - } else if( token == "anisotropicfiltering" ) { Parser.getTokens( 1, false ); @@ -513,12 +453,6 @@ void Global::ConfigParse(cParser &Parser) else if (size <= 8192) { Global::iMaxTextureSize = 8192; } else { Global::iMaxTextureSize = 16384; } } - else if (token == "doubleambient") - { - // podwójna jasność ambient - Parser.getTokens(); - Parser >> Global::bDoubleAmbient; - } else if (token == "movelight") { // numer dnia w roku albo -1 @@ -624,12 +558,6 @@ void Global::ConfigParse(cParser &Parser) Parser.getTokens(1, false); Parser >> Global::iSlowMotionMask; } - else if (token == "modifytga") - { - // czy korygować pliki TGA dla szybszego wczytywania - Parser.getTokens(1, false); - Parser >> Global::iModifyTGA; - } else if (token == "hideconsole") { // hunter-271211: ukrywanie konsoli @@ -654,12 +582,6 @@ void Global::ConfigParse(cParser &Parser) Parser.getTokens(1, false); Parser >> Global::fFpsDeviation; } - else if (token == "fpsradiusmax") - { - // maksymalny promień renderowania - Parser.getTokens(1, false); - Parser >> Global::fFpsRadiusMax; - } else if (token == "calibratein") { // parametry kalibracji wejść @@ -807,14 +729,6 @@ void Global::ConfigParse(cParser &Parser) Parser >> token; TPythonInterpreter::getInstance()->setScreenRendererPriority(token.c_str()); } - else if (token == "background") - { - - Parser.getTokens(3, false); - Parser >> Global::Background[0] // r - >> Global::Background[1] // g - >> Global::Background[2]; // b - } else if( token == "input.gamepad" ) { // czy grupować eventy o tych samych nazwach Parser.getTokens(); diff --git a/Globals.h b/Globals.h index 37fefd65..df62bc17 100644 --- a/Globals.h +++ b/Globals.h @@ -130,25 +130,13 @@ class TTranscript float fHide; // czas ukrycia/usunięcia std::string asText; // tekst gotowy do wyświetlenia (usunięte znaczniki czasu) bool bItalic; // czy kursywa (dźwięk nieistotny dla prowadzącego) -/* - int iNext; // następna używana linijka, żeby nie przestawiać fizycznie tabeli -*/ }; -/* -#define MAX_TRANSCRIPTS 30 -*/ class TTranscripts { // klasa obsługująca napisy do dźwięków -/* - TTranscript aLines[MAX_TRANSCRIPTS]; // pozycje na napisy do wyświetlenia -*/ public: std::deque aLines; -/* - int iCount; // liczba zajętych pozycji - int iStart; // pierwsza istotna pozycja w tabeli, żeby sortować przestawiając numerki -*/ + private: float fRefreshTime; @@ -166,7 +154,6 @@ class Global { private: public: - // double Global::tSinceStart; static int Keys[MaxKeys]; static bool RealisticControlMode; // controls ability to steer the vehicle from outside views static Math3D::vector3 pCameraPosition; // pozycja kamery w świecie @@ -179,23 +166,17 @@ class Global static int iWindowWidth; static int iWindowHeight; static float fDistanceFactor; - static int iBpp; static bool bFullScreen; static bool VSync; static bool bFreeFly; - // float RunningTime; static bool bWireFrame; static bool bSoundEnabled; // McZapkie-131202 - // static bool bRenderAlpha; static bool bAdjustScreenFreq; static bool bEnableTraction; static bool bLoadTraction; static float fFriction; static bool bLiveTraction; - static bool bManageNodes; - static bool bDecompressDDS; - // bool WFreeFly; static float Global::fMouseXScale; static float Global::fMouseYScale; static double fFogStart; @@ -217,11 +198,8 @@ class Global static int iWriteLogEnabled; // maska bitowa: 1-zapis do pliku, 2-okienko static bool MultipleLogs; // McZapkie-221002: definicja swiatla dziennego - static float Background[3]; - static GLfloat AtmoColor[]; static GLfloat FogColor[]; static float Overcast; - // static bool bTimeChange; // TODO: put these things in the renderer static float BaseDrawRange; @@ -244,10 +222,6 @@ class Global static bool bnewAirCouplers; // Ra: nowe zmienne globalne static float AnisotropicFiltering; // requested level of anisotropic filtering. TODO: move it to renderer object - static int iDefaultFiltering; // domyślne rozmywanie tekstur TGA - static int iBallastFiltering; // domyślne rozmywanie tekstury podsypki - static int iRailProFiltering; // domyślne rozmywanie tekstury szyn - static int iDynamicFiltering; // domyślne rozmywanie tekstur pojazdów static bool bUseVBO; // czy jest VBO w karcie graficznej static std::string LastGLError; static int iFeedbackMode; // tryb pracy informacji zwrotnej @@ -270,7 +244,6 @@ class Global static bool InputMouse; // whether control pick mode can be activated static int iTextMode; // tryb pracy wyświetlacza tekstowego static int iScreenMode[12]; // numer ekranu wyświetlacza tekstowego - static bool bDoubleAmbient; // podwójna jasność ambient static double fMoveLight; // numer dnia w roku albo -1 static bool FakeLight; // toggle between fixed and dynamic daylight static bool bSmoothTraction; // wygładzanie drutów @@ -284,15 +257,11 @@ class Global static int iMultisampling; // tryb antyaliasingu: 0=brak,1=2px,2=4px,3=8px,4=16px static bool DLFont; // switch indicating presence of basic font static bool bGlutFont; // tekst generowany przez GLUT - static int iKeyLast; // ostatnio naciśnięty klawisz w celu logowania static int iPause; // globalna pauza ruchu: b0=start,b1=klawisz,b2=tło,b3=lagi,b4=wczytywanie static bool bActive; // czy jest aktywnym oknem static int iConvertModels; // tworzenie plików binarnych - static int iErorrCounter; // licznik sprawdzań do śledzenia błędów OpenGL static bool bInactivePause; // automatyczna pauza, gdy okno nieaktywne - static int iTextures; // licznik użytych tekstur static int iSlowMotionMask; // maska wyłączanych właściwości - static int iModifyTGA; // czy korygować pliki TGA dla szybszego wczytywania static bool bHideConsole; // hunter-271211: ukrywanie konsoli static TWorld *pWorld; // wskaźnik na świat do usuwania pojazdów @@ -304,9 +273,6 @@ class Global static double fFpsDeviation; // odchylenie standardowe FPS static double fFpsMin; // dolna granica FPS, przy której promień scenerii będzie zmniejszany static double fFpsMax; // górna granica FPS, przy której promień scenerii będzie zwiększany - static double fFpsRadiusMax; // maksymalny promień renderowania - static int iFpsRadiusMax; // maksymalny promień renderowania w rozmiarze tabeli sektorów - static double fRadiusFactor; // współczynnik zmiany promienia static TCamera *pCamera; // parametry kamery static TDynamicObject *pUserDynamic; // pojazd użytkownika, renderowany bez trzęsienia static double fCalibrateIn[6][6]; // parametry kalibracyjne wejść z pulpitu diff --git a/Ground.cpp b/Ground.cpp index 482ced09..cf0d9dbb 100644 --- a/Ground.cpp +++ b/Ground.cpp @@ -2022,10 +2022,13 @@ bool TGround::Init(std::string File) { // Ra: ustawienie parametrów OpenGL przeniesione do FirstInit WriteLog("Scenery atmo definition"); parser.getTokens(3); +/* + // disabled, no longer used parser >> Global::AtmoColor[0] >> Global::AtmoColor[1] >> Global::AtmoColor[2]; +*/ parser.getTokens(2); parser >> Global::fFogStart diff --git a/World.cpp b/World.cpp index e573e275..ca7e97be 100644 --- a/World.cpp +++ b/World.cpp @@ -183,14 +183,10 @@ simulation_time::julian_day() const { TWorld::TWorld() { - // randomize(); - // Randomize(); Train = NULL; - // Aspect=1; for (int i = 0; i < 10; ++i) KeyEvents[i] = NULL; // eventy wyzwalane klawiszami cyfrowymi Global::iSlowMotion = 0; - // Global::changeDynObj=NULL; pDynamicNearest = NULL; fTimeBuffer = 0.0; // bufor czasu aktualizacji dla stałego kroku fizyki fMaxDt = 0.01; //[s] początkowy krok czasowy fizyki @@ -199,7 +195,6 @@ TWorld::TWorld() TWorld::~TWorld() { - Global::bManageNodes = false; // Ra: wyłączenie wyrejestrowania, bo się sypie TrainDelete(); // Ground.Free(); //Ra: usunięcie obiektów przed usunięciem dźwięków - sypie się TSoundsManager::Free(); @@ -218,61 +213,6 @@ void TWorld::TrainDelete(TDynamicObject *d) Global::pUserDynamic = NULL; // tego też nie ma }; -/* Ra: do opracowania: wybor karty graficznej ~Intel gdy są dwie... -BOOL GetDisplayMonitorInfo(int nDeviceIndex, LPSTR lpszMonitorInfo) -{ - FARPROC EnumDisplayDevices; - HINSTANCE hInstUser32; - DISPLAY_DEVICE DispDev; - char szSaveDeviceName[33]; // 32 + 1 for the null-terminator - BOOL bRet = TRUE; - HRESULT hr; - - hInstUser32 = LoadLibrary("c:\\windows\User32.DLL"); - if (!hInstUser32) return FALSE; - - // Get the address of the EnumDisplayDevices function - EnumDisplayDevices = (FARPROC)GetProcAddress(hInstUser32,"EnumDisplayDevicesA"); - if (!EnumDisplayDevices) { - FreeLibrary(hInstUser32); - return FALSE; - } - - ZeroMemory(&DispDev, sizeof(DispDev)); - DispDev.cb = sizeof(DispDev); - - // After the first call to EnumDisplayDevices, - // DispDev.DeviceString is the adapter name - if (EnumDisplayDevices(NULL, nDeviceIndex, &DispDev, 0)) - { - hr = StringCchCopy(szSaveDeviceName, 33, DispDev.DeviceName); - if (FAILED(hr)) - { - // TODO: write error handler - } - - // After second call, DispDev.DeviceString is the - // monitor name for that device - EnumDisplayDevices(szSaveDeviceName, 0, &DispDev, 0); - - // In the following, lpszMonitorInfo must be 128 + 1 for - // the null-terminator. - hr = StringCchCopy(lpszMonitorInfo, 129, DispDev.DeviceString); - if (FAILED(hr)) - { - // TODO: write error handler - } - - } else { - bRet = FALSE; - } - - FreeLibrary(hInstUser32); - - return bRet; -} -*/ - bool TWorld::Init( GLFWwindow *Window ) { auto timestart = std::chrono::system_clock::now(); @@ -822,11 +762,6 @@ void TWorld::OnKeyDown(int cKey) } } } - // switch (cKey) - //{case 'a': //ignorowanie repetycji - // case 'A': Global::iKeyLast=cKey; break; - // default: Global::iKeyLast=0; - //} } void TWorld::OnMouseMove(double x, double y) @@ -2020,26 +1955,6 @@ void TWorld::OnCommandGet(DaneRozkaz *pRozkaz) } }; -//--------------------------------------------------------------------------- -void TWorld::ModifyTGA(const std::string &dir) -{ // rekurencyjna modyfikacje plików TGA -/* TODO: implement version without Borland stuff - TSearchRec sr; - if (FindFirst(dir + "*.*", faDirectory | faArchive, sr) == 0) - { - do - { - if (sr.Name[1] != '.') - if ((sr.Attr & faDirectory)) // jeśli katalog, to rekurencja - ModifyTGA(dir + sr.Name + "/"); - else if (sr.Name.LowerCase().SubString(sr.Name.Length() - 3, 4) == ".tga") - TTexturesManager::GetTextureID(NULL, NULL, AnsiString(dir + sr.Name).c_str()); - } while (FindNext(sr) == 0); - FindClose(sr); - } -*/ -}; - //--------------------------------------------------------------------------- void TWorld::CreateE3D(std::string const &Path, bool Dynamic) diff --git a/World.h b/World.h index 54517e7c..ac97a1dd 100644 --- a/World.h +++ b/World.h @@ -140,7 +140,6 @@ private: bool m_init{ false }; // indicates whether initial update of the world was performed public: - void ModifyTGA(std::string const &dir = ""); void CreateE3D(std::string const &dir = "", bool dyn = false); void CabChange(TDynamicObject *old, TDynamicObject *now); // handles vehicle change flag From d75c9ff14d62ce5606cf996719312981d62528df Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Tue, 12 Sep 2017 04:30:51 +0200 Subject: [PATCH 3/3] build 170911. right mouse view panning during mouse picking in external view, signal distance calculation fix, AI car braking improvements, cab camera position retains position between view swaps, physics calculations mode switch, consist brake status report in whois event --- Camera.cpp | 4 -- Camera.h | 9 +-- Driver.cpp | 101 ++++++++++++++++---------- Driver.h | 18 ++--- DynObj.cpp | 34 ++++----- Globals.cpp | 5 +- Globals.h | 17 ++--- Ground.cpp | 60 ++++++++++++---- McZapkie/MOVER.h | 2 - McZapkie/Mover.cpp | 25 ++++--- McZapkie/mctools.cpp | 1 + McZapkie/mctools.h | 1 + Train.cpp | 7 +- Train.h | 1 - World.cpp | 23 ++++-- mouseinput.cpp | 164 +++++++++++++++++++++++-------------------- renderer.cpp | 42 ++++++++--- renderer.h | 2 +- version.h | 2 +- 19 files changed, 300 insertions(+), 218 deletions(-) diff --git a/Camera.cpp b/Camera.cpp index 0c7c21ca..ef589bc5 100644 --- a/Camera.cpp +++ b/Camera.cpp @@ -25,17 +25,13 @@ void TCamera::Init(vector3 NPos, vector3 NAngle) { vUp = vector3(0, 1, 0); - // pOffset= vector3(-0.8,0,0); - CrossDist = 10; Velocity = vector3(0, 0, 0); Pitch = NAngle.x; Yaw = NAngle.y; Roll = NAngle.z; Pos = NPos; - // Type= tp_Follow; Type = (Global::bFreeFly ? tp_Free : tp_Follow); - // Type= tp_Free; }; void TCamera::OnCursorMove(double x, double y) diff --git a/Camera.h b/Camera.h index a6346f52..09135908 100644 --- a/Camera.h +++ b/Camera.h @@ -46,13 +46,10 @@ class TCamera vector3 LookAt; // współrzędne punktu, na który ma patrzeć vector3 vUp; vector3 Velocity; - vector3 CrossPos; - double CrossDist; void Init(vector3 NPos, vector3 NAngle); - void Reset() - { - Pitch = Yaw = Roll = 0; - }; + inline + void Reset() { + Pitch = Yaw = Roll = 0; }; void OnCursorMove(double const x, double const y); void OnCommand( command_data const &Command ); void Update(); diff --git a/Driver.cpp b/Driver.cpp index a0e2a58f..bf99e184 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -64,12 +64,12 @@ double GetDistanceToEvent(TTrack const *track, TEvent const *event, double scan_ seg_len += scan_dir > 0 ? dzielnik : -dzielnik; len2 = (pos_event - segment->FastGetPoint(seg_len)).LengthSquared(); ++krok; - } while ((len1 > len2) && (seg_len >= dzielnik && (seg_len <= (1 - dzielnik)))); + } while ((len1 > len2) && (seg_len >= dzielnik && (seg_len <= (1.0 - dzielnik)))); //trzeba sprawdzić czy seg_len nie osiągnął skrajnych wartości, bo wtedy // trzeba sprawdzić tor obok if (1 == krok) sd = -sd; // jeśli tylko jeden krok tzn, że event przy poprzednim sprawdzaym torze - if (((seg_len <= dzielnik) || (seg_len > (1 - dzielnik))) && (iter < 3)) + if (((1 == krok) || (seg_len <= dzielnik) || (seg_len > (1.0 - dzielnik))) && (iter < 3)) { // przejście na inny tor track = track->Connected(int(sd), sd); start_dist += (1 == krok) ? 0 : back ? -segment->GetLength() : segment->GetLength(); @@ -3919,6 +3919,13 @@ TController::UpdateSituation(double dt) { fStopTime = 0.0; // nie ma na co czekać z odczepianiem } } + else { + if( mvOccupied->Vel > 0.0 ) { + // 1st phase(?) + // bring it to stop if it's not already stopped + SetVelocity( 0, 0, stopJoin ); // wyłączyć przyspieszanie + } + } } // odczepiania else // to poniżej jeśli ilość wagonów ujemna if (iDrivigFlags & movePress) @@ -3985,8 +3992,8 @@ TController::UpdateSituation(double dt) { } else { // samochod (sokista też) - fMinProximityDist = std::max( 4.0, mvOccupied->Vel * 0.2 ); - fMaxProximityDist = std::max( 8.0, mvOccupied->Vel * 0.375 ); //[m] + fMinProximityDist = std::max( 3.0, mvOccupied->Vel * 0.2 ); + fMaxProximityDist = std::max( 9.0, mvOccupied->Vel * 0.375 ); //[m] // margines prędkości powodujący załączenie napędu fVelMinus = 2.0; // dopuszczalne przekroczenie prędkości na ograniczeniu bez hamowania @@ -4259,12 +4266,17 @@ TController::UpdateSituation(double dt) { && ( coupler->CouplingFlag == coupling::faux ) ) { // mamy coś z przodu podłączone sprzęgiem wirtualnym // wyliczanie optymalnego przyspieszenia do jazdy na widoczność +/* ActualProximityDist = std::min( ActualProximityDist, vehicle->fTrackBlock - ( mvOccupied->CategoryFlag & 2 ? fMinProximityDist : // cars can bunch up tighter fMaxProximityDist ) ); // other vehicle types less so +*/ + ActualProximityDist = std::min( + ActualProximityDist, + vehicle->fTrackBlock ); double k = coupler->Connected->Vel; // prędkość pojazdu z przodu (zakładając, // że jedzie w tę samą stronę!!!) if( k < vel + 10 ) { @@ -4323,36 +4335,47 @@ TController::UpdateSituation(double dt) { } // sprawdzamy możliwe ograniczenia prędkości - if (OrderCurrentGet() & (Shunt | Obey_train)) // w Connect nie, bo moveStopHere - // odnosi się do stanu po połączeniu - if (iDrivigFlags & moveStopHere) // jeśli ma czekać na wolną drogę - if (vel == 0.0) // a stoi - if (VelNext == 0.0) // a wyjazdu nie ma - VelDesired = 0.0; // to ma stać - if (fStopTime < 0) // czas postoju przed dalszą jazdą (np. na przystanku) + if( OrderCurrentGet() & ( Shunt | Obey_train ) ) { + // w Connect nie, bo moveStopHere odnosi się do stanu po połączeniu + if( ( iDrivigFlags & moveStopHere ) + && ( vel == 0.0 ) + && ( VelNext == 0.0 ) ) { + // jeśli ma czekać na wolną drogę, stoi a wyjazdu nie ma, to ma stać + VelDesired = 0.0; + } + } + if( fStopTime < 0 ) { + // czas postoju przed dalszą jazdą (np. na przystanku) VelDesired = 0.0; // jak ma czekać, to nie ma jazdy - // else if (VelSignal<0) - // VelDesired=fVelMax; //ile fabryka dala (Ra: uwzględione wagony) - else if (VelSignal >= 0) // jeśli skład był zatrzymany na początku i teraz już może jechać - VelDesired = Global::Min0RSpeed(VelDesired, VelSignal); - - if (mvOccupied->RunningTrack.Velmax >= - 0) // ograniczenie prędkości z trajektorii ruchu + } + else if( VelSignal >= 0 ) { + // jeśli skład był zatrzymany na początku i teraz już może jechać VelDesired = - Global::Min0RSpeed(VelDesired, - mvOccupied->RunningTrack.Velmax); // uwaga na ograniczenia szlakowej! - if (VelforDriver >= 0) // tu jest zero przy zmianie kierunku jazdy - VelDesired = Global::Min0RSpeed(VelDesired, VelforDriver); // Ra: tu może być 40, jeśli - // mechanik nie ma znajomości - // szlaaku, albo kierowca jeździ - // 70 - if (TrainParams) - if (TrainParams->CheckTrainLatency() < 5.0) - if (TrainParams->TTVmax > 0.0) - VelDesired = Global::Min0RSpeed( - VelDesired, - TrainParams - ->TTVmax); // jesli nie spozniony to nie przekraczać rozkladowej + Global::Min0RSpeed( + VelDesired, + VelSignal ); + } + if( mvOccupied->RunningTrack.Velmax >= 0 ) { + // ograniczenie prędkości z trajektorii ruchu + VelDesired = + Global::Min0RSpeed( + VelDesired, + mvOccupied->RunningTrack.Velmax ); // uwaga na ograniczenia szlakowej! + } + if( VelforDriver >= 0 ) { + // tu jest zero przy zmianie kierunku jazdy + // Ra: tu może być 40, jeśli mechanik nie ma znajomości szlaaku, albo kierowca jeździ 70 + VelDesired = Global::Min0RSpeed( VelDesired, VelforDriver ); + } + if( ( TrainParams != nullptr ) + && ( TrainParams->CheckTrainLatency() < 5.0 ) + && ( TrainParams->TTVmax > 0.0 ) ) { + // jesli nie spozniony to nie przekraczać rozkladowej + VelDesired = + Global::Min0RSpeed( + VelDesired, + TrainParams->TTVmax ); + } if (VelDesired > 0.0) if( ( ( iDrivigFlags & moveStopHere ) == 0 ) || ( ( SemNextIndex != -1 ) @@ -4448,10 +4471,16 @@ TController::UpdateSituation(double dt) { VelDesired = Global::Min0RSpeed( VelDesired, VelNext ); */ if( VelNext == 0.0 ) { - // hamowanie tak, aby stanąć - VelDesired = VelNext; - AccDesired = ( VelNext * VelNext - vel * vel ) / ( 25.92 * ( ActualProximityDist + 0.1 - 0.5*fMinProximityDist ) ); - AccDesired = std::min( AccDesired, fAccThreshold ); + if( mvOccupied->CategoryFlag & 1 ) { + // hamowanie tak, aby stanąć + VelDesired = VelNext; + AccDesired = ( VelNext * VelNext - vel * vel ) / ( 25.92 * ( ActualProximityDist + 0.1 - 0.5*fMinProximityDist ) ); + AccDesired = std::min( AccDesired, fAccThreshold ); + } + else { + // for cars (and others) coast at low speed until we hit min proximity range + VelDesired = Global::Min0RSpeed( VelDesired, 5.0 ); + } } } else { diff --git a/Driver.h b/Driver.h index 1d6e410e..12c91d2a 100644 --- a/Driver.h +++ b/Driver.h @@ -212,13 +212,12 @@ private: // parametry aktualnego składu double AbsAccS_pub = 0.0; // próg opóźnienia dla zadziałania hamulca double fBrake_a0[BrakeAccTableSize+1] = { 0.0 }; // próg opóźnienia dla zadziałania hamulca double fBrake_a1[BrakeAccTableSize+1] = { 0.0 }; // próg opóźnienia dla zadziałania hamulca - public: double fLastStopExpDist = -1.0; // odległość wygasania ostateniego przystanku double ReactionTime = 0.0; // czas reakcji Ra: czego i na co? świadomości AI double fBrakeTime = 0.0; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca - private: double fReady = 0.0; // poziom odhamowania wagonów bool Ready = false; // ABu: stan gotowosci do odjazdu - sprawdzenie odhamowania wagonow +private: double LastUpdatedTime = 0.0; // czas od ostatniego logu double ElapsedTime = 0.0; // czas od poczatku logu double deltalog = 0.05; // przyrost czasu @@ -227,26 +226,21 @@ private: // parametry aktualnego składu double m_radiocontroltime{ 0.0 }; // timer used to control speed of radio operations TAction eAction = actSleep; // aktualny stan public: - inline TAction GetAction() - { - return eAction; - } + inline + TAction GetAction() { + return eAction; } bool AIControllFlag = false; // rzeczywisty/wirtualny maszynista int iRouteWanted = 3; // oczekiwany kierunek jazdy (0-stop,1-lewo,2-prawo,3-prosto) np. odpala // migacz lub czeka na stan zwrotnicy private: TDynamicObject *pVehicle = nullptr; // pojazd w którym siedzi sterujący - TDynamicObject - *pVehicles[2]; // skrajne pojazdy w składzie (niekoniecznie bezpośrednio sterowane) + TDynamicObject *pVehicles[2]; // skrajne pojazdy w składzie (niekoniecznie bezpośrednio sterowane) TMoverParameters *mvControlling = nullptr; // jakim pojazdem steruje (może silnikowym w EZT) TMoverParameters *mvOccupied = nullptr; // jakim pojazdem hamuje TTrainParameters *TrainParams = nullptr; // rozkład jazdy zawsze jest, nawet jeśli pusty - // int TrainNumber; //numer rozkladowy tego pociagu - // AnsiString OrderCommand; //komenda pobierana z pojazdu - // double OrderValue; //argument komendy int iRadioChannel = 1; // numer aktualnego kanału radiowego - TTextSound *tsGuardSignal = nullptr; // komunikat od kierownika int iGuardRadio = 0; // numer kanału radiowego kierownika (0, gdy nie używa radia) + TTextSound *tsGuardSignal = nullptr; // komunikat od kierownika public: double AccPreferred = 0.0; // preferowane przyspieszenie (wg psychiki kierującego, zmniejszana przy wykryciu kolizji) double AccDesired = AccPreferred; // przyspieszenie, jakie ma utrzymywać (<0:nie przyspieszaj,<-0.1:hamuj) diff --git a/DynObj.cpp b/DynObj.cpp index 68c8adb0..13c65909 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -1331,15 +1331,7 @@ void TDynamicObject::ABuScanObjects( int Direction, double Distance ) // pojazdu // ScanDir=1 - od strony Coupler0, ScanDir=-1 - od strony Coupler1 auto const initialdirection = Direction; // zapamiętanie kierunku poszukiwań na torze początkowym, względem sprzęgów -/* - TTrackFollower const *firstaxle = (initialdirection > 0 ? &Axle0 : &Axle1); // można by to trzymać w trainset - TTrack const *track = firstaxle->GetTrack(); // tor na którym "stoi" skrajny wózek - // (może być inny niż tor pojazdu) - if( firstaxle->GetDirection() < 0 ) { - // czy oś jest ustawiona w stronę Point1? - Direction = -Direction; // jeśli tak, to kierunek szukania będzie przeciwny - } -*/ + TTrack const *track = RaTrackGet(); if( RaDirectionGet() < 0 ) { // czy oś jest ustawiona w stronę Point1? @@ -1458,18 +1450,18 @@ void TDynamicObject::ABuScanObjects( int Direction, double Distance ) } } - // odległość do najbliższego pojazdu w linii prostej - // Ra: jeśli dwa samochody się mijają na odcinku przed zawrotką, to odległość między nimi nie może być liczona w linii prostej! - fTrackBlock = MoverParameters->Couplers[mycoupler].CoupleDist; - if( track->iCategoryFlag & 254 ) { - // jeśli samochód - if( distance > MoverParameters->Dim.L + foundobject->MoverParameters->Dim.L ) { - // przeskanowana odległość większa od długości pojazdów - // else if (ActDistCouplers[ mycoupler ].CoupleDist ); + } + if( ( false == TestFlag( track->iCategoryFlag, 1 ) ) + && ( distance > 50.0 ) ) { + // Ra: jeśli dwa samochody się mijają na odcinku przed zawrotką, to odległość między nimi nie może być liczona w linii prostej! + // NOTE: the distance is approximated, and additionally less accurate for cars heading in opposite direction + fTrackBlock = distance - ( 0.5 * ( MoverParameters->Dim.L + foundobject->MoverParameters->Dim.L ) ); } } else { diff --git a/Globals.cpp b/Globals.cpp index 67a39d47..5702dc55 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -136,6 +136,7 @@ double Global::fFpsAverage = 20.0; // oczekiwana wartosć FPS double Global::fFpsDeviation = 5.0; // odchylenie standardowe FPS double Global::fFpsMin = 30.0; // dolna granica FPS, przy której promień scenerii będzie zmniejszany double Global::fFpsMax = 65.0; // górna granica FPS, przy której promień scenerii będzie zwiększany +bool Global::FullPhysics { true }; // full calculations performed for each simulation step // parametry testowe (do testowania scenerii i obiektów) bool Global::bWireFrame = false; @@ -308,11 +309,11 @@ void Global::ConfigParse(cParser &Parser) Parser.getTokens(); Parser >> WriteLogFlag; } - else if (token == "physicsdeactivation") + else if (token == "fullphysics") { // McZapkie-291103 - usypianie fizyki Parser.getTokens(); - Parser >> PhysicActivationFlag; + Parser >> Global::FullPhysics; } else if (token == "debuglog") { diff --git a/Globals.h b/Globals.h index df62bc17..77abf302 100644 --- a/Globals.h +++ b/Globals.h @@ -214,15 +214,22 @@ class Global float depth; float distance; } shadowtune; + static bool bUseVBO; // czy jest VBO w karcie graficznej + static float AnisotropicFiltering; // requested level of anisotropic filtering. TODO: move it to renderer object + static int ScreenWidth; // current window dimensions. TODO: move it to renderer + static int ScreenHeight; + static float ZoomFactor; // determines current camera zoom level. TODO: move it to the renderer + static float FieldOfView; // vertical field of view for the camera. TODO: move it to the renderer + static GLint iMaxTextureSize; // maksymalny rozmiar tekstury + static int iMultisampling; // tryb antyaliasingu: 0=brak,1=2px,2=4px,3=8px,4=16px + static bool FullPhysics; // full calculations performed for each simulation step static int iSlowMotion; static TDynamicObject *changeDynObj; static double ABuDebug; static std::string asSky; static bool bnewAirCouplers; // Ra: nowe zmienne globalne - static float AnisotropicFiltering; // requested level of anisotropic filtering. TODO: move it to renderer object - static bool bUseVBO; // czy jest VBO w karcie graficznej static std::string LastGLError; static int iFeedbackMode; // tryb pracy informacji zwrotnej static int iFeedbackPort; // dodatkowy adres dla informacji zwrotnych @@ -233,13 +240,8 @@ class Global static GLFWwindow *window; static bool shiftState; //m7todo: brzydko static bool ctrlState; - static int ScreenWidth; // current window dimensions. TODO: move it to renderer - static int ScreenHeight; - static float ZoomFactor; // determines current camera zoom level. TODO: move it to the renderer - static float FieldOfView; // vertical field of view for the camera. TODO: move it to the renderer static int iCameraLast; static std::string asVersion; // z opisem - static GLint iMaxTextureSize; // maksymalny rozmiar tekstury static bool ControlPicking; // indicates controls pick mode is active static bool InputMouse; // whether control pick mode can be activated static int iTextMode; // tryb pracy wyświetlacza tekstowego @@ -254,7 +256,6 @@ class Global static double fLatitudeDeg; // szerokość geograficzna static std::string szTexturesTGA; // lista tekstur od TGA static std::string szTexturesDDS; // lista tekstur od DDS - static int iMultisampling; // tryb antyaliasingu: 0=brak,1=2px,2=4px,3=8px,4=16px static bool DLFont; // switch indicating presence of basic font static bool bGlutFont; // tekst generowany przez GLUT static int iPause; // globalna pauza ruchu: b0=start,b1=klawisz,b2=tło,b3=lagi,b4=wczytywanie diff --git a/Ground.cpp b/Ground.cpp index cf0d9dbb..36173b84 100644 --- a/Ground.cpp +++ b/Ground.cpp @@ -1870,7 +1870,7 @@ bool TGround::Init(std::string File) } else { - ErrorLog("Scene parsing error in file \"" + parser.Name() + "\" (line " + std::to_string( parser.Line() ) + "), unexpected token \"" + token + "\""); + ErrorLog("Bad node: node parsing error, encountered in file \"" + parser.Name() + "\" (line " + std::to_string( parser.Line() - 1 ) + ")"); // break; } } @@ -3386,46 +3386,76 @@ bool TGround::CheckQuery() } } break; - case tp_WhoIs: // pobranie nazwy pociągu do komórki pamięci - if (tmpEvent->iFlags & update_load) - { // jeśli pytanie o ładunek - if (tmpEvent->iFlags & update_memadd) // jeśli typ pojazdu + case tp_WhoIs: { + // pobranie nazwy pociągu do komórki pamięci + if (tmpEvent->iFlags & update_load) { + // jeśli pytanie o ładunek + if( tmpEvent->iFlags & update_memadd ) { + // jeśli typ pojazdu + // TODO: define and recognize individual request types + auto const owner = ( + ( ( tmpEvent->Activator->Mechanik != nullptr ) && ( tmpEvent->Activator->Mechanik->Primary() ) ) ? + tmpEvent->Activator->Mechanik : + tmpEvent->Activator->ctOwner ); + auto const consistbrakelevel = ( + owner != nullptr ? + owner->fReady : + -1.0 ); + tmpEvent->Params[ 9 ].asMemCell->UpdateValues( tmpEvent->Activator->MoverParameters->TypeName, // typ pojazdu + consistbrakelevel, 0, // na razie nic - 0, // na razie nic - tmpEvent->iFlags & - (update_memstring | update_memval1 | update_memval2)); - else // jeśli parametry ładunku + tmpEvent->iFlags & ( update_memstring | update_memval1 | update_memval2 ) ); + + WriteLog( + "whois request (" + to_string( tmpEvent->iFlags ) + ") " + + "[name: " + tmpEvent->Activator->MoverParameters->TypeName + "], " + + "[consist brake level: " + to_string( consistbrakelevel, 2 ) + "], " + + "[]" ); + } + else { + // jeśli parametry ładunku tmpEvent->Params[ 9 ].asMemCell->UpdateValues( tmpEvent->Activator->MoverParameters->LoadType, // nazwa ładunku tmpEvent->Activator->MoverParameters->Load, // aktualna ilość tmpEvent->Activator->MoverParameters->MaxLoad, // maksymalna ilość - tmpEvent->iFlags & - (update_memstring | update_memval1 | update_memval2)); + tmpEvent->iFlags & ( update_memstring | update_memval1 | update_memval2 ) ); + + WriteLog( + "whois request (" + to_string( tmpEvent->iFlags ) + ") " + + "[load type: " + tmpEvent->Activator->MoverParameters->LoadType + "], " + + "[current load: " + to_string( tmpEvent->Activator->MoverParameters->Load, 2 ) + "], " + + "[max load: " + to_string( tmpEvent->Activator->MoverParameters->MaxLoad, 2 ) + "]" ); + } } else if (tmpEvent->iFlags & update_memadd) { // jeśli miejsce docelowe pojazdu tmpEvent->Params[ 9 ].asMemCell->UpdateValues( tmpEvent->Activator->asDestination, // adres docelowy tmpEvent->Activator->DirectionGet(), // kierunek pojazdu względem czoła składu (1=zgodny,-1=przeciwny) - tmpEvent->Activator->MoverParameters ->Power, // moc pojazdu silnikowego: 0 dla wagonu + tmpEvent->Activator->MoverParameters->Power, // moc pojazdu silnikowego: 0 dla wagonu tmpEvent->iFlags & (update_memstring | update_memval1 | update_memval2)); + + WriteLog( + "whois request (" + to_string( tmpEvent->iFlags ) + ") " + + "[destination: " + tmpEvent->Activator->asDestination + "], " + + "[direction: " + to_string( tmpEvent->Activator->DirectionGet() ) + "], " + + "[engine power: " + to_string( tmpEvent->Activator->MoverParameters->Power, 2 ) + "]" ); } else if (tmpEvent->Activator->Mechanik) if (tmpEvent->Activator->Mechanik->Primary()) { // tylko jeśli ktoś tam siedzi - nie powinno dotyczyć pasażera! tmpEvent->Params[ 9 ].asMemCell->UpdateValues( tmpEvent->Activator->Mechanik->TrainName(), - tmpEvent->Activator->Mechanik->StationCount() - - tmpEvent->Activator->Mechanik - ->StationIndex(), // ile przystanków do końca + tmpEvent->Activator->Mechanik->StationCount() - tmpEvent->Activator->Mechanik->StationIndex(), // ile przystanków do końca tmpEvent->Activator->Mechanik->IsStop() ? 1 : 0, // 1, gdy ma tu zatrzymanie tmpEvent->iFlags); WriteLog("Train detected: " + tmpEvent->Activator->Mechanik->TrainName()); } break; + } case tp_LogValues: // zapisanie zawartości komórki pamięci do logu if (tmpEvent->Params[9].asMemCell) // jeśli była podana nazwa komórki WriteLog("Memcell \"" + tmpEvent->asNodeName + "\": " + diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index 642c7bfb..c53b59f3 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -191,8 +191,6 @@ static int const sound_relay = 16; static int const sound_manyrelay = 32; static int const sound_brakeacc = 64; -static bool PhysicActivationFlag = false; - //szczególne typy pojazdów (inna obsługa) dla zmiennej TrainType //zamienione na flagi bitowe, aby szybko wybierać grupę (np. EZT+SZT) static int const dt_Default = 0; diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 8f00004a..b1c7251c 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -3791,9 +3791,6 @@ void TMoverParameters::ComputeTotalForce(double dt, double dt1, bool FullVer) // McZapkie-031103: sprawdzanie czy warto liczyc fizyke i inne updaty // ABu 300105: cos tu mieszalem , dziala teraz troche lepiej, wiec zostawiam - // zakomentowalem PhysicActivationFlag bo cos nie dzialalo i fizyka byla liczona zawsze. - // if (PhysicActivationFlag) - //{ if ((CabNo == 0) && (Vel < 0.0001) && (abs(AccS) < 0.0001) && (TrainType != dt_EZT)) { if (!PhysicActivation) @@ -3812,7 +3809,6 @@ void TMoverParameters::ComputeTotalForce(double dt, double dt1, bool FullVer) } else PhysicActivation = true; - //}; } double TMoverParameters::BrakeForceR(double ratio, double velocity) @@ -3971,7 +3967,7 @@ double TMoverParameters::Adhesive(double staticfriction) } // WriteLog(FloatToStr(adhesive)); // tutaj jest na poziomie 0.2 - 0.3 return adhesion; -*/ + //wersja druga if( true == SlippingWheels ) { @@ -3984,14 +3980,14 @@ double TMoverParameters::Adhesive(double staticfriction) else { adhesion = staticfriction * ( 100.0 + Vel ) / ( 50.0 + Vel ); } } // adhesion *= ( 0.9 + 0.2 * Random() ); -/* +*/ //wersja3 by youBy - uwzględnia naturalne mikropoślizgi i wpływ piasecznicy, usuwa losowość z pojazdu double Vwheels = nrot * M_PI * WheelDiameter; // predkosc liniowa koła wynikająca z obrotowej double deltaV = V - Vwheels; //poślizg - różnica prędkości w punkcie styku koła i szyny deltaV = std::max(0.0, std::abs(deltaV) - 0.25); //mikropoślizgi do ok. 0,25 m/s nie zrywają przyczepności Vwheels = std::abs( Vwheels ); adhesion = staticfriction * (28 + Vwheels) / (14 + Vwheels) * ((SandDose? sandfactor : 1) - (1 - adh_factor)*(deltaV / (deltaV + slipfactor))); -*/ + return adhesion; } @@ -6804,7 +6800,6 @@ void TMoverParameters::LoadFIZ_Wheels( std::string const &line ) { extract_value( TrackW, "Tw", line, "" ); extract_value( AxleInertialMoment, "AIM", line, "" ); - if( AxleInertialMoment <= 0.0 ) { AxleInertialMoment = 1.0; } extract_value( AxleArangement, "Axle", line, "" ); NPoweredAxles = s2NPW( AxleArangement ); @@ -6812,11 +6807,21 @@ void TMoverParameters::LoadFIZ_Wheels( std::string const &line ) { BearingType = ( extract_value( "BearingType", line ) == "Roll" ) ? - 1 : - 0; + 1 : + 0; extract_value( ADist, "Ad", line, "" ); extract_value( BDist, "Bd", line, "" ); + + if( AxleInertialMoment <= 0.0 ) { +/* + AxleInertialMoment = 1.0; +*/ + // approximation formula by youby + auto const k = 472.0; // arbitrary constant + AxleInertialMoment = k / 4.0 * std::pow( WheelDiameter, 4.0 ) * NAxles; + Mred = k * std::pow( WheelDiameter, 2.0 ) * NAxles; + } } void TMoverParameters::LoadFIZ_Brake( std::string const &line ) { diff --git a/McZapkie/mctools.cpp b/McZapkie/mctools.cpp index f249de8f..2b63e841 100644 --- a/McZapkie/mctools.cpp +++ b/McZapkie/mctools.cpp @@ -19,6 +19,7 @@ Copyright (C) 2007-2014 Maciej Cierniak bool DebugModeFlag = false; bool FreeFlyModeFlag = false; +bool EditorModeFlag = true; bool DebugCameraFlag = false; double Max0R(double x1, double x2) diff --git a/McZapkie/mctools.h b/McZapkie/mctools.h index 9c0c4f5d..6692710b 100644 --- a/McZapkie/mctools.h +++ b/McZapkie/mctools.h @@ -20,6 +20,7 @@ http://mozilla.org/MPL/2.0/. extern bool DebugModeFlag; extern bool FreeFlyModeFlag; +extern bool EditorModeFlag; extern bool DebugCameraFlag; /*funkcje matematyczne*/ diff --git a/Train.cpp b/Train.cpp index 5cd946e8..8610ebce 100644 --- a/Train.cpp +++ b/Train.cpp @@ -296,7 +296,6 @@ TTrain::TTrain() { fPPress = fNPress = 0; // asMessage=""; - fMechCroach = 0.25; pMechShake = vector3(0, 0, 0); vMechMovement = vector3(0, 0, 0); pMechOffset = vector3(0, 0, 0); @@ -389,8 +388,7 @@ bool TTrain::Init(TDynamicObject *NewDynamicObject, bool e3d) */ MechSpring.Init(0.015, 250); vMechVelocity = vector3(0, 0, 0); - pMechOffset = vector3(-0.4, 3.3, 5.5); - fMechCroach = 0.5; + pMechOffset = vector3( 0, 0, 0 ); fMechSpringX = 1; fMechSpringY = 0.5; fMechSpringZ = 0.5; @@ -6286,8 +6284,7 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName) } void TTrain::MechStop() -{ // likwidacja ruchu kamery w kabinie (po powrocie - // przez [F4]) +{ // likwidacja ruchu kamery w kabinie (po powrocie przez [F4]) pMechPosition = vector3(0, 0, 0); pMechShake = vector3(0, 0, 0); vMechMovement = vector3(0, 0, 0); diff --git a/Train.h b/Train.h index 166f2cc1..80b67bc0 100644 --- a/Train.h +++ b/Train.h @@ -378,7 +378,6 @@ public: // reszta może by?publiczna vector3 pMechShake; vector3 vMechVelocity; // McZapkie: do poruszania sie po kabinie - double fMechCroach; // McZapkie: opis kabiny - obszar poruszania sie mechanika oraz zajetosc TCab Cabine[maxcab + 1]; // przedzial maszynowy, kabina 1 (A), kabina 2 (B) int iCabn; diff --git a/World.cpp b/World.cpp index ca7e97be..8aa6ee88 100644 --- a/World.cpp +++ b/World.cpp @@ -772,12 +772,14 @@ void TWorld::OnMouseMove(double x, double y) void TWorld::InOutKey( bool const Near ) { // przełączenie widoku z kabiny na zewnętrzny i odwrotnie FreeFlyModeFlag = !FreeFlyModeFlag; // zmiana widoku - if (FreeFlyModeFlag) - { // jeżeli poza kabiną, przestawiamy w jej okolicę - OK + if (FreeFlyModeFlag) { + // jeżeli poza kabiną, przestawiamy w jej okolicę - OK Global::pUserDynamic = NULL; // bez renderowania względem kamery - if (Train) - { // Train->Dynamic()->ABuSetModelShake(vector3(0,0,0)); - Train->Silence(); // wyłączenie dźwięków kabiny + if (Train) { + // cache current cab position so there's no need to set it all over again after each out-in switch + Train->pMechSittingPosition = Train->pMechOffset; + // wyłączenie dźwięków kabiny + Train->Silence(); Train->Dynamic()->bDisplayCab = false; DistantView( Near ); } @@ -983,8 +985,15 @@ bool TWorld::Update() // this means at count > 20 simulation and render are going to desync. is that right? // NOTE: experimentally changing this to prevent the desync. // TODO: test what happens if we hit more than 20 * 0.01 sec slices, i.e. less than 5 fps - for( int updateidx = 0; updateidx < updatecount; ++updateidx ) { - Ground.Update( dt / updatecount, 1 ); // tu zrobić tylko coklatkową aktualizację przesunięć + if( true == Global::FullPhysics ) { + // default calculation mode, each step calculated separately + for( int updateidx = 0; updateidx < updatecount; ++updateidx ) { + Ground.Update( dt / updatecount, 1 ); + } + } + else { + // slightly simplified calculation mode; can lead to errors + Ground.Update( dt / updatecount, updatecount ); } // yB dodał przyspieszacz fizyki diff --git a/mouseinput.cpp b/mouseinput.cpp index 3709740c..be72ce1d 100644 --- a/mouseinput.cpp +++ b/mouseinput.cpp @@ -68,93 +68,105 @@ void mouse_input::button( int const Button, int const Action ) { if( false == Global::ControlPicking ) { return; } + if( true == FreeFlyModeFlag ) { - // for now we're only interested in cab controls - return; - } - - user_command &mousecommand = ( - Button == GLFW_MOUSE_BUTTON_LEFT ? - m_mousecommandleft : - m_mousecommandright - ); - - if( Action == GLFW_RELEASE ) { - if( mousecommand != user_command::none ) { - // NOTE: basic keyboard controls don't have any parameters - // as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0 - // TODO: pass correct entity id once the missing systems are in place - m_relay.post( mousecommand, 0, 0, Action, 0 ); - mousecommand = user_command::none; - } - else { - // if it's the right mouse button that got released and we had no command active, we were potentially in view panning mode; stop it + // world editor controls + // currently we only handle view panning in this mode + if( Action == GLFW_RELEASE ) { + // if it's the right mouse button that got released we were potentially in view panning mode; stop it if( Button == GLFW_MOUSE_BUTTON_RIGHT ) { m_pickmodepanning = false; } } - // if we were in varying command repeat rate, we can stop that now. done without any conditions, to catch some unforeseen edge cases - m_varyingpollrate = false; + else { + // button press + if( Button == GLFW_MOUSE_BUTTON_RIGHT ) { + // the right button activates mouse panning mode + m_pickmodepanning = true; + } + } } else { - // if not release then it's press - auto train = World.train(); - if( train != nullptr ) { - auto lookup = m_mousecommands.find( train->GetLabel( GfxRenderer.Update_Pick_Control() ) ); - if( lookup != m_mousecommands.end() ) { - mousecommand = ( - Button == GLFW_MOUSE_BUTTON_LEFT ? - lookup->second.left : - lookup->second.right - ); - if( mousecommand != user_command::none ) { - // check manually for commands which have 'fast' variants launched with shift modifier - if( Global::shiftState ) { + // cab controls mode + user_command &mousecommand = ( + Button == GLFW_MOUSE_BUTTON_LEFT ? + m_mousecommandleft : + m_mousecommandright + ); + + if( Action == GLFW_RELEASE ) { + if( mousecommand != user_command::none ) { + // NOTE: basic keyboard controls don't have any parameters + // as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0 + // TODO: pass correct entity id once the missing systems are in place + m_relay.post( mousecommand, 0, 0, Action, 0 ); + mousecommand = user_command::none; + } + else { + // if it's the right mouse button that got released and we had no command active, we were potentially in view panning mode; stop it + if( Button == GLFW_MOUSE_BUTTON_RIGHT ) { + m_pickmodepanning = false; + } + } + // if we were in varying command repeat rate, we can stop that now. done without any conditions, to catch some unforeseen edge cases + m_varyingpollrate = false; + } + else { + // if not release then it's press + auto train = World.train(); + if( train != nullptr ) { + auto lookup = m_mousecommands.find( train->GetLabel( GfxRenderer.Update_Pick_Control() ) ); + if( lookup != m_mousecommands.end() ) { + mousecommand = ( + Button == GLFW_MOUSE_BUTTON_LEFT ? + lookup->second.left : + lookup->second.right + ); + if( mousecommand != user_command::none ) { + // check manually for commands which have 'fast' variants launched with shift modifier + if( Global::shiftState ) { + switch( mousecommand ) { + case user_command::mastercontrollerincrease: { mousecommand = user_command::mastercontrollerincreasefast; break; } + case user_command::mastercontrollerdecrease: { mousecommand = user_command::mastercontrollerdecreasefast; break; } + case user_command::secondcontrollerincrease: { mousecommand = user_command::secondcontrollerincreasefast; break; } + case user_command::secondcontrollerdecrease: { mousecommand = user_command::secondcontrollerdecreasefast; break; } + case user_command::independentbrakeincrease: { mousecommand = user_command::independentbrakeincreasefast; break; } + case user_command::independentbrakedecrease: { mousecommand = user_command::independentbrakedecreasefast; break; } + default: { break; } + } + } + // NOTE: basic keyboard controls don't have any parameters + // as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0 + // TODO: pass correct entity id once the missing systems are in place + m_relay.post( mousecommand, 0, 0, Action, 0 ); + m_updateaccumulator = 0.0; // prevent potential command repeat right after issuing one + switch( mousecommand ) { - case user_command::mastercontrollerincrease: { mousecommand = user_command::mastercontrollerincreasefast; break; } - case user_command::mastercontrollerdecrease: { mousecommand = user_command::mastercontrollerdecreasefast; break; } - case user_command::secondcontrollerincrease: { mousecommand = user_command::secondcontrollerincreasefast; break; } - case user_command::secondcontrollerdecrease: { mousecommand = user_command::secondcontrollerdecreasefast; break; } - case user_command::independentbrakeincrease: { mousecommand = user_command::independentbrakeincreasefast; break; } - case user_command::independentbrakedecrease: { mousecommand = user_command::independentbrakedecreasefast; break; } - default: { break; } - } - } - // NOTE: basic keyboard controls don't have any parameters - // as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0 - // TODO: pass correct entity id once the missing systems are in place - m_relay.post( mousecommand, 0, 0, Action, 0 ); - m_updateaccumulator = 0.0; // prevent potential command repeat right after issuing one -/* - if( mousecommand == user_command::mastercontrollerincrease ) { - m_updateaccumulator -= 0.15; // extra pause on first increase of master controller - } -*/ - switch( mousecommand ) { - case user_command::mastercontrollerincrease: - case user_command::mastercontrollerdecrease: - case user_command::secondcontrollerincrease: - case user_command::secondcontrollerdecrease: - case user_command::trainbrakeincrease: - case user_command::trainbrakedecrease: - case user_command::independentbrakeincrease: - case user_command::independentbrakedecrease: { - // these commands trigger varying repeat rate mode, - // which scales the rate based on the distance of the cursor from its point when the command was first issued - m_commandstartcursor = m_cursorposition; - m_varyingpollrate = true; - break; - } - default: { - break; + case user_command::mastercontrollerincrease: + case user_command::mastercontrollerdecrease: + case user_command::secondcontrollerincrease: + case user_command::secondcontrollerdecrease: + case user_command::trainbrakeincrease: + case user_command::trainbrakedecrease: + case user_command::independentbrakeincrease: + case user_command::independentbrakedecrease: { + // these commands trigger varying repeat rate mode, + // which scales the rate based on the distance of the cursor from its point when the command was first issued + m_commandstartcursor = m_cursorposition; + m_varyingpollrate = true; + break; + } + default: { + break; + } } } } - } - else { - // if we don't have any recognized element under the cursor and the right button was pressed, enter view panning mode - if( Button == GLFW_MOUSE_BUTTON_RIGHT ) { - m_pickmodepanning = true; + else { + // if we don't have any recognized element under the cursor and the right button was pressed, enter view panning mode + if( Button == GLFW_MOUSE_BUTTON_RIGHT ) { + m_pickmodepanning = true; + } } } } diff --git a/renderer.cpp b/renderer.cpp index 530e4c25..46f896e9 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -423,14 +423,23 @@ opengl_renderer::Render_pass( rendermode const Mode ) { ::glEnable( GL_TEXTURE_2D ); } #endif +#ifdef EU07_NEW_CAB_RENDERCODE + if( World.Train != nullptr ) { + // cab render is performed without shadows, due to low resolution and number of models without windows :| + switch_units( true, false, false ); + Render_cab( World.Train->Dynamic(), false ); + } +#endif + switch_units( true, true, true ); Render( &World.Ground ); // ...translucent parts setup_drawing( true ); Render_Alpha( &World.Ground ); - // cab render is performed without shadows, due to low resolution and number of models without windows :| - switch_units( true, false, false ); - // cab render is done in translucent phase to deal with badly configured vehicles - if( World.Train != nullptr ) { Render_cab( World.Train->Dynamic() ); } + if( World.Train != nullptr ) { + // cab render is performed without shadows, due to low resolution and number of models without windows :| + switch_units( true, false, false ); + Render_cab( World.Train->Dynamic(), true ); + } if( m_environmentcubetexturesupport ) { // restore default texture matrix for reflections cube map @@ -1621,8 +1630,8 @@ opengl_renderer::Render( TGroundNode *Node ) { break; } } - if( ( distancesquared > Node->fSquareRadius ) - || ( distancesquared < Node->fSquareMinRadius ) ) { + if( ( distancesquared < Node->fSquareMinRadius ) + || ( distancesquared >= Node->fSquareRadius ) ) { return false; } @@ -1906,7 +1915,7 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) { // rendering kabiny gdy jest oddzielnym modelem i ma byc wyswietlana bool -opengl_renderer::Render_cab( TDynamicObject *Dynamic ) { +opengl_renderer::Render_cab( TDynamicObject *Dynamic, bool const Alpha ) { if( Dynamic == nullptr ) { @@ -1943,8 +1952,19 @@ opengl_renderer::Render_cab( TDynamicObject *Dynamic ) { ::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr( Dynamic->InteriorLight * Dynamic->InteriorLightLevel ) ); } // render +#ifdef EU07_NEW_CAB_RENDERCODE + if( true == Alpha ) { + // translucent parts + Render_Alpha( Dynamic->mdKabina, Dynamic->Material(), 0.0 ); + } + else { + // opaque parts + Render( Dynamic->mdKabina, Dynamic->Material(), 0.0 ); + } +#else Render( Dynamic->mdKabina, Dynamic->Material(), 0.0 ); Render_Alpha( Dynamic->mdKabina, Dynamic->Material(), 0.0 ); +#endif // post-render restore if( Dynamic->fShade > 0.0f ) { // change light level based on light level of the occupied track @@ -2030,7 +2050,7 @@ opengl_renderer::Render( TSubModel *Submodel ) { if( ( Submodel->iVisible ) && ( TSubModel::fSquareDist >= Submodel->fSquareMinDist ) - && ( TSubModel::fSquareDist <= Submodel->fSquareMaxDist ) ) { + && ( TSubModel::fSquareDist < Submodel->fSquareMaxDist ) ) { if( Submodel->iFlags & 0xC000 ) { ::glPushMatrix(); @@ -2412,8 +2432,8 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) { break; } } - if( ( distancesquared > Node->fSquareRadius ) - || ( distancesquared < Node->fSquareMinRadius ) ) { + if( ( distancesquared < Node->fSquareMinRadius ) + || ( distancesquared >= Node->fSquareRadius ) ) { return false; } @@ -2675,7 +2695,7 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) { // renderowanie przezroczystych przez DL if( ( Submodel->iVisible ) && ( TSubModel::fSquareDist >= Submodel->fSquareMinDist ) - && ( TSubModel::fSquareDist <= Submodel->fSquareMaxDist ) ) { + && ( TSubModel::fSquareDist < Submodel->fSquareMaxDist ) ) { if( Submodel->iFlags & 0xC000 ) { ::glPushMatrix(); diff --git a/renderer.h b/renderer.h index 067f64c0..70141315 100644 --- a/renderer.h +++ b/renderer.h @@ -285,7 +285,7 @@ private: void Render( TTrack *Track ); bool - Render_cab( TDynamicObject *Dynamic ); + Render_cab( TDynamicObject *Dynamic, bool const Alpha = false ); void Render( TMemCell *Memcell ); bool diff --git a/version.h b/version.h index 49b29887..50d73e58 100644 --- a/version.h +++ b/version.h @@ -1,5 +1,5 @@ #pragma once #define VERSION_MAJOR 17 -#define VERSION_MINOR 908 +#define VERSION_MINOR 911 #define VERSION_REVISION 0