16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-23 20:19:19 +02:00

switches for local converter and compressor, motor connector fix for multi-unit engines, crossroad generation fixes for vbo render path

This commit is contained in:
tmj-fstate
2017-05-23 02:25:56 +02:00
parent e805533f54
commit 9f07e2b504
16 changed files with 425 additions and 249 deletions

View File

@@ -869,8 +869,9 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
// if (p7&3) //żeby jeszcze poczekał chwilę, zanim zamknie // if (p7&3) //żeby jeszcze poczekał chwilę, zanim zamknie
// WaitingSet(10); //10 sekund (wziąć z rozkładu????) // WaitingSet(10); //10 sekund (wziąć z rozkładu????)
} }
if (fStopTime > -5) // na końcu rozkładu się ustawia 60s i tu by było skrócenie
WaitingSet(10); // 10 sekund (wziąć z rozkładu????) - czekanie if( fStopTime > -5 ) // na końcu rozkładu się ustawia 60s i tu by było skrócenie
WaitingSet( 15.0 + Random( 15.0 ) ); // 10 sekund (wziąć z rozkładu????) - czekanie
// niezależne od sposobu obsługi drzwi, bo opóźnia również kierownika // niezależne od sposobu obsługi drzwi, bo opóźnia również kierownika
} }
if (TrainParams->UpdateMTable( simulation::Time, asNextStop) ) if (TrainParams->UpdateMTable( simulation::Time, asNextStop) )
@@ -980,11 +981,10 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
sSpeedTable[i].fVelNext = -1; // można jechać za W4 sSpeedTable[i].fVelNext = -1; // można jechać za W4
fLastStopExpDist = -1.0f; // nie ma rozkładu, nie ma usuwania stacji fLastStopExpDist = -1.0f; // nie ma rozkładu, nie ma usuwania stacji
WaitingSet(60); // tak ze 2 minuty, aż wszyscy wysiądą WaitingSet(60); // tak ze 2 minuty, aż wszyscy wysiądą
JumpToNextOrder(); // wykonanie kolejnego rozkazu (Change_direction // wykonanie kolejnego rozkazu (Change_direction albo Shunt)
// albo Shunt) JumpToNextOrder();
iDrivigFlags |= moveStopHere | moveStartHorn; // ma się nie ruszać // ma się nie ruszać aż do momentu podania sygnału
// aż do momentu iDrivigFlags |= moveStopHere | moveStartHorn;
// podania sygnału
continue; // nie analizować prędkości continue; // nie analizować prędkości
} // koniec obsługi ostatniej stacji } // koniec obsługi ostatniej stacji
} // if (MoverParameters->Vel==0.0) } // if (MoverParameters->Vel==0.0)
@@ -4142,6 +4142,7 @@ bool TController::UpdateSituation(double dt)
->TTVmax); // jesli nie spozniony to nie przekraczać rozkladowej ->TTVmax); // jesli nie spozniony to nie przekraczać rozkladowej
if (VelDesired > 0.0) if (VelDesired > 0.0)
if( ( ( SemNextIndex != -1 ) if( ( ( SemNextIndex != -1 )
&& ( SemNextIndex < sSpeedTable.size() ) // BUG: index can point at non-existing slot. investigate reason(s)
&& ( sSpeedTable[SemNextIndex].fVelNext != 0.0 ) ) && ( sSpeedTable[SemNextIndex].fVelNext != 0.0 ) )
|| ( ( iDrivigFlags & moveStopHere ) == 0 ) ) || ( ( iDrivigFlags & moveStopHere ) == 0 ) )
{ // jeśli można jechać, to odpalić dźwięk kierownika oraz zamknąć drzwi w { // jeśli można jechać, to odpalić dźwięk kierownika oraz zamknąć drzwi w

View File

@@ -787,7 +787,6 @@ void TSubRect::LoadNodes()
return; // jeśli nie ma obiektów do wyświetlenia z VBO, to koniec return; // jeśli nie ma obiektów do wyświetlenia z VBO, to koniec
if (Global::bUseVBO) if (Global::bUseVBO)
{ // tylko liczenie wierzchołów, gdy nie ma VBO { // tylko liczenie wierzchołów, gdy nie ma VBO
int debugvertexcount{ 0 };
MakeArray(m_nVertexCount); MakeArray(m_nVertexCount);
n = nRootNode; n = nRootNode;
int i; int i;
@@ -809,9 +808,7 @@ void TSubRect::LoadNodes()
m_pVNT[n->iVboPtr + i].nz = n->Vertices[i].Normal.z; m_pVNT[n->iVboPtr + i].nz = n->Vertices[i].Normal.z;
m_pVNT[n->iVboPtr + i].u = n->Vertices[i].tu; m_pVNT[n->iVboPtr + i].u = n->Vertices[i].tu;
m_pVNT[n->iVboPtr + i].v = n->Vertices[i].tv; m_pVNT[n->iVboPtr + i].v = n->Vertices[i].tv;
++debugvertexcount;
} }
assert( debugvertexcount <= m_nVertexCount );
break; break;
case GL_LINES: case GL_LINES:
case GL_LINE_STRIP: case GL_LINE_STRIP:
@@ -822,34 +819,24 @@ void TSubRect::LoadNodes()
m_pVNT[n->iVboPtr + i].y = n->Points[i].y; m_pVNT[n->iVboPtr + i].y = n->Points[i].y;
m_pVNT[n->iVboPtr + i].z = n->Points[i].z; m_pVNT[n->iVboPtr + i].z = n->Points[i].z;
// miejsce w tablicach normalnych i teksturowania się marnuje... // miejsce w tablicach normalnych i teksturowania się marnuje...
++debugvertexcount;
} }
assert( debugvertexcount <= m_nVertexCount );
break; break;
case TP_TRACK: case TP_TRACK:
if( n->iNumVerts ) { // bo tory zabezpieczające są niewidoczne if( n->iNumVerts ) { // bo tory zabezpieczające są niewidoczne
#ifdef EU07_USE_OLD_VERTEXBUFFER #ifdef EU07_USE_OLD_VERTEXBUFFER
int const batch = n->pTrack->RaArrayFill( m_pVNT + n->iVboPtr, m_pVNT, std::min( n->iNumVerts, m_nVertexCount - n->iVboPtr ) ); n->pTrack->RaArrayFill( m_pVNT + n->iVboPtr, m_pVNT, std::min( n->iNumVerts, m_nVertexCount - n->iVboPtr ) );
#else #else
int const batch = n->pTrack->RaArrayFill( m_pVNT.data() + n->iVboPtr, m_pVNT.data(), std::min( n->iNumVerts, m_nVertexCount - n->iVboPtr ) ); n->pTrack->RaArrayFill( m_pVNT.data() + n->iVboPtr, m_pVNT.data(), std::min( n->iNumVerts, m_nVertexCount - n->iVboPtr ) );
#endif #endif
assert( batch == n->iNumVerts );
assert( batch + n->iVboPtr <= m_nVertexCount );
debugvertexcount += batch;
assert( debugvertexcount <= m_nVertexCount );
} }
break; break;
case TP_TRACTION: case TP_TRACTION:
if( n->iNumVerts ) { // druty mogą być niewidoczne...? if( n->iNumVerts ) { // druty mogą być niewidoczne...?
#ifdef EU07_USE_OLD_VERTEXBUFFER #ifdef EU07_USE_OLD_VERTEXBUFFER
int const batch = n->hvTraction->RaArrayFill( m_pVNT + n->iVboPtr ); n->hvTraction->RaArrayFill( m_pVNT + n->iVboPtr );
#else #else
int const batch = n->hvTraction->RaArrayFill( m_pVNT.data() + n->iVboPtr ); n->hvTraction->RaArrayFill( m_pVNT.data() + n->iVboPtr );
#endif #endif
assert( batch == n->iNumVerts );
assert( batch + n->iVboPtr <= m_nVertexCount );
debugvertexcount += batch;
assert( debugvertexcount <= m_nVertexCount );
} }
break; break;
} }
@@ -1333,17 +1320,14 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
TGroundNode *tmp1; TGroundNode *tmp1;
TTrack *Track; TTrack *Track;
std::string token; std::string token;
parser->getTokens(2); parser->getTokens(4);
*parser >> r >> rmin; *parser
parser->getTokens(); >> r
*parser >> token; >> rmin
asNodeName = token; >> asNodeName
parser->getTokens(); >> str;
*parser >> token;
str = token;
//str = AnsiString(token.c_str()); //str = AnsiString(token.c_str());
TGroundNode *tmp; TGroundNode *tmp = new TGroundNode();
tmp = new TGroundNode();
tmp->asName = (asNodeName == "none" ? "" : asNodeName); tmp->asName = (asNodeName == "none" ? "" : asNodeName);
if (r >= 0) if (r >= 0)
tmp->fSquareRadius = r * r; tmp->fSquareRadius = r * r;
@@ -2186,7 +2170,7 @@ bool TGround::Init(std::string File)
if (!LastNode->Vertices) if (!LastNode->Vertices)
SafeDelete(LastNode); // usuwamy nieprzezroczyste trójkąty terenu SafeDelete(LastNode); // usuwamy nieprzezroczyste trójkąty terenu
} }
else if (Global::bLoadTraction ? false : LastNode->iType == TP_TRACTION) else if ( ( LastNode->iType == TP_TRACTION ) && ( false == Global::bLoadTraction ) )
SafeDelete(LastNode); // usuwamy druty, jeśli wyłączone SafeDelete(LastNode); // usuwamy druty, jeśli wyłączone
if (LastNode) // dopiero na koniec dopisujemy do tablic if (LastNode) // dopiero na koniec dopisujemy do tablic
if (LastNode->iType != TP_DYNAMIC) if (LastNode->iType != TP_DYNAMIC)

View File

@@ -847,12 +847,14 @@ public:
bool CompressorFlag = false; /*!o czy wlaczona sprezarka*/ bool CompressorFlag = false; /*!o czy wlaczona sprezarka*/
bool PantCompFlag = false; /*!o czy wlaczona sprezarka pantografow*/ bool PantCompFlag = false; /*!o czy wlaczona sprezarka pantografow*/
bool CompressorAllow = false; /*! zezwolenie na uruchomienie sprezarki NBMX*/ bool CompressorAllow = false; /*! zezwolenie na uruchomienie sprezarki NBMX*/
bool CompressorAllowLocal{ true }; // local device state override (most units don't have this fitted so it's set to true not to intefere)
bool CompressorGovernorLock{ false }; // indicates whether compressor pressure switch was activated due to reaching cut-out pressure bool CompressorGovernorLock{ false }; // indicates whether compressor pressure switch was activated due to reaching cut-out pressure
// TODO converter parameters, for when we start cleaning up mover parameters // TODO converter parameters, for when we start cleaning up mover parameters
start ConverterStart{ manual }; // whether converter is started manually, or by other means start ConverterStart{ manual }; // whether converter is started manually, or by other means
float ConverterStartDelay{ 0.0f }; // delay (in seconds) before the converter is started, once its activation conditions are met float ConverterStartDelay{ 0.0f }; // delay (in seconds) before the converter is started, once its activation conditions are met
double ConverterStartDelayTimer{ 0.0 }; // helper, for tracking whether converter start delay passed double ConverterStartDelayTimer{ 0.0 }; // helper, for tracking whether converter start delay passed
bool ConverterAllow = false; /*zezwolenie na prace przetwornicy NBMX*/ bool ConverterAllow = false; /*zezwolenie na prace przetwornicy NBMX*/
bool ConverterAllowLocal{ true }; // local device state override (most units don't have this fitted so it's set to true not to intefere)
bool ConverterFlag = false; /*! czy wlaczona przetwornica NBMX*/ bool ConverterFlag = false; /*! czy wlaczona przetwornica NBMX*/
int BrakeCtrlPos = -2; /*nastawa hamulca zespolonego*/ int BrakeCtrlPos = -2; /*nastawa hamulca zespolonego*/
@@ -978,8 +980,10 @@ public:
int PantRearStart = 0; int PantRearStart = 0;
double PantFrontVolt = 0.0; //pantograf pod napieciem? 'Winger 160404 double PantFrontVolt = 0.0; //pantograf pod napieciem? 'Winger 160404
double PantRearVolt = 0.0; double PantRearVolt = 0.0;
// TODO: move these switch types where they belong, cabin definition
std::string PantSwitchType; std::string PantSwitchType;
std::string ConvSwitchType; std::string ConvSwitchType;
std::string StLinSwitchType;
bool Heating = false; //ogrzewanie 'Winger 020304 bool Heating = false; //ogrzewanie 'Winger 020304
int DoubleTr = 1; //trakcja ukrotniona - przedni pojazd 'Winger 160304 int DoubleTr = 1; //trakcja ukrotniona - przedni pojazd 'Winger 160304

