Skip to content

Commit

Permalink
Add circle emission shape with random and ordered emission mode
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisb123 committed Dec 21, 2022
1 parent 63f95c0 commit ec9ca07
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 3 deletions.
17 changes: 16 additions & 1 deletion doc/classes/CPUParticles2D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@
<member name="draw_order" type="int" setter="set_draw_order" getter="get_draw_order" enum="CPUParticles2D.DrawOrder" default="0">
Particle draw order. Uses [enum DrawOrder] values.
</member>
<member name="emission_circle_mode" type="int" setter="set_emission_circle_mode" getter="get_emission_circle_mode" enum="CPUParticles2D.EmissionCircleMode">
The order [enum EmissionCircleMode] in which points are emitted for [constant EMISSION_SHAPE_CIRCLE]
</member>
<member name="emission_colors" type="PackedColorArray" setter="set_emission_colors" getter="get_emission_colors">
Sets the [Color]s to modulate particles by when using [constant EMISSION_SHAPE_POINTS] or [constant EMISSION_SHAPE_DIRECTED_POINTS].
</member>
Expand Down Expand Up @@ -361,8 +364,20 @@
<constant name="EMISSION_SHAPE_DIRECTED_POINTS" value="5" enum="EmissionShape">
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].
</constant>
<constant name="EMISSION_SHAPE_MAX" value="6" enum="EmissionShape">
<constant name="EMISSION_SHAPE_CIRCLE" value="6" enum="EmissionShape">
Particles will be emitted from a circle of [member emission_sphere_radius] radius.
</constant>
<constant name="EMISSION_SHAPE_MAX" value="7" enum="EmissionShape">
Represents the size of the [enum EmissionShape] enum.
</constant>
<constant name="EMISSION_CIRCLE_MODE_RANDOM" value="0" enum="EmissionCircleMode">
Particles emitted in random order
</constant>
<constant name="EMISSION_CIRCLE_MODE_CW" value="1" enum="EmissionCircleMode">
Particles emitted in a clockwise order
</constant>
<constant name="EMISSION_CIRCLE_MODE_CCW" value="2" enum="EmissionCircleMode">
Particles emitted in a counter clockwise order
</constant>
</constants>
</class>
40 changes: 38 additions & 2 deletions scene/2d/cpu_particles_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,10 @@ void CPUParticles2D::set_emission_shape(EmissionShape p_shape) {
notify_property_list_changed();
}

void CPUParticles2D::set_emission_circle_mode(EmissionCircleMode p_circle_mode) {
emission_circle_mode = p_circle_mode;
}

void CPUParticles2D::set_emission_sphere_radius(real_t p_radius) {
emission_sphere_radius = p_radius;
}
Expand Down Expand Up @@ -470,6 +474,10 @@ CPUParticles2D::EmissionShape CPUParticles2D::get_emission_shape() const {
return emission_shape;
}

CPUParticles2D::EmissionCircleMode CPUParticles2D::get_emission_circle_mode() const {
return emission_circle_mode;
}

void CPUParticles2D::set_gravity(const Vector2 &p_gravity) {
gravity = p_gravity;
}
Expand Down Expand Up @@ -504,7 +512,11 @@ bool CPUParticles2D::get_split_scale() {
}

