Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ring emitter for 4.0 #50370

Merged
merged 1 commit into from
Jul 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions doc/classes/CPUParticles3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,21 @@
<member name="emission_normals" type="PackedVector3Array" setter="set_emission_normals" getter="get_emission_normals">
Sets the direction the particles will be emitted in when using [constant EMISSION_SHAPE_DIRECTED_POINTS].
</member>
<member name="emission_points" type="PackedVector3Array" setter="set_emission_points" getter="get_emission_points" default="PackedVector3Array()">
<member name="emission_points" type="PackedVector3Array" setter="set_emission_points" getter="get_emission_points">
Sets the initial positions to spawn particles when using [constant EMISSION_SHAPE_POINTS] or [constant EMISSION_SHAPE_DIRECTED_POINTS].
</member>
<member name="emission_ring_axis" type="Vector3" setter="set_emission_ring_axis" getter="get_emission_ring_axis">
The axis of the ring when using the emitter [constant EMISSION_SHAPE_RING].
</member>
<member name="emission_ring_height" type="float" setter="set_emission_ring_height" getter="get_emission_ring_height">
The height of the ring when using the emitter [constant EMISSION_SHAPE_RING].
</member>
<member name="emission_ring_inner_radius" type="float" setter="set_emission_ring_inner_radius" getter="get_emission_ring_inner_radius">
The inner radius of the ring when using the emitter [constant EMISSION_SHAPE_RING].
</member>
<member name="emission_ring_radius" type="float" setter="set_emission_ring_radius" getter="get_emission_ring_radius">
The radius of the ring when using the emitter [constant EMISSION_SHAPE_RING].
</member>
<member name="emission_shape" type="int" setter="set_emission_shape" getter="get_emission_shape" enum="CPUParticles3D.EmissionShape" default="0">
Particles will be emitted inside this region. See [enum EmissionShape] for possible values.
</member>
Expand Down Expand Up @@ -378,7 +390,10 @@
<constant name="EMISSION_SHAPE_DIRECTED_POINTS" value="4" 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="5" enum="EmissionShape">
<constant name="EMISSION_SHAPE_RING" value="5" enum="EmissionShape">
Particles will be emitted in a ring or cylinder.
</constant>
<constant name="EMISSION_SHAPE_MAX" value="6" enum="EmissionShape">
Represents the size of the [enum EmissionShape] enum.
</constant>
</constants>
Expand Down
17 changes: 16 additions & 1 deletion doc/classes/ParticlesMaterial.xml
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,18 @@
<member name="emission_point_texture" type="Texture2D" setter="set_emission_point_texture" getter="get_emission_point_texture">
Particles will be emitted at positions determined by sampling this texture at a random position. Used with [constant EMISSION_SHAPE_POINTS] and [constant EMISSION_SHAPE_DIRECTED_POINTS]. Can be created automatically from mesh or node by selecting "Create Emission Points from Mesh/Node" under the "Particles" tool in the toolbar.
</member>
<member name="emission_ring_axis" type="Vector3" setter="set_emission_ring_axis" getter="get_emission_ring_axis">
The axis of the ring when using the emitter [constant EMISSION_SHAPE_RING].
</member>
<member name="emission_ring_height" type="float" setter="set_emission_ring_height" getter="get_emission_ring_height">
The height of the ring when using the emitter [constant EMISSION_SHAPE_RING].
</member>
<member name="emission_ring_inner_radius" type="float" setter="set_emission_ring_inner_radius" getter="get_emission_ring_inner_radius">
The inner radius of the ring when using the emitter [constant EMISSION_SHAPE_RING].
</member>
<member name="emission_ring_radius" type="float" setter="set_emission_ring_radius" getter="get_emission_ring_radius">
The radius of the ring when using the emitter [constant EMISSION_SHAPE_RING].
</member>
<member name="emission_shape" type="int" setter="set_emission_shape" getter="get_emission_shape" enum="ParticlesMaterial.EmissionShape" default="0">
Particles will be emitted inside this region. Use [enum EmissionShape] constants for values.
</member>
Expand Down Expand Up @@ -338,7 +350,10 @@
<constant name="EMISSION_SHAPE_DIRECTED_POINTS" value="4" enum="EmissionShape">
Particles will be emitted at a position determined by sampling a random point on the [member emission_point_texture]. Particle velocity and rotation will be set based on [member emission_normal_texture]. Particle color will be modulated by [member emission_color_texture].
</constant>
<constant name="EMISSION_SHAPE_MAX" value="5" enum="EmissionShape">
<constant name="EMISSION_SHAPE_RING" value="5" enum="EmissionShape">
Particles will be emitted in a ring or cylinder.
</constant>
<constant name="EMISSION_SHAPE_MAX" value="6" enum="EmissionShape">
Represents the size of the [enum EmissionShape] enum.
</constant>
<constant name="SUB_EMITTER_DISABLED" value="0" enum="SubEmitterMode">
Expand Down
76 changes: 74 additions & 2 deletions scene/3d/cpu_particles_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,22 @@ void CPUParticles3D::set_emission_colors(const Vector<Color> &p_colors) {
emission_colors = p_colors;
}

