Browse Source

*** empty log message ***

Mark Mine 24 years ago
parent
commit
041881345b
2 changed files with 196 additions and 54 deletions
  1. 46 1
      direct/src/actor/Actor.py
  2. 150 53
      direct/src/tkpanels/AnimPanel.py

+ 46 - 1
direct/src/actor/Actor.py

@@ -196,7 +196,52 @@ class Actor(PandaObject, NodePath):
         Actor print function"""
         Actor print function"""
         return "Actor: partBundleDict = %s,\n animControlDict = %s" % \
         return "Actor: partBundleDict = %s,\n animControlDict = %s" % \
                (self.__partBundleDict, self.__animControlDict)
                (self.__partBundleDict, self.__animControlDict)
-        
+
+    def getActorInfo(self):
+        """getActorInfo(self)
+        Utility function to create a list of information about a actor.
+        Useful for iterating over details of an actor.
+        """
+        lodInfo = []
+        for lodName in self.__animControlDict.keys():
+            partDict = self.__animControlDict[lodName]
+            partInfo = []
+            for partName in partDict.keys():
+                partBundle = self.__partBundleDict[lodName][partName]
+                animDict = partDict[partName]
+                animInfo = []
+                for animName in animDict.keys():
+                    file = animDict[animName][0]
+                    animControl = animDict[animName][1]
+                    animInfo.append([animName, file, animControl])
+                partInfo.append([partName, partBundle, animInfo])
+            lodInfo.append([lodName, partInfo])
+        return lodInfo
+
+    def getAnimNames(self):
+        animNames = []
+        for lodName, lodInfo in self.getActorInfo():
+            for partName, bundle, animInfo in lodInfo:
+                for animName, file, animControl in animInfo:
+                    if animName not in animNames:
+                        animNames.append(animName)
+        return animNames
+
+    def pprint(self):
+        """pprint(self)
+        Pretty print actor's details
+        """
+        for lodName, lodInfo in self.getActorInfo():
+            print 'LOD:', lodName
+            for partName, bundle, animInfo in lodInfo:
+                print '  Part:', partName
+                print '  Bundle:', `bundle`
+                for animName, file, animControl in animInfo:
+                    print '    Anim:', animName
+                    print '      File:', file
+                    print ('      NumFrames: %d PlayRate: %0.2f' %
+                           (animControl.getNumFrames(),
+                            animControl.getPlayRate()))
 
 
     def cleanup(self):
     def cleanup(self):
         """cleanup(self)
         """cleanup(self)

+ 150 - 53
direct/src/tkpanels/AnimPanel.py

@@ -7,6 +7,7 @@ from tkSimpleDialog import askfloat
 import Pmw
 import Pmw
 import string
 import string
 import math
 import math
+import types
 
 
 FRAMES = 0
 FRAMES = 0
 SECONDS = 1
 SECONDS = 1
@@ -19,11 +20,16 @@ class AnimPanel(AppShell):
     usecommandarea = 0
     usecommandarea = 0
     usestatusarea  = 0
     usestatusarea  = 0
 
 
-    def __init__(self, parent = None, **kw):
+    def __init__(self, aList =  [], parent = None, **kw):
         INITOPT = Pmw.INITOPT
         INITOPT = Pmw.INITOPT
+        if ((type(aList) == types.ListType) or
+            (type(aList) == types.TupleType)):
+            kw['actorList'] = aList
+        else:
+            kw['actorList'] = [aList]
         optiondefs = (
         optiondefs = (
             ('title',               self.appname,       None),
             ('title',               self.appname,       None),
-            ('actorList',           (),                 None),
+            ('actorList',           [],                 None),
             ('Actor_label_width',   12,                 None),
             ('Actor_label_width',   12,                 None),
             )
             )
         self.defineoptions(kw, optiondefs)
         self.defineoptions(kw, optiondefs)
