| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608 |
- #################################################################
- # collisionWindow.py
- # Written by Yi-Hong Lin, [email protected], 2004
- #################################################################
- # Import Tkinter, Pmw, and the floater code from this directory tree.
- from direct.tkwidgets.AppShell import *
- from direct.showbase.TkGlobal import *
- from tkSimpleDialog import askfloat
- import string
- import math
- import types
- from direct.task import Task
- FRAMES = 0
- SECONDS = 1
- class AnimPanel(AppShell):
- #################################################################
- # This class will generate a animation panel for an actor
- # which user assigned. Inside this panel, instead of using actorInterval
- # or just simply calling the play function in Actor, we create a task to
- # set animation frame by frame using setPose.
- #################################################################
- # Override class variables
- appname = 'Anim Panel'
- frameWidth = 575
- frameHeight = 250
- usecommandarea = 0
- usestatusarea = 0
- index = 0
- dragMode = False
- rateList= ['1/24.0', '0.1', '0.5', '1.0', '2.0', '5.0' , '10.0']
-
- def __init__(self, aNode = None, parent = None, **kw):
- INITOPT = Pmw.INITOPT
- self.id = 'AnimPanel '+ aNode.getName()
- self.appname = self.id
- optiondefs = (
- ('title', self.appname, None),
- ('actor', aNode, None),
- ('animList', [], None),
- )
- self.defineoptions(kw, optiondefs)
- self.frameHeight = 300
- self.id = 'AnimPanel '+ aNode.getName()
- self.nodeName = aNode.getName()
- # Initialize the superclass
- AppShell.__init__(self)
- # Execute option callbacks
- self.initialiseoptions(AnimPanel)
- self.currTime = 0.0 # Initialize the start time
- self.animName = None
- self.parent.resizable(False,False) ## Disable the ability to resize for this Window.
- def createInterface(self):
- # Handle to the toplevels interior
- interior = self.interior()
- menuBar = self.menuBar
- menuBar.addmenu('Anim', 'Anim Panel Operations')
-
- # Reset all actor controls
- menuBar.addmenuitem('File', 'command',
- 'Load Animation',
- label = 'Load Animation',
- command = self.loadAnimation)
- menuBar.addmenuitem('Anim', 'command',
- 'Set actor controls to t = 0.0',
- label = 'Jump all to zero',
- command = self.resetAllToZero)
- menuBar.addmenuitem('Anim', 'command',
- 'Set Actor controls to end time',
- label = 'Jump all to end time',
- command = self.resetAllToEnd)
- menuBar.addmenuitem('Anim', 'separator')
- menuBar.addmenuitem('Anim', 'command',
- 'Play Current Animation',
- label = 'Play',
- command = self.play)
- menuBar.addmenuitem('Anim', 'command',
- 'Stop Current Animation',
- label = 'stop',
- command = self.stop)
- # Create a frame to hold all the actor controls
- actorFrame = Frame(interior)
- name_label = Label(actorFrame, text= self.nodeName,font=('MSSansSerif', 16),
- relief = SUNKEN, borderwidth=3)
- name_label.place(x=5,y=5,anchor=NW)
- Label(actorFrame, text= "Animation:", font=('MSSansSerif', 12)).place(x=140,y=5,anchor=NW)
- Label(actorFrame, text= "Play Rate:", font=('MSSansSerif', 12)).place(x=140,y=35,anchor=NW)
- self['animList'] = self['actor'].getAnimNames()
- self.AnimEntry = self.createcomponent(
- 'AnimationMenu', (), None,
- Pmw.ComboBox, (actorFrame,),
- labelpos = W, entry_width = 20, selectioncommand = self.setAnimation,
- scrolledlist_items = self['animList'])
- self.AnimEntry.place(x=240,y=10,anchor=NW)
-
- self.playRateEntry = self.createcomponent(
- 'playRateMenu', (), None,
- Pmw.ComboBox, (actorFrame,),
- labelpos = W, entry_width = 20, selectioncommand = self.setPlayRate,
- scrolledlist_items = self.rateList)
- self.playRateEntry.place(x=240,y=40,anchor=NW)
- self.playRateEntry.selectitem('1.0')
- ### Loop checkbox
- Label(actorFrame, text= "Loop:", font=('MSSansSerif', 12)).place(x=420,y=05,anchor=NW)
- self.loopVar = IntVar()
- self.loopVar.set(0)
- self.loopButton = self.createcomponent(
- 'loopButton', (), None,
- Checkbutton, (actorFrame,),
- variable = self.loopVar)
- self.loopButton.place(x=470,y=7,anchor=NW)
- ### Display Frames/Seconds
- Label(actorFrame, text= "Frame/Second:", font=('MSSansSerif', 11)).place(x=5,y=75,anchor=NW)
- self.unitsVar = IntVar()
- self.unitsVar.set(FRAMES)
- self.displayButton = self.createcomponent(
- 'displayButton', (), None,
- Checkbutton, (actorFrame,),
- command = self.updateDisplay,
- variable = self.unitsVar)
- self.displayButton.place(x=120,y=77,anchor=NW)
-
- ## scale control
- frameFrame = Frame(actorFrame, relief = SUNKEN, bd = 1)
- self.minLabel = self.createcomponent(
- 'minLabel', (), 'sLabel',
- Label, (frameFrame,),
- text = 0)
- self.minLabel.pack(side = LEFT)
- self.frameControl = self.createcomponent(
- 'scale', (), None,
- Scale, (frameFrame,),
- from_ = 0, to = 24, resolution = 1.0,
- command = self.goTo, length = 500,
- orient = HORIZONTAL, showvalue = 1)
- self.frameControl.pack(side = LEFT, expand = 1)
- self.frameControl.bind('<Button-1>', self.onPress)
- self.frameControl.bind('<ButtonRelease-1>', self.onRelease)
- self.maxLabel = self.createcomponent(
- 'maxLabel', (), 'sLabel',
- Label, (frameFrame,),
- text = 24)
- self.maxLabel.pack(side = LEFT)
- frameFrame.pack(side = LEFT, expand = 1, fill = X)
-
- ## button contorl
- ButtomFrame = Frame(actorFrame, relief = SUNKEN, bd = 1,borderwidth=5)
- self.toStartButton = self.createcomponent(
- 'toStart', (), None,
- Button, (ButtomFrame,),
- text = '<<',
- width = 8,
- command = self.resetAllToZero)
- self.toStartButton.pack(side = LEFT, expand = 1, fill = X)
-
- self.playButton = self.createcomponent(
- 'playButton', (), None,
- Button, (ButtomFrame,),
- text = 'Play', width = 8,
- command = self.play)
- self.playButton.pack(side = LEFT, expand = 1, fill = X)
- self.stopButton = self.createcomponent(
- 'stopButton', (), None,
- Button, (ButtomFrame,),
- text = 'Stop', width = 8, state=DISABLED,
- command = self.stop)
- self.stopButton.pack(side = LEFT, expand = 1, fill = X)
- self.toEndButton = self.createcomponent(
- 'toEnd', (), None,
- Button, (ButtomFrame,),
- text = '>>',
- width = 8,
- command = self.resetAllToEnd)
- self.toEndButton.pack(side = LEFT, expand = 1, fill = X)
- ButtomFrame.place(anchor=NW,x=5,y=165)
- self.removeButton = self.createcomponent(
- 'Remove Animation', (), None,
- Button, (actorFrame,),
- text = 'Remove This Animation', width = 20,
- command = self.removeAnim)
- self.removeButton.place(anchor=NW,x=5,y=220)
- self.loadButton = self.createcomponent(
- 'Load Animation', (), None,
- Button, (actorFrame,),
- text = 'Load New Animation', width = 20,
- command = self.loadAnimation)
- self.loadButton.place(anchor=NW,x=180,y=220)
- # Now pack the actor frame
- actorFrame.pack(expand = 1, fill = BOTH)
- def updateList(self):
- #################################################################
- # updateList(self)
- # This function will update the list of animations that the Actor
- # currently has into the combo box widget.
- #################################################################
- self.ignore('DataH_loadFinish'+self.nodeName)
- del self.loaderWindow
- self['animList'] = self['actor'].getAnimNames()
- animL = self['actor'].getAnimNames()
- self.AnimEntry.setlist(animL)
-
- def removeAnim(self):
- #################################################################
- # removeAnim(self)
- # This function will stop the animation and get the name of animation
- # which user wish to remove from the panel. Then, it will send out
- # a message to dataHolder to remove the target animation.
- # And in the same time, it will start waiting a return message to
- # make sure that target animation has been removed.
- #################################################################
- name = self.AnimEntry.get()
- if taskMgr.hasTaskNamed(self.id + '_UpdateTask'):
- self.stop()
- self.accept('DataH_removeAnimFinish'+self.nodeName,self.afterRemove)
- messenger.send('AW_removeAnim',[self['actor'],name])
- return
- def afterRemove(self):
- #################################################################
- # afterRemove(self)
- # This function will be called once panel has received the return
- # message from dataHolder. This function will call setList to
- # reset the list of Animations
- #################################################################
- self.ignore('DataH_removeAnimFinish'+self.nodeName)
- self['animList'] = self['actor'].getAnimNames()
- animL = self['actor'].getAnimNames()
- self.AnimEntry.setlist(animL)
- print '-----',animL
- return
- def loadAnimation(self):
- #################################################################
- # loadAnimation(self)
- # This function will open a dialog window to require user to input
- # the animation he wants to load in for this actor.
- #################################################################
- self.loaderWindow = LoadAnimPanel(aNode=self['actor'])
- self.accept('DataH_loadFinish'+self.nodeName,self.updateList)
- return
- def play(self):
- #################################################################
- # play(self)
- # This function will be called when user click on the "play" button.
- # First, this function will initialize all parameter that the actual
- # play task need to run and add the play task into the taskMgr.
- #################################################################
- self.animName = self.AnimEntry.get()
- if self.animName in self['animList']:
- animName = self.AnimEntry.get()
- self.playButton.config(state=DISABLED)
- self.lastT = globalClock.getFrameTime()
- taskMgr.add(self.playTask, self.id + '_UpdateTask')
- self.stopButton.config(state=NORMAL)
- else:
- print '----Illegal Animaion name!!', self.animName
- return
- def playTask(self, task):
- #################################################################
- # playTask(self, task)
- # This task will record time by each frame
- # In fact it is just a clock keeper.
- # If the current frame time over the max long of the animation,
- # it will reset the timer.
- # Anyway, this function will call gotoT by each frame.
- #################################################################
- fLoop = self.loopVar.get()
- currT = globalClock.getFrameTime()
- deltaT = currT - self.lastT
- self.lastT = currT
- if self.dragMode:
- return Task.cont
- self.currTime = self.currTime + deltaT
- if (self.currTime > self.maxSeconds):
- if fLoop:
- self.currTime = self.currTime%self.duration
- self.gotoT(self.currTime)
- else:
- self.currTime = 0.0
- self.gotoT(0.0)
- self.playButton.config(state=NORMAL)
- self.stopButton.config(state=DISABLED)
- return Task.done
- else:
- self.gotoT(self.currTime)
- return Task.cont
- def stop(self):
- #################################################################
- # stop(self)
- # This function will remove the play task from taskMgr when user
- # click on the "Stop" button
- #################################################################
- taskMgr.remove(self.id + '_UpdateTask')
- self.playButton.config(state=NORMAL)
- self.stopButton.config(state=DISABLED)
- return
- def setAnimation(self, animation):
- #################################################################
- # setAnimation(self, animation)
- # This function will be called each time when user change
- # the current animation. Most important thing this function do is
- # to recalculate all variables to fit the selected animation
- #################################################################
- self.animName = self.AnimEntry.get()
- playRate = '%0.1f' % self['actor'].getPlayRate(self.animName)
- if playRate not in self.rateList:
- def strCmp(a, b):
- return cmp(eval(a), eval(b))
- self.rateList.append(playRate)
- self.rateList.sort(strCmp)
- self.playRateEntry.reset(self.rateList)
- self.playRateEntry.selectitem(playRate)
- self.currTime = 0.0
- self.frameControl.set(0)
- self.updateDisplay()
- return
- def setPlayRate(self,rate):
- #################################################################
- # setPlayRate(self, rate)
- # This function will be called each time when user changes the current play rate.
- #################################################################
- self.animName = self.AnimEntry.get()
- if self.animName in self['animList']:
- self['actor'].setPlayRate(eval(rate), self.animName)
- self.updateDisplay()
- return
- def updateDisplay(self):
- #################################################################
- # updateDisplay(self)
- # This function will be called whenever something has been changed
- # on the panel. In here we will re-new all widgets on the panel to
- # correct value.
- #################################################################
- self.fps = self['actor'].getFrameRate(self.animName)
- self.duration = self['actor'].getDuration(self.animName)
- self.maxFrame = self['actor'].getNumFrames(self.animName) - 1
- self.maxSeconds = self.duration
- if self.unitsVar.get() == FRAMES:
- fromFrame = 0
- toFrame = self.maxFrame
- self.minLabel['text'] = fromFrame
- self.maxLabel['text'] = toFrame
- self.frameControl.configure(from_ = fromFrame,
- to = toFrame,
- resolution = 1.0)
- else:
- self.minLabel['text'] = '0.0'
- self.maxLabel['text'] = "%.2f" % self.duration
- self.frameControl.configure(from_ = 0.0,
- to = self.duration,
- resolution = 0.01)
- def gotoT(self,time):
- #################################################################
- # gotoT(self, time)
- # calculate the right parameter which will be send to set Frame
- # Control slider, which is the real place we play the animation.
- #################################################################
- if self.unitsVar.get() == FRAMES:
- self.frameControl.set(time * self.fps)
- else:
- self.frameControl.set(time)
- return
- def goTo(self,frame):
- #################################################################
- # goto(self, frame)
- # Call back function for the frame control slider.
- # This function will set the animation by the value on the slider.
- #
- # This function is the real function we "play" the animation.
- #
- #################################################################
- if self.animName in self['animList']:
- # Convert scale value to float
- frame = string.atof(frame)
- # Now convert t to seconds for offset calculations
- if self.unitsVar.get() == FRAMES:
- frame = frame / self.fps
- if self.dragMode:
- # If user is clicking on the slider and is draging the bar, reset the global timer.
- self.currTime = frame
- self['actor'].pose(self.animName,
- min(self.maxFrame, int(frame * self.fps)))
- return
- def onRelease(self,frame):
- #################################################################
- # onRelease(self, frame)
- # disable the dragMode when user releases the bar on the slider.
- #################################################################
- self.dragMode = False
- return
- def onPress(self,frame):
- #################################################################
- # onPress(self, frame)
- # enable the dragMode when user press the bar on the slider.
- #################################################################
- self.dragMode = True
- return
-
- def resetAllToZero(self):
- #################################################################
- # resetAllToZero(self)
- # reset the global timer to zero and also move the slider to zero.
- # This will also reset the actor to the zero frame of current animation
- #################################################################
- self.currTime = 0.0
- self.gotoT(0)
- return
- def resetAllToEnd(self):
- #################################################################
- # resetAllToEnd(self)
- # set the global timer to the end of current animation and
- # also move the slider to the end.
- #################################################################
- self.currTime = self.maxSeconds
- self.gotoT(self.duration)
- return
- def onDestroy(self, event):
- if taskMgr.hasTaskNamed(self.id + '_UpdateTask'):
- taskMgr.remove(self.id + '_UpdateTask')
- self.ignore('DataH_loadFinish')
- messenger.send('AW_close',[self.nodeName])
- '''
- If you have open any thing, please rewrite here!
- '''
- pass
- class LoadAnimPanel(AppShell):
- #################################################################
- # LoadAnimPanel(AppShell)
- # This class will open a dialog to ask user to input names and
- # file paths of animations
- #################################################################
- # Override class variables
- appname = 'Load Animation'
- frameWidth = 575
- frameHeight = 200
- usecommandarea = 0
- usestatusarea = 0
- index = 0
- ## Anim name : File Path
- def __init__(self, aNode = None, parent = None, **kw):
- INITOPT = Pmw.INITOPT
- self.id = 'Load Animation '+ aNode.getName()
- self.appname = self.id
- self.animDic = {}
- self.animList = []
- optiondefs = (
- ('title', self.appname, None),
- )
- self.defineoptions(kw, optiondefs)
- self.frameHeight = 300
- self.nodeName = aNode.getName()
- self.Actor = aNode
- # Initialize the superclass
- AppShell.__init__(self)
- # Execute option callbacks
- self.initialiseoptions(LoadAnimPanel)
- def createInterface(self):
- self.menuBar.destroy()
- interior = self.interior()
- mainFrame = Frame(interior)
- self.inputZone = Pmw.Group(mainFrame, tag_text='File Setting')
- self.inputZone.pack(fill='both',expand=1)
- settingFrame = self.inputZone.interior()
- Label(settingFrame,text='Anim Name').place(anchor=NW,x=60,y=5)
- Label(settingFrame,text='File Path').place(anchor=NW,x=205,y=5)
- self.AnimName_1 = self.createcomponent(
- 'Anim Name List', (), None,
- Pmw.ComboBox, (settingFrame,),label_text='Anim :',
- labelpos = W, entry_width = 10, selectioncommand = self.selectAnim,
- scrolledlist_items = self.animList)
- self.AnimFile_1 = Pmw.EntryField(settingFrame,value='')
- self.AnimFile_1.component('entry').config(width=20)
- self.AnimName_1.place(anchor=NW,x=10,y=25)
- self.AnimFile_1.place(anchor=NW,x=140,y=25)
- self.Browse_1 = self.createcomponent(
- 'File Browser1', (), None,
- Button, (mainFrame,),
- text = 'Browse...',
- command = self.Browse_1)
- self.Browse_1.place(anchor=NW,x=270,y=38)
- self.addIntoButton = self.createcomponent(
- 'Load Add', (), None,
- Button, (mainFrame,),
- text = 'Add to Load',
- command = self.addIntoList)
- self.addIntoButton.place(anchor=NW,x=345,y=38)
- att_label = Label(mainFrame, font=('MSSansSerif', 10),
- text= "Attention! Animations won't be loaded in before you press the 'OK' button below!")
- att_label.place(anchor=NW,x=10,y=80)
- self.button_ok = Button(mainFrame, text="OK", command=self.ok_press,width=10)
- self.button_ok.pack(fill=BOTH,expand=0,side=RIGHT)
- mainFrame.pack(expand = 1, fill = BOTH)
-
-
- def onDestroy(self, event):
- messenger.send('AWL_close',[self.nodeName])
- '''
- If you have open any thing, please rewrite here!
- '''
- pass
- def selectAnim(self,name):
- #################################################################
- # selectAnim(self, name)
- # This function will be called if user select an animation on the list.
- #################################################################
- if name in self.animDic:
- self.AnimFile_1.setvalue = self.animDic[name]
- return
- def Browse_1(self):
- #################################################################
- # Browse_1(self)
- # when the browse button pused, this function will be called.
- # Do nothing but open a file dialog for user to set the path to target file
- # Then, set the path back to the entry on the panel.
- #################################################################
- AnimFilename = askopenfilename(
- defaultextension = '.egg',
- filetypes = (('Egg Files', '*.egg'),
- ('Bam Files', '*.bam'),
- ('All files', '*')),
- initialdir = '.',
- title = 'File Path for Anim 1',
- parent = self.parent)
- if AnimFilename:
- self.AnimFile_1.setvalue(AnimFilename)
- return
- def addIntoList(self):
- #################################################################
- # addIntoList(self)
- # This function will be called each time when user click on the
- # "Add to Load" button. This function will read the current data
- # on the panel into a dictionary. then reset the list of the animation
- # name list on this panel.(not the one in the animation panel...)
- #
- # This function won't load any animation....
- #
- #################################################################
- name = self.AnimName_1.get()
- self.animDic[name] = Filename.fromOsSpecific(self.AnimFile_1.getvalue()).getFullpath()
- if name in self.animList:
- pass
- else:
- self.animList.append(name)
- self.AnimName_1.setlist(self.animList)
- print self.animDic
- return
- def ok_press(self):
- #################################################################
- # ok_press(Self)
- # This functiion will be called when user click on the "OK"
- # button. This function will send a message along with the animation
- # file we wish to load for this actor.
- # Then, it will close the panel itself.
- #################################################################
- messenger.send('AW_AnimationLoad',[self.Actor,self.animDic])
- #print self.animDic
- self.quit()
- return
|