View File

@@ -1565,6 +1565,7 @@ double TMoverParameters::ShowEngineRotation(int VehN)
void TMoverParameters::ConverterCheck( double const Timestep ) { void TMoverParameters::ConverterCheck( double const Timestep ) {
// TODO: move other converter checks here, to have it all in one place for potential device object // TODO: move other converter checks here, to have it all in one place for potential device object
if( ( ConverterAllow ) if( ( ConverterAllow )
&& ( ConverterAllowLocal )
&& ( false == PantPressLockActive ) && ( false == PantPressLockActive )
&& ( Mains ) ) { && ( Mains ) ) {
// delay timer can be optionally configured, and is set anew whenever converter goes off // delay timer can be optionally configured, and is set anew whenever converter goes off
@@ -3018,7 +3019,7 @@ void TMoverParameters::CompressorCheck(double dt)
if (MaxCompressor - MinCompressor < 0.0001) if (MaxCompressor - MinCompressor < 0.0001)
{ {
// if (Mains && (MainCtrlPos > 1)) // if (Mains && (MainCtrlPos > 1))
if (CompressorAllow && Mains && (MainCtrlPos > 0)) if (CompressorAllow && CompressorAllowLocal && Mains && (MainCtrlPos > 0))
{ {
if (Compressor < MaxCompressor) if (Compressor < MaxCompressor)
if ((EngineType == DieselElectric) && (CompressorPower > 0)) if ((EngineType == DieselElectric) && (CompressorPower > 0))
@@ -3048,8 +3049,10 @@ void TMoverParameters::CompressorCheck(double dt)
{ // zasilanie sprężarki w członie ra z członu silnikowego (sprzęg 1) { // zasilanie sprężarki w członie ra z członu silnikowego (sprzęg 1)
if (Couplers[1].Connected != NULL) if (Couplers[1].Connected != NULL)
CompressorFlag = CompressorFlag =
(Couplers[1].Connected->CompressorAllow && ( Couplers[ 1 ].Connected->CompressorAllow
Couplers[1].Connected->ConverterFlag && Couplers[1].Connected->Mains); && Couplers[ 1 ].Connected->CompressorAllowLocal
&& Couplers[ 1 ].Connected->Mains
&& Couplers[ 1 ].Connected->ConverterFlag );
else else
CompressorFlag = false; // bez tamtego członu nie zadziała CompressorFlag = false; // bez tamtego członu nie zadziała
} }
@@ -3057,14 +3060,17 @@ void TMoverParameters::CompressorCheck(double dt)
{ // zasilanie sprężarki w członie ra z członu silnikowego (sprzęg 1) { // zasilanie sprężarki w członie ra z członu silnikowego (sprzęg 1)
if (Couplers[0].Connected != NULL) if (Couplers[0].Connected != NULL)
CompressorFlag = CompressorFlag =
(Couplers[0].Connected->CompressorAllow && ( Couplers[ 0 ].Connected->CompressorAllow
Couplers[0].Connected->ConverterFlag && Couplers[0].Connected->Mains); && Couplers[ 0 ].Connected->CompressorAllowLocal
&& Couplers[ 0 ].Connected->Mains
&& Couplers[ 0 ].Connected->ConverterFlag );
else else
CompressorFlag = false; // bez tamtego członu nie zadziała CompressorFlag = false; // bez tamtego członu nie zadziała
} }
else else
CompressorFlag = CompressorFlag =
( ( CompressorAllow ) ( ( CompressorAllow )
&& ( CompressorAllowLocal )
&& ( Mains ) && ( Mains )
&& ( ( ConverterFlag ) && ( ( ConverterFlag )
|| ( CompressorPower == 0 ) ) ); || ( CompressorPower == 0 ) ) );
@@ -3080,12 +3086,12 @@ void TMoverParameters::CompressorCheck(double dt)
// for these multi-unit engines compressors turn off whenever any of them was affected by the governor // for these multi-unit engines compressors turn off whenever any of them was affected by the governor
// NOTE: this is crude implementation, TODO: re-implement when a more elegant/flexible system is in place // NOTE: this is crude implementation, TODO: re-implement when a more elegant/flexible system is in place
if( ( Couplers[ 1 ].Connected != nullptr ) if( ( Couplers[ 1 ].Connected != nullptr )
&& ( true == TestFlag( Couplers[ 1 ].CouplingFlag, coupling::permanent ) ) ) { && ( true == TestFlag( Couplers[ 1 ].CouplingFlag, coupling::permanent ) ) ) {
// the first unit isn't allowed to start its compressor until second unit can start its own as well // the first unit isn't allowed to start its compressor until second unit can start its own as well
CompressorFlag &= ( Couplers[ 1 ].Connected->CompressorGovernorLock == false ); CompressorFlag &= ( Couplers[ 1 ].Connected->CompressorGovernorLock == false );
} }
if( ( Couplers[ 0 ].Connected != nullptr ) if( ( Couplers[ 0 ].Connected != nullptr )
&& ( true == TestFlag( Couplers[ 0 ].CouplingFlag, coupling::permanent ) ) ) { && ( true == TestFlag( Couplers[ 0 ].CouplingFlag, coupling::permanent ) ) ) {
// the second unit isn't allowed to start its compressor until first unit can start its own as well // the second unit isn't allowed to start its compressor until first unit can start its own as well
CompressorFlag &= ( Couplers[ 0 ].Connected->CompressorGovernorLock == false ); CompressorFlag &= ( Couplers[ 0 ].Connected->CompressorGovernorLock == false );
} }
@@ -3110,8 +3116,9 @@ void TMoverParameters::CompressorCheck(double dt)
if( Couplers[ 1 ].Connected != nullptr ) { if( Couplers[ 1 ].Connected != nullptr ) {
CompressorFlag = CompressorFlag =
( Couplers[ 1 ].Connected->CompressorAllow ( Couplers[ 1 ].Connected->CompressorAllow
&& Couplers[ 1 ].Connected->ConverterFlag && Couplers[ 1 ].Connected->CompressorAllowLocal
&& Couplers[ 1 ].Connected->Mains ); && Couplers[ 1 ].Connected->Mains
&& Couplers[ 1 ].Connected->ConverterFlag );
} }
else { else {
CompressorFlag = false; // bez tamtego członu nie zadziała CompressorFlag = false; // bez tamtego członu nie zadziała
@@ -3122,8 +3129,9 @@ void TMoverParameters::CompressorCheck(double dt)
if( Couplers[ 0 ].Connected != nullptr ) { if( Couplers[ 0 ].Connected != nullptr ) {
CompressorFlag = CompressorFlag =
( Couplers[ 0 ].Connected->CompressorAllow ( Couplers[ 0 ].Connected->CompressorAllow
&& Couplers[ 0 ].Connected->ConverterFlag && Couplers[ 0 ].Connected->CompressorAllowLocal
&& Couplers[ 0 ].Connected->Mains ); && Couplers[ 0 ].Connected->Mains
&& Couplers[ 0 ].Connected->ConverterFlag );
} }
else { else {
CompressorFlag = false; // bez tamtego członu nie zadziała CompressorFlag = false; // bez tamtego członu nie zadziała
@@ -3132,6 +3140,7 @@ void TMoverParameters::CompressorCheck(double dt)
else { else {
CompressorFlag = CompressorFlag =
( ( CompressorAllow ) ( ( CompressorAllow )
&& ( CompressorAllowLocal )
&& ( Mains ) && ( Mains )
&& ( ( ConverterFlag ) && ( ( ConverterFlag )
|| ( CompressorPower == 0 ) ) ); || ( CompressorPower == 0 ) ) );
@@ -7303,9 +7312,11 @@ void TMoverParameters::LoadFIZ_Switches( std::string const &Input ) {
extract_value( PantSwitchType, "Pantograph", Input, "" ); extract_value( PantSwitchType, "Pantograph", Input, "" );
extract_value( ConvSwitchType, "Converter", Input, "" ); extract_value( ConvSwitchType, "Converter", Input, "" );
extract_value( StLinSwitchType, "MotorConnectors", Input, "" );
// because people can't make up their minds whether it's "impulse" or "Impulse"... // because people can't make up their minds whether it's "impulse" or "Impulse"...
PantSwitchType = ToLower( PantSwitchType ); PantSwitchType = ToLower( PantSwitchType );
ConvSwitchType = ToLower( ConvSwitchType ); ConvSwitchType = ToLower( ConvSwitchType );
StLinSwitchType = ToLower( StLinSwitchType );
} }
void TMoverParameters::LoadFIZ_MotorParamTable( std::string const &Input ) { void TMoverParameters::LoadFIZ_MotorParamTable( std::string const &Input ) {

View File

@@ -130,6 +130,7 @@ bool TSegment::Init(vector3 &NewPoint1, vector3 NewCPointOut, vector3 NewCPointI
SafeDeleteArray(fTsBuffer); SafeDeleteArray(fTsBuffer);
iSegCount = static_cast<int>( std::ceil( fLength / fStep ) ); // potrzebne do VBO iSegCount = static_cast<int>( std::ceil( fLength / fStep ) ); // potrzebne do VBO
fStep = fLength / iSegCount; // update step to equalize size of individual pieces
fTsBuffer = new double[ iSegCount + 1 ]; fTsBuffer = new double[ iSegCount + 1 ];
fTsBuffer[ 0 ] = 0.0; fTsBuffer[ 0 ] = 0.0;
for( int i = 1; i < iSegCount; ++i ) { for( int i = 1; i < iSegCount; ++i ) {
@@ -324,10 +325,10 @@ int TSegment::RenderLoft( CVertNormTex* &Output, const vector6 *ShapePoints, int
// po modyfikacji - dla ujemnego (iNumShapePoints) w dodatkowych polach tabeli // po modyfikacji - dla ujemnego (iNumShapePoints) w dodatkowych polach tabeli
// podany jest przekrój końcowy // podany jest przekrój końcowy
// podsypka toru jest robiona za pomocą 6 punktów, szyna 12, drogi i rzeki na 3+2+3 // podsypka toru jest robiona za pomocą 6 punktów, szyna 12, drogi i rzeki na 3+2+3
int debugvertexcount{ 0 }; int vertexcount{ 0 };
if( !fTsBuffer ) if( !fTsBuffer )
return debugvertexcount; // prowizoryczne zabezpieczenie przed wysypem - ustalić faktyczną przyczynę return vertexcount; // prowizoryczne zabezpieczenie przed wysypem - ustalić faktyczną przyczynę
vector3 pos1, pos2, dir, parallel1, parallel2, pt, norm; vector3 pos1, pos2, dir, parallel1, parallel2, pt, norm;
double s, step, fOffset, tv1, tv2, t, fEnd; double s, step, fOffset, tv1, tv2, t, fEnd;
@@ -352,8 +353,6 @@ int TSegment::RenderLoft( CVertNormTex* &Output, const vector6 *ShapePoints, int
m2 = s / fEnd; m2 = s / fEnd;
jmm2 = 1.0 - m2; jmm2 = 1.0 - m2;
int const debugvertexlimit = std::abs( iNumShapePoints ) * 2 * ( iEnd - iSkip );
while( i < iEnd ) { while( i < iEnd ) {
++i; // kolejny punkt łamanej ++i; // kolejny punkt łamanej
@@ -416,7 +415,7 @@ int TSegment::RenderLoft( CVertNormTex* &Output, const vector6 *ShapePoints, int
} }
++Output; ++Output;
} }
++debugvertexcount; ++vertexcount;
} }
if( p ) // jeśli jest wskaźnik do tablicy if( p ) // jeśli jest wskaźnik do tablicy
if( *p ) if( *p )
@@ -454,7 +453,7 @@ int TSegment::RenderLoft( CVertNormTex* &Output, const vector6 *ShapePoints, int
} }
++Output; ++Output;
} }
++debugvertexcount; ++vertexcount;
} }
if( p ) // jeśli jest wskaźnik do tablicy if( p ) // jeśli jest wskaźnik do tablicy
if( *p ) if( *p )
@@ -463,8 +462,6 @@ int TSegment::RenderLoft( CVertNormTex* &Output, const vector6 *ShapePoints, int
*( *p ) = pt; *( *p ) = pt;
( *p )++; ( *p )++;
} // zapamiętanie brzegu jezdni } // zapamiętanie brzegu jezdni
assert( debugvertexcount <= debugvertexlimit );
} }
} }
else { else {
@@ -498,7 +495,7 @@ int TSegment::RenderLoft( CVertNormTex* &Output, const vector6 *ShapePoints, int
} }
++Output; ++Output;
} }
++debugvertexcount; ++vertexcount;
pt = parallel2 * ShapePoints[ j ].x + pos2; pt = parallel2 * ShapePoints[ j ].x + pos2;
pt.y += ShapePoints[ j ].y; pt.y += ShapePoints[ j ].y;
@@ -527,9 +524,7 @@ int TSegment::RenderLoft( CVertNormTex* &Output, const vector6 *ShapePoints, int
} }
++Output; ++Output;
} }
++debugvertexcount; ++vertexcount;
assert( debugvertexcount <= debugvertexlimit );
} }
} }
} }
@@ -544,9 +539,7 @@ int TSegment::RenderLoft( CVertNormTex* &Output, const vector6 *ShapePoints, int
} }
} }
assert( debugvertexcount == debugvertexlimit ); return vertexcount;
return debugvertexcount;
}; };
void TSegment::Render() void TSegment::Render()

