diff options
Diffstat (limited to 'scene/3d/cpu_particles_3d.cpp')
-rw-r--r-- | scene/3d/cpu_particles_3d.cpp | 29 |
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)); |