From 6696a3536d03a17f46b6d7a11bd269dca2c87539 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Mon, 29 Jan 2018 01:28:27 +0100 Subject: [PATCH] basic support for dmu vehicle type, cab sound positioning fix --- Driver.cpp | 85 +++++++++++++++++++++++++++++++++------------- McZapkie/MOVER.h | 2 ++ McZapkie/Mover.cpp | 6 +++- Model3d.cpp | 23 +++++++------ 4 files changed, 81 insertions(+), 35 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index b611b30d..ebbdfeae 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -1394,7 +1394,18 @@ float TController::braking_distance_multiplier( float const Targetvelocity ) const { if( Targetvelocity > 65.f ) { return 1.f; } - if( Targetvelocity < 5.f ) { return 1.f; } + if( Targetvelocity < 5.f ) { + + if( ( mvOccupied->TrainType == dt_DMU ) + && ( mvOccupied->Vel < 40.0 ) + && ( Targetvelocity == 0.f ) ) { + // HACK: engaged automatic transmission means extra/earlier braking effort is needed for the last leg before full stop + return interpolate( 2.f, 1.f, static_cast( mvOccupied->Vel / 40.0 ) ); + } + else { + return 1.f; + } + } // stretch the braking distance up to 3 times; the lower the speed, the greater the stretch return interpolate( 3.f, 1.f, ( Targetvelocity - 5.f ) / 60.f ); } @@ -1518,8 +1529,11 @@ TController::TController(bool AI, TDynamicObject *NewControll, bool InitPsyche, } // fAccThreshold może podlegać uczeniu się - hamowanie powinno być rejestrowane, a potem analizowane - fAccThreshold = - ( mvOccupied->TrainType & dt_EZT ) ? -0.6 : -0.2; // próg opóźnienia dla zadziałania hamulca + // próg opóźnienia dla zadziałania hamulca + fAccThreshold = ( + mvOccupied->TrainType == dt_EZT ? -0.6 : + mvOccupied->TrainType == dt_DMU ? -0.4 : + -0.2 ); } // TrainParams=NewTrainParams; // if (TrainParams) @@ -1794,13 +1808,12 @@ void TController::AutoRewident() fBrake_a0[i+1] = 0; fBrake_a1[i+1] = 0; } - d = pVehicles[0]; // pojazd na czele składu - while (d) - { // 4. Przeliczanie siły hamowania - for (int i = 0; i < BrakeAccTableSize; i++) - { - fBrake_a0[i+1] += d->MoverParameters->BrakeForceR(0.25, velstep*(1 + 2 * i)); - fBrake_a1[i+1] += d->MoverParameters->BrakeForceR(1.00, velstep*(1 + 2 * i)); + // 4. Przeliczanie siły hamowania + d = pVehicles[0]; // pojazd na czele składu + while (d) { + for( int i = 0; i < BrakeAccTableSize; ++i ) { + fBrake_a0[ i + 1 ] += d->MoverParameters->BrakeForceR( 0.25, velstep*( 1 + 2 * i ) ); + fBrake_a1[ i + 1 ] += d->MoverParameters->BrakeForceR( 1.00, velstep*( 1 + 2 * i ) ); } d = d->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła) } @@ -1811,12 +1824,15 @@ void TController::AutoRewident() fBrake_a0[i + 1] += 0.001*velstep*(1 + 2 * i); fBrake_a1[i+1] /= (12*fMass); } - if (mvOccupied->TrainType == dt_EZT) - { + if( mvOccupied->TrainType == dt_EZT ) { fAccThreshold = std::max(-fBrake_a0[BrakeAccTableSize] - 8 * fBrake_a1[BrakeAccTableSize], -0.6); fBrakeReaction = 0.25; } - else if (ustaw > 16) + else if( mvOccupied->TrainType == dt_DMU ) { + fAccThreshold = std::max( -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ], /*-0.7*/ -0.4 ); + fBrakeReaction = 0.25; + } + else if (ustaw > 16) { fAccThreshold = -fBrake_a0[BrakeAccTableSize] - 4 * fBrake_a1[BrakeAccTableSize]; fBrakeReaction = 1.00 + fLength*0.004; @@ -1993,10 +2009,16 @@ bool TController::CheckVehicles(TOrders user) } } // Ra 2014-09: tymczasowo prymitywne ustawienie warunku pod kątem SN61 - if ((mvOccupied->TrainType == dt_EZT) || (iVehicles == 1)) - iDrivigFlags |= movePushPull; // zmiana czoła przez zmianę kabiny - else - iDrivigFlags &= ~movePushPull; // zmiana czoła przez manewry + if( ( mvOccupied->TrainType == dt_EZT ) + || ( mvOccupied->TrainType == dt_DMU ) + || ( iVehicles == 1 ) ) { + // zmiana czoła przez zmianę kabiny + iDrivigFlags |= movePushPull; + } + else { + // zmiana czoła przez manewry + iDrivigFlags &= ~movePushPull; + } } // blok wykonywany, gdy aktywnie prowadzi return true; } @@ -2419,8 +2441,8 @@ bool TController::IncBrake() bool standalone { true }; if( ( mvOccupied->TrainType == dt_ET41 ) || ( mvOccupied->TrainType == dt_ET42 ) ) { - // NOTE: we're doing simplified checks full of presuptions here. - // they'll break if someone does strange thing like turning around the second unit + // NOTE: we're doing simplified checks full of presuptions here. + // they'll break if someone does strange thing like turning around the second unit if( ( mvOccupied->Couplers[ 1 ].CouplingFlag & coupling::permanent ) && ( mvOccupied->Couplers[ 1 ].Connected->Couplers[ 1 ].CouplingFlag > 0 ) ) { standalone = false; @@ -2430,6 +2452,10 @@ bool TController::IncBrake() standalone = false; } } + else if( mvOccupied->TrainType == dt_DMU ) { + // enforce use of train brake for DMUs + standalone = false; + } else { /* standalone = @@ -2488,12 +2514,25 @@ bool TController::IncBrake() mvOccupied->BrakeDelayFlag > bdelay_G ? 1.0 : 1.25 ) ); +/* + // HACK: stronger braking to overcome SA134 engine behaviour + if( ( mvOccupied->TrainType == dt_DMU ) + && ( VelNext == 0.0 ) + && ( fBrakeDist < 200.0 ) ) { + mvOccupied->BrakeLevelAdd( + fBrakeDist / ActualProximityDist < 0.8 ? + 1.0 : + 3.0 ); + } +*/ } else { - OK = mvOccupied->BrakeLevelAdd(0.25); - if ((deltaAcc > 5 * fBrake_a1[0]) && (mvOccupied->BrakeCtrlPosR <= 3.0)) - mvOccupied->BrakeLevelAdd(0.75); + OK = mvOccupied->BrakeLevelAdd( 0.25 ); + if( ( deltaAcc > 5 * fBrake_a1[ 0 ] ) + && ( mvOccupied->BrakeCtrlPosR <= 3.0 ) ) { + mvOccupied->BrakeLevelAdd( 0.75 ); + } } } else @@ -4956,7 +4995,7 @@ TController::UpdateSituation(double dt) { } // yB: usunięte różne dziwne warunki, oddzielamy część zadającą od wykonawczej // zmniejszanie predkosci - if( mvOccupied->TrainType & dt_EZT ) { + if( mvOccupied->TrainType == dt_EZT ) { // właściwie, to warunek powinien być na działający EP // Ra: to dobrze hamuje EP w EZT if( ( AccDesired <= fAccThreshold ) // jeśli hamować - u góry ustawia się hamowanie na fAccThreshold diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index 24094d74..9ba10588 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -208,6 +208,7 @@ enum sound { //szczególne typy pojazdów (inna obsługa) dla zmiennej TrainType //zamienione na flagi bitowe, aby szybko wybierać grupę (np. EZT+SZT) +// TODO: convert to enums, they're used as specific checks anyway static int const dt_Default = 0; static int const dt_EZT = 1; static int const dt_ET41 = 2; @@ -218,6 +219,7 @@ static int const dt_SN61 = 0x20; //nie używane w warunkach, ale ustawiane z CHK static int const dt_EP05 = 0x40; static int const dt_ET40 = 0x80; static int const dt_181 = 0x100; +static int const dt_DMU = 0x200; //stałe dla asynchronów static int const eimc_s_dfic = 0; diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 5fdba3de..ab11d0f4 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -3846,6 +3846,9 @@ double TMoverParameters::BrakeForceR(double ratio, double velocity) ratio = ratio + (1.5 - ratio)*std::min(1.0, Vel*0.02); if ((BrakeDelayFlag&bdelay_R) && (BrakeMethod%128 != bp_Cosid) && (BrakeMethod % 128 != bp_D1) && (BrakeMethod % 128 != bp_D2) && (Power<1) && (velocity<40)) ratio = ratio / 2; + if( ( TrainType == dt_DMU ) && ( velocity < 30.0 ) ) { + ratio -= 0.3; + } } } @@ -4294,7 +4297,7 @@ double TMoverParameters::TractionForce(double dt) case DieselElectric: { if( true == Mains ) { // TBD, TODO: currently ignores RVentType, fix this? - RventRot += clamp( DElist[ MainCtrlPos ].RPM - RventRot, -100.0, 50.0 ) * dt; + RventRot += clamp( DElist[ MainCtrlPos ].RPM / 60.0 - RventRot, -100.0, 50.0 ) * dt; } else { RventRot *= std::max( 0.0, 1.0 - RVentSpeed * dt ); @@ -6978,6 +6981,7 @@ void TMoverParameters::LoadFIZ_Param( std::string const &line ) { std::map types{ { "pseudodiesel", dt_PseudoDiesel }, { "ezt", dt_EZT }, + { "dmu", dt_DMU }, { "sn61", dt_SN61 }, { "et22", dt_ET22 }, { "et40", dt_ET40 }, diff --git a/Model3d.cpp b/Model3d.cpp index e988ba40..e659619b 100644 --- a/Model3d.cpp +++ b/Model3d.cpp @@ -1169,17 +1169,18 @@ TSubModel::offset( float const Geometrytestoffsetthreshold ) const { // offset of zero generally means the submodel has optimized identity matrix // for such cases we resort to an estimate from submodel geometry // TODO: do proper bounding area calculation for submodel when loading mesh and grab the centre point from it here - if( m_geometry != null_handle ) { - auto const &vertices { GfxRenderer.Vertices( m_geometry ) }; - if( false == vertices.empty() ) { - // transformation matrix for the submodel can still contain rotation and/or scaling, - // so we pass the vertex positions through it rather than just grab them directly - offset = glm::vec3(); - auto const vertexfactor { 1.f / vertices.size() }; - auto const transformationmatrix { glm::make_mat4( parentmatrix.readArray() ) }; - for( auto const &vertex : vertices ) { - offset += glm::vec3 { transformationmatrix * glm::vec4 { vertex.position, 1 } } * vertexfactor; - } + auto const &vertices { ( + m_geometry != null_handle ? + GfxRenderer.Vertices( m_geometry ) : + Vertices ) }; + if( false == vertices.empty() ) { + // transformation matrix for the submodel can still contain rotation and/or scaling, + // so we pass the vertex positions through it rather than just grab them directly + offset = glm::vec3(); + auto const vertexfactor { 1.f / vertices.size() }; + auto const transformationmatrix { glm::make_mat4( parentmatrix.readArray() ) }; + for( auto const &vertex : vertices ) { + offset += glm::vec3 { transformationmatrix * glm::vec4 { vertex.position, 1 } } * vertexfactor; } } }