浏览代码

*** empty log message ***

Mark Mine 24 年之前
父节点
当前提交
47798039fc

+ 16 - 9
direct/src/interval/ActorInterval.py

@@ -10,8 +10,8 @@ class ActorInterval(Interval):
     # Interval used to play an animation.  If loop = 0, animation is
     # played only once and the pose of the anim depends on t passed
     # into the setT method every frame.  If loop = 1, the animation is
-    # started and plays on its own and stopped when t > duration or
-    # IVAL_STOP event occurs.  If no duration is specified, interval
+    # started and plays on its own and stopped when t >= duration or
+    # playback stop event occurs.  If no duration is specified, interval
     # duration defaults to be equal to the length of the animation.
     # Note: if loop == 0 and duration > anim duration then the animation
     # will play once and then nothing will happen for the remainder of the
@@ -19,20 +19,27 @@ class ActorInterval(Interval):
     def __init__(self, actor, animName, loop=0, duration=0.0, name=None):
         """__init__(name)
         """
+        # Generate unique id
+        id = 'Actor-%d' % ActorInterval.animNum
+        ActorInterval.animNum += 1
         # Record class specific variables
 	self.actor = actor
 	self.animName = animName
         self.loop = loop
-        # Generate unique name if necessary
-	if (name == None):
-	    name = 'Actor-%d' % ActorInterval.animNum
-	    ActorInterval.animNum += 1
 	self.numFrames = self.actor.getNumFrames(self.animName)
+        # If no name specified, use id as name
+	if (name == None):
+	    name = id
+        # Compute duration if no duration specified
         if duration == 0.0:
 	    duration = self.actor.getDuration(self.animName)
-	self.numFrames
         # Initialize superclass
 	Interval.__init__(self, name, duration)
+        # Update stopEvent
+        if self.loop:
+            stopEvent = id + '_stopEvent'
+            self.stopEventList = [stopEvent]
+            self.accept(stopEvent, self.actor.stop)
 
     def updateFunc(self, t, event = IVAL_NONE):
 	""" updateFunc(t, event)
@@ -40,7 +47,7 @@ class ActorInterval(Interval):
 	"""
         # Update animation based upon current time
         # Pose or stop anim
-        if (t >= self.getDuration()) or (event == IVAL_STOP):
+        if (t >= self.getDuration()):
             self.actor.stop()
         elif self.loop == 1:
             if event == IVAL_INIT:
@@ -49,7 +56,7 @@ class ActorInterval(Interval):
                          self.numFrames)
                 # Pose anim
                 self.actor.pose(self.animName, frame)
-                # And start loop
+                # And start loop, restart flag says continue from current frame
                 self.actor.loop(self.animName, restart=0)
         else:
             # Determine the current frame

+ 8 - 3
direct/src/interval/FunctionInterval.py

@@ -4,6 +4,12 @@ from PandaModules import *
 from Interval import *
 from MessengerGlobal import *
 
+#############################################################
+###                                                       ###
+### See examples of function intervals in IntervalTest.py ###
+###                                                       ###
+#############################################################
+
 class FunctionInterval(Interval):
     # Name counter
     functionIntervalNum = 1
@@ -30,9 +36,8 @@ class FunctionInterval(Interval):
 	""" updateFunc(t, event)
 	    Go to time t
 	"""
-        if event != IVAL_STOP:
-            # Evaluate the function
-            apply(self.function, self.extraArgs)
+        # Evaluate the function
+        apply(self.function, self.extraArgs)
 
 ### FunctionInterval subclass for throwing events ###
 class EventInterval(FunctionInterval):

+ 13 - 7
direct/src/interval/Interval.py

@@ -1,13 +1,13 @@
 """Interval module: contains the Interval class"""
 
 from DirectObject import *
+from IntervalGlobal import *
 import ClockObject
 import Task
 
 # Interval events
 IVAL_NONE = 0
 IVAL_INIT = 1
-IVAL_STOP = 2
 
 class Interval(DirectObject):
     """Interval class: Base class for timeline functionality"""
@@ -16,6 +16,8 @@ class Interval(DirectObject):
     notify = directNotify.newCategory("Interval")
     #notify.setDebug(1)
 
