17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-24 16:57:03 +02:00

fix(track): the blending at the joints exactly as long as set, however far apart the vertices

This commit is contained in:
2026-10-22 00:29:00 +02:00
parent c17d77fe6c
commit c7f4790aa9
3 changed files with 21 additions and 17 deletions

View File

@@ -82,11 +82,17 @@ vec2 parallax_coord(sampler2D heights, vec2 coord, vec3 viewdir, vec2 dcoorddx,
void main()
{
// how far the fragment is into the track from the ends, in the lengths of their blending (track_blend::blending::weigh()):
// from -100 down where the track joined there doesn't blend back and its texture goes all the way to the joint, 10000 where
// nothing's blended at the end
#ifdef TRACKBLEND_SPECGLOSS
vec3 weights = clamp(vec3(UserData.yz, 0.0), 0.0, 1.0);
vec3 along = vec3(UserData.yz, 10000.0);
#else
vec3 weights = clamp(UserData.yzw, 0.0, 1.0);
vec3 along = UserData.yzw;
#endif
vec3 single = vec3(lessThan(along, vec3(-50.0)));
vec3 fraction = mix(along, -100.0 - along, single);
vec3 weights = mix(vec3(0.5), vec3(1.0), single) * clamp(1.0 - fraction, 0.0, 1.0);
float total = weights.x + weights.y + weights.z;
if (total > 1.0)
{

View File

@@ -22,9 +22,6 @@ namespace track_blend {
namespace {
// how far aside of the line of an end its weight reaches, past the widest trackbeds
double constexpr lateral_reach { 6.0 };
blending const *current { nullptr };
int end_count( TTrack const &Track ) {
@@ -194,17 +191,13 @@ void blending::weigh( gfx::vertex_array const &Vertices, gfx::userdata_array &Us
auto &data { Userdata[ index ].data };
for( int end = 0; end < 3; ++end ) {
auto const &blend { ends[ end ] };
auto weight { 0.f };
auto value { none_mark };
if( blend.active ) {
// measured along the line of the end, so both tracks give the vertices of their joint the same weight
auto const offset { position - blend.point };
auto const along { glm::dot( offset, blend.inward ) };
auto const aside { glm::length( offset - blend.inward * along ) };
if( along < blend.length && aside < lateral_reach ) {
weight = blend.peak * static_cast<float>( 1.0 - std::max( 0.0, along ) / blend.length );
}
// measured along the line of the end, so both tracks give the vertices of their joint the same distance
auto const fraction { static_cast<float>( glm::dot( position - blend.point, blend.inward ) / blend.length ) };
value = ( blend.peak < 1.f ? fraction : single_mark - fraction );
}
data[ 1 + end ] = weight;
data[ 1 + end ] = value;
}
}
}

View File

@@ -20,7 +20,7 @@ http://mozilla.org/MPL/2.0/.
class TTrack;
// the rails and the ballast of a track blended into those of the tracks joined at its ends, where their textures differ: near
// an end the vertices carry the weight of the track joined there (y, z, w of their user data for the ends p1, p2 and p4 of a
// an end the vertices carry how far they are from it (y, z, w of their user data for the ends p1, p2 and p4 of a
// switch) and the track is drawn with a material fading its texture into theirs. a plain track blends its rails and its
// ballast, a switch the trackbed made for it
namespace track_blend {
@@ -47,9 +47,14 @@ struct blending {
bool any() const {
return material != null_handle; }
// the weights of the ends put in the user data of the vertices (relative to the origin of the track), made as long as the
// vertices where it's shorter; what the user data hold at x is kept
// how far the vertices (relative to the origin of the track) are into it from each end, in the length of its blending, put
// in their user data: distance / length where the track joined blends back, single_mark - distance / length where it doesn't,
// none_mark where nothing's blended at the end. a distance runs straight along the vertices, so it's led between them exactly
// and the shader (trackblend.glsl) works the weight out of it for each fragment, however far apart the vertices are. the user
// data are made as long as the vertices where they're shorter; what they hold at x is kept
void weigh( gfx::vertex_array const &Vertices, gfx::userdata_array &Userdata ) const;
static float constexpr single_mark { -100.f };
static float constexpr none_mark { 10000.f };
};
// how the rails or the ballast of the track blend into those of the tracks joined to it, nothing for the tracks which don't