Skip to content

Commit be2724a

Browse files
committed
Merge pull request godotengine#76853 from HolonProduction/emission_finished
Add `finished` signal to CPUParticles
2 parents d133b0e + 1472736 commit be2724a

8 files changed

Lines changed: 54 additions & 34 deletions

doc/classes/CPUParticles2D.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,13 @@
285285
Particle texture. If [code]null[/code], particles will be squares.
286286
</member>
287287
</members>
288+
<signals>
289+
<signal name="finished">
290+
<description>
291+
Emitted when all active particles have finished processing. When [member one_shot] is disabled, particles will process continuously, so this is never emitted.
292+
</description>
293+
</signal>
294+
</signals>
288295
<constants>
289296
<constant name="DRAW_ORDER_INDEX" value="0" enum="DrawOrder">
290297
Particles are drawn in the order emitted.

doc/classes/CPUParticles3D.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,13 @@
309309
Minimum tangent acceleration.
310310
</member>
311311
</members>
312+
<signals>
313+
<signal name="finished">
314+
<description>
315+
Emitted when all active particles have finished processing. When [member one_shot] is disabled, particles will process continuously, so this is never emitted.
316+
</description>
317+
</signal>
318+
</signals>
312319
<constants>
313320
<constant name="DRAW_ORDER_INDEX" value="0" enum="DrawOrder">
314321
Particles are drawn in the order emitted.

scene/2d/cpu_particles_2d.cpp

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "core/core_string_names.h"
3434
#include "scene/2d/gpu_particles_2d.h"
3535
#include "scene/resources/particle_process_material.h"
36+
#include "scene/scene_string_names.h"
3637

