summaryrefslogtreecommitdiff
path: root/scene/resources/particles_material.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources/particles_material.cpp')
-rw-r--r--scene/resources/particles_material.cpp110
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);