@@ -63,9 +69,36 @@ class AnimPanel(AppShell):
                             command = self.displaySeconds)
                             command = self.displaySeconds)
         # Reset all actor controls
         # Reset all actor controls
         menuBar.addmenuitem('AnimPanel', 'command',
         menuBar.addmenuitem('AnimPanel', 'command',
-                            'Reset Actor controls',
-                            label = 'Reset all',
-                            command = self.resetAll)
+                            'Reset Actor controls to zero',
+                            label = 'Reset all to zero',
+                            command = self.resetAllToZero)
+        menuBar.addmenuitem('AnimPanel', 'command',
+                            'Reset Actor controls to end time',
+                            label = 'Reset all to end time',
+                            command = self.resetAllToEnd)
+
+        # Add some buttons to update all Actor Controls
+        self.fToggleAll = 1
+        b = self.createcomponent(
+            'toggleEnableButton', (), None,
+            Button, (self.menuFrame,),
+            text = 'Toggle Enable',
+            command = self.toggleAllControls)
+        b.pack(side = RIGHT, expand = 0)
+            
+        b = self.createcomponent(
+            'showSecondsButton', (), None,
+            Button, (self.menuFrame,),
+            text = 'Show Seconds',
+            command = self.displaySeconds)
+        b.pack(side = RIGHT, expand = 0)
+
+        b = self.createcomponent(
+            'showFramesButton', (), None,
+            Button, (self.menuFrame,),
+            text = 'Show Frames',
+            command = self.displayFrameCounts)
+        b.pack(side = RIGHT, expand = 0)
 
 
         # Create a frame to hold all the actor controls
         # Create a frame to hold all the actor controls
         actorFrame = Frame(interior)
         actorFrame = Frame(interior)
@@ -76,7 +109,10 @@ class AnimPanel(AppShell):
         for actor in self['actorList']:
         for actor in self['actorList']:
             ac = self.createcomponent(
             ac = self.createcomponent(
                 'actorControl%d' % index, (), 'Actor',
                 'actorControl%d' % index, (), 'Actor',
-                ActorControl, (actorFrame,))
+                ActorControl, (actorFrame,),
+                text = actor.getName(),
+                animList = actor.getAnimNames(),
+                actor = actor)
             ac.pack(expand = 1, fill = X)
             ac.pack(expand = 1, fill = X)
             self.actorControlList.append(ac)
             self.actorControlList.append(ac)
             index = index + 1
             index = index + 1
@@ -86,23 +122,35 @@ class AnimPanel(AppShell):
 
 
         # Create a frame to hold the playback controls
         # Create a frame to hold the playback controls
         controlFrame = Frame(interior)
         controlFrame = Frame(interior)
-        self.playPauseVar = IntVar()
-        self.playPauseVar.set(0)
-        self.playPauseButton = self.createcomponent(
+        self.toStartButton = self.createcomponent(
+            'toStart', (), None,
+            Button, (controlFrame,),
+            text = '<<',
+            width = 8,
+            command = self.resetAllToZero)
+        self.toStartButton.pack(side = LEFT, expand = 1, fill = X)
+        
+        self.playButton = self.createcomponent(
             'playPause', (), None,
             'playPause', (), None,
-            Checkbutton, (controlFrame,),
+            Button, (controlFrame,),
             text = 'Play', width = 8,
             text = 'Play', width = 8,
-            variable = self.playPauseVar,
-            indicatoron = FALSE)
-        self.playPauseButton.pack(side = LEFT, expand = 1, fill = X)
+            command = self.playActorControls)
+        self.playButton.pack(side = LEFT, expand = 1, fill = X)
 
 
-        self.resetButton = self.createcomponent(
-            'reset', (), None,
+        self.stopButton = self.createcomponent(
+            'playPause', (), None,
             Button, (controlFrame,),
             Button, (controlFrame,),
-            text = 'Reset All',
+            text = 'Stop', width = 8,
+            command = self.stopActorControls)
+        self.stopButton.pack(side = LEFT, expand = 1, fill = X)
+
+        self.toEndButton = self.createcomponent(
+            'toEnd', (), None,
+            Button, (controlFrame,),
+            text = '>>',
             width = 8,
             width = 8,
-            command = self.resetAll)
-        self.resetButton.pack(side = LEFT, expand = 1, fill = X)
+            command = self.resetAllToEnd)
+        self.toEndButton.pack(side = LEFT, expand = 1, fill = X)
         
         
         self.loopVar = IntVar()
         self.loopVar = IntVar()
         self.loopVar.set(0)
         self.loopVar.set(0)
