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

Simulate and light the smoke on the GPU and make rain and snow of particles

This commit is contained in:
2026-10-20 16:44:27 +02:00
parent 6a109e984c
commit 867497b658
22 changed files with 1637 additions and 13 deletions

View File

@@ -57,6 +57,9 @@ public:
m_valuechangemodifier == nullptr ?
m_valuechange :
m_valuechange / *m_valuechangemodifier ); }
Type_
limit( value_limit const Limit ) const {
return m_valuelimits[ Limit ]; }
private:
//types
@@ -81,6 +84,25 @@ class smoke_source {
public:
// types
using particle_sequence = std::vector<smoke_particle>;
// what the particles simulated on the gpu (particle_manager::gpu(), opengl46_gpu_particles) take from the source in an
// update: how many are born, where and how they start, and how they change, all as the cpu update would do it
struct gpu_state {
std::uint32_t spawns { 0 }; // particles born in the last update, at most max_particles()
glm::dvec3 location { 0.0 }; // of the emitter at the last update...
glm::dvec3 previous { 0.0 }; // ...and at the one before; the particles of an update are born along the way between
bool started { false };
float inclination[ 2 ] { 0.f, 0.f }; // radians
float velocity[ 2 ] { 0.f, 0.f }; // m/s, with the share the owner gives
float size[ 2 ] { 0.f, 0.f };
float opacity[ 2 ] { 0.f, 0.f }; // with the smoke fidelity and the share the owner gives
float sizechange[ 3 ] { 0.f, 0.f, 0.f }; // per second, min, max
float opacitychange[ 3 ] { 0.f, 0.f, 0.f }; // per second (with the fidelity), min, max
// the vertical velocity: changes by (rise - damping) * itself per second, and doesn't fall below risemin
float rise { 0.f };
float damping { 0.f };
float risemin { std::numeric_limits<float>::lowest() };
glm::vec3 color { 0.f };
};
// methods
bool
deserialize( cParser &Input );
@@ -93,6 +115,15 @@ public:
// updates state of owned particles
void
update( double const Timedelta, bool const Onlydespawn );
// the same for particles simulated on the gpu: only the births and the state of the source they start from
void
update_gpu( double const Timedelta, bool const Onlydespawn );
gpu_state const &
gpu() const {
return m_gpu; }
std::size_t
max_particles() const {
return m_max_particles; }
glm::vec3 const &
color() const {
return m_emitter.color; }
@@ -131,6 +162,12 @@ private:
// imports member data pair from the config file
bool
deserialize_mapping( cParser &Input );
// adds the particles to spawn in an update of Timedelta to m_spawncount
void
accumulate_spawns( double const Timedelta, bool const Onlydespawn );
// shares of the launch velocity and of the opacity of a particle born now, which the owner gives
void
launch_scales( float &Velocity, float &Opacity ) const;
void
initialize( smoke_particle &Particle );
// updates state of provided particle and bounding box. returns: true if particle is still alive afterwards, false otherwise
@@ -158,6 +195,7 @@ private:
particle_sequence m_particles; // collection of spawned particles
std::size_t m_max_particles; // maximum number of particles existing
scene::bounding_area m_area; // bounding sphere of owned particles
gpu_state m_gpu; // for the particles simulated on the gpu
};
@@ -182,6 +220,20 @@ public:
// updates state of all owned emitters
void
update();
// whether the renderer simulates the particles on the gpu: the sources then work out only their births (smoke_source::gpu());
// the renderer sets it before the next update. the particles simulated on the cpu are dropped when it's switched on
void
gpu( bool const Gpu );
bool
gpu() const {
return m_gpu; }
// number of the updates in which the time went on, and the time of the last one: the gpu simulates once per update
std::uint64_t
updates() const {
return m_updates; }
double
timedelta() const {
return m_timedelta; }
// data access
source_sequence &
sequence() {
@@ -198,6 +250,9 @@ private:
// members
source_map m_sourcetemplates; // cached particle emitter configurations
source_sequence m_sources; // all owned particle emitters
bool m_gpu { false };
std::uint64_t m_updates { 0 };
double m_timedelta { 0.0 };
};