From 7e91a52646cc676aeb459f5f89f93baeceeddfcf Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Sat, 10 Aug 2019 22:24:28 +0200 Subject: [PATCH] basic smoke quality settings --- Globals.cpp | 18 ++++++++++++------ Globals.h | 2 ++ particles.cpp | 17 ++++++++++------- particles.h | 15 +++++++++++++-- renderer.cpp | 4 ++++ 5 files changed, 41 insertions(+), 15 deletions(-) diff --git a/Globals.cpp b/Globals.cpp index c095ed65..ac44aaa0 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -175,12 +175,6 @@ global_settings::ConfigParse(cParser &Parser) { Parser.getTokens(); Parser >> DisabledLogTypes; } - else if( token == "adjustscreenfreq" ) - { - // McZapkie-240403 - czestotliwosc odswiezania ekranu - Parser.getTokens(); - Parser >> bAdjustScreenFreq; - } else if (token == "mousescale") { // McZapkie-060503 - czulosc ruchu myszy (krecenia glowa) @@ -367,6 +361,18 @@ global_settings::ConfigParse(cParser &Parser) { Parser.getTokens(); Parser >> RenderCabShadowsRange; } + else if( token == "gfx.smoke" ) { + // smoke visualization toggle + Parser.getTokens(); + Parser >> Smoke; + } + else if( token == "gfx.smoke.fidelity" ) { + // smoke visualization fidelity + float smokefidelity; + Parser.getTokens(); + Parser >> smokefidelity; + SmokeFidelity = clamp( smokefidelity, 1.f, 4.f ); + } else if (token == "smoothtraction") { // podwójna jasność ambient diff --git a/Globals.h b/Globals.h index d5bbcc29..695b06bc 100644 --- a/Globals.h +++ b/Globals.h @@ -123,6 +123,8 @@ struct global_settings { int iMultisampling{ 2 }; // tryb antyaliasingu: 0=brak,1=2px,2=4px,3=8px,4=16px bool bSmoothTraction{ true }; // wygładzanie drutów starym sposobem float SplineFidelity{ 1.f }; // determines segment size during conversion of splines to geometry + bool Smoke{ true }; // toggles smoke simulation and visualization + float SmokeFidelity{ 1.f }; // determines amount of generated smoke particles bool ResourceSweep{ true }; // gfx resource garbage collection bool ResourceMove{ false }; // gfx resources are moved between cpu and gpu side instead of sending a copy bool compress_tex{ true }; // all textures are compressed on gpu side diff --git a/particles.cpp b/particles.cpp index f8011155..3f186f3f 100644 --- a/particles.cpp +++ b/particles.cpp @@ -58,7 +58,7 @@ smoke_source::particle_emitter::initialize( smoke_particle &Particle ) { Particle.rotation = glm::radians( Random( 0, 360 ) ); Particle.size = Random( size[ value_limit::min ], size[ value_limit::max ] ); - Particle.opacity = Random( opacity[ value_limit::min ], opacity[ value_limit::max ] ); + Particle.opacity = Random( opacity[ value_limit::min ], opacity[ value_limit::max ] ) / Global.SmokeFidelity; Particle.age = 0; } @@ -112,7 +112,7 @@ smoke_source::initialize() { m_particles.reserve( // put a cap on number of particles in a single source. TBD, TODO: make it part of he source configuration? std::min( - 500, + static_cast( 500 * Global.SmokeFidelity ), // NOTE: given nature of the smoke we're presuming opacity decreases over time and the particle is killed when it reaches 0 // this gives us estimate of longest potential lifespan of single particle, and how many particles total can there be at any given time // TBD, TODO: explicit lifespan variable as part of the source configuration? @@ -150,10 +150,10 @@ smoke_source::update( double const Timedelta, bool const Onlydespawn ) { glm::dvec3{ std::numeric_limits::lowest() } }; m_spawncount = ( - Onlydespawn ? + ( ( false == Global.Smoke ) || ( true == Onlydespawn ) ) ? 0.f : std::min( - m_spawncount + ( m_spawnrate * Timedelta ), + m_spawncount + ( m_spawnrate * Timedelta * Global.SmokeFidelity ), m_particles.capacity() ) ); // update spawned particles for( auto particleiterator { std::begin( m_particles ) }; particleiterator != std::end( m_particles ); ++particleiterator ) { @@ -276,13 +276,14 @@ smoke_source::initialize( smoke_particle &Particle ) { if( m_ownertype == owner_type::vehicle ) { Particle.opacity *= m_owner.vehicle->MoverParameters->dizel_fill; + auto const enginerevolutionsfactor { 1.5f }; // high engine revolutions increase initial particle velocity switch( m_owner.vehicle->MoverParameters->EngineType ) { case TEngineType::DieselElectric: { - Particle.velocity *= 1.0 + m_owner.vehicle->MoverParameters->enrot / ( m_owner.vehicle->MoverParameters->DElist[ m_owner.vehicle->MoverParameters->MainCtrlPosNo ].RPM / 60.0 ); + Particle.velocity *= 1.0 + enginerevolutionsfactor * m_owner.vehicle->MoverParameters->enrot / ( m_owner.vehicle->MoverParameters->DElist[ m_owner.vehicle->MoverParameters->MainCtrlPosNo ].RPM / 60.0 ); break; } case TEngineType::DieselEngine: { - Particle.velocity *= 1.0 + m_owner.vehicle->MoverParameters->enrot / m_owner.vehicle->MoverParameters->nmax; + Particle.velocity *= 1.0 + enginerevolutionsfactor * m_owner.vehicle->MoverParameters->enrot / m_owner.vehicle->MoverParameters->nmax; break; } default: { @@ -398,7 +399,9 @@ particle_manager::find( std::string const &Template ) { // ... and if it fails try to add the template to the database from a data file smoke_source source; if( source.deserialize( cParser( templatepath + templatename + ".txt", cParser::buffer_FILE ) ) ) { - // if deserialization didn't fail cache the source as template for future instances + // if deserialization didn't fail finish source setup... + source.m_opacitymodifier.bind( &Global.SmokeFidelity ); + // ...then cache the source as template for future instances m_sourcetemplates.emplace( templatename, source ); // should be 'safe enough' to return lookup result directly afterwards return &( m_sourcetemplates.find( templatename )->second ); diff --git a/particles.h b/particles.h index f7de0630..b8448817 100644 --- a/particles.h +++ b/particles.h @@ -48,9 +48,15 @@ public: // updates state of provided variable void update( Type_ &Variable, double const Timedelta ) const; + void + bind( Type_ const *Modifier ) { + m_valuechangemodifier = Modifier; } Type_ const & value_change() const { - return m_valuechange; } + return ( + m_valuechangemodifier == nullptr ? + m_valuechange : + m_valuechange / *( m_valuechangemodifier ) ); } private: //types @@ -59,6 +65,7 @@ private: // Type_ m_intialvalue { Type_( 0 ) }; // meters per second; velocity applied to freshly spawned particles Type_ m_valuechange { Type_( 0 ) }; // meters per second; change applied to initial velocity Type_ m_valuelimits[ 2 ] { Type_( std::numeric_limits::lowest() ), Type_( std::numeric_limits::max() ) }; + Type_ const *m_valuechangemodifier{ nullptr }; // optional modifier applied to value change }; @@ -203,7 +210,11 @@ void fixedstep_modifier::update( Type_ &Variable, double const Timedelta ) const { // HACK: float cast to avoid vec3 and double mismatch // TBD, TODO: replace with vector types specialization - Variable += ( m_valuechange * static_cast( Timedelta ) ); + auto const valuechange { ( + m_valuechangemodifier == nullptr ? + m_valuechange : + m_valuechange / *( m_valuechangemodifier ) ) }; + Variable += ( valuechange * static_cast( Timedelta ) ); // clamp down to allowed value range Variable = glm::max( Variable, m_valuelimits[ value_limit::min ] ); Variable = glm::min( Variable, m_valuelimits[ value_limit::max ] ); diff --git a/renderer.cpp b/renderer.cpp index dd0f53c6..557d1f53 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -120,6 +120,9 @@ void opengl_particles::update( opengl_camera const &Camera ) { m_particlevertices.clear(); + + if( false == Global.Smoke ) { return; } + // build a list of visible smoke sources // NOTE: arranged by distance to camera, if we ever need sorting and/or total amount cap-based culling std::multimap sources; @@ -213,6 +216,7 @@ opengl_particles::update( opengl_camera const &Camera ) { void opengl_particles::render( int const Textureunit ) { + if( false == Global.Smoke ) { return; } if( m_buffercapacity == 0 ) { return; } if( m_particlevertices.empty() ) { return; }