2
0
Эх сурвалжийг харах

A few bug fixes (play rate and hanle playing anims that could not be loaded) and support to be able to be used by the pirates editor.

Justin Butler 20 жил өмнө
parent
commit
a998cf46cd

+ 142 - 42
direct/src/tkpanels/AnimPanel.py

@@ -23,7 +23,7 @@ class AnimPanel(AppShell):
     usestatusarea  = 0
     index = 0
 
-    def __init__(self, aList =  [], parent = None, **kw):
+    def __init__(self, aList =  [], parent = None, session = None, **kw):
         INITOPT = Pmw.INITOPT
         if ((type(aList) == types.ListType) or
             (type(aList) == types.TupleType)):
@@ -37,13 +37,21 @@ class AnimPanel(AppShell):
             )
         self.defineoptions(kw, optiondefs)
 
+        # direct session that spawned me, if any, used
+        # for certain interactions with the session such
+        # as being able to see selected objects/actors
+        self.session = session
+
         self.frameHeight = 60 + (50 * len(self['actorList']))
         self.playList =  []
         self.id = 'AnimPanel_%d' % AnimPanel.index
         AnimPanel.index += 1
+        # current index used for creating new actor controls
+        self.actorControlIndex = 0
         # Initialize the superclass
         AppShell.__init__(self)
 
+
         # Execute option callbacks
         self.initialiseoptions(AnimPanel)
 
@@ -106,42 +114,8 @@ class AnimPanel(AppShell):
             command = self.displayFrameCounts)
         b.pack(side = RIGHT, expand = 0)
 
-        # Create a frame to hold all the actor controls
-        actorFrame = Frame(interior)
-
-        # Create a control for each actor
-        index = 0
-        self.actorControlList = []
-        for actor in self['actorList']:
-            anims = actor.getAnimNames()
-            topAnims = []
-            if 'neutral' in anims:
-                i = anims.index('neutral')
-                del(anims[i])
-                topAnims.append('neutral')
-            if 'walk' in anims:
-                i = anims.index('walk')
-                del(anims[i])
-                topAnims.append('walk')
-            if 'run' in anims:
-                i = anims.index('run')
-                del(anims[i])
-                topAnims.append('run')
-            anims.sort()
-            anims = topAnims + anims
-            ac = self.createcomponent(
-                'actorControl%d' % index, (), 'Actor',
-                ActorControl, (actorFrame,),
-                animPanel = self,
-                text = actor.getName(),
-                animList = anims,
-                actor = actor)
-            ac.pack(expand = 1, fill = X)
-            self.actorControlList.append(ac)
-            index = index + 1
-
-        # Now pack the actor frame
-        actorFrame.pack(expand = 1, fill = BOTH)
+        self.actorFrame = None
+        self.createActorControls()
 
         # Create a frame to hold the playback controls
         controlFrame = Frame(interior)
@@ -184,8 +158,118 @@ class AnimPanel(AppShell):
             variable = self.loopVar)
         self.loopButton.pack(side = LEFT, expand = 1, fill = X)
 
+        # add actors and animations, only allowed if a direct
+        # session has been specified since these currently require
+        # interaction with selected objects
+        if (self.session):
+            menuBar.addmenuitem('File', 'command',
+                                'Set currently selected group of objects as actors to animate.',
+                                label = 'Set Actors',
+                                command = self.setActors)
+            menuBar.addmenuitem('File', 'command',
+                                'Load animation file',
+                                label = 'Load Anim',
+                                command = self.loadAnim)
+
         controlFrame.pack(fill = X)
 
