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

build 171025: finished initial refactoring of ground class, fixes for text parser to prevent some cases of eternal parameter loops

This commit is contained in:
tmj-fstate
2017-10-26 04:54:07 +02:00
parent e3915e3c52
commit d8c3b5caf4
15 changed files with 332 additions and 245 deletions

View File

@@ -5367,43 +5367,47 @@ void TController::SetProximityVelocity( double dist, double vel, glm::dvec3 cons
TCommandType TController::BackwardScan() TCommandType TController::BackwardScan()
{ // sprawdzanie zdarzeń semaforów z tyłu pojazdu, zwraca komendę { // sprawdzanie zdarzeń semaforów z tyłu pojazdu, zwraca komendę
// dzięki temu będzie można stawać za wskazanym sygnalizatorem, a zwłaszcza jeśli będzie jazda // dzięki temu będzie można stawać za wskazanym sygnalizatorem, a zwłaszcza jeśli będzie jazda na kozioł
// na kozioł // ograniczenia prędkości nie są wtedy istotne, również koniec toru jest do niczego nie przydatny
// ograniczenia prędkości nie są wtedy istotne, również koniec toru jest do niczego nie
// przydatny
// zwraca true, jeśli należy odwrócić kierunek jazdy pojazdu // zwraca true, jeśli należy odwrócić kierunek jazdy pojazdu
if ((OrderList[OrderPos] & ~(Shunt | Connect))) if( ( OrderList[ OrderPos ] & ~( Shunt | Connect ) ) ) {
return cm_Unknown; // skanowanie sygnałów tylko gdy jedzie w trybie manewrowym albo czeka na // skanowanie sygnałów tylko gdy jedzie w trybie manewrowym albo czeka na rozkazy
// rozkazy return cm_Unknown;
}
vector3 sl; vector3 sl;
int startdir = // kierunek jazdy względem sprzęgów pojazdu na czele
-pVehicles[0]->DirectionGet(); // kierunek jazdy względem sprzęgów pojazdu na czele int const startdir = -pVehicles[0]->DirectionGet();
if (startdir == 0) // jeśli kabina i kierunek nie jest określony if( startdir == 0 ) {
return cm_Unknown; // nie robimy nic // jeśli kabina i kierunek nie jest określony nie robimy nic
double scandir = return cm_Unknown;
startdir * pVehicles[0]->RaDirectionGet(); // szukamy od pierwszej osi w wybranym kierunku }
if (scandir != // szukamy od pierwszej osi w wybranym kierunku
0.0) // skanowanie toru w poszukiwaniu eventów GetValues (PutValues nie są przydatne) double scandir = startdir * pVehicles[0]->RaDirectionGet();
{ // Ra: przy wstecznym skanowaniu prędkość nie ma znaczenia if (scandir != 0.0) {
// scanback=pVehicles[1]->NextDistance(fLength+1000.0); //odległość do następnego pojazdu, // skanowanie toru w poszukiwaniu eventów GetValues (PutValues nie są przydatne)
// 1000 gdy nic nie ma // Ra: przy wstecznym skanowaniu prędkość nie ma znaczenia
double scanmax = 1000; // 1000m do tyłu, żeby widział przeciwny koniec stacji double scanmax = 1000; // 1000m do tyłu, żeby widział przeciwny koniec stacji
double scandist = scanmax; // zmodyfikuje na rzeczywiście przeskanowane double scandist = scanmax; // zmodyfikuje na rzeczywiście przeskanowane
TEvent *e = NULL; // event potencjalnie od semafora TEvent *e = NULL; // event potencjalnie od semafora
// opcjonalnie może być skanowanie od "wskaźnika" z przodu, np. W5, Tm=Ms1, koniec toru // opcjonalnie może być skanowanie od "wskaźnika" z przodu, np. W5, Tm=Ms1, koniec toru wg drugiej osi w kierunku ruchu
TTrack *scantrack = BackwardTraceRoute(scandist, scandir, pVehicles[0]->RaTrackGet(), TTrack *scantrack = BackwardTraceRoute(scandist, scandir, pVehicles[0]->RaTrackGet(), e);
e); // wg drugiej osi w kierunku ruchu vector3 const dir = startdir * pVehicles[0]->VectorFront(); // wektor w kierunku jazdy/szukania
vector3 dir = startdir * pVehicles[0]->VectorFront(); // wektor w kierunku jazdy/szukania if( !scantrack ) {
if (!scantrack) // jeśli wstecz wykryto koniec toru // jeśli wstecz wykryto koniec toru to raczej nic się nie da w takiej sytuacji zrobić
return cm_Unknown; // to raczej nic się nie da w takiej sytuacji zrobić return cm_Unknown;
else }
{ // a jeśli są dalej tory else {
// a jeśli są dalej tory
double vmechmax; // prędkość ustawiona semaforem double vmechmax; // prędkość ustawiona semaforem
if (e) if( e != nullptr ) {
{ // jeśli jest jakiś sygnał na widoku // jeśli jest jakiś sygnał na widoku
#if LOGBACKSCAN #if LOGBACKSCAN
AnsiString edir = std::string edir {
pVehicle->asName + " - " + AnsiString((scandir > 0) ? "Event2 " : "Event1 "); "Backward scan by "
+ pVehicle->asName + " - "
+ ( ( scandir > 0 ) ?
"Event2 " :
"Event1 " ) };
#endif #endif
// najpierw sprawdzamy, czy semafor czy inny znak został przejechany // najpierw sprawdzamy, czy semafor czy inny znak został przejechany
vector3 pos = pVehicles[1]->RearPosition(); // pozycja tyłu vector3 pos = pVehicles[1]->RearPosition(); // pozycja tyłu
@@ -5411,66 +5415,67 @@ TCommandType TController::BackwardScan()
if (e->Type == tp_GetValues) if (e->Type == tp_GetValues)
{ // przesłać info o zbliżającym się semaforze { // przesłać info o zbliżającym się semaforze
#if LOGBACKSCAN #if LOGBACKSCAN
edir += "(" + (e->Params[8].asGroundNode->asName) + "): "; edir += "(" + ( e->asNodeName ) + ")";
#endif #endif
sl = e->PositionGet(); // położenie komórki pamięci sl = e->PositionGet(); // położenie komórki pamięci
sem = sl - pos; // wektor do komórki pamięci od końca składu sem = sl - pos; // wektor do komórki pamięci od końca składu
// sem=e->Params[8].asGroundNode->pCenter-pos; //wektor do komórki pamięci if (dir.x * sem.x + dir.z * sem.z < 0) {
if (dir.x * sem.x + dir.z * sem.z < 0) // jeśli został minięty // jeśli został minięty
// if ((mvOccupied->CategoryFlag&1)?(VelNext!=0.0):true) //dla pociągu wymagany // iloczyn skalarny jest ujemny, gdy sygnał stoi z tyłu
// sygnał zezwalający
{ // iloczyn skalarny jest ujemny, gdy sygnał stoi z tyłu
#if LOGBACKSCAN #if LOGBACKSCAN
WriteLog(edir + "- ignored as not passed yet"); WriteLog(edir + " - ignored as not passed yet");
#endif #endif
return cm_Unknown; // nic return cm_Unknown; // nic
} }
vmechmax = e->ValueGet(1); // prędkość przy tym semaforze vmechmax = e->ValueGet(1); // prędkość przy tym semaforze
// przeliczamy odległość od semafora - potrzebne by były współrzędne początku // przeliczamy odległość od semafora - potrzebne by były współrzędne początku składu
// składu
// scandist=(pos-e->Params[8].asGroundNode->pCenter).Length()-0.5*mvOccupied->Dim.L-10;
// //10m luzu
scandist = sem.Length() - 2; // 2m luzu przy manewrach wystarczy scandist = sem.Length() - 2; // 2m luzu przy manewrach wystarczy
if (scandist < 0) if( scandist < 0 ) {
scandist = 0; // ujemnych nie ma po co wysyłać // ujemnych nie ma po co wysyłać
scandist = 0;
}
bool move = false; // czy AI w trybie manewerowym ma dociągnąć pod S1 bool move = false; // czy AI w trybie manewerowym ma dociągnąć pod S1
if (e->Command() == cm_SetVelocity) if( e->Command() == cm_SetVelocity ) {
if ((vmechmax == 0.0) ? (OrderCurrentGet() & (Shunt | Connect)) : if( ( vmechmax == 0.0 ) ?
(OrderCurrentGet() & ( OrderCurrentGet() & ( Shunt | Connect ) ) :
Connect)) // przy podczepianiu ignorować wyjazd? ( OrderCurrentGet() & Connect ) ) { // przy podczepianiu ignorować wyjazd?
move = true; // AI w trybie manewerowym ma dociągnąć pod S1 move = true; // AI w trybie manewerowym ma dociągnąć pod S1
else }
{ // else {
if ((scandist > fMinProximityDist) ? if( ( scandist > fMinProximityDist )
(mvOccupied->Vel > 0.0) && (OrderCurrentGet() != Shunt) : && ( ( mvOccupied->Vel > 0.0 )
false) && ( OrderCurrentGet() != Shunt ) ) ) {
{ // jeśli semafor jest daleko, a pojazd jedzie, to informujemy o // jeśli semafor jest daleko, a pojazd jedzie, to informujemy o zmianie prędkości
// zmianie prędkości // jeśli jedzie manewrowo, musi dostać SetVelocity, żeby sie na pociągowy przełączył
// jeśli jedzie manewrowo, musi dostać SetVelocity, żeby sie na pociągowy przełączył
// Mechanik->PutCommand("SetProximityVelocity",scandist,vmechmax,sl);
#if LOGBACKSCAN #if LOGBACKSCAN
// WriteLog(edir+"SetProximityVelocity "+AnsiString(scandist)+" // WriteLog(edir+"SetProximityVelocity "+AnsiString(scandist) + AnsiString(vmechmax));
// "+AnsiString(vmechmax));
WriteLog(edir); WriteLog(edir);
#endif #endif
// SetProximityVelocity(scandist,vmechmax,&sl); // SetProximityVelocity(scandist,vmechmax,&sl);
return (vmechmax > 0) ? cm_SetVelocity : cm_Unknown; return (
vmechmax > 0 ?
cm_SetVelocity :
cm_Unknown );
} }
else // ustawiamy prędkość tylko wtedy, gdy ma ruszyć, stanąć albo ma else {
// stać // ustawiamy prędkość tylko wtedy, gdy ma ruszyć, stanąć albo ma stać
// if ((MoverParameters->Vel==0.0)||(vmechmax==0.0)) //jeśli stoi lub ma // if ((MoverParameters->Vel==0.0)||(vmechmax==0.0)) //jeśli stoi lub ma stanąć/stać
// stanąć/st // semafor na tym torze albo lokomtywa stoi, a ma ruszyć, albo ma stanąć, albo nie rusz
{ // semafor na tym torze albo lokomtywa stoi, a ma ruszyć, albo ma // stop trzeba powtarzać, bo inaczej zatrąbi i pojedzie sam
// stanąć, albo nie ruszać // PutCommand("SetVelocity",vmechmax,e->Params[9].asMemCell->Value2(),&sl,stopSem);
// stop trzeba powtarzać, bo inaczej zatrąbi i pojedzie sam
// PutCommand("SetVelocity",vmechmax,e->Params[9].asMemCell->Value2(),&sl,stopSem);
#if LOGBACKSCAN #if LOGBACKSCAN
WriteLog(edir + "SetVelocity " + AnsiString(vmechmax) + " " + WriteLog(
AnsiString(e->Params[9].asMemCell->Value2())); edir + " - [SetVelocity] ["
+ to_string( vmechmax, 2 ) + "] ["
+ to_string( e->Params[ 9 ].asMemCell->Value2(), 2 ) + "]" );
#endif #endif
return (vmechmax > 0) ? cm_SetVelocity : cm_Unknown; return (
vmechmax > 0 ?
cm_SetVelocity :
cm_Unknown );
} }
} }
}
if (OrderCurrentGet() ? OrderCurrentGet() & (Shunt | Connect) : if (OrderCurrentGet() ? OrderCurrentGet() & (Shunt | Connect) :
true) // w Wait_for_orders też widzi tarcze true) // w Wait_for_orders też widzi tarcze
{ // reakcja AI w trybie manewrowym dodatkowo na sygnały manewrowe { // reakcja AI w trybie manewrowym dodatkowo na sygnały manewrowe
@@ -5497,28 +5502,34 @@ TCommandType TController::BackwardScan()
// to można zmienić kierunek // to można zmienić kierunek
} }
} }
else // ustawiamy prędkość tylko wtedy, gdy ma ruszyć, albo stanąć albo else {
// ma stać pod tarczą // ustawiamy prędkość tylko wtedy, gdy ma ruszyć, albo stanąć albo ma stać pod tarczą
{ // stop trzeba powtarzać, bo inaczej zatrąbi i pojedzie sam // stop trzeba powtarzać, bo inaczej zatrąbi i pojedzie sam
// if ((MoverParameters->Vel==0.0)||(vmechmax==0.0)) //jeśli jedzie // if ((MoverParameters->Vel==0.0)||(vmechmax==0.0)) //jeśli jedzie lub ma stanąć/stać
// lub ma stanąć/stać
{ // nie dostanie komendy jeśli jedzie i ma jechać { // nie dostanie komendy jeśli jedzie i ma jechać
// PutCommand("ShuntVelocity",vmechmax,e->Params[9].asMemCell->Value2(),&sl,stopSem); // PutCommand("ShuntVelocity",vmechmax,e->Params[9].asMemCell->Value2(),&sl,stopSem);
#if LOGBACKSCAN #if LOGBACKSCAN
WriteLog(edir + "ShuntVelocity " + AnsiString(vmechmax) + " " + WriteLog(
AnsiString(e->ValueGet(2))); edir + " - [ShuntVelocity] ["
+ to_string( vmechmax, 2 ) + "] ["
+ to_string( e->ValueGet( 2 ), 2 ) + "]" );
#endif #endif
return (vmechmax > 0) ? cm_ShuntVelocity : cm_Unknown; return (
vmechmax > 0 ?
cm_ShuntVelocity :
cm_Unknown );
} }
} }
if ((vmechmax != 0.0) && (scandist < 100.0)) if ((vmechmax != 0.0) && (scandist < 100.0)) {
{ // jeśli Tm w odległości do 100m podaje zezwolenie na jazdę, to od // jeśli Tm w odległości do 100m podaje zezwolenie na jazdę, to od razu ją ignorujemy, aby móc szukać kolejnej
// razu ją ignorujemy, aby móc szukać kolejnej // eSignSkip=e; //wtedy uznajemy ignorowaną przy poszukiwaniu nowej
// eSignSkip=e; //wtedy uznajemy ignorowaną przy poszukiwaniu nowej
#if LOGBACKSCAN #if LOGBACKSCAN
WriteLog(edir + "- will be ignored due to Ms2"); WriteLog(edir + " - will be ignored due to Ms2");
#endif #endif
return (vmechmax > 0) ? cm_ShuntVelocity : cm_Unknown; return (
vmechmax > 0 ?
cm_ShuntVelocity :
cm_Unknown );
} }
} // if (move?... } // if (move?...
} // if (OrderCurrentGet()==Shunt) } // if (OrderCurrentGet()==Shunt)

