mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-03 16:40:21 +01:00
feat(editor,track): a cant ramp of its own, off the transition curve: each end of a curve may have its ramp moved and of a length of its own (ST-T1-A6 9.6 pkt 5 and 11), on the straight before the curve or on the arc, the transition keeping the full cant all along, as a switch laid on it wants it; set in the plan under "Cant ramps", stored with the vertex as "ramps", reversed with the curve, marked across the track in the view. The cant of a line is a profile along it now, the paths cut where a ramp of its own starts and ends, their rolls following it, warnings where a ramp is shorter than its cant asks for or reaches into the curve before, past the line or over the other ramp. A switch on a cant ramp is drawn following it: its rails, blades, frogs and bed made at the mean of its rolls, as before, are turned along each path to the roll of the path there, so it no longer steps at its ends against the tracks either side. The checks of a switch laid into a curve warn of the values of table 11.9 in brackets as of the others, with no word of a consent. Unit test of a ramp moved onto the straight
This commit is contained in:
@@ -578,6 +578,7 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin,
|
||||
pt,
|
||||
glm::normalize( norm ),
|
||||
glm::vec2 { ( jmm1 * ShapePoints[ j ].texture.x + m1 * ShapePoints[ j + iNumShapePoints ].texture.x ) / texturescale, tv1 } );
|
||||
roll_vertex( Output.back(), pos1, parallel1, s - step );
|
||||
}
|
||||
// jeśli jest wskaźnik do tablicy
|
||||
if (p && *p && !j) // to dla pierwszego punktu
|
||||
@@ -596,6 +597,7 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin,
|
||||
pt,
|
||||
glm::normalize( norm ),
|
||||
glm::vec2 { ( jmm2 * ShapePoints[ j ].texture.x + m2 * ShapePoints[ j + iNumShapePoints ].texture.x ) / texturescale, tv2 } );
|
||||
roll_vertex( Output.back(), pos2, parallel2, s );
|
||||
}
|
||||
// jeśli jest wskaźnik do tablicy
|
||||
// to dla pierwszego punktu
|
||||
@@ -618,6 +620,7 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin,
|
||||
pt,
|
||||
glm::normalize( norm ),
|
||||
glm::vec2 { ShapePoints[ j ].texture.x / texturescale, tv1 } );
|
||||
roll_vertex( Output.back(), pos1, parallel1, s - step );
|
||||
|
||||
pt = parallel2 * ( jmm2 * ( ShapePoints[ j ].position.x - fOffsetX.first ) + m2 * ( ShapePoints[ j ].position.x - fOffsetX.second ) ) + pos2;
|
||||
pt.y += ShapePoints[ j ].position.y;
|
||||
@@ -628,6 +631,7 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin,
|
||||
pt,
|
||||
glm::normalize( norm ),
|
||||
glm::vec2 { ShapePoints[ j ].texture.x / texturescale, tv2 } );
|
||||
roll_vertex( Output.back(), pos2, parallel2, s );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -638,6 +642,25 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin,
|
||||
return true;
|
||||
};
|
||||
|
||||
void TSegment::roll_vertex( gfx::basic_vertex &Vertex, glm::vec3 const &Position, glm::vec3 const &Parallel, double const Distance ) const {
|
||||
if( false == m_baked_roll.has_value() ) {
|
||||
return;
|
||||
}
|
||||
auto const delta { GetRoll( std::clamp( Distance, 0.0, fLength ) ) - *m_baked_roll };
|
||||
if( std::abs( delta ) < 1e-6f ) {
|
||||
return;
|
||||
}
|
||||
auto const c { std::cos( delta ) };
|
||||
auto const s { std::sin( delta ) };
|
||||
// across the path and up turned the way the profiles are turned by the roll, along the path as it was
|
||||
auto const turn = [&]( glm::vec3 const &Vector ) {
|
||||
auto const across { glm::dot( Vector, Parallel ) };
|
||||
auto const along { Vector - Parallel * across - glm::vec3 { 0.f, Vector.y, 0.f } };
|
||||
return along + Parallel * ( across * c + Vector.y * s ) + glm::vec3 { 0.f, -across * s + Vector.y * c, 0.f }; };
|
||||
Vertex.position = Position + turn( Vertex.position - Position );
|
||||
Vertex.normal = turn( Vertex.normal );
|
||||
}
|
||||
|
||||
bool TSegment::RenderLoftSteps( gfx::vertex_array &Output, glm::dvec3 const &Origin, gfx::vertex_array const &ShapePoints, double fTextureLength, int const Steps ) const
|
||||
{
|
||||
if( fTsBuffer.empty() || Steps < 1 || fLength <= 0.0 )
|
||||
@@ -675,7 +698,8 @@ bool TSegment::RenderLoftSteps( gfx::vertex_array &Output, glm::dvec3 const &Ori
|
||||
point.y += rest * from.position.y + Share * to.position.y;
|
||||
auto normal { ( rest * from.normal.x + Share * to.normal.x ) * Parallel };
|
||||
normal.y += rest * from.normal.y + Share * to.normal.y;
|
||||
Output.emplace_back( point, glm::normalize( normal ), glm::vec2 { rest * from.texture.x + Share * to.texture.x, V } ); };
|
||||
Output.emplace_back( point, glm::normalize( normal ), glm::vec2 { rest * from.texture.x + Share * to.texture.x, V } );
|
||||
roll_vertex( Output.back(), Position, Parallel, Share * fLength ); };
|
||||
|
||||
glm::vec3 pos1, pos2, parallel1, parallel2;
|
||||
station( 0, pos1, parallel1 );
|
||||
@@ -917,6 +941,9 @@ bool TSegment::RenderLoftSpan( gfx::vertex_array &Output, glm::dvec3 const &Orig
|
||||
Ring.emplace_back( pt, glm::normalize( norm ), glm::vec2{ shape.texture.x, 0.f } );
|
||||
Wear.push_back( Span.rampwidth != 0.0 ? static_cast<float>( std::clamp( ( Span.rampwidth > 0.0 ? outside - worn : worn - outside ) / std::abs( Span.rampwidth ) + 1.0, 0.0, 1.0 ) ) : 1.f );
|
||||
}
|
||||
for( auto &vertex : Ring ) {
|
||||
roll_vertex( vertex, position, parallel, Distance );
|
||||
}
|
||||
};
|
||||
|
||||
auto const texturelength { static_cast<float>( Span.texturelength ) };
|
||||
|
||||
@@ -102,6 +102,9 @@ class TSegment
|
||||
std::vector<double> m_starts; // distance from Point1 to the start of each part
|
||||
std::optional<std::pair<glm::dvec3, glm::dvec3>> m_joints[ 2 ];
|
||||
double m_dense { 0.0 };
|
||||
// a switch makes the profiles of its rails and its bed at the mean of the rolls of its paths: lofted along a path, they're turned
|
||||
// from it to the roll of the path there, so a switch on a cant ramp follows it; none for the other paths
|
||||
std::optional<float> m_baked_roll;
|
||||
|
||||
glm::dvec3 GetFirstDerivative(double const fTime) const;
|
||||
double RombergIntegral(double const fA, double const fB) const;
|
||||
@@ -111,6 +114,8 @@ class TSegment
|
||||
glm::dvec3 RaInterpolate(double const t) const;
|
||||
glm::dvec3 RaInterpolate0(double const t) const;
|
||||
std::size_t piece_at(double const s) const;
|
||||
// the vertex of a profile lofted at the point and across the path there, turned from the baked roll to the one of the path at the distance
|
||||
void roll_vertex( gfx::basic_vertex &Vertex, glm::vec3 const &Position, glm::vec3 const &Parallel, double const Distance ) const;
|
||||
|
||||
public:
|
||||
bool bCurve = false;
|
||||
@@ -200,6 +205,9 @@ public:
|
||||
void
|
||||
set_dense( double const Distance ) {
|
||||
m_dense = Distance; }
|
||||
void
|
||||
set_baked_roll( std::optional<float> const Roll ) {
|
||||
m_baked_roll = Roll; }
|
||||
/*
|
||||
void
|
||||
Render();
|
||||
|
||||
@@ -1086,6 +1086,13 @@ void TTrack::init_segments( bool const Initial ) {
|
||||
fTexHeightOffset = texheightoffset;
|
||||
SwitchExtension->Segments[ index ]->InitChain( std::move( chain ) );
|
||||
}
|
||||
// the profiles of the switch are made at the mean of the rolls of its paths; lofted, they're turned from it to the roll of
|
||||
// each path along it, so a switch on a cant ramp follows the ramp to its ends
|
||||
float mean1, mean2;
|
||||
profile_rolls( mean1, mean2 );
|
||||
for( std::size_t index = 0; index < 2; ++index ) {
|
||||
SwitchExtension->Segments[ index ]->set_baked_roll( mean1 );
|
||||
}
|
||||
}
|
||||
|
||||
if( Initial ) {
|
||||
|
||||
Reference in New Issue
Block a user