diff options
Diffstat (limited to 'scene/3d/gpu_particles_3d.cpp')
-rw-r--r-- | scene/3d/gpu_particles_3d.cpp | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp index 3a23cbcff1..a7667267a6 100644 --- a/scene/3d/gpu_particles_3d.cpp +++ b/scene/3d/gpu_particles_3d.cpp @@ -30,6 +30,9 @@ #include "gpu_particles_3d.h" +#include "scene/3d/cpu_particles_3d.h" +#include "scene/resources/curve_texture.h" +#include "scene/resources/gradient_texture.h" #include "scene/resources/particle_process_material.h" #include "scene/scene_string_names.h" @@ -546,10 +549,98 @@ void GPUParticles3D::set_transform_align(TransformAlign p_align) { transform_align = p_align; RS::get_singleton()->particles_set_transform_align(particles, RS::ParticlesTransformAlign(transform_align)); } + GPUParticles3D::TransformAlign GPUParticles3D::get_transform_align() const { return transform_align; } +void GPUParticles3D::convert_from_particles(Node *p_particles) { + CPUParticles3D *cpu_particles = Object::cast_to<CPUParticles3D>(p_particles); + ERR_FAIL_NULL_MSG(cpu_particles, "Only CPUParticles3D nodes can be converted to GPUParticles3D."); + + set_emitting(cpu_particles->is_emitting()); + set_amount(cpu_particles->get_amount()); + set_lifetime(cpu_particles->get_lifetime()); + set_one_shot(cpu_particles->get_one_shot()); + set_pre_process_time(cpu_particles->get_pre_process_time()); + set_explosiveness_ratio(cpu_particles->get_explosiveness_ratio()); + set_randomness_ratio(cpu_particles->get_randomness_ratio()); + set_use_local_coordinates(cpu_particles->get_use_local_coordinates()); + set_fixed_fps(cpu_particles->get_fixed_fps()); + set_fractional_delta(cpu_particles->get_fractional_delta()); + set_speed_scale(cpu_particles->get_speed_scale()); + set_draw_order(DrawOrder(cpu_particles->get_draw_order())); + set_draw_pass_mesh(0, cpu_particles->get_mesh()); + + Ref<ParticleProcessMaterial> proc_mat = memnew(ParticleProcessMaterial); + set_process_material(proc_mat); + + proc_mat->set_direction(cpu_particles->get_direction()); + proc_mat->set_spread(cpu_particles->get_spread()); + proc_mat->set_flatness(cpu_particles->get_flatness()); + proc_mat->set_color(cpu_particles->get_color()); + + Ref<Gradient> grad = cpu_particles->get_color_ramp(); + if (grad.is_valid()) { + Ref<GradientTexture1D> tex = memnew(GradientTexture1D); + tex->set_gradient(grad); + proc_mat->set_color_ramp(tex); + } + + Ref<Gradient> grad_init = cpu_particles->get_color_initial_ramp(); + if (grad_init.is_valid()) { + Ref<GradientTexture1D> tex = memnew(GradientTexture1D); + tex->set_gradient(grad_init); + proc_mat->set_color_initial_ramp(tex); + } + + proc_mat->set_particle_flag(ParticleProcessMaterial::PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY, cpu_particles->get_particle_flag(CPUParticles3D::PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY)); + proc_mat->set_particle_flag(ParticleProcessMaterial::PARTICLE_FLAG_ROTATE_Y, cpu_particles->get_particle_flag(CPUParticles3D::PARTICLE_FLAG_ROTATE_Y)); + proc_mat->set_particle_flag(ParticleProcessMaterial::PARTICLE_FLAG_DISABLE_Z, cpu_particles->get_particle_flag(CPUParticles3D::PARTICLE_FLAG_DISABLE_Z)); + + proc_mat->set_emission_shape(ParticleProcessMaterial::EmissionShape(cpu_particles->get_emission_shape())); + proc_mat->set_emission_sphere_radius(cpu_particles->get_emission_sphere_radius()); + proc_mat->set_emission_box_extents(cpu_particles->get_emission_box_extents()); + + if (cpu_particles->get_split_scale()) { + Ref<CurveXYZTexture> scale3D = memnew(CurveXYZTexture); + scale3D->set_curve_x(cpu_particles->get_scale_curve_x()); + scale3D->set_curve_y(cpu_particles->get_scale_curve_y()); + scale3D->set_curve_z(cpu_particles->get_scale_curve_z()); + proc_mat->set_param_texture(ParticleProcessMaterial::PARAM_SCALE, scale3D); + } + + proc_mat->set_gravity(cpu_particles->get_gravity()); + proc_mat->set_lifetime_randomness(cpu_particles->get_lifetime_randomness()); + +#define CONVERT_PARAM(m_param) \ + proc_mat->set_param_min(ParticleProcessMaterial::m_param, cpu_particles->get_param_min(CPUParticles3D::m_param)); \ + { \ + Ref<Curve> curve = cpu_particles->get_param_curve(CPUParticles3D::m_param); \ + if (curve.is_valid()) { \ + Ref<CurveTexture> tex = memnew(CurveTexture); \ + tex->set_curve(curve); \ + proc_mat->set_param_texture(ParticleProcessMaterial::m_param, tex); \ + } \ + } \ + proc_mat->set_param_max(ParticleProcessMaterial::m_param, cpu_particles->get_param_max(CPUParticles3D::m_param)); + + CONVERT_PARAM(PARAM_INITIAL_LINEAR_VELOCITY); + CONVERT_PARAM(PARAM_ANGULAR_VELOCITY); + CONVERT_PARAM(PARAM_ORBIT_VELOCITY); + CONVERT_PARAM(PARAM_LINEAR_ACCEL); + CONVERT_PARAM(PARAM_RADIAL_ACCEL); + CONVERT_PARAM(PARAM_TANGENTIAL_ACCEL); + CONVERT_PARAM(PARAM_DAMPING); + CONVERT_PARAM(PARAM_ANGLE); + CONVERT_PARAM(PARAM_SCALE); + CONVERT_PARAM(PARAM_HUE_VARIATION); + CONVERT_PARAM(PARAM_ANIM_SPEED); + CONVERT_PARAM(PARAM_ANIM_OFFSET); + +#undef CONVERT_PARAM +} + void GPUParticles3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_emitting", "emitting"), &GPUParticles3D::set_emitting); ClassDB::bind_method(D_METHOD("set_amount", "amount"), &GPUParticles3D::set_amount); @@ -613,6 +704,8 @@ void GPUParticles3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_transform_align", "align"), &GPUParticles3D::set_transform_align); ClassDB::bind_method(D_METHOD("get_transform_align"), &GPUParticles3D::get_transform_align); + ClassDB::bind_method(D_METHOD("convert_from_particles", "particles"), &GPUParticles3D::convert_from_particles); + ADD_SIGNAL(MethodInfo("finished")); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting"); |