16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-23 13:19:19 +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()
{ // 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
// na kozioł
// ograniczenia prędkości nie są wtedy istotne, również koniec toru jest do niczego nie
// przydatny
// dzięki temu będzie można stawać za wskazanym sygnalizatorem, a zwłaszcza jeśli będzie jazda na kozioł
// 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
if ((OrderList[OrderPos] & ~(Shunt | Connect)))
return cm_Unknown; // skanowanie sygnałów tylko gdy jedzie w trybie manewrowym albo czeka na
// rozkazy
if( ( OrderList[ OrderPos ] & ~( Shunt | Connect ) ) ) {
// skanowanie sygnałów tylko gdy jedzie w trybie manewrowym albo czeka na rozkazy
return cm_Unknown;
}
vector3 sl;
int startdir =
-pVehicles[0]->DirectionGet(); // kierunek jazdy względem sprzęgów pojazdu na czele
if (startdir == 0) // jeśli kabina i kierunek nie jest określony
return cm_Unknown; // nie robimy nic
double scandir =
startdir * pVehicles[0]->RaDirectionGet(); // szukamy od pierwszej osi w wybranym kierunku
if (scandir !=
0.0) // skanowanie toru w poszukiwaniu eventów GetValues (PutValues nie są przydatne)
{ // Ra: przy wstecznym skanowaniu prędkość nie ma znaczenia
// scanback=pVehicles[1]->NextDistance(fLength+1000.0); //odległość do następnego pojazdu,
// 1000 gdy nic nie ma
// 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 nie robimy nic
return cm_Unknown;
}
// szukamy od pierwszej osi w wybranym kierunku
double scandir = startdir * pVehicles[0]->RaDirectionGet();
if (scandir != 0.0) {
// skanowanie toru w poszukiwaniu eventów GetValues (PutValues nie są przydatne)
// Ra: przy wstecznym skanowaniu prędkość nie ma znaczenia
double scanmax = 1000; // 1000m do tyłu, żeby widział przeciwny koniec stacji
double scandist = scanmax; // zmodyfikuje na rzeczywiście przeskanowane
TEvent *e = NULL; // event potencjalnie od semafora
// opcjonalnie może być skanowanie od "wskaźnika" z przodu, np. W5, Tm=Ms1, koniec toru
TTrack *scantrack = BackwardTraceRoute(scandist, scandir, pVehicles[0]->RaTrackGet(),
e); // wg drugiej osi w kierunku ruchu
vector3 dir = startdir * pVehicles[0]->VectorFront(); // wektor w kierunku jazdy/szukania
if (!scantrack) // jeśli wstecz wykryto koniec toru
return cm_Unknown; // to raczej nic się nie da w takiej sytuacji zrobić
else
{ // a jeśli są dalej tory
// 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(), e);
vector3 const dir = startdir * pVehicles[0]->VectorFront(); // wektor w kierunku jazdy/szukania
if( !scantrack ) {
// jeśli wstecz wykryto koniec toru to raczej nic się nie da w takiej sytuacji zrobić
return cm_Unknown;
}
else {
// a jeśli są dalej tory
double vmechmax; // prędkość ustawiona semaforem
if (e)
{ // jeśli jest jakiś sygnał na widoku
if( e != nullptr ) {
// jeśli jest jakiś sygnał na widoku
#if LOGBACKSCAN
AnsiString edir =
pVehicle->asName + " - " + AnsiString((scandir > 0) ? "Event2 " : "Event1 ");
std::string edir {
"Backward scan by "
+ pVehicle->asName + " - "
+ ( ( scandir > 0 ) ?
"Event2 " :
"Event1 " ) };
#endif
// najpierw sprawdzamy, czy semafor czy inny znak został przejechany
vector3 pos = pVehicles[1]->RearPosition(); // pozycja tyłu
@@ -5411,66 +5415,67 @@ TCommandType TController::BackwardScan()
if (e->Type == tp_GetValues)
{ // przesłać info o zbliżającym się semaforze
#if LOGBACKSCAN
edir += "(" + (e->Params[8].asGroundNode->asName) + "): ";
edir += "(" + ( e->asNodeName ) + ")";
#endif
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=e->Params[8].asGroundNode->pCenter-pos; //wektor do komórki pamięci
if (dir.x * sem.x + dir.z * sem.z < 0) // jeśli został minięty
// if ((mvOccupied->CategoryFlag&1)?(VelNext!=0.0):true) //dla pociągu wymagany
// sygnał zezwalający
{ // iloczyn skalarny jest ujemny, gdy sygnał stoi z tyłu
if (dir.x * sem.x + dir.z * sem.z < 0) {
// jeśli został minięty
// iloczyn skalarny jest ujemny, gdy sygnał stoi z tyłu
#if LOGBACKSCAN
WriteLog(edir + "- ignored as not passed yet");
WriteLog(edir + " - ignored as not passed yet");
#endif
return cm_Unknown; // nic
}
vmechmax = e->ValueGet(1); // prędkość przy tym semaforze
// przeliczamy odległość od semafora - potrzebne by były współrzędne początku
// składu
// scandist=(pos-e->Params[8].asGroundNode->pCenter).Length()-0.5*mvOccupied->Dim.L-10;
// //10m luzu
// przeliczamy odległość od semafora - potrzebne by były współrzędne początku składu
scandist = sem.Length() - 2; // 2m luzu przy manewrach wystarczy
if (scandist < 0)
scandist = 0; // ujemnych nie ma po co wysyłać
if( scandist < 0 ) {
// ujemnych nie ma po co wysyłać
scandist = 0;
}
bool move = false; // czy AI w trybie manewerowym ma dociągnąć pod S1
if (e->Command() == cm_SetVelocity)
if ((vmechmax == 0.0) ? (OrderCurrentGet() & (Shunt | Connect)) :
(OrderCurrentGet() &
Connect)) // przy podczepianiu ignorować wyjazd?
if( e->Command() == cm_SetVelocity ) {
if( ( vmechmax == 0.0 ) ?
( OrderCurrentGet() & ( Shunt | Connect ) ) :
( OrderCurrentGet() & Connect ) ) { // przy podczepianiu ignorować wyjazd?
move = true; // AI w trybie manewerowym ma dociągnąć pod S1
else
{ //
if ((scandist > fMinProximityDist) ?
(mvOccupied->Vel > 0.0) && (OrderCurrentGet() != Shunt) :
false)
{ // jeśli semafor jest daleko, a pojazd jedzie, to informujemy o
// zmianie prędkości
// jeśli jedzie manewrowo, musi dostać SetVelocity, żeby sie na pociągowy przełączył
// Mechanik->PutCommand("SetProximityVelocity",scandist,vmechmax,sl);
}
else {
if( ( scandist > fMinProximityDist )
&& ( ( mvOccupied->Vel > 0.0 )
&& ( OrderCurrentGet() != Shunt ) ) ) {
// jeśli semafor jest daleko, a pojazd jedzie, to informujemy o zmianie prędkości
// jeśli jedzie manewrowo, musi dostać SetVelocity, żeby sie na pociągowy przełączył
#if LOGBACKSCAN
// WriteLog(edir+"SetProximityVelocity "+AnsiString(scandist)+"
// "+AnsiString(vmechmax));
// WriteLog(edir+"SetProximityVelocity "+AnsiString(scandist) + AnsiString(vmechmax));
WriteLog(edir);
#endif
// 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
// stać
// if ((MoverParameters->Vel==0.0)||(vmechmax==0.0)) //jeśli stoi lub ma
// stanąć/st
{ // semafor na tym torze albo lokomtywa stoi, a ma ruszyć, albo ma
// stanąć, albo nie ruszać
// stop trzeba powtarzać, bo inaczej zatrąbi i pojedzie sam
// PutCommand("SetVelocity",vmechmax,e->Params[9].asMemCell->Value2(),&sl,stopSem);
else {
// 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 stanąć/stać
// semafor na tym torze albo lokomtywa stoi, a ma ruszyć, albo ma stanąć, albo nie rusz
// stop trzeba powtarzać, bo inaczej zatrąbi i pojedzie sam
// PutCommand("SetVelocity",vmechmax,e->Params[9].asMemCell->Value2(),&sl,stopSem);
#if LOGBACKSCAN
WriteLog(edir + "SetVelocity " + AnsiString(vmechmax) + " " +
AnsiString(e->Params[9].asMemCell->Value2()));
WriteLog(
edir + " - [SetVelocity] ["
+ to_string( vmechmax, 2 ) + "] ["
+ to_string( e->Params[ 9 ].asMemCell->Value2(), 2 ) + "]" );
#endif
return (vmechmax > 0) ? cm_SetVelocity : cm_Unknown;
return (
vmechmax > 0 ?
cm_SetVelocity :
cm_Unknown );
}
}
}
if (OrderCurrentGet() ? OrderCurrentGet() & (Shunt | Connect) :
true) // w Wait_for_orders też widzi tarcze
{ // reakcja AI w trybie manewrowym dodatkowo na sygnały manewrowe
@@ -5497,28 +5502,34 @@ TCommandType TController::BackwardScan()
// to można zmienić kierunek
}
}
else // 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
// if ((MoverParameters->Vel==0.0)||(vmechmax==0.0)) //jeśli jedzie
// lub ma stanąć/stać
else {
// 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
// if ((MoverParameters->Vel==0.0)||(vmechmax==0.0)) //jeśli jedzie lub ma stanąć/stać
{ // 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
WriteLog(edir + "ShuntVelocity " + AnsiString(vmechmax) + " " +
AnsiString(e->ValueGet(2)));
WriteLog(
edir + " - [ShuntVelocity] ["
+ to_string( vmechmax, 2 ) + "] ["
+ to_string( e->ValueGet( 2 ), 2 ) + "]" );
#endif
return (vmechmax > 0) ? cm_ShuntVelocity : cm_Unknown;
return (
vmechmax > 0 ?
cm_ShuntVelocity :
cm_Unknown );
}
}
if ((vmechmax != 0.0) && (scandist < 100.0))
{ // jeśli Tm w odległości do 100m podaje zezwolenie na jazdę, to od
// razu ją ignorujemy, aby móc szukać kolejnej
// eSignSkip=e; //wtedy uznajemy ignorowaną przy poszukiwaniu nowej
if ((vmechmax != 0.0) && (scandist < 100.0)) {
// jeśli Tm w odległości do 100m podaje zezwolenie na jazdę, to od razu ją ignorujemy, aby móc szukać kolejnej
// eSignSkip=e; //wtedy uznajemy ignorowaną przy poszukiwaniu nowej
#if LOGBACKSCAN
WriteLog(edir + "- will be ignored due to Ms2");
WriteLog(edir + " - will be ignored due to Ms2");
#endif
return (vmechmax > 0) ? cm_ShuntVelocity : cm_Unknown;
return (
vmechmax > 0 ?
cm_ShuntVelocity :
cm_Unknown );
}
} // if (move?...
} // 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
// w efekcie drzwi otwierane na zewnątrz będą odlatywac dowolnie daleko :)
// ograniczyłem zakres ruchu funkcją max
if (pAnim->smAnimated)
{
if (pAnim->iNumber & 1)
if (pAnim->smAnimated) {
if( pAnim->iNumber & 1 ) {
pAnim->smAnimated->SetTranslate(
vector3(0, 0, Min0R(dDoorMoveR * pAnim->fSpeed, dDoorMoveR)));
else
vector3{
0.0,
0.0,
dDoorMoveR } );
}
else {
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)
{ // animacja drzwi - odskokprzesuw
if (pAnim->smAnimated)
{
if (pAnim->iNumber & 1)
if (pAnim->smAnimated) {
if( pAnim->iNumber & 1 ) {
pAnim->smAnimated->SetTranslate(
vector3(Min0R(dDoorMoveR * 2, MoverParameters->DoorMaxPlugShift), 0,
Max0R(0, Min0R(dDoorMoveR * pAnim->fSpeed, dDoorMoveR) -
MoverParameters->DoorMaxPlugShift * 0.5f)));
else
vector3 {
std::min(
dDoorMoveR * 2,
MoverParameters->DoorMaxPlugShift ),
0.0,
std::max(
0.0,
dDoorMoveR - MoverParameters->DoorMaxPlugShift * 0.5 ) } );
}
else {
pAnim->smAnimated->SetTranslate(
vector3(Min0R(dDoorMoveL * 2, MoverParameters->DoorMaxPlugShift), 0,
Max0R(0, Min0R(dDoorMoveL * pAnim->fSpeed, dDoorMoveL) -
MoverParameters->DoorMaxPlugShift * 0.5f)));
vector3 {
std::min(
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
{
MoverParameters->Hamulec->SetBrakeStatus( MoverParameters->Hamulec->GetBrakeStatus() | b_dmg ); // wylacz
MoverParameters->Hamulec->ForceEmptiness();
MoverParameters->Hamulec->SetBrakeStatus( MoverParameters->Hamulec->GetBrakeStatus() | b_dmg ); // wylacz
}
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
{
MoverParameters->Hamulec->SetBrakeStatus( MoverParameters->Hamulec->GetBrakeStatus() | b_dmg ); // wylacz
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 (Random(100) < 20) // losowanie 20/100
{
MoverParameters->Hamulec->SetBrakeStatus( MoverParameters->Hamulec->GetBrakeStatus() | b_dmg ); // wylacz
MoverParameters->Hamulec->ForceEmptiness();
MoverParameters->Hamulec->SetBrakeStatus( MoverParameters->Hamulec->GetBrakeStatus() | b_dmg ); // wylacz
}
if (MoverParameters->BrakeCylMult[2] * MoverParameters->BrakeCylMult[1] >
0.01) // jesli jest nastawiacz mechaniczny PL
@@ -5367,7 +5387,6 @@ vehicle_table::update( double Deltatime, int Iterationcount ) {
if( false == vehicle->bEnabled ) { continue; }
// Ra: zmienić warunek na sprawdzanie pantografów w jednej zmiennej: czy pantografy i czy podniesione
if( vehicle->MoverParameters->EnginePowerSource.SourceType == CurrentCollector ) {
// TODO: re-implement
update_traction( vehicle );
}
vehicle->MoverParameters->ComputeConstans();

View File

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

View File

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

View File

@@ -202,3 +202,16 @@ memory_table::InitCells() {
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
void
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
pos1 = glm::dvec3{ FastGetPoint( t ) - Origin }; // wektor początku segmentu
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 )
iEnd = 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);
pos2 = glm::dvec3{ FastGetPoint( t ) - Origin };
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 ) {
for( int j = 0; j < iNumShapePoints; ++j ) {

View File

@@ -583,16 +583,7 @@ void TTrack::Load(cParser *parser, vector3 pOrigin)
>> fTexHeight1
>> fTexWidth
>> 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)
fTexHeight1 = -fTexHeight1; // rzeki mają wysokość odwrotnie niż drogi
}
@@ -1185,13 +1176,15 @@ bool TTrack::InMovement()
#ifdef EU07_USE_OLD_GROUNDCODE
void TTrack::RaAssign(TGroundNode *gn, TAnimModel *am, TEvent *done, TEvent *joined)
#else
void TTrack::RaAssign( scene::basic_cell *gn, TAnimModel *am, TEvent *done, TEvent *joined )
void TTrack::RaAssign( TAnimModel *am, TEvent *done, TEvent *joined )
#endif
{ // Ra: wiązanie toru z modelem obrotnicy
if (eType == tt_Table)
{
SwitchExtension->pModel = am;
#ifdef EU07_USE_OLD_GROUNDCODE
SwitchExtension->pMyNode = gn;
#endif
SwitchExtension->evMinus = done; // event zakończenia animacji (zadanie nowej przedłuża)
SwitchExtension->evPlus =
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;
glm::vec3 const normalup{ 0.f, 1.f, 0.f };
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;
float fHTW2, side2, slop2, rozp2, fTexHeight2, hypot2;
if( iTrapezoid & 2 ) {
@@ -1232,6 +1229,10 @@ void TTrack::create_geometry( geometrybank_handle const &Bank ) {
if( hypot2 == 0.f )
hypot2 = 1.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 {
// 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
rpts1[ 0 ] = {
{rozp, -fTexHeight1, 0.f},
normalup,
{ 1.f, 0.f, 0.f },
{0.f, 0.f} }; // lewy brzeg podstawy
rpts1[ 1 ] = {
{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
rpts2[ 2 ] = {
{-rozp, -fTexHeight1, 0.f},
normalup,
{ -1.f, 0.f, 0.f },
{0.f, 0.f} }; // prawy brzeg podstawy
if (iTrapezoid) {
// pobocza do trapezowatej nawierzchni - dodatkowe punkty z drugiej strony odcinka
rpts1[ 3 ] = {
{rozp2, -fTexHeight2, 0.f},
normalup,
{ 1.f, 0.f, 0.f },
{0.f, 0.f} }; // lewy brzeg lewego pobocza
rpts1[ 4 ] = {
{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} };
rpts2[ 5 ] = {
{-rozp2, -fTexHeight2, 0.f},
normalup,
{ -1.f, 0.f, 0.f },
{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
rpts1[ 2 ] = {
{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
rpts2[ 0 ] = {
{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
rpts2[ 1 ] = {
{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
rpts1[ 5 ] = {
{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
rpts2[ 3 ] = {
{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
rpts2[ 4 ] = {
{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
rpts1[ 0 ] = {
{rozp, -fTexHeight1, 0.f},
normalup,
{ 1.f, 0.f, 0.f },
{0.f, 0.f} }; // lewy brzeg podstawy
rpts1[ 1 ] = {
{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
rpts2[ 2 ] = {
{-rozp, -fTexHeight1, 0.f},
normalup,
{ -1.f, 0.f, 0.f },
{0.f, 0.f} }; // prawy brzeg podstawy
// if (iTrapezoid) //trapez albo przechyłki
{ // pobocza do trapezowatej nawierzchni - dodatkowe punkty z drugiej strony odcinka
rpts1[ 3 ] = {
{rozp2, -fTexHeight2, 0.f},
normalup,
{ 1.f, 0.f, 0.f },
{0.f, 0.f} }; // lewy brzeg lewego pobocza
rpts1[ 4 ] = {
{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} };
rpts2[ 5 ] = {
{-rozp2, -fTexHeight2, 0.f},
normalup,
{ -1.f, 0.f, 0.f },
{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
rpts1[ 2 ] = {
{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
rpts2[ 0 ] = {
{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
rpts2[ 1 ] = {
{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
rpts1[ 5 ] = {
{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
rpts2[ 3 ] = {
{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
rpts2[ 4 ] = {
{bpts1[ 3 ].position.x - d, bpts1[ 3 ].position.y - fTexHeight2, 0.f},
@@ -2664,11 +2665,11 @@ TTrack * TTrack::RaAnimate()
#ifdef EU07_USE_OLD_GROUNDCODE
SwitchExtension->pMyNode->pCenter +
#else
SwitchExtension->pMyNode->area().center +
location() +
#endif
SwitchExtension->vTrans; // SwitchExtension->Segments[0]->FastGetPoint(0.5);
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 ) {
// minimalny ruch, aby przeliczyć pozycję
dynamic->Move( 0.000001 );
@@ -2957,18 +2958,19 @@ path_table::InitTracks() {
}
switch (track->eType) {
/*
// TODO: re-enable
case tt_Table: {
// obrotnicę też łączymy na starcie z innymi torami
// szukamy modelu o tej samej nazwie
auto *instance = simulation::Instances.find( trackname );
// wiązanie toru z modelem obrotnicy
#ifdef EU07_USE_OLD_GROUNDCODE
#else
track->RaAssign(
Current,
instance,
simulation::Events.FindEvent( trackname + ":done" ),
simulation::Events.FindEvent( trackname + ":joined" ) );
#endif
if( instance == nullptr ) {
// jak nie ma modelu to pewnie jest wykolejnica, a ta jest domyślnie zamknięta i wykoleja
break;
@@ -2976,7 +2978,6 @@ path_table::InitTracks() {
// no break on purpose:
// jak coś pójdzie źle, to robimy z tego normalny tor
}
*/
case tt_Normal: {
// tylko proste są podłączane do rozjazdów, stąd dwa rozjazdy się nie połączą ze sobą
if( track->CurrentPrev() == nullptr ) {

View File

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

View File

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

View File

@@ -21,13 +21,14 @@ http://mozilla.org/MPL/2.0/.
// cParser -- generic class for parsing text data.
// 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),
LoadTraction( Loadtraction ) {
// build comments map
mComments.insert(commentmap::value_type("/*", "*/"));
mComments.insert(commentmap::value_type("//", "\n"));
// mComments.insert(commentmap::value_type("--","\n")); //Ra: to chyba nie używane
// store to calculate sub-sequent includes from relative path
if( Type == buffertype::buffer_FILE ) {
mFile = Stream;
@@ -59,6 +60,10 @@ cParser::cParser( std::string const &Stream, buffertype const Type, std::string
mLine = 1;
}
}
// set parameter set if one was provided
if( false == Parameters.empty() ) {
parameters.swap( Parameters );
}
}
// destructor
@@ -145,86 +150,83 @@ bool cParser::getTokens(unsigned int Count, bool ToLower, const char *Break)
return true;
}
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()) {
std::string cParser::readToken( bool ToLower, const char *Break ) {
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
}
return token;
}
else
{
mIncludeParser = NULL;
parameters.clear();
std::string token;
if( mIncludeParser ) {
// see if there's include parsing going on. clean up when it's done.
token = mIncludeParser->readToken( ToLower, Break );
if( true == token.empty() ) {
mIncludeParser = nullptr;
}
}
// get the token yourself if there's no child to delegate it to.
char c { 0 };
do
{
while (mStream->peek() != EOF && strchr(Break, c = mStream->get()) == NULL)
{
if (ToLower)
c = tolower(c);
token += c;
if (findQuotes(token)) // do glue together words enclosed in quotes
break;
if (trimComments(token)) // don't glue together words separated with comment
break;
if( true == token.empty() ) {
// get the token yourself if the delegation attempt failed
char c { 0 };
do {
while( mStream->peek() != EOF && strchr( Break, c = mStream->get() ) == NULL ) {
if( ToLower )
c = tolower( c );
token += c;
if( findQuotes( token ) ) // do glue together words enclosed in quotes
break;
if( trimComments( token ) ) // don't glue together words separated with comment
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;
}
} while (token == "" && mStream->peek() != EOF); // double check to deal with trailing spaces
// launch child parser if include directive found.
// NOTE: parameter collecting uses default set of token separators.
if (token.compare("include") == 0)
{ // obsługa include
}
if( token == "include" ) {
// launch child parser if include directive found.
// NOTE: parameter collecting uses default set of token separators.
std::string includefile = readToken(ToLower); // nazwa pliku
if( ( true == LoadTraction )
|| ( ( includefile.find( "tr/" ) == std::string::npos )
&& ( includefile.find( "tra/" ) == std::string::npos ) ) ) {
std::string parameter = readToken(false); // w parametrach nie zmniejszamy
while( (parameter.empty() == false)
&& (parameter.compare("end") != 0) )
{
parameters.emplace_back(parameter);
parameter = readToken(false);
// get parameter list for the child parser
std::vector<std::string> includeparameters;
std::string parameter = readToken( false ); // w parametrach nie zmniejszamy
while( ( parameter.empty() == false )
&& ( parameter != "end" ) ) {
includeparameters.emplace_back( parameter );
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 {
while( token.compare( "end" ) != 0 ) {
while( token != "end" ) {
token = readToken( true ); // minimize risk of case mismatch on comparison
}
}
token = readToken(ToLower, Break);
}
// all done
return token;
}

View File

@@ -28,7 +28,7 @@ class cParser //: public std::stringstream
buffer_TEXT
};
// 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:
virtual ~cParser();
// methods:

View File

@@ -2060,7 +2060,6 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
// tracks
// TODO: update after path node refactoring
Render( std::begin( cell->m_paths ), std::end( cell->m_paths ) );
// TODO: add other content types
// post-render cleanup
::glPopMatrix();
@@ -2076,7 +2075,8 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
// render
// opaque non-instanced shapes
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
::glPopMatrix();
@@ -2091,6 +2091,7 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
// render
// opaque non-instanced shapes
// non-interactive scenery elements get neutral colour
::glColor3fv( glm::value_ptr( colors::none ) );
for( auto const &shape : cell->m_shapesopaque ) { Render( shape, false ); }
// 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 ) ) );
Render( path );
}
// TODO: add other content types
// post-render cleanup
::glPopMatrix();
@@ -2134,11 +2135,12 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
}
case rendermode::pickscenery: {
// 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 ) {
::glColor3fv( glm::value_ptr( pick_color( m_picksceneryitems.size() + 1 ) ) );
Render( instance );
}
// TODO: add remaining content types
// vehicles aren't included in scenery picking for the time being
break;
}
case rendermode::reflections:
@@ -2224,19 +2226,18 @@ opengl_renderer::Render( TAnimModel *Instance ) {
|| ( distancesquared >= Instance->m_rangesquaredmax ) ) {
return;
}
/*
// TODO: enable adding items to the picking list
switch( m_renderpass.draw_mode ) {
case rendermode::pickscenery: {
// add the node to the pick list
m_picksceneryitems.emplace_back( Node );
m_picksceneryitems.emplace_back( Instance );
break;
}
default: {
break;
}
}
*/
Instance->RaAnimate( m_framestamp ); // jednorazowe przeliczenie animacji
Instance->RaPrepare();
if( Instance->pModel ) {
@@ -2767,8 +2768,15 @@ opengl_renderer::Render( TTrack *Track ) {
Track->EnvironmentReset();
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: {
// add the node to the pick list
m_picksceneryitems.emplace_back( Track );
if( Track->m_material1 != 0 ) {
Bind_Material( Track->m_material1 );
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();
break;
}
case rendermode::shadows: {
Bind_Material( track->m_material1 );
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::shadows: // shadows are calculated only for trackbeds
case rendermode::pickscenery: // pick scenery mode uses piece-by-piece approach
case rendermode::pickcontrols:
default: {
break;
@@ -2850,11 +2854,16 @@ opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First,
break;
}
case rendermode::shadows: {
if( ( track->iCategoryFlag != 1 )
|| ( track->eType != tt_Normal ) ) {
// shadows are only calculated for trackbeds
continue;
}
Bind_Material( track->m_material2 );
m_geometry.draw( std::begin( track->Geometry2 ), std::end( track->Geometry2 ) );
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:
default: {
break;
@@ -3121,6 +3130,7 @@ opengl_renderer::Render_Alpha( scene::basic_region *Region ) {
void
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
{
auto first { First };
@@ -3690,7 +3700,11 @@ opengl_renderer::Update_Pick_Control() {
return control;
}
#ifdef EU07_USE_OLD_GROUNDCODE
TGroundNode const *
#else
editor::basic_node const *
#endif
opengl_renderer::Update_Pick_Node() {
#ifdef EU07_USE_PICKING_FRAMEBUFFER
@@ -3725,7 +3739,11 @@ opengl_renderer::Update_Pick_Node() {
unsigned char pickreadout[4];
::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 ] } );
#ifdef EU07_USE_OLD_GROUNDCODE
TGroundNode const *node { nullptr };
#else
editor::basic_node const *node { nullptr };
#endif
if( ( nodeindex > 0 )
&& ( nodeindex <= m_picksceneryitems.size() ) ) {
node = m_picksceneryitems[ nodeindex - 1 ];

View File

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

View File

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