17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-23 19:26:12 +02:00

Let the smoke leave the exhaust as a widening jet that fades in

This commit is contained in:
2026-10-20 18:00:51 +02:00
parent abbdca4773
commit cf36b24e8d
8 changed files with 42 additions and 6 deletions

View File

@@ -246,10 +246,10 @@ void opengl46_gpu_particles::simulate_smoke(particle_manager &Particles, glm::dv
record.previous = glm::vec4{glm::vec3{state.previous - m_origin}, 0.f};
record.launch = glm::vec4{state.inclination[0], state.inclination[1], state.velocity[0], state.velocity[1]};
record.initial = glm::vec4{state.size[0], state.size[1], state.opacity[0], state.opacity[1]};
record.sizechange = glm::vec4{state.sizechange[0], state.sizechange[1], state.sizechange[2], 0.f};
record.sizechange = glm::vec4{state.sizechange[0], state.sizechange[1], state.sizechange[2], state.spread};
record.opacitychange = glm::vec4{state.opacitychange[0], state.opacitychange[1], state.opacitychange[2], 0.f};
record.motion = glm::vec4{state.rise, state.damping, state.risemin, 0.f};
record.settling = glm::vec4{state.settling, state.drag, state.settles ? 1.f : 0.f, 0.f};
record.settling = glm::vec4{state.settling, state.drag, state.settles ? 1.f : 0.f, state.fadein};
record.color = glm::vec4{glm::clamp(state.color, glm::vec3{0.f}, glm::vec3{1.f}), 0.f};
record.oldcolor = glm::vec4{glm::clamp(state.color * oldlight, glm::vec3{0.f}, glm::vec3{1.f}), 0.f};
if (pool.size > 0)

View File

@@ -67,7 +67,7 @@ opengl46_particles::update( opengl_camera const &Camera ) {
vertex.color[ 0 ] = particlecolor.r;
vertex.color[ 1 ] = particlecolor.g;
vertex.color[ 2 ] = particlecolor.b;
vertex.color.a = std::clamp(particle.opacity, 0.0f, 1.0f);
vertex.color.a = std::clamp(particle.opacity, 0.0f, 1.0f) * sourcedata.fade_in(particle.age);
auto const offset { glm::vec3{ particle.position - Camera.position() } };
auto const rotation { glm::angleAxis( particle.rotation, glm::vec3{ 0.f, 0.f, 1.f } ) };

View File

@@ -122,6 +122,12 @@ smoke_source::deserialize_mapping( cParser &Input ) {
else if( key == "drag:" ) {
m_drag = std::max( 0.f, Input.getToken<float>( true, "\n\r\t ,;[]" ) );
}
else if( key == "spread:" ) {
m_spread = std::max( 0.f, Input.getToken<float>( true, "\n\r\t ,;[]" ) );
}
else if( key == "fade_in:" ) {
m_fadein = std::max( 0.f, Input.getToken<float>( true, "\n\r\t ,;[]" ) );
}
return true; // return value marks a [ key: value ] pair was extracted, nothing about whether it's recognized
}
@@ -385,6 +391,10 @@ smoke_source::update( smoke_particle &Particle, bounding_box &Boundingbox, doubl
if( Particle.opacity <= 0.f ) { return false; }
// ... otherwise proceed with full update
m_sizemodifier.update( Particle.size, Timedelta );
if( m_spread > 0.f ) {
// the jet widens with the way it goes
Particle.size = std::min( Particle.size + m_spread * glm::length( Particle.velocity ) * static_cast<float>( Timedelta ), m_sizemodifier.limit( value_limit::max ) );
}
if( m_settles ) {
// the drag of the air takes the particle towards the velocity it settles at
@@ -463,6 +473,8 @@ smoke_source::update_gpu( double const Timedelta, bool const Onlydespawn ) {
m_gpu.damping = static_cast<float>( 0.050 * Global.Overcast );
m_gpu.risemin = static_cast<float>( 0.25 * ( 2.f - Global.Overcast ) );
}
m_gpu.spread = m_spread;
m_gpu.fadein = m_fadein;
m_gpu.settles = m_settles;
m_gpu.settling = m_settling;
m_gpu.drag = m_drag;

View File

@@ -105,6 +105,8 @@ public:
bool settles { false };
float settling { 0.f };
float drag { 1.f };
float spread { 0.f }; // see smoke_source::m_spread
float fadein { 0.f }; // see smoke_source::m_fadein
glm::vec3 color { 0.f };
};
// methods
@@ -128,6 +130,12 @@ public:
std::size_t
max_particles() const {
return m_max_particles; }
// share of the opacity of a particle the age has let through so far, 0-1 (fade_in:)
float
fade_in( float const Age ) const {
if( m_fadein <= 0.f ) { return 1.f; }
auto const share { std::clamp( Age / m_fadein, 0.f, 1.f ) };
return share * share * ( 3.f - 2.f * share ); }
glm::vec3 const &
color() const {
return m_emitter.color; }
@@ -199,6 +207,11 @@ private:
bool m_settles { false };
float m_settling { 0.f }; // terminal_velocity:
float m_drag { 1.f }; // drag:
// optional growth of the particles with the way they go through the air, metres of size per metre: the jet out of the
// exhaust widens into a cone as it takes in the air around, instead of the puffs swelling in one place
float m_spread { 0.f }; // spread:
// optional time the particles take to show up after they're born, seconds, so they don't pop up at the exhaust
float m_fadein { 0.f }; // fade_in:
// texture_handle m_texture { -1 }; // texture assigned to particle billboards
// current state
float m_spawncount { 0.f }; // number of particles to spawn during next update