@@ -115,12 +163,28 @@ class AnimPanel(AppShell):
 
 
         controlFrame.pack(fill = X)
         controlFrame.pack(fill = X)
 
 
+    def playActorControls(self):
+        fLoop = self.loopVar.get()
+        for actorControl in self.actorControlList:
+            actorControl.play(fLoop)
+
+    def stopActorControls(self):
+        for actorControl in self.actorControlList:
+            actorControl.stop()
+
     def getActorControlAt(self, index):
     def getActorControlAt(self, index):
         return self.actorControlList[index]
         return self.actorControlList[index]
 
 
     def enableActorControlAt(self,index):
     def enableActorControlAt(self,index):
         self.getActorControlAt(index).enableControl()
         self.getActorControlAt(index).enableControl()
 
 
+    def toggleAllControls(self):
+        if self.fToggleAll:
+            self.disableActorControls()
+        else:
+            self.enableActorControls()
+        self.fToggleAll = 1 - self.fToggleAll
+        
     def enableActorControls(self):
     def enableActorControls(self):
         for actorControl in self.actorControlList:
         for actorControl in self.actorControlList:
             actorControl.enableControl()
             actorControl.enableControl()
@@ -140,9 +204,13 @@ class AnimPanel(AppShell):
         for actorControl in self.actorControlList:
         for actorControl in self.actorControlList:
             actorControl.displaySeconds()
             actorControl.displaySeconds()
 
 
-    def resetAll(self):
+    def resetAllToZero(self):
+        for actorControl in self.actorControlList:
+            actorControl.resetToZero()
+
+    def resetAllToEnd(self):
         for actorControl in self.actorControlList:
         for actorControl in self.actorControlList:
-            actorControl.reset()
+            actorControl.resetToEnd()
 
 
 class ActorControl(Pmw.MegaWidget):
 class ActorControl(Pmw.MegaWidget):
     def __init__(self, parent = None, **kw):
     def __init__(self, parent = None, **kw):
@@ -150,17 +218,20 @@ class ActorControl(Pmw.MegaWidget):
         INITOPT = Pmw.INITOPT
         INITOPT = Pmw.INITOPT
         DEFAULT_FONT = (('MS', 'Sans', 'Serif'), 12, 'bold')
         DEFAULT_FONT = (('MS', 'Sans', 'Serif'), 12, 'bold')
         DEFAULT_ANIMS = ('neutral', 'run', 'walk')
         DEFAULT_ANIMS = ('neutral', 'run', 'walk')
+        animList = kw.get('animList', DEFAULT_ANIMS)
+        if len(animList) > 0:
+            initActive = animList[0]
+        else:
+            initActive = DEFAULT_ANIMS[0]
         optiondefs = (
         optiondefs = (
             ('text',            'Actor',            self._updateLabelText),
             ('text',            'Actor',            self._updateLabelText),
             ('actor',           None,               None),
             ('actor',           None,               None),
             ('animList',        DEFAULT_ANIMS,      None),
             ('animList',        DEFAULT_ANIMS,      None),
+            ('active',          initActive,         None),
             ('sLabel_width',    5,                  None),
             ('sLabel_width',    5,                  None),
             ('sLabel_font',     DEFAULT_FONT,       None),
             ('sLabel_font',     DEFAULT_FONT,       None),
             )
             )
         self.defineoptions(kw, optiondefs)
         self.defineoptions(kw, optiondefs)
-        self.addoptions(
-            (('active',      self['animList'][0],    None),)
-            )
 
 
         # Initialize the superclass
         # Initialize the superclass
         Pmw.MegaWidget.__init__(self, parent)
         Pmw.MegaWidget.__init__(self, parent)