View File

@@ -17,6 +17,8 @@ http://mozilla.org/MPL/2.0/.
using namespace Math3D; using namespace Math3D;
#define EU07_DEBUG_VBO
// 110405 Ra: klasa punktów przekroju z normalnymi // 110405 Ra: klasa punktów przekroju z normalnymi
class vector6 : public vector3 class vector6 : public vector3

288
Track.cpp
View File

@@ -405,8 +405,7 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name)
std::string token; std::string token;
parser->getTokens(); parser->getTokens();
*parser >> token; *parser >> str; // typ toru
str = token; // typ toru
if (str == "normal") if (str == "normal")
{ {
@@ -460,8 +459,7 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name)
if (iDamageFlag & 128) if (iDamageFlag & 128)
iAction |= 0x80; // flaga wykolejania z powodu uszkodzenia iAction |= 0x80; // flaga wykolejania z powodu uszkodzenia
parser->getTokens(); parser->getTokens();
*parser >> token; *parser >> str; // environment
str = token; // environment
if (str == "flat") if (str == "flat")
eEnvironment = e_flat; eEnvironment = e_flat;
else if (str == "mountains" || str == "mountain") else if (str == "mountains" || str == "mountain")
@@ -477,7 +475,7 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name)
else else
{ {
eEnvironment = e_unknown; eEnvironment = e_unknown;
Error("Unknown track environment: \"" + str + "\""); Error( "Unknown track environment: \"" + str + "\"" );
} }
parser->getTokens(); parser->getTokens();
*parser >> token; *parser >> token;
@@ -485,8 +483,7 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name)
if (bVisible) if (bVisible)
{ {
parser->getTokens(); parser->getTokens();
*parser >> token; *parser >> str; // railtex
str = token; // railtex
TextureID1 = (str == "none" ? 0 : GfxRenderer.GetTextureId( TextureID1 = (str == "none" ? 0 : GfxRenderer.GetTextureId(
str, szTexturePath, str, szTexturePath,
(iCategoryFlag & 1) ? Global::iRailProFiltering : (iCategoryFlag & 1) ? Global::iRailProFiltering :
@@ -496,8 +493,7 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name)
if (fTexLength < 0.01) if (fTexLength < 0.01)
fTexLength = 4; // Ra: zabezpiecznie przed zawieszeniem fTexLength = 4; // Ra: zabezpiecznie przed zawieszeniem
parser->getTokens(); parser->getTokens();
*parser >> token; *parser >> str; // sub || railtex
str = token; // sub || railtex
TextureID2 = (str == "none" ? 0 : GfxRenderer.GetTextureId( TextureID2 = (str == "none" ? 0 : GfxRenderer.GetTextureId(
str, szTexturePath, str, szTexturePath,
(eType == tt_Normal) ? Global::iBallastFiltering : (eType == tt_Normal) ? Global::iBallastFiltering :
@@ -1232,7 +1228,7 @@ void TTrack::Compile(GLuint tex)
} }
break; break;
case tt_Switch: // dla zwrotnicy dwa razy szyny case tt_Switch: // dla zwrotnicy dwa razy szyny
if (TextureID1) // zwrotnice nie są grupowane, aby prościej było je animować if (TextureID1 || TextureID2) // zwrotnice nie są grupowane, aby prościej było je animować
{ // iglice liczone tylko dla zwrotnic { // iglice liczone tylko dla zwrotnic
// Ra: TODO: oddzielna animacja każdej iglicy, opór na docisku // Ra: TODO: oddzielna animacja każdej iglicy, opór na docisku
vector6 rpts3[24], rpts4[24]; vector6 rpts3[24], rpts4[24];
@@ -1254,27 +1250,34 @@ void TTrack::Compile(GLuint tex)
// McZapkie-130302 - poprawione rysowanie szyn // McZapkie-130302 - poprawione rysowanie szyn
if (SwitchExtension->RightSwitch) if (SwitchExtension->RightSwitch)
{ // zwrotnica prawa { // zwrotnica prawa
GfxRenderer.Bind( TextureID1 ); if( TextureID1 ) {
SwitchExtension->Segments[0]->RenderLoft( immediate, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, SwitchExtension->fOffset2); // prawa iglica GfxRenderer.Bind( TextureID1 );
SwitchExtension->Segments[0]->RenderLoft( immediate, rpts1, nnumPts, fTexLength, 1.0, 2); // prawa szyna za iglicą SwitchExtension->Segments[ 0 ]->RenderLoft( immediate, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, SwitchExtension->fOffset2 ); // prawa iglica
SwitchExtension->Segments[0]->RenderLoft( immediate, rpts2, nnumPts, fTexLength); // lewa szyna normalnie cała SwitchExtension->Segments[ 0 ]->RenderLoft( immediate, rpts1, nnumPts, fTexLength, 1.0, 2 ); // prawa szyna za iglicą
if (TextureID2 != TextureID1) // nie wiadomo, czy OpenGL to optymalizuje SwitchExtension->Segments[ 0 ]->RenderLoft( immediate, rpts2, nnumPts, fTexLength ); // lewa szyna normalnie cała
}
if( TextureID2 ) {
GfxRenderer.Bind( TextureID2 ); GfxRenderer.Bind( TextureID2 );
SwitchExtension->Segments[1]->RenderLoft( immediate, rpts1, nnumPts, fTexLength); // prawa szyna normalna cała SwitchExtension->Segments[ 1 ]->RenderLoft( immediate, rpts1, nnumPts, fTexLength ); // prawa szyna normalna cała
SwitchExtension->Segments[1]->RenderLoft( immediate, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -fMaxOffset + SwitchExtension->fOffset1); // lewa iglica SwitchExtension->Segments[ 1 ]->RenderLoft( immediate, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -fMaxOffset + SwitchExtension->fOffset1 ); // lewa iglica
SwitchExtension->Segments[1]->RenderLoft( immediate, rpts2, nnumPts, fTexLength, 1.0, 2); // lewa szyna za iglicą SwitchExtension->Segments[ 1 ]->RenderLoft( immediate, rpts2, nnumPts, fTexLength, 1.0, 2 ); // lewa szyna za iglicą
}
} }
else else
{ // lewa kiedyś działała lepiej niż prawa { // lewa kiedyś działała lepiej niż prawa
GfxRenderer.Bind( TextureID1 ); if( TextureID1 ) {
SwitchExtension->Segments[0]->RenderLoft( immediate, rpts1, nnumPts, fTexLength); // prawa szyna normalna cała GfxRenderer.Bind( TextureID1 );
SwitchExtension->Segments[0]->RenderLoft( immediate, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -SwitchExtension->fOffset2); // lewa iglica SwitchExtension->Segments[ 0 ]->RenderLoft( immediate, rpts1, nnumPts, fTexLength ); // prawa szyna normalna cała
SwitchExtension->Segments[0]->RenderLoft( immediate, rpts2, nnumPts, fTexLength, 1.0, 2); // lewa szyna za iglicą SwitchExtension->Segments[ 0 ]->RenderLoft( immediate, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -SwitchExtension->fOffset2 ); // lewa iglica
if (TextureID2 != TextureID1) // nie wiadomo, czy OpenGL to optymalizuje SwitchExtension->Segments[ 0 ]->RenderLoft( immediate, rpts2, nnumPts, fTexLength, 1.0, 2 ); // lewa szyna za iglicą
}
if( TextureID2 ) {
// nie wiadomo, czy OpenGL to optymalizuje
GfxRenderer.Bind( TextureID2 ); GfxRenderer.Bind( TextureID2 );
SwitchExtension->Segments[1]->RenderLoft( immediate, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, fMaxOffset - SwitchExtension->fOffset1); // prawa iglica SwitchExtension->Segments[ 1 ]->RenderLoft( immediate, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, fMaxOffset - SwitchExtension->fOffset1 ); // prawa iglica
SwitchExtension->Segments[1]->RenderLoft( immediate, rpts1, nnumPts, fTexLength, 1.0, 2); // prawa szyna za iglicą SwitchExtension->Segments[ 1 ]->RenderLoft( immediate, rpts1, nnumPts, fTexLength, 1.0, 2 ); // prawa szyna za iglicą
SwitchExtension->Segments[1]->RenderLoft( immediate, rpts2, nnumPts, fTexLength); // lewa szyna normalnie cała SwitchExtension->Segments[ 1 ]->RenderLoft( immediate, rpts2, nnumPts, fTexLength ); // lewa szyna normalnie cała
}
} }
} }
break; break;
@@ -1782,31 +1785,33 @@ int TTrack::RaArrayPrepare()
if( SwitchExtension->iRoads == 3 ) { if( SwitchExtension->iRoads == 3 ) {
// mogą być tylko 3 drogi zamiast 4 // mogą być tylko 3 drogi zamiast 4
SwitchExtension->iPoints = SwitchExtension->iPoints =
5 SwitchExtension->Segments[ 0 ]->RaSegCount()
+ SwitchExtension->Segments[ 0 ]->RaSegCount()
+ SwitchExtension->Segments[ 1 ]->RaSegCount() + SwitchExtension->Segments[ 1 ]->RaSegCount()
+ SwitchExtension->Segments[ 2 ]->RaSegCount(); + SwitchExtension->Segments[ 2 ]->RaSegCount();
} }
else { else {
SwitchExtension->iPoints = SwitchExtension->iPoints =
5 SwitchExtension->Segments[ 2 ]->RaSegCount()
+ SwitchExtension->Segments[ 2 ]->RaSegCount()
+ SwitchExtension->Segments[ 3 ]->RaSegCount() + SwitchExtension->Segments[ 3 ]->RaSegCount()
+ SwitchExtension->Segments[ 4 ]->RaSegCount() + SwitchExtension->Segments[ 4 ]->RaSegCount()
+ SwitchExtension->Segments[ 5 ]->RaSegCount(); + SwitchExtension->Segments[ 5 ]->RaSegCount();
} }
/*
if (fTexHeight1 >= 0) { if (fTexHeight1 >= 0) {
// normalne pobocze, na razie się składa z // normalne pobocze, na razie się składa z
return SwitchExtension->iPoints * ((TextureID1 ? 1 : 0) + (TextureID2 ? 12 : 0)); return ( ( TextureID1 ? SwitchExtension->iPoints + SwitchExtension->iRoads + 2 : 0 ) + ( TextureID2 ? SwitchExtension->iPoints * 12 : 0 ) );
} }
else { else {
// jeśli fTexHeight1<0, to są chodniki i może któregoś nie być // jeśli fTexHeight1<0, to są chodniki i może któregoś nie być
return SwitchExtension->iPoints * ((TextureID1 ? 1 : 0) + (TextureID2 ? 6 : 0 )); return ( ( TextureID1 ? SwitchExtension->iPoints + SwitchExtension->iRoads + 2 : 0 ) + ( TextureID2 ? SwitchExtension->iPoints * 6 : 0 ) );
} }
*/
// each sub-segment covers only one side of the road, so it has points for single sideroad, if any
return ( ( TextureID1 ? SwitchExtension->iPoints + SwitchExtension->iRoads + 2 : 0 ) + ( TextureID2 ? SwitchExtension->iPoints * 6 : 0 ) );
} }
else // standardowo dla zwykłej drogi else // standardowo dla zwykłej drogi
if (fTexHeight1 >= 0) // jeśli fTexHeight1<0, to są chodniki i może któregoś nie być if (fTexHeight1 >= 0) // jeśli fTexHeight1<0, to są chodniki i może któregoś nie być
return (Segment->RaSegCount()) * return ( Segment->RaSegCount()) *
((TextureID1 ? 4 : 0) + (TextureID2 ? 12 : 0)); // może nie być poziomego! ((TextureID1 ? 4 : 0) + (TextureID2 ? 12 : 0)); // może nie być poziomego!
else else
return (Segment->RaSegCount()) * return (Segment->RaSegCount()) *
@@ -1818,9 +1823,8 @@ int TTrack::RaArrayPrepare()
return 0; return 0;
}; };
int TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int const Vertexcount) void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int const Vertexcount)
{ // wypełnianie tablic VBO { // wypełnianie tablic VBO
int debugvertexcount{ 0 };
// Ra: trzeba rozdzielić szyny od podsypki, aby móc grupować wg tekstur // Ra: trzeba rozdzielić szyny od podsypki, aby móc grupować wg tekstur
double fHTW = 0.5 * fabs(fTrackWidth); double fHTW = 0.5 * fabs(fTrackWidth);
double side = fabs(fTexWidth); // szerokść podsypki na zewnątrz szyny albo pobocza double side = fabs(fTexWidth); // szerokść podsypki na zewnątrz szyny albo pobocza
@@ -1955,19 +1959,16 @@ int TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int const
bpts1[3] = vector6(-rozp, -fTexHeight1 - 0.18, 0.5 + map12, -normal1.x, -normal1.y, 0.0); // prawy skos bpts1[3] = vector6(-rozp, -fTexHeight1 - 0.18, 0.5 + map12, -normal1.x, -normal1.y, 0.0); // prawy skos
} }
} }
debugvertexcount += Segment->RenderLoft(Vert, bpts1, iTrapezoid ? -4 : 4, fTexLength); Segment->RenderLoft(Vert, bpts1, iTrapezoid ? -4 : 4, fTexLength);
assert( debugvertexcount <= Vertexcount );
} }
if (TextureID1) if (TextureID1)
{ // szyny - generujemy dwie, najwyżej rysować się będzie jedną { // szyny - generujemy dwie, najwyżej rysować się będzie jedną
debugvertexcount += Segment->RenderLoft(Vert, rpts1, iTrapezoid ? -nnumPts : nnumPts, fTexLength); Segment->RenderLoft(Vert, rpts1, iTrapezoid ? -nnumPts : nnumPts, fTexLength);
assert( debugvertexcount <= Vertexcount ); Segment->RenderLoft(Vert, rpts2, iTrapezoid ? -nnumPts : nnumPts, fTexLength);
debugvertexcount += Segment->RenderLoft(Vert, rpts2, iTrapezoid ? -nnumPts : nnumPts, fTexLength);
assert( debugvertexcount <= Vertexcount );
} }
break; break;
case tt_Switch: // dla zwrotnicy dwa razy szyny case tt_Switch: // dla zwrotnicy dwa razy szyny
if (TextureID1) // Ra: !!!! tu jest do poprawienia if( TextureID1 || TextureID2 )
{ // iglice liczone tylko dla zwrotnic { // iglice liczone tylko dla zwrotnic
vector6 rpts3[24], rpts4[24]; vector6 rpts3[24], rpts4[24];
for (i = 0; i < 12; ++i) for (i = 0; i < 12; ++i)
@@ -1987,46 +1988,34 @@ int TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int const
} }
if (SwitchExtension->RightSwitch) if (SwitchExtension->RightSwitch)
{ // nowa wersja z SPKS, ale odwrotnie lewa/prawa { // nowa wersja z SPKS, ale odwrotnie lewa/prawa
int batch{ 0 }; if( TextureID1 ) {
batch = SwitchExtension->Segments[0]->RenderLoft( Vert, rpts2, nnumPts, fTexLength); SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, rpts2, nnumPts, fTexLength );
debugvertexcount += batch; SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, rpts1, nnumPts, fTexLength, 1.0, 2 );
assert( debugvertexcount <= Vertexcount );
batch = SwitchExtension->Segments[0]->RenderLoft( Vert, rpts1, nnumPts, fTexLength, 1.0, 2 );
debugvertexcount += batch;
assert( debugvertexcount <= Vertexcount );
SwitchExtension->iLeftVBO = Vert - Start; // indeks lewej iglicy
batch = SwitchExtension->Segments[0]->RenderLoft( Vert, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, SwitchExtension->fOffset2 );
debugvertexcount += batch;
assert( debugvertexcount <= Vertexcount );
SwitchExtension->iRightVBO = Vert - Start; // indeks prawej iglicy SwitchExtension->iLeftVBO = Vert - Start; // indeks lewej iglicy
batch = SwitchExtension->Segments[1]->RenderLoft( Vert, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -fMaxOffset + SwitchExtension->fOffset1 ); SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, SwitchExtension->fOffset2 );
debugvertexcount += batch; }
assert( debugvertexcount <= Vertexcount ); if( TextureID2 ) {
batch = SwitchExtension->Segments[1]->RenderLoft( Vert, rpts2, nnumPts, fTexLength, 1.0, 2 ); SwitchExtension->iRightVBO = Vert - Start; // indeks prawej iglicy
debugvertexcount += batch; SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -fMaxOffset + SwitchExtension->fOffset1 );
assert( debugvertexcount <= Vertexcount ); SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, rpts2, nnumPts, fTexLength, 1.0, 2 );
batch = SwitchExtension->Segments[1]->RenderLoft( Vert, rpts1, nnumPts, fTexLength ); SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, rpts1, nnumPts, fTexLength );
debugvertexcount += batch; }
assert( debugvertexcount <= Vertexcount );
} }
else else
{ // lewa działa lepiej niż prawa { // lewa działa lepiej niż prawa
debugvertexcount += SwitchExtension->Segments[0]->RenderLoft( Vert, rpts1, nnumPts, fTexLength); // lewa szyna normalna cała if( TextureID1 ) {
assert( debugvertexcount <= Vertexcount ); SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, rpts1, nnumPts, fTexLength ); // lewa szyna normalna cała
debugvertexcount += SwitchExtension->Segments[0]->RenderLoft( Vert, rpts2, nnumPts, fTexLength, 1.0, 2 ); // prawa szyna za iglicą SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, rpts2, nnumPts, fTexLength, 1.0, 2 ); // prawa szyna za iglicą
assert( debugvertexcount <= Vertexcount ); SwitchExtension->iLeftVBO = Vert - Start; // indeks lewej iglicy
SwitchExtension->iLeftVBO = Vert - Start; // indeks lewej iglicy SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -SwitchExtension->fOffset2 ); // prawa iglica
debugvertexcount += SwitchExtension->Segments[0]->RenderLoft( Vert, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -SwitchExtension->fOffset2); // prawa iglica }
assert( debugvertexcount <= Vertexcount ); if( TextureID2 ) {
SwitchExtension->iRightVBO = Vert - Start; // indeks prawej iglicy
SwitchExtension->iRightVBO = Vert - Start; // indeks prawej iglicy SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, fMaxOffset - SwitchExtension->fOffset1 ); // lewa iglica
debugvertexcount += SwitchExtension->Segments[1]->RenderLoft( Vert, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, fMaxOffset - SwitchExtension->fOffset1); // lewa iglica SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, rpts1, nnumPts, fTexLength, 1.0, 2 ); // lewa szyna za iglicą
assert( debugvertexcount <= Vertexcount ); SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, rpts2, nnumPts, fTexLength ); // prawa szyna normalnie cała
debugvertexcount += SwitchExtension->Segments[1]->RenderLoft( Vert, rpts1, nnumPts, fTexLength, 1.0, 2); // lewa szyna za iglicą }
assert( debugvertexcount <= Vertexcount );
debugvertexcount += SwitchExtension->Segments[1]->RenderLoft( Vert, rpts2, nnumPts, fTexLength); // prawa szyna normalnie cała
assert( debugvertexcount <= Vertexcount );
} }
} }
break; break;
@@ -2060,8 +2049,7 @@ int TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int const
} }
if (TextureID1) // jeśli podana była tekstura, generujemy trójkąty if (TextureID1) // jeśli podana była tekstura, generujemy trójkąty
{ // tworzenie trójkątów nawierzchni szosy { // tworzenie trójkątów nawierzchni szosy
debugvertexcount += Segment->RenderLoft(Vert, bpts1, iTrapezoid ? -2 : 2, fTexLength); Segment->RenderLoft(Vert, bpts1, iTrapezoid ? -2 : 2, fTexLength);
assert( debugvertexcount <= Vertexcount );
} }
if (TextureID2) if (TextureID2)
{ // pobocze drogi - poziome przy przechyłce (a może krawężnik i chodnik zrobić jak w Midtown Madness 2?) { // pobocze drogi - poziome przy przechyłce (a może krawężnik i chodnik zrobić jak w Midtown Madness 2?)
@@ -2142,25 +2130,21 @@ int TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int const
{ // pobocza do trapezowatej nawierzchni - dodatkowe punkty z drugiej strony { // pobocza do trapezowatej nawierzchni - dodatkowe punkty z drugiej strony
// odcinka // odcinka
if( ( fTexHeight1 >= 0.0 ) || ( slop != 0.0 ) ) { if( ( fTexHeight1 >= 0.0 ) || ( slop != 0.0 ) ) {
debugvertexcount += Segment->RenderLoft( Vert, rpts1, -3, fTexLength ); // tylko jeśli jest z prawej Segment->RenderLoft( Vert, rpts1, -3, fTexLength ); // tylko jeśli jest z prawej
assert( debugvertexcount <= Vertexcount );
} }
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) { if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) {
debugvertexcount += Segment->RenderLoft( Vert, rpts2, -3, fTexLength ); // tylko jeśli jest z lewej Segment->RenderLoft( Vert, rpts2, -3, fTexLength ); // tylko jeśli jest z lewej
assert( debugvertexcount <= Vertexcount );
} }
} }
else { // pobocza zwykłe, brak przechyłki else { // pobocza zwykłe, brak przechyłki
if( ( fTexHeight1 >= 0.0 ) || ( slop != 0.0 ) ) { if( ( fTexHeight1 >= 0.0 ) || ( slop != 0.0 ) ) {
debugvertexcount += Segment->RenderLoft( Vert, rpts1, 3, fTexLength ); Segment->RenderLoft( Vert, rpts1, 3, fTexLength );
assert( debugvertexcount <= Vertexcount );
} }
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) { if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) {
debugvertexcount += Segment->RenderLoft( Vert, rpts2, 3, fTexLength ); Segment->RenderLoft( Vert, rpts2, 3, fTexLength );
assert( debugvertexcount <= Vertexcount );
}
} }
} }
}
break; break;
} }
case tt_Cross: // skrzyżowanie dróg rysujemy inaczej case tt_Cross: // skrzyżowanie dróg rysujemy inaczej
@@ -2191,24 +2175,9 @@ int TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int const
int i; // ile punktów (może byc różna ilość punktów między drogami) int i; // ile punktów (może byc różna ilość punktów między drogami)
if (!SwitchExtension->vPoints) if (!SwitchExtension->vPoints)
{ // jeśli tablica punktów nie jest jeszcze utworzona, zliczamy punkty i tworzymy ją { // jeśli tablica punktów nie jest jeszcze utworzona, zliczamy punkty i tworzymy ją
if( SwitchExtension->iRoads == 3 ) { // points were already counted during preparation stage
// mogą być tylko 3 drogi zamiast 4 // we'll need to add couple extra points for the complete fan we'll build
SwitchExtension->iPoints = SwitchExtension->vPoints = new vector3[SwitchExtension->iPoints + SwitchExtension->iRoads];
5
+ SwitchExtension->Segments[ 0 ]->RaSegCount()
+ SwitchExtension->Segments[ 1 ]->RaSegCount()
+ SwitchExtension->Segments[ 2 ]->RaSegCount();
}
else {
SwitchExtension->iPoints =
5
+ SwitchExtension->Segments[ 2 ]->RaSegCount()
+ SwitchExtension->Segments[ 3 ]->RaSegCount()
+ SwitchExtension->Segments[ 4 ]->RaSegCount()
+ SwitchExtension->Segments[ 5 ]->RaSegCount();
}
// tablica utworzona z zapasem, ale nie wypełniona współrzędnymi
SwitchExtension->vPoints = new vector3[SwitchExtension->iPoints];
} }
vector3 *b = vector3 *b =
SwitchExtension->bPoints ? SwitchExtension->bPoints ?
@@ -2297,46 +2266,32 @@ int TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int const
if (SwitchExtension->iRoads == 4) if (SwitchExtension->iRoads == 4)
{ // pobocza do trapezowatej nawierzchni - dodatkowe punkty z drugiej strony odcinka { // pobocza do trapezowatej nawierzchni - dodatkowe punkty z drugiej strony odcinka
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) { if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) {
debugvertexcount += SwitchExtension->Segments[ 2 ]->RenderLoft( Vert, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render ); SwitchExtension->Segments[ 2 ]->RenderLoft( Vert, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render );
assert( debugvertexcount <= Vertexcount ); SwitchExtension->Segments[ 3 ]->RenderLoft( Vert, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render );
debugvertexcount += SwitchExtension->Segments[ 3 ]->RenderLoft( Vert, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render ); SwitchExtension->Segments[ 4 ]->RenderLoft( Vert, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render );
assert( debugvertexcount <= Vertexcount ); SwitchExtension->Segments[ 5 ]->RenderLoft( Vert, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render );
debugvertexcount += SwitchExtension->Segments[ 4 ]->RenderLoft( Vert, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render );
assert( debugvertexcount <= Vertexcount );
debugvertexcount += SwitchExtension->Segments[ 5 ]->RenderLoft( Vert, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render );
assert( debugvertexcount <= Vertexcount );
} }
} }
else { else {
// punkt 3 pokrywa się z punktem 1, jak w zwrotnicy; połączenie 1->2 nie musi być prostoliniowe // punkt 3 pokrywa się z punktem 1, jak w zwrotnicy; połączenie 1->2 nie musi być prostoliniowe
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) { if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) {
debugvertexcount += SwitchExtension->Segments[ 2 ]->RenderLoft( Vert, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render ); // z P2 do P4 SwitchExtension->Segments[ 2 ]->RenderLoft( Vert, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render ); // z P2 do P4
assert( debugvertexcount <= Vertexcount ); SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render ); // z P4 do P3=P1 (odwrócony)
debugvertexcount += SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render ); // z P4 do P3=P1 (odwrócony) SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render ); // z P1 do P2
assert( debugvertexcount <= Vertexcount );
debugvertexcount += SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render ); // z P1 do P2
assert( debugvertexcount <= Vertexcount );
} }
} }
} }
// renderowanie nawierzchni na końcu // renderowanie nawierzchni na końcu
double sina0 = sin(a[0]), cosa0 = cos(a[0]); double sina0 = sin(a[0]), cosa0 = cos(a[0]);
double u, v; double u, v;
if (!SwitchExtension->bPoints) // jeśli tablica nie wypełniona if( ( false == SwitchExtension->bPoints ) // jeśli tablica nie wypełniona
if (b) // ale jest wskaźnik do tablicy - może nie być? && ( b != nullptr ) ) {
{ // coś się gubi w obliczeniach na wskaźnikach SwitchExtension->bPoints = true; // tablica punktów została wypełniona
// ustalenie liczby punktów, bo mogło wyjść inaczej niż policzone z góry }
i = (int)(((size_t)(b)) - ((size_t)(SwitchExtension->vPoints))) / sizeof(vector3);
if (i > 0)
{ // jeśli zostało to właśnie utworzone
SwitchExtension->iPoints = std::min( SwitchExtension->iPoints - 2, i );
SwitchExtension->vPoints[SwitchExtension->iPoints++] = SwitchExtension->vPoints[0];
++SwitchExtension->iPoints; // we'll add one extra point in the middle
SwitchExtension->bPoints = true; // tablica punktów została wypełniona
}
}
if (TextureID1) { if (TextureID1) {
// jeśli podana tekstura nawierzchni // jeśli podana tekstura nawierzchni
// we start with a vertex in the middle...
Vert->nx = 0.0; Vert->nx = 0.0;
Vert->ny = 1.0; Vert->ny = 1.0;
Vert->nz = 0.0; Vert->nz = 0.0;
@@ -2346,8 +2301,21 @@ int TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int const
Vert->y = oxz.y; Vert->y = oxz.y;
Vert->z = oxz.z; Vert->z = oxz.z;
++Vert; ++Vert;
++debugvertexcount; // ...and add one extra vertex to close the fan...
for (i = SwitchExtension->iPoints - 2; i >= 0; --i) Vert->nx = 0.0;
Vert->ny = 1.0;
Vert->nz = 0.0;
// mapowanie we współrzędnych scenerii
u = ( SwitchExtension->vPoints[ 0 ].x - oxz.x ) / fTexLength;
v = ( SwitchExtension->vPoints[ 0 ].z - oxz.z ) / ( fTexRatio1 * fTexLength );
Vert->u = cosa0 * u + sina0 * v + 0.5;
Vert->v = -sina0 * u + cosa0 * v + 0.5;
Vert->x = SwitchExtension->vPoints[ 0 ].x;
Vert->y = SwitchExtension->vPoints[ 0 ].y;
Vert->z = SwitchExtension->vPoints[ 0 ].z;
++Vert;
// ...then draw the precalculated rest
for (i = SwitchExtension->iPoints + SwitchExtension->iRoads - 1; i >= 0; --i)
{ {
Vert->nx = 0.0; Vert->nx = 0.0;
Vert->ny = 1.0; Vert->ny = 1.0;
@@ -2361,13 +2329,11 @@ int TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int const
Vert->y = SwitchExtension->vPoints[ i ].y; Vert->y = SwitchExtension->vPoints[ i ].y;
Vert->z = SwitchExtension->vPoints[ i ].z; Vert->z = SwitchExtension->vPoints[ i ].z;
++Vert; ++Vert;
++debugvertexcount;
} }
assert( debugvertexcount <= Vertexcount );
} }
break; break;
} } // tt_cross
} } // road
break; break;
case 4: // Ra: rzeki na razie jak drogi, przechyłki na pewno nie mają case 4: // Ra: rzeki na razie jak drogi, przechyłki na pewno nie mają
switch (eType) // dalej zależnie od typu switch (eType) // dalej zależnie od typu
@@ -2402,8 +2368,7 @@ int TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int const
} }
if (TextureID1) // jeśli podana była tekstura, generujemy trójkąty if (TextureID1) // jeśli podana była tekstura, generujemy trójkąty
{ // tworzenie trójkątów nawierzchni szosy { // tworzenie trójkątów nawierzchni szosy
debugvertexcount += Segment->RenderLoft(Vert, bpts1, iTrapezoid ? -2 : 2, fTexLength); Segment->RenderLoft(Vert, bpts1, iTrapezoid ? -2 : 2, fTexLength);
assert( debugvertexcount <= Vertexcount );
} }
if (TextureID2) if (TextureID2)
{ // pobocze drogi - poziome przy przechyłce (a może krawężnik i chodnik zrobić jak w { // pobocze drogi - poziome przy przechyłce (a może krawężnik i chodnik zrobić jak w
@@ -2425,24 +2390,20 @@ int TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int const
rpts2[3] = vector6(bpts1[3].x, bpts1[3].y, 1.0); rpts2[3] = vector6(bpts1[3].x, bpts1[3].y, 1.0);
rpts2[4] = vector6(bpts1[3].x - side2, bpts1[3].y, 0.5); rpts2[4] = vector6(bpts1[3].x - side2, bpts1[3].y, 0.5);
rpts2[5] = vector6(-rozp2, -fTexHeight2, 0.0); // prawy brzeg prawego pobocza rpts2[5] = vector6(-rozp2, -fTexHeight2, 0.0); // prawy brzeg prawego pobocza
debugvertexcount += Segment->RenderLoft(Vert, rpts1, -3, fTexLength); Segment->RenderLoft(Vert, rpts1, -3, fTexLength);
assert( debugvertexcount <= Vertexcount ); Segment->RenderLoft(Vert, rpts2, -3, fTexLength);
debugvertexcount += Segment->RenderLoft(Vert, rpts2, -3, fTexLength);
assert( debugvertexcount <= Vertexcount );
} }
else else
{ // pobocza zwykłe, brak przechyłki { // pobocza zwykłe, brak przechyłki
debugvertexcount += Segment->RenderLoft(Vert, rpts1, 3, fTexLength); Segment->RenderLoft(Vert, rpts1, 3, fTexLength);
assert( debugvertexcount <= Vertexcount ); Segment->RenderLoft(Vert, rpts2, 3, fTexLength);
debugvertexcount += Segment->RenderLoft(Vert, rpts2, 3, fTexLength);
assert( debugvertexcount <= Vertexcount );
} }
} }
} }
} }
break; break;
} }
return debugvertexcount; return;
}; };
void TTrack::RaRenderVBO( int iPtr ) { // renderowanie z użyciem VBO void TTrack::RaRenderVBO( int iPtr ) { // renderowanie z użyciem VBO
@@ -2456,12 +2417,12 @@ void TTrack::RaRenderVBO( int iPtr ) { // renderowanie z użyciem VBO
if( eType == tt_Switch ) // dla zwrotnicy tylko szyny if( eType == tt_Switch ) // dla zwrotnicy tylko szyny
{ {
int const bladesegmentcount = 2; int const bladesegmentcount = 2;
if( TextureID1 ) if( TextureID1 ) {
if( ( seg = SwitchExtension->Segments[ 0 ]->RaSegCount() ) > 0 ) { if( ( seg = SwitchExtension->Segments[ 0 ]->RaSegCount() ) > 0 ) {
GfxRenderer.Bind( TextureID1 ); // szyny + GfxRenderer.Bind( TextureID1 ); // szyny +
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 * seg ); ::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 * seg );
iPtr += 24 * seg; iPtr += 24 * seg;
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 * (seg - bladesegmentcount) ); ::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 * ( seg - bladesegmentcount ) );
// NOTE: due to way blades bend need to render each segment separately, or some unwanted edges may show // NOTE: due to way blades bend need to render each segment separately, or some unwanted edges may show
iPtr += 24 * ( seg - bladesegmentcount ); iPtr += 24 * ( seg - bladesegmentcount );
for( int i = 0; i < bladesegmentcount; ++i ) { for( int i = 0; i < bladesegmentcount; ++i ) {
@@ -2469,7 +2430,8 @@ void TTrack::RaRenderVBO( int iPtr ) { // renderowanie z użyciem VBO
iPtr += 24; iPtr += 24;
} }
} }
if( TextureID2 ) }
if( TextureID2 ) {
if( ( seg = SwitchExtension->Segments[ 1 ]->RaSegCount() ) > 0 ) { if( ( seg = SwitchExtension->Segments[ 1 ]->RaSegCount() ) > 0 ) {
GfxRenderer.Bind( TextureID2 ); GfxRenderer.Bind( TextureID2 );
// NOTE: due to way blades bend need to render each segment separately, or some unwanted edges may show // NOTE: due to way blades bend need to render each segment separately, or some unwanted edges may show
@@ -2482,6 +2444,7 @@ void TTrack::RaRenderVBO( int iPtr ) { // renderowanie z użyciem VBO
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 * seg ); ::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 * seg );
iPtr += 24 * seg; iPtr += 24 * seg;
} }
}
} }
else // dla toru podsypka plus szyny else // dla toru podsypka plus szyny
{ {
@@ -2564,7 +2527,7 @@ void TTrack::RaRenderVBO( int iPtr ) { // renderowanie z użyciem VBO
if( TextureID1 ) { if( TextureID1 ) {
// roads // roads
GfxRenderer.Bind( TextureID1 ); GfxRenderer.Bind( TextureID1 );
::glDrawArrays( GL_TRIANGLE_FAN, iPtr, SwitchExtension->iPoints ); ::glDrawArrays( GL_TRIANGLE_FAN, iPtr, SwitchExtension->iPoints + SwitchExtension->iRoads + 2 );
iPtr += SwitchExtension->iPoints; iPtr += SwitchExtension->iPoints;
} }
} }
@@ -2921,19 +2884,21 @@ TTrack * TTrack::RaAnimate(GLuint const Vertexbuffer)
// fetch current blade geometry // fetch current blade geometry
std::vector<CVertNormTex> bladesbuffer; bladesbuffer.resize( 2 * 2 * 24 ); // 2 blades, 2 segments each std::vector<CVertNormTex> bladesbuffer; bladesbuffer.resize( 2 * 2 * 24 ); // 2 blades, 2 segments each
/*
::glGetBufferSubData( ::glGetBufferSubData(
GL_ARRAY_BUFFER, GL_ARRAY_BUFFER,
SwitchExtension->iLeftVBO * sizeof( CVertNormTex ), SwitchExtension->iLeftVBO * sizeof( CVertNormTex ),
bladesbuffer.size() * sizeof( CVertNormTex ), bladesbuffer.size() * sizeof( CVertNormTex ),
bladesbuffer.data() ); bladesbuffer.data() );
*/
auto bladevertices = bladesbuffer.data(); auto bladevertices = bladesbuffer.data();
if( SwitchExtension->RightSwitch ) { // nowa wersja z SPKS, ale odwrotnie lewa/prawa if( SwitchExtension->RightSwitch ) { // nowa wersja z SPKS, ale odwrotnie lewa/prawa
SwitchExtension->Segments[ 0 ]->RenderLoft( bladevertices, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, SwitchExtension->fOffset2, true ); SwitchExtension->Segments[ 0 ]->RenderLoft( bladevertices, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, SwitchExtension->fOffset2 /*, true*/ );
SwitchExtension->Segments[ 1 ]->RenderLoft( bladevertices, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -fMaxOffset + SwitchExtension->fOffset1, true ); SwitchExtension->Segments[ 1 ]->RenderLoft( bladevertices, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -fMaxOffset + SwitchExtension->fOffset1 /*, true*/ );
} }
else { else {
SwitchExtension->Segments[ 0 ]->RenderLoft( bladevertices, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -SwitchExtension->fOffset2, true ); // prawa iglica SwitchExtension->Segments[ 0 ]->RenderLoft( bladevertices, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -SwitchExtension->fOffset2 /*, true*/ ); // prawa iglica
SwitchExtension->Segments[ 1 ]->RenderLoft( bladevertices, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, fMaxOffset - SwitchExtension->fOffset1, true ); // lewa iglica SwitchExtension->Segments[ 1 ]->RenderLoft( bladevertices, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, fMaxOffset - SwitchExtension->fOffset1 /*, true*/ ); // lewa iglica
} }
// push back updated geometry // push back updated geometry
::glBufferSubData( ::glBufferSubData(
@@ -2987,8 +2952,7 @@ TTrack * TTrack::RaAnimate(GLuint const Vertexbuffer)
int size = RaArrayPrepare(); // wielkość tabeli potrzebna dla tej obrotnicy int size = RaArrayPrepare(); // wielkość tabeli potrzebna dla tej obrotnicy
CVertNormTex *Vert = new CVertNormTex[size]; // bufor roboczy CVertNormTex *Vert = new CVertNormTex[size]; // bufor roboczy
// CVertNormTex *v=Vert; //zmieniane przez // CVertNormTex *v=Vert; //zmieniane przez
auto const debugvertexcount = RaArrayFill(Vert, Vert - SwitchExtension->iLeftVBO, size); // iLeftVBO powinno zostać niezmienione RaArrayFill(Vert, Vert - SwitchExtension->iLeftVBO, size); // iLeftVBO powinno zostać niezmienione
assert( debugvertexcount == size );
::glBufferSubData( ::glBufferSubData(
GL_ARRAY_BUFFER, SwitchExtension->iLeftVBO * sizeof(CVertNormTex), GL_ARRAY_BUFFER, SwitchExtension->iLeftVBO * sizeof(CVertNormTex),
size * sizeof(CVertNormTex), Vert); // wysłanie fragmentu bufora VBO size * sizeof(CVertNormTex), Vert); // wysłanie fragmentu bufora VBO

View File

@@ -240,7 +240,7 @@ class TTrack : public Resource
void Render(); // renderowanie z Display Lists void Render(); // renderowanie z Display Lists
int RaArrayPrepare(); // zliczanie rozmiaru dla VBO sektroa int RaArrayPrepare(); // zliczanie rozmiaru dla VBO sektroa
int RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int const Vertexcount); // wypełnianie VBO void RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int const Vertexcount); // wypełnianie VBO
void RaRenderVBO(int iPtr); // renderowanie z VBO sektora void RaRenderVBO(int iPtr); // renderowanie z VBO sektora
void RenderDyn(); // renderowanie nieprzezroczystych pojazdów (oba tryby) void RenderDyn(); // renderowanie nieprzezroczystych pojazdów (oba tryby)
void RenderDynAlpha(); // renderowanie przezroczystych pojazdów (oba tryby) void RenderDynAlpha(); // renderowanie przezroczystych pojazdów (oba tryby)

247
Train.cpp
View File

@@ -175,8 +175,10 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
{ user_command::pantographlowerall, &TTrain::OnCommand_pantographlowerall }, { user_command::pantographlowerall, &TTrain::OnCommand_pantographlowerall },
{ user_command::linebreakertoggle, &TTrain::OnCommand_linebreakertoggle }, { user_command::linebreakertoggle, &TTrain::OnCommand_linebreakertoggle },
{ user_command::convertertoggle, &TTrain::OnCommand_convertertoggle }, { user_command::convertertoggle, &TTrain::OnCommand_convertertoggle },
{ user_command::convertertogglelocal, &TTrain::OnCommand_convertertogglelocal },
{ user_command::converteroverloadrelayreset, &TTrain::OnCommand_converteroverloadrelayreset }, { user_command::converteroverloadrelayreset, &TTrain::OnCommand_converteroverloadrelayreset },
{ user_command::compressortoggle, &TTrain::OnCommand_compressortoggle }, { user_command::compressortoggle, &TTrain::OnCommand_compressortoggle },
{ user_command::compressortogglelocal, &TTrain::OnCommand_compressortogglelocal },
{ user_command::motorconnectorsopen, &TTrain::OnCommand_motorconnectorsopen }, { user_command::motorconnectorsopen, &TTrain::OnCommand_motorconnectorsopen },
{ user_command::motordisconnect, &TTrain::OnCommand_motordisconnect }, { user_command::motordisconnect, &TTrain::OnCommand_motordisconnect },
{ user_command::motoroverloadrelaythresholdtoggle, &TTrain::OnCommand_motoroverloadrelaythresholdtoggle }, { user_command::motoroverloadrelaythresholdtoggle, &TTrain::OnCommand_motoroverloadrelaythresholdtoggle },
@@ -1727,6 +1729,69 @@ void TTrain::OnCommand_convertertoggle( TTrain *Train, command_data const &Comma
} }
} }
void TTrain::OnCommand_convertertogglelocal( TTrain *Train, command_data const &Command ) {
if( Train->mvOccupied->ConverterStart == start::automatic ) {
// let the automatic thing do its automatic thing...
return;
}
if( Train->ggConverterLocalButton.SubModel == nullptr ) {
return;
}
if( Command.action == GLFW_PRESS ) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down
if( ( false == Train->mvOccupied->ConverterAllowLocal )
&& ( Train->ggConverterLocalButton.GetValue() < 0.5 ) ) {
// turn on
// sound feedback
if( Train->ggConverterLocalButton.GetValue() < 0.5 ) {
Train->play_sound( Train->dsbSwitch );
}
// visual feedback
Train->ggConverterLocalButton.UpdateValue( 1.0 );
// effect
Train->mvOccupied->ConverterAllowLocal = true;
/*
if( true == Train->mvControlled->ConverterSwitch( true, range::local ) ) {
// side effects
// control the compressor, if it's paired with the converter
if( Train->mvControlled->CompressorPower == 2 ) {
// hunter-091012: tak jest poprawnie
Train->mvControlled->CompressorSwitch( true, range::local );
}
}
*/
}
else {
//turn off
// sound feedback
if( Train->ggConverterLocalButton.GetValue() > 0.5 ) {
Train->play_sound( Train->dsbSwitch );
}
// visual feedback
Train->ggConverterLocalButton.UpdateValue( 0.0 );
// effect
Train->mvOccupied->ConverterAllowLocal = false;
/*
if( true == Train->mvControlled->ConverterSwitch( false, range::local ) ) {
// side effects
// control the compressor, if it's paired with the converter
if( Train->mvControlled->CompressorPower == 2 ) {
// hunter-091012: tak jest poprawnie
Train->mvControlled->CompressorSwitch( false, range::local );
}
// if there's no (low voltage) power source left, drop pantographs
if( false == Train->mvControlled->Battery ) {
Train->mvControlled->PantFront( false, range::local );
Train->mvControlled->PantRear( false, range::local );
}
}
*/
}
}
}
void TTrain::OnCommand_converteroverloadrelayreset( TTrain *Train, command_data const &Command ) { void TTrain::OnCommand_converteroverloadrelayreset( TTrain *Train, command_data const &Command ) {
if( Train->ggConverterFuseButton.SubModel == nullptr ) { if( Train->ggConverterFuseButton.SubModel == nullptr ) {
@@ -1824,6 +1889,42 @@ void TTrain::OnCommand_compressortoggle( TTrain *Train, command_data const &Comm
*/ */
} }
void TTrain::OnCommand_compressortogglelocal( TTrain *Train, command_data const &Command ) {
if( Train->mvOccupied->CompressorPower >= 2 ) {
return;
}
if( Train->ggCompressorLocalButton.SubModel == nullptr ) {
return;
}
if( Command.action == GLFW_PRESS ) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down
if( false == Train->mvOccupied->CompressorAllowLocal ) {
// turn on
// sound feedback
if( Train->ggCompressorLocalButton.GetValue() < 0.5 ) {
Train->play_sound( Train->dsbSwitch );
}
// visual feedback
Train->ggCompressorLocalButton.UpdateValue( 1.0 );
// effect
Train->mvOccupied->CompressorAllowLocal = true;
}
else {
//turn off
// sound feedback
if( Train->ggCompressorLocalButton.GetValue() > 0.5 ) {
Train->play_sound( Train->dsbSwitch );
}
// visual feedback
Train->ggCompressorLocalButton.UpdateValue( 0.0 );
// effect
Train->mvOccupied->CompressorAllowLocal = false;
}
}
}
void TTrain::OnCommand_motorconnectorsopen( TTrain *Train, command_data const &Command ) { void TTrain::OnCommand_motorconnectorsopen( TTrain *Train, command_data const &Command ) {
// TODO: don't rely on presense of 3d model to determine presence of the switch // TODO: don't rely on presense of 3d model to determine presence of the switch
@@ -1833,31 +1934,111 @@ void TTrain::OnCommand_motorconnectorsopen( TTrain *Train, command_data const &C
} }
return; return;
} }
// NOTE: because we don't have modeled actual circuits this is a simplification of the real mechanics
if( Command.action != GLFW_RELEASE ) { // namely, pressing the button will flip it in the entire unit, which isn't exactly physically possible
// button works while it's held down if( Command.action == GLFW_PRESS ) {
if( true == Train->mvControlled->StLinFlag ) { // button works while it's held down but we can only pay attention to initial press
if( false == Train->mvControlled->StLinSwitchOff ) {
// open the connectors
Train->mvControlled->StLinSwitchOff = true;
if( ( Train->mvControlled->TrainType == dt_ET41 )
|| ( Train->mvControlled->TrainType == dt_ET42 ) ) {
// crude implementation of the butto affecting entire unit for multi-unit engines
// TODO: rework it into part of standard command propagation system
if( ( Train->mvControlled->Couplers[ 0 ].Connected != nullptr )
&& ( true == TestFlag( Train->mvControlled->Couplers[ 0 ].CouplingFlag, coupling::permanent ) ) ) {
// the first unit isn't allowed to start its compressor until second unit can start its own as well
Train->mvControlled->Couplers[ 0 ].Connected->StLinSwitchOff = true;
}
if( ( Train->mvControlled->Couplers[ 1 ].Connected != nullptr )
&& ( true == TestFlag( Train->mvControlled->Couplers[ 1 ].CouplingFlag, coupling::permanent ) ) ) {
// the first unit isn't allowed to start its compressor until second unit can start its own as well
Train->mvControlled->Couplers[ 1 ].Connected->StLinSwitchOff = true;
}
}
// sound feedback
if( Train->ggStLinOffButton.GetValue() < 0.5 ) {
Train->play_sound( Train->dsbSwitch );
}
// visual feedback
Train->ggStLinOffButton.UpdateValue( 1.0 );
// effect
if( true == Train->mvControlled->StLinFlag ) {
Train->play_sound( Train->dsbRelay );
}
// yBARC - zmienione na przeciwne, bo true to zalaczone // yBARC - zmienione na przeciwne, bo true to zalaczone
Train->mvControlled->StLinFlag = false; Train->mvControlled->StLinFlag = false;
Train->play_sound( Train->dsbRelay ); if( ( Train->mvControlled->TrainType == dt_ET41 )
|| ( Train->mvControlled->TrainType == dt_ET42 ) ) {
// crude implementation of the butto affecting entire unit for multi-unit engines
// TODO: rework it into part of standard command propagation system
if( ( Train->mvControlled->Couplers[ 0 ].Connected != nullptr )
&& ( true == TestFlag( Train->mvControlled->Couplers[ 0 ].CouplingFlag, coupling::permanent ) ) ) {
// the first unit isn't allowed to start its compressor until second unit can start its own as well
Train->mvControlled->Couplers[ 0 ].Connected->StLinFlag = false;
}
if( ( Train->mvControlled->Couplers[ 1 ].Connected != nullptr )
&& ( true == TestFlag( Train->mvControlled->Couplers[ 1 ].CouplingFlag, coupling::permanent ) ) ) {
// the first unit isn't allowed to start its compressor until second unit can start its own as well
Train->mvControlled->Couplers[ 1 ].Connected->StLinFlag = false;
}
}
} }
Train->mvControlled->StLinSwitchOff = true; else {
// sound feedback if( Train->mvControlled->StLinSwitchType == "toggle" ) {
if( Train->ggStLinOffButton.GetValue() < 0.05 ) { // default type of button (impulse) has only one effect on press, but the toggle type can toggle the state
Train->play_sound( Train->dsbSwitch ); Train->mvControlled->StLinSwitchOff = false;
if( ( Train->mvControlled->TrainType == dt_ET41 )
|| ( Train->mvControlled->TrainType == dt_ET42 ) ) {
// crude implementation of the butto affecting entire unit for multi-unit engines
// TODO: rework it into part of standard command propagation system
if( ( Train->mvControlled->Couplers[ 0 ].Connected != nullptr )
&& ( true == TestFlag( Train->mvControlled->Couplers[ 0 ].CouplingFlag, coupling::permanent ) ) ) {
// the first unit isn't allowed to start its compressor until second unit can start its own as well
Train->mvControlled->Couplers[ 0 ].Connected->StLinSwitchOff = false;
}
if( ( Train->mvControlled->Couplers[ 1 ].Connected != nullptr )
&& ( true == TestFlag( Train->mvControlled->Couplers[ 1 ].CouplingFlag, coupling::permanent ) ) ) {
// the first unit isn't allowed to start its compressor until second unit can start its own as well
Train->mvControlled->Couplers[ 1 ].Connected->StLinSwitchOff = false;
}
}
// sound feedback
if( Train->ggStLinOffButton.GetValue() > 0.5 ) {
Train->play_sound( Train->dsbSwitch );
}
// visual feedback
Train->ggStLinOffButton.UpdateValue( 0.0 );
}
} }
// visual feedback
Train->ggStLinOffButton.UpdateValue( 1.0 );
} }
else { else if( Command.action == GLFW_RELEASE ) {
// button released // button released
Train->mvControlled->StLinSwitchOff = false; if( Train->mvControlled->StLinSwitchType != "toggle" ) {
// sound feedback // default button type (impulse) works on button release
if( Train->ggStLinOffButton.GetValue() > 0.5 ) { Train->mvControlled->StLinSwitchOff = false;
Train->play_sound( Train->dsbSwitch ); if( ( Train->mvControlled->TrainType == dt_ET41 )
|| ( Train->mvControlled->TrainType == dt_ET42 ) ) {
// crude implementation of the butto affecting entire unit for multi-unit engines
// TODO: rework it into part of standard command propagation system
if( ( Train->mvControlled->Couplers[ 0 ].Connected != nullptr )
&& ( true == TestFlag( Train->mvControlled->Couplers[ 0 ].CouplingFlag, coupling::permanent ) ) ) {
// the first unit isn't allowed to start its compressor until second unit can start its own as well
Train->mvControlled->Couplers[ 0 ].Connected->StLinSwitchOff = false;
}
if( ( Train->mvControlled->Couplers[ 1 ].Connected != nullptr )
&& ( true == TestFlag( Train->mvControlled->Couplers[ 1 ].CouplingFlag, coupling::permanent ) ) ) {
// the first unit isn't allowed to start its compressor until second unit can start its own as well
Train->mvControlled->Couplers[ 1 ].Connected->StLinSwitchOff = false;
}
}
// sound feedback
if( Train->ggStLinOffButton.GetValue() > 0.5 ) {
Train->play_sound( Train->dsbSwitch );
}
// visual feedback
Train->ggStLinOffButton.UpdateValue( 0.0 );
} }
// visual feedback
Train->ggStLinOffButton.UpdateValue( 0.0 );
} }
} }
@@ -4674,9 +4855,11 @@ bool TTrain::Update( double const Deltatime )
ggDepartureSignalButton.Update(); ggDepartureSignalButton.Update();
// NBMX dzwignia sprezarki // NBMX dzwignia sprezarki
ggCompressorButton.Update(); ggCompressorButton.Update();
ggCompressorLocalButton.Update();
ggMainButton.Update(); ggMainButton.Update();
ggRadioButton.Update(); ggRadioButton.Update();
ggConverterButton.Update(); ggConverterButton.Update();
ggConverterLocalButton.Update();
ggConverterOffButton.Update(); ggConverterOffButton.Update();
#ifdef EU07_USE_OLD_COMMAND_SYSTEM #ifdef EU07_USE_OLD_COMMAND_SYSTEM
@@ -6604,6 +6787,11 @@ void TTrain::set_cab_controls() {
if( true == mvOccupied->Battery ) { if( true == mvOccupied->Battery ) {
ggBatteryButton.PutValue( 1.0 ); ggBatteryButton.PutValue( 1.0 );
} }
// motor connectors
ggStLinOffButton.PutValue(
( mvControlled->StLinSwitchOff ?
1.0 :
0.0 ) );
// radio // radio
if( true == mvOccupied->Radio ) { if( true == mvOccupied->Radio ) {
ggRadioButton.PutValue( 1.0 ); ggRadioButton.PutValue( 1.0 );
@@ -6636,10 +6824,19 @@ void TTrain::set_cab_controls() {
1.0 : 1.0 :
0.0 ); 0.0 );
} }
ggConverterLocalButton.PutValue(
mvControlled->ConverterAllowLocal ?
1.0 :
0.0 );
// compressor // compressor
if( true == mvControlled->CompressorAllow ) { ggCompressorButton.PutValue(
ggCompressorButton.PutValue( 1.0 ); mvControlled->CompressorAllow ?
} 1.0 :
0.0 );
ggCompressorLocalButton.PutValue(
mvControlled->CompressorAllowLocal ?
1.0 :
0.0 );
// motor overload relay threshold / shunt mode // motor overload relay threshold / shunt mode
if( mvControlled->Imax == mvControlled->ImaxHi ) { if( mvControlled->Imax == mvControlled->ImaxHi ) {
ggMaxCurrentCtrl.PutValue( 1.0 ); ggMaxCurrentCtrl.PutValue( 1.0 );
@@ -7175,11 +7372,19 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
// sprezarka // sprezarka
ggCompressorButton.Load(Parser, DynamicObject->mdKabina); ggCompressorButton.Load(Parser, DynamicObject->mdKabina);
} }
else if( Label == "compressorlocal_sw:" ) {
// sprezarka
ggCompressorLocalButton.Load( Parser, DynamicObject->mdKabina );
}
else if (Label == "converter_sw:") else if (Label == "converter_sw:")
{ {
// przetwornica // przetwornica
ggConverterButton.Load(Parser, DynamicObject->mdKabina); ggConverterButton.Load(Parser, DynamicObject->mdKabina);
} }
else if( Label == "converterlocal_sw:" ) {
// przetwornica
ggConverterLocalButton.Load( Parser, DynamicObject->mdKabina );
}
else if (Label == "converteroff_sw:") else if (Label == "converteroff_sw:")
{ {
// przetwornica wyl // przetwornica wyl

View File

@@ -146,8 +146,10 @@ class TTrain
static void OnCommand_pantographlowerall( TTrain *Train, command_data const &Command ); static void OnCommand_pantographlowerall( TTrain *Train, command_data const &Command );
static void OnCommand_linebreakertoggle( TTrain *Train, command_data const &Command ); static void OnCommand_linebreakertoggle( TTrain *Train, command_data const &Command );
static void OnCommand_convertertoggle( TTrain *Train, command_data const &Command ); static void OnCommand_convertertoggle( TTrain *Train, command_data const &Command );
static void OnCommand_convertertogglelocal( TTrain *Train, command_data const &Command );
static void OnCommand_converteroverloadrelayreset( TTrain *Train, command_data const &Command ); static void OnCommand_converteroverloadrelayreset( TTrain *Train, command_data const &Command );
static void OnCommand_compressortoggle( TTrain *Train, command_data const &Command ); static void OnCommand_compressortoggle( TTrain *Train, command_data const &Command );
static void OnCommand_compressortogglelocal( TTrain *Train, command_data const &Command );
static void OnCommand_motorconnectorsopen( TTrain *Train, command_data const &Command ); static void OnCommand_motorconnectorsopen( TTrain *Train, command_data const &Command );
static void OnCommand_motordisconnect( TTrain *Train, command_data const &Command ); static void OnCommand_motordisconnect( TTrain *Train, command_data const &Command );
static void OnCommand_motoroverloadrelaythresholdtoggle( TTrain *Train, command_data const &Command ); static void OnCommand_motoroverloadrelaythresholdtoggle( TTrain *Train, command_data const &Command );
@@ -251,7 +253,9 @@ public: // reszta może by?publiczna
TGauge ggIgnitionKey; TGauge ggIgnitionKey;
TGauge ggCompressorButton; TGauge ggCompressorButton;
TGauge ggCompressorLocalButton; // controls only compressor of its own unit (et42-specific)
TGauge ggConverterButton; TGauge ggConverterButton;
TGauge ggConverterLocalButton; // controls only converter of its own unit (et42-specific)
TGauge ggConverterOffButton; TGauge ggConverterOffButton;
// ABu 090305 - syrena i prad nastepnego czlonu // ABu 090305 - syrena i prad nastepnego czlonu

View File

@@ -1863,9 +1863,9 @@ TWorld::Update_UI() {
uitextline3 += ( tmp->MoverParameters->PantRearUp ? ( tmp->MoverParameters->PantRearVolt > 0.0 ? "O" : "o" ) : "." );; uitextline3 += ( tmp->MoverParameters->PantRearUp ? ( tmp->MoverParameters->PantRearVolt > 0.0 ? "O" : "o" ) : "." );;
uitextline3 += ( tmp->MoverParameters->PantFrontUp ? ( tmp->MoverParameters->PantFrontVolt > 0.0 ? "P" : "p" ) : "." );; uitextline3 += ( tmp->MoverParameters->PantFrontUp ? ( tmp->MoverParameters->PantFrontVolt > 0.0 ? "P" : "p" ) : "." );;
uitextline3 += ( tmp->MoverParameters->PantPressLockActive ? "!" : ( tmp->MoverParameters->PantPressSwitchActive ? "*" : "." ) ); uitextline3 += ( tmp->MoverParameters->PantPressLockActive ? "!" : ( tmp->MoverParameters->PantPressSwitchActive ? "*" : "." ) );
uitextline3 += ( tmp->MoverParameters->ConverterAllow ? ( tmp->MoverParameters->ConverterFlag ? "X" : "x" ) : "." ); uitextline3 += ( false == tmp->MoverParameters->ConverterAllowLocal ? "-" : ( tmp->MoverParameters->ConverterAllow ? ( tmp->MoverParameters->ConverterFlag ? "X" : "x" ) : "." ) );
uitextline3 += ( tmp->MoverParameters->ConvOvldFlag ? "!" : "." ); uitextline3 += ( tmp->MoverParameters->ConvOvldFlag ? "!" : "." );
uitextline3 += ( tmp->MoverParameters->CompressorAllow ? ( tmp->MoverParameters->CompressorFlag ? "C" : "c" ) : "." ); uitextline3 += ( false == tmp->MoverParameters->CompressorAllowLocal ? "-" : ( tmp->MoverParameters->CompressorAllow ? ( tmp->MoverParameters->CompressorFlag ? "C" : "c" ) : "." ) );
uitextline3 += ( tmp->MoverParameters->CompressorGovernorLock ? "!" : "." ); uitextline3 += ( tmp->MoverParameters->CompressorGovernorLock ? "!" : "." );
uitextline3 += uitextline3 +=

View File

@@ -47,8 +47,10 @@ commanddescription_sequence Commands_descriptions = {
{ "reverserdecrease", command_target::vehicle }, { "reverserdecrease", command_target::vehicle },
{ "linebreakertoggle", command_target::vehicle }, { "linebreakertoggle", command_target::vehicle },
{ "convertertoggle", command_target::vehicle }, { "convertertoggle", command_target::vehicle },
{ "convertertogglelocal", command_target::vehicle },
{ "converteroverloadrelayreset", command_target::vehicle }, { "converteroverloadrelayreset", command_target::vehicle },
{ "compressortoggle", command_target::vehicle }, { "compressortoggle", command_target::vehicle },
{ "compressortogglelocal", command_target::vehicle },
{ "motoroverloadrelaythresholdtoggle", command_target::vehicle }, { "motoroverloadrelaythresholdtoggle", command_target::vehicle },
{ "motoroverloadrelayreset", command_target::vehicle }, { "motoroverloadrelayreset", command_target::vehicle },
{ "notchingrelaytoggle", command_target::vehicle }, { "notchingrelaytoggle", command_target::vehicle },

View File

@@ -42,8 +42,10 @@ enum class user_command {
reverserdecrease, reverserdecrease,
linebreakertoggle, linebreakertoggle,
convertertoggle, convertertoggle,
convertertogglelocal,
converteroverloadrelayreset, converteroverloadrelayreset,
compressortoggle, compressortoggle,
compressortogglelocal,
motoroverloadrelaythresholdtoggle, motoroverloadrelaythresholdtoggle,
motoroverloadrelayreset, motoroverloadrelayreset,
notchingrelaytoggle, notchingrelaytoggle,

View File

@@ -228,10 +228,14 @@ keyboard_input::default_bindings() {
{ GLFW_KEY_M }, { GLFW_KEY_M },
// convertertoggle // convertertoggle
{ GLFW_KEY_X }, { GLFW_KEY_X },
// convertertogglelocal
{ GLFW_KEY_X | keymodifier::shift },
// converteroverloadrelayreset // converteroverloadrelayreset
{ GLFW_KEY_N | keymodifier::control }, { GLFW_KEY_N | keymodifier::control },
// compressortoggle // compressortoggle
{ GLFW_KEY_C }, { GLFW_KEY_C },
// compressortoggleloal
{ GLFW_KEY_C | keymodifier::shift },
// motoroverloadrelaythresholdtoggle // motoroverloadrelaythresholdtoggle
{ GLFW_KEY_F }, { GLFW_KEY_F },
// motoroverloadrelayreset // motoroverloadrelayreset

View File

@@ -70,7 +70,7 @@ private:
bool m_shift{ false }; bool m_shift{ false };
bool m_ctrl{ false }; bool m_ctrl{ false };
bindings_cache m_bindingscache; bindings_cache m_bindingscache;
std::array<char, GLFW_KEY_LAST> m_keys; std::array<char, GLFW_KEY_LAST + 1> m_keys;
}; };
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#define VERSION_MAJOR 17 #define VERSION_MAJOR 17
#define VERSION_MINOR 520 #define VERSION_MINOR 522
#define VERSION_REVISION 0 #define VERSION_REVISION 0