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

fix: restore min>max tolerance lost in clamp->std::clamp migration

The dumb3d->glm / utilities-simplification refactor replaced the old custom
clamp() (which tolerated Lo>Hi, returning the upper bound) with std::clamp,
where inverted bounds are undefined behaviour. Only a few sites were patched
afterwards, by hand, with std::minmax plumbing (incl. a stray `static` inside
a per-axle loop). Others silently produced wrong results in the AI braking /
acceleration path.

Add a safe_clamp() helper (normalizes inverted bounds) and use it ONLY where
Lo<=Hi cannot be proven at compile time (config min/max pairs, sign-dependent
expressions, container underflow). Sites with constant bounds or [0, x>=0]
keep std::clamp. Remove the manual std::minmax workarounds and rewrite the
damaged-track jolt code value-first.
This commit is contained in:
maj00r
2026-07-02 00:16:03 +02:00
parent 80c3feac03
commit 03bfbb1345
4 changed files with 33 additions and 23 deletions

View File

@@ -3701,7 +3701,7 @@ bool TController::IncSpeedEIM() {
// TBD, TODO: set position based on desired acceleration?
OK = mvControlling->MainCtrlPos < mvControlling->MainCtrlPosNo;
if( OK ) {
mvControlling->MainCtrlPos = std::clamp( mvControlling->MainCtrlPos + 1, 6, mvControlling->MainCtrlPosNo );
mvControlling->MainCtrlPos = safe_clamp( mvControlling->MainCtrlPos + 1, 6, mvControlling->MainCtrlPosNo );
}
*/
break;
@@ -7669,7 +7669,7 @@ TController::adjust_desired_speed_for_current_speed() {
if( iVehicles - ControlledEnginesCount > 0 ) {
MaxAcc *= std::clamp( vel * 0.025, 0.2, 1.0 );
}
AccDesired = std::min(AccDesired, std::clamp(MaxAcc, HeavyCargoTrainAcceleration, AccPreferred));
AccDesired = std::min(AccDesired, safe_clamp(MaxAcc, HeavyCargoTrainAcceleration, AccPreferred));
// TBD: expand this behaviour to all trains with car(s) exceeding certain weight?
/*
if( ( IsPassengerTrain ) && ( iVehicles - ControlledEnginesCount > 0 ) ) {
@@ -7770,8 +7770,7 @@ TController::adjust_desired_speed_for_braking_test() {
break;
}
case 3: {
auto [minV, maxV] = std::minmax(fAccThreshold * 1.01f, fAccThreshold * 1.21f);
AccDesired = std::clamp(-AbsAccS, minV, maxV);
AccDesired = safe_clamp( -AbsAccS, fAccThreshold * 1.01, fAccThreshold * 1.21 );
VelDesired = DBT_VelocityBrake;
if( vel <= DBT_VelocityRelease ) {
DynamicBrakeTest = 4;

View File

@@ -3014,7 +3014,7 @@ TDynamicObject::update_load_offset() {
0.0 :
100.0 * MoverParameters->LoadAmount / MoverParameters->MaxLoad ) };
LoadOffset = std::lerp( MoverParameters->LoadType.offset_min, 0.f, std::clamp( 0.0, loadpercentage * 0.01, 1.0 ) );
LoadOffset = std::lerp( MoverParameters->LoadType.offset_min, 0.f, safe_clamp( 0.0, loadpercentage * 0.01, 1.0 ) );
}
void
@@ -3453,7 +3453,7 @@ bool TDynamicObject::Update(double dt, double dt1)
else
p->MoverParameters->MED_EPVC_CurrentTime += dt1;
bool EPVC = p->MoverParameters->MED_EPVC && (p->MoverParameters->MED_EPVC_Time < 0 || p->MoverParameters->MED_EPVC_CurrentTime < p->MoverParameters->MED_EPVC_Time);
float VelC = EPVC ? std::clamp(p->MoverParameters->Vel, p->MoverParameters->MED_Vmin, p->MoverParameters->MED_Vmax) : p->MoverParameters->MED_Vref;//korekcja EP po prędkości
float VelC = EPVC ? safe_clamp(p->MoverParameters->Vel, p->MoverParameters->MED_Vmin, p->MoverParameters->MED_Vmax) : p->MoverParameters->MED_Vref;//korekcja EP po prędkości
float FmaxPoj = Nmax *
p->MoverParameters->Hamulec->GetFC(
Nmax / (p->MoverParameters->NAxles * p->MoverParameters->NBpA), VelC) *
@@ -3647,22 +3647,20 @@ bool TDynamicObject::Update(double dt, double dt1)
// crude bump simulation, drop down on even axles, move back up on
// the odd ones
// MoverParameters->AccVert += (MoverParameters->Vel*0.1f) *
static double minV, maxV;
std::tie(minV, maxV) = std::minmax(MoverParameters->Vmax, MoverParameters->Vmax - (MoverParameters->Vel + MoverParameters->Vmax * 0.32f));
double precalculatedValue = std::clamp(0.0, minV, maxV) * .05f * (MyTrack->iDamageFlag * 0.25f);
double const headroom = std::clamp(
MoverParameters->Vmax - ( MoverParameters->Vel + MoverParameters->Vmax * 0.32f ),
0.0, MoverParameters->Vmax );
double const jolt = headroom * .05f * ( MyTrack->iDamageFlag * 0.25f );
if (MyTrack->eType == tt_Normal)
{
std::tie(minV, maxV) = std::minmax(4.0, precalculatedValue);
MoverParameters->AccVert += std::clamp(0.0, minV, maxV);
MoverParameters->AccVert += std::clamp( jolt, 0.0, 4.0 );
}
else if (MyTrack->eType == tt_Switch)
{
std::tie(minV, maxV) = std::minmax(1.0, precalculatedValue);
double accHorizontal = std::clamp(0.0, minV, maxV) * (axleindex % 2 != 0 ? 1 : -1);
double const accHorizontal = std::clamp( jolt, 0.0, 1.0 ) * ((axleindex % 2) != 0 ? 1 : -1);
MoverParameters->AccS += accHorizontal;
MoverParameters->AccN += accHorizontal;
std::tie(minV, maxV) = std::minmax(2.0, precalculatedValue);
MoverParameters->AccVert += std::clamp(0.0, minV, maxV);
MoverParameters->AccVert += std::clamp( jolt, 0.0, 2.0 );
}
}
}