ParticleInterval.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. """Undocumented Module"""
  2. __all__ = ['ParticleInterval']
  3. """
  4. Contains the ParticleInterval class
  5. """
  6. from pandac.PandaModules import *
  7. from direct.directnotify.DirectNotifyGlobal import directNotify
  8. from Interval import Interval
  9. from direct.particles import ParticleEffect
  10. class ParticleInterval(Interval):
  11. """
  12. Use this interval when you want to have greater control over a
  13. ParticleEffect. The interval does not register the effect with
  14. the global particle and physics managers, but it does call upon
  15. them to perform its stepping. You should NOT call
  16. particleEffect.start() with an effect that is being controlled
  17. by a ParticleInterval.
  18. """
  19. # Name counter
  20. particleNum = 1
  21. # create ParticleInterval DirectNotify category
  22. notify = directNotify.newCategory('ParticleInterval')
  23. # Class methods
  24. def __init__(self,
  25. particleEffect,
  26. parent,
  27. worldRelative = 1,
  28. renderParent = None,
  29. duration = 0.0,
  30. softStopT = 0.0,
  31. cleanup = False,
  32. name = None):
  33. """
  34. particleEffect is a ParticleEffect
  35. parent is a NodePath: this is where the effect will be
  36. parented in the scenegraph
  37. worldRelative is a boolean: this will override 'renderParent'
  38. with render
  39. renderParent is a NodePath: this is where the particles will
  40. be rendered in the scenegraph
  41. duration is a float: for the time
  42. softStopT is a float: no effect if 0.0,
  43. a positive value will count from the
  44. start of the interval,
  45. a negative value will count from the
  46. end of the interval
  47. cleanup is a boolean: if True the effect will be destroyed
  48. and removed from the scenegraph upon
  49. interval completion
  50. set to False if planning on reusing
  51. the interval
  52. name is a string: use this for unique intervals so that
  53. they can be easily found in the taskMgr
  54. """
  55. # Generate unique name
  56. id = 'Particle-%d' % ParticleInterval.particleNum
  57. ParticleInterval.particleNum += 1
  58. if name == None:
  59. name = id
  60. # Record instance variables
  61. self.particleEffect = particleEffect
  62. self.cleanup = cleanup
  63. if parent != None:
  64. self.particleEffect.reparentTo(parent)
  65. if worldRelative:
  66. renderParent = render
  67. if renderParent:
  68. for particles in self.particleEffect.getParticlesList():
  69. particles.setRenderParent(renderParent.node())
  70. self.__softStopped = False
  71. if softStopT == 0.0:
  72. self.softStopT = duration
  73. elif softStopT < 0.0:
  74. self.softStopT = duration+softStopT
  75. else:
  76. self.softStopT = softStopT
  77. # Initialize superclass
  78. Interval.__init__(self, name, duration)
  79. def __step(self,dt):
  80. if self.particleEffect:
  81. self.particleEffect.accelerate(dt,1,0.05)
  82. def __softStart(self):
  83. if self.particleEffect:
  84. self.particleEffect.softStart()
  85. self.__softStopped = False
  86. def __softStop(self):
  87. if self.particleEffect:
  88. self.particleEffect.softStop()
  89. self.__softStopped = True
  90. def privInitialize(self, t):
  91. if self.state != CInterval.SPaused:
  92. # Restarting from a hard stop or just interrupting the
  93. # current play
  94. self.__softStart()
  95. if self.particleEffect:
  96. self.particleEffect.clearToInitial()
  97. self.currT = 0
  98. if self.particleEffect:
  99. for forceGroup in self.particleEffect.getForceGroupList():
  100. forceGroup.enable()
  101. Interval.privInitialize(self,t)
  102. def privInstant(self):
  103. self.privInitialize(self.getDuration())
  104. self.privFinalize()
  105. def privStep(self, t):
  106. if self.state == CInterval.SPaused or t < self.currT:
  107. # Restarting from a pause.
  108. self.privInitialize(t)
  109. else:
  110. if not self.__softStopped and t > self.softStopT:
  111. self.__step(self.softStopT-self.currT)
  112. self.__softStop()
  113. self.__step(t-self.softStopT)
  114. else:
  115. self.__step(t-self.currT)
  116. Interval.privStep(self,t)
  117. def privFinalize(self):
  118. Interval.privFinalize(self)
  119. if self.cleanup and self.particleEffect:
  120. self.particleEffect.disable()
  121. self.particleEffect = None