diff options
Diffstat (limited to 'scene/3d/cpu_particles_3d.cpp')
-rw-r--r-- | scene/3d/cpu_particles_3d.cpp | 159 |
1 files changed, 59 insertions, 100 deletions
diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index 2226b0ed83..4244a11592 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -36,31 +36,30 @@ #include "servers/rendering_server.h" AABB CPUParticles3D::get_aabb() const { - return AABB(); } -Vector<Face3> CPUParticles3D::get_faces(uint32_t p_usage_flags) const { +Vector<Face3> CPUParticles3D::get_faces(uint32_t p_usage_flags) const { return Vector<Face3>(); } void CPUParticles3D::set_emitting(bool p_emitting) { - - if (emitting == p_emitting) + if (emitting == p_emitting) { return; + } emitting = p_emitting; if (emitting) { set_process_internal(true); // first update before rendering to avoid one frame delay after emitting starts - if (time == 0) + if (time == 0) { _update_internal(); + } } } void CPUParticles3D::set_amount(int p_amount) { - ERR_FAIL_COND_MSG(p_amount < 1, "Amount of particles must be greater than 0."); particles.resize(p_amount); @@ -69,6 +68,7 @@ void CPUParticles3D::set_amount(int p_amount) { for (int i = 0; i < p_amount; i++) { w[i].active = false; + w[i].custom[3] = 0.0; // Make sure w component isn't garbage data } } @@ -77,98 +77,89 @@ void CPUParticles3D::set_amount(int p_amount) { particle_order.resize(p_amount); } -void CPUParticles3D::set_lifetime(float p_lifetime) { +void CPUParticles3D::set_lifetime(float p_lifetime) { ERR_FAIL_COND_MSG(p_lifetime <= 0, "Particles lifetime must be greater than 0."); lifetime = p_lifetime; } void CPUParticles3D::set_one_shot(bool p_one_shot) { - one_shot = p_one_shot; } void CPUParticles3D::set_pre_process_time(float p_time) { - pre_process_time = p_time; } -void CPUParticles3D::set_explosiveness_ratio(float p_ratio) { +void CPUParticles3D::set_explosiveness_ratio(float p_ratio) { explosiveness_ratio = p_ratio; } -void CPUParticles3D::set_randomness_ratio(float p_ratio) { +void CPUParticles3D::set_randomness_ratio(float p_ratio) { randomness_ratio = p_ratio; } -void CPUParticles3D::set_lifetime_randomness(float p_random) { +void CPUParticles3D::set_lifetime_randomness(float p_random) { lifetime_randomness = p_random; } -void CPUParticles3D::set_use_local_coordinates(bool p_enable) { +void CPUParticles3D::set_use_local_coordinates(bool p_enable) { local_coords = p_enable; } -void CPUParticles3D::set_speed_scale(float p_scale) { +void CPUParticles3D::set_speed_scale(float p_scale) { speed_scale = p_scale; } bool CPUParticles3D::is_emitting() const { - return emitting; } -int CPUParticles3D::get_amount() const { +int CPUParticles3D::get_amount() const { return particles.size(); } -float CPUParticles3D::get_lifetime() const { +float CPUParticles3D::get_lifetime() const { return lifetime; } -bool CPUParticles3D::get_one_shot() const { +bool CPUParticles3D::get_one_shot() const { return one_shot; } float CPUParticles3D::get_pre_process_time() const { - return pre_process_time; } -float CPUParticles3D::get_explosiveness_ratio() const { +float CPUParticles3D::get_explosiveness_ratio() const { return explosiveness_ratio; } -float CPUParticles3D::get_randomness_ratio() const { +float CPUParticles3D::get_randomness_ratio() const { return randomness_ratio; } -float CPUParticles3D::get_lifetime_randomness() const { +float CPUParticles3D::get_lifetime_randomness() const { return lifetime_randomness; } bool CPUParticles3D::get_use_local_coordinates() const { - return local_coords; } float CPUParticles3D::get_speed_scale() const { - return speed_scale; } void CPUParticles3D::set_draw_order(DrawOrder p_order) { - draw_order = p_order; } CPUParticles3D::DrawOrder CPUParticles3D::get_draw_order() const { - return draw_order; } void CPUParticles3D::set_mesh(const Ref<Mesh> &p_mesh) { - mesh = p_mesh; if (mesh.is_valid()) { RS::get_singleton()->multimesh_set_mesh(multimesh, mesh->get_rid()); @@ -178,7 +169,6 @@ void CPUParticles3D::set_mesh(const Ref<Mesh> &p_mesh) { } Ref<Mesh> CPUParticles3D::get_mesh() const { - return mesh; } @@ -199,7 +189,6 @@ bool CPUParticles3D::get_fractional_delta() const { } String CPUParticles3D::get_configuration_warning() const { - String warnings; bool mesh_found = false; @@ -208,26 +197,28 @@ String CPUParticles3D::get_configuration_warning() const { if (get_mesh().is_valid()) { mesh_found = true; for (int j = 0; j < get_mesh()->get_surface_count(); j++) { - anim_material_found = Object::cast_to<ShaderMaterial>(get_mesh()->surface_get_material(j).ptr()) != NULL; + anim_material_found = Object::cast_to<ShaderMaterial>(get_mesh()->surface_get_material(j).ptr()) != nullptr; StandardMaterial3D *spat = Object::cast_to<StandardMaterial3D>(get_mesh()->surface_get_material(j).ptr()); anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == StandardMaterial3D::BILLBOARD_PARTICLES); } } - anim_material_found = anim_material_found || Object::cast_to<ShaderMaterial>(get_material_override().ptr()) != NULL; + anim_material_found = anim_material_found || Object::cast_to<ShaderMaterial>(get_material_override().ptr()) != nullptr; StandardMaterial3D *spat = Object::cast_to<StandardMaterial3D>(get_material_override().ptr()); anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == StandardMaterial3D::BILLBOARD_PARTICLES); if (!mesh_found) { - if (warnings != String()) + if (warnings != String()) { warnings += "\n"; + } warnings += "- " + TTR("Nothing is visible because no mesh has been assigned."); } if (!anim_material_found && (get_param(PARAM_ANIM_SPEED) != 0.0 || get_param(PARAM_ANIM_OFFSET) != 0.0 || get_param_curve(PARAM_ANIM_SPEED).is_valid() || get_param_curve(PARAM_ANIM_OFFSET).is_valid())) { - if (warnings != String()) + if (warnings != String()) { warnings += "\n"; + } warnings += "- " + TTR("CPUParticles3D animation requires the usage of a StandardMaterial3D whose Billboard Mode is set to \"Particle Billboard\"."); } @@ -235,7 +226,6 @@ String CPUParticles3D::get_configuration_warning() const { } void CPUParticles3D::restart() { - time = 0; inactive_time = 0; frame_remainder = 0; @@ -255,71 +245,63 @@ void CPUParticles3D::restart() { } void CPUParticles3D::set_direction(Vector3 p_direction) { - direction = p_direction; } Vector3 CPUParticles3D::get_direction() const { - return direction; } void CPUParticles3D::set_spread(float p_spread) { - spread = p_spread; } float CPUParticles3D::get_spread() const { - return spread; } void CPUParticles3D::set_flatness(float p_flatness) { - flatness = p_flatness; } -float CPUParticles3D::get_flatness() const { +float CPUParticles3D::get_flatness() const { return flatness; } void CPUParticles3D::set_param(Parameter p_param, float p_value) { - ERR_FAIL_INDEX(p_param, PARAM_MAX); parameters[p_param] = p_value; } -float CPUParticles3D::get_param(Parameter p_param) const { +float CPUParticles3D::get_param(Parameter p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); return parameters[p_param]; } void CPUParticles3D::set_param_randomness(Parameter p_param, float p_value) { - ERR_FAIL_INDEX(p_param, PARAM_MAX); randomness[p_param] = p_value; } -float CPUParticles3D::get_param_randomness(Parameter p_param) const { +float CPUParticles3D::get_param_randomness(Parameter p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); return randomness[p_param]; } static void _adjust_curve_range(const Ref<Curve> &p_curve, float p_min, float p_max) { - Ref<Curve> curve = p_curve; - if (!curve.is_valid()) + if (!curve.is_valid()) { return; + } curve->ensure_default_setup(p_min, p_max); } void CPUParticles3D::set_param_curve(Parameter p_param, const Ref<Curve> &p_curve) { - ERR_FAIL_INDEX(p_param, PARAM_MAX); curve_parameters[p_param] = p_curve; @@ -350,7 +332,6 @@ void CPUParticles3D::set_param_curve(Parameter p_param, const Ref<Curve> &p_curv _adjust_curve_range(p_curve, -360, 360); } break; case PARAM_SCALE: { - } break; case PARAM_HUE_VARIATION: { _adjust_curve_range(p_curve, -1, 1); @@ -364,30 +345,26 @@ void CPUParticles3D::set_param_curve(Parameter p_param, const Ref<Curve> &p_curv } } } -Ref<Curve> CPUParticles3D::get_param_curve(Parameter p_param) const { +Ref<Curve> CPUParticles3D::get_param_curve(Parameter p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, Ref<Curve>()); return curve_parameters[p_param]; } void CPUParticles3D::set_color(const Color &p_color) { - color = p_color; } Color CPUParticles3D::get_color() const { - return color; } void CPUParticles3D::set_color_ramp(const Ref<Gradient> &p_ramp) { - color_ramp = p_ramp; } Ref<Gradient> CPUParticles3D::get_color_ramp() const { - return color_ramp; } @@ -410,67 +387,58 @@ void CPUParticles3D::set_emission_shape(EmissionShape p_shape) { } void CPUParticles3D::set_emission_sphere_radius(float p_radius) { - emission_sphere_radius = p_radius; } void CPUParticles3D::set_emission_box_extents(Vector3 p_extents) { - emission_box_extents = p_extents; } void CPUParticles3D::set_emission_points(const Vector<Vector3> &p_points) { - emission_points = p_points; } void CPUParticles3D::set_emission_normals(const Vector<Vector3> &p_normals) { - emission_normals = p_normals; } void CPUParticles3D::set_emission_colors(const Vector<Color> &p_colors) { - emission_colors = p_colors; } float CPUParticles3D::get_emission_sphere_radius() const { - return emission_sphere_radius; } -Vector3 CPUParticles3D::get_emission_box_extents() const { +Vector3 CPUParticles3D::get_emission_box_extents() const { return emission_box_extents; } -Vector<Vector3> CPUParticles3D::get_emission_points() const { +Vector<Vector3> CPUParticles3D::get_emission_points() const { return emission_points; } -Vector<Vector3> CPUParticles3D::get_emission_normals() const { +Vector<Vector3> CPUParticles3D::get_emission_normals() const { return emission_normals; } Vector<Color> CPUParticles3D::get_emission_colors() const { - return emission_colors; } CPUParticles3D::EmissionShape CPUParticles3D::get_emission_shape() const { return emission_shape; } -void CPUParticles3D::set_gravity(const Vector3 &p_gravity) { +void CPUParticles3D::set_gravity(const Vector3 &p_gravity) { gravity = p_gravity; } Vector3 CPUParticles3D::get_gravity() const { - return gravity; } void CPUParticles3D::_validate_property(PropertyInfo &property) const { - if (property.name == "color" && color_ramp.is_valid()) { property.usage = 0; } @@ -497,7 +465,6 @@ void CPUParticles3D::_validate_property(PropertyInfo &property) const { } static uint32_t idhash(uint32_t x) { - x = ((x >> uint32_t(16)) ^ x) * uint32_t(0x45d9f3b); x = ((x >> uint32_t(16)) ^ x) * uint32_t(0x45d9f3b); x = (x >> uint32_t(16)) ^ x; @@ -507,18 +474,19 @@ static uint32_t idhash(uint32_t x) { static float rand_from_seed(uint32_t &seed) { int k; int s = int(seed); - if (s == 0) + if (s == 0) { s = 305420679; + } k = s / 127773; s = 16807 * (s - k * 127773) - 2836 * k; - if (s < 0) + if (s < 0) { s += 2147483647; + } seed = uint32_t(s); return float(seed % uint32_t(65536)) / 65535.0; } void CPUParticles3D::_update_internal() { - if (particles.size() == 0 || !is_visible_in_tree()) { _set_redraw(false); return; @@ -546,12 +514,12 @@ void CPUParticles3D::_update_internal() { bool processed = false; if (time == 0 && pre_process_time > 0.0) { - float frame_time; - if (fixed_fps > 0) + if (fixed_fps > 0) { frame_time = 1.0 / fixed_fps; - else + } else { frame_time = 1.0 / 30.0; + } float todo = pre_process_time; @@ -593,7 +561,6 @@ void CPUParticles3D::_update_internal() { } void CPUParticles3D::_particles_process(float p_delta) { - p_delta *= speed_scale; int pcount = particles.size(); @@ -622,11 +589,11 @@ void CPUParticles3D::_particles_process(float p_delta) { float system_phase = time / lifetime; for (int i = 0; i < pcount; i++) { - Particle &p = parray[i]; - if (!emitting && !p.active) + if (!emitting && !p.active) { continue; + } float local_delta = p_delta; @@ -680,7 +647,6 @@ void CPUParticles3D::_particles_process(float p_delta) { } if (restart) { - if (!emitting) { p.active = false; continue; @@ -749,10 +715,10 @@ void CPUParticles3D::_particles_process(float p_delta) { } break; case EMISSION_SHAPE_POINTS: case EMISSION_SHAPE_DIRECTED_POINTS: { - int pc = emission_points.size(); - if (pc == 0) + if (pc == 0) { break; + } int random_idx = Math::rand() % pc; @@ -804,7 +770,6 @@ void CPUParticles3D::_particles_process(float p_delta) { } else if (p.time > p.lifetime) { p.active = false; } else { - uint32_t alt_seed = p.seed; p.time += local_delta; @@ -874,7 +839,6 @@ void CPUParticles3D::_particles_process(float p_delta) { force += diff.length() > 0.0 ? diff.normalized() * (parameters[PARAM_RADIAL_ACCEL] + tex_radial_accel) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_RADIAL_ACCEL]) : Vector3(); //apply tangential acceleration; if (flags[FLAG_DISABLE_Z]) { - Vector2 yx = Vector2(diff.y, diff.x); Vector2 yx2 = (yx * Vector2(-1.0, 1.0)).normalized(); force += yx.length() > 0.0 ? Vector3(yx2.x, yx2.y, 0.0) * ((parameters[PARAM_TANGENTIAL_ACCEL] + tex_tangential_accel) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_TANGENTIAL_ACCEL])) : Vector3(); @@ -902,7 +866,6 @@ void CPUParticles3D::_particles_process(float p_delta) { p.velocity = p.velocity.normalized() * tex_linear_velocity; } if (parameters[PARAM_DAMPING] + tex_damping > 0.0) { - float v = p.velocity.length(); float damp = (parameters[PARAM_DAMPING] + tex_damping) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_DAMPING]); v -= damp * local_delta; @@ -959,7 +922,6 @@ void CPUParticles3D::_particles_process(float p_delta) { p.color *= p.base_color; if (flags[FLAG_DISABLE_Z]) { - if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) { if (p.velocity.length() > 0.0) { p.transform.basis.set_axis(1, p.velocity.normalized()); @@ -1003,7 +965,9 @@ void CPUParticles3D::_particles_process(float p_delta) { //scale by scale float base_scale = tex_scale * Math::lerp(parameters[PARAM_SCALE], 1.0f, p.scale_rand * randomness[PARAM_SCALE]); - if (base_scale < 0.000001) base_scale = 0.000001; + if (base_scale < 0.000001) { + base_scale = 0.000001; + } p.transform.basis.scale(Vector3(1, 1, 1) * base_scale); @@ -1022,7 +986,7 @@ void CPUParticles3D::_update_particle_data_buffer() { int pc = particles.size(); int *ow; - int *order = NULL; + int *order = nullptr; float *w = particle_data.ptrw(); const Particle *r = particles.ptr(); @@ -1045,7 +1009,6 @@ void CPUParticles3D::_update_particle_data_buffer() { Vector3 dir = c->get_global_transform().basis.get_axis(2); //far away to close if (local_coords) { - // will look different from Particles in editor as this is based on the camera in the scenetree // and not the editor camera dir = inv_emission_transform.xform(dir).normalized(); @@ -1062,7 +1025,6 @@ void CPUParticles3D::_update_particle_data_buffer() { } for (int i = 0; i < pc; i++) { - int idx = order ? order[i] : i; Transform t = r[idx].transform; @@ -1107,8 +1069,9 @@ void CPUParticles3D::_update_particle_data_buffer() { } void CPUParticles3D::_set_redraw(bool p_redraw) { - if (redraw == p_redraw) + if (redraw == p_redraw) { return; + } redraw = p_redraw; { @@ -1129,7 +1092,6 @@ void CPUParticles3D::_set_redraw(bool p_redraw) { } void CPUParticles3D::_update_render_thread() { - MutexLock lock(update_mutex); if (can_update) { @@ -1139,13 +1101,13 @@ void CPUParticles3D::_update_render_thread() { } void CPUParticles3D::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE) { set_process_internal(emitting); // first update before rendering to avoid one frame delay after emitting starts - if (emitting && (time == 0)) + if (emitting && (time == 0)) { _update_internal(); + } } if (p_what == NOTIFICATION_EXIT_TREE) { @@ -1154,8 +1116,9 @@ void CPUParticles3D::_notification(int p_what) { if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { // first update before rendering to avoid one frame delay after emitting starts - if (emitting && (time == 0)) + if (emitting && (time == 0)) { _update_internal(); + } } if (p_what == NOTIFICATION_INTERNAL_PROCESS) { @@ -1163,11 +1126,9 @@ void CPUParticles3D::_notification(int p_what) { } if (p_what == NOTIFICATION_TRANSFORM_CHANGED) { - inv_emission_transform = get_global_transform().affine_inverse(); if (!local_coords) { - int pc = particles.size(); float *w = particle_data.ptrw(); @@ -1175,7 +1136,6 @@ void CPUParticles3D::_notification(int p_what) { float *ptr = w; for (int i = 0; i < pc; i++) { - Transform t = inv_emission_transform * r[i].transform; if (r[i].active) { @@ -1204,7 +1164,6 @@ void CPUParticles3D::_notification(int p_what) { } void CPUParticles3D::convert_from_particles(Node *p_particles) { - GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_particles); ERR_FAIL_COND_MSG(!particles, "Only GPUParticles3D nodes can be converted to CPUParticles3D."); @@ -1223,8 +1182,9 @@ void CPUParticles3D::convert_from_particles(Node *p_particles) { set_mesh(particles->get_draw_pass_mesh(0)); Ref<ParticlesMaterial> material = particles->get_process_material(); - if (material.is_null()) + if (material.is_null()) { return; + } set_direction(material->get_direction()); set_spread(material->get_spread()); @@ -1252,7 +1212,8 @@ void CPUParticles3D::convert_from_particles(Node *p_particles) { set_param(m_param, material->get_param(ParticlesMaterial::m_param)); \ { \ Ref<CurveTexture> ctex = material->get_param_texture(ParticlesMaterial::m_param); \ - if (ctex.is_valid()) set_param_curve(m_param, ctex->get_curve()); \ + if (ctex.is_valid()) \ + set_param_curve(m_param, ctex->get_curve()); \ } \ set_param_randomness(m_param, material->get_param_randomness(ParticlesMaterial::m_param)); @@ -1273,7 +1234,6 @@ void CPUParticles3D::convert_from_particles(Node *p_particles) { } void CPUParticles3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_emitting", "emitting"), &CPUParticles3D::set_emitting); ClassDB::bind_method(D_METHOD("set_amount", "amount"), &CPUParticles3D::set_amount); ClassDB::bind_method(D_METHOD("set_lifetime", "secs"), &CPUParticles3D::set_lifetime); @@ -1478,7 +1438,6 @@ void CPUParticles3D::_bind_methods() { } CPUParticles3D::CPUParticles3D() { - time = 0; inactive_time = 0; frame_remainder = 0; |