From b2dcb8a42e419e60ce689462c4a10a9004bd48b0 Mon Sep 17 00:00:00 2001 From: maj00r Date: Sat, 31 Oct 2026 18:21:28 +0100 Subject: [PATCH] fix(vehicle): wheel clatter on an uneven track doesn't loop into a buzz The phase of the rails was wrapped to the rail length of the track the vehicle is on, while an axle can be on a track with longer rails. From then on every frame looked like a joint crossed. --- vehicle/DynObj.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/vehicle/DynObj.cpp b/vehicle/DynObj.cpp index 83354288..2c56cb7c 100644 --- a/vehicle/DynObj.cpp +++ b/vehicle/DynObj.cpp @@ -3665,16 +3665,19 @@ bool TDynamicObject::Update(double dt, double dt1) auto const railphase { Axle0.RailPhase( axle.offset - 0.5 * fAxleDist ) }; auto crossed { false }; if( railphase >= 0.0 ) { - crossed = axle.atjoints && std::abs( railphase - axle.distance ) > 0.5 * dRailLength; + // the rails under the axle, which aren't always those under the track the vehicle is on + crossed = axle.atjoints && std::abs( railphase - axle.distance ) > 0.5 * Axle0.GetTrack()->fSoundDistance; axle.distance = railphase; } else { axle.distance += dDOMoveLen * directioninconsist; crossed = axle.distance < 0 || axle.distance > dRailLength; + if( crossed ) { + axle.distance = clamp_circular( axle.distance, dRailLength ); + } } axle.atjoints = ( railphase >= 0.0 ); if( crossed ) { - axle.distance = clamp_circular( axle.distance, dRailLength ); if( MoverParameters->Vel > 0.1 ) { // NOTE: for combined clatter sound we supply 1/100th of actual value, as the sound module converts does the opposite, converting received (typically) 0-1 values to 0-100 range auto const frequency = true == axle.clatter.is_combined() ? MoverParameters->Vel * 0.01 : 1.0;