Skip to content

Commit 1e1f54e

Browse files
committed
Merge pull request godotengine#100050 from YeldhamDev/sub_emitter_at_start
Add "At Start" mode for sub-emitter particles
2 parents a69ccee + eb5839d commit 1e1f54e

File tree

3 files changed

+47
-3
lines changed

3 files changed

+47
-3
lines changed

doc/classes/ParticleProcessMaterial.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,10 @@
346346
The amount of particles to spawn from the subemitter node when the particle expires.
347347
[b]Note:[/b] This value shouldn't exceed [member GPUParticles2D.amount] or [member GPUParticles3D.amount] defined on the [i]subemitter node[/i] (not the main node), relative to the subemitter's particle lifetime. If the number of particles is exceeded, no new particles will spawn from the subemitter until enough particles have expired.
348348
</member>
349+
<member name="sub_emitter_amount_at_start" type="int" setter="set_sub_emitter_amount_at_start" getter="get_sub_emitter_amount_at_start">
350+
The amount of particles to spawn from the subemitter node when the particle spawns.
351+
[b]Note:[/b] This value shouldn't exceed [member GPUParticles2D.amount] or [member GPUParticles3D.amount] defined on the [i]subemitter node[/i] (not the main node), relative to the subemitter's particle lifetime. If the number of particles is exceeded, no new particles will spawn from the subemitter until enough particles have expired.
352+
</member>
349353
<member name="sub_emitter_frequency" type="float" setter="set_sub_emitter_frequency" getter="get_sub_emitter_frequency">
350354
The frequency at which particles should be emitted from the subemitter node. One particle will be spawned every [member sub_emitter_frequency] seconds.
351355
[b]Note:[/b] This value shouldn't exceed [member GPUParticles2D.amount] or [member GPUParticles3D.amount] defined on the [i]subemitter node[/i] (not the main node), relative to the subemitter's particle lifetime. If the number of particles is exceeded, no new particles will spawn from the subemitter until enough particles have expired.
@@ -521,7 +525,9 @@
521525
</constant>
522526
<constant name="SUB_EMITTER_AT_COLLISION" value="3" enum="SubEmitterMode">
523527
</constant>
524-
<constant name="SUB_EMITTER_MAX" value="4" enum="SubEmitterMode">
528+
<constant name="SUB_EMITTER_AT_START" value="4" enum="SubEmitterMode">
529+
</constant>
530+
<constant name="SUB_EMITTER_MAX" value="5" enum="SubEmitterMode">
525531
Represents the size of the [enum SubEmitterMode] enum.
526532
</constant>
527533
<constant name="COLLISION_DISABLED" value="0" enum="CollisionMode">

scene/resources/particle_process_material.cpp

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ void ParticleProcessMaterial::init_shaders() {
132132
shader_names->sub_emitter_frequency = "sub_emitter_frequency";
133133
shader_names->sub_emitter_amount_at_end = "sub_emitter_amount_at_end";
134134
shader_names->sub_emitter_amount_at_collision = "sub_emitter_amount_at_collision";
135+
shader_names->sub_emitter_amount_at_start = "sub_emitter_amount_at_start";
135136
shader_names->sub_emitter_keep_velocity = "sub_emitter_keep_velocity";
136137

137138
shader_names->collision_friction = "collision_friction";
@@ -287,6 +288,9 @@ void ParticleProcessMaterial::_update_shader() {
287288
if (sub_emitter_mode == SUB_EMITTER_AT_COLLISION) {
288289
code += "uniform int sub_emitter_amount_at_collision;\n";
289290
}
291+
if (sub_emitter_mode == SUB_EMITTER_AT_START) {
292+
code += "uniform int sub_emitter_amount_at_start;\n";
293+
}
290294
code += "uniform bool sub_emitter_keep_velocity;\n";
291295
}
292296

@@ -923,6 +927,10 @@ void ParticleProcessMaterial::_update_shader() {
923927
code += " float pi = 3.14159;\n";
924928
code += " float degree_to_rad = pi / 180.0;\n\n";
925929

930+
if (sub_emitter_mode == SUB_EMITTER_AT_START && !RenderingServer::get_singleton()->is_low_end()) {
931+
code += " bool just_spawned = CUSTOM.y == 0.0;\n";
932+
}
933+
926934
code += " CUSTOM.y += DELTA / LIFETIME;\n";
927935
code += " CUSTOM.y = mix(CUSTOM.y, 1.0, INTERPOLATE_TO_END);\n";
928936
code += " float lifetime_percent = CUSTOM.y / params.lifetime;\n";
@@ -1139,6 +1147,11 @@ void ParticleProcessMaterial::_update_shader() {
11391147
code += " emit_count = sub_emitter_amount_at_end;\n";
11401148
code += " }\n";
11411149
} break;
1150+
case SUB_EMITTER_AT_START: {
1151+
code += " if (just_spawned) {\n";
1152+
code += " emit_count = sub_emitter_amount_at_start;\n";
1153+
code += " }\n";
1154+
} break;
11421155
default: {
11431156
}
11441157
}
@@ -1858,6 +1871,10 @@ void ParticleProcessMaterial::_validate_property(PropertyInfo &p_property) const
18581871
p_property.usage = PROPERTY_USAGE_NONE;
18591872
}
18601873

