mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-03 01:30:16 +01:00
fix(track): obtuse crossings share the running surface too: the top of a rail crossed by the treads of the wheels of the other track takes the brighter texture between the gauge line of the other rail and the edge of its treads, so the boundary runs aslant on both sides
This commit is contained in:
@@ -400,6 +400,7 @@ public:
|
|||||||
material_handle material { 0 };
|
material_handle material { 0 };
|
||||||
int anchor { 0 };
|
int anchor { 0 };
|
||||||
std::vector<glm::dvec2> edge;
|
std::vector<glm::dvec2> edge;
|
||||||
|
std::vector<glm::dvec2> gauge;
|
||||||
bool below { false };
|
bool below { false };
|
||||||
};
|
};
|
||||||
struct rail_layout {
|
struct rail_layout {
|
||||||
|
|||||||
@@ -1066,7 +1066,7 @@ struct frame_corner {
|
|||||||
double facing { 0.0 };
|
double facing { 0.0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<glm::dvec2> tread_edge( TTrack const &Track, int const Path, int const Side, TTrack const &Other, int const Otherpath, int const Otherside, double const From, double const To, bool &Below ) {
|
std::vector<glm::dvec2> tread_edge( TTrack const &Track, int const Path, int const Side, TTrack const &Other, int const Otherpath, int const Otherside, double const From, double const To, bool &Below, std::vector<glm::dvec2> &Gauge ) {
|
||||||
|
|
||||||
auto const &ours { rail_line( Track, Path, Side > 0, false ) };
|
auto const &ours { rail_line( Track, Path, Side > 0, false ) };
|
||||||
auto const &theirs { rail_line( Other, Otherpath, Otherside > 0, false ) };
|
auto const &theirs { rail_line( Other, Otherpath, Otherside > 0, false ) };
|
||||||
@@ -1101,12 +1101,15 @@ std::vector<glm::dvec2> tread_edge( TTrack const &Track, int const Path, int con
|
|||||||
auto const normal { theirs.normal( otherat, Otherside ) };
|
auto const normal { theirs.normal( otherat, Otherside ) };
|
||||||
auto at { distance };
|
auto at { distance };
|
||||||
auto const gauge { project( ours, Side, line, at ) };
|
auto const gauge { project( ours, Side, line, at ) };
|
||||||
|
Gauge.emplace_back( at, gauge );
|
||||||
at = distance;
|
at = distance;
|
||||||
auto const edge { project( ours, Side, line - normal * rolled_band, at ) };
|
auto const edge { project( ours, Side, line - normal * rolled_band, at ) };
|
||||||
below += ( gauge < edge ? 1 : -1 );
|
below += ( gauge < edge ? 1 : -1 );
|
||||||
knots.emplace_back( at, edge );
|
knots.emplace_back( at, edge );
|
||||||
}
|
}
|
||||||
std::sort( knots.begin(), knots.end(), []( glm::dvec2 const &A, glm::dvec2 const &B ) { return A.x < B.x; } );
|
auto const byposition = []( glm::dvec2 const &A, glm::dvec2 const &B ) { return A.x < B.x; };
|
||||||
|
std::sort( knots.begin(), knots.end(), byposition );
|
||||||
|
std::sort( Gauge.begin(), Gauge.end(), byposition );
|
||||||
Below = ( below > 0 );
|
Below = ( below > 0 );
|
||||||
return knots;
|
return knots;
|
||||||
}
|
}
|
||||||
@@ -1179,13 +1182,15 @@ TTrack::rail_layout TTrack::plan_rails( bool const Crossings ) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rail_tread part { Span.x, Span.y, material, Anchor };
|
rail_tread part { Span.x, Span.y, material, Anchor };
|
||||||
part.edge = tread_edge( *this, Path, Side, Other, Otherpath, Otherside, Span.x, Span.y, part.below );
|
part.edge = tread_edge( *this, Path, Side, Other, Otherpath, Otherside, Span.x, Span.y, part.below, part.gauge );
|
||||||
auto from { 1e9 };
|
auto from { 1e9 };
|
||||||
auto to { -1e9 };
|
auto to { -1e9 };
|
||||||
for( auto const &knot : part.edge ) {
|
for( std::size_t i = 0; i < part.edge.size() && i < part.gauge.size(); ++i ) {
|
||||||
if( part.below ? knot.y > 0.0 : knot.y < size.head ) {
|
auto const low { std::min( part.edge[ i ].y, part.gauge[ i ].y ) };
|
||||||
from = std::min( from, knot.x );
|
auto const high { std::max( part.edge[ i ].y, part.gauge[ i ].y ) };
|
||||||
to = std::max( to, knot.x );
|
if( low < size.head && high > 0.0 ) {
|
||||||
|
from = std::min( from, part.edge[ i ].x );
|
||||||
|
to = std::max( to, part.edge[ i ].x );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
part.from = std::max( Span.x, from - 0.1 );
|
part.from = std::max( Span.x, from - 0.1 );
|
||||||
@@ -1271,6 +1276,8 @@ TTrack::rail_layout TTrack::plan_rails( bool const Crossings ) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
obtuse( plan, crossing.at, crossing.into, size );
|
obtuse( plan, crossing.at, crossing.into, size );
|
||||||
|
auto const reach { ( rolled_band + size.head ) / std::max( std::tan( crossing.angle ), 0.01 ) + 0.2 };
|
||||||
|
tread( crossing.path, crossing.side, { crossing.at - reach, crossing.at + reach }, *crossing.track, crossing.otherpath, 0, crossing.otherside );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for( auto &pathguards : guards ) {
|
for( auto &pathguards : guards ) {
|
||||||
@@ -1634,31 +1641,40 @@ bool TTrack::lay_rail( rail_layout const &Layout, rail_drawing const &Drawing, i
|
|||||||
low = std::min( low, static_cast<double>( Side * point.position.x - halfwidth ) );
|
low = std::min( low, static_cast<double>( Side * point.position.x - halfwidth ) );
|
||||||
high = std::max( high, static_cast<double>( Side * point.position.x - halfwidth ) );
|
high = std::max( high, static_cast<double>( Side * point.position.x - halfwidth ) );
|
||||||
}
|
}
|
||||||
|
auto const &lower { Span.below ? Span.gauge : Span.edge };
|
||||||
|
auto const &upper { Span.below ? Span.edge : Span.gauge };
|
||||||
std::vector<double> splits { Start, End };
|
std::vector<double> splits { Start, End };
|
||||||
for( auto const edge : { low, high } ) {
|
for( auto const *knots : { &lower, &upper } ) {
|
||||||
for( std::size_t i = 1; i < Span.edge.size(); ++i ) {
|
for( auto const edge : { low, high } ) {
|
||||||
auto const &a { Span.edge[ i - 1 ] };
|
for( std::size_t i = 1; i < knots->size(); ++i ) {
|
||||||
auto const &b { Span.edge[ i ] };
|
auto const &a { ( *knots )[ i - 1 ] };
|
||||||
if( ( a.y - edge ) * ( b.y - edge ) < 0.0 ) {
|
auto const &b { ( *knots )[ i ] };
|
||||||
auto const distance { a.x + ( edge - a.y ) / ( b.y - a.y ) * ( b.x - a.x ) };
|
if( ( a.y - edge ) * ( b.y - edge ) < 0.0 ) {
|
||||||
if( distance > Start + 0.001 && distance < End - 0.001 ) {
|
auto const distance { a.x + ( edge - a.y ) / ( b.y - a.y ) * ( b.x - a.x ) };
|
||||||
splits.push_back( distance );
|
if( distance > Start + 0.001 && distance < End - 0.001 ) {
|
||||||
|
splits.push_back( distance );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::sort( splits.begin(), splits.end() );
|
std::sort( splits.begin(), splits.end() );
|
||||||
auto const below { bound( Extents, Span.edge, true ) };
|
auto const inside { bound( Extents, upper, true ) };
|
||||||
auto const above { bound( Inner, Span.edge, false ) };
|
|
||||||
for( std::size_t i = 1; i < splits.size(); ++i ) {
|
for( std::size_t i = 1; i < splits.size(); ++i ) {
|
||||||
auto const edge { level( Span.edge, 0.5 * ( splits[ i - 1 ] + splits[ i ] ) ) };
|
auto const middle { 0.5 * ( splits[ i - 1 ] + splits[ i ] ) };
|
||||||
if( edge > low ) {
|
auto const from { level( lower, middle ) };
|
||||||
current = ( Span.below ? Span.material : null_handle );
|
auto const to { level( upper, middle ) };
|
||||||
piece( splits[ i - 1 ], splits[ i ], Offsets, below, false, false, top, true, Inner );
|
if( from > low ) {
|
||||||
|
current = null_handle;
|
||||||
|
piece( splits[ i - 1 ], splits[ i ], Offsets, bound( Extents, lower, true ), false, false, top, true, Inner );
|
||||||
}
|
}
|
||||||
if( edge < high ) {
|
if( to > low && from < high ) {
|
||||||
current = ( Span.below ? null_handle : Span.material );
|
current = Span.material;
|
||||||
piece( splits[ i - 1 ], splits[ i ], Offsets, Extents, false, false, top, true, above );
|
piece( splits[ i - 1 ], splits[ i ], Offsets, inside, false, false, top, true, bound( Inner, lower, false ) );
|
||||||
|
}
|
||||||
|
if( to < high ) {
|
||||||
|
current = null_handle;
|
||||||
|
piece( splits[ i - 1 ], splits[ i ], Offsets, Extents, false, false, top, true, bound( Inner, upper, false ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
current = null_handle;
|
current = null_handle;
|
||||||
|
|||||||
Reference in New Issue
Block a user