+    playbackCounter = 0
+
     # Class methods
     def __init__(self, name, duration, openEnded = 1):
         """__init__(name, duration)
@@ -25,6 +27,7 @@ class Interval(DirectObject):
 	self.clock = ClockObject.ClockObject.getGlobalClock()
 	self.curr_t = 0.0
 	self.prev_t = 0.0
+        self.stopEventList = []
         self.setTHooks = []
         # Set true if interval responds to setT(t): t>duration
         self.fOpenEnded = openEnded
@@ -102,10 +105,11 @@ class Interval(DirectObject):
     def stop(self):
         """ stop()
         """
+        # First send event to stop freerunning (e.g. sound and anim) intervals
+        for stopEvent in self.stopEventList:
+            messenger.send(stopEvent)
         # Kill task
         taskMgr.removeTasksNamed(self.name + '-play')
-        # And stop freerunning (e.g. sound and anim) intervals
-        self.setT(self.curr_t, event = IVAL_STOP)
 	return self.curr_t
 
     def isPlaying(self):
@@ -164,17 +168,19 @@ class Interval(DirectObject):
         # To make sure you stop free running intervals
         es.onRelease = lambda s=self: s.stop()
         # To update scale and execute intervals with IVAL_INIT
-        es.onReturnRelease = lambda s=self, es = es: s.setT(es.get(),
-                                                            event = IVAL_INIT)
+        def onReturn(s = self, es = es):
+            s.setT(es.get(), event = IVAL_INIT)
+            s.stop()
+        es.onReturnRelease = onReturn
         es.pack(expand = 1, fill = X)
         bf = Frame(outerFrame)
         # Jump to start and end
         def toStart(s=self, es=es):
-            s.stop()
             s.setT(0.0, event = IVAL_INIT)
-        def toEnd(s=self):
             s.stop()
+        def toEnd(s=self):
             s.setT(s.getDuration(), event = IVAL_INIT)
+            s.stop()
         jumpToStart = Button(bf, text = '<<', command = toStart)
         # Stop/play buttons
         stop = Button(bf, text = 'Stop',

+ 2 - 2
direct/src/interval/IntervalTest.py

@@ -9,8 +9,8 @@ boat = loader.loadModel('models/directmodels/smiley')
 boat.reparentTo(render)
 
 donald = Actor()
-donald.loadModel("phase_3/models/char/donald-wheel-mod")
-donald.loadAnims({"steer":"phase_3/models/char/donald-wheel-chan"})
+donald.loadModel("phase_6/models/char/donald-wheel-mod")
+donald.loadAnims({"steer":"phase_6/models/char/donald-wheel-chan"})
 donald.reparentTo(boat)
 
 dock = loader.loadModel('models/directmodels/smiley')

+ 1 - 1
direct/src/interval/LerpInterval.py

@@ -20,7 +20,7 @@ class LerpInterval(Interval):
 	""" updateFunc(t, event)
 	"""
         # Check to see if we need to create the lerp
-	if (event == IVAL_INIT):
+        if (event == IVAL_INIT):
 	    self.lerp = Lerp.Lerp(self.functorFunc(), self.duration, 
                                   self.blendType)
         # Make sure lerp exists

+ 5 - 0
direct/src/interval/MultiTrack.py

@@ -12,6 +12,7 @@ class MultiTrack(Interval):
         """
         # Record track list
 	self.tlist = trackList
+        # Generate name if necessary
 	if (name == None):
 	    name = 'MultiTrack-%d' % MultiTrack.multiTrackNum
 	    MultiTrack.multiTrackNum = MultiTrack.multiTrackNum + 1
@@ -19,6 +20,10 @@ class MultiTrack(Interval):
 	duration = self.__computeDuration()
         # Initialize superclass
 	Interval.__init__(self, name, duration)
+        # Update stopEventList after initialization
+        # It is the union of the stopEventLists of all tracks in the MultiTrack
+        for t in self.tlist:
+            self.stopEventList = self.stopEventList + t.stopEventList
 
     # Access track at given index
     def __getitem__(self, item):

+ 22 - 4
direct/src/interval/SoundInterval.py

@@ -19,24 +19,42 @@ class SoundInterval(Interval):
     def __init__(self, sound, loop = 0, duration = 0.0, name = None):
         """__init__(sound, loop, name)
         """
+        # Generate unique name
+        id = 'Sound-%d' % SoundInterval.soundNum
+        SoundInterval.soundNum += 1
         # Record instance variables
 	self.sound = sound
 	self.loop = loop
+        self.wantSound = base.config.GetBool('want-sound', 0)
         # If no duration given use sound's duration as interval's duration
         if duration == 0.0:
-            duration = self.sound.length()
+            if self.wantSound:
+                duration = self.sound.length()
+            else:
+                # This will screw up any intervals that base their
+                # time on the duration of this sound interval
+                print ('SoundInterval: Warning, want-sound #f,'+
+                       ' zero sound duration assumed')
+                duration = 0.0
         # Generate unique name if necessary
 	if (name == None):
-	    name = 'Sound-%d' % SoundInterval.soundNum
-	    SoundInterval.soundNum += 1
+            name = id
         # Initialize superclass
 	Interval.__init__(self, name, duration)
+        # Update stopEvent
+        if self.wantSound:
+            stopEvent = id + '_stopEvent'
+            self.stopEventList = [stopEvent]
+            self.accept(stopEvent, lambda s = self: AudioManager.stop(s.sound))
+        
     def updateFunc(self, t, event = IVAL_NONE):
 	""" updateFunc(t, event)
         Go to time t
 	"""
+        if not self.wantSound:
+            return
         # Update sound based on current time
-        if (t >= self.getDuration()) or (event == IVAL_STOP):
+        if (t >= self.getDuration()):
             # If end of sound reached or stop event received, stop sound
             AudioManager.stop(self.sound)
         elif (event == IVAL_INIT):

+ 6 - 2
direct/src/interval/Track.py

@@ -21,8 +21,9 @@ class Track(Interval):
         """__init__(intervalList, name)
         """
         # Record instance variables
-	self.__buildIlist(intervalList)
 	self.currentInterval = None
+        # Build ilist (need to do this before computing duration)
+	self.__buildIlist(intervalList)
         # Generate unique name if necessary
 	if (name == None):
 	    name = 'Track-%d' % Track.trackNum
@@ -31,6 +32,9 @@ class Track(Interval):
 	duration = self.__computeDuration()
         # Initialize superclass
 	Interval.__init__(self, name, duration)
+        # Update stopEventList
+        for i in self.ilist:
+            self.stopEventList = self.stopEventList + i[0].stopEventList
 
     # Access interval at given index
     def __getitem__(self, item):
@@ -178,7 +182,7 @@ class Track(Interval):
 	    for ival, itime, itype, tStart, tEnd in self.ilist:
                 # Compare time with each ival's start/end times
                 if (t < tStart):
-                    if (self.prev_t > tStart) and (event != IVAL_STOP):
+                    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