@@ -141,7 +141,22 @@ void GPUParticles2D::_update_particle_emission_transform() {
141
141
}
142
142
143
143
void GPUParticles2D::set_process_material (const Ref<Material> &p_material) {
144
+ if (process_material == p_material) {
145
+ return ;
146
+ }
147
+
148
+ if (process_material.is_valid () && process_material->is_class (" ParticleProcessMaterial" )) {
149
+ process_material->disconnect (" emission_shape_changed" , callable_mp ((CanvasItem *)this , &GPUParticles2D::queue_redraw));
150
+ }
151
+
144
152
process_material = p_material;
153
+
154
+ if (process_material.is_valid () && process_material->is_class (" ParticleProcessMaterial" )) {
155
+ process_material->connect (" emission_shape_changed" , callable_mp ((CanvasItem *)this , &GPUParticles2D::queue_redraw));
156
+ }
157
+
158
+ queue_redraw ();
159
+
145
160
Ref<ParticleProcessMaterial> pm = p_material;
146
161
if (pm.is_valid () && !pm->get_particle_flag (ParticleProcessMaterial::PARTICLE_FLAG_DISABLE_Z) && pm->get_gravity () == Vector3 (0 , -9.8 , 0 )) {
147
162
// Likely a new (3D) material, modify it to match 2D space
@@ -195,8 +210,8 @@ void GPUParticles2D::set_interp_to_end(float p_interp) {
195
210
}
196
211
197
212
#ifdef TOOLS_ENABLED
198
- void GPUParticles2D::set_show_visibility_rect (bool p_show_visibility_rect ) {
199
- show_visibility_rect = p_show_visibility_rect ;
213
+ void GPUParticles2D::set_show_gizmos (bool p_show_gizmos ) {
214
+ show_gizmos = p_show_gizmos ;
200
215
queue_redraw ();
201
216
}
202
217
#endif
@@ -704,8 +719,9 @@ void GPUParticles2D::_notification(int p_what) {
704
719
RS::get_singleton ()->canvas_item_add_particles (get_canvas_item (), particles, texture_rid);
705
720
706
721
#ifdef TOOLS_ENABLED
707
- if (show_visibility_rect ) {
722
+ if (show_gizmos ) {
708
723
draw_rect (visibility_rect, Color (0 , 0.7 , 0.9 , 0.4 ), false );
724
+ _draw_emission_gizmo ();
709
725
}
710
726
#endif
711
727
} break ;
@@ -781,6 +797,60 @@ void GPUParticles2D::_notification(int p_what) {
781
797
}
782
798
}
783
799
800
+ #ifdef TOOLS_ENABLED
801
+ void GPUParticles2D::_draw_emission_gizmo () {
802
+ Ref<ParticleProcessMaterial> pm = process_material;
803
+ Color emission_ring_color = Color (0.8 , 0.7 , 0.4 , 0.4 );
804
+ if (pm.is_null ()) {
805
+ return ;
806
+ }
807
+ draw_set_transform (
808
+ Vector2 (pm->get_emission_shape_offset ().x , pm->get_emission_shape_offset ().y ),
809
+ 0.0 ,
810
+ Vector2 (pm->get_emission_shape_scale ().x , pm->get_emission_shape_scale ().y ));
811
+
812
+ switch (pm->get_emission_shape ()) {
813
+ case ParticleProcessMaterial::EmissionShape::EMISSION_SHAPE_BOX: {
814
+ Vector2 extents2d = Vector2 (pm->get_emission_box_extents ().x , pm->get_emission_box_extents ().y );
815
+ draw_rect (Rect2 (-extents2d, extents2d * 2.0 ), emission_ring_color, false );
816
+ break ;
817
+ }
818
+ case ParticleProcessMaterial::EmissionShape::EMISSION_SHAPE_SPHERE:
819
+ case ParticleProcessMaterial::EmissionShape::EMISSION_SHAPE_SPHERE_SURFACE: {
820
+ draw_circle (Vector2 (), pm->get_emission_sphere_radius (), emission_ring_color, false );
821
+ break ;
822
+ }
823
+ case ParticleProcessMaterial::EmissionShape::EMISSION_SHAPE_RING: {
824
+ Vector3 ring_axis = pm->get_emission_ring_axis ();
825
+ if (ring_axis.is_equal_approx (Vector3 (0.0 , 0.0 , 1.0 )) || ring_axis.is_zero_approx ()) {
826
+ draw_circle (Vector2 (), pm->get_emission_ring_inner_radius (), emission_ring_color, false );
827
+ draw_circle (Vector2 (), pm->get_emission_ring_radius (), emission_ring_color, false );
828
+ } else {
829
+ Vector2 a = Vector2 (pm->get_emission_ring_height () / -2.0 , pm->get_emission_ring_radius () / -1.0 );
830
+ Vector2 b = Vector2 (-a.x , MIN (a.y + tan ((90.0 - pm->get_emission_ring_cone_angle ()) * 0.01745329 ) * pm->get_emission_ring_height (), 0.0 ));
831
+ Vector2 c = Vector2 (b.x , -b.y );
832
+ Vector2 d = Vector2 (a.x , -a.y );
833
+ if (ring_axis.is_equal_approx (Vector3 (1.0 , 0.0 , 0.0 ))) {
834
+ Vector<Vector2> pos = { a, b, b, c, c, d, d, a };
835
+ draw_multiline (pos, emission_ring_color);
836
+ } else if (ring_axis.is_equal_approx (Vector3 (0.0 , 1.0 , 0.0 ))) {
837
+ a = Vector2 (a.y , a.x );
838
+ b = Vector2 (b.y , b.x );
839
+ c = Vector2 (c.y , c.x );
840
+ d = Vector2 (d.y , d.x );
841
+ Vector<Vector2> pos = { a, b, b, c, c, d, d, a };
842
+ draw_multiline (pos, emission_ring_color);
843
+ }
844
+ }
845
+ break ;
846
+ }
847
+ default : {
848
+ break ;
849
+ }
850
+ }
851
+ }
852
+ #endif
853
+
784
854
void GPUParticles2D::_bind_methods () {
785
855
ClassDB::bind_method (D_METHOD (" set_emitting" , " emitting" ), &GPUParticles2D::set_emitting);
786
856
ClassDB::bind_method (D_METHOD (" set_amount" , " amount" ), &GPUParticles2D::set_amount);
0 commit comments