mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-05 21:49:10 +01:00
fix(track): 3D sleepers let go of the beams of the tracks far away
This commit is contained in:
@@ -5889,6 +5889,11 @@ void opengl46_renderer::Render_Timbers( scene::basic_cell::path_sequence::const_
|
|||||||
// the distance is taken from the camera of the view, the shadow pass culling against its own frustum
|
// the distance is taken from the camera of the view, the shadow pass culling against its own frustum
|
||||||
auto const camera = ( shadows ? m_renderpass.viewport_camera.position() : m_renderpass.pass_camera.position() );
|
auto const camera = ( shadows ? m_renderpass.viewport_camera.position() : m_renderpass.pass_camera.position() );
|
||||||
auto const range = static_cast<double>( shadows ? std::min( Global.SleeperDistance, 50.f ) : Global.SleeperDistance );
|
auto const range = static_cast<double>( shadows ? std::min( Global.SleeperDistance, 50.f ) : Global.SleeperDistance );
|
||||||
|
if( m_renderpass.draw_mode == rendermode::color && m_timbersweepframe != m_framestamp ) {
|
||||||
|
// once a frame the beams of the tracks well past where they're laid and worked out ahead are let go
|
||||||
|
m_timbersweepframe = m_framestamp;
|
||||||
|
track_sleepers::release_far( camera, range + 600.0 );
|
||||||
|
}
|
||||||
glm::mat4 const originmodelview = OpenGLMatrices.data( GL_MODELVIEW );
|
glm::mat4 const originmodelview = OpenGLMatrices.data( GL_MODELVIEW );
|
||||||
for( auto &bucket : m_timberbuckets ) {
|
for( auto &bucket : m_timberbuckets ) {
|
||||||
bucket.instances.clear();
|
bucket.instances.clear();
|
||||||
|
|||||||
@@ -598,6 +598,7 @@ class opengl46_renderer : public gfx_renderer {
|
|||||||
bool m_particlesoft{false}; // the depth for the soft particles is bound in the colour pass being drawn
|
bool m_particlesoft{false}; // the depth for the soft particles is bound in the colour pass being drawn
|
||||||
|
|
||||||
unsigned int m_framestamp; // id of currently rendered gfx frame
|
unsigned int m_framestamp; // id of currently rendered gfx frame
|
||||||
|
unsigned int m_timbersweepframe { 0 }; // the frame the beams of the tracks far away were last let go in
|
||||||
float m_framerate;
|
float m_framerate;
|
||||||
double m_updateaccumulator{0.0};
|
double m_updateaccumulator{0.0};
|
||||||
std::string m_debugtimestext;
|
std::string m_debugtimestext;
|
||||||
|
|||||||
@@ -227,4 +227,10 @@ void settle_background() {
|
|||||||
worker().settle();
|
worker().settle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void forget_layout( TTrack const &Track ) {
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock { clusters_mutex() };
|
||||||
|
known_clusters().erase( &Track );
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace track_sleepers
|
} // namespace track_sleepers
|
||||||
|
|||||||
@@ -27,5 +27,8 @@ bool in_background();
|
|||||||
void ask_layout( TTrack &Track );
|
void ask_layout( TTrack &Track );
|
||||||
// nothing left to work out in the background nor being worked out, the waiting ones dropped
|
// nothing left to work out in the background nor being worked out, the waiting ones dropped
|
||||||
void settle_background();
|
void settle_background();
|
||||||
|
// the layout of the cluster kept for the track let go, once the track laid its beams or went far; the cluster stays while
|
||||||
|
// another track of it keeps it
|
||||||
|
void forget_layout( TTrack const &Track );
|
||||||
|
|
||||||
} // namespace track_sleepers
|
} // namespace track_sleepers
|
||||||
|
|||||||
@@ -1542,7 +1542,8 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
|
|||||||
m_sleepers3d.active = track_sleepers::lays( *this );
|
m_sleepers3d.active = track_sleepers::lays( *this );
|
||||||
// bake per-instance sleeper transforms now that the owning cell has assigned m_origin.
|
// bake per-instance sleeper transforms now that the owning cell has assigned m_origin.
|
||||||
// safe to call here even if the track has no sleepermodel (early-outs internally).
|
// safe to call here even if the track has no sleepermodel (early-outs internally).
|
||||||
if( m_sleeper_enabled && m_sleeper_local_transforms.empty() ) {
|
// a track laying the 3D sleepers draws its sleeper model with them, the transforms of the model alone wouldn't be drawn
|
||||||
|
if( m_sleeper_enabled && false == m_sleepers3d.active && m_sleeper_local_transforms.empty() ) {
|
||||||
build_sleeper_transforms();
|
build_sleeper_transforms();
|
||||||
}
|
}
|
||||||
switch (iCategoryFlag & 15)
|
switch (iCategoryFlag & 15)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
@@ -111,7 +112,6 @@ void lay( TTrack &Track ) {
|
|||||||
}
|
}
|
||||||
laid.whole.clear();
|
laid.whole.clear();
|
||||||
laid.plain.clear();
|
laid.plain.clear();
|
||||||
laid.beams.clear();
|
|
||||||
laid.chunks.clear();
|
laid.chunks.clear();
|
||||||
laid.timbers = timber_model( Track );
|
laid.timbers = timber_model( Track );
|
||||||
laid.plains = plain_model( Track );
|
laid.plains = plain_model( Track );
|
||||||
@@ -125,9 +125,10 @@ void lay( TTrack &Track ) {
|
|||||||
+ to_string( panel.second, 2 ) + " m along, where they share the timbers of its panel" );
|
+ to_string( panel.second, 2 ) + " m along, where they share the timbers of its panel" );
|
||||||
}
|
}
|
||||||
laid.laying = true;
|
laid.laying = true;
|
||||||
laid.beams = ( in_background() ? std::move( placed ) : place( Track ) );
|
auto const beams { in_background() ? std::move( placed ) : place( Track ) };
|
||||||
laid.laying = false;
|
laid.laying = false;
|
||||||
auto const &beams { laid.beams };
|
// the layout of the cluster isn't needed by this track any more, the instances below are what's drawn
|
||||||
|
forget_layout( Track );
|
||||||
|
|
||||||
auto const partlength = [&]( int const Part ) {
|
auto const partlength = [&]( int const Part ) {
|
||||||
return static_cast<double>( parts.spans[ Part ].y - parts.spans[ Part ].x ); };
|
return static_cast<double>( parts.spans[ Part ].y - parts.spans[ Part ].x ); };
|
||||||
@@ -233,6 +234,47 @@ void lay( TTrack &Track ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
close_run();
|
close_run();
|
||||||
|
// kept for as long as the track is near, without the room the vectors grew into
|
||||||
|
for( auto &instances : laid.instances ) {
|
||||||
|
instances.shrink_to_fit();
|
||||||
|
}
|
||||||
|
laid.whole.shrink_to_fit();
|
||||||
|
laid.plain.shrink_to_fit();
|
||||||
|
laid.chunks.shrink_to_fit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void release_far( glm::dvec3 const &Camera, double const Range ) {
|
||||||
|
|
||||||
|
// the tracks swept in slices, so a big scenery costs little in a frame
|
||||||
|
static std::size_t next { 0 };
|
||||||
|
auto const &tracks { simulation::Paths.sequence() };
|
||||||
|
auto const slice { std::min<std::size_t>( tracks.size(), 256 ) };
|
||||||
|
for( std::size_t count = 0; count < slice; ++count ) {
|
||||||
|
if( next >= tracks.size() ) {
|
||||||
|
next = 0;
|
||||||
|
}
|
||||||
|
auto *track { tracks[ next++ ] };
|
||||||
|
if( track == nullptr || false == track->m_sleepers3d.active || track->m_sleepers3d.laying ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if( glm::length( track->location() - Camera ) - track->radius() <= Range ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto &laid { track->m_sleepers3d };
|
||||||
|
forget_layout( *track );
|
||||||
|
auto const holds { laid.chunks.capacity() > 0 || laid.whole.capacity() > 0 || laid.plain.capacity() > 0
|
||||||
|
|| std::any_of( laid.instances.begin(), laid.instances.end(), []( std::vector<glm::mat4> const &Instances ) { return Instances.capacity() > 0; } ) };
|
||||||
|
if( false == holds ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for( auto &instances : laid.instances ) {
|
||||||
|
std::vector<glm::mat4> {}.swap( instances );
|
||||||
|
}
|
||||||
|
std::vector<glm::mat4> {}.swap( laid.whole );
|
||||||
|
std::vector<glm::mat4> {}.swap( laid.plain );
|
||||||
|
std::vector<chunk> {}.swap( laid.chunks );
|
||||||
|
laid.dirty = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
layout_check check() {
|
layout_check check() {
|
||||||
|
|||||||
@@ -86,7 +86,6 @@ struct laid {
|
|||||||
std::vector<glm::mat4> whole; // transforms of the timbers of a model without parts, drawn whole
|
std::vector<glm::mat4> whole; // transforms of the timbers of a model without parts, drawn whole
|
||||||
std::vector<glm::mat4> plain; // transforms of the plain sleepers, whole models, relative to the origin of the track
|
std::vector<glm::mat4> plain; // transforms of the plain sleepers, whole models, relative to the origin of the track
|
||||||
std::vector<chunk> chunks;
|
std::vector<chunk> chunks;
|
||||||
std::vector<beam> beams; // as they're laid
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// how far the ballast of a track with beams is lowered, so they stick out of it
|
// how far the ballast of a track with beams is lowered, so they stick out of it
|
||||||
@@ -130,6 +129,9 @@ void unsettle_around( TTrack &Track );
|
|||||||
void lay_in_background( bool const Background );
|
void lay_in_background( bool const Background );
|
||||||
// the beams of the track worked out ahead, before it comes in range
|
// the beams of the track worked out ahead, before it comes in range
|
||||||
void prefetch( TTrack &Track );
|
void prefetch( TTrack &Track );
|
||||||
|
// the beams of the tracks far from the camera let go, a slice of the tracks each call, to be laid again as they come near;
|
||||||
|
// otherwise each track keeps the beams laid since it was first seen
|
||||||
|
void release_far( glm::dvec3 const &Camera, double const Range );
|
||||||
|
|
||||||
// what's wrong with the layout of the beams of all the tracks: beams over each other, rails with too few beams under them,
|
// what's wrong with the layout of the beams of all the tracks: beams over each other, rails with too few beams under them,
|
||||||
// timbers shared by rails out of one plane
|
// timbers shared by rails out of one plane
|
||||||
|
|||||||
Reference in New Issue
Block a user