"PANDA3D Particle Panel" # Import Tkinter, Pmw, and the floater code from this directory tree. from Tkinter import * import Pmw import Dial import Floater import VectorWidgets class ParticlePanel(Pmw.MegaToplevel): def __init__(self, parent = None, **kw): INITOPT = Pmw.INITOPT optiondefs = ( ('title', 'Particle Panel', None), ) self.defineoptions(kw, optiondefs) Pmw.MegaToplevel.__init__(self, parent, title = self['title']) # Handle to the toplevels hull hull = self.component('hull') balloon = self.balloon = Pmw.Balloon(hull) # Start with balloon help disabled self.balloon.configure(state = 'none') menuFrame = Frame(hull, relief = GROOVE, bd = 2) menuFrame.pack(fill = X, expand = 1) menuBar = Pmw.MenuBar(menuFrame, hotkeys = 1, balloon = balloon) menuBar.pack(side = LEFT, expand = 1, fill = X) menuBar.addmenu('Particles', 'Particle Panel Operations') menuBar.addmenuitem('Particles', 'command', 'Exit Particles Panel', label = 'Exit', command = self.destroy) menuBar.addmenu('Help', 'Particle Panel Help Operations') self.toggleBalloonVar = IntVar() self.toggleBalloonVar.set(0) menuBar.addmenuitem('Help', 'checkbutton', 'Toggle balloon help', label = 'Balloon Help', variable = self.toggleBalloonVar, command = self.toggleBalloon) self.systemSelector = Pmw.ComboBox(menuFrame, labelpos = W, label_text = 'Particle System:', entry_width = 16, selectioncommand = self.selectSystemNamed, scrolledlist_items = ('system 0',)) self.systemSelector.selectitem('system 0') self.systemSelector.pack(side = 'left', expand = 0) # Create the notebook pages notebook = Pmw.NoteBook(hull) notebook.pack(fill = BOTH, expand = 1) systemPage = notebook.add('System') factoryPage = notebook.add('Factory') emitterPage = notebook.add('Emitter') rendererPage = notebook.add('Renderer') # System page systemWidgets = ( ('Pool size', 'Size of particle pool', 0.0, 1.0), ('Birth rate', 'Seconds between particle births', 0.0, None), ('Litter size', 'Number of particle created at each birth', 1.0, 1.0), ('Litter spread', 'Variation in litter size', 0.0, 1.0), ('System lifespan', 'Age in seconds at which system should die', 0.0, None) ) self.createFloaters(systemPage, systemWidgets) Checkbutton(systemPage, text = 'Local velocity',anchor = W).pack( fill = X) Checkbutton(systemPage, text = 'System grows older',anchor = W).pack( fill = X) pos = self.createVector3Entry(systemPage, 'Pos', 'Particle system position') pos.addMenuItem('Popup 3DoF Panel') hpr = self.createVector3Entry(systemPage, 'Hpr', 'Particle system orientation', floaterGroup_labels = ('H', 'P', 'R')) hpr.addMenuItem('Popup 3DoF Panel') # FACTORY PAGE self.createOptionMenu(factoryPage, 'Factory type:', 'Select type of particle factory', ('Point', 'Z Spin', 'Oriented'), self.selectFactoryType) factoryWidgets = ( ('Life span', 'Average lifespan in seconds', 0.0, None), ('Life span spread', 'Variation in lifespan', 0.0, None), ('Mass', 'Average particle mass', 0.0, None), ('Mass spread', 'Variation in particle mass', 0.0, None), ('Terminal velocity', 'Average particle terminal velocity', 0.0, None), ('Terminal vel. spread', 'Variation in terminal velocity', 0.0, None)) self.createFloaters(factoryPage, factoryWidgets) self.factoryNotebook = Pmw.NoteBook(factoryPage, tabpos = None) pointPage = self.factoryNotebook.add('Point') zSpinPage = self.factoryNotebook.add('Z Spin') self.createAngleDial(zSpinPage, 'Initial angle', 'Starting angle in degrees') self.createAngleDial(zSpinPage, 'Final angle', 'Final angle in degrees') self.createAngleDial(zSpinPage, 'Angle spread', 'Spread of the final angle') orientedPage = self.factoryNotebook.add('Oriented') Label(orientedPage, text = 'Not implemented').pack(expand = 1, fill = BOTH) self.factoryNotebook.pack(expand = 1, fill = BOTH) # EMITTER PAGE self.createOptionMenu(emitterPage, 'Emitter type:', 'Select type of particle emitter', ('Box', 'Disc', 'Line', 'Point', 'Rectangle', 'Ring', 'Sphere Surface', 'Sphere Volume', 'Tangent Ring'), self.selectEmitterType) self.emitterNotebook = Pmw.NoteBook(emitterPage, tabpos = None) pointPage = self.emitterNotebook.add('Box') self.createVector3Entry(pointPage, 'Point 1', 'Point defining emitter box') self.createVector3Entry(pointPage, 'Point 2', 'Point defining emitter box', initialValue = (1.0, 1.0, 1.0)) self.createVector3Entry(pointPage, 'Launch vector', 'Initial particle velocity vector') discPage = self.emitterNotebook.add('Disc') self.createFloater(discPage, 'Radius', 'Radius of disc') self.createAngleDial(discPage, 'Inner angle', 'Particle launch angle at center of disc') self.createFloater(discPage, 'Inner magnitude', 'Launch velocity multiplier at center of disc') self.createAngleDial(discPage, 'Outer angle', 'Particle launch angle at outer edge of disc') self.createFloater(discPage, 'Outer magnitude', 'Launch velocity multiplier at edge of disc') Checkbutton(discPage, text = 'Cubic Lerping').pack( side = LEFT, expand = 1, fill = X) linePage = self.emitterNotebook.add('Line') self.createVector3Entry(linePage, 'Point 1', 'Point defining emitter line') self.createVector3Entry(linePage, 'Point 2', 'Point defining emitter line', initialValue = (1.0, 0.0, 0.0)) self.createVector3Entry(linePage, 'Launch Vector', 'Initial particle velocity vector', initialValue = (0.0, 0.0, 1.0)) pointPage = self.emitterNotebook.add('Point') self.createVector3Entry(pointPage, 'Location', 'Location of emitter point') self.createVector3Entry(pointPage, 'Launch vector', 'Initial particle velocity vector', initialValue = (0.0, 0.0, 1.0)) rectanglePage = self.emitterNotebook.add('Rectangle') self.createVector3Entry(rectanglePage, 'Point 1', 'Point defining rectangle') self.createVector3Entry(rectanglePage, 'Point 2', 'Point defining rectangle') self.createVector3Entry(rectanglePage, 'Launch vector', 'Initial particle velocity vector', initialValue = (0.0, 0.0, 1.0)) ringPage = self.emitterNotebook.add('Ring') self.createFloater(ringPage, 'Radius', 'Radius of ring') self.createAngleDial(ringPage, 'Angle', 'Particle launch angle') self.createFloater(ringPage, 'Magnitude', 'Launch velocity multiplier at outer edge of ring') sphereSurfacePage = self.emitterNotebook.add('Sphere Surface') self.createFloater(sphereSurfacePage, 'Radius', 'Radius of sphere') sphereVolumePage = self.emitterNotebook.add('Sphere Volume') self.createFloater(sphereVolumePage, 'Radius', 'Radius of sphere') tangentRingPage = self.emitterNotebook.add('Tangent Ring') self.createFloater(tangentRingPage, 'Radius', 'Radius of ring') self.emitterNotebook.pack(fill = X) # RENDERER PAGE self.createOptionMenu(rendererPage, 'Renderer type:', 'Select type of particle renderer', ('Geom', 'Point', 'Sparkle', 'Sprite'), self.selectRendererType) self.rendererNotebook = Pmw.NoteBook(rendererPage, tabpos = None) geomPage = self.rendererNotebook.add('Geom') f = Frame(geomPage) f.pack(fill = X) Label(f, width = 12, text = 'Geom node:').pack(side = LEFT) Entry(f, width = 12).pack(side = LEFT, expand = 1, fill = X) pointPage = self.rendererNotebook.add('Point') self.createFloater(pointPage, 'Point size', 'Width and height of points in pixels') self.createColorEntry(pointPage, 'Start color', 'Starting color of point') self.createColorEntry(pointPage, 'End color', 'Ending color of point') self.createOptionMenu(pointPage, 'Blend type:', 'Type of color blending used for particle', ('ONE_COLOR', 'BLEND_LIFE', 'BLEND_VEL'), self.selectBlendType) self.createOptionMenu(pointPage, 'Blend method:', 'Interpolation method between colors', ('LINEAR', 'CUBIC'), self.selectBlendMethod) sparklePage = self.rendererNotebook.add('Sparkle') self.createColorEntry(sparklePage, 'Center color', 'Color of sparkle center') self.createColorEntry(sparklePage, 'Edge color', 'Color of sparkle line endpoints') self.createFloater(sparklePage, 'Birth radius', 'Initial sparkle radius') self.createFloater(sparklePage, 'Death radius', 'Final sparkle radius') self.createOptionMenu(pointPage, 'Life scale:', 'Does particle scale over its lifetime?', ('NO_SCALE', 'SCALE'), self.selectBlendMethod) spritePage = self.rendererNotebook.add('Sprite') f = Frame(spritePage) f.pack(fill = X) Label(f, width = 12, text = 'Texture:').pack(side = LEFT) Entry(f, width = 12).pack(side = LEFT, expand = 1, fill = X) Checkbutton(spritePage, text = 'xScale',anchor = W).pack(fill = X) Checkbutton(spritePage, text = 'yScale',anchor = W).pack(fill = X) Checkbutton(spritePage, text = 'animAngle',anchor = W).pack(fill = X) self.createFloater(spritePage, 'Initial X Scale', 'Initial X scaling factor') self.createFloater(spritePage, 'Final X Scale', 'Final X scaling factor') self.createFloater(spritePage, 'Initial Y Scale', 'Initial Y scaling factor') self.createFloater(spritePage, 'Final Y Scale', 'Final Y scaling factor') self.createAngleDial(spritePage, 'Non Animated Theta', 'Counter clockwise Z rotation of all sprites') self.createOptionMenu(spritePage, 'Blend Type', 'Interpolation blend type for X and Y scaling', ('LINEAR', 'CUBIC'), self.selectBlendMethod) Checkbutton(spritePage, text = 'alphaDisable',anchor = W).pack(fill = X) self.rendererNotebook.pack(fill = X) self.factoryNotebook.setnaturalsize() self.emitterNotebook.setnaturalsize() self.rendererNotebook.setnaturalsize() notebook.setnaturalsize() # Make sure input variables processed self.initialiseoptions(ParticlePanel) def createFloaters(self, parent, widgetDefinitions): for label, balloonHelp, min, resolution in widgetDefinitions: self.createFloater(parent, label, balloonHelp, min, resolution) def createFloater(self, parent, text, balloonHelp, min = 0.0, resolution = None, **kw): kw['text'] = text kw['min'] = min kw['initialValue'] = min kw['resolution'] = resolution widget = apply(Floater.Floater, (parent,), kw) widget.pack(fill = X) self.balloon.bind(widget, balloonHelp) return widget def createAngleDial(self, parent, text, balloonHelp, **kw): kw['text'] = text widget = apply(Dial.AngleDial,(parent,), kw) widget.pack(fill = X) self.balloon.bind(widget, balloonHelp) return widget def createVector3Entry(self, parent, text, balloonHelp, **kw): # Set label's text kw['text'] = text widget = apply(VectorWidgets.Vector3Entry, (parent,), kw) widget.pack(fill = X) self.balloon.bind(widget, balloonHelp) return widget def createColorEntry(self, parent, text, balloonHelp, **kw): # Set label's text kw['text'] = text widget = apply(VectorWidgets.ColorEntry, (parent,) ,kw) widget.pack(fill = X) self.balloon.bind(widget, balloonHelp) return widget def createOptionMenu(self, parent, text, balloonHelp, items, command): optionVar = StringVar() optionVar.set(items[0]) widget = Pmw.OptionMenu(parent, labelpos = W, label_text = text, label_width = 12, menu_tearoff = 1, menubutton_textvariable = optionVar, items = items, command = command) widget.pack(fill = X) self.balloon.bind(widget.component('menubutton'), balloonHelp) return optionVar def selectFactoryType(self, type): self.factoryNotebook.selectpage(type) def selectEmitterType(self, type): self.emitterNotebook.selectpage(type) def selectRendererType(self, type): self.rendererNotebook.selectpage(type) def selectBlendType(self, type): print type def selectBlendMethod(self, method): print method def selectSystemNamed(self, name): print name def toggleBalloon(self): if self.toggleBalloonVar.get(): self.balloon.configure(state = 'balloon') else: self.balloon.configure(state = 'none') ###################################################################### # Create demo in root window for testing. if __name__ == '__main__': root = Pmw.initialise() pp = ParticlePanel() #ve = VectorEntry(Toplevel(), relief = GROOVE) #ve.pack()