View File

@@ -415,14 +415,22 @@ void TDynamicObject::UpdateDoorTranslate(TAnim *pAnim)
// Ra: te współczynniki są bez sensu, bo modyfikują wektor przesunięcia // Ra: te współczynniki są bez sensu, bo modyfikują wektor przesunięcia
// w efekcie drzwi otwierane na zewnątrz będą odlatywac dowolnie daleko :) // w efekcie drzwi otwierane na zewnątrz będą odlatywac dowolnie daleko :)
// ograniczyłem zakres ruchu funkcją max // ograniczyłem zakres ruchu funkcją max
if (pAnim->smAnimated) if (pAnim->smAnimated) {
{
if (pAnim->iNumber & 1) if( pAnim->iNumber & 1 ) {
pAnim->smAnimated->SetTranslate( pAnim->smAnimated->SetTranslate(
vector3(0, 0, Min0R(dDoorMoveR * pAnim->fSpeed, dDoorMoveR))); vector3{
else 0.0,
0.0,
dDoorMoveR } );
}
else {
pAnim->smAnimated->SetTranslate( pAnim->smAnimated->SetTranslate(
vector3(0, 0, Min0R(dDoorMoveL * pAnim->fSpeed, dDoorMoveL))); vector3{
0.0,
0.0,
dDoorMoveL } );
}
} }
}; };
@@ -493,18 +501,30 @@ void TDynamicObject::UpdatePant(TAnim *pAnim)
void TDynamicObject::UpdateDoorPlug(TAnim *pAnim) void TDynamicObject::UpdateDoorPlug(TAnim *pAnim)
{ // animacja drzwi - odskokprzesuw { // animacja drzwi - odskokprzesuw
if (pAnim->smAnimated) if (pAnim->smAnimated) {
{
if (pAnim->iNumber & 1) if( pAnim->iNumber & 1 ) {
pAnim->smAnimated->SetTranslate( pAnim->smAnimated->SetTranslate(
vector3(Min0R(dDoorMoveR * 2, MoverParameters->DoorMaxPlugShift), 0, vector3 {
Max0R(0, Min0R(dDoorMoveR * pAnim->fSpeed, dDoorMoveR) - std::min(
MoverParameters->DoorMaxPlugShift * 0.5f))); dDoorMoveR * 2,
else MoverParameters->DoorMaxPlugShift ),
0.0,
std::max(
0.0,
dDoorMoveR - MoverParameters->DoorMaxPlugShift * 0.5 ) } );
}
else {
pAnim->smAnimated->SetTranslate( pAnim->smAnimated->SetTranslate(
vector3(Min0R(dDoorMoveL * 2, MoverParameters->DoorMaxPlugShift), 0, vector3 {
Max0R(0, Min0R(dDoorMoveL * pAnim->fSpeed, dDoorMoveL) - std::min(
MoverParameters->DoorMaxPlugShift * 0.5f))); dDoorMoveL * 2,
MoverParameters->DoorMaxPlugShift ),
0.0,
std::max(
0.0,
dDoorMoveL - MoverParameters->DoorMaxPlugShift * 0.5f ) } );
}
} }
}; };
@@ -1745,8 +1765,8 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
} }
if (ActPar.find('0') != std::string::npos) // wylaczanie na sztywno if (ActPar.find('0') != std::string::npos) // wylaczanie na sztywno
{ {
MoverParameters->Hamulec->SetBrakeStatus( MoverParameters->Hamulec->GetBrakeStatus() | b_dmg ); // wylacz
MoverParameters->Hamulec->ForceEmptiness(); MoverParameters->Hamulec->ForceEmptiness();
MoverParameters->Hamulec->SetBrakeStatus( MoverParameters->Hamulec->GetBrakeStatus() | b_dmg ); // wylacz
} }
if (ActPar.find('E') != std::string::npos) // oprozniony if (ActPar.find('E') != std::string::npos) // oprozniony
{ {
@@ -1770,16 +1790,16 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
{ {
if (Random(10) < 1) // losowanie 1/10 if (Random(10) < 1) // losowanie 1/10
{ {
MoverParameters->Hamulec->SetBrakeStatus( MoverParameters->Hamulec->GetBrakeStatus() | b_dmg ); // wylacz
MoverParameters->Hamulec->ForceEmptiness(); MoverParameters->Hamulec->ForceEmptiness();
MoverParameters->Hamulec->SetBrakeStatus( MoverParameters->Hamulec->GetBrakeStatus() | b_dmg ); // wylacz
} }
} }
if (ActPar.find('X') != std::string::npos) // agonalny wylaczanie 20%, usrednienie przekladni if (ActPar.find('X') != std::string::npos) // agonalny wylaczanie 20%, usrednienie przekladni
{ {
if (Random(100) < 20) // losowanie 20/100 if (Random(100) < 20) // losowanie 20/100
{ {
MoverParameters->Hamulec->SetBrakeStatus( MoverParameters->Hamulec->GetBrakeStatus() | b_dmg ); // wylacz
MoverParameters->Hamulec->ForceEmptiness(); MoverParameters->Hamulec->ForceEmptiness();
MoverParameters->Hamulec->SetBrakeStatus( MoverParameters->Hamulec->GetBrakeStatus() | b_dmg ); // wylacz
} }
if (MoverParameters->BrakeCylMult[2] * MoverParameters->BrakeCylMult[1] > if (MoverParameters->BrakeCylMult[2] * MoverParameters->BrakeCylMult[1] >
0.01) // jesli jest nastawiacz mechaniczny PL 0.01) // jesli jest nastawiacz mechaniczny PL
@@ -5367,7 +5387,6 @@ vehicle_table::update( double Deltatime, int Iterationcount ) {
if( false == vehicle->bEnabled ) { continue; } if( false == vehicle->bEnabled ) { continue; }
// Ra: zmienić warunek na sprawdzanie pantografów w jednej zmiennej: czy pantografy i czy podniesione // Ra: zmienić warunek na sprawdzanie pantografów w jednej zmiennej: czy pantografy i czy podniesione
if( vehicle->MoverParameters->EnginePowerSource.SourceType == CurrentCollector ) { if( vehicle->MoverParameters->EnginePowerSource.SourceType == CurrentCollector ) {
// TODO: re-implement
update_traction( vehicle ); update_traction( vehicle );
} }
vehicle->MoverParameters->ComputeConstans(); vehicle->MoverParameters->ComputeConstans();

View File

@@ -1263,16 +1263,8 @@ event_manager::CheckQuery() {
+ to_string( m_workevent->Params[ 9 ].asMemCell->Value2(), 2 ) + "]" ); + to_string( m_workevent->Params[ 9 ].asMemCell->Value2(), 2 ) + "]" );
} }
else { else {
/*
// TODO: re-enable when cell manager is in place
// lista wszystkich // lista wszystkich
for( TGroundNode *Current = nRootOfType[ TP_MEMCELL ]; Current; Current = Current->nNext ) { simulation::Memory.log_all();
WriteLog( "Memcell \"" + Current->asName + "\": "
+ Current->MemCell->Text() + " "
+ std::to_string( Current->MemCell->Value1() ) + " "
+ std::to_string( Current->MemCell->Value2() ) );
}
*/
} }
break; break;
} }

View File

@@ -1200,7 +1200,6 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
} }
break; break;
#endif
case TP_MODEL: { case TP_MODEL: {
if( rmin < 0 ) { if( rmin < 0 ) {
// legacy leftover: special case, terrain provided as 3d model // legacy leftover: special case, terrain provided as 3d model
@@ -1234,7 +1233,6 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
} }
} }
else { else {
#ifdef EU07_USE_OLD_GROUNDCODE
// regular 3d model // regular 3d model
parser->getTokens( 3 ); parser->getTokens( 3 );
*parser *parser
@@ -1265,11 +1263,9 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
ErrorLog( "Duplicated model: " + tmp->asName ); // to zgłaszać duplikat ErrorLog( "Duplicated model: " + tmp->asName ); // to zgłaszać duplikat
} }
} }
#endif
} }
break; break;
} }
#ifdef EU07_USE_OLD_GROUNDCODE
// case TP_GEOMETRY : // case TP_GEOMETRY :
case GL_TRIANGLES: case GL_TRIANGLES:
case GL_TRIANGLE_STRIP: case GL_TRIANGLE_STRIP:
@@ -1472,7 +1468,6 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
} // koniec wczytywania trójkątów } // koniec wczytywania trójkątów
break; break;
} }
#endif
case GL_LINES: case GL_LINES:
case GL_LINE_STRIP: case GL_LINE_STRIP:
case GL_LINE_LOOP: { case GL_LINE_LOOP: {
@@ -1566,6 +1561,7 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
} }
break; break;
} }
#endif
} }
return tmp; return tmp;
} }
@@ -1933,7 +1929,12 @@ bool TGround::Init(std::string File)
} }
else if (str == "endorigin") else if (str == "endorigin")
{ {
OriginStack.pop(); if( true == OriginStack.empty() ) {
// report error here
}
else {
OriginStack.pop();
}
pOrigin = ( OriginStack.empty() ? pOrigin = ( OriginStack.empty() ?
Math3D::vector3() : Math3D::vector3() :
OriginStack.top() ); OriginStack.top() );

View File

@@ -202,3 +202,16 @@ memory_table::InitCells() {
cell->AssignEvents( simulation::Events.FindEvent( cell->name() + ":sent" ) ); cell->AssignEvents( simulation::Events.FindEvent( cell->name() + ":sent" ) );
} }
} }
// legacy method, sends content of all cells to the log
void
memory_table::log_all() {
for( auto *cell : m_items ) {
WriteLog( "Memcell \"" + cell->name() + "\": ["
+ cell->Text() + "] ["
+ to_string( cell->Value1(), 2 ) + "] ["
+ to_string( cell->Value2(), 2 ) + "]" );
}
}

