From 00b15c19b7adcad21465f731f76e1888f1553da2 Mon Sep 17 00:00:00 2001 From: Tomasz Chabora Date: Mon, 4 Mar 2019 23:45:53 +0100 Subject: [PATCH] Add a Direction property to ParticlesMaterial --- scene/2d/cpu_particles_2d.cpp | 21 +++++++++++++++-- scene/2d/cpu_particles_2d.h | 4 ++++ scene/3d/cpu_particles.cpp | 24 +++++++++++++++---- scene/3d/cpu_particles.h | 4 ++++ scene/resources/particles_material.cpp | 32 ++++++++++++++++++++------ scene/resources/particles_material.h | 5 ++++ 6 files changed, 77 insertions(+), 13 deletions(-) diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index c50a8d4a1a9..2a497605633 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -269,6 +269,16 @@ void CPUParticles2D::restart() { } } +void CPUParticles2D::set_direction(Vector2 p_direction) { + + direction = p_direction; +} + +Vector2 CPUParticles2D::get_direction() const { + + return direction; +} + void CPUParticles2D::set_spread(float p_spread) { spread = p_spread; @@ -635,7 +645,7 @@ void CPUParticles2D::_particles_process(float p_delta) { p.hue_rot_rand = Math::randf(); p.anim_offset_rand = Math::randf(); - float angle1_rad = (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; + float angle1_rad = Math::atan2(direction.y, direction.x) + (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; Vector2 rot = Vector2(Math::cos(angle1_rad), Math::sin(angle1_rad)); p.velocity = rot * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp(1.0f, float(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]); @@ -1104,6 +1114,8 @@ void CPUParticles2D::convert_from_particles(Node *p_particles) { if (material.is_null()) return; + Vector3 dir = material->get_direction(); + set_direction(Vector2(dir.x, dir.y)); set_spread(material->get_spread()); set_flatness(material->get_flatness()); @@ -1208,6 +1220,9 @@ void CPUParticles2D::_bind_methods() { //////////////////////////////// + ClassDB::bind_method(D_METHOD("set_direction", "direction"), &CPUParticles2D::set_direction); + ClassDB::bind_method(D_METHOD("get_direction"), &CPUParticles2D::get_direction); + ClassDB::bind_method(D_METHOD("set_spread", "degrees"), &CPUParticles2D::set_spread); ClassDB::bind_method(D_METHOD("get_spread"), &CPUParticles2D::get_spread); @@ -1266,7 +1281,8 @@ void CPUParticles2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "emission_colors"), "set_emission_colors", "get_emission_colors"); ADD_GROUP("Flags", "flag_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_align_y"), "set_particle_flag", "get_particle_flag", FLAG_ALIGN_Y_TO_VELOCITY); - ADD_GROUP("Spread", ""); + ADD_GROUP("Direction", ""); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "direction"), "set_direction", "get_direction"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "flatness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_flatness", "get_flatness"); ADD_GROUP("Gravity", ""); @@ -1373,6 +1389,7 @@ CPUParticles2D::CPUParticles2D() { set_draw_order(DRAW_ORDER_INDEX); set_speed_scale(1); + set_direction(Vector2(1, 0)); set_spread(45); set_flatness(0); set_param(PARAM_INITIAL_LINEAR_VELOCITY, 1); diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index b1adf62980a..18a855ab303 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -148,6 +148,7 @@ private: //////// + Vector2 direction; float spread; float flatness; @@ -227,6 +228,9 @@ public: /////////////////// + void set_direction(Vector2 p_direction); + Vector2 get_direction() const; + void set_spread(float p_spread); float get_spread() const; diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp index 11dfbdb1f95..6415b0ff28f 100644 --- a/scene/3d/cpu_particles.cpp +++ b/scene/3d/cpu_particles.cpp @@ -247,6 +247,16 @@ void CPUParticles::restart() { } } +void CPUParticles::set_direction(Vector3 p_direction) { + + direction = p_direction; +} + +Vector3 CPUParticles::get_direction() const { + + return direction; +} + void CPUParticles::set_spread(float p_spread) { spread = p_spread; @@ -606,13 +616,13 @@ void CPUParticles::_particles_process(float p_delta) { p.anim_offset_rand = Math::randf(); if (flags[FLAG_DISABLE_Z]) { - float angle1_rad = (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; + float angle1_rad = Math::atan2(direction.y, direction.x) + (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; Vector3 rot = Vector3(Math::cos(angle1_rad), Math::sin(angle1_rad), 0.0); p.velocity = rot * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp(1.0f, float(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]); } else { //initiate velocity spread in 3D - float angle1_rad = (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; - float angle2_rad = (Math::randf() * 2.0 - 1.0) * (1.0 - flatness) * Math_PI * spread / 180.0; + float angle1_rad = Math::atan2(direction.x, direction.z) + (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; + float angle2_rad = Math::atan2(direction.y, Math::abs(direction.z)) + (Math::randf() * 2.0 - 1.0) * (1.0 - flatness) * Math_PI * spread / 180.0; Vector3 direction_xz = Vector3(Math::sin(angle1_rad), 0, Math::cos(angle1_rad)); Vector3 direction_yz = Vector3(0, Math::sin(angle2_rad), Math::cos(angle2_rad)); @@ -1156,6 +1166,7 @@ void CPUParticles::convert_from_particles(Node *p_particles) { if (material.is_null()) return; + set_direction(material->get_direction()); set_spread(material->get_spread()); set_flatness(material->get_flatness()); @@ -1257,6 +1268,9 @@ void CPUParticles::_bind_methods() { //////////////////////////////// + ClassDB::bind_method(D_METHOD("set_direction", "direction"), &CPUParticles::set_direction); + ClassDB::bind_method(D_METHOD("get_direction"), &CPUParticles::get_direction); + ClassDB::bind_method(D_METHOD("set_spread", "degrees"), &CPUParticles::set_spread); ClassDB::bind_method(D_METHOD("get_spread"), &CPUParticles::get_spread); @@ -1317,7 +1331,8 @@ void CPUParticles::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_align_y"), "set_particle_flag", "get_particle_flag", FLAG_ALIGN_Y_TO_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_rotate_y"), "set_particle_flag", "get_particle_flag", FLAG_ROTATE_Y); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_disable_z"), "set_particle_flag", "get_particle_flag", FLAG_DISABLE_Z); - ADD_GROUP("Spread", ""); + ADD_GROUP("Direction", ""); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "direction"), "set_direction", "get_direction"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "flatness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_flatness", "get_flatness"); ADD_GROUP("Gravity", ""); @@ -1424,6 +1439,7 @@ CPUParticles::CPUParticles() { set_draw_order(DRAW_ORDER_INDEX); set_speed_scale(1); + set_direction(Vector3(1, 0, 0)); set_spread(45); set_flatness(0); set_param(PARAM_INITIAL_LINEAR_VELOCITY, 1); diff --git a/scene/3d/cpu_particles.h b/scene/3d/cpu_particles.h index b50befe7bec..05a9d7abe83 100644 --- a/scene/3d/cpu_particles.h +++ b/scene/3d/cpu_particles.h @@ -149,6 +149,7 @@ private: //////// + Vector3 direction; float spread; float flatness; @@ -226,6 +227,9 @@ public: /////////////////// + void set_direction(Vector3 p_direction); + Vector3 get_direction() const; + void set_spread(float p_spread); float get_spread() const; diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index ef67e6ea809..4ce9da824ea 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -45,6 +45,7 @@ void ParticlesMaterial::init_shaders() { shader_names = memnew(ShaderNames); + shader_names->direction = "direction"; shader_names->spread = "spread"; shader_names->flatness = "flatness"; shader_names->initial_linear_velocity = "initial_linear_velocity"; @@ -144,6 +145,7 @@ void ParticlesMaterial::_update_shader() { String code = "shader_type particles;\n"; + code += "uniform vec3 direction;\n"; code += "uniform float spread;\n"; code += "uniform float flatness;\n"; code += "uniform float initial_linear_velocity;\n"; @@ -303,20 +305,20 @@ void ParticlesMaterial::_update_shader() { if (flags[FLAG_DISABLE_Z]) { - code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; + code += " float angle1_rad = atan(direction.y, direction.x) + rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; code += " vec3 rot = vec3(cos(angle1_rad), sin(angle1_rad), 0.0);\n"; code += " VELOCITY = rot * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n"; } else { //initiate velocity spread in 3D - code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; - code += " float angle2_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);\n"; + code += " float angle1_rad = atan(direction.x, direction.z) + rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; + code += " float angle2_rad = atan(direction.y, abs(direction.z)) + rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);\n"; code += " vec3 direction_xz = vec3(sin(angle1_rad), 0.0, cos(angle1_rad));\n"; code += " vec3 direction_yz = vec3(0.0, sin(angle2_rad), cos(angle2_rad));\n"; code += " direction_yz.z = direction_yz.z / max(0.0001,sqrt(abs(direction_yz.z))); // better uniform distribution\n"; - code += " vec3 direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);\n"; - code += " direction = normalize(direction);\n"; - code += " VELOCITY = direction * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n"; + code += " vec3 vec_direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);\n"; + code += " vec_direction = normalize(vec_direction);\n"; + code += " VELOCITY = vec_direction * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n"; } code += " float base_angle = (initial_angle + tex_angle) * mix(1.0, angle_rand, initial_angle_random);\n"; @@ -626,6 +628,17 @@ bool ParticlesMaterial::_is_shader_dirty() const { return dirty; } +void ParticlesMaterial::set_direction(Vector3 p_direction) { + + direction = p_direction; + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->direction, direction); +} + +Vector3 ParticlesMaterial::get_direction() const { + + return direction; +} + void ParticlesMaterial::set_spread(float p_spread) { spread = p_spread; @@ -1041,6 +1054,9 @@ Shader::Mode ParticlesMaterial::get_shader_mode() const { void ParticlesMaterial::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_direction", "degrees"), &ParticlesMaterial::set_direction); + ClassDB::bind_method(D_METHOD("get_direction"), &ParticlesMaterial::get_direction); + ClassDB::bind_method(D_METHOD("set_spread", "degrees"), &ParticlesMaterial::set_spread); ClassDB::bind_method(D_METHOD("get_spread"), &ParticlesMaterial::get_spread); @@ -1114,7 +1130,8 @@ void ParticlesMaterial::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_align_y"), "set_flag", "get_flag", FLAG_ALIGN_Y_TO_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_rotate_y"), "set_flag", "get_flag", FLAG_ROTATE_Y); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_disable_z"), "set_flag", "get_flag", FLAG_DISABLE_Z); - ADD_GROUP("Spread", ""); + ADD_GROUP("Direction", ""); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "direction"), "set_direction", "get_direction"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "flatness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_flatness", "get_flatness"); ADD_GROUP("Gravity", ""); @@ -1198,6 +1215,7 @@ void ParticlesMaterial::_bind_methods() { ParticlesMaterial::ParticlesMaterial() : element(this) { + set_direction(Vector3(1, 0, 0)); set_spread(45); set_flatness(0); set_param(PARAM_INITIAL_LINEAR_VELOCITY, 0); diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h index 8b3248a9cb2..457a1c50bde 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particles_material.h @@ -129,6 +129,7 @@ private: static SelfList::List *dirty_materials; struct ShaderNames { + StringName direction; StringName spread; StringName flatness; StringName initial_linear_velocity; @@ -194,6 +195,7 @@ private: _FORCE_INLINE_ void _queue_shader_change(); _FORCE_INLINE_ bool _is_shader_dirty() const; + Vector3 direction; float spread; float flatness; @@ -230,6 +232,9 @@ protected: virtual void _validate_property(PropertyInfo &property) const; public: + void set_direction(Vector3 p_direction); + Vector3 get_direction() const; + void set_spread(float p_spread); float get_spread() const;