diff options
author | heavydemon21 <nielsstunnebrink1@gmail.com> | 2024-12-17 14:17:25 +0100 |
---|---|---|
committer | heavydemon21 <nielsstunnebrink1@gmail.com> | 2024-12-17 14:17:25 +0100 |
commit | e70c2a3a4a7f636f190cc64792029cadd3613337 (patch) | |
tree | 8371b0e067430db780b72638eb61555869641979 /src/crepe/system/ParticleSystem.cpp | |
parent | 68be6b67f79413cb4af0ca15262ca1547a7d0d41 (diff) | |
parent | 9957da232e7c96f7f88a7ab0edfa4aaf560d1c00 (diff) |
Merge branch 'master' into niels/UI
Diffstat (limited to 'src/crepe/system/ParticleSystem.cpp')
-rw-r--r-- | src/crepe/system/ParticleSystem.cpp | 89 |
1 files changed, 42 insertions, 47 deletions
diff --git a/src/crepe/system/ParticleSystem.cpp b/src/crepe/system/ParticleSystem.cpp index b14c52f..35a1d41 100644 --- a/src/crepe/system/ParticleSystem.cpp +++ b/src/crepe/system/ParticleSystem.cpp @@ -1,3 +1,4 @@ +#include <chrono> #include <cmath> #include <cstdlib> #include <ctime> @@ -5,6 +6,7 @@ #include "../api/ParticleEmitter.h" #include "../api/Transform.h" #include "../manager/ComponentManager.h" +#include "../manager/LoopTimerManager.h" #include "ParticleSystem.h" @@ -12,7 +14,11 @@ using namespace crepe; void ParticleSystem::update() { // Get all emitters - ComponentManager & mgr = this->mediator.component_manager; + const Mediator & mediator = this->mediator; + LoopTimerManager & loop_timer = mediator.loop_timer; + ComponentManager & mgr = mediator.component_manager; + float dt = loop_timer.get_scaled_fixed_delta_time().count(); + RefVector<ParticleEmitter> emitters = mgr.get_components_by_type<ParticleEmitter>(); for (ParticleEmitter & emitter : emitters) { @@ -21,38 +27,39 @@ void ParticleSystem::update() { = mgr.get_components_by_id<Transform>(emitter.game_object_id).front().get(); // Emit particles based on emission_rate - int updates = calculate_update(this->update_count, emitter.data.emission_rate); - for (size_t i = 0; i < updates; i++) { - emit_particle(emitter, transform); + emitter.spawn_accumulator += emitter.data.emission_rate * dt; + while (emitter.spawn_accumulator >= 1.0) { + this->emit_particle(emitter, transform); + emitter.spawn_accumulator -= 1.0; } // Update all particles - for (Particle & particle : emitter.data.particles) { + for (Particle & particle : emitter.particles) { if (particle.active) { - particle.update(); + particle.update(dt); } } // Check if within boundary - check_bounds(emitter, transform); + this->check_bounds(emitter, transform); } - - this->update_count = (this->update_count + 1) % this->MAX_UPDATE_COUNT; } void ParticleSystem::emit_particle(ParticleEmitter & emitter, const Transform & transform) { constexpr float DEG_TO_RAD = M_PI / 180.0; - vec2 initial_position = emitter.data.position + transform.position; - float random_angle = generate_random_angle(emitter.data.min_angle, emitter.data.max_angle); + vec2 initial_position = emitter.data.offset + transform.position; + float random_angle + = this->generate_random_angle(emitter.data.min_angle, emitter.data.max_angle); - float random_speed = generate_random_speed(emitter.data.min_speed, emitter.data.max_speed); + float random_speed + = this->generate_random_speed(emitter.data.min_speed, emitter.data.max_speed); float angle_radians = random_angle * DEG_TO_RAD; vec2 velocity = {random_speed * std::cos(angle_radians), random_speed * std::sin(angle_radians)}; - for (Particle & particle : emitter.data.particles) { + for (Particle & particle : emitter.particles) { if (!particle.active) { particle.reset(emitter.data.end_lifespan, initial_position, velocity, random_angle); @@ -61,66 +68,54 @@ void ParticleSystem::emit_particle(ParticleEmitter & emitter, const Transform & } } -int ParticleSystem::calculate_update(int count, double emission) const { - double integer_part = std::floor(emission); - double fractional_part = emission - integer_part; - - if (fractional_part > 0) { - int denominator = static_cast<int>(1.0 / fractional_part); - return (count % denominator == 0) ? 1 : 0; - } - - return static_cast<int>(emission); -} - void ParticleSystem::check_bounds(ParticleEmitter & emitter, const Transform & transform) { - vec2 offset = emitter.data.boundary.offset + transform.position + emitter.data.position; - double half_width = emitter.data.boundary.width / 2.0; - double half_height = emitter.data.boundary.height / 2.0; + vec2 offset = emitter.data.boundary.offset + transform.position + emitter.data.offset; + float half_width = emitter.data.boundary.width / 2.0; + float half_height = emitter.data.boundary.height / 2.0; - const double LEFT = offset.x - half_width; - const double RIGHT = offset.x + half_width; - const double TOP = offset.y - half_height; - const double BOTTOM = offset.y + half_height; + float left = offset.x - half_width; + float right = offset.x + half_width; + float top = offset.y - half_height; + float bottom = offset.y + half_height; - for (Particle & particle : emitter.data.particles) { + for (Particle & particle : emitter.particles) { const vec2 & position = particle.position; - bool within_bounds = (position.x >= LEFT && position.x <= RIGHT && position.y >= TOP - && position.y <= BOTTOM); - + bool within_bounds = (position.x >= left && position.x <= right && position.y >= top + && position.y <= bottom); + //if not within bounds do a reset or stop velocity if (!within_bounds) { if (emitter.data.boundary.reset_on_exit) { particle.active = false; } else { particle.velocity = {0, 0}; - if (position.x < LEFT) particle.position.x = LEFT; - else if (position.x > RIGHT) particle.position.x = RIGHT; - if (position.y < TOP) particle.position.y = TOP; - else if (position.y > BOTTOM) particle.position.y = BOTTOM; + if (position.x < left) particle.position.x = left; + else if (position.x > right) particle.position.x = right; + if (position.y < top) particle.position.y = top; + else if (position.y > bottom) particle.position.y = bottom; } } } } -double ParticleSystem::generate_random_angle(double min_angle, double max_angle) const { +float ParticleSystem::generate_random_angle(float min_angle, float max_angle) const { if (min_angle == max_angle) { return min_angle; } else if (min_angle < max_angle) { return min_angle - + static_cast<double>(std::rand() % static_cast<int>(max_angle - min_angle)); + + static_cast<float>(std::rand() % static_cast<int>(max_angle - min_angle)); } else { - double angle_offset = (360 - min_angle) + max_angle; - double random_angle - = min_angle + static_cast<double>(std::rand() % static_cast<int>(angle_offset)); + float angle_offset = (360 - min_angle) + max_angle; + float random_angle + = min_angle + static_cast<float>(std::rand() % static_cast<int>(angle_offset)); return (random_angle >= 360) ? random_angle - 360 : random_angle; } } -double ParticleSystem::generate_random_speed(double min_speed, double max_speed) const { +float ParticleSystem::generate_random_speed(float min_speed, float max_speed) const { if (min_speed == max_speed) { return min_speed; } else { return min_speed - + static_cast<double>(std::rand() % static_cast<int>(max_speed - min_speed)); + + static_cast<float>(std::rand() % static_cast<int>(max_speed - min_speed)); } } |