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

Merge branch 'master' into feat/renderers-cleanup

This commit is contained in:
2026-11-07 16:44:51 +01:00
177 changed files with 11657 additions and 833 deletions

View File

@@ -81,10 +81,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
@@ -139,7 +137,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 > 0.0 && std::isfinite( fNewStep ) ) ? fNewStep : fLength;
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 );
}
@@ -179,8 +177,8 @@ bool TSegment::InitChain(std::vector<std::shared_ptr<TSegment>> Pieces)
Point2 = last.Point2;
fRoll1 = first.fRoll1;
fRoll2 = last.fRoll2;
m_designrolls[ 0 ] = first.m_designrolls[ 0 ];
m_designrolls[ 1 ] = last.m_designrolls[ 1 ];
m_setting.designrolls[ 0 ] = first.m_setting.designrolls[ 0 ];
m_setting.designrolls[ 1 ] = last.m_setting.designrolls[ 1 ];
bCurve = true;
fDirection = -std::atan2(Point2.x - Point1.x, Point2.z - Point1.z);
fStoop = std::atan2(Point2.y - Point1.y, fLength);
@@ -435,21 +433,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 };
@@ -459,30 +442,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
@@ -492,12 +470,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( false == m_pieces.empty() ) {
// the pieces keep to their design, the unevenness is the one of the whole path
auto const piece { piece_at( fDistance ) };
@@ -525,6 +503,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 );
};
glm::dvec3 TSegment::FastGetPoint(double const t) const
@@ -584,9 +573,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;
@@ -633,9 +622,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
@@ -749,13 +738,13 @@ bool TSegment::RenderLoftSteps( gfx::vertex_array &Output, glm::dvec3 const &Ori
auto const offset { 0.1 / fLength };
// point and the unit vector across the path at the k-th of the Steps stations
auto const station = [&]( int const k, glm::vec3 &Position, glm::vec3 &Parallel ) {
if( k == 0 && m_joints[ 0 ] ) {
Position = glm::vec3{ m_joints[ 0 ]->first - Origin };
Parallel = glm::vec3{ m_joints[ 0 ]->second };
if( k == 0 && m_setting.joints[ 0 ] ) {
Position = glm::vec3{ m_setting.joints[ 0 ]->first - Origin };
Parallel = glm::vec3{ m_setting.joints[ 0 ]->second };
return; }
if( k == Steps && m_joints[ 1 ] ) {
Position = glm::vec3{ m_joints[ 1 ]->first - Origin };
Parallel = glm::vec3{ m_joints[ 1 ]->second };
if( k == Steps && m_setting.joints[ 1 ] ) {
Position = glm::vec3{ m_setting.joints[ 1 ]->first - Origin };
Parallel = glm::vec3{ m_setting.joints[ 1 ]->second };
return; }
auto const t { k == 0 ? 0.0 : k == Steps ? 1.0 : FastGetTFromS( fLength * k / Steps ) };
Position = glm::vec3{ FastGetPoint( t ) - Origin };
@@ -957,7 +946,7 @@ bool TSegment::RenderLoftSpan( gfx::vertex_array &Output, glm::dvec3 const &Orig
glm::dvec3 point;
glm::dvec3 across;
plan_frame( Distance, point, across );
if( auto const &joint { m_joints[ Distance < 0.001 ? 0 : 1 ] }; joint && ( Distance < 0.001 || Distance > fLength - 0.001 ) ) {
if( auto const &joint { m_setting.joints[ Distance < 0.001 ? 0 : 1 ] }; joint && ( Distance < 0.001 || Distance > fLength - 0.001 ) ) {
point = joint->first;
across = joint->second;
}