summaryrefslogtreecommitdiffstats
path: root/scene/3d/cpu_particles_3d.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/3d/cpu_particles_3d.cpp')
-rw-r--r--scene/3d/cpu_particles_3d.cpp29
1 files changed, 24 insertions, 5 deletions
diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp
index 03fe5e1fad..acbc443a93 100644
--- a/scene/3d/cpu_particles_3d.cpp
+++ b/scene/3d/cpu_particles_3d.cpp
@@ -448,6 +448,10 @@ void CPUParticles3D::set_emission_ring_inner_radius(real_t p_radius) {
emission_ring_inner_radius = p_radius;
}
+void CPUParticles3D::set_emission_ring_cone_angle(real_t p_angle) {
+ emission_ring_cone_angle = p_angle;
+}
+
void CPUParticles3D::set_scale_curve_x(Ref<Curve> p_scale_curve) {
scale_curve_x = p_scale_curve;
}
@@ -501,6 +505,10 @@ real_t CPUParticles3D::get_emission_ring_inner_radius() const {
return emission_ring_inner_radius;
}
+real_t CPUParticles3D::get_emission_ring_cone_angle() const {
+ return emission_ring_cone_angle;
+}
+
CPUParticles3D::EmissionShape CPUParticles3D::get_emission_shape() const {
return emission_shape;
}
@@ -878,8 +886,14 @@ void CPUParticles3D::_particles_process(double p_delta) {
}
} break;
case EMISSION_SHAPE_RING: {
+ real_t radius_clamped = MAX(0.001, emission_ring_radius);
+ real_t top_radius = MAX(radius_clamped - Math::tan(Math::deg_to_rad(90.0 - emission_ring_cone_angle)) * emission_ring_height, 0.0);
+ real_t y_pos = Math::randf();
+ real_t skew = MAX(MIN(radius_clamped, top_radius) / MAX(radius_clamped, top_radius), 0.5);
+ y_pos = radius_clamped < top_radius ? Math::pow(y_pos, skew) : 1.0 - Math::pow(y_pos, skew);
real_t ring_random_angle = Math::randf() * Math_TAU;
- real_t ring_random_radius = Math::sqrt(Math::randf() * (emission_ring_radius * emission_ring_radius - emission_ring_inner_radius * emission_ring_inner_radius) + emission_ring_inner_radius * emission_ring_inner_radius);
+ real_t ring_random_radius = Math::sqrt(Math::randf() * (radius_clamped * radius_clamped - emission_ring_inner_radius * emission_ring_inner_radius) + emission_ring_inner_radius * emission_ring_inner_radius);
+ ring_random_radius = Math::lerp(ring_random_radius, ring_random_radius * (top_radius / radius_clamped), y_pos);
Vector3 axis = emission_ring_axis == Vector3(0.0, 0.0, 0.0) ? Vector3(0.0, 0.0, 1.0) : emission_ring_axis.normalized();
Vector3 ortho_axis;
if (axis.abs() == Vector3(1.0, 0.0, 0.0)) {
@@ -890,7 +904,7 @@ void CPUParticles3D::_particles_process(double p_delta) {
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;
+ p.transform.origin = ortho_axis * ring_random_radius + (y_pos * emission_ring_height - emission_ring_height / 2.0) * axis;
} break;
case EMISSION_SHAPE_MAX: { // Max value for validity check.
break;
@@ -1550,6 +1564,9 @@ void CPUParticles3D::_bind_methods() {
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("set_emission_ring_cone_angle", "cone_angle"), &CPUParticles3D::set_emission_ring_cone_angle);
+ ClassDB::bind_method(D_METHOD("get_emission_ring_cone_angle"), &CPUParticles3D::get_emission_ring_cone_angle);
+
ClassDB::bind_method(D_METHOD("get_gravity"), &CPUParticles3D::get_gravity);
ClassDB::bind_method(D_METHOD("set_gravity", "accel_vec"), &CPUParticles3D::set_gravity);
@@ -1577,9 +1594,10 @@ void CPUParticles3D::_bind_methods() {
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_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_ring_height", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_emission_ring_height", "get_emission_ring_height");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_ring_radius", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_emission_ring_radius", "get_emission_ring_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_ring_inner_radius", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_emission_ring_inner_radius", "get_emission_ring_inner_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_ring_cone_angle", PROPERTY_HINT_RANGE, "0,90,0.01,degrees"), "set_emission_ring_cone_angle", "get_emission_ring_cone_angle");
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);
@@ -1716,6 +1734,7 @@ CPUParticles3D::CPUParticles3D() {
set_emission_ring_height(1);
set_emission_ring_radius(1);
set_emission_ring_inner_radius(0);
+ set_emission_ring_cone_angle(90);
set_gravity(Vector3(0, -9.8, 0));