|
@@ -9,21 +9,52 @@ from Interval import Interval
|
|
|
from direct.particles import ParticleEffect
|
|
from direct.particles import ParticleEffect
|
|
|
|
|
|
|
|
class ParticleInterval(Interval):
|
|
class ParticleInterval(Interval):
|
|
|
|
|
+ """
|
|
|
|
|
+ Use this interval when you want to have greater control over a
|
|
|
|
|
+ ParticleEffect. The interval does not register the effect with
|
|
|
|
|
+ the global particle and physics managers, but it does call upon
|
|
|
|
|
+ them to perform its stepping. You should NOT call
|
|
|
|
|
+ particleEffect.start() with an effect that is being controlled
|
|
|
|
|
+ by a ParticleInterval.
|
|
|
|
|
+ """
|
|
|
# Name counter
|
|
# Name counter
|
|
|
particleNum = 1
|
|
particleNum = 1
|
|
|
# create ParticleInterval DirectNotify category
|
|
# create ParticleInterval DirectNotify category
|
|
|
notify = directNotify.newCategory('ParticleInterval')
|
|
notify = directNotify.newCategory('ParticleInterval')
|
|
|
# Class methods
|
|
# Class methods
|
|
|
- def __init__(self, particleEffect, parent, worldRelative=1, loop=0,
|
|
|
|
|
- duration=0.0, name=None):
|
|
|
|
|
|
|
+ def __init__(self,
|
|
|
|
|
+ particleEffect,
|
|
|
|
|
+ parent,
|
|
|
|
|
+ worldRelative = 1,
|
|
|
|
|
+ renderParent = None,
|
|
|
|
|
+ duration = 0.0,
|
|
|
|
|
+ softStopT = 0.0,
|
|
|
|
|
+ cleanup = False,
|
|
|
|
|
+ name = None):
|
|
|
"""
|
|
"""
|
|
|
- particleEffect is ??
|
|
|
|
|
- parent is ??
|
|
|
|
|
- worldRelative is a boolean
|
|
|
|
|
- loop is a boolean
|
|
|
|
|
- duration is a float for the time
|
|
|
|
|
- name is ??
|
|
|
|
|
|
|
+ particleEffect is a ParticleEffect
|
|
|
|
|
+ parent is a NodePath: this is where the effect will be
|
|
|
|
|
+ parented in the scenegraph
|
|
|
|
|
+ worldRelative is a boolean: this will override 'renderParent'
|
|
|
|
|
+ with render
|
|
|
|
|
+ renderParent is a NodePath: this is where the particles will
|
|
|
|
|
+ be rendered in the scenegraph
|
|
|
|
|
+ duration is a float for the time
|
|
|
|
|
+ softStopT is a float: no effect if 0.0,
|
|
|
|
|
+ a positive value will count from the
|
|
|
|
|
+ start of the interval,
|
|
|
|
|
+ a negative value will count from the
|
|
|
|
|
+ end of the interval
|
|
|
|
|
+
|
|
|
|
|
+ cleanup is a boolean: if True the effect will be destroyed
|
|
|
|
|
+ and removed from the scenegraph upon
|
|
|
|
|
+ interval completion
|
|
|
|
|
+ set to False if planning on reusing
|
|
|
|
|
+ the interval
|
|
|
|
|
+ name is a string: use this for unique intervals so that
|
|
|
|
|
+ they can be easily found in the taskMgr
|
|
|
"""
|
|
"""
|
|
|
|
|
+
|
|
|
# Generate unique name
|
|
# Generate unique name
|
|
|
id = 'Particle-%d' % ParticleInterval.particleNum
|
|
id = 'Particle-%d' % ParticleInterval.particleNum
|
|
|
ParticleInterval.particleNum += 1
|
|
ParticleInterval.particleNum += 1
|
|
@@ -31,49 +62,72 @@ class ParticleInterval(Interval):
|
|
|
name = id
|
|
name = id
|
|
|
# Record instance variables
|
|
# Record instance variables
|
|
|
self.particleEffect = particleEffect
|
|
self.particleEffect = particleEffect
|
|
|
- self.parent = parent
|
|
|
|
|
- self.worldRelative = worldRelative
|
|
|
|
|
- self.fLoop = loop
|
|
|
|
|
- assert duration > 0.0 or loop == 1
|
|
|
|
|
|
|
+ self.cleanup = cleanup
|
|
|
|
|
+
|
|
|
|
|
+ if parent != None:
|
|
|
|
|
+ self.particleEffect.reparentTo(parent)
|
|
|
|
|
+ if worldRelative:
|
|
|
|
|
+ renderParent = render
|
|
|
|
|
+ if renderParent:
|
|
|
|
|
+ for particles in self.particleEffect.getParticlesList():
|
|
|
|
|
+ particles.setRenderParent(renderParent.node())
|
|
|
|
|
+
|
|
|
|
|
+ if softStopT == 0.0:
|
|
|
|
|
+ self.softStopT = duration
|
|
|
|
|
+ elif softStopT < 0.0:
|
|
|
|
|
+ self.softStopT = duration+softStopT
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.softStopT = softStopT
|
|
|
|
|
+
|
|
|
# Initialize superclass
|
|
# Initialize superclass
|
|
|
Interval.__init__(self, name, duration)
|
|
Interval.__init__(self, name, duration)
|
|
|
|
|
|
|
|
- def __del__(self):
|
|
|
|
|
|
|
+ def __step(self,dt):
|
|
|
if self.particleEffect:
|
|
if self.particleEffect:
|
|
|
- self.particleEffect.cleanup()
|
|
|
|
|
- self.particleEffect = None
|
|
|
|
|
|
|
+ self.particleEffect.accelerate(dt,1,0.05)
|
|
|
|
|
+
|
|
|
|
|
+ def __softStart(self):
|
|
|
|
|
+ if self.particleEffect:
|
|
|
|
|
+ self.particleEffect.softStart()
|
|
|
|
|
+ self.__softStopped = False
|
|
|
|
|
+
|
|
|
|
|
+ def __softStop(self):
|
|
|
|
|
+ if self.particleEffect:
|
|
|
|
|
+ self.particleEffect.softStop()
|
|
|
|
|
+ self.__softStopped = True
|
|
|
|
|
+
|
|
|
|
|
|
|
|
def privInitialize(self, t):
|
|
def privInitialize(self, t):
|
|
|
- renderParent = None
|
|
|
|
|
- if self.worldRelative:
|
|
|
|
|
- renderParent = render
|
|
|
|
|
|
|
+ if self.state != CInterval.SPaused:
|
|
|
|
|
+ # Restarting from a hard stop or just interrupting the
|
|
|
|
|
+ # current play
|
|
|
|
|
+ self.__softStart()
|
|
|
|
|
+ if self.particleEffect:
|
|
|
|
|
+ self.particleEffect.clearToInitial()
|
|
|
|
|
+ self.currT = 0
|
|
|
|
|
+
|
|
|
if self.particleEffect:
|
|
if self.particleEffect:
|
|
|
- self.particleEffect.start(self.parent, renderParent)
|
|
|
|
|
- self.state = CInterval.SStarted
|
|
|
|
|
- self.currT = t
|
|
|
|
|
|
|
+ for forceGroup in self.particleEffect.getForceGroupList():
|
|
|
|
|
+ forceGroup.enable()
|
|
|
|
|
+
|
|
|
|
|
+ Interval.privInitialize(self,t)
|
|
|
|
|
|
|
|
def privStep(self, t):
|
|
def privStep(self, t):
|
|
|
- if self.state == CInterval.SPaused:
|
|
|
|
|
|
|
+ if self.state == CInterval.SPaused or t < self.currT:
|
|
|
# Restarting from a pause.
|
|
# Restarting from a pause.
|
|
|
self.privInitialize(t)
|
|
self.privInitialize(t)
|
|
|
else:
|
|
else:
|
|
|
- self.state = CInterval.SStarted
|
|
|
|
|
- self.currT = t
|
|
|
|
|
|
|
+ if not self.__softStopped and t > self.softStopT:
|
|
|
|
|
+ self.__step(self.softStopT-self.currT)
|
|
|
|
|
+ self.__softStop()
|
|
|
|
|
+ self.__step(t-self.softStopT)
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.__step(t-self.currT)
|
|
|
|
|
+ Interval.privStep(self,t)
|
|
|
|
|
|
|
|
def privFinalize(self):
|
|
def privFinalize(self):
|
|
|
- if self.particleEffect:
|
|
|
|
|
|
|
+ Interval.privFinalize(self)
|
|
|
|
|
+ if self.cleanup and self.particleEffect:
|
|
|
self.particleEffect.cleanup()
|
|
self.particleEffect.cleanup()
|
|
|
self.particleEffect = None
|
|
self.particleEffect = None
|
|
|
- self.currT = self.getDuration()
|
|
|
|
|
- self.state = CInterval.SFinal
|
|
|
|
|
-
|
|
|
|
|
- def privInstant(self):
|
|
|
|
|
- if self.particleEffect:
|
|
|
|
|
- self.particleEffect.cleanup()
|
|
|
|
|
- self.particleEffect = None
|
|
|
|
|
- self.currT = self.getDuration()
|
|
|
|
|
- self.state = CInterval.SFinal
|
|
|
|
|
-
|
|
|
|
|
- def privInterrupt(self):
|
|
|
|
|
- self.particleEffect.disable()
|
|
|
|
|
- self.state = CInterval.SPaused
|
|
|
|
|
|
|
+
|