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.

This commit is contained in:
Justin Butler 2006-01-19 00:01:20 +00:00
parent 08a099ba3a
commit a998cf46cd
1 changed files with 142 additions and 42 deletions

View File

@ -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)