View File

@@ -73,6 +73,9 @@ public:
// legacy method, initializes traction after deserialization from scenario file // legacy method, initializes traction after deserialization from scenario file
void void
InitCells(); InitCells();
// legacy method, sends content of all cells to the log
void
log_all();
}; };
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@@ -386,7 +386,12 @@ bool TSegment::RenderLoft( vertex_array &Output, Math3D::vector3 const &Origin,
fOffset = 0.1 / fLength; // pierwsze 10cm fOffset = 0.1 / fLength; // pierwsze 10cm
pos1 = glm::dvec3{ FastGetPoint( t ) - Origin }; // wektor początku segmentu pos1 = glm::dvec3{ FastGetPoint( t ) - Origin }; // wektor początku segmentu
dir = glm::dvec3{ FastGetDirection( t, fOffset ) }; // wektor kierunku dir = glm::dvec3{ FastGetDirection( t, fOffset ) }; // wektor kierunku
parallel1 = glm::normalize( glm::vec3{ -dir.z, 0.f, dir.x } ); // wektor poprzeczny parallel1 = glm::vec3{ -dir.z, 0.f, dir.x }; // wektor poprzeczny
if( glm::length2( parallel1 ) == 0.f ) {
// temporary workaround for malformed situations with control points placed above endpoints
parallel1 = glm::vec3{ glm::dvec3{ FastGetPoint_1() - FastGetPoint_0() } };
}
parallel1 = glm::normalize( parallel1 );
if( iEnd == 0 ) if( iEnd == 0 )
iEnd = iSegCount; iEnd = iSegCount;
fEnd = fLength * double( iEnd ) / double( iSegCount ); fEnd = fLength * double( iEnd ) / double( iSegCount );
@@ -416,7 +421,12 @@ bool TSegment::RenderLoft( vertex_array &Output, Math3D::vector3 const &Origin,
t = fTsBuffer[ i ]; // szybsze od GetTFromS(s); t = fTsBuffer[ i ]; // szybsze od GetTFromS(s);
pos2 = glm::dvec3{ FastGetPoint( t ) - Origin }; pos2 = glm::dvec3{ FastGetPoint( t ) - Origin };
dir = glm::dvec3{ FastGetDirection( t, fOffset ) }; // nowy wektor kierunku dir = glm::dvec3{ FastGetDirection( t, fOffset ) }; // nowy wektor kierunku
parallel2 = glm::normalize( glm::vec3{ -dir.z, 0.f, dir.x } ); // wektor poprzeczny parallel2 = glm::vec3{ -dir.z, 0.f, dir.x }; // wektor poprzeczny
if( glm::length2( parallel2 ) == 0.f ) {
// temporary workaround for malformed situations with control points placed above endpoints
parallel2 = glm::vec3{ glm::dvec3{ FastGetPoint_1() - FastGetPoint_0() } };
}
parallel2 = glm::normalize( parallel2 );
if( trapez ) { if( trapez ) {
for( int j = 0; j < iNumShapePoints; ++j ) { for( int j = 0; j < iNumShapePoints; ++j ) {

View File

@@ -583,16 +583,7 @@ void TTrack::Load(cParser *parser, vector3 pOrigin)
>> fTexHeight1 >> fTexHeight1
>> fTexWidth >> fTexWidth
>> fTexSlope; >> fTexSlope;
if( fTexLength != 4.f ) {
// force defaults for malformed track definitions
bool paramsvalid { true };
if( fTexHeight1 == 0.f ) { fTexHeight1 = 0.6f; paramsvalid = false; }
if( fTexWidth == 0.f ) { fTexWidth = 0.9f; paramsvalid = false; }
if( fTexSlope == 0.f ) { fTexSlope = 0.9f; paramsvalid = false; }
if( false == paramsvalid ) {
ErrorLog( "Bad track: one or more of texture dimensions set to 0 for track \"" + name() + "\" in file \"" + parser->Name() + "\" (line " + std::to_string( parser->Line() - 1 ) + ")" );
}
}
if (iCategoryFlag & 4) if (iCategoryFlag & 4)
fTexHeight1 = -fTexHeight1; // rzeki mają wysokość odwrotnie niż drogi fTexHeight1 = -fTexHeight1; // rzeki mają wysokość odwrotnie niż drogi
} }
@@ -1185,13 +1176,15 @@ bool TTrack::InMovement()
#ifdef EU07_USE_OLD_GROUNDCODE #ifdef EU07_USE_OLD_GROUNDCODE
void TTrack::RaAssign(TGroundNode *gn, TAnimModel *am, TEvent *done, TEvent *joined) void TTrack::RaAssign(TGroundNode *gn, TAnimModel *am, TEvent *done, TEvent *joined)
#else #else
void TTrack::RaAssign( scene::basic_cell *gn, TAnimModel *am, TEvent *done, TEvent *joined ) void TTrack::RaAssign( TAnimModel *am, TEvent *done, TEvent *joined )
#endif #endif
{ // Ra: wiązanie toru z modelem obrotnicy { // Ra: wiązanie toru z modelem obrotnicy
if (eType == tt_Table) if (eType == tt_Table)
{ {
SwitchExtension->pModel = am; SwitchExtension->pModel = am;
#ifdef EU07_USE_OLD_GROUNDCODE
SwitchExtension->pMyNode = gn; SwitchExtension->pMyNode = gn;
#endif
SwitchExtension->evMinus = done; // event zakończenia animacji (zadanie nowej przedłuża) SwitchExtension->evMinus = done; // event zakończenia animacji (zadanie nowej przedłuża)
SwitchExtension->evPlus = SwitchExtension->evPlus =
joined; // event potwierdzenia połączenia (gdy nie znajdzie, to się nie połączy) joined; // event potwierdzenia połączenia (gdy nie znajdzie, to się nie połączy)
@@ -1218,6 +1211,10 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
hypot1 = 1.f; hypot1 = 1.f;
glm::vec3 const normalup{ 0.f, 1.f, 0.f }; glm::vec3 const normalup{ 0.f, 1.f, 0.f };
glm::vec3 normal1 { fTexHeight1 / hypot1, fTexSlope / hypot1, 0.f }; // wektor normalny glm::vec3 normal1 { fTexHeight1 / hypot1, fTexSlope / hypot1, 0.f }; // wektor normalny
if( glm::length( normal1 ) == 0.f ) {
// fix normal for vertical surfaces
normal1 = glm::vec3 { 1.f, 0.f, 0.f };
}
glm::vec3 normal2; glm::vec3 normal2;
float fHTW2, side2, slop2, rozp2, fTexHeight2, hypot2; float fHTW2, side2, slop2, rozp2, fTexHeight2, hypot2;
if( iTrapezoid & 2 ) { if( iTrapezoid & 2 ) {
@@ -1232,6 +1229,10 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
if( hypot2 == 0.f ) if( hypot2 == 0.f )
hypot2 = 1.f; hypot2 = 1.f;
normal2 = { fTexHeight2 / hypot2, trNext->fTexSlope / hypot2, 0.f }; normal2 = { fTexHeight2 / hypot2, trNext->fTexSlope / hypot2, 0.f };
if( glm::length( normal2 ) == 0.f ) {
// fix normal for vertical surfaces
normal2 = glm::vec3 { 1.f, 0.f, 0.f };
}
} }
else { else {
// gdy nie ma następnego albo jest nieodpowiednim końcem podpięty // gdy nie ma następnego albo jest nieodpowiednim końcem podpięty
@@ -1645,7 +1646,7 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
{ // standardowo: od zewnątrz pochylenie, a od wewnątrz poziomo { // standardowo: od zewnątrz pochylenie, a od wewnątrz poziomo
rpts1[ 0 ] = { rpts1[ 0 ] = {
{rozp, -fTexHeight1, 0.f}, {rozp, -fTexHeight1, 0.f},
normalup, { 1.f, 0.f, 0.f },
{0.f, 0.f} }; // lewy brzeg podstawy {0.f, 0.f} }; // lewy brzeg podstawy
rpts1[ 1 ] = { rpts1[ 1 ] = {
{bpts1[ 0 ].position.x + side, bpts1[ 0 ].position.y, 0.f}, {bpts1[ 0 ].position.x + side, bpts1[ 0 ].position.y, 0.f},
@@ -1665,13 +1666,13 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
{0.5f, 0.f} }; // prawa krawędź załamania {0.5f, 0.f} }; // prawa krawędź załamania
rpts2[ 2 ] = { rpts2[ 2 ] = {
{-rozp, -fTexHeight1, 0.f}, {-rozp, -fTexHeight1, 0.f},
normalup, { -1.f, 0.f, 0.f },
{0.f, 0.f} }; // prawy brzeg podstawy {0.f, 0.f} }; // prawy brzeg podstawy
if (iTrapezoid) { if (iTrapezoid) {
// pobocza do trapezowatej nawierzchni - dodatkowe punkty z drugiej strony odcinka // pobocza do trapezowatej nawierzchni - dodatkowe punkty z drugiej strony odcinka
rpts1[ 3 ] = { rpts1[ 3 ] = {
{rozp2, -fTexHeight2, 0.f}, {rozp2, -fTexHeight2, 0.f},
normalup, { 1.f, 0.f, 0.f },
{0.f, 0.f} }; // lewy brzeg lewego pobocza {0.f, 0.f} }; // lewy brzeg lewego pobocza
rpts1[ 4 ] = { rpts1[ 4 ] = {
{bpts1[ 2 ].position.x + side2, bpts1[ 2 ].position.y, 0.f}, {bpts1[ 2 ].position.x + side2, bpts1[ 2 ].position.y, 0.f},
@@ -1691,7 +1692,7 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
{0.5f, 0.f} }; {0.5f, 0.f} };
rpts2[ 5 ] = { rpts2[ 5 ] = {
{-rozp2, -fTexHeight2, 0.f}, {-rozp2, -fTexHeight2, 0.f},
normalup, { -1.f, 0.f, 0.f },
{0.f, 0.f} }; // prawy brzeg prawego pobocza {0.f, 0.f} }; // prawy brzeg prawego pobocza
} }
} }
@@ -1728,11 +1729,11 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
{0.515625f, 0.f} }; // prawy krawężnik u góry {0.515625f, 0.f} }; // prawy krawężnik u góry
rpts1[ 2 ] = { rpts1[ 2 ] = {
{bpts1[ 0 ].position.x, bpts1[ 0 ].position.y, 0.f}, {bpts1[ 0 ].position.x, bpts1[ 0 ].position.y, 0.f},
normalup, { -1.f, 0.f, 0.f },
{0.515625f - d / 2.56f, 0.f} }; // prawy krawężnik u dołu {0.515625f - d / 2.56f, 0.f} }; // prawy krawężnik u dołu
rpts2[ 0 ] = { rpts2[ 0 ] = {
{bpts1[ 1 ].position.x, bpts1[ 1 ].position.y, 0.f}, {bpts1[ 1 ].position.x, bpts1[ 1 ].position.y, 0.f},
normalup, { 1.f, 0.f, 0.f },
{0.484375f + d / 2.56f, 0.f} }; // lewy krawężnik u dołu {0.484375f + d / 2.56f, 0.f} }; // lewy krawężnik u dołu
rpts2[ 1 ] = { rpts2[ 1 ] = {
{bpts1[ 1 ].position.x - d, bpts1[ 1 ].position.y + h1l, 0.f}, {bpts1[ 1 ].position.x - d, bpts1[ 1 ].position.y + h1l, 0.f},
@@ -1776,11 +1777,11 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
{0.515625f, 0.f} }; // prawy krawężnik u góry {0.515625f, 0.f} }; // prawy krawężnik u góry
rpts1[ 5 ] = { rpts1[ 5 ] = {
{bpts1[ 2 ].position.x, bpts1[ 2 ].position.y, 0.f}, {bpts1[ 2 ].position.x, bpts1[ 2 ].position.y, 0.f},
normalup, { -1.f, 0.f, 0.f },
{0.515625f - d / 2.56f, 0.f} }; // prawy krawężnik u dołu {0.515625f - d / 2.56f, 0.f} }; // prawy krawężnik u dołu
rpts2[ 3 ] = { rpts2[ 3 ] = {
{bpts1[ 3 ].position.x, bpts1[ 3 ].position.y, 0.f}, {bpts1[ 3 ].position.x, bpts1[ 3 ].position.y, 0.f},
normalup, { 1.f, 0.f, 0.f },
{0.484375f + d / 2.56f, 0.f} }; // lewy krawężnik u dołu {0.484375f + d / 2.56f, 0.f} }; // lewy krawężnik u dołu
rpts2[ 4 ] = { rpts2[ 4 ] = {
{bpts1[ 3 ].position.x - d, bpts1[ 3 ].position.y + h2l, 0.f}, {bpts1[ 3 ].position.x - d, bpts1[ 3 ].position.y + h2l, 0.f},
@@ -1912,7 +1913,7 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
{ // standardowo: od zewnątrz pochylenie, a od wewnątrz poziomo { // standardowo: od zewnątrz pochylenie, a od wewnątrz poziomo
rpts1[ 0 ] = { rpts1[ 0 ] = {
{rozp, -fTexHeight1, 0.f}, {rozp, -fTexHeight1, 0.f},
normalup, { 1.f, 0.f, 0.f },
{0.f, 0.f} }; // lewy brzeg podstawy {0.f, 0.f} }; // lewy brzeg podstawy
rpts1[ 1 ] = { rpts1[ 1 ] = {
{bpts1[ 0 ].position.x + side, bpts1[ 0 ].position.y, 0.f}, {bpts1[ 0 ].position.x + side, bpts1[ 0 ].position.y, 0.f},
@@ -1932,13 +1933,13 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
{0.5f, 0.f} }; // prawa krawędź załamania {0.5f, 0.f} }; // prawa krawędź załamania
rpts2[ 2 ] = { rpts2[ 2 ] = {
{-rozp, -fTexHeight1, 0.f}, {-rozp, -fTexHeight1, 0.f},
normalup, { -1.f, 0.f, 0.f },
{0.f, 0.f} }; // prawy brzeg podstawy {0.f, 0.f} }; // prawy brzeg podstawy
// if (iTrapezoid) //trapez albo przechyłki // if (iTrapezoid) //trapez albo przechyłki
{ // pobocza do trapezowatej nawierzchni - dodatkowe punkty z drugiej strony odcinka { // pobocza do trapezowatej nawierzchni - dodatkowe punkty z drugiej strony odcinka
rpts1[ 3 ] = { rpts1[ 3 ] = {
{rozp2, -fTexHeight2, 0.f}, {rozp2, -fTexHeight2, 0.f},
normalup, { 1.f, 0.f, 0.f },
{0.f, 0.f} }; // lewy brzeg lewego pobocza {0.f, 0.f} }; // lewy brzeg lewego pobocza
rpts1[ 4 ] = { rpts1[ 4 ] = {
{bpts1[ 2 ].position.x + side2, bpts1[ 2 ].position.y, 0.f}, {bpts1[ 2 ].position.x + side2, bpts1[ 2 ].position.y, 0.f},
@@ -1958,7 +1959,7 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
{0.5f, 0.f} }; {0.5f, 0.f} };
rpts2[ 5 ] = { rpts2[ 5 ] = {
{-rozp2, -fTexHeight2, 0.f}, {-rozp2, -fTexHeight2, 0.f},
normalup, { -1.f, 0.f, 0.f },
{0.f, 0.f} }; // prawy brzeg prawego pobocza {0.f, 0.f} }; // prawy brzeg prawego pobocza
} }
} }
@@ -1987,11 +1988,11 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
{0.515625f, 0.f} }; // prawy krawężnik u góry {0.515625f, 0.f} }; // prawy krawężnik u góry
rpts1[ 2 ] = { rpts1[ 2 ] = {
{bpts1[ 0 ].position.x, bpts1[ 0 ].position.y, 0.f}, {bpts1[ 0 ].position.x, bpts1[ 0 ].position.y, 0.f},
normalup, { -1.f, 0.f, 0.f },
{0.515625f - d / 2.56f, 0.f} }; // prawy krawężnik u dołu {0.515625f - d / 2.56f, 0.f} }; // prawy krawężnik u dołu
rpts2[ 0 ] = { rpts2[ 0 ] = {
{bpts1[ 1 ].position.x, bpts1[ 1 ].position.y, 0.f}, {bpts1[ 1 ].position.x, bpts1[ 1 ].position.y, 0.f},
normalup, { 1.f, 0.f, 0.f },
{0.484375f + d / 2.56f, 0.f} }; // lewy krawężnik u dołu {0.484375f + d / 2.56f, 0.f} }; // lewy krawężnik u dołu
rpts2[ 1 ] = { rpts2[ 1 ] = {
{bpts1[ 1 ].position.x - d, bpts1[ 1 ].position.y - fTexHeight1, 0.f}, {bpts1[ 1 ].position.x - d, bpts1[ 1 ].position.y - fTexHeight1, 0.f},
@@ -2026,11 +2027,11 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
{0.515625f, 0.f} }; // prawy krawężnik u góry {0.515625f, 0.f} }; // prawy krawężnik u góry
rpts1[ 5 ] = { rpts1[ 5 ] = {
{bpts1[ 2 ].position.x, bpts1[ 2 ].position.y, 0.f}, {bpts1[ 2 ].position.x, bpts1[ 2 ].position.y, 0.f},
normalup, { -1.f, 0.f, 0.f },
{0.515625f - d / 2.56f, 0.f} }; // prawy krawężnik u dołu {0.515625f - d / 2.56f, 0.f} }; // prawy krawężnik u dołu
rpts2[ 3 ] = { rpts2[ 3 ] = {
{bpts1[ 3 ].position.x, bpts1[ 3 ].position.y, 0.f}, {bpts1[ 3 ].position.x, bpts1[ 3 ].position.y, 0.f},
normalup, { 1.f, 0.f, 0.f },
{0.484375f + d / 2.56, 0.f} }; // lewy krawężnik u dołu {0.484375f + d / 2.56, 0.f} }; // lewy krawężnik u dołu
rpts2[ 4 ] = { rpts2[ 4 ] = {
{bpts1[ 3 ].position.x - d, bpts1[ 3 ].position.y - fTexHeight2, 0.f}, {bpts1[ 3 ].position.x - d, bpts1[ 3 ].position.y - fTexHeight2, 0.f},
@@ -2664,11 +2665,11 @@ TTrack * TTrack::RaAnimate()
#ifdef EU07_USE_OLD_GROUNDCODE #ifdef EU07_USE_OLD_GROUNDCODE
SwitchExtension->pMyNode->pCenter + SwitchExtension->pMyNode->pCenter +
#else #else
SwitchExtension->pMyNode->area().center + location() +
#endif #endif
SwitchExtension->vTrans; // SwitchExtension->Segments[0]->FastGetPoint(0.5); SwitchExtension->vTrans; // SwitchExtension->Segments[0]->FastGetPoint(0.5);
Segment->Init(middle + vector3(sina, 0.0, cosa), Segment->Init(middle + vector3(sina, 0.0, cosa),
middle - vector3(sina, 0.0, cosa), 5.0); // nowy odcinek middle - vector3(sina, 0.0, cosa), 10.0); // nowy odcinek
for( auto dynamic : Dynamics ) { for( auto dynamic : Dynamics ) {
// minimalny ruch, aby przeliczyć pozycję // minimalny ruch, aby przeliczyć pozycję
dynamic->Move( 0.000001 ); dynamic->Move( 0.000001 );
@@ -2957,18 +2958,19 @@ path_table::InitTracks() {
} }
switch (track->eType) { switch (track->eType) {
/*
// TODO: re-enable // TODO: re-enable
case tt_Table: { case tt_Table: {
// obrotnicę też łączymy na starcie z innymi torami // obrotnicę też łączymy na starcie z innymi torami
// szukamy modelu o tej samej nazwie // szukamy modelu o tej samej nazwie
auto *instance = simulation::Instances.find( trackname ); auto *instance = simulation::Instances.find( trackname );
// wiązanie toru z modelem obrotnicy // wiązanie toru z modelem obrotnicy
#ifdef EU07_USE_OLD_GROUNDCODE
#else
track->RaAssign( track->RaAssign(
Current,
instance, instance,
simulation::Events.FindEvent( trackname + ":done" ), simulation::Events.FindEvent( trackname + ":done" ),
simulation::Events.FindEvent( trackname + ":joined" ) ); simulation::Events.FindEvent( trackname + ":joined" ) );
#endif
if( instance == nullptr ) { if( instance == nullptr ) {
// jak nie ma modelu to pewnie jest wykolejnica, a ta jest domyślnie zamknięta i wykoleja // jak nie ma modelu to pewnie jest wykolejnica, a ta jest domyślnie zamknięta i wykoleja
break; break;
@@ -2976,7 +2978,6 @@ path_table::InitTracks() {
// no break on purpose: // no break on purpose:
// jak coś pójdzie źle, to robimy z tego normalny tor // jak coś pójdzie źle, to robimy z tego normalny tor
} }
*/
case tt_Normal: { case tt_Normal: {
// tylko proste są podłączane do rozjazdów, stąd dwa rozjazdy się nie połączą ze sobą // tylko proste są podłączane do rozjazdów, stąd dwa rozjazdy się nie połączą ze sobą
if( track->CurrentPrev() == nullptr ) { if( track->CurrentPrev() == nullptr ) {

View File

@@ -75,13 +75,11 @@ class TSwitchExtension
}; };
struct struct
{ // zmienne potrzebne tylko dla obrotnicy/przesuwnicy { // zmienne potrzebne tylko dla obrotnicy/przesuwnicy
// TAnimContainer *pAnim; //animator modelu dla obrotnicy
TAnimModel *pModel; // na razie model
#ifdef EU07_USE_OLD_GROUNDCODE #ifdef EU07_USE_OLD_GROUNDCODE
TGroundNode *pMyNode; // dla obrotnicy do wtórnego podłączania torów TGroundNode *pMyNode; // dla obrotnicy do wtórnego podłączania torów
#else
scene::basic_cell *pMyNode; // TODO: convert this to observer pattern
#endif #endif
// TAnimContainer *pAnim; //animator modelu dla obrotnicy
TAnimModel *pModel; // na razie model
}; };
struct struct
{ // zmienne dla skrzyżowania { // zmienne dla skrzyżowania
@@ -270,7 +268,7 @@ public:
#ifdef EU07_USE_OLD_GROUNDCODE #ifdef EU07_USE_OLD_GROUNDCODE
void RaAssign(TGroundNode *gn, TAnimModel *am, TEvent *done, TEvent *joined); void RaAssign(TGroundNode *gn, TAnimModel *am, TEvent *done, TEvent *joined);
#else #else
void RaAssign( scene::basic_cell *gn, TAnimModel *am, TEvent *done, TEvent *joined ); void RaAssign( TAnimModel *am, TEvent *done, TEvent *joined );
#endif #endif
void RaAnimListAdd(TTrack *t); void RaAnimListAdd(TTrack *t);
TTrack * RaAnimate(); TTrack * RaAnimate();

View File

@@ -1312,7 +1312,7 @@ void
TWorld::Update_UI() { TWorld::Update_UI() {
UITable->text_lines.clear(); UITable->text_lines.clear();
std::string uitextline1, uitextline2, uitextline3, uitextline4; std::string uitextline1, uitextline2, uitextline3, uitextline4;
UILayer.set_tooltip( "" ); UILayer.set_tooltip( "" );
if( ( Train != nullptr ) && ( false == FreeFlyModeFlag ) ) { if( ( Train != nullptr ) && ( false == FreeFlyModeFlag ) ) {
@@ -1328,7 +1328,14 @@ TWorld::Update_UI() {
} }
if( ( true == Global::ControlPicking ) && ( true == FreeFlyModeFlag ) && ( true == DebugModeFlag ) ) { if( ( true == Global::ControlPicking ) && ( true == FreeFlyModeFlag ) && ( true == DebugModeFlag ) ) {
auto const scenerynode = GfxRenderer.Pick_Node(); auto const scenerynode = GfxRenderer.Pick_Node();
#ifdef EU07_USE_OLD_GROUNDCODE
UILayer.set_tooltip( ( scenerynode ? scenerynode->asName : "" ) ); UILayer.set_tooltip( ( scenerynode ? scenerynode->asName : "" ) );
#else
UILayer.set_tooltip(
( scenerynode ?
scenerynode->name() :
"" ) );
#endif
} }
switch( Global::iTextMode ) { switch( Global::iTextMode ) {

View File

@@ -21,13 +21,14 @@ http://mozilla.org/MPL/2.0/.
// cParser -- generic class for parsing text data. // cParser -- generic class for parsing text data.
// constructors // constructors
cParser::cParser( std::string const &Stream, buffertype const Type, std::string Path, bool const Loadtraction ) : cParser::cParser( std::string const &Stream, buffertype const Type, std::string Path, bool const Loadtraction, std::vector<std::string> Parameters ) :
mPath(Path), mPath(Path),
LoadTraction( Loadtraction ) { LoadTraction( Loadtraction ) {
// build comments map // build comments map
mComments.insert(commentmap::value_type("/*", "*/")); mComments.insert(commentmap::value_type("/*", "*/"));
mComments.insert(commentmap::value_type("//", "\n")); mComments.insert(commentmap::value_type("//", "\n"));
// mComments.insert(commentmap::value_type("--","\n")); //Ra: to chyba nie używane // mComments.insert(commentmap::value_type("--","\n")); //Ra: to chyba nie używane
// store to calculate sub-sequent includes from relative path // store to calculate sub-sequent includes from relative path
if( Type == buffertype::buffer_FILE ) { if( Type == buffertype::buffer_FILE ) {
mFile = Stream; mFile = Stream;
@@ -59,6 +60,10 @@ cParser::cParser( std::string const &Stream, buffertype const Type, std::string
mLine = 1; mLine = 1;
} }
} }
// set parameter set if one was provided
if( false == Parameters.empty() ) {
parameters.swap( Parameters );
}
} }
// destructor // destructor
@@ -145,86 +150,83 @@ bool cParser::getTokens(unsigned int Count, bool ToLower, const char *Break)
return true; return true;
} }
std::string cParser::readToken(bool ToLower, const char *Break) std::string cParser::readToken( bool ToLower, const char *Break ) {
{
std::string token = "";
size_t pos; // początek podmienianego ciągu
// see if there's include parsing going on. clean up when it's done.
if (mIncludeParser)
{
token = mIncludeParser->readToken(ToLower, Break);
if (!token.empty()) {
while( ( pos = token.find( "(p" ) ) != std::string::npos ) { std::string token;
// check if the token is a parameter which should be replaced with stored true value if( mIncludeParser ) {
auto const parameter { token.substr( pos + 2, token.find( ")", pos ) - ( pos + 2 ) ) }; // numer parametru // see if there's include parsing going on. clean up when it's done.
token.erase(pos, token.find(")", pos) - pos + 1); // najpierw usunięcie "(pN)" token = mIncludeParser->readToken( ToLower, Break );
size_t nr = atoi(parameter.c_str()) - 1; if( true == token.empty() ) {
if (nr < parameters.size()) mIncludeParser = nullptr;
{
token.insert(pos, parameters.at(nr)); // wklejenie wartości parametru
if (ToLower)
for (; pos < parameters.at( nr ).size(); ++pos)
token[pos] = tolower(token[pos]);
}
else
token.insert(pos, "none"); // zabezpieczenie przed brakiem parametru
}
return token;
}
else
{
mIncludeParser = NULL;
parameters.clear();
} }
} }
// get the token yourself if there's no child to delegate it to. if( true == token.empty() ) {
char c { 0 }; // get the token yourself if the delegation attempt failed
do char c { 0 };
{ do {
while (mStream->peek() != EOF && strchr(Break, c = mStream->get()) == NULL) while( mStream->peek() != EOF && strchr( Break, c = mStream->get() ) == NULL ) {
{ if( ToLower )
if (ToLower) c = tolower( c );
c = tolower(c); token += c;
token += c; if( findQuotes( token ) ) // do glue together words enclosed in quotes
if (findQuotes(token)) // do glue together words enclosed in quotes break;
break; if( trimComments( token ) ) // don't glue together words separated with comment
if (trimComments(token)) // don't glue together words separated with comment break;
break; }
if( c == '\n' ) {
// update line counter
++mLine;
}
} while( token == "" && mStream->peek() != EOF ); // double check to deal with trailing spaces
}
if( false == parameters.empty() ) {
// if there's parameter list, check the token for potential parameters to replace
size_t pos; // początek podmienianego ciągu
while( ( pos = token.find( "(p" ) ) != std::string::npos ) {
// check if the token is a parameter which should be replaced with stored true value
auto const parameter{ token.substr( pos + 2, token.find( ")", pos ) - ( pos + 2 ) ) }; // numer parametru
token.erase( pos, token.find( ")", pos ) - pos + 1 ); // najpierw usunięcie "(pN)"
size_t nr = atoi( parameter.c_str() ) - 1;
if( nr < parameters.size() ) {
token.insert( pos, parameters.at( nr ) ); // wklejenie wartości parametru
if( ToLower )
for( ; pos < parameters.at( nr ).size(); ++pos )
token[ pos ] = tolower( token[ pos ] );
}
else
token.insert( pos, "none" ); // zabezpieczenie przed brakiem parametru
} }
if( c == '\n' ) { }
// update line counter
++mLine; if( token == "include" ) {
} // launch child parser if include directive found.
} while (token == "" && mStream->peek() != EOF); // double check to deal with trailing spaces // NOTE: parameter collecting uses default set of token separators.
// launch child parser if include directive found.
// NOTE: parameter collecting uses default set of token separators.
if (token.compare("include") == 0)
{ // obsługa include
std::string includefile = readToken(ToLower); // nazwa pliku std::string includefile = readToken(ToLower); // nazwa pliku
if( ( true == LoadTraction ) if( ( true == LoadTraction )
|| ( ( includefile.find( "tr/" ) == std::string::npos ) || ( ( includefile.find( "tr/" ) == std::string::npos )
&& ( includefile.find( "tra/" ) == std::string::npos ) ) ) { && ( includefile.find( "tra/" ) == std::string::npos ) ) ) {
// get parameter list for the child parser
std::string parameter = readToken(false); // w parametrach nie zmniejszamy std::vector<std::string> includeparameters;
while( (parameter.empty() == false) std::string parameter = readToken( false ); // w parametrach nie zmniejszamy
&& (parameter.compare("end") != 0) ) while( ( parameter.empty() == false )
{ && ( parameter != "end" ) ) {
parameters.emplace_back(parameter); includeparameters.emplace_back( parameter );
parameter = readToken(false); parameter = readToken( false );
}
mIncludeParser = std::make_shared<cParser>( includefile, buffer_FILE, mPath, LoadTraction, includeparameters );
if( mIncludeParser->mSize <= 0 ) {
ErrorLog( "Bad include: can't open file \"" + includefile + "\"" );
} }
// if (trtest2.find("tr/")!=0)
mIncludeParser = std::make_shared<cParser>(includefile, buffer_FILE, mPath, LoadTraction);
if (mIncludeParser->mSize <= 0)
ErrorLog("Bad include: can't open file \"" + includefile + "\"" );
} }
else { else {
while( token.compare( "end" ) != 0 ) { while( token != "end" ) {
token = readToken( true ); // minimize risk of case mismatch on comparison token = readToken( true ); // minimize risk of case mismatch on comparison
} }
} }
token = readToken(ToLower, Break); token = readToken(ToLower, Break);
} }
// all done
return token; return token;
} }

View File

@@ -28,7 +28,7 @@ class cParser //: public std::stringstream
buffer_TEXT buffer_TEXT
}; };
// constructors: // constructors:
cParser(std::string const &Stream, buffertype const Type = buffer_TEXT, std::string Path = "", bool const Loadtraction = true ); cParser(std::string const &Stream, buffertype const Type = buffer_TEXT, std::string Path = "", bool const Loadtraction = true, std::vector<std::string> Parameters = std::vector<std::string>() );
// destructor: // destructor:
virtual ~cParser(); virtual ~cParser();
// methods: // methods:

View File

@@ -2060,7 +2060,6 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
// tracks // tracks
// TODO: update after path node refactoring // TODO: update after path node refactoring
Render( std::begin( cell->m_paths ), std::end( cell->m_paths ) ); Render( std::begin( cell->m_paths ), std::end( cell->m_paths ) );
// TODO: add other content types
// post-render cleanup // post-render cleanup
::glPopMatrix(); ::glPopMatrix();
@@ -2076,7 +2075,8 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
// render // render
// opaque non-instanced shapes // opaque non-instanced shapes
for( auto const &shape : cell->m_shapesopaque ) { Render( shape, false ); } for( auto const &shape : cell->m_shapesopaque ) { Render( shape, false ); }
// TODO: add other content types // tracks
Render( std::begin( cell->m_paths ), std::end( cell->m_paths ) );
// post-render cleanup // post-render cleanup
::glPopMatrix(); ::glPopMatrix();
@@ -2091,6 +2091,7 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
::glTranslated( originoffset.x, originoffset.y, originoffset.z ); ::glTranslated( originoffset.x, originoffset.y, originoffset.z );
// render // render
// opaque non-instanced shapes // opaque non-instanced shapes
// non-interactive scenery elements get neutral colour
::glColor3fv( glm::value_ptr( colors::none ) ); ::glColor3fv( glm::value_ptr( colors::none ) );
for( auto const &shape : cell->m_shapesopaque ) { Render( shape, false ); } for( auto const &shape : cell->m_shapesopaque ) { Render( shape, false ); }
// tracks // tracks
@@ -2099,7 +2100,7 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
::glColor3fv( glm::value_ptr( pick_color( m_picksceneryitems.size() + 1 ) ) ); ::glColor3fv( glm::value_ptr( pick_color( m_picksceneryitems.size() + 1 ) ) );
Render( path ); Render( path );
} }
// TODO: add other content types
// post-render cleanup // post-render cleanup
::glPopMatrix(); ::glPopMatrix();
@@ -2134,11 +2135,12 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
} }
case rendermode::pickscenery: { case rendermode::pickscenery: {
// opaque parts of instanced models // opaque parts of instanced models
// same procedure like with regular render, but each node receives custom colour used for picking
for( auto *instance : cell->m_instancesopaque ) { for( auto *instance : cell->m_instancesopaque ) {
::glColor3fv( glm::value_ptr( pick_color( m_picksceneryitems.size() + 1 ) ) ); ::glColor3fv( glm::value_ptr( pick_color( m_picksceneryitems.size() + 1 ) ) );
Render( instance ); Render( instance );
} }
// TODO: add remaining content types // vehicles aren't included in scenery picking for the time being
break; break;
} }
case rendermode::reflections: case rendermode::reflections:
@@ -2224,19 +2226,18 @@ opengl_renderer::Render( TAnimModel *Instance ) {
|| ( distancesquared >= Instance->m_rangesquaredmax ) ) { || ( distancesquared >= Instance->m_rangesquaredmax ) ) {
return; return;
} }
/*
// TODO: enable adding items to the picking list
switch( m_renderpass.draw_mode ) { switch( m_renderpass.draw_mode ) {
case rendermode::pickscenery: { case rendermode::pickscenery: {
// add the node to the pick list // add the node to the pick list
m_picksceneryitems.emplace_back( Node ); m_picksceneryitems.emplace_back( Instance );
break; break;
} }
default: { default: {
break; break;
} }
} }
*/
Instance->RaAnimate( m_framestamp ); // jednorazowe przeliczenie animacji Instance->RaAnimate( m_framestamp ); // jednorazowe przeliczenie animacji
Instance->RaPrepare(); Instance->RaPrepare();
if( Instance->pModel ) { if( Instance->pModel ) {
@@ -2767,8 +2768,15 @@ opengl_renderer::Render( TTrack *Track ) {
Track->EnvironmentReset(); Track->EnvironmentReset();
break; break;
} }
case rendermode::shadows: case rendermode::shadows: {
// shadow pass includes trackbeds but not tracks themselves due to low resolution of the map
// TODO: implement
break;
}
case rendermode::pickscenery: { case rendermode::pickscenery: {
// add the node to the pick list
m_picksceneryitems.emplace_back( Track );
if( Track->m_material1 != 0 ) { if( Track->m_material1 != 0 ) {
Bind_Material( Track->m_material1 ); Bind_Material( Track->m_material1 );
m_geometry.draw( std::begin( Track->Geometry1 ), std::end( Track->Geometry1 ) ); m_geometry.draw( std::begin( Track->Geometry1 ), std::end( Track->Geometry1 ) );
@@ -2816,12 +2824,8 @@ opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First,
track->EnvironmentReset(); track->EnvironmentReset();
break; break;
} }
case rendermode::shadows: { case rendermode::shadows: // shadows are calculated only for trackbeds
Bind_Material( track->m_material1 ); case rendermode::pickscenery: // pick scenery mode uses piece-by-piece approach
m_geometry.draw( std::begin( track->Geometry1 ), std::end( track->Geometry1 ) );
break;
}
case rendermode::pickscenery: // pick scenery should use track-by-track approach
case rendermode::pickcontrols: case rendermode::pickcontrols:
default: { default: {
break; break;
@@ -2850,11 +2854,16 @@ opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First,
break; break;
} }
case rendermode::shadows: { case rendermode::shadows: {
if( ( track->iCategoryFlag != 1 )
|| ( track->eType != tt_Normal ) ) {
// shadows are only calculated for trackbeds
continue;
}
Bind_Material( track->m_material2 ); Bind_Material( track->m_material2 );
m_geometry.draw( std::begin( track->Geometry2 ), std::end( track->Geometry2 ) ); m_geometry.draw( std::begin( track->Geometry2 ), std::end( track->Geometry2 ) );
break; break;
} }
case rendermode::pickscenery: // pick scenery should use track-by-track approach case rendermode::pickscenery: // pick scenery mode uses piece-by-piece approach
case rendermode::pickcontrols: case rendermode::pickcontrols:
default: { default: {
break; break;
@@ -3121,6 +3130,7 @@ opengl_renderer::Render_Alpha( scene::basic_region *Region ) {
void void
opengl_renderer::Render_Alpha( cell_sequence::reverse_iterator First, cell_sequence::reverse_iterator Last ) { opengl_renderer::Render_Alpha( cell_sequence::reverse_iterator First, cell_sequence::reverse_iterator Last ) {
// NOTE: this method is launched only during color pass therefore we don't bother with mode test here
// first pass draws elements which we know are located in section banks, to reduce vbo switching // first pass draws elements which we know are located in section banks, to reduce vbo switching
{ {
auto first { First }; auto first { First };
@@ -3690,7 +3700,11 @@ opengl_renderer::Update_Pick_Control() {
return control; return control;
} }
#ifdef EU07_USE_OLD_GROUNDCODE
TGroundNode const * TGroundNode const *
#else
editor::basic_node const *
#endif
opengl_renderer::Update_Pick_Node() { opengl_renderer::Update_Pick_Node() {
#ifdef EU07_USE_PICKING_FRAMEBUFFER #ifdef EU07_USE_PICKING_FRAMEBUFFER
@@ -3725,7 +3739,11 @@ opengl_renderer::Update_Pick_Node() {
unsigned char pickreadout[4]; unsigned char pickreadout[4];
::glReadPixels( pickbufferpos.x, pickbufferpos.y, 1, 1, GL_BGRA, GL_UNSIGNED_BYTE, pickreadout ); ::glReadPixels( pickbufferpos.x, pickbufferpos.y, 1, 1, GL_BGRA, GL_UNSIGNED_BYTE, pickreadout );
auto const nodeindex = pick_index( glm::ivec3{ pickreadout[ 2 ], pickreadout[ 1 ], pickreadout[ 0 ] } ); auto const nodeindex = pick_index( glm::ivec3{ pickreadout[ 2 ], pickreadout[ 1 ], pickreadout[ 0 ] } );
#ifdef EU07_USE_OLD_GROUNDCODE
TGroundNode const *node { nullptr }; TGroundNode const *node { nullptr };
#else
editor::basic_node const *node { nullptr };
#endif
if( ( nodeindex > 0 ) if( ( nodeindex > 0 )
&& ( nodeindex <= m_picksceneryitems.size() ) ) { && ( nodeindex <= m_picksceneryitems.size() ) ) {
node = m_picksceneryitems[ nodeindex - 1 ]; node = m_picksceneryitems[ nodeindex - 1 ];

View File

@@ -192,14 +192,22 @@ public:
// utility methods // utility methods
TSubModel const * TSubModel const *
Pick_Control() const { return m_pickcontrolitem; } Pick_Control() const { return m_pickcontrolitem; }
#ifdef EU07_USE_OLD_GROUNDCODE
TGroundNode const * TGroundNode const *
#else
editor::basic_node const *
#endif
Pick_Node() const { return m_picksceneryitem; } Pick_Node() const { return m_picksceneryitem; }
// maintenance jobs // maintenance jobs
void void
Update( double const Deltatime ); Update( double const Deltatime );
TSubModel const * TSubModel const *
Update_Pick_Control(); Update_Pick_Control();
#ifdef EU07_USE_OLD_GROUNDCODE
TGroundNode const * TGroundNode const *
#else
editor::basic_node const *
#endif
Update_Pick_Node(); Update_Pick_Node();
// debug performance string // debug performance string
std::string const & std::string const &
@@ -420,11 +428,15 @@ private:
section_sequence m_sectionqueue; // list of sections in current render pass section_sequence m_sectionqueue; // list of sections in current render pass
cell_sequence m_cellqueue; cell_sequence m_cellqueue;
#endif #endif
std::vector<TGroundNode const *> m_picksceneryitems;
std::vector<TSubModel const *> m_pickcontrolsitems; std::vector<TSubModel const *> m_pickcontrolsitems;
TSubModel const *m_pickcontrolitem { nullptr }; TSubModel const *m_pickcontrolitem { nullptr };
#ifdef EU07_USE_OLD_GROUNDCODE
std::vector<TGroundNode const *> m_picksceneryitems;
TGroundNode const *m_picksceneryitem { nullptr }; TGroundNode const *m_picksceneryitem { nullptr };
#else
std::vector<editor::basic_node const *> m_picksceneryitems;
editor::basic_node const *m_picksceneryitem { nullptr };
#endif
#ifdef EU07_USE_DEBUG_CAMERA #ifdef EU07_USE_DEBUG_CAMERA
renderpass_config m_worldcamera; // debug item renderpass_config m_worldcamera; // debug item
#endif #endif

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#define VERSION_MAJOR 17 #define VERSION_MAJOR 17
#define VERSION_MINOR 1020 #define VERSION_MINOR 1025
#define VERSION_REVISION 0 #define VERSION_REVISION 0