From 4dfc93240c3055c44e2baa83c4b7c3a434bdbc1e Mon Sep 17 00:00:00 2001 From: Thaumaturge Date: Fri, 1 Nov 2019 21:18:32 +0200 Subject: [PATCH 1/6] Changes intended to allow for an offset start to a particle system's generation--without the addition of a new field, this time. And, as before, exposure of a method by which to read the "_tics_since_birth" variable. --- direct/src/particles/ParticleEffect.py | 4 ++-- panda/src/particlesystem/particleSystem.I | 12 ++++++++++-- panda/src/particlesystem/particleSystem.h | 3 ++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/direct/src/particles/ParticleEffect.py b/direct/src/particles/ParticleEffect.py index f801432b7e3..e7449b00f11 100644 --- a/direct/src/particles/ParticleEffect.py +++ b/direct/src/particles/ParticleEffect.py @@ -220,10 +220,10 @@ def softStop(self): for particles in self.getParticlesList(): particles.softStop() - def softStart(self): + def softStart(self, firstBirthOffset = 0): if self.__isValid(): for particles in self.getParticlesList(): - particles.softStart() + particles.softStart(boff = firstBirthOffset) else: # Not asserting here since we want to crash live clients for more expedient bugfix # (Sorry, live clients) diff --git a/panda/src/particlesystem/particleSystem.I b/panda/src/particlesystem/particleSystem.I index a96083f7e22..1ff9f8c30e8 100644 --- a/panda/src/particlesystem/particleSystem.I +++ b/panda/src/particlesystem/particleSystem.I @@ -51,11 +51,11 @@ clear_to_initial() { * Causes system to use birth rate set by set_birth_rate() */ INLINE void ParticleSystem:: -soft_start(PN_stdfloat br) { +soft_start(PN_stdfloat br, PN_stdfloat boff) { if (br > 0.0) set_birth_rate(br); _cur_birth_rate = _birth_rate; - _tics_since_birth = 0.0f; + _tics_since_birth = boff; } /** @@ -342,6 +342,14 @@ get_floor_z() const { return _floor_z; } +/** + +*/ +INLINE PN_stdfloat ParticleSystem:: +get_tics_since_birth() const { + return _tics_since_birth; +} + /** */ diff --git a/panda/src/particlesystem/particleSystem.h b/panda/src/particlesystem/particleSystem.h index 1e5bfdaac8c..c5fcaf88811 100644 --- a/panda/src/particlesystem/particleSystem.h +++ b/panda/src/particlesystem/particleSystem.h @@ -83,6 +83,7 @@ class EXPCL_PANDA_PARTICLESYSTEM ParticleSystem : public Physical { INLINE BaseParticleEmitter *get_emitter() const; INLINE BaseParticleFactory *get_factory() const; INLINE PN_stdfloat get_floor_z() const; + INLINE PN_stdfloat get_tics_since_birth() const; // particle template vector @@ -95,7 +96,7 @@ class EXPCL_PANDA_PARTICLESYSTEM ParticleSystem : public Physical { INLINE void induce_labor(); INLINE void clear_to_initial(); INLINE void soft_stop(PN_stdfloat br = 0.0); - INLINE void soft_start(PN_stdfloat br = 0.0); + INLINE void soft_start(PN_stdfloat br = 0.0, PN_stdfloat boff = 0.0); void update(PN_stdfloat dt); virtual void output(std::ostream &out) const; From 6e17959b394f44b566a51e57c4fe408f42e6a6ce Mon Sep 17 00:00:00 2001 From: Thaumaturge Date: Sat, 2 Nov 2019 02:51:38 +0200 Subject: [PATCH 2/6] Replacement of the altered version of "soft_start" with a new method that calls it internally, as well as logic to handle this in "ParticleEffect.py", I believe. --- direct/src/particles/ParticleEffect.py | 7 +++++-- panda/src/particlesystem/particleSystem.I | 11 ++++++++++- panda/src/particlesystem/particleSystem.h | 3 ++- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/direct/src/particles/ParticleEffect.py b/direct/src/particles/ParticleEffect.py index e7449b00f11..644cde133b8 100644 --- a/direct/src/particles/ParticleEffect.py +++ b/direct/src/particles/ParticleEffect.py @@ -220,10 +220,13 @@ def softStop(self): for particles in self.getParticlesList(): particles.softStop() - def softStart(self, firstBirthOffset = 0): + def softStart(self, firstBirthOffset = None): if self.__isValid(): for particles in self.getParticlesList(): - particles.softStart(boff = firstBirthOffset) + if firstBirthOffset is not None: + particles.softStartOffset(boff = firstBirthOffset) + else: + particles.softStart() else: # Not asserting here since we want to crash live clients for more expedient bugfix # (Sorry, live clients) diff --git a/panda/src/particlesystem/particleSystem.I b/panda/src/particlesystem/particleSystem.I index 1ff9f8c30e8..55ab395c817 100644 --- a/panda/src/particlesystem/particleSystem.I +++ b/panda/src/particlesystem/particleSystem.I @@ -51,10 +51,19 @@ clear_to_initial() { * Causes system to use birth rate set by set_birth_rate() */ INLINE void ParticleSystem:: -soft_start(PN_stdfloat br, PN_stdfloat boff) { +soft_start(PN_stdfloat br) { if (br > 0.0) set_birth_rate(br); _cur_birth_rate = _birth_rate; + _tics_since_birth = 0.0f; +} + +/** + * Causes system to use birth rate set by set_birth_rate() + */ +INLINE void ParticleSystem:: +soft_start_offset(PN_stdfloat br, PN_stdfloat boff) { + soft_start(br); _tics_since_birth = boff; } diff --git a/panda/src/particlesystem/particleSystem.h b/panda/src/particlesystem/particleSystem.h index c5fcaf88811..c1beff08876 100644 --- a/panda/src/particlesystem/particleSystem.h +++ b/panda/src/particlesystem/particleSystem.h @@ -96,7 +96,8 @@ class EXPCL_PANDA_PARTICLESYSTEM ParticleSystem : public Physical { INLINE void induce_labor(); INLINE void clear_to_initial(); INLINE void soft_stop(PN_stdfloat br = 0.0); - INLINE void soft_start(PN_stdfloat br = 0.0, PN_stdfloat boff = 0.0); + INLINE void soft_start(PN_stdfloat br = 0.0); + INLINE void soft_start_offset(PN_stdfloat br = 0.0, PN_stdfloat boff = 0.0); void update(PN_stdfloat dt); virtual void output(std::ostream &out) const; From 3cf6e42bdebc95e38fa8233ee4e056df77448414 Mon Sep 17 00:00:00 2001 From: Thaumaturge Date: Sat, 2 Nov 2019 22:22:36 +0200 Subject: [PATCH 3/6] I believe: - Changed "soft_start_offset" to be an overload of "soft_start" that has no default values - Updated the Python-side soft-start code to reflect the above -- Passing in -1 for the value of "br", since the relevant C++ code only checks for a br that is greater than 0, I believe. - Made the new parameter to "soft_start" more descriptive than "boff". - Updated the doc-string to reflect the offsetting parameter - Removed the spaces around the equal-sign in the parameter list for the Python-side softStart method. --- direct/src/particles/ParticleEffect.py | 4 ++-- panda/src/particlesystem/particleSystem.I | 6 +++--- panda/src/particlesystem/particleSystem.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/direct/src/particles/ParticleEffect.py b/direct/src/particles/ParticleEffect.py index 644cde133b8..d350e0ff1c6 100644 --- a/direct/src/particles/ParticleEffect.py +++ b/direct/src/particles/ParticleEffect.py @@ -220,11 +220,11 @@ def softStop(self): for particles in self.getParticlesList(): particles.softStop() - def softStart(self, firstBirthOffset = None): + def softStart(self, firstBirthOffset=None): if self.__isValid(): for particles in self.getParticlesList(): if firstBirthOffset is not None: - particles.softStartOffset(boff = firstBirthOffset) + particles.softStart(br = -1, first_birth_offset_time = firstBirthOffset) else: particles.softStart() else: diff --git a/panda/src/particlesystem/particleSystem.I b/panda/src/particlesystem/particleSystem.I index 55ab395c817..d80887ec8fe 100644 --- a/panda/src/particlesystem/particleSystem.I +++ b/panda/src/particlesystem/particleSystem.I @@ -59,12 +59,12 @@ soft_start(PN_stdfloat br) { } /** - * Causes system to use birth rate set by set_birth_rate() + * Causes system to use birth rate set by set_birth_rate(), with the timer for the system's initial birth offset by the value of first_birth_offset_time */ INLINE void ParticleSystem:: -soft_start_offset(PN_stdfloat br, PN_stdfloat boff) { +soft_start(PN_stdfloat br, PN_stdfloat first_birth_offset_time) { soft_start(br); - _tics_since_birth = boff; + _tics_since_birth = first_birth_offset_time; } /** diff --git a/panda/src/particlesystem/particleSystem.h b/panda/src/particlesystem/particleSystem.h index c1beff08876..d92746e5543 100644 --- a/panda/src/particlesystem/particleSystem.h +++ b/panda/src/particlesystem/particleSystem.h @@ -97,7 +97,7 @@ class EXPCL_PANDA_PARTICLESYSTEM ParticleSystem : public Physical { INLINE void clear_to_initial(); INLINE void soft_stop(PN_stdfloat br = 0.0); INLINE void soft_start(PN_stdfloat br = 0.0); - INLINE void soft_start_offset(PN_stdfloat br = 0.0, PN_stdfloat boff = 0.0); + INLINE void soft_start(PN_stdfloat br, PN_stdfloat first_birth_offset_time); void update(PN_stdfloat dt); virtual void output(std::ostream &out) const; From 8bfbc819b4823842e65d7871adcf47139684e28e Mon Sep 17 00:00:00 2001 From: Thaumaturge Date: Mon, 4 Nov 2019 21:53:59 +0200 Subject: [PATCH 4/6] Unit-testing for particle birth-rate and initial-birth offsetting, I believe. --- ...test_particle_offsetting_and_birth_rate.py | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 tests/particles/test_particle_offsetting_and_birth_rate.py diff --git a/tests/particles/test_particle_offsetting_and_birth_rate.py b/tests/particles/test_particle_offsetting_and_birth_rate.py new file mode 100644 index 00000000000..9932d744aba --- /dev/null +++ b/tests/particles/test_particle_offsetting_and_birth_rate.py @@ -0,0 +1,97 @@ +from panda3d.core import NodePath, PandaNode +from direct.particles.ParticleEffect import ParticleEffect +from direct.particles.Particles import Particles + +def test_particle_soft_start(): + # Create a particle effect and a particle system. + # The effect serves to test the Python-level "softStart" + # method, while the systme serves to test the C++-level + # "soft_start" method (via the associated Python "softStart" + # method) + effect = ParticleEffect() + system = Particles("testSystem", 10) + + # Setup some dummy nodes, since it seems to want them + system.setRenderParent(NodePath(PandaNode("test"))) + system.setSpawnRenderNodePath(NodePath(PandaNode("test"))) + + # Add the system to the effect + effect.addParticles(system) + + # Re-assign the system, just to make sure that we have the + # right object. + system = effect.getParticlesList()[0] + + # First, standard "softStart"--i.e. without changing either + # birth-rate or applying an offset. This should work as it + # used to. + effect.softStart() + + assert (system.getBirthRate() == 0.5) + + # Now, check that the pre-existing single-parameter soft-start, + # which alters the birth-rate, still does so. + system.softStart(1) + + assert (system.getBirthRate() == 1) + + # Next, birth-offsetting. + + # Run a standard soft-start, then check that the birth-timer + # is zero, as used to be the case on running this command. + effect.softStart() + + assert (system.getTicsSinceBirth() == 0) + + # Run an offset soft-start via the system, then check + # that the birth-timer has the assigned value, + # and that the birth-rate is unchanged. + + # (We pass in a birth-rate ("br") of -1 because the related code + # checks for a birth-rate greater than 0, I believe. This allows + # us to change the offset-time without affecting the birth-rate.) + system.softStart(br = -1, first_birth_offset_time = 2) + + assert (system.getBirthRate() == 1) + assert (system.getTicsSinceBirth() == 2) + + # Now, run an offset soft-start via the effect, and + # again check that the birth-timer has changed as intended, + # and the birth-rate hasn't changed at all. + effect.softStart(firstBirthOffset = -0.25) + + assert (system.getBirthRate() == 1) + assert (system.getTicsSinceBirth() == -0.25) + + # Update the system, advancing it far enough that it should + # have birthed a particle if not for the offset, but not + # so far that it should have birthed a particle >with< + # the offset. Check thus that no particles have been birthed. + system.update(1) + + assert (system.getLivingParticles() == 0) + + # Update the system again, this time far enough that with the + # offset it should have birthed just one particle, and + # then check that this is the case. + system.update(1) + + assert (system.getLivingParticles() == 1) + + # And finally, check that an unaltered system births as + # expected given a single update: + systemControl = Particles("testSystem; control", 10) + + systemControl.setRenderParent(NodePath(PandaNode("test 2"))) + systemControl.setSpawnRenderNodePath(NodePath(PandaNode("test 2"))) + + assert (systemControl.getBirthRate() == 0.5) + assert (systemControl.getTicsSinceBirth() == 0) + + assert (systemControl.getLivingParticles() == 0) + + systemControl.update(0.6) + + assert (systemControl.getLivingParticles() == 1) + + # Done! :D \ No newline at end of file From 11b549a2a7a2b0d9adbd24921235df052c11c918 Mon Sep 17 00:00:00 2001 From: Thaumaturge Date: Wed, 6 Nov 2019 17:56:58 +0200 Subject: [PATCH 5/6] Changing the "first birth offset" to a (more intuitive, I think) "first birth delay", and with that negating the value applied so that it behaves as one is likely to imagine that a delay would, I believe. --- direct/src/particles/ParticleEffect.py | 6 ++--- panda/src/particlesystem/particleSystem.I | 9 +++++--- panda/src/particlesystem/particleSystem.h | 2 +- ...test_particle_offsetting_and_birth_rate.py | 22 +++++++++---------- 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/direct/src/particles/ParticleEffect.py b/direct/src/particles/ParticleEffect.py index d350e0ff1c6..3926110e94b 100644 --- a/direct/src/particles/ParticleEffect.py +++ b/direct/src/particles/ParticleEffect.py @@ -220,11 +220,11 @@ def softStop(self): for particles in self.getParticlesList(): particles.softStop() - def softStart(self, firstBirthOffset=None): + def softStart(self, firstBirthDelay=None): if self.__isValid(): for particles in self.getParticlesList(): - if firstBirthOffset is not None: - particles.softStart(br = -1, first_birth_offset_time = firstBirthOffset) + if firstBirthDelay is not None: + particles.softStart(br = -1, first_birth_delay = firstBirthDelay) else: particles.softStart() else: diff --git a/panda/src/particlesystem/particleSystem.I b/panda/src/particlesystem/particleSystem.I index d80887ec8fe..731ae9d7dcb 100644 --- a/panda/src/particlesystem/particleSystem.I +++ b/panda/src/particlesystem/particleSystem.I @@ -59,12 +59,15 @@ soft_start(PN_stdfloat br) { } /** - * Causes system to use birth rate set by set_birth_rate(), with the timer for the system's initial birth offset by the value of first_birth_offset_time + * Causes system to use birth rate set by set_birth_rate(), with the system's + * first birth being delayed by the value of first_birth_delay. Note that a + * negative delay is perfectly valid, causing the first birth to happen + * sooner rather than later. */ INLINE void ParticleSystem:: -soft_start(PN_stdfloat br, PN_stdfloat first_birth_offset_time) { +soft_start(PN_stdfloat br, PN_stdfloat first_birth_delay) { soft_start(br); - _tics_since_birth = first_birth_offset_time; + _tics_since_birth = -first_birth_delay; } /** diff --git a/panda/src/particlesystem/particleSystem.h b/panda/src/particlesystem/particleSystem.h index d92746e5543..23e6f5ce828 100644 --- a/panda/src/particlesystem/particleSystem.h +++ b/panda/src/particlesystem/particleSystem.h @@ -97,7 +97,7 @@ class EXPCL_PANDA_PARTICLESYSTEM ParticleSystem : public Physical { INLINE void clear_to_initial(); INLINE void soft_stop(PN_stdfloat br = 0.0); INLINE void soft_start(PN_stdfloat br = 0.0); - INLINE void soft_start(PN_stdfloat br, PN_stdfloat first_birth_offset_time); + INLINE void soft_start(PN_stdfloat br, PN_stdfloat first_birth_delay); void update(PN_stdfloat dt); virtual void output(std::ostream &out) const; diff --git a/tests/particles/test_particle_offsetting_and_birth_rate.py b/tests/particles/test_particle_offsetting_and_birth_rate.py index 9932d744aba..b763474faf9 100644 --- a/tests/particles/test_particle_offsetting_and_birth_rate.py +++ b/tests/particles/test_particle_offsetting_and_birth_rate.py @@ -22,8 +22,8 @@ def test_particle_soft_start(): # right object. system = effect.getParticlesList()[0] - # First, standard "softStart"--i.e. without changing either - # birth-rate or applying an offset. This should work as it + # First, standard "softStart"--i.e. without either changing + # the birth-rate or applying a delay. This should work as it # used to. effect.softStart() @@ -35,7 +35,7 @@ def test_particle_soft_start(): assert (system.getBirthRate() == 1) - # Next, birth-offsetting. + # Next, birth-delaying. # Run a standard soft-start, then check that the birth-timer # is zero, as used to be the case on running this command. @@ -43,36 +43,36 @@ def test_particle_soft_start(): assert (system.getTicsSinceBirth() == 0) - # Run an offset soft-start via the system, then check + # Run an delayed soft-start via the system, then check # that the birth-timer has the assigned value, # and that the birth-rate is unchanged. # (We pass in a birth-rate ("br") of -1 because the related code # checks for a birth-rate greater than 0, I believe. This allows - # us to change the offset-time without affecting the birth-rate.) - system.softStart(br = -1, first_birth_offset_time = 2) + # us to change the delay without affecting the birth-rate.) + system.softStart(br = -1, first_birth_delay = -2) assert (system.getBirthRate() == 1) assert (system.getTicsSinceBirth() == 2) - # Now, run an offset soft-start via the effect, and + # Now, run a delayed soft-start via the effect, and # again check that the birth-timer has changed as intended, # and the birth-rate hasn't changed at all. - effect.softStart(firstBirthOffset = -0.25) + effect.softStart(firstBirthDelay = 0.25) assert (system.getBirthRate() == 1) assert (system.getTicsSinceBirth() == -0.25) # Update the system, advancing it far enough that it should - # have birthed a particle if not for the offset, but not + # have birthed a particle if not for the delay, but not # so far that it should have birthed a particle >with< - # the offset. Check thus that no particles have been birthed. + # the delay. Check thus that no particles have been birthed. system.update(1) assert (system.getLivingParticles() == 0) # Update the system again, this time far enough that with the - # offset it should have birthed just one particle, and + # delay it should have birthed just one particle, and # then check that this is the case. system.update(1) From 97338618b555bb29ee9ef5edb331bc2ed10259b5 Mon Sep 17 00:00:00 2001 From: Thaumaturge Date: Wed, 6 Nov 2019 19:40:23 +0200 Subject: [PATCH 6/6] Various little changes, I believe. --- direct/src/particles/ParticleEffect.py | 2 +- ...test_particle_offsetting_and_birth_rate.py | 30 +++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/direct/src/particles/ParticleEffect.py b/direct/src/particles/ParticleEffect.py index 3926110e94b..efe61056b64 100644 --- a/direct/src/particles/ParticleEffect.py +++ b/direct/src/particles/ParticleEffect.py @@ -224,7 +224,7 @@ def softStart(self, firstBirthDelay=None): if self.__isValid(): for particles in self.getParticlesList(): if firstBirthDelay is not None: - particles.softStart(br = -1, first_birth_delay = firstBirthDelay) + particles.softStart(br=-1, first_birth_delay=firstBirthDelay) else: particles.softStart() else: diff --git a/tests/particles/test_particle_offsetting_and_birth_rate.py b/tests/particles/test_particle_offsetting_and_birth_rate.py index b763474faf9..6df762816f0 100644 --- a/tests/particles/test_particle_offsetting_and_birth_rate.py +++ b/tests/particles/test_particle_offsetting_and_birth_rate.py @@ -27,13 +27,13 @@ def test_particle_soft_start(): # used to. effect.softStart() - assert (system.getBirthRate() == 0.5) + assert system.getBirthRate() == 0.5 # Now, check that the pre-existing single-parameter soft-start, # which alters the birth-rate, still does so. system.softStart(1) - assert (system.getBirthRate() == 1) + assert system.getBirthRate() == 1 # Next, birth-delaying. @@ -41,7 +41,7 @@ def test_particle_soft_start(): # is zero, as used to be the case on running this command. effect.softStart() - assert (system.getTicsSinceBirth() == 0) + assert system.getTicsSinceBirth() == 0 # Run an delayed soft-start via the system, then check # that the birth-timer has the assigned value, @@ -50,18 +50,18 @@ def test_particle_soft_start(): # (We pass in a birth-rate ("br") of -1 because the related code # checks for a birth-rate greater than 0, I believe. This allows # us to change the delay without affecting the birth-rate.) - system.softStart(br = -1, first_birth_delay = -2) + system.softStart(br=-1, first_birth_delay=-2) - assert (system.getBirthRate() == 1) - assert (system.getTicsSinceBirth() == 2) + assert system.getBirthRate() == 1 + assert system.getTicsSinceBirth() == 2 # Now, run a delayed soft-start via the effect, and # again check that the birth-timer has changed as intended, # and the birth-rate hasn't changed at all. - effect.softStart(firstBirthDelay = 0.25) + effect.softStart(firstBirthDelay=0.25) - assert (system.getBirthRate() == 1) - assert (system.getTicsSinceBirth() == -0.25) + assert system.getBirthRate() == 1 + assert system.getTicsSinceBirth() == -0.25 # Update the system, advancing it far enough that it should # have birthed a particle if not for the delay, but not @@ -69,14 +69,14 @@ def test_particle_soft_start(): # the delay. Check thus that no particles have been birthed. system.update(1) - assert (system.getLivingParticles() == 0) + assert system.getLivingParticles() == 0 # Update the system again, this time far enough that with the # delay it should have birthed just one particle, and # then check that this is the case. system.update(1) - assert (system.getLivingParticles() == 1) + assert system.getLivingParticles() == 1 # And finally, check that an unaltered system births as # expected given a single update: @@ -85,13 +85,13 @@ def test_particle_soft_start(): systemControl.setRenderParent(NodePath(PandaNode("test 2"))) systemControl.setSpawnRenderNodePath(NodePath(PandaNode("test 2"))) - assert (systemControl.getBirthRate() == 0.5) - assert (systemControl.getTicsSinceBirth() == 0) + assert systemControl.getBirthRate() == 0.5 + assert systemControl.getTicsSinceBirth() == 0 - assert (systemControl.getLivingParticles() == 0) + assert systemControl.getLivingParticles() == 0 systemControl.update(0.6) - assert (systemControl.getLivingParticles() == 1) + assert systemControl.getLivingParticles() == 1 # Done! :D \ No newline at end of file