+    def createActorControls(self):
+        # Create a frame to hold all the actor controls
+        self.actorFrame = Frame(self.interior())
+        # Create a control for each actor
+        self.actorControlList = []
+        for actor in self['actorList']:
+            anims = actor.getAnimNames()
+            print "actor animnames: %s"%anims
+            topAnims = []
+            if 'neutral' in anims:
+                i = anims.index('neutral')
+                del(anims[i])
+                topAnims.append('neutral')
+            if 'walk' in anims:
+                i = anims.index('walk')
+                del(anims[i])
+                topAnims.append('walk')
+            if 'run' in anims:
+                i = anims.index('run')
+                del(anims[i])
+                topAnims.append('run')
+            anims.sort()
+            anims = topAnims + anims
+            if (len(anims)== 0):
+                # no animations set for this actor, don't
+                # display the control panel
+                continue
+#            currComponents = self.components()
+#            if ('actorControl%d' % index in currComponents):
+#                self.destroycomponent('actorControl%d' % index)
+#            ac = self.component('actorControl%d' % index)
+#            if (ac == None):
+            ac = self.createcomponent(
+                'actorControl%d' % self.actorControlIndex, (), 'Actor',
+                ActorControl, (self.actorFrame,),
+                animPanel = self,
+                text = actor.getName(),
+                animList = anims,
+                actor = actor)
+            ac.pack(expand = 1, fill = X)
+            self.actorControlList.append(ac)
+            self.actorControlIndex = self.actorControlIndex + 1
+
+        # Now pack the actor frame
+        self.actorFrame.pack(expand = 1, fill = BOTH)
+
+    def clearActorControls(self):
+        if (self.actorFrame):
+            self.actorFrame.forget()
+            self.actorFrame.destroy()
+            self.actorFrame = None
+
+    def setActors(self):
+        self.stopActorControls()
+        actors = self.session.getSelectedActors()
+        # make sure selected objects are actors, if not don't
+        # use?
+        aList = []
+        for currActor in actors:
+            aList.append(currActor)
+        self['actorList'] = aList
+
+        self.clearActorControls()
+        self.createActorControls()
+
+    def loadAnim(self):
+        # bring up file open box to allow selection of an
+        # animation file
+        animFilename = askopenfilename(
+            defaultextension = '.mb',
+            filetypes = (('Maya Models', '*.mb'),
+                         ('All files', '*')),
+            initialdir = '/i/beta',
+            title = 'Load Animation',
+            parent = self.component('hull')
+            )
+        if (animFilename == ''):
+            # no file selected, canceled
+            return
+
+        # add directory where animation was loaded from to the
+        # current model path so any further searches for the file
+        # can find it
+        fileDirName = os.path.dirname(animFilename)
+        fileBaseName = os.path.basename(animFilename)
+        fileBaseNameBase = os.path.splitext(fileBaseName)[0]
+        fileDirNameFN = Filename(fileDirName)
+        fileDirNameFN.makeCanonical()
+        getModelPath().prependDirectory(fileDirNameFN)
+        for currActor in self['actorList']:
+            # replace all currently loaded anims with specified one
+#            currActor.unloadAnims(None,None,None)
+            currActor.loadAnims({fileBaseNameBase:fileBaseNameBase})
+        self.clearActorControls()
+        self.createActorControls()
+
+
     def playActorControls(self):
         self.stopActorControls()
         self.lastT = globalClock.getFrameTime()
@@ -200,7 +284,8 @@ class AnimPanel(AppShell):
         deltaT = currT - self.lastT
         self.lastT = currT
         for actorControl in self.playList:
-            actorControl.play(deltaT, fLoop)
+            # scale time by play rate value
+            actorControl.play(deltaT * actorControl.playRate, fLoop)
         return Task.cont
 
     def stopActorControls(self):
@@ -380,6 +465,7 @@ class ActorControl(Pmw.MegaWidget):
 
         # Execute option callbacks
         self.initialiseoptions(ActorControl)
+        self.playRate = 1.0
         self.updateDisplay()
 
     def _updateLabelText(self):
@@ -389,9 +475,18 @@ class ActorControl(Pmw.MegaWidget):
         actor = self['actor']
         active = self['active']
         self.fps = actor.getFrameRate(active)
-        self.duration = actor.getDuration(active)
-        self.maxFrame = actor.getNumFrames(active) - 1
-        self.maxSeconds = self.offset + self.duration
+        if (self.fps == None):
+            # there was probably a problem loading the
+            # active animation, set default anim properties
+            print "unable to get animation fps, zeroing out animation info"
+            self.fps = 24
+            self.duration = 0
+            self.maxFrame = 0
+            self.maxSeconds = 0
+        else:
+            self.duration = actor.getDuration(active)
+            self.maxFrame = actor.getNumFrames(active) - 1
+            self.maxSeconds = self.offset + self.duration
         # switch between showing frame counts and seconds
         if self.unitsVar.get() == FRAMES:
             # these are approximate due to discrete frame size
@@ -427,7 +522,12 @@ class ActorControl(Pmw.MegaWidget):
         self.resetToZero()
 
     def setPlayRate(self, rate):
+        # set play rate on the actor, although for the AnimPanel
+        # purpose we dont use the actor's play rate, but rather
+        # the self.playRate value since we drive the animation
+        # playback ourselves
         self['actor'].setPlayRate(eval(rate), self['active'])
+        self.playRate = eval(rate)
         self.updateDisplay()
 
     def setOffset(self):
@@ -456,7 +556,7 @@ class ActorControl(Pmw.MegaWidget):
         if self.frameActiveVar.get():
             # Compute new time
             self.currT = self.currT + deltaT
-            if fLoop:
+            if fLoop and self.duration:
                 # If its looping compute modulo
                 loopT = self.currT % self.duration
                 self.goToT(loopT)