@@ -171,9 +242,7 @@ class ActorControl(Pmw.MegaWidget):
 
 
         # Instance variables
         # Instance variables
         self.offset = 0.0
         self.offset = 0.0
-        self.fps = 24.0
-        self.maxFrame = 120
-        self.maxSeconds = self.maxFrame / self.fps
+        self.maxFrame = 1.0
 
 
         # Create component widgets
         # Create component widgets
         self._label = self.createcomponent(
         self._label = self.createcomponent(
@@ -201,7 +270,7 @@ class ActorControl(Pmw.MegaWidget):
         # Items for top level menu
         # Items for top level menu
         labelMenu.add_cascade(label = 'Display Units', menu = displayMenu)
         labelMenu.add_cascade(label = 'Display Units', menu = displayMenu)
         labelMenu.add_command(label = 'Set Offset', command = self.setOffset)
         labelMenu.add_command(label = 'Set Offset', command = self.setOffset)
-        labelMenu.add_command(label = 'Reset', command = self.reset)
+        labelMenu.add_command(label = 'Reset', command = self.resetToZero)
         # Now associate menu with menubutton
         # Now associate menu with menubutton
         self._label['menu'] = labelMenu
         self._label['menu'] = labelMenu
         self._label.pack(side = LEFT, fill = X)
         self._label.pack(side = LEFT, fill = X)
@@ -217,19 +286,23 @@ class ActorControl(Pmw.MegaWidget):
         animMenu.pack(side = 'left', padx = 5, expand = 0)
         animMenu.pack(side = 'left', padx = 5, expand = 0)
 
 
         # Combo box to select frame rate
         # Combo box to select frame rate
-        fpsList = (1,2,4,8,12,15,24,30)
-        fpsMenu = self.createcomponent(
-            'fpsMenu', (), None,
+        playRateList = [1/24.0, 0.1, 0.5, 1.0, 2.0,5.0,10.0]
+        playRate = self['actor'].getPlayRate(self['active'])
+        if playRate not in playRateList:
+            playRateList.append(playRate)
+            playRateList.sort
+        playRateMenu = self.createcomponent(
+            'playRateMenu', (), None,
             Pmw.ComboBox, (interior,),
             Pmw.ComboBox, (interior,),
-            labelpos = W, label_text = 'at:',
-            entry_width = 4, selectioncommand = self.setFrameRate,
-            scrolledlist_items = fpsList)
-        fpsMenu.selectitem('24')
-        fpsMenu.pack(side = LEFT, padx = 5, expand = 0)
+            labelpos = W, label_text = 'X',
+            entry_width = 4, selectioncommand = self.setPlayRate,
+            scrolledlist_items = playRateList)
+        playRateMenu.selectitem(`playRate`)
+        playRateMenu.pack(side = LEFT, padx = 5, expand = 0)
 
 
         # A label
         # A label
-        fpsLabel = Label(interior, text = "fps")
-        fpsLabel.pack(side = LEFT)
+        playRateLabel = Label(interior, text = 'speed')
+        playRateLabel.pack(side = LEFT)
 
 
         # Scale to control animation
         # Scale to control animation
         frameFrame = Frame(interior, relief = SUNKEN, bd = 1)
         frameFrame = Frame(interior, relief = SUNKEN, bd = 1)
@@ -243,6 +316,7 @@ class ActorControl(Pmw.MegaWidget):
             'scale', (), None,
             'scale', (), None,
             Scale, (frameFrame,),
             Scale, (frameFrame,),
             from_ = 0.0, to = self.maxFrame, resolution = 1.0,
             from_ = 0.0, to = self.maxFrame, resolution = 1.0,
+            command = self.goTo,
             orient = HORIZONTAL, showvalue = 1)
             orient = HORIZONTAL, showvalue = 1)
         self.frameControl.pack(side = LEFT, expand = 1)
         self.frameControl.pack(side = LEFT, expand = 1)
 
 
