From 2109b80b67eb8a6d5e5a4715cebd9a8bb4051e58 Mon Sep 17 00:00:00 2001 From: Benny Smit Date: Tue, 30 Jul 2024 09:27:32 +0200 Subject: [PATCH] Add emission shape ring for CPUParticles2D Particles will be emitted in the area of a ring parameterized by its outer and inner radius. The distribution is uniform across the area. --- doc/classes/CPUParticles2D.xml | 11 +++++++++- scene/2d/cpu_particles_2d.cpp | 39 +++++++++++++++++++++++++++++++++- scene/2d/cpu_particles_2d.h | 9 +++++++- 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/doc/classes/CPUParticles2D.xml b/doc/classes/CPUParticles2D.xml index 99411c73aa7..e752b05a3d1 100644 --- a/doc/classes/CPUParticles2D.xml +++ b/doc/classes/CPUParticles2D.xml @@ -162,6 +162,12 @@ The rectangle's extents if [member emission_shape] is set to [constant EMISSION_SHAPE_RECTANGLE]. + + The ring's inner radius if [member emission_shape] is set to [constant EMISSION_SHAPE_RING]. + + + The ring's outer radius if [member emission_shape] is set to [constant EMISSION_SHAPE_RING]. + Particles will be emitted inside this region. See [enum EmissionShape] for possible values. @@ -368,7 +374,10 @@ Particles will be emitted at a position chosen randomly among [member emission_points]. Particle velocity and rotation will be set based on [member emission_normals]. Particle color will be modulated by [member emission_colors]. - + + Particles will be emitted in the area of a ring parameterized by its outer and inner radius. + + Represents the size of the [enum EmissionShape] enum. diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index 9c9ba93b410..64f9f553bec 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -448,6 +448,13 @@ void CPUParticles2D::set_emission_colors(const Vector &p_colors) { emission_colors = p_colors; } +void CPUParticles2D::set_emission_ring_inner_radius(real_t p_inner_radius) { + emission_ring_inner_radius = p_inner_radius; +} +void CPUParticles2D::set_emission_ring_radius(real_t p_ring_radius) { + emission_ring_radius = p_ring_radius; +} + real_t CPUParticles2D::get_emission_sphere_radius() const { return emission_sphere_radius; } @@ -468,6 +475,13 @@ Vector CPUParticles2D::get_emission_colors() const { return emission_colors; } +real_t CPUParticles2D::get_emission_ring_inner_radius() const { + return emission_ring_inner_radius; +} +real_t CPUParticles2D::get_emission_ring_radius() const { + return emission_ring_radius; +} + CPUParticles2D::EmissionShape CPUParticles2D::get_emission_shape() const { return emission_shape; } @@ -532,6 +546,13 @@ void CPUParticles2D::_validate_property(PropertyInfo &p_property) const { if (p_property.name.begins_with("scale_curve_") && !split_scale) { p_property.usage = PROPERTY_USAGE_NONE; } + + if (p_property.name == "emission_ring_inner_radius" && emission_shape != EMISSION_SHAPE_RING) { + p_property.usage = PROPERTY_USAGE_NONE; + } + if (p_property.name == "emission_ring_radius" && emission_shape != EMISSION_SHAPE_RING) { + p_property.usage = PROPERTY_USAGE_NONE; + } } static uint32_t idhash(uint32_t x) { @@ -798,6 +819,13 @@ void CPUParticles2D::_particles_process(double p_delta) { p.base_color = emission_colors.get(random_idx); } } break; + case EMISSION_SHAPE_RING: { + real_t t = Math_TAU * Math::randf(); + real_t outer_sq = emission_ring_radius * emission_ring_radius; + real_t inner_sq = emission_ring_inner_radius * emission_ring_inner_radius; + real_t radius = Math::sqrt(Math::randf() * (outer_sq - inner_sq) + inner_sq); + p.transform[2] = Vector2(Math::cos(t), Math::sin(t)) * radius; + } break; case EMISSION_SHAPE_MAX: { // Max value for validity check. break; } @@ -1353,6 +1381,12 @@ void CPUParticles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_emission_colors", "array"), &CPUParticles2D::set_emission_colors); ClassDB::bind_method(D_METHOD("get_emission_colors"), &CPUParticles2D::get_emission_colors); + ClassDB::bind_method(D_METHOD("set_emission_ring_inner_radius", "inner_radius"), &CPUParticles2D::set_emission_ring_inner_radius); + ClassDB::bind_method(D_METHOD("get_emission_ring_inner_radius"), &CPUParticles2D::get_emission_ring_inner_radius); + + ClassDB::bind_method(D_METHOD("set_emission_ring_radius", "radius"), &CPUParticles2D::set_emission_ring_radius); + ClassDB::bind_method(D_METHOD("get_emission_ring_radius"), &CPUParticles2D::get_emission_ring_radius); + ClassDB::bind_method(D_METHOD("get_gravity"), &CPUParticles2D::get_gravity); ClassDB::bind_method(D_METHOD("set_gravity", "accel_vec"), &CPUParticles2D::set_gravity); @@ -1370,12 +1404,14 @@ void CPUParticles2D::_bind_methods() { ADD_SIGNAL(MethodInfo("finished")); ADD_GROUP("Emission Shape", "emission_"); - 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"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Sphere Surface,Rectangle,Points,Directed Points,Ring", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_emission_shape", "get_emission_shape"); 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"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "emission_rect_extents", PROPERTY_HINT_NONE, "suffix:px"), "set_emission_rect_extents", "get_emission_rect_extents"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "emission_points"), "set_emission_points", "get_emission_points"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "emission_normals"), "set_emission_normals", "get_emission_normals"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_COLOR_ARRAY, "emission_colors"), "set_emission_colors", "get_emission_colors"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_ring_inner_radius"), "set_emission_ring_inner_radius", "get_emission_ring_inner_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_ring_radius"), "set_emission_ring_radius", "get_emission_ring_radius"); ADD_GROUP("Particle Flags", "particle_flag_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_align_y"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY); ADD_GROUP("Direction", ""); @@ -1464,6 +1500,7 @@ void CPUParticles2D::_bind_methods() { BIND_ENUM_CONSTANT(EMISSION_SHAPE_RECTANGLE); BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINTS); BIND_ENUM_CONSTANT(EMISSION_SHAPE_DIRECTED_POINTS); + BIND_ENUM_CONSTANT(EMISSION_SHAPE_RING); BIND_ENUM_CONSTANT(EMISSION_SHAPE_MAX); } diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index 3f858c32776..d145bfd7bc0 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -73,7 +73,8 @@ public: EMISSION_SHAPE_RECTANGLE, EMISSION_SHAPE_POINTS, EMISSION_SHAPE_DIRECTED_POINTS, - EMISSION_SHAPE_MAX + EMISSION_SHAPE_RING, + EMISSION_SHAPE_MAX, }; private: @@ -169,6 +170,8 @@ private: Vector emission_normals; Vector emission_colors; int emission_point_count = 0; + real_t emission_ring_inner_radius = 0.8; + real_t emission_ring_radius = 1.0; Ref scale_curve_x; Ref scale_curve_y; @@ -265,6 +268,8 @@ public: void set_emission_points(const Vector &p_points); void set_emission_normals(const Vector &p_normals); void set_emission_colors(const Vector &p_colors); + void set_emission_ring_inner_radius(real_t p_inner_radius); + void set_emission_ring_radius(real_t p_ring_radius); void set_scale_curve_x(Ref p_scale_curve); void set_scale_curve_y(Ref p_scale_curve); void set_split_scale(bool p_split_scale); @@ -275,6 +280,8 @@ public: Vector get_emission_points() const; Vector get_emission_normals() const; Vector get_emission_colors() const; + real_t get_emission_ring_inner_radius() const; + real_t get_emission_ring_radius() const; Ref get_scale_curve_x() const; Ref get_scale_curve_y() const; bool get_split_scale();