diff options
author | RĂ©mi Verschelde <remi@verschelde.fr> | 2022-01-24 22:19:55 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-24 22:19:55 +0100 |
commit | 672363f295495478ef7d03ea00878b8ebfbdb430 (patch) | |
tree | 4b3af3d94acba094ab2ac4b3480cf958b58a78c2 | |
parent | 33960b3b87f663923bc7d29a8cfaed77060e1056 (diff) | |
parent | 6f882945280ddc90a2de4000c1917375af6376e7 (diff) |
Merge pull request #56888 from FreegleBarr/implement_gpuparticle_subemitters2d
-rw-r--r-- | doc/classes/GPUParticles2D.xml | 29 | ||||
-rw-r--r-- | doc/classes/GPUParticles3D.xml | 6 | ||||
-rw-r--r-- | scene/2d/gpu_particles_2d.cpp | 58 | ||||
-rw-r--r-- | scene/2d/gpu_particles_2d.h | 16 |
4 files changed, 109 insertions, 0 deletions
diff --git a/doc/classes/GPUParticles2D.xml b/doc/classes/GPUParticles2D.xml index 72adc49742..f97198658e 100644 --- a/doc/classes/GPUParticles2D.xml +++ b/doc/classes/GPUParticles2D.xml @@ -18,6 +18,17 @@ Returns a rectangle containing the positions of all existing particles. </description> </method> + <method name="emit_particle"> + <return type="void" /> + <argument index="0" name="xform" type="Transform2D" /> + <argument index="1" name="velocity" type="Vector2" /> + <argument index="2" name="color" type="Color" /> + <argument index="3" name="custom" type="Color" /> + <argument index="4" name="flags" type="int" /> + <description> + Emits a single particle. Whether [code]xform[/code], [code]velocity[/code], [code]color[/code] and [code]custom[/code] are applied depends on the value of [code]flags[/code]. See [enum EmitFlags]. + </description> + </method> <method name="restart"> <return type="void" /> <description> @@ -67,6 +78,9 @@ <member name="speed_scale" type="float" setter="set_speed_scale" getter="get_speed_scale" default="1.0"> Particle system's running speed scaling ratio. A value of [code]0[/code] can be used to pause the particles. </member> + <member name="sub_emitter" type="NodePath" setter="set_sub_emitter" getter="get_sub_emitter" default="NodePath("")"> + The [NodePath] to the [GPUParticles2D] used for sub-emissions. + </member> <member name="texture" type="Texture2D" setter="set_texture" getter="get_texture"> Particle texture. If [code]null[/code], particles will be squares. </member> @@ -92,5 +106,20 @@ </constant> <constant name="DRAW_ORDER_REVERSE_LIFETIME" value="2" enum="DrawOrder"> </constant> + <constant name="EMIT_FLAG_POSITION" value="1" enum="EmitFlags"> + Particle starts at the specified position. + </constant> + <constant name="EMIT_FLAG_ROTATION_SCALE" value="2" enum="EmitFlags"> + Particle starts with specified rotation and scale. + </constant> + <constant name="EMIT_FLAG_VELOCITY" value="4" enum="EmitFlags"> + Particle starts with the specified velocity vector, which defines the emission direction and speed. + </constant> + <constant name="EMIT_FLAG_COLOR" value="8" enum="EmitFlags"> + Particle starts with specified color. + </constant> + <constant name="EMIT_FLAG_CUSTOM" value="16" enum="EmitFlags"> + Particle starts with specificed [code]CUSTOM[/code] data. + </constant> </constants> </class> diff --git a/doc/classes/GPUParticles3D.xml b/doc/classes/GPUParticles3D.xml index 771056cb93..62ac846077 100644 --- a/doc/classes/GPUParticles3D.xml +++ b/doc/classes/GPUParticles3D.xml @@ -26,6 +26,7 @@ <argument index="3" name="custom" type="Color" /> <argument index="4" name="flags" type="int" /> <description> + Emits a single particle. Whether [code]xform[/code], [code]velocity[/code], [code]color[/code] and [code]custom[/code] are applied depends on the value of [code]flags[/code]. See [enum EmitFlags]. </description> </method> <method name="get_draw_pass_mesh" qualifiers="const"> @@ -137,14 +138,19 @@ Particles are drawn in order of depth. </constant> <constant name="EMIT_FLAG_POSITION" value="1" enum="EmitFlags"> + Particle starts at the specified position. </constant> <constant name="EMIT_FLAG_ROTATION_SCALE" value="2" enum="EmitFlags"> + Particle starts with specified rotation and scale. </constant> <constant name="EMIT_FLAG_VELOCITY" value="4" enum="EmitFlags"> + Particle starts with the specified velocity vector, which defines the emission direction and speed. </constant> <constant name="EMIT_FLAG_COLOR" value="8" enum="EmitFlags"> + Particle starts with specified color. </constant> <constant name="EMIT_FLAG_CUSTOM" value="16" enum="EmitFlags"> + Particle starts with specificed [code]CUSTOM[/code] data. </constant> <constant name="MAX_DRAW_PASSES" value="4"> Maximum number of draw passes supported. diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp index b6d1e5c934..11c036ac9c 100644 --- a/scene/2d/gpu_particles_2d.cpp +++ b/scene/2d/gpu_particles_2d.cpp @@ -335,6 +335,42 @@ Ref<Texture2D> GPUParticles2D::get_texture() const { void GPUParticles2D::_validate_property(PropertyInfo &property) const { } +void GPUParticles2D::emit_particle(const Transform2D &p_transform2d, const Vector2 &p_velocity2d, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) { + Transform3D transform; + transform.basis.set_axis(0, Vector3(p_transform2d.get_axis(0).x, p_transform2d.get_axis(0).y, 0)); + transform.basis.set_axis(1, Vector3(p_transform2d.get_axis(1).x, p_transform2d.get_axis(1).y, 0)); + transform.set_origin(Vector3(p_transform2d.get_origin().x, p_transform2d.get_origin().y, 0)); + Vector3 velocity = Vector3(p_velocity2d.x, p_velocity2d.y, 0); + + RS::get_singleton()->particles_emit(particles, transform, velocity, p_color, p_custom, p_emit_flags); +} + +void GPUParticles2D::_attach_sub_emitter() { + Node *n = get_node_or_null(sub_emitter); + if (n) { + GPUParticles2D *sen = Object::cast_to<GPUParticles2D>(n); + if (sen && sen != this) { + RS::get_singleton()->particles_set_subemitter(particles, sen->particles); + } + } +} + +void GPUParticles2D::set_sub_emitter(const NodePath &p_path) { + if (is_inside_tree()) { + RS::get_singleton()->particles_set_subemitter(particles, RID()); + } + + sub_emitter = p_path; + + if (is_inside_tree() && sub_emitter != NodePath()) { + _attach_sub_emitter(); + } +} + +NodePath GPUParticles2D::get_sub_emitter() const { + return sub_emitter; +} + void GPUParticles2D::restart() { RS::get_singleton()->particles_restart(particles); RS::get_singleton()->particles_set_emitting(particles, true); @@ -462,6 +498,16 @@ void GPUParticles2D::_notification(int p_what) { #endif } + if (p_what == NOTIFICATION_ENTER_TREE) { + if (sub_emitter != NodePath()) { + _attach_sub_emitter(); + } + } + + if (p_what == NOTIFICATION_EXIT_TREE) { + RS::get_singleton()->particles_set_subemitter(particles, RID()); + } + if (p_what == NOTIFICATION_PAUSED || p_what == NOTIFICATION_UNPAUSED) { if (can_process()) { RS::get_singleton()->particles_set_speed_scale(particles, speed_scale); @@ -523,6 +569,11 @@ void GPUParticles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("restart"), &GPUParticles2D::restart); + ClassDB::bind_method(D_METHOD("set_sub_emitter", "path"), &GPUParticles2D::set_sub_emitter); + ClassDB::bind_method(D_METHOD("get_sub_emitter"), &GPUParticles2D::get_sub_emitter); + + ClassDB::bind_method(D_METHOD("emit_particle", "xform", "velocity", "color", "custom", "flags"), &GPUParticles2D::emit_particle); + ClassDB::bind_method(D_METHOD("set_trail_enabled", "enabled"), &GPUParticles2D::set_trail_enabled); ClassDB::bind_method(D_METHOD("set_trail_length", "secs"), &GPUParticles2D::set_trail_length); @@ -538,6 +589,7 @@ void GPUParticles2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting"); ADD_PROPERTY_DEFAULT("emitting", true); // Workaround for doctool in headless mode, as dummy rasterizer always returns false. ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_RANGE, "1,1000000,1,exp"), "set_amount", "get_amount"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "sub_emitter", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "GPUParticles2D"), "set_sub_emitter", "get_sub_emitter"); ADD_GROUP("Time", ""); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime", PROPERTY_HINT_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "get_one_shot"); @@ -566,6 +618,12 @@ void GPUParticles2D::_bind_methods() { BIND_ENUM_CONSTANT(DRAW_ORDER_INDEX); BIND_ENUM_CONSTANT(DRAW_ORDER_LIFETIME); BIND_ENUM_CONSTANT(DRAW_ORDER_REVERSE_LIFETIME); + + BIND_ENUM_CONSTANT(EMIT_FLAG_POSITION); + BIND_ENUM_CONSTANT(EMIT_FLAG_ROTATION_SCALE); + BIND_ENUM_CONSTANT(EMIT_FLAG_VELOCITY); + BIND_ENUM_CONSTANT(EMIT_FLAG_COLOR); + BIND_ENUM_CONSTANT(EMIT_FLAG_CUSTOM); } GPUParticles2D::GPUParticles2D() { diff --git a/scene/2d/gpu_particles_2d.h b/scene/2d/gpu_particles_2d.h index aa9a8da129..fc95ae27b2 100644 --- a/scene/2d/gpu_particles_2d.h +++ b/scene/2d/gpu_particles_2d.h @@ -79,6 +79,8 @@ private: RID mesh; + void _attach_sub_emitter(); + protected: static void _bind_methods(); virtual void _validate_property(PropertyInfo &property) const override; @@ -139,6 +141,19 @@ public: TypedArray<String> get_configuration_warnings() const override; + void set_sub_emitter(const NodePath &p_path); + NodePath get_sub_emitter() const; + + enum EmitFlags { + EMIT_FLAG_POSITION = RS::PARTICLES_EMIT_FLAG_POSITION, + EMIT_FLAG_ROTATION_SCALE = RS::PARTICLES_EMIT_FLAG_ROTATION_SCALE, + EMIT_FLAG_VELOCITY = RS::PARTICLES_EMIT_FLAG_VELOCITY, + EMIT_FLAG_COLOR = RS::PARTICLES_EMIT_FLAG_COLOR, + EMIT_FLAG_CUSTOM = RS::PARTICLES_EMIT_FLAG_CUSTOM + }; + + void emit_particle(const Transform2D &p_transform, const Vector2 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags); + void restart(); Rect2 capture_rect() const; GPUParticles2D(); @@ -146,5 +161,6 @@ public: }; VARIANT_ENUM_CAST(GPUParticles2D::DrawOrder) +VARIANT_ENUM_CAST(GPUParticles2D::EmitFlags) #endif // PARTICLES_2D_H |