1874+
if (p_property.name == "sub_emitter_amount_at_start" && sub_emitter_mode != SUB_EMITTER_AT_START) {
1875+
p_property.usage = PROPERTY_USAGE_NONE;
1876+
}
1877+
18611878
if (!turbulence_enabled) {
18621879
if (p_property.name == "turbulence_noise_strength" ||
18631880
p_property.name == "turbulence_noise_scale" ||
@@ -1932,6 +1949,15 @@ int ParticleProcessMaterial::get_sub_emitter_amount_at_collision() const {
19321949
return sub_emitter_amount_at_collision;
19331950
}
19341951

1952+
void ParticleProcessMaterial::set_sub_emitter_amount_at_start(int p_amount) {
1953+
sub_emitter_amount_at_start = p_amount;
1954+
RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->sub_emitter_amount_at_start, p_amount);
1955+
}
1956+
1957+
int ParticleProcessMaterial::get_sub_emitter_amount_at_start() const {
1958+
return sub_emitter_amount_at_start;
1959+
}
1960+
19351961
void ParticleProcessMaterial::set_sub_emitter_keep_velocity(bool p_enable) {
19361962
sub_emitter_keep_velocity = p_enable;
19371963
RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->sub_emitter_keep_velocity, p_enable);
@@ -2113,6 +2139,9 @@ void ParticleProcessMaterial::_bind_methods() {
21132139
ClassDB::bind_method(D_METHOD("get_sub_emitter_amount_at_collision"), &ParticleProcessMaterial::get_sub_emitter_amount_at_collision);
21142140
ClassDB::bind_method(D_METHOD("set_sub_emitter_amount_at_collision", "amount"), &ParticleProcessMaterial::set_sub_emitter_amount_at_collision);
21152141

2142+
ClassDB::bind_method(D_METHOD("get_sub_emitter_amount_at_start"), &ParticleProcessMaterial::get_sub_emitter_amount_at_start);
2143+
ClassDB::bind_method(D_METHOD("set_sub_emitter_amount_at_start", "amount"), &ParticleProcessMaterial::set_sub_emitter_amount_at_start);
2144+
21162145
ClassDB::bind_method(D_METHOD("get_sub_emitter_keep_velocity"), &ParticleProcessMaterial::get_sub_emitter_keep_velocity);
21172146
ClassDB::bind_method(D_METHOD("set_sub_emitter_keep_velocity", "enable"), &ParticleProcessMaterial::set_sub_emitter_keep_velocity);
21182147

@@ -2242,10 +2271,11 @@ void ParticleProcessMaterial::_bind_methods() {
22422271
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_collision_bounce", "get_collision_bounce");
22432272
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision_use_scale"), "set_collision_use_scale", "is_collision_using_scale");
22442273
ADD_GROUP("Sub Emitter", "sub_emitter_");
2245-
ADD_PROPERTY(PropertyInfo(Variant::INT, "sub_emitter_mode", PROPERTY_HINT_ENUM, "Disabled,Constant,At End,At Collision"), "set_sub_emitter_mode", "get_sub_emitter_mode");
2274+
ADD_PROPERTY(PropertyInfo(Variant::INT, "sub_emitter_mode", PROPERTY_HINT_ENUM, "Disabled:0,Constant:1,At Start:4,At End:2,At Collision:3"), "set_sub_emitter_mode", "get_sub_emitter_mode");
22462275
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sub_emitter_frequency", PROPERTY_HINT_RANGE, "0.01,100,0.01,suffix:Hz"), "set_sub_emitter_frequency", "get_sub_emitter_frequency");
22472276
ADD_PROPERTY(PropertyInfo(Variant::INT, "sub_emitter_amount_at_end", PROPERTY_HINT_RANGE, "1,32,1"), "set_sub_emitter_amount_at_end", "get_sub_emitter_amount_at_end");
22482277
ADD_PROPERTY(PropertyInfo(Variant::INT, "sub_emitter_amount_at_collision", PROPERTY_HINT_RANGE, "1,32,1"), "set_sub_emitter_amount_at_collision", "get_sub_emitter_amount_at_collision");
2278+
ADD_PROPERTY(PropertyInfo(Variant::INT, "sub_emitter_amount_at_start", PROPERTY_HINT_RANGE, "1,32,1"), "set_sub_emitter_amount_at_start", "get_sub_emitter_amount_at_start");
22492279
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sub_emitter_keep_velocity"), "set_sub_emitter_keep_velocity", "get_sub_emitter_keep_velocity");
22502280

22512281
ADD_SIGNAL(MethodInfo("emission_shape_changed"));
@@ -2290,6 +2320,7 @@ void ParticleProcessMaterial::_bind_methods() {
22902320
BIND_ENUM_CONSTANT(SUB_EMITTER_CONSTANT);
22912321
BIND_ENUM_CONSTANT(SUB_EMITTER_AT_END);
22922322
BIND_ENUM_CONSTANT(SUB_EMITTER_AT_COLLISION);
2323+
BIND_ENUM_CONSTANT(SUB_EMITTER_AT_START);
22932324
BIND_ENUM_CONSTANT(SUB_EMITTER_MAX);
22942325

22952326
BIND_ENUM_CONSTANT(COLLISION_DISABLED);
@@ -2361,6 +2392,7 @@ ParticleProcessMaterial::ParticleProcessMaterial() :
23612392
set_sub_emitter_frequency(4);
23622393
set_sub_emitter_amount_at_end(1);
23632394
set_sub_emitter_amount_at_collision(1);
2395+
set_sub_emitter_amount_at_start(1);
23642396
set_sub_emitter_keep_velocity(false);
23652397

23662398
set_attractor_interaction_enabled(true);

scene/resources/particle_process_material.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ class ParticleProcessMaterial : public Material {
9696
SUB_EMITTER_CONSTANT,
9797
SUB_EMITTER_AT_END,
9898
SUB_EMITTER_AT_COLLISION,
99+
SUB_EMITTER_AT_START,
99100
SUB_EMITTER_MAX
100101
};
101102

@@ -117,7 +118,7 @@ class ParticleProcessMaterial : public Material {
117118
uint64_t emission_shape : 3;
118119
uint64_t invalid_key : 1;
119120
uint64_t has_emission_color : 1;
120-
uint64_t sub_emitter : 2;
121+
uint64_t sub_emitter : 3;
121122
uint64_t attractor_enabled : 1;
122123
uint64_t collision_mode : 2;
123124
uint64_t collision_scale : 1;
@@ -282,6 +283,7 @@ class ParticleProcessMaterial : public Material {
282283
StringName sub_emitter_frequency;
283284
StringName sub_emitter_amount_at_end;
284285
StringName sub_emitter_amount_at_collision;
286+
StringName sub_emitter_amount_at_start;
285287
StringName sub_emitter_keep_velocity;
286288

287289
StringName collision_friction;
@@ -349,6 +351,7 @@ class ParticleProcessMaterial : public Material {
349351
double sub_emitter_frequency = 0.0;
350352
int sub_emitter_amount_at_end = 0;
351353
int sub_emitter_amount_at_collision = 0;
354+
int sub_emitter_amount_at_start = 0;
352355
bool sub_emitter_keep_velocity = false;
353356
//do not save emission points here
354357

@@ -487,6 +490,9 @@ class ParticleProcessMaterial : public Material {
487490
void set_sub_emitter_amount_at_collision(int p_amount);
488491
int get_sub_emitter_amount_at_collision() const;
489492

493+
void set_sub_emitter_amount_at_start(int p_amount);
494+
int get_sub_emitter_amount_at_start() const;
495+
490496
void set_sub_emitter_keep_velocity(bool p_enable);
491497
bool get_sub_emitter_keep_velocity() const;
492498

0 commit comments

Comments
 (0)