3738
void CPUParticles2D::set_emitting(bool p_emitting) {
3839
if (emitting == p_emitting) {
@@ -41,6 +42,7 @@ void CPUParticles2D::set_emitting(bool p_emitting) {
4142

4243
emitting = p_emitting;
4344
if (emitting) {
45+
active = true;
4446
set_process_internal(true);
4547
}
4648
}
@@ -259,7 +261,6 @@ PackedStringArray CPUParticles2D::get_configuration_warnings() const {
259261

260262
void CPUParticles2D::restart() {
261263
time = 0;
262-
inactive_time = 0;
263264
frame_remainder = 0;
264265
cycle = 0;
265266
emitting = false;
@@ -561,21 +562,15 @@ void CPUParticles2D::_update_internal() {
561562
}
562563

563564
double delta = get_process_delta_time();
564-
if (emitting) {
565-
inactive_time = 0;
566-
} else {
567-
inactive_time += delta;
568-
if (inactive_time > lifetime * 1.2) {
569-
set_process_internal(false);
570-
_set_do_redraw(false);
565+
if (!active && !emitting) {
566+
set_process_internal(false);
567+
_set_do_redraw(false);
571568

572-
//reset variables
573-
time = 0;
574-
inactive_time = 0;
575-
frame_remainder = 0;
576-
cycle = 0;
577-
return;
578-
}
569+
//reset variables
570+
time = 0;
571+
frame_remainder = 0;
572+
cycle = 0;
573+
return;
579574
}
580575
_set_do_redraw(true);
581576

@@ -650,6 +645,7 @@ void CPUParticles2D::_particles_process(double p_delta) {
650645

651646
double system_phase = time / lifetime;
652647

648+
bool should_be_active = false;
653649
for (int i = 0; i < pcount; i++) {
654650
Particle &p = parray[i];
655651

@@ -994,6 +990,12 @@ void CPUParticles2D::_particles_process(double p_delta) {
994990
p.transform.columns[1] *= base_scale.y;
995991

996992
p.transform[2] += p.velocity * local_delta;
993+
994+
should_be_active = true;
995+
}
996+
if (!Math::is_equal_approx(time, 0.0) && active && !should_be_active) {
997+
active = false;
998+
emit_signal(SceneStringNames::get_singleton()->finished);
997999
}
9981000
}
9991001

@@ -1364,6 +1366,8 @@ void CPUParticles2D::_bind_methods() {
13641366

13651367
ClassDB::bind_method(D_METHOD("convert_from_particles", "particles"), &CPUParticles2D::convert_from_particles);
13661368

1369+
ADD_SIGNAL(MethodInfo("finished"));
1370+
13671371
ADD_GROUP("Emission Shape", "emission_");
13681372
ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Sphere Surface,Rectangle,Points,Directed Points", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_emission_shape", "get_emission_shape");
13691373
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01,suffix:px"), "set_emission_sphere_radius", "get_emission_sphere_radius");

scene/2d/cpu_particles_2d.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class CPUParticles2D : public Node2D {
7878

7979
private:
8080
bool emitting = false;
81+
bool active = false;
8182

8283
struct Particle {
8384
Transform2D transform;
@@ -99,7 +100,6 @@ class CPUParticles2D : public Node2D {
99100
};
100101

101102
double time = 0.0;
102-
double inactive_time = 0.0;
103103
double frame_remainder = 0.0;
104104
int cycle = 0;
105105
bool do_redraw = false;

scene/3d/cpu_particles_3d.cpp

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "scene/3d/gpu_particles_3d.h"
3535
#include "scene/main/viewport.h"
3636
#include "scene/resources/particle_process_material.h"
37+
#include "scene/scene_string_names.h"
3738

3839
AABB CPUParticles3D::get_aabb() const {
3940
return AABB();
@@ -46,6 +47,7 @@ void CPUParticles3D::set_emitting(bool p_emitting) {
4647

4748
emitting = p_emitting;
4849
if (emitting) {
50+
active = true;
4951
set_process_internal(true);
5052

5153
// first update before rendering to avoid one frame delay after emitting starts
@@ -220,7 +222,6 @@ PackedStringArray CPUParticles3D::get_configuration_warnings() const {
220222

221223
void CPUParticles3D::restart() {
222224
time = 0;
223-
inactive_time = 0;
224225
frame_remainder = 0;
225226
cycle = 0;
226227
emitting = false;
@@ -575,21 +576,15 @@ void CPUParticles3D::_update_internal() {
575576
}
576577

577578
double delta = get_process_delta_time();
578-
if (emitting) {
579-
inactive_time = 0;
580-
} else {
581-
inactive_time += delta;
582-
if (inactive_time > lifetime * 1.2) {
583-
set_process_internal(false);
584-
_set_redraw(false);
579+
if (!active && !emitting) {
580+
set_process_internal(false);
581+
_set_redraw(false);
585582

586-
//reset variables
587-
time = 0;
588-
inactive_time = 0;
589-
frame_remainder = 0;
590-
cycle = 0;
591-
return;
592-
}
583+
//reset variables
584+
time = 0;
585+
frame_remainder = 0;
586+
cycle = 0;
587+
return;
593588
}
594589
_set_redraw(true);
595590

@@ -670,6 +665,7 @@ void CPUParticles3D::_particles_process(double p_delta) {
670665

671666
double system_phase = time / lifetime;
672667

668+
bool should_be_active = false;
673669
for (int i = 0; i < pcount; i++) {
674670
Particle &p = parray[i];
675671

@@ -1136,6 +1132,12 @@ void CPUParticles3D::_particles_process(double p_delta) {
11361132
}
11371133

11381134
p.transform.origin += p.velocity * local_delta;
1135+
1136+
should_be_active = true;
1137+
}
1138+
if (!Math::is_equal_approx(time, 0.0) && active && !should_be_active) {
1139+
active = false;
1140+
emit_signal(SceneStringNames::get_singleton()->finished);
11391141
}
11401142
}
11411143

@@ -1543,6 +1545,8 @@ void CPUParticles3D::_bind_methods() {
15431545

15441546
ClassDB::bind_method(D_METHOD("convert_from_particles", "particles"), &CPUParticles3D::convert_from_particles);
15451547

1548+
ADD_SIGNAL(MethodInfo("finished"));
1549+
15461550
ADD_GROUP("Emission Shape", "emission_");
15471551
ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Sphere Surface,Box,Points,Directed Points,Ring", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_emission_shape", "get_emission_shape");
15481552
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01"), "set_emission_sphere_radius", "get_emission_sphere_radius");

scene/3d/cpu_particles_3d.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class CPUParticles3D : public GeometryInstance3D {
8181

8282
private:
8383
bool emitting = false;
84+
bool active = false;
8485

8586
struct Particle {
8687
Transform3D transform;
@@ -101,7 +102,6 @@ class CPUParticles3D : public GeometryInstance3D {
101102
};
102103

103104
double time = 0.0;
104-
double inactive_time = 0.0;
105105
double frame_remainder = 0.0;
106106
int cycle = 0;
107107
bool redraw = false;

scene/scene_string_names.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ SceneStringNames::SceneStringNames() {
5757
sleeping_state_changed = StaticCString::create("sleeping_state_changed");
5858

5959
finished = StaticCString::create("finished");
60-
emission_finished = StaticCString::create("emission_finished");
6160
animation_finished = StaticCString::create("animation_finished");
6261
animation_changed = StaticCString::create("animation_changed");
6362
animation_started = StaticCString::create("animation_started");

scene/scene_string_names.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ class SceneStringNames {
9393
StringName sort_children;
9494

9595
StringName finished;
96-
StringName emission_finished;
9796
StringName animation_finished;
9897
StringName animation_changed;
9998
StringName animation_started;

0 commit comments

Comments
 (0)