diff options
author | Yuri Sizov <yuris@humnom.net> | 2023-07-14 18:50:56 +0200 |
---|---|---|
committer | Yuri Sizov <yuris@humnom.net> | 2023-07-14 18:50:56 +0200 |
commit | 0f7625ab46a64b3f5da2b09969ebabf38df9a6e9 (patch) | |
tree | 5300150473caa2b83de54e6c58116ae18b72d486 /scene/3d/gpu_particles_3d.cpp | |
parent | a91f0e6bca51c7f3a492f0038478bd73813eb1c2 (diff) | |
parent | 5322e255addbcef1773d8bd22482765187c75113 (diff) | |
download | redot-engine-0f7625ab46a64b3f5da2b09969ebabf38df9a6e9.tar.gz |
Merge pull request #76859 from HolonProduction/emission-finished-gpu
Add `finished` signal to GPUParticles
Diffstat (limited to 'scene/3d/gpu_particles_3d.cpp')
-rw-r--r-- | scene/3d/gpu_particles_3d.cpp | 56 |
1 files changed, 50 insertions, 6 deletions
diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp index 4d0bc8b02f..fb889c928d 100644 --- a/scene/3d/gpu_particles_3d.cpp +++ b/scene/3d/gpu_particles_3d.cpp @@ -31,19 +31,37 @@ #include "gpu_particles_3d.h" #include "scene/resources/particle_process_material.h" +#include "scene/scene_string_names.h" AABB GPUParticles3D::get_aabb() const { return AABB(); } void GPUParticles3D::set_emitting(bool p_emitting) { - RS::get_singleton()->particles_set_emitting(particles, p_emitting); + // Do not return even if `p_emitting == emitting` because `emitting` is just an approximation. if (p_emitting && one_shot) { + if (!active && !emitting) { + // Last cycle ended. + active = true; + time = 0; + signal_cancled = false; + emission_time = lifetime; + active_time = lifetime * (2 - explosiveness_ratio); + } else { + signal_cancled = true; + } set_process_internal(true); } else if (!p_emitting) { - set_process_internal(false); + if (one_shot) { + set_process_internal(true); + } else { + set_process_internal(false); + } } + + emitting = p_emitting; + RS::get_singleton()->particles_set_emitting(particles, p_emitting); } void GPUParticles3D::set_amount(int p_amount) { @@ -122,7 +140,7 @@ void GPUParticles3D::set_collision_base_size(real_t p_size) { } bool GPUParticles3D::is_emitting() const { - return RS::get_singleton()->particles_get_emitting(particles); + return emitting; } int GPUParticles3D::get_amount() const { @@ -373,6 +391,16 @@ PackedStringArray GPUParticles3D::get_configuration_warnings() const { void GPUParticles3D::restart() { RenderingServer::get_singleton()->particles_restart(particles); RenderingServer::get_singleton()->particles_set_emitting(particles, true); + + emitting = true; + active = true; + signal_cancled = false; + time = 0; + emission_time = lifetime * (1 - explosiveness_ratio); + active_time = lifetime * (2 - explosiveness_ratio); + if (one_shot) { + set_process_internal(true); + } } AABB GPUParticles3D::capture_aabb() const { @@ -425,9 +453,23 @@ void GPUParticles3D::_notification(int p_what) { // Use internal process when emitting and one_shot is on so that when // the shot ends the editor can properly update. case NOTIFICATION_INTERNAL_PROCESS: { - if (one_shot && !is_emitting()) { - notify_property_list_changed(); - set_process_internal(false); + if (one_shot) { + time += get_process_delta_time(); + if (time > emission_time) { + emitting = false; + if (!active) { + set_process_internal(false); + } + } + if (time > active_time) { + if (active && !signal_cancled) { + emit_signal(SceneStringNames::get_singleton()->finished); + } + active = false; + if (!emitting) { + set_process_internal(false); + } + } } } break; @@ -571,6 +613,8 @@ void GPUParticles3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_transform_align", "align"), &GPUParticles3D::set_transform_align); ClassDB::bind_method(D_METHOD("get_transform_align"), &GPUParticles3D::get_transform_align); + ADD_SIGNAL(MethodInfo("finished")); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting"); ADD_PROPERTY_DEFAULT("emitting", true); // Workaround for doctool in headless mode, as dummy rasterizer always returns false. ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_RANGE, "1,1000000,1,exp"), "set_amount", "get_amount"); |