Hello, I’ve a problem with particles. I use many particles in my application: I create an effect, and after some seconds I would remove it.
But I don’t know the “correct” approach to destroy an effect. I copy a little example to show the problem:
import direct.directbase.DirectStart
from panda3d.core import AmbientLight,DirectionalLight
from panda3d.core import Point3,Vec3,Vec4
from panda3d.core import Filename
from direct.particles.Particles import Particles
from direct.particles.ParticleEffect import ParticleEffect
from direct.showbase.DirectObject import DirectObject
from direct.interval.IntervalGlobal import Sequence
class World(DirectObject):
def __init__(self):
self.accept( '1', self.stopParticle )
base.disableMouse()
camera.setPos(0,-20,2)
base.enableParticles()
self.t = loader.loadModel("models/teapot")
self.t.setPos(0,10,0)
self.t.reparentTo(render)
self.rotateTeapot()
self.setupLights()
self.p = ParticleEffect()
self.loadParticleConfig('steam.ptf')
def loadParticleConfig(self, file):
self.p.cleanup()
self.p = ParticleEffect()
self.p.loadConfig(Filename(file))
self.p.start(self.t)
self.p.setPos(3.000, 0.000, 2.250)
def stopParticle(self):
#self.p.cleanup()
self.p.softStop()
taskMgr.doMethodLater( 10, self.printNodes, 'print nodes' )
def printNodes(self,task):
print( render.ls() )
def rotateTeapot(self):
Sequence(
self.t.hprInterval(2, Point3(0, 0, 0) , startHpr=Point3(360, 0, 0))
).loop()
def setupLights(self):
ambientLight = AmbientLight("ambientLight")
ambientLight.setColor(Vec4(.4, .4, .35, 1))
directionalLight = DirectionalLight("directionalLight")
directionalLight.setDirection(Vec3( 0, 8, -2.5 ) )
directionalLight.setColor(Vec4( 0.9, 0.8, 0.9, 1 ) )
self.t.setLight(self.t.attachNewNode(directionalLight))
self.t.setLight(self.t.attachNewNode(ambientLight))
w = World()
run()
(it’s only a modification of the example provided by Panda, so it can be launched from the same folder and it’ll find the resources needed)
When the user press the key ‘1’, the method stopParticle is called. If the method is defined as follows:
def stopParticle(self):
#self.p.cleanup()
self.p.softStop()
taskMgr.doMethodLater( 10, self.printNodes, 'print nodes' )
The effect is stopped (and removed from screen), but it remains still in the scene graph - in the console I see:
c:\Panda3D-1.7.0\samples\Particles>python try.py
[...]
PandaNode render S:(CullFaceAttrib RescaleNormalAttrib)
[...]
PandaNode particle-effect-2 T:(pos 3 0 2.25)
PhysicalNode particles-1
GeomNode BaseParticleRenderer render node (1 geoms: S:(ColorAttrib Rende
rModeAttrib TexMatrixAttrib TextureAttrib TexGenAttrib TransparencyAttrib))
ForceNode vertex (1 forces)
So, the node corresponding the effect, PandaNode particle-effect-2, is alive.
Instead, if I define the method as follows:
def stopParticle(self):
self.p.cleanup()
#self.p.softStop()
taskMgr.doMethodLater( 10, self.printNodes, 'print nodes' )
The node is correctly cleared: in the console, there is not the node PandaNode particle-effect-2. But, in this case, I’ve another problem: when the method self.p.cleanup is called, the application freezes (the teapot stops about half a second).
So, if I use softStop I don’t see any freezes, but the node remains in the scene graph. If I use cleanup, the node is effectively cleared, but the application freezes. Is there a way to remove the particle effect from the scene graph, without freezing the application? Very thanks!