void CPUParticles3D::set_emission_ring_axis(Vector3 p_axis) {
emission_ring_axis = p_axis;
}

void CPUParticles3D::set_emission_ring_height(float p_height) {
emission_ring_height = p_height;
}

void CPUParticles3D::set_emission_ring_radius(float p_radius) {
emission_ring_radius = p_radius;
}

void CPUParticles3D::set_emission_ring_inner_radius(float p_radius) {
emission_ring_inner_radius = p_radius;
}

float CPUParticles3D::get_emission_sphere_radius() const {
return emission_sphere_radius;
}
Expand All @@ -421,6 +437,22 @@ Vector<Color> CPUParticles3D::get_emission_colors() const {
return emission_colors;
}

Vector3 CPUParticles3D::get_emission_ring_axis() const {
return emission_ring_axis;
}

float CPUParticles3D::get_emission_ring_height() const {
return emission_ring_height;
}

float CPUParticles3D::get_emission_ring_radius() const {
return emission_ring_radius;
}

float CPUParticles3D::get_emission_ring_inner_radius() const {
return emission_ring_inner_radius;
}

CPUParticles3D::EmissionShape CPUParticles3D::get_emission_shape() const {
return emission_shape;
}
Expand All @@ -446,14 +478,18 @@ void CPUParticles3D::_validate_property(PropertyInfo &property) const {
property.usage = PROPERTY_USAGE_NONE;
}

if ((property.name == "emission_point_texture" || property.name == "emission_color_texture") && (emission_shape < EMISSION_SHAPE_POINTS)) {
if ((property.name == "emission_point_texture" || property.name == "emission_color_texture" || property.name == "emission_points") && (emission_shape != EMISSION_SHAPE_POINTS && (emission_shape != EMISSION_SHAPE_DIRECTED_POINTS))) {
property.usage = PROPERTY_USAGE_NONE;
}

if (property.name == "emission_normals" && emission_shape != EMISSION_SHAPE_DIRECTED_POINTS) {
property.usage = PROPERTY_USAGE_NONE;
}

if (property.name.begins_with("emission_ring_") && emission_shape != EMISSION_SHAPE_RING) {
property.usage = PROPERTY_USAGE_NONE;
}

if (property.name.begins_with("orbit_") && !particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
property.usage = PROPERTY_USAGE_NONE;
}
Expand Down Expand Up @@ -750,6 +786,21 @@ void CPUParticles3D::_particles_process(float p_delta) {
p.base_color = emission_colors.get(random_idx);
}
} break;
case EMISSION_SHAPE_RING: {
float ring_random_angle = Math::randf() * 2.0 * Math_PI;
float ring_random_radius = Math::randf() * (emission_ring_radius - emission_ring_inner_radius) + emission_ring_inner_radius;
Vector3 axis = emission_ring_axis.normalized();
Vector3 ortho_axis = Vector3();
if (axis == Vector3(1.0, 0.0, 0.0)) {
ortho_axis = Vector3(0.0, 1.0, 0.0).cross(axis);
} else {
ortho_axis = Vector3(1.0, 0.0, 0.0).cross(axis);
}
ortho_axis = ortho_axis.normalized();
ortho_axis.rotate(axis, ring_random_angle);
ortho_axis = ortho_axis.normalized();
p.transform.origin = ortho_axis * ring_random_radius + (Math::randf() * emission_ring_height - emission_ring_height / 2.0) * axis;
} break;
case EMISSION_SHAPE_MAX: { // Max value for validity check.
break;
}
Expand Down Expand Up @@ -1340,18 +1391,34 @@ void CPUParticles3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_emission_colors", "array"), &CPUParticles3D::set_emission_colors);
ClassDB::bind_method(D_METHOD("get_emission_colors"), &CPUParticles3D::get_emission_colors);

ClassDB::bind_method(D_METHOD("set_emission_ring_axis", "axis"), &CPUParticles3D::set_emission_ring_axis);
ClassDB::bind_method(D_METHOD("get_emission_ring_axis"), &CPUParticles3D::get_emission_ring_axis);

