diff --git a/direct/src/particles/Forces.py b/direct/src/particles/Forces.py new file mode 100644 index 0000000000..2db7942620 --- /dev/null +++ b/direct/src/particles/Forces.py @@ -0,0 +1,62 @@ +from PandaObject import * +from DirectObject import * +from PhysicsManagerGlobal import * + +import ForceNode + +class Forces(DirectObject): + + forceNum = 1 + + def __init__(self, name = None): + """__init__(self)""" + + if (name == None): + self.name = 'Forces-%d' % forceNum + forceNum = forceNum + 1 + else: + self.name = name + + self.node = ForceNode.ForceNode(self.name) + self.nodePath = hidden.attachNewNode(self.node) + + def addForce(self, force): + """addForce(self, force)""" + self.node.addForce(force) + + def removeForce(self, force): + """removeForce(self, force)""" + self.node.removeForce(force) + + def enable(self): + """enable(self)""" + for i in self.node.getNumForces(): + f = self.node.getForce(i) + if (f.isLinear() == 1): + physicsManager.addLinearForce(f) + else: + physicsManager.addAngularForce(f) + + def disable(self): + """disable(self)""" + for i in self.node.getNumForces(): + f = self.node.getForce(i) + if (f.isLinear() == 1): + physicsManager.removeLinearForce(f) + else: + physicsManager.removeAngularForce(f) + + def __getItem__(self, index): + """__getItem__(self, index)""" + return self.node.getForce(index) + + def __len__(self): + """__len__(self)""" + return self.node.getNumForces() + + def __asList__(self): + """__asList__(self)""" + l = [] + for i in self.node.getNumForces(): + l.append(self.node.getForce(i)) + return l diff --git a/direct/src/particles/ParticleEffect.py b/direct/src/particles/ParticleEffect.py index eadb43749a..5af3eeef33 100644 --- a/direct/src/particles/ParticleEffect.py +++ b/direct/src/particles/ParticleEffect.py @@ -1,84 +1,41 @@ from PandaObject import * from DirectObject import * -from ParticleManagerGlobal import * -from PhysicsManagerGlobal import * -from TaskManagerGlobal import * import Particles -import ForceNode -import PhysicalNode -import ClockObject +import Forces -globalClock = ClockObject.ClockObject.getGlobalClock() +class ParticleEffect(NodePath): + def __init__(self, nodePath): + """__init__(self, nodePath)""" + NodePath.__init__(self) + self.assign(nodePath) + self.name = self.getName() -class ParticleEffect(DirectObject): - def __init__(self, name): - """__init__(self, name)""" - - self.name = name - self.activated = 0 - self.particleDict = {} + self.forces = [] - self.forceNode = ForceNode.ForceNode() - self.forceNodePath = hidden.attachNewNode(self.forceNode) + self.particles = [] + self.addParticles(Particles.Particles()) - self.physicalNode = PhysicalNode.PhysicalNode() - self.physicalNodePath = hidden.attachNewNode(self.physicalNode) + def addForces(self, forces): + """addForces(self, forces)""" + forces.nodePath.reparentTo(self) + self.forces.append(forces) - def addLinearForce(self, force): - """addLinearForce(self, force)""" - self.forceNode.addForce(force) - physicsMgr.addLinearForce(force) + def addParticles(self, part): + """addParticles(self, part)""" + part.nodePath.reparentTo(self) + self.particles.append(part) - def removeLinearForce(self, force): - """removeLinearForce(self, force)""" - physicsMgr.removeLinearForce(force) - self.forceNode.removeForce(force) + def enable(self): + """enable(self)""" + for f in self.forces: + f.enable() + for p = self.particles: + p.enable() - def addAngularForce(self, force): - """addAngularForce(self, force)""" - self.forceNode.addForce(force) - physicsMgr.addAngularForce(force) - - def removeAngularForce(self, force): - """removeAngularForce(self, force)""" - physicsMgr.removeAngularForce(force) - self.forceNode.removeForce(force) - - def addParticles(self, particles): - """addParticles(self, particles)""" - self.particleDict[particles.name] = particles - self.physicalNode.addPhysical(particles) - physicsMgr.attachPhysical(particles) - particleMgr.attachParticlesystem(particles) - - def removeParticles(self, particles): - """removeParticles(self, particles)""" - particleMgr.removeParticlesystem(particles) - physicsMgr.removePhysical(particles) - self.physicalNode.removePhysical(particles) - self.particleDict[particles.name] = None - - def activate(self): - """activate(self)""" - if (self.activated == 0): - self.activated = 1 - self.forceNodePath.reparentTo(render) - self.physicalNodePath.reparentTo(render) - taskMgr.spawnTaskNamed(Task.Task(self.__update), - self.name + '-update') - - def deactivate(self): - """deactivate(self)""" - if (self.activated == 1): - self.activated = 0 - taskMgr.removeTasksNamed(self.name + '-update') - self.forceNodePath.reparentTo(hidden) - self.physicalNodePath.reparentTo(hidden) - - def __update(self, state): - """__update(self, state)""" - dt = min(globalClock.getDt(), 0.1) - physicsMgr.doPhysics(dt) - particleMgr.doParticles(dt) - return Task.cont + def disable(self): + """disable(self)""" + for f = self.forces: + f.disable() + for p = self.particles: + p.disable() diff --git a/direct/src/particles/Particles.py b/direct/src/particles/Particles.py index 9876f00ec7..18217d345f 100644 --- a/direct/src/particles/Particles.py +++ b/direct/src/particles/Particles.py @@ -1,4 +1,6 @@ from PandaObject import * +from ParticleManagerGlobal import * +from PhysicsManagerGlobal import * import ParticleSystem import BaseParticleFactory @@ -29,15 +31,26 @@ SparkleParticleRenderer.SparkleParticleRenderer.SPSCALE = 1 class Particles(ParticleSystem.ParticleSystem): - def __init__(self, name, poolSize = 1024): - """__init__(self)""" + particleNum = 1 - self.name = name + def __init__(self, name = None, poolSize = 1024): + """__init__(self, name, poolSize)""" + + if (name == None): + self.name = 'particles-%d' % particleNum + particleNum = particleNum + 1 + else: + self.name = name ParticleSystem.ParticleSystem.__init__(self, poolSize) self.setBirthRate(0.02) self.setLitterSize(10) self.setLitterSpread(0) - self.setRenderParent(render.node()) + + # Set up a physical node + self.node = PhysicalNode.PhysicalNode(self.name) + self.nodePath = hidden.attachNewNode(self.node) + self.setRenderParent(self.node) + self.node.addPhysical(self) self.factory = None self.factoryType = "undefined" @@ -49,6 +62,16 @@ class Particles(ParticleSystem.ParticleSystem): self.emitterType = "undefined" self.setEmitter("SphereVolumeEmitter") + def enable(self): + """enable(self)""" + physicsMgr.attachPhysical(self.node) + particleMgr.attachParticlesystem(self) + + def disable(self): + """disable(self)""" + physicsMgr.removePhysical(self.node) + particleMgr.removeParticlesystem(self) + def setFactory(self, type): """setFactory(self, type)""" if (self.factoryType == type): @@ -170,6 +193,7 @@ class Particles(ParticleSystem.ParticleSystem): targ = 'p' file.write('from Particles import *\n') file.write('p = Particles(\'' + self.name + '\')\n') + file.write('self.enable()\n') file.write('# Particles parameters\n') file.write(targ + '.setFactory(\"' + self.factoryType + '\")\n') file.write(targ + '.setRenderer(\"' + self.rendererType + '\")\n') diff --git a/direct/src/showbase/ShowBase.py b/direct/src/showbase/ShowBase.py index 5ac462c7a9..b72e320bb7 100644 --- a/direct/src/showbase/ShowBase.py +++ b/direct/src/showbase/ShowBase.py @@ -7,11 +7,15 @@ from EventManagerGlobal import * from PythonUtil import * from ParticleManagerGlobal import * from PhysicsManagerGlobal import * + import Task import EventManager import math import sys import LinearEulerIntegrator +import ClockObject + +globalClock = ClockObject.ClockObject.getGlobalClock() class ShowBase: @@ -106,11 +110,20 @@ class ShowBase: self.taskMgr = taskMgr + # Particle manager self.particleMgr = particleMgr self.particleMgr.setFrameStepping(1) + self.particleMgrEnabled = 0 + + # Physics manager self.physicsMgr = physicsMgr self.integrator = LinearEulerIntegrator.LinearEulerIntegrator() self.physicsMgr.attachLinearIntegrator(self.integrator) + self.physicsMgrEnabled = 0 + + # Spawn the update managers task + self.taskMgr.spawnTaskNamed(Task.Task(self.__updateManagers), + 'manager-update') self.createAudioManager() self.createRootPanel() @@ -118,6 +131,20 @@ class ShowBase: self.restart() + def enableParticles(self, flag = 1): + """enableParticles(self, flag)""" + self.particleMgrEnabled = flag + self.physicsMgrEnabled = flag + + def __updateManagers(self, state): + """__updateManagers(self)""" + dt = min(globalClock.getDt(), 0.1) + if (self.particleMgrEnabled == 1): + self.particleMgr.doParticles(dt) + if (self.physicsMgrEnabled == 1): + self.physicsMgr.doPhysics(dt) + return Task.cont + def createStats(self): # You must specify a pstats-host in your configrc # The default is localhost diff --git a/direct/src/tkpanels/ParticlePanel.py b/direct/src/tkpanels/ParticlePanel.py index 06548b52a5..0b5c6992cc 100644 --- a/direct/src/tkpanels/ParticlePanel.py +++ b/direct/src/tkpanels/ParticlePanel.py @@ -675,9 +675,9 @@ class ParticlePanel(AppShell): self.getWidget('System', 'Litter Spread').set(litterSpread, 0) systemLifespan = self.particles.getSystemLifespan() self.getWidget('System', 'Lifespan').set(systemLifespan, 0) - pos = self.particleEffect.physicalNodePath.getPos() + pos = self.particles.nodePath.getPos() self.getWidget('System', 'Pos').set([pos[0], pos[1], pos[2]], 0) - hpr = self.particleEffect.physicalNodePath.getHpr() + hpr = self.particles.nodePath.getHpr() self.getWidget('System', 'Hpr').set([hpr[0], hpr[1], hpr[2]], 0) self.systemLocalVelocity.set(self.particles.getLocalVelocityFlag()) self.systemGrowsOlder.set(self.particles.getSystemGrowsOlderFlag()) @@ -696,9 +696,9 @@ class ParticlePanel(AppShell): def toggleSystemGrowsOlder(self): self.particles.setSystemGrowsOlderFlag(self.systemGrowsOlder.get()) def setSystemPos(self, pos): - self.particleEffect.physicalNodePath.setPos(Vec3(pos[0], pos[1], pos[2])) + self.particles.nodePath.setPos(Vec3(pos[0], pos[1], pos[2])) def setSystemHpr(self, pos): - self.particleEffect.physicalNodePath.setHpr(Vec3(pos[0], pos[1], pos[2])) + self.particles.nodePath.setHpr(Vec3(pos[0], pos[1], pos[2])) ## FACTORY PAGE ## def selectFactoryType(self, type):