@@ -263,12 +337,18 @@ class ActorControl(Pmw.MegaWidget):
         frameActive.pack(side = LEFT, expand = 1)
         frameActive.pack(side = LEFT, expand = 1)
 
 
         # Execute option callbacks
         # Execute option callbacks
-        self.initialiseoptions(ActorControl)        
+        self.initialiseoptions(ActorControl)
+        self.updateDisplay()
 
 
     def _updateLabelText(self):
     def _updateLabelText(self):
         self._label['text'] = self['text']
         self._label['text'] = self['text']
 
 
     def updateDisplay(self):
     def updateDisplay(self):
+        actor = self['actor']
+        active = self['active']
+        self.fps = actor.getFrameRate(active)
+        self.maxFrame = actor.getNumFrames(active) - 1
+        self.maxSeconds = self.maxFrame / self.fps
         # Switch between showing frame counts and seconds
         # Switch between showing frame counts and seconds
         if self.unitsVar.get() == FRAMES:
         if self.unitsVar.get() == FRAMES:
             newMin = int(math.floor(self.offset * self.fps))
             newMin = int(math.floor(self.offset * self.fps))
@@ -281,22 +361,21 @@ class ActorControl(Pmw.MegaWidget):
             newMax = self.offset + self.maxSeconds
             newMax = self.offset + self.maxSeconds
             self.minLabel['text'] = "%.1f" % newMin
             self.minLabel['text'] = "%.1f" % newMin
             self.maxLabel['text'] = "%.1f" % newMax
             self.maxLabel['text'] = "%.1f" % newMax
-            print newMin, newMax
-            self.frameControl.configure(to = newMax, resolution = 0.1)
+            self.frameControl.configure(to = newMax, resolution = 0.01)
 
 
     def selectAnimNamed(self, name):
     def selectAnimNamed(self, name):
-        print 'Selected Anim: ' + name
+        self['active'] = name
+        self.updateDisplay()
 
 
-    def setFrameRate(self, rate):
-        self.fps = string.atof(rate)
-        self.maxSeconds = self.maxFrame / self.fps
+    def setPlayRate(self, rate):
+        self['actor'].setPlayRate(eval(rate), self['active'])
         self.updateDisplay()
         self.updateDisplay()
 
 
     def setOffset(self):
     def setOffset(self):
         newOffset = askfloat(parent = self.interior(),
         newOffset = askfloat(parent = self.interior(),
                              title = self['text'],
                              title = self['text'],
                              prompt = 'Start offset (seconds):')
                              prompt = 'Start offset (seconds):')
-        if newOffset:
+        if newOffset != None:
             self.offset = newOffset
             self.offset = newOffset
             self.updateDisplay()
             self.updateDisplay()
 
 
@@ -314,13 +393,31 @@ class ActorControl(Pmw.MegaWidget):
         self.unitsVar.set(SECONDS)
         self.unitsVar.set(SECONDS)
         self.updateDisplay()
         self.updateDisplay()
 
 
-    def reset(self):
-        self.offset = 0.0
-        self.frameControl.set(0.0)
-        self.updateDisplay()
-######################################################################
+    def play(self, fLoop):
+        if self.frameActiveVar.get():
+            if fLoop:
+                self['actor'].loop(self['active'])
+            else:
+                self['actor'].play(self['active'])
 
 
-# Create demo in root window for testing.
-if __name__ == '__main__':
-    widget = AnimPanel(actorList = (1,2,3))
+    def goTo(self, t):
+        if self.unitsVar.get() == FRAMES:
+            self['actor'].pose(self['active'], string.atoi(t))
+        else:
+            self['actor'].pose(self['active'], int(string.atof(t) * self.fps))
+
+    def stop(self):
+        if self.frameActiveVar.get():
+            self['actor'].stop()
 
 
+    def resetToZero(self):
+        self.frameControl.set(0.0)
+        
+    def resetToEnd(self):
+        if self.unitsVar.get() == FRAMES:
+            t = self.maxFrame
+        else:
+            t = self.maxFrame / self.fps
+        self.frameControl.set(t)
+        
+