diff options
Diffstat (limited to 'scene/resources/particles_material.cpp')
-rw-r--r-- | scene/resources/particles_material.cpp | 110 |
1 files changed, 69 insertions, 41 deletions
diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index 4b2e029f47..29a06622a3 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -287,7 +287,7 @@ void ParticlesMaterial::_update_shader() { code += "uniform sampler2D anim_offset_texture : repeat_disable;\n"; } - if (collision_enabled) { + if (collision_mode == COLLISION_RIGID) { code += "uniform float collision_friction;\n"; code += "uniform float collision_bounce;\n"; } @@ -695,8 +695,10 @@ void ParticlesMaterial::_update_shader() { } code += " vec3 noise_direction = get_noise_direction(TRANSFORM[3].xyz, EMISSION_TRANSFORM[3].xyz, time_noise);\n"; // If collision happened, turbulence is no longer applied. + // We don't need this check when the collision mode is "hide on contact", + // as the particle will be hidden anyway. String extra_tab = ""; - if (collision_enabled) { + if (collision_mode != COLLISION_RIGID) { code += " if (!COLLIDED) {\n"; extra_tab = " "; } @@ -704,7 +706,7 @@ void ParticlesMaterial::_update_shader() { code += extra_tab + " float vel_mag = length(VELOCITY);\n"; code += extra_tab + " float vel_infl = clamp(mix(turbulence_influence_min, turbulence_influence_max, rand_from_seed(alt_seed)) * turbulence_influence, 0.0, 1.0);\n"; code += extra_tab + " VELOCITY = mix(VELOCITY, normalize(noise_direction) * vel_mag * (1.0 + (1.0 - vel_infl) * 0.2), vel_infl);\n"; - if (collision_enabled) { + if (collision_mode != COLLISION_RIGID) { code += " }"; } } @@ -828,7 +830,7 @@ void ParticlesMaterial::_update_shader() { code += " TRANSFORM[3].z = 0.0;\n"; } - if (collision_enabled) { + if (collision_mode == COLLISION_RIGID) { code += " if (COLLIDED) {\n"; code += " if (length(VELOCITY) > 3.0) {\n"; code += " TRANSFORM[3].xyz += COLLISION_NORMAL * COLLISION_DEPTH;\n"; @@ -851,6 +853,18 @@ void ParticlesMaterial::_update_shader() { code += " TRANSFORM[1].xyz *= base_scale * sign(tex_scale.g) * max(abs(tex_scale.g), 0.001);\n"; code += " TRANSFORM[2].xyz *= base_scale * sign(tex_scale.b) * max(abs(tex_scale.b), 0.001);\n"; + if (collision_mode == COLLISION_RIGID) { + code += " if (COLLIDED) {\n"; + code += " TRANSFORM[3].xyz+=COLLISION_NORMAL * COLLISION_DEPTH;\n"; + code += " VELOCITY -= COLLISION_NORMAL * dot(COLLISION_NORMAL, VELOCITY) * (1.0 + collision_bounce);\n"; + code += " VELOCITY = mix(VELOCITY,vec3(0.0),collision_friction * DELTA * 100.0);\n"; + code += " }\n"; + } else if (collision_mode == COLLISION_HIDE_ON_CONTACT) { + code += " if (COLLIDED) {\n"; + code += " ACTIVE = false;\n"; + code += " }\n"; + } + if (sub_emitter_mode != SUB_EMITTER_DISABLED) { code += " int emit_count = 0;\n"; switch (sub_emitter_mode) { @@ -1386,56 +1400,64 @@ RID ParticlesMaterial::get_shader_rid() const { return shader_map[current_key].shader; } -void ParticlesMaterial::_validate_property(PropertyInfo &property) const { - if (property.name == "emission_sphere_radius" && (emission_shape != EMISSION_SHAPE_SPHERE && emission_shape != EMISSION_SHAPE_SPHERE_SURFACE)) { - property.usage = PROPERTY_USAGE_NONE; +void ParticlesMaterial::_validate_property(PropertyInfo &p_property) const { + if (p_property.name == "emission_sphere_radius" && (emission_shape != EMISSION_SHAPE_SPHERE && emission_shape != EMISSION_SHAPE_SPHERE_SURFACE)) { + p_property.usage = PROPERTY_USAGE_NONE; } - if (property.name == "emission_box_extents" && emission_shape != EMISSION_SHAPE_BOX) { - property.usage = PROPERTY_USAGE_NONE; + if (p_property.name == "emission_box_extents" && emission_shape != EMISSION_SHAPE_BOX) { + p_property.usage = PROPERTY_USAGE_NONE; } - if ((property.name == "emission_point_texture" || property.name == "emission_color_texture") && (emission_shape != EMISSION_SHAPE_POINTS && emission_shape != EMISSION_SHAPE_DIRECTED_POINTS)) { - property.usage = PROPERTY_USAGE_NONE; + if ((p_property.name == "emission_point_texture" || p_property.name == "emission_color_texture") && (emission_shape != EMISSION_SHAPE_POINTS && emission_shape != EMISSION_SHAPE_DIRECTED_POINTS)) { + p_property.usage = PROPERTY_USAGE_NONE; } - if (property.name == "emission_normal_texture" && emission_shape != EMISSION_SHAPE_DIRECTED_POINTS) { - property.usage = PROPERTY_USAGE_NONE; + if (p_property.name == "emission_normal_texture" && emission_shape != EMISSION_SHAPE_DIRECTED_POINTS) { + p_property.usage = PROPERTY_USAGE_NONE; } - if (property.name == "emission_point_count" && (emission_shape != EMISSION_SHAPE_POINTS && emission_shape != EMISSION_SHAPE_DIRECTED_POINTS)) { - property.usage = PROPERTY_USAGE_NONE; + if (p_property.name == "emission_point_count" && (emission_shape != EMISSION_SHAPE_POINTS && emission_shape != EMISSION_SHAPE_DIRECTED_POINTS)) { + p_property.usage = PROPERTY_USAGE_NONE; } - if (property.name.begins_with("emission_ring_") && emission_shape != EMISSION_SHAPE_RING) { - property.usage = PROPERTY_USAGE_NONE; + if (p_property.name.begins_with("emission_ring_") && emission_shape != EMISSION_SHAPE_RING) { + p_property.usage = PROPERTY_USAGE_NONE; } - if (property.name == "sub_emitter_frequency" && sub_emitter_mode != SUB_EMITTER_CONSTANT) { - property.usage = PROPERTY_USAGE_NONE; + if (p_property.name == "sub_emitter_frequency" && sub_emitter_mode != SUB_EMITTER_CONSTANT) { + p_property.usage = PROPERTY_USAGE_NONE; } - if (property.name == "sub_emitter_amount_at_end" && sub_emitter_mode != SUB_EMITTER_AT_END) { - property.usage = PROPERTY_USAGE_NONE; + if (p_property.name == "sub_emitter_amount_at_end" && sub_emitter_mode != SUB_EMITTER_AT_END) { + p_property.usage = PROPERTY_USAGE_NONE; } - if (property.name.begins_with("orbit_") && !particle_flags[PARTICLE_FLAG_DISABLE_Z]) { - property.usage = PROPERTY_USAGE_NONE; + if (p_property.name.begins_with("orbit_") && !particle_flags[PARTICLE_FLAG_DISABLE_Z]) { + p_property.usage = PROPERTY_USAGE_NONE; } if (!turbulence_enabled) { - if (property.name == "turbulence_noise_strength" || - property.name == "turbulence_noise_scale" || - property.name == "turbulence_noise_speed" || - property.name == "turbulence_noise_speed_random" || - property.name == "turbulence_influence_over_life" || - property.name == "turbulence_influence_min" || - property.name == "turbulence_influence_max" || - property.name == "turbulence_initial_displacement_min" || - property.name == "turbulence_initial_displacement_max") { - property.usage = PROPERTY_USAGE_NO_EDITOR; + if (p_property.name == "turbulence_noise_strength" || + p_property.name == "turbulence_noise_scale" || + p_property.name == "turbulence_noise_speed" || + p_property.name == "turbulence_noise_speed_random" || + p_property.name == "turbulence_influence_over_life" || + p_property.name == "turbulence_influence_min" || + p_property.name == "turbulence_influence_max" || + p_property.name == "turbulence_initial_displacement_min" || + p_property.name == "turbulence_initial_displacement_max") { + p_property.usage = PROPERTY_USAGE_NO_EDITOR; } } + + if (p_property.name == "collision_friction" && collision_mode != COLLISION_RIGID) { + p_property.usage = PROPERTY_USAGE_NONE; + } + + if (p_property.name == "collision_bounce" && collision_mode != COLLISION_RIGID) { + p_property.usage = PROPERTY_USAGE_NONE; + } } void ParticlesMaterial::set_sub_emitter_mode(SubEmitterMode p_sub_emitter_mode) { @@ -1483,13 +1505,14 @@ bool ParticlesMaterial::is_attractor_interaction_enabled() const { return attractor_interaction_enabled; } -void ParticlesMaterial::set_collision_enabled(bool p_enabled) { - collision_enabled = p_enabled; +void ParticlesMaterial::set_collision_mode(CollisionMode p_collision_mode) { + collision_mode = p_collision_mode; _queue_shader_change(); + notify_property_list_changed(); } -bool ParticlesMaterial::is_collision_enabled() const { - return collision_enabled; +ParticlesMaterial::CollisionMode ParticlesMaterial::get_collision_mode() const { + return collision_mode; } void ParticlesMaterial::set_collision_use_scale(bool p_scale) { @@ -1623,8 +1646,8 @@ void ParticlesMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_attractor_interaction_enabled", "enabled"), &ParticlesMaterial::set_attractor_interaction_enabled); ClassDB::bind_method(D_METHOD("is_attractor_interaction_enabled"), &ParticlesMaterial::is_attractor_interaction_enabled); - ClassDB::bind_method(D_METHOD("set_collision_enabled", "enabled"), &ParticlesMaterial::set_collision_enabled); - ClassDB::bind_method(D_METHOD("is_collision_enabled"), &ParticlesMaterial::is_collision_enabled); + ClassDB::bind_method(D_METHOD("set_collision_mode", "mode"), &ParticlesMaterial::set_collision_mode); + ClassDB::bind_method(D_METHOD("get_collision_mode"), &ParticlesMaterial::get_collision_mode); ClassDB::bind_method(D_METHOD("set_collision_use_scale", "radius"), &ParticlesMaterial::set_collision_use_scale); ClassDB::bind_method(D_METHOD("is_collision_using_scale"), &ParticlesMaterial::is_collision_using_scale); @@ -1734,7 +1757,7 @@ void ParticlesMaterial::_bind_methods() { ADD_GROUP("Attractor Interaction", "attractor_interaction_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "attractor_interaction_enabled"), "set_attractor_interaction_enabled", "is_attractor_interaction_enabled"); ADD_GROUP("Collision", "collision_"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision_enabled"), "set_collision_enabled", "is_collision_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mode", PROPERTY_HINT_ENUM, "Disabled,Rigid,Hide On Contact"), "set_collision_mode", "get_collision_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_collision_friction", "get_collision_friction"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_collision_bounce", "get_collision_bounce"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision_use_scale"), "set_collision_use_scale", "is_collision_using_scale"); @@ -1776,6 +1799,11 @@ void ParticlesMaterial::_bind_methods() { BIND_ENUM_CONSTANT(SUB_EMITTER_AT_END); BIND_ENUM_CONSTANT(SUB_EMITTER_AT_COLLISION); BIND_ENUM_CONSTANT(SUB_EMITTER_MAX); + + BIND_ENUM_CONSTANT(COLLISION_DISABLED); + BIND_ENUM_CONSTANT(COLLISION_RIGID); + BIND_ENUM_CONSTANT(COLLISION_HIDE_ON_CONTACT); + BIND_ENUM_CONSTANT(COLLISION_MAX); } ParticlesMaterial::ParticlesMaterial() : @@ -1834,7 +1862,7 @@ ParticlesMaterial::ParticlesMaterial() : set_sub_emitter_keep_velocity(false); set_attractor_interaction_enabled(true); - set_collision_enabled(false); + set_collision_mode(COLLISION_DISABLED); set_collision_bounce(0.0); set_collision_friction(0.0); set_collision_use_scale(false); |