| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976 |
- """PANDA3D Particle Panel"""
- # Import Tkinter, Pmw, and the floater code from this directory tree.
- from direct.tkwidgets.AppShell import AppShell
- from tkFileDialog import *
- from tkSimpleDialog import askstring
- import os, Pmw, Tkinter
- from direct.tkwidgets.Dial import AngleDial
- from direct.tkwidgets.Floater import Floater
- from direct.tkwidgets.Slider import Slider
- from direct.tkwidgets.VectorWidgets import Vector2Entry, Vector3Entry
- from direct.tkwidgets.VectorWidgets import ColorEntry
- import sePlacer
- import seForceGroup
- import seParticles
- import seParticleEffect
- class ParticlePanel(AppShell):
- # Override class variables
- appname = 'Particle Panel'
- frameWidth = 375
- frameHeight = 575
- usecommandarea = 0
- usestatusarea = 0
- balloonState = 'both'
- effectsDict={}
- def __init__(self, particleEffect = None, effectsDict={}, **kw):
- INITOPT = Pmw.INITOPT
- optiondefs = (
- ('title', self.appname, None),
- )
- self.defineoptions(kw, optiondefs)
- # Record particle effect
- if particleEffect != None:
- self.particleEffect = particleEffect
- self.effectsDict = effectsDict
- else:
- # Or create a new one if none given
- particles = seParticles.Particles()
- particles.setBirthRate(0.02)
- particles.setLitterSize(10)
- particles.setLitterSpread(0)
- particles.setFactory("PointParticleFactory")
- particles.setRenderer("PointParticleRenderer")
- particles.setEmitter("SphereVolumeEmitter")
- particles.enable()
- pe = seParticleEffect.ParticleEffect('effect1', particles)
- self.particleEffect = pe
- self.emitter=loader.loadModel("sphere")
- pe.reparentTo(self.emitter)
- self.emitter.setName("effect1")
- self.emitter.reparentTo(render)
- pe.enable()
- messenger.send('ParticlePanel_Added_Effect',['effect1',pe,self.emitter])
- self.effectsDict[self.particleEffect.getName()]=self.particleEffect
-
- messenger.send('SGE_Update Explorer',[render])
-
- # Initialize application specific info
- AppShell.__init__(self)
- # Initialize panel Pmw options
- self.initialiseoptions(ParticlePanel)
- # Update panel values to reflect particle effect's state
- self.selectEffectNamed(self.effectsDict.keys()[0])
- # Make sure labels/menus reflect current state
- self.updateMenusAndLabels()
- # Make sure there is a page for each forceGroup objects
- for forceGroup in self.particleEffect.getForceGroupList():
- self.addForceGroupNotebookPage(self.particleEffect, forceGroup)
- def appInit(self):
- # Create dictionaries to keep track of panel objects
- self.widgetDict = {}
- self.variableDict = {}
- self.forcePagesDict = {}
- # Make sure particles are enabled
- base.enableParticles()
- def onDestroy(self, event):
- messenger.send('ParticlePanle_close')
- return
- def createInterface(self):
- # Handle to the toplevels hull
- interior = self.interior()
- # Create particle panel menu items
- ## MENUBAR ENTRIES ##
- # FILE MENU
- # Get a handle on the file menu so commands can be inserted
- # before quit item
- fileMenu = self.menuBar.component('File-menu')
- # MRM: Need to add load and save effects methods
- fileMenu.insert_command(
- fileMenu.index('Quit'),
- label = 'Load Params',
- command = self.loadParticleEffectFromFile)
- fileMenu.insert_command(
- fileMenu.index('Quit'),
- label = 'Save Params',
- command = self.saveParticleEffectToFile)
- fileMenu.insert_command(
- fileMenu.index('Quit'),
- label = 'Print Params',
- command = lambda s = self: s.particles.printParams())
- # PARTICLE MANAGER MENU
- self.menuBar.addmenu('ParticleMgr', 'ParticleMgr Operations')
- self.particleMgrActive = IntVar()
- self.particleMgrActive.set(base.isParticleMgrEnabled())
- self.menuBar.addmenuitem(
- 'ParticleMgr', 'checkbutton',
- 'Enable/Disable ParticleMgr',
- label = 'Active',
- variable = self.particleMgrActive,
- command = self.toggleParticleMgr)
- ## MENUBUTTON LABELS ##
- # Menubutton/label to identify the current objects being configured
- labelFrame = Frame(interior)
- # Current effect
- self.effectsLabel = Menubutton(labelFrame, width = 10,
- relief = RAISED,
- borderwidth = 2,
- font=('MSSansSerif', 12, 'bold'),
- activebackground = '#909090')
- self.effectsLabelMenu = Menu(self.effectsLabel, tearoff = 0)
- self.effectsLabel['menu'] = self.effectsLabelMenu
- self.effectsLabel.pack(side = LEFT, fill = 'x', expand = 1)
- self.bind(self.effectsLabel,
- 'Select effect to configure or create new effect')
- self.effectsLabelMenu.add_command(label = 'Create New Effect',
- command = self.createNewEffect)
- self.effectsLabelMenu.add_command(
- label = 'Select Particle Effect',
- command = lambda s = self: SEditor.select(s.particleEffect))
- self.effectsLabelMenu.add_command(
- label = 'Place Particle Effect',
- command = lambda s = self: sePlacer.place(s.particleEffect))
- def togglePEVis(s = self):
- if s.particleEffect.isHidden():
- s.particleEffect.show()
- else:
- s.particleEffect.hide()
- self.effectsLabelMenu.add_command(
- label = 'Toggle Effect Vis',
- command = togglePEVis)
- self.effectsEnableMenu = Menu(self.effectsLabelMenu, tearoff = 0)
- self.effectsLabelMenu.add_cascade(label = 'Enable/Disable',
- menu = self.effectsEnableMenu)
- self.effectsLabelMenu.add_separator()
- # Current particles
- self.particlesLabel = Menubutton(labelFrame, width = 10,
- relief = RAISED,
- borderwidth = 2,
- font=('MSSansSerif', 12, 'bold'),
- activebackground = '#909090')
- self.particlesLabelMenu = Menu(self.particlesLabel, tearoff = 0)
- self.particlesLabel['menu'] = self.particlesLabelMenu
- self.particlesLabel.pack(side = LEFT, fill = 'x', expand = 1)
- self.bind(self.particlesLabel,
- ('Select particles object to configure ' +
- 'or add new particles object to current effect' ))
- self.particlesLabelMenu.add_command(label = 'Create New Particles',
- command = self.createNewParticles)
- self.particlesEnableMenu = Menu(self.particlesLabelMenu, tearoff = 0)
- self.particlesLabelMenu.add_cascade(label = 'Enable/Disable',
- menu = self.particlesEnableMenu)
- self.particlesLabelMenu.add_separator()
- # Current force
- self.forceGroupLabel = Menubutton(labelFrame, width = 10,
- relief = RAISED,
- borderwidth = 2,
- font=('MSSansSerif', 12, 'bold'),
- activebackground = '#909090')
- self.forceGroupLabelMenu = Menu(self.forceGroupLabel, tearoff = 0)
- self.forceGroupLabel['menu'] = self.forceGroupLabelMenu
- self.forceGroupLabel.pack(side = LEFT, fill = 'x', expand = 1)
- self.bind(self.forceGroupLabel,
- ('Select force group to configure ' +
- 'or add a new force group to current effect'))
- self.forceGroupLabelMenu.add_command(
- label = 'Create New ForceGroup',
- command = self.createNewForceGroup)
- self.forceGroupEnableMenu = Menu(self.forceGroupLabelMenu, tearoff = 0)
- self.forceGroupLabelMenu.add_cascade(label = 'Enable/Disable',
- menu = self.forceGroupEnableMenu)
- self.forceGroupLabelMenu.add_separator()
- # Pack labels
- labelFrame.pack(fill = 'x', expand = 0)
- # Create the toplevel notebook pages
- self.mainNotebook = Pmw.NoteBook(interior)
- self.mainNotebook.pack(fill = BOTH, expand = 1)
- systemPage = self.mainNotebook.add('System')
- factoryPage = self.mainNotebook.add('Factory')
- emitterPage = self.mainNotebook.add('Emitter')
- rendererPage = self.mainNotebook.add('Renderer')
- forcePage = self.mainNotebook.add('Force')
- # Put this here so it isn't called right away
- self.mainNotebook['raisecommand'] = self.updateInfo
- ## SYSTEM PAGE WIDGETS ##
- # Create system floaters
- systemFloaterDefs = (
- ('System', 'Pool Size',
- 'Max number of simultaneous particles',
- self.setSystemPoolSize,
- 1.0, 1.0),
- ('System', 'Birth Rate',
- 'Seconds between particle births',
- self.setSystemBirthRate,
- 0.0, None),
- ('System', 'Litter Size',
- 'Number of particle created at each birth',
- self.setSystemLitterSize,
- 1.0, 1.0),
- ('System', 'Litter Spread',
- 'Variation in litter size',
- self.setSystemLitterSpread,
- 0.0, 1.0),
- ('System', 'Lifespan',
- 'Age in seconds at which the system (vs. particles) should die',
- self.setSystemLifespan,
- 0.0, None)
- )
- self.createFloaters(systemPage, systemFloaterDefs)
- # Checkboxes
- self.createCheckbutton(
- systemPage, 'System', 'Render Space Velocities',
- ('On: velocities are in render space; ' +
- 'Off: velocities are in particle local space'),
- self.toggleSystemLocalVelocity, 0)
- self.createCheckbutton(
- systemPage, 'System', 'System Grows Older',
- 'On: system has a lifespan',
- self.toggleSystemGrowsOlder, 0)
- # Vector widgets
- pos = self.createVector3Entry(systemPage, 'System', 'Pos',
- 'Particle system position',
- command = self.setSystemPos)
- pos.addMenuItem('Popup Placer Panel', sePlacer.Placer)
- hpr = self.createVector3Entry(systemPage, 'System', 'Hpr',
- 'Particle system orientation',
- fGroup_labels = ('H', 'P', 'R'),
- command = self.setSystemHpr)
- hpr.addMenuItem('Popup Placer Panel', sePlacer.Placer)
- ## FACTORY PAGE WIDGETS ##
- self.createOptionMenu(
- factoryPage,
- 'Factory', 'Factory Type',
- 'Select type of particle factory',
- ('PointParticleFactory', 'ZSpinParticleFactory',
- 'OrientedParticleFactory'),
- self.selectFactoryType)
- factoryWidgets = (
- ('Factory', 'Life Span',
- 'Average particle lifespan in seconds',
- self.setFactoryLifeSpan,
- 0.0, None),
- ('Factory', 'Life Span Spread',
- 'Variation in lifespan',
- self.setFactoryLifeSpanSpread,
- 0.0, None),
- ('Factory', 'Mass',
- 'Average particle mass',
- self.setFactoryParticleMass,
- 0.001, None),
- ('Factory', 'Mass Spread',
- 'Variation in particle mass',
- self.setFactoryParticleMassSpread,
- 0.0, None),
- ('Factory', 'Terminal Velocity',
- 'Cap on average particle velocity',
- self.setFactoryTerminalVelocity,
- 0.0, None),
- ('Factory', 'Terminal Vel. Spread',
- 'Variation in terminal velocity',
- self.setFactoryTerminalVelocitySpread,
- 0.0, None),
- )
- self.createFloaters(factoryPage, factoryWidgets)
- self.factoryNotebook = Pmw.NoteBook(factoryPage, tabpos = None)
- # Point page #
- factoryPointPage = self.factoryNotebook.add('PointParticleFactory')
- # Z spin page #
- zSpinPage = self.factoryNotebook.add('ZSpinParticleFactory')
- self.createCheckbutton(
- zSpinPage, 'Z Spin Factory', 'Enable Angular Velocity',
- ("On: angular velocity is used; " +
- "Off: final angle is used"),
- self.toggleAngularVelocity, 0, side = TOP),
- self.createFloater(
- zSpinPage, 'Z Spin Factory', 'Angular Velocity',
- 'How fast sprites rotate',
- command = self.setFactoryZSpinAngularVelocity)
- self.createFloater(
- zSpinPage, 'Z Spin Factory', 'Angular Velocity Spread',
- 'Variation in how fast sprites rotate',
- command = self.setFactoryZSpinAngularVelocitySpread)
- self.createAngleDial(zSpinPage, 'Z Spin Factory', 'Initial Angle',
- 'Starting angle in degrees',
- fRollover = 1,
- command = self.setFactoryZSpinInitialAngle)
- self.createAngleDial(
- zSpinPage, 'Z Spin Factory',
- 'Initial Angle Spread',
- 'Spread of the initial angle',
- fRollover = 1,
- command = self.setFactoryZSpinInitialAngleSpread)
- self.createAngleDial(zSpinPage, 'Z Spin Factory', 'Final Angle',
- 'Final angle in degrees',
- fRollover = 1,
- command = self.setFactoryZSpinFinalAngle)
- self.createAngleDial(
- zSpinPage, 'Z Spin Factory',
- 'Final Angle Spread',
- 'Spread of the final angle',
- fRollover = 1,
- command = self.setFactoryZSpinFinalAngleSpread)
- # Oriented page #
- orientedPage = self.factoryNotebook.add('OrientedParticleFactory')
- Label(orientedPage, text = 'Not implemented').pack(expand = 1,
- fill = BOTH)
- self.factoryNotebook.pack(expand = 1, fill = BOTH)
- ## EMITTER PAGE WIDGETS ##
- self.createOptionMenu(
- emitterPage, 'Emitter',
- 'Emitter Type',
- 'Select type of particle emitter',
- ('BoxEmitter', 'DiscEmitter', 'LineEmitter', 'PointEmitter',
- 'RectangleEmitter', 'RingEmitter', 'SphereVolumeEmitter',
- 'SphereSurfaceEmitter', 'TangentRingEmitter'),
- self.selectEmitterType)
- # Emitter modes
- self.emissionType = IntVar()
- self.emissionType.set(BaseParticleEmitter.ETRADIATE)
- emissionFrame = Frame(emitterPage)
- self.createRadiobutton(
- emissionFrame, 'left',
- 'Emitter', 'Explicit Emission',
- ('particles are all emitted in parallel, direction is based ' +
- 'on explicit velocity vector'),
- self.emissionType, BaseParticleEmitter.ETEXPLICIT,
- self.setEmissionType)
- self.createRadiobutton(
- emissionFrame, 'left',
- 'Emitter', 'Radiate Emission',
- 'particles are emitted away from a specific point',
- self.emissionType, BaseParticleEmitter.ETRADIATE,
- self.setEmissionType)
- self.createRadiobutton(
- emissionFrame, 'left',
- 'Emitter', 'Custom Emission',
- ('particles are emitted with a velocity that ' +
- 'is determined by the particular emitter'),
- self.emissionType, BaseParticleEmitter.ETCUSTOM,
- self.setEmissionType)
- emissionFrame.pack(fill = 'x', expand = 0)
- self.createFloater(
- emitterPage, 'Emitter', 'Velocity Multiplier',
- 'launch velocity multiplier (all emission modes)',
- command = self.setEmitterAmplitude,
- min = None)
- self.createFloater(
- emitterPage, 'Emitter', 'Velocity Multiplier Spread',
- 'spread for launch velocity multiplier (all emission modes)',
- command = self.setEmitterAmplitudeSpread)
- self.createVector3Entry(
- emitterPage, 'Emitter', 'Offset Velocity',
- 'Velocity vector applied to all particles',
- command = self.setEmitterOffsetForce)
- self.createVector3Entry(
- emitterPage, 'Emitter', 'Explicit Velocity',
- 'all particles launch with this velocity in Explicit mode',
- command = self.setEmitterExplicitLaunchVector)
- self.createVector3Entry(
- emitterPage, 'Emitter', 'Radiate Origin',
- 'particles launch away from this point in Radiate mode',
- command = self.setEmitterRadiateOrigin)
- self.emitterNotebook = Pmw.NoteBook(emitterPage, tabpos = None)
- # Box page #
- boxPage = self.emitterNotebook.add('BoxEmitter')
- self.createVector3Entry(boxPage, 'Box Emitter', 'Min',
- 'Min point defining emitter box',
- command = self.setEmitterBoxPoint1)
- self.createVector3Entry(boxPage, 'Box Emitter', 'Max',
- 'Max point defining emitter box',
- command = self.setEmitterBoxPoint2,
- value = (1.0, 1.0, 1.0))
- # Disc page #
- discPage = self.emitterNotebook.add('DiscEmitter')
- self.createFloater(discPage, 'Disc Emitter', 'Radius',
- 'Radius of disc',
- command = self.setEmitterDiscRadius,
- min = 0.01)
- customPage = self.discCustomFrame = Frame(discPage)
- self.createAngleDial(customPage, 'Disc Emitter', 'Inner Angle',
- 'Particle launch angle at center of disc',
- command = self.setEmitterDiscInnerAngle)
- self.createFloater(customPage, 'Disc Emitter', 'Inner Velocity',
- 'Launch velocity multiplier at center of disc',
- command = self.setEmitterDiscInnerVelocity)
- self.createAngleDial(customPage, 'Disc Emitter', 'Outer Angle',
- 'Particle launch angle at outer edge of disc',
- command = self.setEmitterDiscOuterAngle)
- self.createFloater(customPage, 'Disc Emitter', 'Outer Velocity',
- 'Launch velocity multiplier at edge of disc',
- command = self.setEmitterDiscOuterVelocity)
- self.createCheckbutton(
- customPage, 'Disc Emitter', 'Cubic Lerping',
- 'On: magnitude/angle interpolation from center',
- self.toggleEmitterDiscCubicLerping, 0)
- customPage.pack(fill = BOTH, expand = 1)
- # Line page #
- linePage = self.emitterNotebook.add('LineEmitter')
- self.createVector3Entry(linePage, 'Line Emitter', 'Min',
- 'Min point defining emitter line',
- command = self.setEmitterLinePoint1)
- self.createVector3Entry(linePage, 'Line Emitter', 'Max',
- 'Max point defining emitter line',
- command = self.setEmitterLinePoint2,
- value = (1.0, 0.0, 0.0))
- # Point page #
- emitterPointPage = self.emitterNotebook.add('PointEmitter')
- self.createVector3Entry(emitterPointPage, 'Point Emitter', 'Position',
- 'Position of emitter point',
- command = self.setEmitterPointPosition)
- # Rectangle #
- rectanglePage = self.emitterNotebook.add('RectangleEmitter')
- self.createVector2Entry(rectanglePage,
- 'Rectangle Emitter', 'Min',
- 'Point defining rectangle',
- command = self.setEmitterRectanglePoint1)
- self.createVector2Entry(rectanglePage,
- 'Rectangle Emitter', 'Max',
- 'Point defining rectangle',
- command = self.setEmitterRectanglePoint2)
- # Ring #
- ringPage = self.emitterNotebook.add('RingEmitter')
- self.createFloater(ringPage, 'Ring Emitter', 'Radius',
- 'Radius of ring',
- command = self.setEmitterRingRadius,
- min = 0.01)
- self.ringCustomFrame = Frame(ringPage)
- self.createAngleDial(self.ringCustomFrame, 'Ring Emitter', 'Angle',
- 'Particle launch angle',
- command = self.setEmitterRingLaunchAngle)
- self.ringCustomFrame.pack(fill = BOTH, expand = 1)
- # Sphere volume #
- sphereVolumePage = self.emitterNotebook.add('SphereVolumeEmitter')
- self.createFloater(sphereVolumePage, 'Sphere Volume Emitter', 'Radius',
- 'Radius of sphere',
- command = self.setEmitterSphereVolumeRadius,
- min = 0.01)
- # Sphere surface #
- sphereSurfacePage = self.emitterNotebook.add('SphereSurfaceEmitter')
- self.createFloater(sphereSurfacePage, 'Sphere Surface Emitter',
- 'Radius',
- 'Radius of sphere',
- command = self.setEmitterSphereSurfaceRadius,
- min = 0.01)
- # Tangent ring #
- tangentRingPage = self.emitterNotebook.add('TangentRingEmitter')
- self.createFloater(tangentRingPage, 'Tangent Ring Emitter', 'Radius',
- 'Radius of ring',
- command = self.setEmitterTangentRingRadius,
- min = 0.01)
- self.emitterNotebook.pack(fill = X)
- ## RENDERER PAGE WIDGETS ##
- self.createOptionMenu(
- rendererPage, 'Renderer', 'Renderer Type',
- 'Select type of particle renderer',
- ('LineParticleRenderer', 'GeomParticleRenderer',
- 'PointParticleRenderer', 'SparkleParticleRenderer',
- 'SpriteParticleRenderer'),
- self.selectRendererType)
- self.createOptionMenu(rendererPage,
- 'Renderer', 'Alpha Mode',
- "alpha setting over particles' lifetime",
- ('NO_ALPHA','ALPHA_OUT','ALPHA_IN','ALPHA_USER'),
- self.setRendererAlphaMode)
- self.createSlider(
- rendererPage, 'Renderer', 'User Alpha',
- 'alpha value for ALPHA_USER alpha mode',
- command = self.setRendererUserAlpha)
- self.rendererNotebook = Pmw.NoteBook(rendererPage, tabpos = None)
- # Line page #
- linePage = self.rendererNotebook.add('LineParticleRenderer')
- self.createColorEntry(linePage, 'Line Renderer', 'Head Color',
- 'Head color of line',
- command = self.setRendererLineHeadColor)
- self.createColorEntry(linePage, 'Line Renderer', 'Tail Color',
- 'Tail color of line',
- command = self.setRendererLineTailColor)
- # Geom page #
- geomPage = self.rendererNotebook.add('GeomParticleRenderer')
- f = Frame(geomPage)
- f.pack(fill = X)
- Label(f, width = 12, text = 'Geom Node').pack(side = LEFT)
- self.rendererGeomNode = StringVar()
- self.rendererGeomNodeEntry = Entry(
- f, width = 12,
- textvariable = self.rendererGeomNode)
- self.rendererGeomNodeEntry.bind('<Return>', self.setRendererGeomNode)
- self.rendererGeomNodeEntry.pack(side = LEFT, expand = 1, fill = X)
- # Point #
- rendererPointPage = self.rendererNotebook.add('PointParticleRenderer')
- self.createFloater(rendererPointPage, 'Point Renderer', 'Point Size',
- 'Width and height of points in pixels',
- command = self.setRendererPointSize)
- self.createColorEntry(rendererPointPage, 'Point Renderer',
- 'Start Color',
- 'Starting color of point',
- command = self.setRendererPointStartColor)
- self.createColorEntry(rendererPointPage, 'Point Renderer',
- 'End Color',
- 'Ending color of point',
- command = self.setRendererPointEndColor)
- self.createOptionMenu(rendererPointPage, 'Point Renderer',
- 'Blend Type',
- 'Type of color blending used for particle',
- ('PP_ONE_COLOR', 'PP_BLEND_LIFE',
- 'PP_BLEND_VEL'),
- self.rendererPointSelectBlendType)
- self.createOptionMenu(rendererPointPage, 'Point Renderer',
- 'Blend Method',
- 'Interpolation method between colors',
- ('PP_NO_BLEND', 'PP_BLEND_LINEAR',
- 'PP_BLEND_CUBIC'),
- self.rendererPointSelectBlendMethod)
- # Sparkle #
- sparklePage = self.rendererNotebook.add('SparkleParticleRenderer')
- self.createColorEntry(sparklePage, 'Sparkle Renderer',
- 'Center Color',
- 'Color of sparkle center',
- command = self.setRendererSparkleCenterColor)
- self.createColorEntry(sparklePage, 'Sparkle Renderer',
- 'Edge Color',
- 'Color of sparkle line endpoints',
- command = self.setRendererSparkleEdgeColor)
- self.createFloater(sparklePage, 'Sparkle Renderer',
- 'Birth Radius',
- 'Initial sparkle radius',
- command = self.setRendererSparkleBirthRadius)
- self.createFloater(sparklePage, 'Sparkle Renderer',
- 'Death Radius',
- 'Final sparkle radius',
- command = self.setRendererSparkleDeathRadius)
- self.createOptionMenu(sparklePage,
- 'Sparkle Renderer', 'Life Scale',
- 'Does particle scale over its lifetime?',
- ('SP_NO_SCALE', 'SP_SCALE'),
- self.setRendererSparkleLifeScale)
- # Sprite #
- spritePage = self.rendererNotebook.add('SpriteParticleRenderer')
- f = Frame(spritePage)
- Label(f, width = 12, text = 'Texture Type:').pack(side = LEFT)
- self.rendererSpriteSourceType = IntVar()
- self.rendererSpriteSourceType.set(SpriteParticleRenderer.STTexture)
- self.rendererSpriteSTTexture = self.createRadiobutton(
- f, 'left',
- 'Sprite Renderer', 'Texture Type',
- 'Sprite particle renderer created from texture file',
- self.rendererSpriteSourceType, SpriteParticleRenderer.STTexture,
- self.setSpriteSourceType)
- self.rendererSpriteSTTexture = self.createRadiobutton(
- f, 'left',
- 'Sprite Renderer', 'NodePath Type',
- 'Sprite particle renderer created from node path',
- self.rendererSpriteSourceType, SpriteParticleRenderer.STFromNode,
- self.setSpriteSourceType)
- f.pack(fill = X)
- f = Frame(spritePage)
- Label(f, width = 6, text = 'Texture:').pack(side = LEFT)
- self.rendererSpriteTexture = StringVar()
- self.rendererSpriteTexture.set(SpriteParticleRenderer.sourceTextureName)
- self.rendererSpriteTextureEntry = Entry(
- f, width = 12,
- textvariable = self.rendererSpriteTexture)
- self.rendererSpriteTextureEntry.pack(side = LEFT, expand = 1, fill = X)
- f.pack(fill = X)
- f = Frame(spritePage)
- Label(f, width = 6, text = 'File:').pack(side = LEFT)
- self.rendererSpriteFile = StringVar()
- self.rendererSpriteFile.set(SpriteParticleRenderer.sourceFileName)
- self.rendererSpriteFileEntry = Entry(
- f, width = 12,
- textvariable = self.rendererSpriteFile)
- self.rendererSpriteFileEntry.pack(side = LEFT, expand = 1, fill = X)
- Label(f, width = 6, text = 'Node:').pack(side = LEFT)
- self.rendererSpriteNode = StringVar()
- self.rendererSpriteNode.set(SpriteParticleRenderer.sourceNodeName)
- self.rendererSpriteNodeEntry = Entry(
- f, width = 6,
- textvariable = self.rendererSpriteNode)
- self.rendererSpriteNodeEntry.pack(side = LEFT, expand = 1, fill = X)
- f.pack(fill = X)
- # Init entries
- self.setSpriteSourceType()
- self.setTextureButton = Button(spritePage, text = 'Set Texture',
- command = self.setRendererSpriteTexture)
- self.setTextureButton.pack(fill = X)
- f = Frame(spritePage)
- self.createCheckbutton(
- f, 'Sprite Renderer', 'X Scale',
- ("On: x scale is interpolated over particle's life; " +
- "Off: stays as start_X_Scale"),
- self.toggleRendererSpriteXScale, 0, side = LEFT)
- self.createCheckbutton(
- f, 'Sprite Renderer', 'Y Scale',
- ("On: y scale is interpolated over particle's life; " +
- "Off: stays as start_Y_Scale"),
- self.toggleRendererSpriteYScale, 0, side = LEFT)
- self.createCheckbutton(
- f, 'Sprite Renderer', 'Anim Angle',
- ("On: particles that are set to spin on the Z axis will " +
- "spin appropriately"),
- self.toggleRendererSpriteAnimAngle, 0, side = LEFT)
- f.pack(fill = X)
- self.createFloater(spritePage, 'Sprite Renderer',
- 'Initial X Scale',
- 'Initial X scaling factor',
- command = self.setRendererSpriteInitialXScale)
- self.createFloater(spritePage, 'Sprite Renderer',
- 'Final X Scale',
- 'Final X scaling factor, if xScale enabled',
- command = self.setRendererSpriteFinalXScale)
- self.createFloater(spritePage, 'Sprite Renderer',
- 'Initial Y Scale',
- 'Initial Y scaling factor',
- command = self.setRendererSpriteInitialYScale)
- self.createFloater(spritePage, 'Sprite Renderer',
- 'Final Y Scale',
- 'Final Y scaling factor, if yScale enabled',
- command = self.setRendererSpriteFinalYScale)
- self.createAngleDial(spritePage, 'Sprite Renderer',
- 'Non Animated Theta',
- ('If animAngle is false: counter clockwise ' +
- 'Z rotation of all sprites'),
- command = self.setRendererSpriteNonAnimatedTheta)
- self.createOptionMenu(spritePage, 'Sprite Renderer',
- 'Blend Type',
- 'Interpolation blend type for X and Y scaling',
- ('PP_NO_BLEND', 'PP_LINEAR', 'PP_CUBIC'),
- self.setRendererSpriteBlendMethod)
- self.createCheckbutton(
- spritePage, 'Sprite Renderer', 'Alpha Disable',
- 'On: alpha blending is disabled',
- self.toggleRendererSpriteAlphaDisable, 0)
- self.rendererNotebook.pack(fill = X)
- ## FORCE PAGE WIDGETS ##
- self.addForceButton = Menubutton(forcePage, text = 'Add Force',
- relief = RAISED,
- borderwidth = 2,
- font=('MSSansSerif', 14, 'bold'),
- activebackground = '#909090')
- forceMenu = Menu(self.addForceButton)
- self.addForceButton['menu'] = forceMenu
- # DERIVED FROM LINEAR FORCE
- # This also has: setVector
- forceMenu.add_command(label = 'Add Linear Vector Force',
- command = self.addLinearVectorForce)
- # Parameters: setAmplitude, setMassDependent, setVectorMasks
- forceMenu.add_command(label = 'Add Linear Noise Force',
- command = self.addLinearNoiseForce)
- forceMenu.add_command(label = 'Add Linear Jitter Force',
- command = self.addLinearJitterForce)
- # This also has setCoef
- forceMenu.add_command(label = 'Add Linear Friction Force',
- command = self.addLinearFrictionForce)
- # This also has: setCoef, setLength, setRadius,
- forceMenu.add_command(label = 'Add Linear Cylinder Vortex Force',
- command = self.addLinearCylinderVortexForce)
- # DERIVED FROM LINEAR DISTANCE FORCE
- # Parameters: setFalloffType, setForceCenter, setRadius
- forceMenu.add_command(label = 'Add Linear Sink Force',
- command = self.addLinearSinkForce)
- forceMenu.add_command(label = 'Add Linear Source Force',
- command = self.addLinearSourceForce)
- """
- # Avoid for now
- forceMenu.add_command(label = 'Add Linear User Defined Force',
- command = self.addLinearUserDefinedForce)
- """
- self.addForceButton.pack(expand = 0)
- # Scrolled frame to hold force widgets
- self.sf = Pmw.ScrolledFrame(forcePage, horizflex = 'elastic')
- self.sf.pack(fill = 'both', expand = 1)
- self.forceFrame = self.sf.interior()
- # Notebook to hold force widgets as the are added
- self.forceGroupNotebook = Pmw.NoteBook(self.forceFrame, tabpos = None)
- self.forceGroupNotebook.pack(fill = X)
- self.factoryNotebook.setnaturalsize()
- self.emitterNotebook.setnaturalsize()
- self.rendererNotebook.setnaturalsize()
- self.forceGroupNotebook.setnaturalsize()
- self.mainNotebook.setnaturalsize()
- # Make sure input variables processed
- self.initialiseoptions(ParticlePanel)
- ### WIDGET UTILITY FUNCTIONS ###
- def createCheckbutton(self, parent, category, text,
- balloonHelp, command, initialState, side = 'top'):
- bool = BooleanVar()
- bool.set(initialState)
- widget = Checkbutton(parent, text = text, anchor = W,
- variable = bool)
- # Do this after the widget so command isn't called on creation
- widget['command'] = command
- widget.pack(fill = X, side = side)
- self.bind(widget, balloonHelp)
- self.widgetDict[category + '-' + text] = widget
- self.variableDict[category + '-' + text] = bool
- return widget
- def createRadiobutton(self, parent, side, category, text,
- balloonHelp, variable, value,
- command):
- widget = Radiobutton(parent, text = text, anchor = W,
- variable = variable, value = value)
- # Do this after the widget so command isn't called on creation
- widget['command'] = command
- widget.pack(side = side, fill = X)
- self.bind(widget, balloonHelp)
- self.widgetDict[category + '-' + text] = widget
- return widget
- def createFloaters(self, parent, widgetDefinitions):
- widgets = []
- for category, label, balloonHelp, command, min, resolution in widgetDefinitions:
- widgets.append(
- self.createFloater(parent, category, label, balloonHelp,
- command, min, resolution)
- )
- return widgets
- def createFloater(self, parent, category, text, balloonHelp,
- command = None, min = 0.0, resolution = None,
- numDigits = 3, **kw):
- kw['text'] = text
- kw['min'] = min
- kw['resolution'] = resolution
- kw['numDigits'] = numDigits
- widget = apply(Floater, (parent,), kw)
- # Do this after the widget so command isn't called on creation
- widget['command'] = command
- widget.pack(fill = X)
- self.bind(widget, balloonHelp)
- self.widgetDict[category + '-' + text] = widget
- return widget
- def createAngleDial(self, parent, category, text, balloonHelp,
- command = None, **kw):
- kw['text'] = text
- kw['style'] = 'mini'
- widget = apply(AngleDial,(parent,), kw)
- # Do this after the widget so command isn't called on creation
- widget['command'] = command
- widget.pack(fill = X)
- self.bind(widget, balloonHelp)
- self.widgetDict[category + '-' + text] = widget
- return widget
- def createSlider(self, parent, category, text, balloonHelp,
- command = None, min = 0.0, max = 1.0,
- resolution = 0.001, **kw):
- kw['text'] = text
- kw['min'] = min
- kw['max'] = max
- kw['resolution'] = resolution
- widget = apply(Slider, (parent,), kw)
- # Do this after the widget so command isn't called on creation
- widget['command'] = command
- widget.pack(fill = X)
- self.bind(widget, balloonHelp)
- self.widgetDict[category + '-' + text] = widget
- return widget
- def createVector2Entry(self, parent, category, text, balloonHelp,
- command = None, **kw):
- # Set label's text
- kw['text'] = text
- widget = apply(Vector2Entry, (parent,), kw)
- # Do this after the widget so command isn't called on creation
- widget['command'] = command
- widget.pack(fill = X)
- self.bind(widget, balloonHelp)
- self.widgetDict[category + '-' + text] = widget
- return widget
- def createVector3Entry(self, parent, category, text, balloonHelp,
- command = None, **kw):
- # Set label's text
- kw['text'] = text
- widget = apply(Vector3Entry, (parent,), kw)
- # Do this after the widget so command isn't called on creation
- widget['command'] = command
- widget.pack(fill = X)
- self.bind(widget, balloonHelp)
- self.widgetDict[category + '-' + text] = widget
- return widget
- def createColorEntry(self, parent, category, text, balloonHelp,
- command = None, **kw):
- # Set label's text
- kw['text'] = text
- widget = apply(ColorEntry, (parent,) ,kw)
- # Do this after the widget so command isn't called on creation
- widget['command'] = command
- widget.pack(fill = X)
- self.bind(widget, balloonHelp)
- self.widgetDict[category + '-' + text] = widget
- return widget
- def createOptionMenu(self, parent, category, text, balloonHelp,
- items, command):
- optionVar = StringVar()
- if len(items) > 0:
- optionVar.set(items[0])
- widget = Pmw.OptionMenu(parent, labelpos = W, label_text = text,
- label_width = 12, menu_tearoff = 1,
- menubutton_textvariable = optionVar,
- items = items)
- # Do this after the widget so command isn't called on creation
- widget['command'] = command
- widget.pack(fill = X)
- self.bind(widget.component('menubutton'), balloonHelp)
- self.widgetDict[category + '-' + text] = widget
- self.variableDict[category + '-' + text] = optionVar
- return optionVar
- def createComboBox(self, parent, category, text, balloonHelp,
- items, command, history = 0):
- widget = Pmw.ComboBox(parent,
- labelpos = W,
- label_text = text,
- label_anchor = 'w',
- label_width = 12,
- entry_width = 16,
- history = history,
- scrolledlist_items = items)
- # Don't allow user to edit entryfield
- widget.configure(entryfield_entry_state = 'disabled')
- # Select first item if it exists
- if len(items) > 0:
- widget.selectitem(items[0])
- # Bind selection command
- widget['selectioncommand'] = command
- widget.pack(side = 'left', expand = 0)
- # Bind help
- self.bind(widget, balloonHelp)
- # Record widget
- self.widgetDict[category + '-' + text] = widget
- return widget
- def updateMenusAndLabels(self):
- self.updateMenus()
- self.updateLabels()
- def updateLabels(self):
- self.effectsLabel['text'] = self.particleEffect.getName()
- self.particlesLabel['text'] = self.particles.getName()
- if self.forceGroup != None:
- self.forceGroupLabel['text'] = self.forceGroup.getName()
- else:
- self.forceGroupLabel['text'] = 'Force Group'
- def updateMenus(self):
- self.updateEffectsMenus()
- self.updateParticlesMenus()
- self.updateForceGroupMenus()
- def updateEffectsMenus(self):
- # Get rid of old effects entries if any
- self.effectsEnableMenu.delete(0, 'end')
- self.effectsLabelMenu.delete(5, 'end')
- self.effectsLabelMenu.add_separator()
- # Add in a checkbutton for each effect (to toggle on/off)
- keys = self.effectsDict.keys()
- keys.sort()
- for name in keys:
- effect = self.effectsDict[name]
- self.effectsLabelMenu.add_command(
- label = effect.getName(),
- command = (lambda s = self,
- e = effect: s.selectEffectNamed(e.getName()))
- )
- effectActive = IntVar()
- effectActive.set(effect.isEnabled())
- self.effectsEnableMenu.add_checkbutton(
- label = effect.getName(),
- variable = effectActive,
- command = (lambda s = self,
- e = effect,
- v = effectActive: s.toggleEffect(e, v)))
- def updateParticlesMenus(self):
- # Get rid of old particles entries if any
- self.particlesEnableMenu.delete(0, 'end')
- self.particlesLabelMenu.delete(2, 'end')
- self.particlesLabelMenu.add_separator()
- # Add in a checkbutton for each effect (to toggle on/off)
- particles = self.particleEffect.getParticlesList()
- names = map(lambda x: x.getName(), particles)
- names.sort()
- for name in names:
- particle = self.particleEffect.getParticlesNamed(name)
- self.particlesLabelMenu.add_command(
- label = name,
- command = (lambda s = self,
- n = name: s.selectParticlesNamed(n))
- )
- particleActive = IntVar()
- particleActive.set(particle.isEnabled())
- self.particlesEnableMenu.add_checkbutton(
- label = name,
- variable = particleActive,
- command = (lambda s = self,
- p = particle,
- v = particleActive: s.toggleParticles(p, v)))
- def updateForceGroupMenus(self):
- # Get rid of old forceGroup entries if any
- self.forceGroupEnableMenu.delete(0, 'end')
- self.forceGroupLabelMenu.delete(2, 'end')
- self.forceGroupLabelMenu.add_separator()
- # Add in a checkbutton for each effect (to toggle on/off)
- forceGroupList = self.particleEffect.getForceGroupList()
- names = map(lambda x: x.getName(), forceGroupList)
- names.sort()
- for name in names:
- force = self.particleEffect.getForceGroupNamed(name)
- self.forceGroupLabelMenu.add_command(
- label = name,
- command = (lambda s = self,
- n = name: s.selectForceGroupNamed(n))
- )
- forceActive = IntVar()
- forceActive.set(force.isEnabled())
- self.forceGroupEnableMenu.add_checkbutton(
- label = name,
- variable = forceActive,
- command = (lambda s = self,
- f = force,
- v = forceActive: s.toggleForceGroup(f, v)))
- def selectEffectNamed(self, name):
- effect = self.effectsDict.get(name, None)
- if effect != None:
- self.particleEffect = effect
- # Default to first particle in particlesDict
- self.particles = self.particleEffect.getParticlesList()[0]
- # See if particle effect has any forceGroup
- forceGroupList = self.particleEffect.getForceGroupList()
- if len(forceGroupList) > 0:
- self.forceGroup = forceGroupList[0]
- else:
- self.forceGroup = None
- self.mainNotebook.selectpage('System')
- self.updateInfo('System')
- else:
- print 'ParticlePanel: No effect named ' + name
- def toggleEffect(self, effect, var):
- if var.get():
- effect.enable()
- else:
- effect.disable()
- def selectParticlesNamed(self, name):
- particles = self.particleEffect.getParticlesNamed(name)
- if particles != None:
- self.particles = particles
- self.updateInfo()
- def toggleParticles(self, particles, var):
- if var.get():
- particles.enable()
- else:
- particles.disable()
- def selectForceGroupNamed(self, name):
- forceGroup = self.particleEffect.getForceGroupNamed(name)
- if forceGroup != None:
- self.forceGroup = forceGroup
- self.updateInfo('Force')
- def toggleForceGroup(self, forceGroup, var):
- if var.get():
- forceGroup.enable()
- else:
- forceGroup.disable()
- def toggleForce(self, force, pageName, variableName):
- v = self.getVariable(pageName, variableName)
- if v.get():
- force.setActive(1)
- else:
- force.setActive(0)
- def getWidget(self, category, text):
- return self.widgetDict[category + '-' + text]
- def getVariable(self, category, text):
- return self.variableDict[category + '-' + text]
- def loadParticleEffectFromFile(self):
- # Find path to particle directory
- pPath = getParticlePath()
- if pPath.getNumDirectories() > 0:
- if `pPath.getDirectory(0)` == '.':
- path = '.'
- else:
- path = pPath.getDirectory(0).toOsSpecific()
- else:
- path = '.'
- if not os.path.isdir(path):
- print 'ParticlePanel Warning: Invalid default DNA directory!'
- print 'Using current directory'
- path = '.'
- particleFilename = askopenfilename(
- defaultextension = '.ptf',
- filetypes = (('Particle Files', '*.ptf'),('All files', '*')),
- initialdir = path,
- title = 'Load Particle Effect',
- parent = self.parent)
- if particleFilename:
- # Delete existing particles and forces
- self.particleEffect.loadConfig(
- Filename.fromOsSpecific(particleFilename))
- self.selectEffectNamed(self.particleEffect.getName())
- # Enable effect
- self.particleEffect.enable()
- messenger.send('SGE_Update Explorer',[render])
- def saveParticleEffectToFile(self):
- # Find path to particle directory
- pPath = getParticlePath()
- if pPath.getNumDirectories() > 0:
- if `pPath.getDirectory(0)` == '.':
- path = '.'
- else:
- path = pPath.getDirectory(0).toOsSpecific()
- else:
- path = '.'
- if not os.path.isdir(path):
- print 'ParticlePanel Warning: Invalid default DNA directory!'
- print 'Using current directory'
- path = '.'
- particleFilename = asksaveasfilename(
- defaultextension = '.ptf',
- filetypes = (('Particle Files', '*.ptf'),('All files', '*')),
- initialdir = path,
- title = 'Save Particle Effect as',
- parent = self.parent)
- if particleFilename:
- self.particleEffect.saveConfig(Filename(particleFilename))
- ### PARTICLE EFFECTS COMMANDS ###
- def toggleParticleMgr(self):
- if self.particleMgrActive.get():
- base.enableParticles()
- else:
- base.disableParticles()
- ### PARTICLE SYSTEM COMMANDS ###
- def updateInfo(self, page = 'System'):
- self.updateMenusAndLabels()
- if page == 'System':
- self.updateSystemWidgets()
- elif page == 'Factory':
- self.selectFactoryPage()
- self.updateFactoryWidgets()
- elif page == 'Emitter':
- self.selectEmitterPage()
- self.updateEmitterWidgets()
- elif page == 'Renderer':
- self.selectRendererPage()
- self.updateRendererWidgets()
- elif page == 'Force':
- self.updateForceWidgets()
- def toggleParticleEffect(self):
- if self.getVariable('Effect', 'Active').get():
- self.particleEffect.enable()
- else:
- self.particleEffect.disable()
- ## SYSTEM PAGE ##
- def updateSystemWidgets(self):
- poolSize = self.particles.getPoolSize()
- self.getWidget('System', 'Pool Size').set(int(poolSize), 0)
- birthRate = self.particles.getBirthRate()
- self.getWidget('System', 'Birth Rate').set(birthRate, 0)
- litterSize = self.particles.getLitterSize()
- self.getWidget('System', 'Litter Size').set(int(litterSize), 0)
- litterSpread = self.particles.getLitterSpread()
- self.getWidget('System', 'Litter Spread').set(litterSpread, 0)
- systemLifespan = self.particles.getSystemLifespan()
- self.getWidget('System', 'Lifespan').set(systemLifespan, 0)
- pos = self.particles.nodePath.getPos()
- self.getWidget('System', 'Pos').set([pos[0], pos[1], pos[2]], 0)
- hpr = self.particles.nodePath.getHpr()
- self.getWidget('System', 'Hpr').set([hpr[0], hpr[1], hpr[2]], 0)
- self.getVariable('System', 'Render Space Velocities').set(
- self.particles.getLocalVelocityFlag())
- self.getVariable('System', 'System Grows Older').set(
- self.particles.getSystemGrowsOlderFlag())
- def setSystemPoolSize(self, value):
- self.particles.setPoolSize(int(value))
- def setSystemBirthRate(self, value):
- self.particles.setBirthRate(value)
- def setSystemLitterSize(self, value):
- self.particles.setLitterSize(int(value))
- def setSystemLitterSpread(self, value):
- self.particles.setLitterSpread(int(value))
- def setSystemLifespan(self, value):
- self.particles.setSystemLifespan(value)
- def toggleSystemLocalVelocity(self):
- self.particles.setLocalVelocityFlag(
- self.getVariable('System', 'Render Space Velocities').get())
- def toggleSystemGrowsOlder(self):
- self.particles.setSystemGrowsOlderFlag(
- self.getVariable('System', 'System Grows Older').get())
- def setSystemPos(self, pos):
- self.particles.nodePath.setPos(Vec3(pos[0], pos[1], pos[2]))
- def setSystemHpr(self, pos):
- self.particles.nodePath.setHpr(Vec3(pos[0], pos[1], pos[2]))
- ## FACTORY PAGE ##
- def selectFactoryType(self, type):
- self.factoryNotebook.selectpage(type)
- self.particles.setFactory(type)
- self.updateFactoryWidgets()
- def selectFactoryPage(self):
- pass
- def updateFactoryWidgets(self):
- factory = self.particles.factory
- lifespan = factory.getLifespanBase()
- self.getWidget('Factory', 'Life Span').set(lifespan, 0)
- lifespanSpread = factory.getLifespanSpread()
- self.getWidget('Factory', 'Life Span Spread').set(lifespanSpread, 0)
- mass = factory.getMassBase()
- self.getWidget('Factory', 'Mass').set(mass, 0)
- massSpread = factory.getMassSpread()
- self.getWidget('Factory', 'Mass Spread').set(massSpread, 0)
- terminalVelocity = factory.getTerminalVelocityBase()
- self.getWidget('Factory', 'Terminal Velocity').set(terminalVelocity, 0)
- terminalVelocitySpread = factory.getTerminalVelocitySpread()
- self.getWidget('Factory', 'Terminal Vel. Spread').set(
- terminalVelocitySpread, 0)
- def setFactoryLifeSpan(self, value):
- self.particles.factory.setLifespanBase(value)
- def setFactoryLifeSpanSpread(self, value):
- self.particles.factory.setLifespanSpread(value)
- def setFactoryParticleMass(self, value):
- self.particles.factory.setMassBase(value)
- def setFactoryParticleMassSpread(self, value):
- self.particles.factory.setMassSpread(value)
- def setFactoryTerminalVelocity(self, value):
- self.particles.factory.setTerminalVelocityBase(value)
- def setFactoryTerminalVelocitySpread(self, value):
- self.particles.factory.setTerminalVelocitySpread(value)
- # Point Page #
- # Z Spin Page #
- def setFactoryZSpinInitialAngle(self, angle):
- self.particles.factory.setInitialAngle(angle)
- def setFactoryZSpinInitialAngleSpread(self, spread):
- self.particles.factory.setInitialAngleSpread(spread)
- def setFactoryZSpinFinalAngle(self, angle):
- self.particles.factory.setFinalAngle(angle)
- def setFactoryZSpinFinalAngleSpread(self, spread):
- self.particles.factory.setFinalAngleSpread(spread)
- def setFactoryZSpinAngularVelocity(self, vel):
- self.particles.factory.setAngularVelocity(vel)
- def setFactoryZSpinAngularVelocitySpread(self, spread):
- self.particles.factory.setAngularVelocitySpread(spread)
- ## EMITTER PAGE ##
- def selectEmitterType(self, type):
- self.emitterNotebook.selectpage(type)
- self.particles.setEmitter(type)
- self.updateEmitterWidgets()
- def selectEmitterPage(self):
- type = self.particles.emitter.__class__.__name__
- self.emitterNotebook.selectpage(type)
- self.getVariable('Emitter', 'Emitter Type').set(type)
- def updateEmitterWidgets(self):
- emitter = self.particles.emitter
- self.setEmissionType(self.particles.emitter.getEmissionType())
- amp = emitter.getAmplitude()
- self.getWidget('Emitter', 'Velocity Multiplier').set(amp)
- spread = emitter.getAmplitudeSpread()
- self.getWidget('Emitter', 'Velocity Multiplier Spread').set(spread)
- vec = emitter.getOffsetForce()
- self.getWidget('Emitter', 'Offset Velocity').set(
- [vec[0], vec[1], vec[2]], 0)
- vec = emitter.getRadiateOrigin()
- self.getWidget('Emitter', 'Radiate Origin').set(
- [vec[0], vec[1], vec[2]], 0)
- vec = emitter.getExplicitLaunchVector()
- self.getWidget('Emitter', 'Explicit Velocity').set(
- [vec[0], vec[1], vec[2]], 0)
- if isinstance(emitter, BoxEmitter):
- min = emitter.getMinBound()
- self.getWidget('Box Emitter', 'Min').set(
- [min[0], min[1], min[2]], 0)
- max = emitter.getMaxBound()
- self.getWidget('Box Emitter', 'Max').set(
- [max[0], max[1], max[2]], 0)
- elif isinstance(emitter, DiscEmitter):
- radius = emitter.getRadius()
- self.getWidget('Disc Emitter', 'Radius').set(radius, 0)
- innerAngle = emitter.getInnerAngle()
- self.getWidget('Disc Emitter', 'Inner Angle').set(innerAngle, 0)
- innerMagnitude = emitter.getInnerMagnitude()
- self.getWidget('Disc Emitter', 'Inner Velocity').set(
- innerMagnitude, 0)
- outerAngle = emitter.getOuterAngle()
- self.getWidget('Disc Emitter', 'Outer Angle').set(outerAngle, 0)
- outerMagnitude = emitter.getOuterMagnitude()
- self.getWidget('Disc Emitter', 'Inner Velocity').set(
- outerMagnitude, 0)
- cubicLerping = emitter.getCubicLerping()
- self.getVariable('Disc Emitter', 'Cubic Lerping').set(cubicLerping)
- elif isinstance(emitter, LineEmitter):
- min = emitter.getEndpoint1()
- self.getWidget('Line Emitter', 'Min').set(
- [min[0], min[1], min[2]], 0)
- max = emitter.getEndpoint2()
- self.getWidget('Line Emitter', 'Max').set(
- [max[0], max[1], max[2]], 0)
- elif isinstance(emitter, PointEmitter):
- location = emitter.getLocation()
- self.getWidget('Point Emitter', 'Position').set(
- [location[0], location[1], location[2]], 0)
- elif isinstance(emitter, RectangleEmitter):
- min = emitter.getMinBound()
- self.getWidget('Rectangle Emitter', 'Min').set(
- [min[0], min[1]], 0)
- max = emitter.getMaxBound()
- self.getWidget('Rectangle Emitter', 'Max').set(
- [max[0], max[1]], 0)
- elif isinstance(emitter, RingEmitter):
- radius = emitter.getRadius()
- self.getWidget('Ring Emitter', 'Radius').set(radius, 0)
- angle = emitter.getAngle()
- self.getWidget('Ring Emitter', 'Angle').set(angle, 0)
- elif isinstance(emitter, SphereVolumeEmitter):
- radius = emitter.getRadius()
- self.getWidget('Sphere Volume Emitter', 'Radius').set(radius, 0)
- elif isinstance(emitter, SphereSurfaceEmitter):
- radius = emitter.getRadius()
- self.getWidget('Sphere Surface Emitter', 'Radius').set(radius, 0)
- elif isinstance(emitter, TangentRingEmitter):
- radius = emitter.getRadius()
- self.getWidget('Tangent Ring Emitter', 'Radius').set(radius, 0)
- # All #
- def setEmissionType(self, newType = None):
- if newType:
- type = newType
- self.emissionType.set(type)
- else:
- type = self.emissionType.get()
- self.particles.emitter.setEmissionType(type)
- if type == BaseParticleEmitter.ETEXPLICIT:
- self.getWidget(
- 'Emitter', 'Radiate Origin')['state'] = 'disabled'
- self.getWidget(
- 'Emitter', 'Explicit Velocity')['state'] = 'normal'
- # Hide custom widgets
- if isinstance(self.particles.emitter, DiscEmitter):
- self.discCustomFrame.pack_forget()
- elif isinstance(self.particles.emitter, RingEmitter):
- self.ringCustomFrame.pack_forget()
- elif type == BaseParticleEmitter.ETRADIATE:
- self.getWidget(
- 'Emitter', 'Radiate Origin')['state'] = 'normal'
- self.getWidget(
- 'Emitter', 'Explicit Velocity')['state'] = 'disabled'
- # Hide custom widgets
- if isinstance(self.particles.emitter, DiscEmitter):
- self.discCustomFrame.pack_forget()
- elif isinstance(self.particles.emitter, RingEmitter):
- self.ringCustomFrame.pack_forget()
- elif type == BaseParticleEmitter.ETCUSTOM:
- self.getWidget(
- 'Emitter', 'Radiate Origin')['state'] = 'disabled'
- self.getWidget(
- 'Emitter', 'Explicit Velocity')['state'] = 'disabled'
- # Show custom widgets
- if isinstance(self.particles.emitter, DiscEmitter):
- self.discCustomFrame.pack(fill = BOTH, expand = 1)
- elif isinstance(self.particles.emitter, RingEmitter):
- self.ringCustomFrame.pack(fill = BOTH, expand = 1)
- def setEmitterAmplitude(self, value):
- self.particles.emitter.setAmplitude(value)
- def setEmitterAmplitudeSpread(self, value):
- self.particles.emitter.setAmplitudeSpread(value)
- def setEmitterOffsetForce(self, vec):
- self.particles.emitter.setOffsetForce(
- Vec3(vec[0], vec[1], vec[2]))
- def setEmitterRadiateOrigin(self, origin):
- self.particles.emitter.setRadiateOrigin(
- Point3(origin[0], origin[1], origin[2]))
- def setEmitterExplicitLaunchVector(self, vec):
- self.particles.emitter.setExplicitLaunchVector(
- Vec3(vec[0], vec[1], vec[2]))
- # Box #
- def setEmitterBoxPoint1(self, point):
- self.particles.emitter.setMinBound(Point3(point[0],
- point[1],
- point[2]))
- def setEmitterBoxPoint2(self, point):
- self.particles.emitter.setMaxBound(Point3(point[0],
- point[1],
- point[2]))
- # Disc #
- def setEmitterDiscRadius(self, radius):
- self.particles.emitter.setRadius(radius)
- def setEmitterDiscInnerAngle(self, angle):
- self.particles.emitter.setInnerAngle(angle)
- def setEmitterDiscInnerVelocity(self, velocity):
- self.particles.emitter.setInnerMagnitude(velocity)
- def setEmitterDiscOuterAngle(self, angle):
- self.particles.emitter.setOuterAngle(angle)
- def setEmitterDiscOuterVelocity(self, velocity):
- self.particles.emitter.setOuterMagnitude(velocity)
- def toggleEmitterDiscCubicLerping(self):
- self.particles.emitter.setCubicLerping(
- self.getVariable('Disc Emitter', 'Cubic Lerping').get())
- # Line #
- def setEmitterLinePoint1(self, point):
- self.particles.emitter.setEndpoint1(Point3(point[0],
- point[1],
- point[2]))
- def setEmitterLinePoint2(self, point):
- self.particles.emitter.setEndpoint2(Point3(point[0],
- point[1],
- point[2]))
- # Point #
- def setEmitterPointPosition(self, pos):
- self.particles.emitter.setLocation(Point3(pos[0], pos[1], pos[2]))
- # Rectangle #
- def setEmitterRectanglePoint1(self, point):
- self.particles.emitter.setMinBound(Point2(point[0], point[1]))
- def setEmitterRectanglePoint2(self, point):
- self.particles.emitter.setMaxBound(Point2(point[0], point[1]))
- # Ring #
- def setEmitterRingRadius(self, radius):
- self.particles.emitter.setRadius(radius)
- def setEmitterRingLaunchAngle(self, angle):
- self.particles.emitter.setAngle(angle)
- # Sphere surface #
- def setEmitterSphereSurfaceRadius(self, radius):
- self.particles.emitter.setRadius(radius)
- # Sphere volume #
- def setEmitterSphereVolumeRadius(self, radius):
- self.particles.emitter.setRadius(radius)
- # Tangent ring #
- def setEmitterTangentRingRadius(self, radius):
- self.particles.emitter.setRadius(radius)
- ## RENDERER PAGE ##
- def selectRendererType(self, type):
- self.rendererNotebook.selectpage(type)
- self.particles.setRenderer(type)
- self.updateRendererWidgets()
- def updateRendererWidgets(self):
- renderer = self.particles.renderer
- alphaMode = renderer.getAlphaMode()
- if alphaMode == BaseParticleRenderer.PRALPHANONE:
- aMode = 'NO_ALPHA'
- elif alphaMode == BaseParticleRenderer.PRALPHAOUT:
- aMode = 'ALPHA_OUT'
- elif alphaMode == BaseParticleRenderer.PRALPHAIN:
- aMode = 'ALPHA_IN'
- elif alphaMode == BaseParticleRenderer.PRALPHAUSER:
- aMode = 'ALPHA_USER'
- self.getVariable('Renderer', 'Alpha Mode').set(aMode)
- userAlpha = renderer.getUserAlpha()
- self.getWidget('Renderer', 'User Alpha').set(userAlpha)
- if isinstance(renderer, LineParticleRenderer):
- headColor = renderer.getHeadColor() * 255.0
- self.getWidget('Line Renderer', 'Head Color').set(
- [headColor[0], headColor[1], headColor[2], headColor[3]])
- tailColor = renderer.getTailColor() * 255.0
- self.getWidget('Line Renderer', 'Tail Color').set(
- [tailColor[0], tailColor[1], tailColor[2], tailColor[3]])
- elif isinstance(renderer, GeomParticleRenderer):
- pass
- elif isinstance(renderer, PointParticleRenderer):
- pointSize = renderer.getPointSize()
- self.getWidget('Point Renderer', 'Point Size').set(pointSize)
- startColor = renderer.getStartColor() * 255.0
- self.getWidget('Point Renderer', 'Start Color').set(
- [startColor[0], startColor[1], startColor[2], startColor[3]])
- endColor = renderer.getEndColor() * 255.0
- self.getWidget('Point Renderer', 'End Color').set(
- [endColor[0], endColor[1], endColor[2], endColor[3]])
- blendType = renderer.getBlendType()
- if (blendType == PointParticleRenderer.PPONECOLOR):
- bType = "PP_ONE_COLOR"
- elif (blendType == PointParticleRenderer.PPBLENDLIFE):
- bType = "PP_BLEND_LIFE"
- elif (blendType == PointParticleRenderer.PPBLENDVEL):
- bType = "PP_BLEND_VEL"
- self.getVariable('Point Renderer', 'Blend Type').set(bType)
- blendMethod = renderer.getBlendMethod()
- bMethod = "PP_NO_BLEND"
- if (blendMethod == BaseParticleRenderer.PPNOBLEND):
- bMethod = "PP_NO_BLEND"
- elif (blendMethod == BaseParticleRenderer.PPBLENDLINEAR):
- bMethod = "PP_BLEND_LINEAR"
- elif (blendMethod == BaseParticleRenderer.PPBLENDCUBIC):
- bMethod = "PP_BLEND_CUBIC"
- self.getVariable('Point Renderer', 'Blend Method').set(bMethod)
- elif isinstance(renderer, SparkleParticleRenderer):
- centerColor = renderer.getCenterColor() * 255.0
- self.getWidget('Sparkle Renderer', 'Center Color').set(
- [centerColor[0], centerColor[1],
- centerColor[2], centerColor[3]])
- edgeColor = renderer.getEdgeColor() * 255.0
- self.getWidget('Sparkle Renderer', 'Edge Color').set(
- [edgeColor[0], edgeColor[1], edgeColor[2], edgeColor[3]])
- birthRadius = renderer.getBirthRadius()
- self.getWidget('Sparkle Renderer', 'Birth Radius').set(birthRadius)
- deathRadius = renderer.getDeathRadius()
- self.getWidget('Sparkle Renderer', 'Death Radius').set(deathRadius)
- lifeScale = renderer.getLifeScale()
- lScale = "SP_NO_SCALE"
- if (lifeScale == SparkleParticleRenderer.SPSCALE):
- lScale = "SP_SCALE"
- self.getVariable('Sparkle Renderer', 'Life Scale').set(lScale)
- elif isinstance(renderer, SpriteParticleRenderer):
- color = renderer.getColor() * 255.0
- # Update widgets to reflect current default values
- # Texture
- textureName = renderer.getSourceTextureName()
- if textureName != None:
- self.rendererSpriteTexture.set(textureName)
- # File
- fileName = renderer.getSourceFileName()
- if fileName != None:
- self.rendererSpriteFile.set(fileName)
- # Node
- nodeName = renderer.getSourceNodeName()
- if nodeName != None:
- self.rendererSpriteNode.set(nodeName)
- self.getVariable('Sprite Renderer', 'X Scale').set(
- renderer.getXScaleFlag())
- self.getVariable('Sprite Renderer', 'Y Scale').set(
- renderer.getYScaleFlag())
- self.getVariable('Sprite Renderer', 'Anim Angle').set(
- renderer.getAnimAngleFlag())
- initialXScale = renderer.getInitialXScale()
- self.getWidget('Sprite Renderer', 'Initial X Scale').set(
- initialXScale)
- initialYScale = renderer.getInitialYScale()
- self.getWidget('Sprite Renderer', 'Initial Y Scale').set(
- initialYScale)
- finalXScale = renderer.getFinalXScale()
- self.getWidget('Sprite Renderer', 'Final X Scale').set(
- finalXScale)
- finalYScale = renderer.getFinalYScale()
- self.getWidget('Sprite Renderer', 'Final Y Scale').set(
- finalYScale)
- nonanimatedTheta = renderer.getNonanimatedTheta()
- self.getWidget('Sprite Renderer', 'Non Animated Theta').set(
- nonanimatedTheta)
- blendMethod = renderer.getAlphaBlendMethod()
- bMethod = "PP_NO_BLEND"
- if (blendMethod == BaseParticleRenderer.PPNOBLEND):
- bMethod = "PP_NO_BLEND"
- elif (blendMethod == BaseParticleRenderer.PPBLENDLINEAR):
- bMethod = "PP_BLEND_LINEAR"
- elif (blendMethod == BaseParticleRenderer.PPBLENDCUBIC):
- bMethod = "PP_BLEND_CUBIC"
- self.getVariable('Sprite Renderer', 'Alpha Disable').set(
- renderer.getAlphaDisable())
- def selectRendererPage(self):
- type = self.particles.renderer.__class__.__name__
- self.rendererNotebook.selectpage(type)
- self.getVariable('Renderer', 'Renderer Type').set(type)
- # All #
- def setRendererAlphaMode(self, alphaMode):
- if alphaMode == 'NO_ALPHA':
- aMode = BaseParticleRenderer.PRALPHANONE
- elif alphaMode == 'ALPHA_OUT':
- aMode = BaseParticleRenderer.PRALPHAOUT
- elif alphaMode == 'ALPHA_IN':
- aMode = BaseParticleRenderer.PRALPHAIN
- elif alphaMode == 'ALPHA_USER':
- aMode = BaseParticleRenderer.PRALPHAUSER
- self.particles.renderer.setAlphaMode(aMode)
- def setRendererUserAlpha(self, alpha):
- self.particles.renderer.setUserAlpha(alpha)
- # Line #
- def setRendererLineHeadColor(self, color):
- self.particles.renderer.setHeadColor(
- Vec4(color[0]/255.0, color[1]/255.0,
- color[2]/255.0, color[3]/255.0))
- def setRendererLineTailColor(self, color):
- self.particles.renderer.setTailColor(
- Vec4(color[0]/255.0, color[1]/255.0,
- color[2]/255.0, color[3]/255.0))
- # Geom #
- def setRendererGeomNode(self, event):
- node = None
- nodePath = loader.loadModel(self.rendererGeomNode.get())
- if nodePath != None:
- node = nodePath.node()
- if (node != None):
- self.particles.renderer.setGeomNode(node)
- # Point #
- def setRendererPointSize(self, size):
- self.particles.renderer.setPointSize(size)
- def setRendererPointStartColor(self, color):
- self.particles.renderer.setStartColor(
- Vec4(color[0]/255.0, color[1]/255.0,
- color[2]/255.0, color[3]/255.0))
- def setRendererPointEndColor(self, color):
- self.particles.renderer.setEndColor(
- Vec4(color[0]/255.0, color[1]/255.0,
- color[2]/255.0, color[3]/255.0))
- def rendererPointSelectBlendType(self, blendType):
- if blendType == "PP_ONE_COLOR":
- bType = PointParticleRenderer.PPONECOLOR
- elif blendType == "PP_BLEND_LIFE":
- bType = PointParticleRenderer.PPBLENDLIFE
- elif blendType == "PP_BLEND_VEL":
- bType = PointParticleRenderer.PPBLENDVEL
- self.particles.renderer.setBlendType(bType)
- def rendererPointSelectBlendMethod(self, blendMethod):
- if blendMethod == "PP_NO_BLEND":
- bMethod = BaseParticleRenderer.PPNOBLEND
- elif blendMethod == "PP_BLEND_LINEAR":
- bMethod = BaseParticleRenderer.PPBLENDLINEAR
- elif blendMethod == "PP_BLEND_CUBIC":
- bMethod = BaseParticleRenderer.PPBLENDCUBIC
- self.particles.renderer.setBlendMethod(bMethod)
- # Sparkle #
- def setRendererSparkleCenterColor(self, color):
- self.particles.renderer.setCenterColor(
- Vec4(color[0]/255.0, color[1]/255.0,
- color[2]/255.0, color[3]/255.0))
- def setRendererSparkleEdgeColor(self, color):
- self.particles.renderer.setEdgeColor(
- Vec4(color[0]/255.0, color[1]/255.0,
- color[2]/255.0, color[3]/255.0))
- def setRendererSparkleBirthRadius(self, radius):
- self.particles.renderer.setBirthRadius(radius)
- def setRendererSparkleDeathRadius(self, radius):
- self.particles.renderer.setDeathRadius(radius)
- def setRendererSparkleLifeScale(self, lifeScaleMethod):
- if lifeScaleMethod == 'SP_NO_SCALE':
- lScale = SparkleParticleRenderer.SPNOSCALE
- else:
- lScale = SparkleParticleRenderer.SPSCALE
- self.particles.renderer.setLifeScale(lScale)
- # Sprite #
- def setSpriteSourceType(self):
- if self.rendererSpriteSourceType.get() == SpriteParticleRenderer.STTexture:
- self.rendererSpriteTextureEntry['state'] = 'normal'
- self.rendererSpriteFileEntry['state'] = 'disabled'
- self.rendererSpriteNodeEntry['state'] = 'disabled'
- self.rendererSpriteTextureEntry['background'] = '#FFFFFF'
- self.rendererSpriteFileEntry['background'] = '#C0C0C0'
- self.rendererSpriteNodeEntry['background'] = '#C0C0C0'
- else:
- self.rendererSpriteTextureEntry['state'] = 'disabled'
- self.rendererSpriteFileEntry['state'] = 'normal'
- self.rendererSpriteNodeEntry['state'] = 'normal'
- self.rendererSpriteTextureEntry['background'] = '#C0C0C0'
- self.rendererSpriteFileEntry['background'] = '#FFFFFF'
- self.rendererSpriteNodeEntry['background'] = '#FFFFFF'
- def setRendererSpriteTexture(self):
- if self.rendererSpriteSourceType.get() == SpriteParticleRenderer.STTexture:
- self.particles.renderer.setTextureFromFile(self.rendererSpriteTexture.get())
- else:
- self.particles.renderer.setTextureFromNode(
- self.rendererSpriteFile.get(), self.rendererSpriteNode.get())
- def toggleRendererSpriteXScale(self):
- self.particles.renderer.setXScaleFlag(
- self.getVariable('Sprite Renderer', 'X Scale').get())
- def toggleRendererSpriteYScale(self):
- self.particles.renderer.setYScaleFlag(
- self.getVariable('Sprite Renderer', 'Y Scale').get())
- def toggleRendererSpriteAnimAngle(self):
- self.particles.renderer.setAnimAngleFlag(
- self.getVariable('Sprite Renderer', 'Anim Angle').get())
- def toggleAngularVelocity(self):
- self.particles.factory.enableAngularVelocity(
- self.getVariable('Z Spin Factory', 'Enable Angular Velocity').get())
- def setRendererSpriteInitialXScale(self, xScale):
- self.particles.renderer.setInitialXScale(xScale)
- def setRendererSpriteFinalXScale(self, xScale):
- self.particles.renderer.setFinalXScale(xScale)
- def setRendererSpriteInitialYScale(self, yScale):
- self.particles.renderer.setInitialYScale(yScale)
- def setRendererSpriteFinalYScale(self, yScale):
- self.particles.renderer.setFinalYScale(yScale)
- def setRendererSpriteNonAnimatedTheta(self, theta):
- self.particles.renderer.setNonanimatedTheta(theta)
- def setRendererSpriteBlendMethod(self, blendMethod):
- print blendMethod
- if blendMethod == 'PP_NO_BLEND':
- bMethod = BaseParticleRenderer.PPNOBLEND
- elif blendMethod == 'PP_BLEND_LINEAR':
- bMethod = BaseParticleRenderer.PPBLENDLINEAR
- elif blendMethod == 'PP_BLEND_CUBIC':
- bMethod = BaseParticleRenderer.PPBLENDCUBIC
- else:
- bMethod = BaseParticleRenderer.PPNOBLEND
- self.particles.renderer.setAlphaBlendMethod(bMethod)
- def toggleRendererSpriteAlphaDisable(self):
- self.particles.renderer.setAlphaDisable(
- self.getVariable('Sprite Renderer', 'Alpha Disable').get())
- ## FORCEGROUP COMMANDS ##
- def updateForceWidgets(self):
- # Select appropriate notebook page
- if self.forceGroup != None:
- self.forceGroupNotebook.pack(fill = X)
- self.forcePageName = (self.particleEffect.getName() + '-' +
- self.forceGroup.getName())
- self.forcePage = self.forcePagesDict.get(
- self.forcePageName, None)
- # Page doesn't exist, add it
- if self.forcePage == None:
- self.addForceGroupNotebookPage(
- self.particleEffect, self.forceGroup)
- self.forceGroupNotebook.selectpage(self.forcePageName)
- else:
- self.forceGroupNotebook.pack_forget()
- def addLinearVectorForce(self):
- self.addForce(LinearVectorForce())
- def addLinearFrictionForce(self):
- self.addForce(LinearFrictionForce())
- def addLinearJitterForce(self):
- self.addForce(LinearJitterForce())
- def addLinearNoiseForce(self):
- self.addForce(LinearNoiseForce())
- def addLinearSinkForce(self):
- self.addForce(LinearSinkForce())
- def addLinearSourceForce(self):
- self.addForce(LinearSourceForce())
- def addLinearCylinderVortexForce(self):
- self.addForce(LinearCylinderVortexForce())
- def addLinearUserDefinedForce(self):
- self.addForce(LinearUserDefinedForce())
- def addForce(self, f):
- if self.forceGroup == None:
- self.createNewForceGroup()
- self.forceGroup.addForce(f)
- self.addForceWidget(self.forceGroup,f)
- ## SYSTEM COMMANDS ##
- def createNewEffect(self):
- name = askstring('Particle Panel', 'Effect Name:',
- parent = self.parent)
- if name:
- particles = seParticles.Particles()
- particles.setBirthRate(0.02)
- particles.setLitterSize(10)
- particles.setLitterSpread(0)
- particles.setFactory("PointParticleFactory")
- particles.setRenderer("PointParticleRenderer")
- particles.setEmitter("SphereVolumeEmitter")
- particles.enable()
- effect = seParticleEffect.ParticleEffect(name,particles)
- self.effectsDict[name] = effect
- self.updateMenusAndLabels()
- self.selectEffectNamed(name)
- self.emitter=loader.loadModel("sphere")
- self.emitter.setName(name)
- effect.reparentTo(self.emitter)
- self.emitter.reparentTo(render)
- effect.enable()
- messenger.send('ParticlePanel_Added_Effect',[name,effect,self.emitter])
- messenger.send('SGE_Update Explorer',[render])
- def createNewParticles(self):
- name = askstring('Particle Panel', 'Particles Name:',
- parent = self.parent)
- if name:
- p = seParticles.Particles(name)
- p.setBirthRate(0.02)
- p.setLitterSize(10)
- p.setLitterSpread(0)
- p.setFactory("PointParticleFactory")
- p.setRenderer("PointParticleRenderer")
- p.setEmitter("SphereVolumeEmitter")
- self.particleEffect.addParticles(p)
- self.updateParticlesMenus()
- self.selectParticlesNamed(name)
- p.enable()
- def createNewForceGroup(self):
- name = askstring('Particle Panel', 'ForceGroup Name:',
- parent = self.parent)
- if name:
- forceGroup = seForceGroup.ForceGroup(name)
- self.particleEffect.addForceGroup(forceGroup)
- self.updateForceGroupMenus()
- self.addForceGroupNotebookPage(self.particleEffect, forceGroup)
- self.selectForceGroupNamed(name)
- forceGroup.enable()
- def addForceGroupNotebookPage(self, particleEffect, forceGroup):
- self.forcePageName = (particleEffect.getName() + '-' +
- forceGroup.getName())
- self.forcePage = self.forceGroupNotebook.add(self.forcePageName)
- self.forcePagesDict[self.forcePageName] = self.forcePage
- for force in forceGroup:
- self.addForceWidget(forceGroup, force)
- def addForceWidget(self, forceGroup, force):
- forcePage = self.forcePage
- pageName = self.forcePageName
- # How many forces of the same type in the force group object
- count = 0
- for f in forceGroup:
- if f.getClassType().eq(force.getClassType()):
- count += 1
- if isinstance(force, LinearVectorForce):
- self.createLinearVectorForceWidget(
- forcePage, pageName, count, force)
- elif isinstance(force, LinearNoiseForce):
- self.createLinearRandomForceWidget(
- forcePage, pageName, count, force, 'Noise')
- elif isinstance(force, LinearJitterForce):
- self.createLinearRandomForceWidget(
- forcePage, pageName, count, force, 'Jitter')
- elif isinstance(force, LinearFrictionForce):
- self.createLinearFrictionForceWidget(
- forcePage, pageName, count, force)
- elif isinstance(force, LinearCylinderVortexForce):
- self.createLinearCylinderVortexForceWidget(
- forcePage, pageName, count, force)
- elif isinstance(force, LinearSinkForce):
- self.createLinearDistanceForceWidget(
- forcePage, pageName, count, force, 'Sink')
- elif isinstance(force, LinearSourceForce):
- self.createLinearDistanceForceWidget(
- forcePage, pageName, count, force, 'Source')
- elif isinstance(force, LinearUserDefinedForce):
- # Nothing
- pass
- self.forceGroupNotebook.setnaturalsize()
- def createForceFrame(self, forcePage, forceName, force):
- frame = Frame(forcePage, relief = RAISED, borderwidth = 2)
- lFrame = Frame(frame, relief = FLAT)
- def removeForce(s = self, f = force, fr = frame):
- s.forceGroup.removeForce(f)
- fr.pack_forget()
- b = Button(lFrame, text = 'X',
- command = removeForce)
- b.pack(side = 'right', expand = 0)
- Label(lFrame, text = forceName,
- foreground = 'Blue',
- font=('MSSansSerif', 12, 'bold'),
- ).pack(expand = 1, fill = 'x')
- lFrame.pack(fill = 'x', expand =1)
- frame.pack(pady = 3, fill = 'x', expand =0)
- return frame
- def createLinearForceWidgets(self, frame, pageName, forceName, force):
- def setAmplitude(amp, f = force):
- f.setAmplitude(amp)
- def toggleMassDependent(s=self, f=force, p=pageName, n=forceName):
- v = s.getVariable(p, n+' Mass Dependent')
- f.setMassDependent(v.get())
- def setVectorMasks(s=self, f=force, p=pageName, n=forceName):
- xMask = s.getVariable(p, n+' Mask X').get()
- yMask = s.getVariable(p, n+' Mask Y').get()
- zMask = s.getVariable(p, n+' Mask Z').get()
- f.setVectorMasks(xMask, yMask, zMask)
- self.createFloater(frame, pageName, forceName + ' Amplitude',
- 'Force amplitude multiplier',
- command = setAmplitude,
- value = force.getAmplitude())
- cbf = Frame(frame, relief = FLAT)
- self.createCheckbutton(cbf, pageName, forceName + ' Mass Dependent',
- ('On: force depends on mass; ' +
- 'Off: force does not depend on mass'),
- toggleMassDependent,
- force.getMassDependent())
- self.createCheckbutton(cbf, pageName, forceName + ' Mask X',
- 'On: enable force along X axis',
- setVectorMasks, 1)
- self.createCheckbutton(cbf, pageName, forceName + ' Mask Y',
- 'On: enable force along X axis',
- setVectorMasks, 1)
- self.createCheckbutton(cbf, pageName, forceName + ' Mask Z',
- 'On: enable force along X axis',
- setVectorMasks, 1)
- cbf.pack(fill = 'x', expand = 0)
- def createForceActiveWidget(self, frame, pageName, forceName, force):
- cbName = forceName + ' Active'
- def toggle(s = self, f = force, p = pageName, n = cbName):
- s.toggleForce(f, p, n)
- self.createCheckbutton(frame, pageName, cbName,
- 'On: force is enabled; Off: force is disabled',
- toggle, 1)
- def createLinearVectorForceWidget(self, forcePage, pageName,
- count, force):
- def setVec(vec, f = force):
- f.setVector(vec[0], vec[1], vec[2])
- forceName = 'Vector Force-' + `count`
- frame = self.createForceFrame(forcePage, forceName, force)
- self.createLinearForceWidgets(frame, pageName, forceName, force)
- vec = force.getLocalVector()
- self.createVector3Entry(frame, pageName, forceName,
- 'Set force direction and magnitude',
- command = setVec,
- value = [vec[0], vec[1], vec[2]])
- self.createForceActiveWidget(frame, pageName, forceName, force)
- def createLinearRandomForceWidget(self, forcePage, pageName, count,
- force, type):
- forceName = type + ' Force-' + `count`
- frame = self.createForceFrame(forcePage, forceName, force)
- self.createLinearForceWidgets(frame, pageName, forceName, force)
- self.createForceActiveWidget(frame, pageName, forceName, force)
- def createLinearFrictionForceWidget(self, forcePage, pageName,
- count, force):
- def setCoef(coef, f = force):
- f.setCoef(coef)
- forceName = 'Friction Force-' + `count`
- frame = self.createForceFrame(forcePage, forceName, force)
- self.createLinearForceWidgets(frame, pageName, forceName, force)
- self.createFloater(frame, pageName, forceName + ' Coef',
- 'Set linear friction force',
- command = setCoef, min = None,
- value = force.getCoef())
- self.createForceActiveWidget(frame, pageName, forceName, force)
- def createLinearCylinderVortexForceWidget(self, forcePage, pageName,
- count, force):
- forceName = 'Vortex Force-' + `count`
- def setCoef(coef, f = force):
- f.setCoef(coef)
- def setLength(length, f = force):
- f.setLength(length)
- def setRadius(radius, f = force):
- f.setRadius(radius)
- frame = self.createForceFrame(forcePage, forceName, force)
- self.createLinearForceWidgets(frame, pageName, forceName, force)
- self.createFloater(frame, pageName, forceName + ' Coef',
- 'Set linear cylinder vortex coefficient',
- command = setCoef,
- value = force.getCoef())
- self.createFloater(frame, pageName, forceName + ' Length',
- 'Set linear cylinder vortex length',
- command = setLength,
- value = force.getLength())
- self.createFloater(frame, pageName, forceName + ' Radius',
- 'Set linear cylinder vortex radius',
- command = setRadius,
- value = force.getRadius())
- self.createForceActiveWidget(frame, pageName, forceName, force)
- def createLinearDistanceForceWidget(self, forcePage, pageName,
- count, force, type):
- def setFalloffType(type, f=force):
- if type == 'FT_ONE_OVER_R':
- #f.setFalloffType(LinearDistanceForce.FTONEOVERR)
- f.setFalloffType(0)
- if type == 'FT_ONE_OVER_R_SQUARED':
- #f.setFalloffType(LinearDistanceForce.FTONEOVERRSQUARED)
- f.setFalloffType(1)
- if type == 'FT_ONE_OVER_R_CUBED':
- #f.setFalloffType(LinearDistanceForce.FTONEOVERRCUBED)
- f.setFalloffType(2)
- def setForceCenter(vec, f = force):
- f.setForceCenter(Point3(vec[0], vec[1], vec[2]))
- def setRadius(radius, f = force):
- f.setRadius(radius)
- forceName = type + ' Force-' + `count`
- frame = self.createForceFrame(forcePage, forceName, force)
- self.createLinearForceWidgets(frame, pageName, forceName, force)
- var = self.createOptionMenu(
- frame, pageName, forceName + ' Falloff',
- 'Set force falloff type',
- ('FT_ONE_OVER_R',
- 'FT_ONE_OVER_R_SQUARED',
- 'FT_ONE_OVER_R_CUBED'),
- command = setFalloffType)
- self.getWidget(pageName, forceName + ' Falloff').configure(
- label_width = 16)
- falloff = force.getFalloffType()
- if falloff == LinearDistanceForce.FTONEOVERR:
- var.set('FT_ONE_OVER_R')
- elif falloff == LinearDistanceForce.FTONEOVERRSQUARED:
- var.set('FT_ONE_OVER_R_SQUARED')
- elif falloff == LinearDistanceForce.FTONEOVERRCUBED:
- var.set('FT_ONE_OVER_R_CUBED')
- vec = force.getForceCenter()
- self.createVector3Entry(frame, pageName, forceName + ' Center',
- 'Set center of force',
- command = setForceCenter,
- label_width = 16,
- value = [vec[0], vec[1], vec[2]])
- self.createFloater(frame, pageName, forceName + ' Radius',
- 'Set falloff radius',
- command = setRadius,
- min = 0.01,
- value = force.getRadius())
- self.createForceActiveWidget(frame, pageName, forceName, force)
- ######################################################################
- # Create demo in root window for testing.
- if __name__ == '__main__':
- root = Pmw.initialise()
- pp = ParticlePanel()
- #ve = VectorEntry(Toplevel(), relief = GROOVE)
- #ve.pack()
|