Source code for direct.tkpanels.DirectSessionPanel

""" DIRECT Session Main panel """

__all__ = ['DirectSessionPanel']

# Import Tkinter, Pmw, and the dial code
from direct.showbase.TkGlobal import *
from direct.tkwidgets.AppShell import *
from panda3d.core import *
import Pmw
from direct.tkwidgets import Dial
from direct.tkwidgets import Floater
from direct.tkwidgets import Slider
from direct.tkwidgets import VectorWidgets
from direct.tkwidgets import SceneGraphExplorer
from .TaskManagerPanel import TaskManagerWidget
from direct.tkwidgets import MemoryExplorer

"""
Possible to add:
messenger.clear?
popup panels
taskMgr page
"""

[docs]class DirectSessionPanel(AppShell): # Override class variables here appname = 'Direct Session Panel' frameWidth = 600 frameHeight = 365 usecommandarea = 0 usestatusarea = 0
[docs] def __init__(self, parent = None, **kw): INITOPT = Pmw.INITOPT optiondefs = ( ('title', self.appname, None), ) self.defineoptions(kw, optiondefs) # Call superclass initialization function AppShell.__init__(self, parent) # Active light if len(base.direct.lights) > 0: name = base.direct.lights.getNameList()[0] self.lightMenu.selectitem(name) self.selectLightNamed(name) else: self.activeLight = None # Active display region self.drMenu.selectitem('Display Region 0') self.selectDisplayRegionNamed('Display Region 0') # Make sure we've got valid initial values self.updateInfo() self.initialiseoptions(DirectSessionPanel)
[docs] def appInit(self): # Initialize state # Dictionary keeping track of all node paths selected so far self.nodePathDict = {} self.nodePathDict['widget'] = base.direct.widget self.nodePathNames = ['widget'] # Dictionary keeping track of all jb node paths selected so far self.jbNodePathDict = {} self.jbNodePathDict['none'] = 'No Node Path' self.jbNodePathDict['widget'] = base.direct.widget self.jbNodePathDict['camera'] = base.direct.camera self.jbNodePathNames = ['camera', 'selected', 'none'] # Set up event hooks self.actionEvents = [ ('DIRECT_undo', self.undoHook), ('DIRECT_pushUndo', self.pushUndoHook), ('DIRECT_undoListEmpty', self.undoListEmptyHook), ('DIRECT_redo', self.redoHook), ('DIRECT_pushRedo', self.pushRedoHook), ('DIRECT_redoListEmpty', self.redoListEmptyHook), ('DIRECT_selectedNodePath', self.selectedNodePathHook), ('DIRECT_addLight', self.addLight), ] for event, method in self.actionEvents: self.accept(event, method)
[docs] def createInterface(self): # The interior of the toplevel panel interior = self.interior() # Add placer commands to menubar self.menuBar.addmenu('DIRECT', 'Direct Session Panel Operations') self.directEnabled = BooleanVar() self.directEnabled.set(1) self.menuBar.addmenuitem('DIRECT', 'checkbutton', 'DIRECT Enabled', label = 'Enable', variable = self.directEnabled, command = self.toggleDirect) self.directGridEnabled = BooleanVar() self.directGridEnabled.set(base.direct.grid.isEnabled()) self.menuBar.addmenuitem('DIRECT', 'checkbutton', 'DIRECT Grid Enabled', label = 'Enable Grid', variable = self.directGridEnabled, command = self.toggleDirectGrid) self.menuBar.addmenuitem('DIRECT', 'command', 'Toggle Object Handles Visability', label = 'Toggle Widget Viz', command = base.direct.toggleWidgetVis) self.menuBar.addmenuitem( 'DIRECT', 'command', 'Toggle Widget Move/COA Mode', label = 'Toggle Widget Mode', command = base.direct.manipulationControl.toggleObjectHandlesMode) self.directWidgetOnTop = BooleanVar() self.directWidgetOnTop.set(0) self.menuBar.addmenuitem('DIRECT', 'checkbutton', 'DIRECT Widget On Top', label = 'Widget On Top', variable = self.directWidgetOnTop, command = self.toggleWidgetOnTop) self.menuBar.addmenuitem('DIRECT', 'command', 'Deselect All', label = 'Deselect All', command = base.direct.deselectAll) # Get a handle to the menu frame menuFrame = self.menuFrame # Widget to select node paths (and display list of selected node paths) self.nodePathMenu = Pmw.ComboBox( menuFrame, labelpos = W, label_text = 'DIRECT Select:', entry_width = 20, selectioncommand = self.selectNodePathNamed, scrolledlist_items = self.nodePathNames) self.nodePathMenu.selectitem('widget') self.nodePathMenuEntry = ( self.nodePathMenu.component('entryfield_entry')) self.nodePathMenuBG = ( self.nodePathMenuEntry.configure('background')[3]) self.nodePathMenu.pack(side = LEFT, fill = X, expand = 1) self.bind(self.nodePathMenu, 'Select node path to manipulate') self.undoButton = Button(menuFrame, text = 'Undo', command = base.direct.undo) if base.direct.undoList: self.undoButton['state'] = 'normal' else: self.undoButton['state'] = 'disabled' self.undoButton.pack(side = LEFT, expand = 0) self.bind(self.undoButton, 'Undo last operation') self.redoButton = Button(menuFrame, text = 'Redo', command = base.direct.redo) if base.direct.redoList: self.redoButton['state'] = 'normal' else: self.redoButton['state'] = 'disabled' self.redoButton.pack(side = LEFT, expand = 0) self.bind(self.redoButton, 'Redo last operation') # The master frame for the dials mainFrame = Frame(interior) # Paned widget for dividing two halves framePane = Pmw.PanedWidget(mainFrame, orient = HORIZONTAL) sgeFrame = framePane.add('left', min = 250) notebookFrame = framePane.add('right', min = 300) # Scene Graph Explorer self.SGE = SceneGraphExplorer.SceneGraphExplorer( sgeFrame, nodePath = render, scrolledCanvas_hull_width = 250, scrolledCanvas_hull_height = 300) self.SGE.pack(fill = BOTH, expand = 1) sgeFrame.pack(side = LEFT, fill = 'both', expand = 1) # Create the notebook pages notebook = Pmw.NoteBook(notebookFrame) notebook.pack(fill = BOTH, expand = 1) self.createEnvPage(notebook.add('Environment')) self.createLightsPage(notebook.add('Lights')) self.createGridPage(notebook.add('Grid')) self.createDevicePage(notebook.add('Devices')) self.createTasksPage(notebook.add('Tasks')) self.createMemPage(notebook.add('Memory')) notebook.setnaturalsize() framePane.pack(expand = 1, fill = BOTH) mainFrame.pack(fill = 'both', expand = 1) # Put this here so it isn't called right away notebook['raisecommand'] = self.updateInfo
[docs] def createEnvPage(self, envPage): bkgrdFrame = Frame(envPage, borderwidth = 2, relief = 'sunken') Label(bkgrdFrame, text = 'Background', font=('MSSansSerif', 14, 'bold')).pack(expand = 0) self.backgroundColor = VectorWidgets.ColorEntry( bkgrdFrame, text = 'Background Color') self.backgroundColor['command'] = self.setBackgroundColorVec self.backgroundColor.pack(fill = X, expand = 0) self.bind(self.backgroundColor, 'Set background color') bkgrdFrame.pack(fill = BOTH, expand = 0) drFrame = Frame(envPage, borderwidth = 2, relief = 'sunken') Label(drFrame, text = 'Display Region', font=('MSSansSerif', 14, 'bold')).pack(expand = 0) nameList = ['Display Region ' + repr(x) for x in range(len(base.direct.drList))] self.drMenu = Pmw.ComboBox( drFrame, labelpos = W, label_text = 'Display Region:', entry_width = 20, selectioncommand = self.selectDisplayRegionNamed, scrolledlist_items = nameList) self.drMenu.pack(fill = X, expand = 0) self.bind(self.drMenu, 'Select display region to configure') self.nearPlane = Floater.Floater( drFrame, text = 'Near Plane', min = 0.01) self.nearPlane['command'] = self.setNear self.nearPlane.pack(fill = X, expand = 0) self.bind(self.nearPlane, 'Set near plane distance') self.farPlane = Floater.Floater( drFrame, text = 'Far Plane', min = 0.01) self.farPlane['command'] = self.setFar self.farPlane.pack(fill = X, expand = 0) self.bind(self.farPlane, 'Set far plane distance') fovFrame = Frame(drFrame) fovFloaterFrame = Frame(fovFrame) self.hFov = Slider.Slider( fovFloaterFrame, text = 'Horizontal FOV', min = 0.01, max = 170.0) self.hFov['command'] = self.setHFov self.hFov.pack(fill = X, expand = 0) self.bind(self.hFov, 'Set horizontal field of view') self.vFov = Slider.Slider( fovFloaterFrame, text = 'Vertical FOV', min = 0.01, max = 170.0) self.vFov['command'] = self.setVFov self.vFov.pack(fill = X, expand = 0) self.bind(self.vFov, 'Set vertical field of view') fovFloaterFrame.pack(side = LEFT, fill = X, expand = 1) frame = Frame(fovFrame) self.lockedFov = BooleanVar() self.lockedFov.set(1) self.lockedFovButton = Checkbutton( frame, text = 'Locked', anchor = 'w', justify = LEFT, variable = self.lockedFov) self.lockedFovButton.pack(fill = X, expand = 0) self.resetFovButton = Button( frame, text = 'Reset', command = self.resetFov) self.resetFovButton.pack(fill = X, expand = 0) frame.pack(side = LEFT, fill = X, expand = 0) fovFrame.pack(fill = X, expand = 1) drFrame.pack(fill = BOTH, expand = 0) ## Render Style ## toggleFrame = Frame(envPage, borderwidth = 2, relief = 'sunken') Label(toggleFrame, text = 'Toggle Render Style', font=('MSSansSerif', 14, 'bold')).pack(expand = 0) self.toggleBackfaceButton = Button( toggleFrame, text = 'Backface', command = base.toggleBackface) self.toggleBackfaceButton.pack(side = LEFT, fill = X, expand = 1) self.toggleLightsButton = Button( toggleFrame, text = 'Lights', command = base.direct.lights.toggle) self.toggleLightsButton.pack(side = LEFT, fill = X, expand = 1) self.toggleTextureButton = Button( toggleFrame, text = 'Texture', command = base.toggleTexture) self.toggleTextureButton.pack(side = LEFT, fill = X, expand = 1) self.toggleWireframeButton = Button( toggleFrame, text = 'Wireframe', command = base.toggleWireframe) self.toggleWireframeButton.pack(fill = X, expand = 1) toggleFrame.pack(side = LEFT, fill = X, expand = 1)
[docs] def createLightsPage(self, lightsPage): # Lights # lightFrame = Frame(lightsPage, borderwidth = 2, relief = 'sunken') self.lightsButton = Menubutton(lightFrame, text = 'Lights', font=('MSSansSerif', 14, 'bold'), activebackground = '#909090') lightsMenu = Menu(self.lightsButton) lightsMenu.add_command(label = 'Add Ambient Light', command = self.addAmbient) lightsMenu.add_command(label = 'Add Directional Light', command = self.addDirectional) lightsMenu.add_command(label = 'Add Point Light', command = self.addPoint) lightsMenu.add_command(label = 'Add Spotlight', command = self.addSpot) self.lightsButton.pack(expand = 0) self.lightsButton['menu'] = lightsMenu # Notebook pages for light specific controls self.lightNotebook = Pmw.NoteBook(lightFrame, tabpos = None, borderwidth = 0) ambientPage = self.lightNotebook.add('Ambient') directionalPage = self.lightNotebook.add('Directional') pointPage = self.lightNotebook.add('Point') spotPage = self.lightNotebook.add('Spot') # Put this here so it isn't called right away self.lightNotebook['raisecommand'] = self.updateLightInfo # Main light switch mainSwitchFrame = Frame(lightFrame) Label(mainSwitchFrame, text = 'Lighting:').pack(side = LEFT, expand = 0) self.enableLights = BooleanVar() self.enableLightsButton = Checkbutton( mainSwitchFrame, text = 'Enabled/Disabled', variable = self.enableLights, command = self.toggleLights) self.enableLightsButton.pack(side = LEFT, fill = X, expand = 0) mainSwitchFrame.pack(fill = X, expand = 0) # Widget to select a light to configure nameList = base.direct.lights.getNameList() lightMenuFrame = Frame(lightFrame) self.lightMenu = Pmw.ComboBox( lightMenuFrame, labelpos = W, label_text = 'Light:', entry_width = 20, selectioncommand = self.selectLightNamed, scrolledlist_items = nameList) self.lightMenu.pack(side = LEFT, fill = X, expand = 0) self.bind(self.lightMenu, 'Select light to configure') self.lightActive = BooleanVar() self.lightActiveButton = Checkbutton( lightMenuFrame, text = 'On/Off', variable = self.lightActive, command = self.toggleActiveLight) self.lightActiveButton.pack(side = LEFT, fill = X, expand = 0) # Pack light menu lightMenuFrame.pack(fill = X, expand = 0, padx = 2) self.lightColor = VectorWidgets.ColorEntry( lightFrame, text = 'Light Color') self.lightColor['command'] = self.setLightColor self.lightColor.pack(fill = X, expand = 0, padx = 4) self.bind(self.lightColor, 'Set active light color') # Directional light controls self.dSpecularColor = VectorWidgets.ColorEntry( directionalPage, text = 'Specular Color') self.dSpecularColor['command'] = self.setSpecularColor self.dSpecularColor.pack(fill = X, expand = 0) self.bind(self.dSpecularColor, 'Set directional light specular color') # Point light controls self.pSpecularColor = VectorWidgets.ColorEntry( pointPage, text = 'Specular Color') self.pSpecularColor['command'] = self.setSpecularColor self.pSpecularColor.pack(fill = X, expand = 0) self.bind(self.pSpecularColor, 'Set point light specular color') self.pConstantAttenuation = Slider.Slider( pointPage, text = 'Constant Attenuation', min = 0.0, max = 1.0, value = 1.0) self.pConstantAttenuation['command'] = self.setConstantAttenuation self.pConstantAttenuation.pack(fill = X, expand = 0) self.bind(self.pConstantAttenuation, 'Set point light constant attenuation') self.pLinearAttenuation = Slider.Slider( pointPage, text = 'Linear Attenuation', min = 0.0, max = 1.0, value = 0.0) self.pLinearAttenuation['command'] = self.setLinearAttenuation self.pLinearAttenuation.pack(fill = X, expand = 0) self.bind(self.pLinearAttenuation, 'Set point light linear attenuation') self.pQuadraticAttenuation = Slider.Slider( pointPage, text = 'Quadratic Attenuation', min = 0.0, max = 1.0, value = 0.0) self.pQuadraticAttenuation['command'] = self.setQuadraticAttenuation self.pQuadraticAttenuation.pack(fill = X, expand = 0) self.bind(self.pQuadraticAttenuation, 'Set point light quadratic attenuation') # Spot light controls self.sSpecularColor = VectorWidgets.ColorEntry( spotPage, text = 'Specular Color') self.sSpecularColor['command'] = self.setSpecularColor self.sSpecularColor.pack(fill = X, expand = 0) self.bind(self.sSpecularColor, 'Set spot light specular color') self.sConstantAttenuation = Slider.Slider( spotPage, text = 'Constant Attenuation', min = 0.0, max = 1.0, value = 1.0) self.sConstantAttenuation['command'] = self.setConstantAttenuation self.sConstantAttenuation.pack(fill = X, expand = 0) self.bind(self.sConstantAttenuation, 'Set spot light constant attenuation') self.sLinearAttenuation = Slider.Slider( spotPage, text = 'Linear Attenuation', min = 0.0, max = 1.0, value = 0.0) self.sLinearAttenuation['command'] = self.setLinearAttenuation self.sLinearAttenuation.pack(fill = X, expand = 0) self.bind(self.sLinearAttenuation, 'Set spot light linear attenuation') self.sQuadraticAttenuation = Slider.Slider( spotPage, text = 'Quadratic Attenuation', min = 0.0, max = 1.0, value = 0.0) self.sQuadraticAttenuation['command'] = self.setQuadraticAttenuation self.sQuadraticAttenuation.pack(fill = X, expand = 0) self.bind(self.sQuadraticAttenuation, 'Set spot light quadratic attenuation') self.sExponent = Slider.Slider( spotPage, text = 'Exponent', min = 0.0, max = 1.0, value = 0.0) self.sExponent['command'] = self.setExponent self.sExponent.pack(fill = X, expand = 0) self.bind(self.sExponent, 'Set spot light exponent') # MRM: Add frustum controls self.lightNotebook.setnaturalsize() self.lightNotebook.pack(expand = 1, fill = BOTH) lightFrame.pack(expand = 1, fill = BOTH)
[docs] def createGridPage(self, gridPage): Label(gridPage, text = 'Grid', font=('MSSansSerif', 14, 'bold')).pack(expand = 0) self.enableGrid = BooleanVar() self.enableGridButton = Checkbutton( gridPage, text = 'Enabled/Disabled', anchor = 'w', justify = LEFT, variable = self.enableGrid, command = self.toggleGrid) self.enableGridButton.pack(fill = X, expand = 0) self.xyzSnap = BooleanVar() self.xyzSnapButton = Checkbutton( gridPage, text = 'XYZ Snap', anchor = 'w', justify = LEFT, variable = self.xyzSnap, command = self.toggleXyzSnap) self.xyzSnapButton.pack(fill = X, expand = 0) self.hprSnap = BooleanVar() self.hprSnapButton = Checkbutton( gridPage, text = 'HPR Snap', anchor = 'w', justify = LEFT, variable = self.hprSnap, command = self.toggleHprSnap) self.hprSnapButton.pack(fill = X, expand = 0) self.gridSpacing = Floater.Floater( gridPage, text = 'Grid Spacing', min = 0.1, value = base.direct.grid.getGridSpacing()) self.gridSpacing['command'] = base.direct.grid.setGridSpacing self.gridSpacing.pack(fill = X, expand = 0) self.gridSize = Floater.Floater( gridPage, text = 'Grid Size', min = 1.0, value = base.direct.grid.getGridSize()) self.gridSize['command'] = base.direct.grid.setGridSize self.gridSize.pack(fill = X, expand = 0) self.gridSnapAngle = Dial.AngleDial( gridPage, text = 'Snap Angle', style = 'mini', value = base.direct.grid.getSnapAngle()) self.gridSnapAngle['command'] = base.direct.grid.setSnapAngle self.gridSnapAngle.pack(fill = X, expand = 0)
[docs] def createDevicePage(self, devicePage): Label(devicePage, text = 'DEVICES', font=('MSSansSerif', 14, 'bold')).pack(expand = 0) if base.direct.joybox != None: joyboxFrame = Frame(devicePage, borderwidth = 2, relief = 'sunken') Label(joyboxFrame, text = 'Joybox', font=('MSSansSerif', 14, 'bold')).pack(expand = 0) self.enableJoybox = BooleanVar() self.enableJoybox.set(1) self.enableJoyboxButton = Checkbutton( joyboxFrame, text = 'Enabled/Disabled', anchor = 'w', justify = LEFT, variable = self.enableJoybox, command = self.toggleJoybox) self.enableJoyboxButton.pack(fill = X, expand = 0) joyboxFrame.pack(fill = X, expand = 0) self.jbModeMenu = Pmw.ComboBox( joyboxFrame, labelpos = W, label_text = 'Joybox Mode:', label_width = 16, entry_width = 20, selectioncommand = self.selectJBModeNamed, scrolledlist_items = ['Joe Mode', 'Drive Mode', 'Orbit Mode', 'Look At Mode', 'Look Around Mode', 'Walkthru Mode', 'Demo Mode', 'HPRXYZ Mode']) self.jbModeMenu.selectitem('Joe Mode') self.jbModeMenu.pack(fill = X, expand = 1) self.jbNodePathMenu = Pmw.ComboBox( joyboxFrame, labelpos = W, label_text = 'Joybox Node Path:', label_width = 16, entry_width = 20, selectioncommand = self.selectJBNodePathNamed, scrolledlist_items = self.jbNodePathNames) self.jbNodePathMenu.selectitem('camera') self.jbNodePathMenuEntry = ( self.jbNodePathMenu.component('entryfield_entry')) self.jbNodePathMenuBG = ( self.jbNodePathMenuEntry.configure('background')[3]) self.jbNodePathMenu.pack(fill = X, expand = 1) self.bind(self.jbNodePathMenu, 'Select node path to manipulate using the joybox') self.jbXyzSF = Slider.Slider( joyboxFrame, text = 'XYZ Scale Factor', value = 1.0, hull_relief = RIDGE, hull_borderwidth = 2, min = 1.0, max = 100.0) self.jbXyzSF['command'] = ( lambda v: base.direct.joybox.setXyzMultiplier(v)) self.jbXyzSF.pack(fill = X, expand = 0) self.bind(self.jbXyzSF, 'Set joybox XYZ speed multiplier') self.jbHprSF = Slider.Slider( joyboxFrame, text = 'HPR Scale Factor', value = 1.0, hull_relief = RIDGE, hull_borderwidth = 2, min = 1.0, max = 100.0) self.jbHprSF['command'] = ( lambda v: base.direct.joybox.setHprMultiplier(v)) self.jbHprSF.pack(fill = X, expand = 0) self.bind(self.jbHprSF, 'Set joybox HPR speed multiplier')
[docs] def createTasksPage(self, tasksPage): Label(tasksPage, text = 'TASKS', font=('MSSansSerif', 14, 'bold')).pack(expand = 0) self.taskMgrPanel = TaskManagerWidget(tasksPage, taskMgr) self.taskMgrPanel.taskListBox['listbox_height'] = 10
[docs] def createMemPage(self, memPage): self.MemExp = MemoryExplorer.MemoryExplorer( memPage, nodePath = render, scrolledCanvas_hull_width = 250, scrolledCanvas_hull_height = 250) self.MemExp.pack(fill = BOTH, expand = 1)
[docs] def toggleDirect(self): if self.directEnabled.get(): base.direct.enable() else: base.direct.disable()
[docs] def toggleDirectGrid(self): if self.directGridEnabled.get(): base.direct.grid.enable() else: base.direct.grid.disable()
[docs] def toggleWidgetOnTop(self): if self.directWidgetOnTop.get(): base.direct.widget.setBin('gui-popup', 0) base.direct.widget.setDepthTest(0) else: base.direct.widget.clearBin() base.direct.widget.setDepthTest(1)
[docs] def selectedNodePathHook(self, nodePath): # Make sure node path is in nodePathDict # MRM: Do we need to truncate list? if isinstance(nodePath, NodePath): self.addNodePath(nodePath)
[docs] def selectNodePathNamed(self, name): # See if node path has already been selected nodePath = self.nodePathDict.get(name, None) # If not, see if listbox evals into a node path if (nodePath == None): # See if this evaluates into a node path try: nodePath = eval(name) if isinstance(nodePath, NodePath): self.addNodePath(nodePath) else: # Good eval but not a node path, give up nodePath = None except: # Bogus eval nodePath = None # Clear bogus entry from listbox listbox = self.nodePathMenu.component('scrolledlist') listbox.setlist(self.nodePathNames) # Did we finally get something? if (nodePath != None): # Yes, select it! base.direct.select(nodePath)
[docs] def addNodePath(self, nodePath): self.addNodePathToDict(nodePath, self.nodePathNames, self.nodePathMenu, self.nodePathDict)
[docs] def selectJBModeNamed(self, name): if name == 'Joe Mode': base.direct.joybox.joeMode() elif name == 'Drive Mode': base.direct.joybox.driveMode() elif name == 'Orbit Mode': base.direct.joybox.orbitMode() elif name == 'Look At Mode': base.direct.joybox.lookAtMode() elif name == 'Look Around Mode': base.direct.joybox.lookAroundMode() elif name == 'Walkthru Mode': base.direct.joybox.walkthruMode() elif name == 'Demo Mode': base.direct.joybox.demoMode() elif name == 'HPRXYZ Mode': base.direct.joybox.hprXyzMode()
[docs] def selectJBNodePathNamed(self, name): if name == 'selected': nodePath = base.direct.selected.last # Add Combo box entry for this selected object self.addJBNodePath(nodePath) else: # See if node path has already been selected nodePath = self.jbNodePathDict.get(name, None) if (nodePath == None): # If not, see if listbox evals into a node path try: nodePath = eval(name) if isinstance(nodePath, NodePath): self.addJBNodePath(nodePath) else: # Good eval but not a node path, give up nodePath = None except: # Bogus eval nodePath = None # Clear bogus entry from listbox listbox = self.jbNodePathMenu.component('scrolledlist') listbox.setlist(self.jbNodePathNames) # Did we finally get something? if (nodePath != None): # Yes, select it! if (nodePath == 'No Node Path'): base.direct.joybox.setNodePath(None) else: base.direct.joybox.setNodePath(nodePath)
[docs] def addJBNodePath(self, nodePath): self.addNodePathToDict(nodePath, self.jbNodePathNames, self.jbNodePathMenu, self.jbNodePathDict)
[docs] def addNodePathToDict(self, nodePath, names, menu, dict): if not nodePath: return # Get node path's name name = nodePath.getName() if name in ['parent', 'render', 'camera']: dictName = name else: # Generate a unique name for the dict dictName = name + '-' + repr(hash(nodePath)) if dictName not in dict: # Update combo box to include new item names.append(dictName) listbox = menu.component('scrolledlist') listbox.setlist(names) # Add new item to dictionary dict[dictName] = nodePath menu.selectitem(dictName)
## ENVIRONMENT CONTROLS ## # Background #
[docs] def setBackgroundColor(self, r, g, b): self.setBackgroundColorVec((r, g, b))
[docs] def setBackgroundColorVec(self, color): base.setBackgroundColor(color[0]/255.0, color[1]/255.0, color[2]/255.0)
[docs] def selectDisplayRegionNamed(self, name): if name.find('Display Region ') >= 0: drIndex = int(name[-1:]) self.activeDisplayRegion = base.direct.drList[drIndex] else: self.activeDisplayRegion = None # Make sure info is current self.updateDisplayRegionInfo()
[docs] def setNear(self, near): dr = self.activeDisplayRegion if dr: dr.camLens.setNear(near) cluster('base.camLens.setNear(%f)' % near, 0)
[docs] def setFar(self, far): dr = self.activeDisplayRegion if dr: dr.camLens.setFar(far) cluster('base.camLens.setFar(%f)' % far, 0)
[docs] def setHFov(self, hFov): dr = self.activeDisplayRegion if dr: if self.lockedFov.get(): sf = hFov/dr.getHfov() vFov = min(dr.getVfov() * sf, 170.0) dr.setFov(hFov, vFov) # Update scale self.vFov.set(vFov, 0) else: # Just set horizontal dr.setHfov(hFov)
[docs] def setVFov(self, vFov): dr = self.activeDisplayRegion if dr: if self.lockedFov.get(): sf = vFov/dr.getVfov() hFov = min(dr.getHfov() * sf, 170.0) dr.setFov(hFov, vFov) # Update scale self.hFov.set(hFov, 0) else: # Just set horizontal dr.setVfov(vFov)
[docs] def resetFov(self): dr = self.activeDisplayRegion if dr: dr.setFov(45.0, 33.75) self.hFov.set(45.0, 0) self.vFov.set(33.75, 0)
# Lights #
[docs] def selectLightNamed(self, name): # See if light exists self.activeLight = base.direct.lights[name] # If not...create new one if self.activeLight == None: self.activeLight = base.direct.lights.create(name) # Do we have a valid light at this point? if self.activeLight: light = self.activeLight.getLight() if isinstance(light, AmbientLight): self.lightNotebook.selectpage('Ambient') elif isinstance(light, DirectionalLight): self.lightNotebook.selectpage('Directional') elif isinstance(light, PointLight): self.lightNotebook.selectpage('Point') elif isinstance(light, Spotlight): self.lightNotebook.selectpage('Spot') else: # Restore valid data listbox = self.lightMenu.component('scrolledlist') listbox.setlist(base.direct.lights.getNameList()) if len(base.direct.lights) > 0: self.lightMenu.selectitem(base.direct.lights.getNameList()[0]) # Make sure info is current self.updateLightInfo()
[docs] def addAmbient(self): return base.direct.lights.create('ambient')
[docs] def addDirectional(self): return base.direct.lights.create('directional')
[docs] def addPoint(self): return base.direct.lights.create('point')
[docs] def addSpot(self): return base.direct.lights.create('spot')
[docs] def addLight(self, light): # Make list reflect current list of lights listbox = self.lightMenu.component('scrolledlist') listbox.setlist(base.direct.lights.getNameList()) # Select the newly added light self.lightMenu.selectitem(light.getName()) # And show corresponding page self.selectLightNamed(light.getName())
[docs] def toggleLights(self): if self.enableLights.get(): base.direct.lights.allOn() else: base.direct.lights.allOff()
[docs] def toggleActiveLight(self): if self.activeLight: if self.lightActive.get(): base.direct.lights.setOn(self.activeLight) else: base.direct.lights.setOff(self.activeLight)
[docs] def setLightColor(self, color): if self.activeLight: self.activeLight.getLight().setColor(Vec4(color[0]/255.0, color[1]/255.0, color[2]/255.0, color[3]/255.0))
[docs] def setSpecularColor(self, color): if self.activeLight: self.activeLight.getLight().setSpecularColor(Vec4(color[0]/255.0, color[1]/255.0, color[2]/255.0, color[3]/255.0))
[docs] def setConstantAttenuation(self, value): if self.activeLight: self.activeLight.getLight().setConstantAttenuation(value)
[docs] def setLinearAttenuation(self, value): if self.activeLight: self.activeLight.getLight().setLinearAttenuation(value)
[docs] def setQuadraticAttenuation(self, value): if self.activeLight: self.activeLight.getLight().setQuadraticAttenuation(value)
[docs] def setExponent(self, value): if self.activeLight: self.activeLight.getLight().setExponent(value)
## GRID CONTROLS ##
[docs] def toggleGrid(self): if self.enableGrid.get(): base.direct.grid.enable() else: base.direct.grid.disable()
[docs] def toggleXyzSnap(self): base.direct.grid.setXyzSnap(self.xyzSnap.get())
[docs] def toggleHprSnap(self): base.direct.grid.setHprSnap(self.hprSnap.get())
## DEVICE CONTROLS
[docs] def toggleJoybox(self): if self.enableJoybox.get(): base.direct.joybox.enable() else: base.direct.joybox.disable()
## UPDATE INFO ##
[docs] def updateInfo(self, page = 'Environment'): if page == 'Environment': self.updateEnvironmentInfo() elif page == 'Lights': self.updateLightInfo() elif page == 'Grid': self.updateGridInfo()
[docs] def updateEnvironmentInfo(self): bkgrdColor = base.getBackgroundColor() * 255.0 self.backgroundColor.set([bkgrdColor[0], bkgrdColor[1], bkgrdColor[2], bkgrdColor[3]], 0) self.updateDisplayRegionInfo()
[docs] def updateDisplayRegionInfo(self): if self.activeDisplayRegion: self.nearPlane.set(self.activeDisplayRegion.near, 0) self.farPlane.set(self.activeDisplayRegion.far, 0) self.hFov.set(self.activeDisplayRegion.fovH, 0) self.vFov.set(self.activeDisplayRegion.fovV, 0)
[docs] def updateLightInfo(self, page = None): # Set main lighting button self.enableLights.set( render.node().hasAttrib(LightAttrib.getClassType())) # Set light specific info if self.activeLight: l = self.activeLight.getLight() self.lightActive.set(render.hasLight(self.activeLight)) lightColor = l.getColor() * 255.0 self.lightColor.set([lightColor[0], lightColor[1], lightColor[2], lightColor[3]], 0) if isinstance(l, DirectionalLight): specularColor = l.getSpecularColor() * 255.0 self.dSpecularColor.set([specularColor[0], specularColor[1], specularColor[2], specularColor[3]], 0) elif isinstance(l, PointLight): specularColor = l.getSpecularColor() * 255.0 self.pSpecularColor.set([specularColor[0], specularColor[1], specularColor[2], specularColor[3]], 0) att = l.getAttenuation() self.pConstantAttenuation.set(att[0], 0) self.pLinearAttenuation.set(att[1], 0) self.pQuadraticAttenuation.set(att[2], 0) elif isinstance(l, Spotlight): specularColor = l.getSpecularColor() * 255.0 self.sSpecularColor.set([specularColor[0], specularColor[1], specularColor[2], specularColor[3]], 0) att = l.getAttenuation() self.pConstantAttenuation.set(att[0], 0) self.pLinearAttenuation.set(att[1], 0) self.pQuadraticAttenuation.set(att[2], 0)
[docs] def updateGridInfo(self): self.enableGrid.set(base.direct.grid.isEnabled()) self.xyzSnap.set(base.direct.grid.getXyzSnap()) self.hprSnap.set(base.direct.grid.getHprSnap()) self.gridSpacing.set(base.direct.grid.getGridSpacing(), 0) self.gridSize.set(base.direct.grid.getGridSize(), 0) self.gridSnapAngle.set(base.direct.grid.getSnapAngle(), 0)
# UNDO/REDO
[docs] def pushUndo(self, fResetRedo = 1): base.direct.pushUndo([self['nodePath']])
[docs] def undoHook(self, nodePathList = []): pass
[docs] def pushUndoHook(self): # Make sure button is reactivated self.undoButton.configure(state = 'normal')
[docs] def undoListEmptyHook(self): # Make sure button is deactivated self.undoButton.configure(state = 'disabled')
[docs] def pushRedo(self): base.direct.pushRedo([self['nodePath']])
[docs] def redoHook(self, nodePathList = []): pass
[docs] def pushRedoHook(self): # Make sure button is reactivated self.redoButton.configure(state = 'normal')
[docs] def redoListEmptyHook(self): # Make sure button is deactivated self.redoButton.configure(state = 'disabled')
[docs] def onDestroy(self, event): # Remove hooks for event, method in self.actionEvents: self.ignore(event) # Destroy SGE hierarchy self.SGE._node.destroy()