void CPUParticles2D::_validate_property(PropertyInfo &p_property) const {
if (p_property.name == "emission_sphere_radius" && (emission_shape != EMISSION_SHAPE_SPHERE && emission_shape != EMISSION_SHAPE_SPHERE_SURFACE)) {
if (p_property.name == "emission_sphere_radius" && (emission_shape != EMISSION_SHAPE_SPHERE && emission_shape != EMISSION_SHAPE_SPHERE_SURFACE && emission_shape != EMISSION_SHAPE_CIRCLE)) {
p_property.usage = PROPERTY_USAGE_NONE;
}

if (p_property.name == "emission_circle_mode" && emission_shape != EMISSION_SHAPE_CIRCLE) {
p_property.usage = PROPERTY_USAGE_NONE;
}

Expand Down Expand Up @@ -770,6 +782,21 @@ void CPUParticles2D::_particles_process(double p_delta) {
real_t radius = emission_sphere_radius * Math::randf();
p.transform[2] = Vector2(Math::cos(t), Math::sin(t)) * radius;
} break;
case EMISSION_SHAPE_CIRCLE: {
real_t t = 0;
switch (emission_circle_mode) {
case EMISSION_CIRCLE_MODE_RANDOM: {
t = Math_TAU * Math::randf();
} break;
case EMISSION_CIRCLE_MODE_CW: {
t = Math_TAU * (i / float(pcount));
} break;
case EMISSION_CIRCLE_MODE_CCW: {
t = Math_TAU * (1 - i / float(pcount));
} break;
}
p.transform[2] = Vector2(Math::cos(t), Math::sin(t)) * emission_sphere_radius;
} break;
case EMISSION_SHAPE_SPHERE_SURFACE: {
real_t s = Math::randf(), t = Math_TAU * Math::randf();
real_t radius = emission_sphere_radius * Math::sqrt(1.0 - s * s);
Expand Down Expand Up @@ -1335,6 +1362,9 @@ void CPUParticles2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_emission_shape", "shape"), &CPUParticles2D::set_emission_shape);
ClassDB::bind_method(D_METHOD("get_emission_shape"), &CPUParticles2D::get_emission_shape);

ClassDB::bind_method(D_METHOD("set_emission_circle_mode", "mode"), &CPUParticles2D::set_emission_circle_mode);
ClassDB::bind_method(D_METHOD("get_emission_circle_mode"), &CPUParticles2D::get_emission_circle_mode);

ClassDB::bind_method(D_METHOD("set_emission_sphere_radius", "radius"), &CPUParticles2D::set_emission_sphere_radius);
ClassDB::bind_method(D_METHOD("get_emission_sphere_radius"), &CPUParticles2D::get_emission_sphere_radius);

Expand Down Expand Up @@ -1365,8 +1395,9 @@ void CPUParticles2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("convert_from_particles", "particles"), &CPUParticles2D::convert_from_particles);

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,Circle", 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::INT, "emission_circle_mode", PROPERTY_HINT_ENUM, "Random,Clockwise,Counter Clockwise", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_emission_circle_mode", "get_emission_circle_mode");
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");
Expand Down Expand Up @@ -1459,7 +1490,12 @@ 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_CIRCLE);
BIND_ENUM_CONSTANT(EMISSION_SHAPE_MAX);

BIND_ENUM_CONSTANT(EMISSION_CIRCLE_MODE_RANDOM);
BIND_ENUM_CONSTANT(EMISSION_CIRCLE_MODE_CW);
BIND_ENUM_CONSTANT(EMISSION_CIRCLE_MODE_CCW);
}

CPUParticles2D::CPUParticles2D() {
Expand Down
11 changes: 11 additions & 0 deletions scene/2d/cpu_particles_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,16 @@ class CPUParticles2D : public Node2D {
EMISSION_SHAPE_RECTANGLE,
EMISSION_SHAPE_POINTS,
EMISSION_SHAPE_DIRECTED_POINTS,
EMISSION_SHAPE_CIRCLE,
EMISSION_SHAPE_MAX
};

enum EmissionCircleMode {
EMISSION_CIRCLE_MODE_RANDOM,
EMISSION_CIRCLE_MODE_CW,
EMISSION_CIRCLE_MODE_CCW,
};

private:
bool emitting = false;

Expand Down Expand Up @@ -163,6 +170,7 @@ class CPUParticles2D : public Node2D {
bool particle_flags[PARTICLE_FLAG_MAX];

EmissionShape emission_shape = EMISSION_SHAPE_POINT;
EmissionCircleMode emission_circle_mode = EMISSION_CIRCLE_MODE_RANDOM;
real_t emission_sphere_radius = 1.0;
Vector2 emission_rect_extents = Vector2(1, 1);
Vector<Vector2> emission_points;
Expand Down Expand Up @@ -260,6 +268,7 @@ class CPUParticles2D : public Node2D {
bool get_particle_flag(ParticleFlags p_particle_flag) const;

void set_emission_shape(EmissionShape p_shape);
void set_emission_circle_mode(EmissionCircleMode p_circle_mode);
void set_emission_sphere_radius(real_t p_radius);
void set_emission_rect_extents(Vector2 p_extents);
void set_emission_points(const Vector<Vector2> &p_points);
Expand All @@ -270,6 +279,7 @@ class CPUParticles2D : public Node2D {
void set_split_scale(bool p_split_scale);

EmissionShape get_emission_shape() const;
EmissionCircleMode get_emission_circle_mode() const;
real_t get_emission_sphere_radius() const;
Vector2 get_emission_rect_extents() const;
Vector<Vector2> get_emission_points() const;
Expand All @@ -296,5 +306,6 @@ VARIANT_ENUM_CAST(CPUParticles2D::DrawOrder)
VARIANT_ENUM_CAST(CPUParticles2D::Parameter)
VARIANT_ENUM_CAST(CPUParticles2D::ParticleFlags)
VARIANT_ENUM_CAST(CPUParticles2D::EmissionShape)
VARIANT_ENUM_CAST(CPUParticles2D::EmissionCircleMode)

#endif // CPU_PARTICLES_2D_H

0 comments on commit ec9ca07

Please sign in to comment.