17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-22 17:53:21 +02:00

Let the templates of smoke sources set how fast their particles rise or fall

This commit is contained in:
2026-10-20 17:12:23 +02:00
parent 867497b658
commit abbdca4773
7 changed files with 47 additions and 6 deletions

View File

@@ -249,6 +249,7 @@ void opengl46_gpu_particles::simulate_smoke(particle_manager &Particles, glm::dv
record.sizechange = glm::vec4{state.sizechange[0], state.sizechange[1], state.sizechange[2], 0.f};
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.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

@@ -115,6 +115,13 @@ smoke_source::deserialize_mapping( cParser &Input ) {
else if( key == "opacity_change:" ) {
m_opacitymodifier.deserialize( Input );
}
else if( key == "terminal_velocity:" ) {
m_settles = true;
m_settling = Input.getToken<float>( true, "\n\r\t ,;[]" );
}
else if( key == "drag:" ) {
m_drag = 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
}
@@ -379,9 +386,14 @@ smoke_source::update( smoke_particle &Particle, bounding_box &Boundingbox, doubl
// ... otherwise proceed with full update
m_sizemodifier.update( Particle.size, Timedelta );
if( m_settles ) {
// the drag of the air takes the particle towards the velocity it settles at
auto const share { static_cast<float>( 1.0 - std::exp( -m_drag * Timedelta ) ) };
Particle.velocity += ( glm::vec3{ 0.f, m_settling, 0.f } - Particle.velocity ) * share;
}
// crude smoke dispersion simulation
// http://www.auburn.edu/academic/forestry_wildlife/fire/smoke_guide/smoke_dispersion.htm
if (m_ownertype == owner_type::vehicle)
else if (m_ownertype == owner_type::vehicle)
{
Particle.velocity.y += static_cast<float>(( 0.025 * Particle.velocity.y ) * std::min( 0.f, Global.AirTemperature - 90 ) * Timedelta); // decelerate faster in cold weather
Particle.velocity.y -= static_cast<float>(( (0.05 * (pow(m_owner.vehicle->GetVelocity()*1,0.4))) * Particle.velocity.y ) * Global.Overcast * Timedelta); // decelerate faster with high air humidity and/or precipitation
@@ -451,6 +463,9 @@ 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.settles = m_settles;
m_gpu.settling = m_settling;
m_gpu.drag = m_drag;
m_gpu.color = m_emitter.color;
// the renderer culls the particles one by one; the area is where they come from, for the distance of the source

View File

@@ -101,6 +101,10 @@ public:
float rise { 0.f };
float damping { 0.f };
float risemin { std::numeric_limits<float>::lowest() };
// with a settling velocity (settles): the velocity goes over to it instead, see smoke_source::m_settling
bool settles { false };
float settling { 0.f };
float drag { 1.f };
glm::vec3 color { 0.f };
};
// methods
@@ -189,6 +193,12 @@ private:
fixedstep_modifier<float> m_sizemodifier; // particle billboard size
// fixedstep_modifier<glm::vec3> m_colormodifier; // particle billboard color and opacity
fixedstep_modifier<float> m_opacitymodifier;
// optional velocity the particles settle at in still air, m/s, positive upwards (light, hot smoke rises, heavy particles
// fall), and how fast they get to it: the share of the rest of the way per second is 1 - exp(-drag). when given, it takes
// the place of the crude dispersion of update( Particle ) (the rise in cold air, the damping in humid air)
bool m_settles { false };
float m_settling { 0.f }; // terminal_velocity:
float m_drag { 1.f }; // drag:
// 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