ClassDB::bind_method(D_METHOD("set_emission_ring_height", "height"), &CPUParticles3D::set_emission_ring_height);
ClassDB::bind_method(D_METHOD("get_emission_ring_height"), &CPUParticles3D::get_emission_ring_height);

ClassDB::bind_method(D_METHOD("set_emission_ring_radius", "radius"), &CPUParticles3D::set_emission_ring_radius);
ClassDB::bind_method(D_METHOD("get_emission_ring_radius"), &CPUParticles3D::get_emission_ring_radius);

ClassDB::bind_method(D_METHOD("set_emission_ring_inner_radius", "inner_radius"), &CPUParticles3D::set_emission_ring_inner_radius);
ClassDB::bind_method(D_METHOD("get_emission_ring_inner_radius"), &CPUParticles3D::get_emission_ring_inner_radius);

ClassDB::bind_method(D_METHOD("get_gravity"), &CPUParticles3D::get_gravity);
ClassDB::bind_method(D_METHOD("set_gravity", "accel_vec"), &CPUParticles3D::set_gravity);

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

ADD_GROUP("Emission Shape", "emission_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Box,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,Box,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"), "set_emission_sphere_radius", "get_emission_sphere_radius");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "emission_box_extents"), "set_emission_box_extents", "get_emission_box_extents");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "emission_points"), "set_emission_points", "get_emission_points");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_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::VECTOR3, "emission_ring_axis"), "set_emission_ring_axis", "get_emission_ring_axis");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_ring_height"), "set_emission_ring_height", "get_emission_ring_height");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_ring_radius"), "set_emission_ring_radius", "get_emission_ring_radius");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_ring_inner_radius"), "set_emission_ring_inner_radius", "get_emission_ring_inner_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_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_rotate_y"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_ROTATE_Y);
Expand Down Expand Up @@ -1437,6 +1504,7 @@ void CPUParticles3D::_bind_methods() {
BIND_ENUM_CONSTANT(EMISSION_SHAPE_BOX);
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);
}

Expand Down Expand Up @@ -1465,6 +1533,10 @@ CPUParticles3D::CPUParticles3D() {
set_emission_shape(EMISSION_SHAPE_POINT);
set_emission_sphere_radius(1);
set_emission_box_extents(Vector3(1, 1, 1));
set_emission_ring_axis(Vector3(0, 0, 1.0));
set_emission_ring_height(1);
set_emission_ring_radius(1);
set_emission_ring_inner_radius(0);

set_gravity(Vector3(0, -9.8, 0));

Expand Down
13 changes: 13 additions & 0 deletions scene/3d/cpu_particles_3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class CPUParticles3D : public GeometryInstance3D {
EMISSION_SHAPE_BOX,
EMISSION_SHAPE_POINTS,
EMISSION_SHAPE_DIRECTED_POINTS,
EMISSION_SHAPE_RING,
EMISSION_SHAPE_MAX
};

Expand Down Expand Up @@ -171,6 +172,10 @@ class CPUParticles3D : public GeometryInstance3D {
Vector<Vector3> emission_normals;
Vector<Color> emission_colors;
int emission_point_count = 0;
Vector3 emission_ring_axis;
float emission_ring_height;
float emission_ring_radius;
float emission_ring_inner_radius;

Vector3 gravity = Vector3(0, -9.8, 0);

Expand Down Expand Up @@ -268,6 +273,10 @@ class CPUParticles3D : public GeometryInstance3D {
void set_emission_normals(const Vector<Vector3> &p_normals);
void set_emission_colors(const Vector<Color> &p_colors);
void set_emission_point_count(int p_count);
void set_emission_ring_axis(Vector3 p_axis);
void set_emission_ring_height(float p_height);
void set_emission_ring_radius(float p_radius);
void set_emission_ring_inner_radius(float p_radius);

EmissionShape get_emission_shape() const;
float get_emission_sphere_radius() const;
Expand All @@ -276,6 +285,10 @@ class CPUParticles3D : public GeometryInstance3D {
Vector<Vector3> get_emission_normals() const;
Vector<Color> get_emission_colors() const;
int get_emission_point_count() const;
Vector3 get_emission_ring_axis() const;
float get_emission_ring_height() const;
float get_emission_ring_radius() const;
float get_emission_ring_inner_radius() const;

void set_gravity(const Vector3 &p_gravity);
Vector3 get_gravity() const;
Expand Down
Loading