mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
*** empty log message ***
This commit is contained in:
parent
b576991038
commit
ae843d2401
@ -4,43 +4,46 @@ from PandaModules import *
|
||||
from Interval import *
|
||||
|
||||
class AnimInterval(Interval):
|
||||
|
||||
# Name counter
|
||||
animNum = 1
|
||||
|
||||
# special methods
|
||||
|
||||
# Class methods
|
||||
def __init__(self, animControl, loop=0, name=None):
|
||||
"""__init__(name)
|
||||
"""
|
||||
# Record class specific variables
|
||||
self.animControl = animControl
|
||||
duration = (float(animControl.getNumFrames()) /
|
||||
animControl.getFrameRate())
|
||||
self.loop = loop
|
||||
# Generate unique name if necessary
|
||||
if (name == None):
|
||||
n = 'Anim-%d' % self.animNum
|
||||
self.animNum = self.animNum + 1
|
||||
else:
|
||||
n = name
|
||||
Interval.__init__(self, n, duration)
|
||||
name = 'Anim-%d' % AnimInterval.animNum
|
||||
AnimInterval.animNum += 1
|
||||
# Compute anim duration
|
||||
duration = (float(animControl.getNumFrames()) /
|
||||
animControl.getFrameRate())
|
||||
# Initialize superclass
|
||||
Interval.__init__(self, name, duration)
|
||||
|
||||
def setT(self, t, entry=0):
|
||||
""" setT(t, entry)
|
||||
def updateFunc(self, t, event = IVAL_NONE):
|
||||
""" updateFunc(t, event)
|
||||
Go to time t
|
||||
"""
|
||||
if (t < 0):
|
||||
return
|
||||
elif (t > self.duration):
|
||||
# Update animation based upon current time
|
||||
if (t == self.getDuration()):
|
||||
if (self.isPlaying == 1):
|
||||
self.isPlaying = 0
|
||||
if (self.loop):
|
||||
self.animControl.stop()
|
||||
return
|
||||
elif (entry == 1):
|
||||
else:
|
||||
# Set flag
|
||||
self.isPlaying = 1
|
||||
# Determine the current frame
|
||||
frame = int(self.animControl.getFrameRate() * t)
|
||||
# Pose anim
|
||||
if (self.loop):
|
||||
self.animControl.pos(frame)
|
||||
self.animControl.loop(0)
|
||||
else:
|
||||
self.animControl.play(frame, self.animControl.getNumFrames())
|
||||
|
||||
|
||||
|
||||
|
@ -5,33 +5,28 @@ from Interval import *
|
||||
from MessengerGlobal import *
|
||||
|
||||
class FunctionInterval(Interval):
|
||||
|
||||
# Name counter
|
||||
functionIntervalNum = 1
|
||||
|
||||
# special methods
|
||||
def __init__(self, function, name = None):
|
||||
# Class methods
|
||||
def __init__(self, function, name = None, openEnded = 1):
|
||||
"""__init__(function, name = None)
|
||||
"""
|
||||
duration = 0.0
|
||||
self.prevt = 0.0
|
||||
# Record instance variables
|
||||
self.function = function
|
||||
|
||||
# Create a unique name for the interval if necessary
|
||||
if (name == None):
|
||||
name = 'FunctionInterval-%d' % FunctionInterval.functionIntervalNum
|
||||
FunctionInterval.functionIntervalNum += 1
|
||||
|
||||
Interval.__init__(self, name, duration)
|
||||
|
||||
def setT(self, t, entry=0):
|
||||
""" setT(t, entry)
|
||||
# Initialize superclass
|
||||
# Set openEnded true if calls after end time cause interval
|
||||
# function to be called
|
||||
Interval.__init__(self, name, duration = 0.0, openEnded = openEnded)
|
||||
def updateFunc(self, t, event = IVAL_NONE):
|
||||
""" updateFunc(t, event)
|
||||
Go to time t
|
||||
"""
|
||||
if (t < 0):
|
||||
self.prevt = t
|
||||
return
|
||||
elif (t == 0) or (self.prevt < 0):
|
||||
self.function()
|
||||
self.prevt = 0.0
|
||||
# Evaluate the function
|
||||
self.function()
|
||||
|
||||
### FunctionInterval subclass for throwing events ###
|
||||
class EventInterval(FunctionInterval):
|
||||
@ -42,7 +37,8 @@ class EventInterval(FunctionInterval):
|
||||
def sendFunc(event = event, sentArgs = sentArgs):
|
||||
messenger.send(event, sentArgs)
|
||||
# Create function interval
|
||||
FunctionInterval.__init__(self, sendFunc, name = event)
|
||||
FunctionInterval.__init__(self, sendFunc, name = event,
|
||||
openEnded = 0)
|
||||
|
||||
### FunctionInterval subclass for accepting hooks ###
|
||||
class AcceptInterval(FunctionInterval):
|
||||
@ -54,7 +50,8 @@ class AcceptInterval(FunctionInterval):
|
||||
print "accepting..."
|
||||
dirObj.accept(event, function)
|
||||
# Create function interval
|
||||
FunctionInterval.__init__(self, acceptFunc, name = name)
|
||||
FunctionInterval.__init__(self, acceptFunc, name = name,
|
||||
openEnded = 0)
|
||||
|
||||
### FunctionInterval subclass for throwing events ###
|
||||
class IgnoreInterval(FunctionInterval):
|
||||
@ -66,7 +63,8 @@ class IgnoreInterval(FunctionInterval):
|
||||
print "ignoring..."
|
||||
dirObj.ignore(event)
|
||||
# Create function interval
|
||||
FunctionInterval.__init__(self, ignoreFunc, name = name)
|
||||
FunctionInterval.__init__(self, ignoreFunc, name = name,
|
||||
openEnded = 0)
|
||||
|
||||
### Function Interval subclass for adjusting scene graph hierarchy ###
|
||||
class ParentInterval(FunctionInterval):
|
||||
@ -97,7 +95,8 @@ class WrtParentInterval(FunctionInterval):
|
||||
nodePath.wrtReparentTo(parent)
|
||||
# Determine name
|
||||
if (name == None):
|
||||
name = 'WrtParentInterval-%d' % WrtParentInterval.wrtParentIntervalNum
|
||||
name = ('WrtParentInterval-%d' %
|
||||
WrtParentInterval.wrtParentIntervalNum)
|
||||
WrtParentInterval.wrtParentIntervalNum += 1
|
||||
# Create function interval
|
||||
FunctionInterval.__init__(self, wrtReparentFunc, name = name)
|
||||
@ -210,7 +209,6 @@ class PosHprScaleInterval(FunctionInterval):
|
||||
# Create function interval
|
||||
FunctionInterval.__init__(self, posHprScaleFunc, name = name)
|
||||
|
||||
|
||||
"""
|
||||
SAMPLE CODE
|
||||
from IntervalGlobal import *
|
||||
@ -226,6 +224,7 @@ def printHello():
|
||||
i3 = FunctionInterval(printHello)
|
||||
# Create track
|
||||
t1 = Track([(0.0, i1), (2.0, i2), (4.0, i3)], name = 'demo')
|
||||
|
||||
# Play track
|
||||
t1.play()
|
||||
|
||||
|
@ -4,6 +4,10 @@ from DirectObject import *
|
||||
import ClockObject
|
||||
import Task
|
||||
|
||||
# Interval events
|
||||
IVAL_NONE = 0
|
||||
IVAL_INIT = 1
|
||||
|
||||
class Interval(DirectObject):
|
||||
"""Interval class: Base class for timeline functionality"""
|
||||
|
||||
@ -13,13 +17,17 @@ class Interval(DirectObject):
|
||||
|
||||
# special methods
|
||||
|
||||
def __init__(self, name, duration):
|
||||
def __init__(self, name, duration, openEnded = 1):
|
||||
"""__init__(name, duration)
|
||||
"""
|
||||
self.name = name
|
||||
self.duration = duration
|
||||
self.clock = ClockObject.ClockObject.getGlobalClock()
|
||||
self.curr_t = 0.0
|
||||
self.prev_t = 0.0
|
||||
self.setTHooks = []
|
||||
# Set true if interval responds to setT(t): t>duration
|
||||
self.fOpenEnded = openEnded
|
||||
|
||||
def getName(self):
|
||||
""" getName()
|
||||
@ -31,16 +39,40 @@ class Interval(DirectObject):
|
||||
"""
|
||||
return self.duration
|
||||
|
||||
def setT(self, t, entry=0):
|
||||
""" setT(t, entry)
|
||||
def setfOpenEnded(self, openEnded):
|
||||
""" setfOpenEnded(openEnded)
|
||||
"""
|
||||
self.fOpenEnded = openEnded
|
||||
|
||||
def getfOpenEnded(self):
|
||||
""" getfOpenEnded()
|
||||
"""
|
||||
return self.fOpenEnded
|
||||
|
||||
def setT(self, t, event = IVAL_NONE):
|
||||
""" setT(t, event)
|
||||
Go to time t
|
||||
"""
|
||||
pass
|
||||
# Update current time
|
||||
self.curr_t = t
|
||||
# Perform interval actions
|
||||
self.updateFunc(t, event)
|
||||
# Call setT Hook
|
||||
for func in self.setTHooks:
|
||||
func(t)
|
||||
# Record t for next time around
|
||||
self.prev_t = self.curr_t
|
||||
|
||||
def updateFunc(self, t, event = IVAL_NONE):
|
||||
pass
|
||||
|
||||
def setTHook(self, t):
|
||||
pass
|
||||
|
||||
def setFinalT(self):
|
||||
""" setFinalT()
|
||||
"""
|
||||
self.setT(self.getDuration(), entry=1)
|
||||
self.setT(self.getDuration(), event=IVAL_NONE)
|
||||
|
||||
def play(self, t0=0.0, duration=0.0, scale=1.0):
|
||||
""" play(t0, duration)
|
||||
@ -51,10 +83,10 @@ class Interval(DirectObject):
|
||||
self.scale = scale
|
||||
self.firstTime = 1
|
||||
if (duration == 0.0):
|
||||
self.playDuration = self.duration
|
||||
self.endTime = self.offset + self.duration
|
||||
else:
|
||||
self.playDuration = duration
|
||||
assert(t0 <= self.playDuration)
|
||||
self.endTime = self.offset + duration
|
||||
assert(t0 <= self.endTime)
|
||||
taskMgr.spawnMethodNamed(self.__playTask, self.name + '-play')
|
||||
|
||||
def stop(self):
|
||||
@ -68,16 +100,15 @@ class Interval(DirectObject):
|
||||
"""
|
||||
t = self.clock.getFrameTime()
|
||||
te = self.offset + ((t - self.startT) * self.scale)
|
||||
self.curr_t = te
|
||||
if (te <= self.playDuration):
|
||||
if (te <= self.endTime):
|
||||
if (self.firstTime):
|
||||
self.setT(te, entry=1)
|
||||
self.setT(te, event = IVAL_INIT)
|
||||
self.firstTime = 0
|
||||
else:
|
||||
self.setT(te)
|
||||
return Task.cont
|
||||
else:
|
||||
self.setT(self.playDuration)
|
||||
self.setT(self.endTime)
|
||||
return Task.done
|
||||
|
||||
def __repr__(self, indent=0):
|
||||
@ -86,16 +117,54 @@ class Interval(DirectObject):
|
||||
space = ''
|
||||
for l in range(indent):
|
||||
space = space + ' '
|
||||
return (space + self.name + ' dur: %.2f\n' % self.duration)
|
||||
return (space + self.name + ' dur: %.2f' % self.duration)
|
||||
|
||||
def popupControls(self):
|
||||
import fpformat
|
||||
import string
|
||||
# I moved this here because Toontown does not ship Tk
|
||||
from Tkinter import *
|
||||
import Pmw
|
||||
import EntryScale
|
||||
tl = Toplevel()
|
||||
tl.title(self.getName() + ' Interval Controls')
|
||||
es = EntryScale.EntryScale(
|
||||
tl, min = 0, max = self.duration,
|
||||
tl, text = 'Time',
|
||||
min = 0, max = string.atof(fpformat.fix(self.duration, 2)),
|
||||
command = lambda t, s = self: s.setT(t))
|
||||
es.onPress = lambda s=self: s.setT(s.curr_t, entry = 1)
|
||||
es.onRelease = lambda s=self, es = es: s.setT(es.get(),
|
||||
event = IVAL_INIT)
|
||||
es.onReturnRelease = lambda s=self, es = es: s.setT(es.get(),
|
||||
event = IVAL_INIT)
|
||||
es.pack(expand = 1, fill = X)
|
||||
f = Frame(tl)
|
||||
def toStart(s=self, es=es):
|
||||
s.stop()
|
||||
s.setT(0.0, event = IVAL_INIT)
|
||||
def toEnd(s=self):
|
||||
s.stop()
|
||||
s.setT(s.getDuration(), event = IVAL_INIT)
|
||||
jumpToStart = Button(tl, text = '<<', command = toStart)
|
||||
stop = Button(tl, text = 'Stop',
|
||||
command = lambda s=self: s.stop())
|
||||
play = Button(
|
||||
tl, text = 'Play',
|
||||
command = lambda s=self, es=es: s.play(es.get()))
|
||||
jumpToEnd = Button(tl, text = '>>', command = toEnd)
|
||||
jumpToStart.pack(side = LEFT, expand = 1, fill = X)
|
||||
play.pack(side = LEFT, expand = 1, fill = X)
|
||||
stop.pack(side = LEFT, expand = 1, fill = X)
|
||||
jumpToEnd.pack(side = LEFT, expand = 1, fill = X)
|
||||
f.pack(expand = 1, fill = X)
|
||||
# Add hook to update slider on changes in curr_t
|
||||
def update(t,es=es):
|
||||
es.set(t, fCommand = 0)
|
||||
self.setTHooks.append(update)
|
||||
# Clear out hook on destroy
|
||||
def onDestroy(e, s=self, u=update):
|
||||
if u in s.setTHooks:
|
||||
s.setTHooks.remove(u)
|
||||
tl.bind('<Destroy>', onDestroy)
|
||||
|
||||
|
||||
|
||||
|
@ -50,7 +50,7 @@ waterEventTrack.setIntervalStartTime('water-is-done', eventTime)
|
||||
|
||||
mtrack = MultiTrack([boatTrack, dockTrack, soundTrack, waterEventTrack])
|
||||
# Print out MultiTrack parameters
|
||||
mtrack
|
||||
print(mtrack)
|
||||
|
||||
def handleWaterDone():
|
||||
print 'water is done'
|
||||
|
@ -9,21 +9,20 @@ class LerpInterval(Interval):
|
||||
def __init__(self, name, duration, functorFunc, blendType='noBlend'):
|
||||
"""__init__(name, duration, functorFunc, blendType)
|
||||
"""
|
||||
self.lerp = None
|
||||
self.functorFunc = functorFunc
|
||||
self.blendType = self.getBlend(blendType)
|
||||
Interval.__init__(self, name, duration)
|
||||
def setT(self, t, entry=0):
|
||||
""" setT(t, entry)
|
||||
def updateFunc(self, t, event = IVAL_NONE):
|
||||
""" updateFunc(t, event)
|
||||
"""
|
||||
if (t < 0):
|
||||
return
|
||||
elif (entry == 1):
|
||||
# First check to see if we need to create the lerp
|
||||
if (event == IVAL_INIT):
|
||||
self.lerp = Lerp.Lerp(self.functorFunc(), self.duration,
|
||||
self.blendType)
|
||||
if (entry == 1) and (t > self.duration):
|
||||
self.lerp.setT(self.duration)
|
||||
elif (t <= self.duration):
|
||||
self.lerp.setT(t)
|
||||
self.blendType)
|
||||
# Now evaluate the lerp
|
||||
if self.lerp:
|
||||
self.lerp.setT(t)
|
||||
def getBlend(self, blendType):
|
||||
"""__getBlend(self, string)
|
||||
Return the C++ blend class corresponding to blendType string
|
||||
@ -42,9 +41,9 @@ class LerpInterval(Interval):
|
||||
'Error: LerpInterval.__getBlend: Unknown blend type')
|
||||
|
||||
class LerpPosInterval(LerpInterval):
|
||||
|
||||
# Name counter
|
||||
lerpPosNum = 1
|
||||
|
||||
# Class methods
|
||||
def __init__(self, node, duration, pos, startPos=None,
|
||||
other=None, blendType='noBlend', name=None):
|
||||
""" __init__(node, duration, pos, startPos, other, blendType, name)
|
||||
@ -66,18 +65,15 @@ class LerpPosInterval(LerpInterval):
|
||||
functor = PosLerpFunctor.PosLerpFunctor(
|
||||
node, startPos, pos)
|
||||
return functor
|
||||
|
||||
# Generate unique name if necessary
|
||||
if (name == None):
|
||||
n = 'LerpPosInterval-%d' % LerpPosInterval.lerpPosNum
|
||||
name = 'LerpPosInterval-%d' % LerpPosInterval.lerpPosNum
|
||||
LerpPosInterval.lerpPosNum += 1
|
||||
else:
|
||||
n = name
|
||||
|
||||
LerpInterval.__init__(self, n, duration, functorFunc, blendType)
|
||||
# Initialize superclass
|
||||
LerpInterval.__init__(self, name, duration, functorFunc, blendType)
|
||||
|
||||
class LerpHprInterval(LerpInterval):
|
||||
|
||||
# Interval counter
|
||||
# Name counter
|
||||
lerpHprNum = 1
|
||||
# Class methods
|
||||
def __init__(self, node, duration, hpr, startHpr=None,
|
||||
@ -101,14 +97,12 @@ class LerpHprInterval(LerpInterval):
|
||||
functor = HprLerpFunctor.HprLerpFunctor(
|
||||
node, startHpr, hpr)
|
||||
return functor
|
||||
|
||||
# Generate unique name if necessary
|
||||
if (name == None):
|
||||
n = 'LerpHprInterval-%d' % LerpHprInterval.lerpHprNum
|
||||
name = 'LerpHprInterval-%d' % LerpHprInterval.lerpHprNum
|
||||
LerpHprInterval.lerpHprNum += 1
|
||||
else:
|
||||
n = name
|
||||
|
||||
LerpInterval.__init__(self, n, duration, functorFunc, blendType)
|
||||
# Initialize superclass
|
||||
LerpInterval.__init__(self, name, duration, functorFunc, blendType)
|
||||
|
||||
class LerpScaleInterval(LerpInterval):
|
||||
|
||||
@ -137,13 +131,12 @@ class LerpScaleInterval(LerpInterval):
|
||||
node, startScale, scale)
|
||||
return functor
|
||||
|
||||
# Generate unique name if necessary
|
||||
if (name == None):
|
||||
n = 'LerpScaleInterval-%d' % LerpScaleInterval.lerpScaleNum
|
||||
name = 'LerpScaleInterval-%d' % LerpScaleInterval.lerpScaleNum
|
||||
LerpScaleInterval.lerpScaleNum += 1
|
||||
else:
|
||||
n = name
|
||||
|
||||
LerpInterval.__init__(self, n, duration, functorFunc, blendType)
|
||||
# Initialize superclass
|
||||
LerpInterval.__init__(self, name, duration, functorFunc, blendType)
|
||||
|
||||
class LerpPosHprInterval(LerpInterval):
|
||||
# Interval counter
|
||||
@ -179,13 +172,12 @@ class LerpPosHprInterval(LerpInterval):
|
||||
startHpr, hpr)
|
||||
return functor
|
||||
|
||||
# Generate unique name if necessary
|
||||
if (name == None):
|
||||
n = 'LerpPosHpr-%d' % LerpPosHprInterval.lerpPosHprNum
|
||||
name = 'LerpPosHpr-%d' % LerpPosHprInterval.lerpPosHprNum
|
||||
LerpPosHprInterval.lerpPosHprNum += 1
|
||||
else:
|
||||
n = name
|
||||
|
||||
LerpInterval.__init__(self, n, duration, functorFunc, blendType)
|
||||
# Initialize superclass
|
||||
LerpInterval.__init__(self, name, duration, functorFunc, blendType)
|
||||
|
||||
class LerpPosHprScaleInterval(LerpInterval):
|
||||
# Interval counter
|
||||
@ -226,14 +218,13 @@ class LerpPosHprScaleInterval(LerpInterval):
|
||||
node, startPos, pos, startHpr, hpr, startScale, scale)
|
||||
return functor
|
||||
|
||||
# Generate unique name if necessary
|
||||
if (name == None):
|
||||
n = ('LerpPosHprScale-%d' %
|
||||
LerpPosHprScaleInterval.lerpPosHprScaleNum)
|
||||
name = ('LerpPosHprScale-%d' %
|
||||
LerpPosHprScaleInterval.lerpPosHprScaleNum)
|
||||
LerpPosHprScaleInterval.lerpPosHprScaleNum += 1
|
||||
else:
|
||||
n = name
|
||||
|
||||
LerpInterval.__init__(self, n, duration, functorFunc, blendType)
|
||||
# Initialize superclass
|
||||
LerpInterval.__init__(self, name, duration, functorFunc, blendType)
|
||||
|
||||
# Class used to execute a function over time. Function can access fromData
|
||||
# and toData to perform blend
|
||||
@ -245,27 +236,29 @@ class LerpFunctionInterval(Interval):
|
||||
blendType = 'noBlend', name = None):
|
||||
"""__init__(function, duration, fromData, toData, name)
|
||||
"""
|
||||
# Record instance variables
|
||||
self.function = function
|
||||
self.fromData = fromData
|
||||
self.toData = toData
|
||||
self.blendType = self.getBlend(blendType)
|
||||
# Generate unique name if necessary
|
||||
if (name == None):
|
||||
name = ('LerpFunctionInterval-%d' %
|
||||
LerpFunctionInterval.lerpFunctionIntervalNum)
|
||||
LerpFunctionInterval.lerpFunctionIntervalNum += 1
|
||||
# Initialize superclass
|
||||
Interval.__init__(self, name, duration)
|
||||
def setT(self, t, entry=0):
|
||||
""" setT(t, entry)
|
||||
def updateFunc(self, t, event = IVAL_NONE):
|
||||
""" updateFunc(t, event)
|
||||
"""
|
||||
if (t < 0):
|
||||
return
|
||||
if (entry == 1) and (t > self.duration):
|
||||
self.function(self.toData)
|
||||
elif (t <= self.duration):
|
||||
# Evaluate the function
|
||||
if (t == self.duration):
|
||||
# Set to end value
|
||||
self.function(self.toData)
|
||||
else:
|
||||
# In the middle of the lerp, compute appropriate value
|
||||
try:
|
||||
#bt = self.blendType(t/self.duration)
|
||||
bt = t/self.duration
|
||||
bt = self.blendType(t/self.duration)
|
||||
data = (self.fromData * (1 - bt)) + (self.toData * bt)
|
||||
self.function(data)
|
||||
except ZeroDivisionError:
|
||||
|
@ -5,31 +5,25 @@ from Interval import *
|
||||
import Mopath
|
||||
|
||||
class MopathInterval(Interval):
|
||||
|
||||
# Name counter
|
||||
mopathNum = 1
|
||||
|
||||
# special methods
|
||||
|
||||
# Class methods
|
||||
def __init__(self, mopath, node, name=None):
|
||||
"""__init__(mopath, node, name)
|
||||
"""
|
||||
self.node = node
|
||||
self.mopath = mopath
|
||||
duration = self.mopath.getMaxT()
|
||||
self.node = node
|
||||
# Generate unique name if necessary
|
||||
if (name == None):
|
||||
n = 'Mopath-%d' % self.mopathNum
|
||||
self.mopathNum = self.mopathNum + 1
|
||||
else:
|
||||
n = name
|
||||
Interval.__init__(self, n, duration)
|
||||
name = 'Mopath-%d' % MopathInterval.mopathNum
|
||||
MopathInterval.mopathNum += 1
|
||||
# Compute duration
|
||||
duration = self.mopath.getMaxT()
|
||||
# Initialize superclass
|
||||
Interval.__init__(self, name, duration)
|
||||
|
||||
def setT(self, t, entry=0):
|
||||
""" setT(t, entry)
|
||||
def updateFunc(self, t, event = IVAL_NONE):
|
||||
""" updateFunc(t, event)
|
||||
Go to time t
|
||||
"""
|
||||
if (t < 0):
|
||||
return
|
||||
elif (entry == 1) and (t > self.duration):
|
||||
self.mopath.goTo(self.node, self.duration)
|
||||
else:
|
||||
self.mopath.goTo(self.node, t)
|
||||
self.mopath.goTo(self.node, t)
|
||||
|
@ -35,19 +35,17 @@ class MultiTrack(Interval):
|
||||
duration = dur
|
||||
return duration
|
||||
|
||||
def setT(self, t, entry=0):
|
||||
""" setT(t, entry)
|
||||
def updateFunc(self, t, event = IVAL_NONE):
|
||||
""" updateFunc(t, event)
|
||||
Go to time t
|
||||
"""
|
||||
if (t > self.duration):
|
||||
pass
|
||||
for track in self.tlist:
|
||||
track.setT(t, entry)
|
||||
track.setT(min(t, track.getDuration()), event)
|
||||
|
||||
def __repr__(self, indent=0):
|
||||
""" __repr__(indent)
|
||||
"""
|
||||
str = Interval.__repr__(self, indent)
|
||||
str = Interval.__repr__(self, indent) + '\n'
|
||||
for t in self.tlist:
|
||||
str = str + t.__repr__(indent+1)
|
||||
return str
|
||||
|
@ -4,43 +4,42 @@ from PandaModules import *
|
||||
from Interval import *
|
||||
|
||||
class SoundInterval(Interval):
|
||||
|
||||
# Name counter
|
||||
soundNum = 1
|
||||
|
||||
# special methods
|
||||
|
||||
# Class methods
|
||||
def __init__(self, sound, loop=0, name=None):
|
||||
"""__init__(sound, loop, name)
|
||||
"""
|
||||
self.sound = sound
|
||||
duration = self.sound.length()
|
||||
self.loop = loop
|
||||
self.isPlaying = 0
|
||||
# Generate unique name if necessary
|
||||
if (name == None):
|
||||
n = 'Sound-%d' % self.soundNum
|
||||
self.soundNum = self.soundNum + 1
|
||||
else:
|
||||
n = name
|
||||
self.prevt = 0.0
|
||||
Interval.__init__(self, n, duration)
|
||||
name = 'Sound-%d' % SoundInterval.soundNum
|
||||
SoundInterval.soundNum += 1
|
||||
# Calculate duration
|
||||
duration = self.sound.length()
|
||||
# Initialize superclass
|
||||
Interval.__init__(self, name, duration)
|
||||
|
||||
def setT(self, t, entry=0):
|
||||
""" setT(t, entry)
|
||||
Go to time t
|
||||
def updateFunc(self, t, event = IVAL_NONE):
|
||||
""" updateFunc(t, event)
|
||||
Go to time t
|
||||
"""
|
||||
if (t < 0):
|
||||
self.prevt = t
|
||||
return
|
||||
elif (t > self.duration):
|
||||
if(t == self.duration):
|
||||
# Stop sound if necessary
|
||||
if (self.isPlaying == 1):
|
||||
AudioManager.stop(self.sound)
|
||||
self.isPlaying = 0
|
||||
return
|
||||
elif (entry == 1):
|
||||
AudioManager.stop(self.sound)
|
||||
elif (event == IVAL_INIT):
|
||||
# Set flag
|
||||
self.isPlaying = 1
|
||||
if (self.prevt < 0.0):
|
||||
AudioManager.play(self.sound)
|
||||
else:
|
||||
AudioManager.play(self.sound, t)
|
||||
# If its within a 20th of a second of the start,
|
||||
# start at the beginning
|
||||
if (t < 0.05):
|
||||
t = 0.0
|
||||
# Start sound
|
||||
AudioManager.play(self.sound, t)
|
||||
# Loop in necessary
|
||||
if (self.loop):
|
||||
AudioManager.setLoop(self.sound, 1)
|
||||
|
@ -8,33 +8,39 @@ PREVIOUS_END = 1
|
||||
PREVIOUS_START = 2
|
||||
TRACK_START = 3
|
||||
|
||||
IDATA_IVAL = 0
|
||||
IDATA_TIME = 1
|
||||
IDATA_TYPE = 2
|
||||
IDATA_START = 3
|
||||
IDATA_END = 4
|
||||
|
||||
class Track(Interval):
|
||||
|
||||
# Name counter
|
||||
trackNum = 1
|
||||
|
||||
# special methods
|
||||
|
||||
# Class methods
|
||||
def __init__(self, intervalList, name=None):
|
||||
"""__init__(intervalList, name)
|
||||
"""
|
||||
if (name == None):
|
||||
n = 'Track-%d' % Track.trackNum
|
||||
Track.trackNum = Track.trackNum + 1
|
||||
else:
|
||||
n = name
|
||||
# Record instance variables
|
||||
self.__buildIlist(intervalList)
|
||||
duration = self.__computeDuration(len(self.ilist))
|
||||
self.currentInterval = None
|
||||
Interval.__init__(self, n, duration)
|
||||
# Generate unique name if necessary
|
||||
if (name == None):
|
||||
name = 'Track-%d' % Track.trackNum
|
||||
Track.trackNum = Track.trackNum + 1
|
||||
# Compute duration
|
||||
duration = self.__computeDuration()
|
||||
# Initialize superclass
|
||||
Interval.__init__(self, name, duration)
|
||||
|
||||
def __getitem__(self, item):
|
||||
return self.ilist[item][0]
|
||||
return self.ilist[item]
|
||||
|
||||
def __buildIlist(self, intervalList):
|
||||
self.ilist = []
|
||||
for i in intervalList:
|
||||
if isinstance(i, Interval):
|
||||
self.ilist.append((i, 0.0, PREVIOUS_END))
|
||||
self.ilist.append([i, 0.0, PREVIOUS_END, 0.0, 0.0])
|
||||
elif (isinstance(i, types.ListType) or
|
||||
isinstance(i, types.TupleType)):
|
||||
t0 = i[0]
|
||||
@ -43,21 +49,22 @@ class Track(Interval):
|
||||
type = i[2]
|
||||
except IndexError:
|
||||
type = TRACK_START
|
||||
self.ilist.append((ival, t0, type))
|
||||
self.ilist.append([ival, t0, type, 0.0, 0.0])
|
||||
else:
|
||||
print 'Track.__buildIlist: Invalid intervallist entry'
|
||||
|
||||
def __computeDuration(self, length):
|
||||
""" __computeDuration(length)
|
||||
def __computeDuration(self):
|
||||
""" __computeDuration()
|
||||
"""
|
||||
assert(length <= len(self.ilist))
|
||||
duration = 0.0
|
||||
prev = None
|
||||
for i in self.ilist[0:length]:
|
||||
ival = i[0]
|
||||
t0 = i[1]
|
||||
type = i[2]
|
||||
for idata in self.ilist:
|
||||
ival = idata[IDATA_IVAL]
|
||||
t0 = idata[IDATA_TIME]
|
||||
type = idata[IDATA_TYPE]
|
||||
assert(t0 >= 0.0)
|
||||
# Compute fill time, time between end of last interval and
|
||||
# start of this one
|
||||
fillTime = t0
|
||||
if (type == PREVIOUS_END):
|
||||
pass
|
||||
@ -72,23 +79,27 @@ class Track(Interval):
|
||||
if (fillTime < 0.0):
|
||||
Interval.notify.error(
|
||||
'Track.__computeDuration(): overlap detected')
|
||||
duration = duration + fillTime + ival.getDuration()
|
||||
# Compute start time of interval
|
||||
idata[IDATA_START] = duration + fillTime
|
||||
# Compute end time of interval
|
||||
idata[IDATA_END] = idata[IDATA_START] + ival.getDuration()
|
||||
# Keep track of current duration
|
||||
duration = idata[IDATA_END]
|
||||
prev = ival
|
||||
return duration
|
||||
|
||||
def setIntervalStartTime(self, name, t0, type=TRACK_START):
|
||||
""" setIntervalStartTime(name, t0, type)
|
||||
"""
|
||||
length = len(self.ilist)
|
||||
found = 0
|
||||
for i in range(length):
|
||||
if (self.ilist[i][0].getName() == name):
|
||||
newi = (self.ilist[i][0], t0, type)
|
||||
self.ilist[i] = newi
|
||||
for idata in self.ilist:
|
||||
if (idata[IDATA_IVAL].getName() == name):
|
||||
idata[IDATA_TIME] = t0
|
||||
idata[IDATA_TYPE] = type
|
||||
found = 1
|
||||
break;
|
||||
break
|
||||
if (found):
|
||||
self.duration = self.__computeDuration(length)
|
||||
self.duration = self.__computeDuration()
|
||||
else:
|
||||
Interval.notify.warning(
|
||||
'Track.setIntervalStartTime(): no Interval named: %s' % name)
|
||||
@ -96,71 +107,104 @@ class Track(Interval):
|
||||
def getIntervalStartTime(self, name):
|
||||
""" getIntervalStartTime(name)
|
||||
"""
|
||||
for i in range(len(self.ilist)):
|
||||
if (self.ilist[i][0].getName() == name):
|
||||
return (self.__computeDuration(i+1) -
|
||||
self.ilist[i][0].getDuration())
|
||||
for idata in self.ilist:
|
||||
if (idata[IDATA_IVAL].getName() == name):
|
||||
return idata[IDATA_START]
|
||||
Interval.notify.warning(
|
||||
'Track.getIntervalStartTime(): no Interval named: %s' % name)
|
||||
return 0.0
|
||||
return None
|
||||
|
||||
def __getIntervalStartTime(self, interval):
|
||||
""" __getIntervalStartTime(interval)
|
||||
"""
|
||||
for i in range(len(self.ilist)):
|
||||
if (self.ilist[i][0] == interval):
|
||||
return (self.__computeDuration(i+1) - interval.getDuration())
|
||||
for idata in self.ilist:
|
||||
if (idata[IDATA_IVAL] == interval):
|
||||
return idata[IDATA_START]
|
||||
Interval.notify.warning(
|
||||
'Track.getIntervalStartTime(): Interval not found')
|
||||
return 0.0
|
||||
return None
|
||||
|
||||
def getIntervalEndTime(self, name):
|
||||
""" getIntervalEndTime(name)
|
||||
"""
|
||||
for i in range(len(self.ilist)):
|
||||
if (self.ilist[i][0].getName() == name):
|
||||
return self.__computeDuration(i+1)
|
||||
for idata in self.ilist:
|
||||
if (idata[IDATA_IVAL].getName() == name):
|
||||
return idata[IDATA_END]
|
||||
Interval.notify.warning(
|
||||
'Track.getIntervalEndTime(): no Interval named: %s' % name)
|
||||
return 0.0
|
||||
return None
|
||||
|
||||
def setT(self, t, entry=0):
|
||||
""" setT(t, entry)
|
||||
def updateFunc(self, t, event = IVAL_NONE):
|
||||
""" updateFunc(t, event)
|
||||
Go to time t
|
||||
"""
|
||||
# Make sure track actually contains some intervals
|
||||
if not self.ilist:
|
||||
Interval.notify.warning(
|
||||
'Track.updateFunc(): track has no intervals')
|
||||
return
|
||||
# Deterimine which interval, if any to evaluate
|
||||
if (t < 0):
|
||||
return
|
||||
elif (entry == 1):
|
||||
self.currentInterval = None
|
||||
if (len(self.ilist) == 0):
|
||||
Interval.notify.warning('Track.setT(): track has no intervals')
|
||||
return
|
||||
elif (entry == 1) and (t > self.duration):
|
||||
# Anything beyond the end of the track is assumed to be the
|
||||
# final state of the last Interval on the track
|
||||
self.ilist[len(self.ilist)-1][0].setT(t, entry=1)
|
||||
# Before start of track, do nothing
|
||||
pass
|
||||
else:
|
||||
for i in self.ilist:
|
||||
# Calculate the track relative start time for the interval
|
||||
ival = i[0]
|
||||
t0 = self.__getIntervalStartTime(ival)
|
||||
|
||||
# Calculate the interval-relative time value for t
|
||||
tc = t - t0
|
||||
|
||||
# There can only be one interval active at any given time
|
||||
# per track, so see if we've crossed over
|
||||
if ((t0 <= t) and (t <= t0 + ival.getDuration()) and
|
||||
(self.currentInterval != ival)):
|
||||
ival.setT(tc, entry=1)
|
||||
self.currentInterval = ival
|
||||
else:
|
||||
ival.setT(tc)
|
||||
# Initialize local variables
|
||||
currentInterval = None
|
||||
# First entry, re-init instance variables
|
||||
if (event == IVAL_INIT):
|
||||
# Initialize prev_t to max t of track
|
||||
self.prev_t = self.getDuration()
|
||||
# Clear record of currentInterval
|
||||
self.currentInterval = None
|
||||
# Compare t with start and end of each interval to determine
|
||||
# which interval(s) to execute.
|
||||
# If t falls between the start and end of an interval, that
|
||||
# becomes the current interval. If we've crossed over the end
|
||||
# of an interval ((prev_t < tEnd) and (t > tEnd)) then execute
|
||||
# that interval at its final value. If we've crossed over the
|
||||
# start of an interval ((prev_t > tStart) and (t < tStart))
|
||||
# then execute that interval at its start value
|
||||
for ival, itime, itype, tStart, tEnd in self.ilist:
|
||||
# Compare time with ival's start/end times
|
||||
if (t < tStart):
|
||||
if self.prev_t > tStart:
|
||||
# We just crossed the start of this interval
|
||||
# going backwards (e.g. via the slider)
|
||||
# Execute this interval at its start time
|
||||
ival.setT(0.0)
|
||||
# Done checking intervals
|
||||
break
|
||||
elif (t >= tStart) and (t <= tEnd):
|
||||
# Between start/end, record current interval
|
||||
currentInterval = ival
|
||||
# Make sure event == IVAL_INIT if entering new interval
|
||||
if ((self.prev_t < tStart) or
|
||||
(ival != self.currentInterval)):
|
||||
event = IVAL_INIT
|
||||
# Evaluate interval at interval relative time
|
||||
currentInterval.setT(t - tStart, event)
|
||||
# Done checking intervals
|
||||
break
|
||||
elif (t > tEnd):
|
||||
# Crossing over interval end
|
||||
if ((self.prev_t < tEnd) or
|
||||
((event == IVAL_INIT) and ival.getfOpenEnded())):
|
||||
# If we've just crossed the end of this interval
|
||||
# or its an INIT event after the interval's end
|
||||
# and the interval is openended,
|
||||
# then execute the interval at its end time
|
||||
ival.setT(ival.getDuration())
|
||||
# May not be the last, keep checking other intervals
|
||||
# Record current interval (may be None)
|
||||
self.currentInterval = currentInterval
|
||||
|
||||
def __repr__(self, indent=0):
|
||||
""" __repr__(indent)
|
||||
"""
|
||||
str = Interval.__repr__(self, indent)
|
||||
for i in self.ilist:
|
||||
str = str + i[0].__repr__(indent+1)
|
||||
str = Interval.__repr__(self, indent) + '\n'
|
||||
for idata in self.ilist:
|
||||
str = (str + idata[IDATA_IVAL].__repr__(indent+1) +
|
||||
(' start: %0.2f end: %0.2f' %
|
||||
(idata[IDATA_START], idata[IDATA_END])) + '\n'
|
||||
)
|
||||
return str
|
||||
|
@ -4,17 +4,15 @@ from PandaModules import *
|
||||
from Interval import *
|
||||
|
||||
class WaitInterval(Interval):
|
||||
|
||||
# Name counter
|
||||
waitNum = 1
|
||||
|
||||
# special methods
|
||||
|
||||
# Class methods
|
||||
def __init__(self, duration, name=None):
|
||||
"""__init__(duration, name)
|
||||
"""
|
||||
# Generate unique name if necessary
|
||||
if (name == None):
|
||||
n = 'Wait-%d' % self.waitNum
|
||||
self.waitNum = self.waitNum + 1
|
||||
else:
|
||||
n = name
|
||||
Interval.__init__(self, n, duration)
|
||||
name = 'Wait-%d' % WaitInterval.waitNum
|
||||
WaitInterval.waitNum += 1
|
||||
# Initialize superclass
|
||||
Interval.__init__(self, name, duration)
|
||||
|
Loading…
x
Reference in New Issue
Block a user