17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-11-08 21:00:03 +01:00

fix(track): what Sonar reports on the unevenness

The blockers are in the EP brake of a vehicle, older than this work: its
arrays made with new[] are vectors now, which also removes the deletes.

- The caches of the unevenness of a track are no longer mutable: what fills
  them isn't const any more.
- TSegment gets back to RaPositionGet in one piece, with what the path has
  to do with the others in one struct.
- Less nesting in the group of switches and in the fields of the editor,
  nested conditionals written out, and the attribute is read from a
  string_view. A test no longer counts in floating point.

No change in behaviour.
This commit is contained in:
maj00r
2026-10-31 20:17:47 +01:00
parent 56d389e2df
commit 9364b03e1a
9 changed files with 223 additions and 207 deletions

View File

@@ -69,10 +69,8 @@ bool TSegment::Init(glm::dvec3 &NewPoint1, glm::dvec3 NewCPointOut, glm::dvec3 N
// poprawienie przechyłki
fRoll1 = static_cast<float>(glm::radians(fNewRoll1)); // Ra: przeliczone jest bardziej przydatne do obliczeń
fRoll2 = static_cast<float>(glm::radians(fNewRoll2));
m_designrolls[ 0 ] = fRoll1;
m_designrolls[ 1 ] = fRoll2;
m_joints[ 0 ].reset();
m_joints[ 1 ].reset();
m_setting.designrolls = { fRoll1, fRoll2 };
m_setting.joints = {};
bCurve = bIsCurve;
if (Global.bRollFix)
{ // Ra: poprawianie przechyłki
@@ -122,7 +120,7 @@ bool TSegment::Init(glm::dvec3 &NewPoint1, glm::dvec3 NewCPointOut, glm::dvec3 N
fStoop = std::atan2(Point2.y - Point1.y, fLength); // pochylenie toru prostego, żeby nie liczyć wielokrotnie
fStep = fNewStep;
if( m_uneven && pOwner->eType != tt_Switch ) {
if( m_setting.uneven && pOwner->eType != tt_Switch ) {
// dense enough for the waves; a switch keeps its division, the blades depend on it
fStep = std::min( fStep, 2.0 );
}
@@ -373,21 +371,6 @@ Math3D::vector3 TSegment::GetPoint(double const fDistance) const
};
*/
void TSegment::RaPositionGet(double const fDistance, glm::dvec3 &position, glm::vec3 &rotation) const {
design_position( fDistance, position, rotation );
if( false == m_uneven ) {
return;
}
// direction and slope stay as designed: the physics takes the curve radius and the grade from them
auto const gauge { std::max( std::abs( pOwner->fTrackWidth ), 0.1f ) };
glm::dvec3 const across { -std::cos( rotation.z ), 0.0, -std::sin( rotation.z ) };
auto const amount { pOwner->uneven_at( fDistance, m_path ) };
rotation.x += static_cast<float>( track_uneven::stray_per_mm * (
amount.up * track_uneven::roll( position, across, gauge )
+ amount.cross * track_uneven::level( position, across ) / gauge ) );
position += track_uneven::across_only( stray( position, amount, fDistance ), across );
}
glm::dvec3 TSegment::stray( glm::dvec3 const &Point, track_uneven::amounts const &Amount, double const Distance ) const {
auto const field { track_uneven::field( Point ) };
glm::dvec3 result { field.x * Amount.side, field.y * Amount.up, field.z * Amount.side };
@@ -397,30 +380,25 @@ glm::dvec3 TSegment::stray( glm::dvec3 const &Point, track_uneven::amounts const
}
glm::dvec3 TSegment::uneven_bend( double const Distance ) const {
if( false == m_uneven ) {
if( false == m_setting.uneven ) {
return glm::dvec3 { 0.0 };
}
// over about a bogie
auto const reach { 1.5 };
auto const strayed = [&]( double const At ) {
return stray( point_extended( At ), pOwner->uneven_at( At, m_path ), At ); };
auto const strayed = [ this ]( double const At ) {
// past the ends of the path straight on: the polynomial would run off on a short curved one
auto const on { std::clamp( At, 0.0, fLength ) };
auto const t { FastGetTFromS( on ) };
auto point { FastGetPoint( t ) };
if( auto const direction { FastGetDirection( t, 0.1 / fLength ) }; on != At && glm::length( direction ) > 0.0 ) {
point += direction * ( ( At - on ) / glm::length( direction ) );
}
return stray( point, pOwner->uneven_at( At, m_setting.path ), At ); };
return ( strayed( Distance + reach ) - 2.0 * strayed( Distance ) + strayed( Distance - reach ) ) / ( reach * reach );
}
glm::dvec3 TSegment::point_extended( double const Distance ) const {
auto const on { std::clamp( Distance, 0.0, fLength ) };
auto const t { FastGetTFromS( on ) };
auto const point { FastGetPoint( t ) };
if( on == Distance ) {
return point;
}
auto const direction { FastGetDirection( t, 0.1 / fLength ) };
auto const size { glm::length( direction ) };
return size > 0.0 ? point + direction * ( ( Distance - on ) / size ) : point;
}
void TSegment::settle_vertex( gfx::basic_vertex &Vertex, glm::dvec3 const &Origin, glm::vec3 const &Position, glm::vec3 const &Parallel, double const Distance ) const {
if( false == m_uneven ) {
if( false == m_setting.uneven ) {
return;
}
// the rails settling apart turn about the middle of the track, what's outside them follows the rail; the foot of the ballast stays
@@ -430,12 +408,12 @@ void TSegment::settle_vertex( gfx::basic_vertex &Vertex, glm::dvec3 const &Origi
if( share <= 0.0 ) {
return;
}
auto const amount { pOwner->uneven_at( Distance, m_path ) };
auto const amount { pOwner->uneven_at( Distance, m_setting.path ) };
Vertex.position.y -= static_cast<float>( share * track_uneven::stray_per_mm * amount.cross * track_uneven::level( Origin + glm::dvec3 { Position }, glm::dvec3 { Parallel } ) * across / gauge );
Vertex.position += glm::vec3 { share * stray( Origin + glm::dvec3 { Vertex.position }, amount, Distance ) };
}
void TSegment::design_position(double const fDistance, glm::dvec3 &position, glm::vec3 &rotation) const {
void TSegment::RaPositionGet(double const fDistance, glm::dvec3 &position, glm::vec3 &rotation) const {
if (bCurve) {
// można by wprowadzić uproszczony wzór dla okręgów płaskich
auto const t = FastGetTFromS(fDistance); // aproksymacja dystansu na krzywej Beziera na parametr (t)
@@ -458,6 +436,17 @@ void TSegment::design_position(double const fDistance, glm::dvec3 &position, glm
rotation.y = static_cast<float>(fStoop); // pochylenie toru prostego
rotation.z = static_cast<float>(fDirection); // kierunek toru w planie
}
if( false == m_setting.uneven ) {
return;
}
// direction and slope stay as designed: the physics takes the curve radius and the grade from them
auto const gauge { std::max( std::abs( pOwner->fTrackWidth ), 0.1f ) };
glm::dvec3 const across { -std::cos( rotation.z ), 0.0, -std::sin( rotation.z ) };
auto const amount { pOwner->uneven_at( fDistance, m_setting.path ) };
rotation.x += static_cast<float>( track_uneven::stray_per_mm * (
amount.up * track_uneven::roll( position, across, gauge )
+ amount.cross * track_uneven::level( position, across ) / gauge ) );
position += track_uneven::across_only( stray( position, amount, fDistance ), across );
};
void TSegment::plan_frame( double const Distance, glm::dvec3 &Point, glm::dvec3 &Across ) const {
@@ -523,9 +512,9 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin,
parallel1 = glm::vec3{ glm::dvec3{ FastGetPoint_1() - FastGetPoint_0() } };
}
parallel1 = glm::normalize( parallel1 );
if( iSkip == 0 && m_joints[ 0 ] ) {
pos1 = glm::vec3{ m_joints[ 0 ]->first - Origin };
parallel1 = glm::vec3{ m_joints[ 0 ]->second };
if( iSkip == 0 && m_setting.joints[ 0 ] ) {
pos1 = glm::vec3{ m_setting.joints[ 0 ]->first - Origin };
parallel1 = glm::vec3{ m_setting.joints[ 0 ]->second };
}
if( iEnd == 0 )
iEnd = iSegCount;
@@ -572,9 +561,9 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin,
parallel2 = glm::vec3{ glm::dvec3{ FastGetPoint_1() - FastGetPoint_0() } };
}
parallel2 = glm::normalize( parallel2 );
if( i == iSegCount && m_joints[ 1 ] ) {
pos2 = glm::vec3{ m_joints[ 1 ]->first - Origin };
parallel2 = glm::vec3{ m_joints[ 1 ]->second };
if( i == iSegCount && m_setting.joints[ 1 ] ) {
pos2 = glm::vec3{ m_setting.joints[ 1 ]->first - Origin };
parallel2 = glm::vec3{ m_setting.joints[ 1 ]->second };
}
// TODO: refactor the loop, there's no need to calculate starting points for each segment when we can copy the end points of the previous one