| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450 |
- """FunctionInterval module: contains the FunctionInterval class"""
- __all__ = ['FunctionInterval', 'EventInterval', 'AcceptInterval', 'IgnoreInterval', 'ParentInterval', 'WrtParentInterval', 'PosInterval', 'HprInterval', 'ScaleInterval', 'PosHprInterval', 'HprScaleInterval', 'PosHprScaleInterval', 'Func', 'Wait']
- from panda3d.core import *
- from panda3d.direct import *
- from direct.showbase.MessengerGlobal import *
- from direct.directnotify.DirectNotifyGlobal import directNotify
- from . import Interval
- import sys
- #############################################################
- ### ###
- ### See examples of function intervals in IntervalTest.py ###
- ### ###
- #############################################################
- class FunctionInterval(Interval.Interval):
- # Name counter
- functionIntervalNum = 1
- # Keep a list of function intervals currently in memory for
- # Control-C-Control-V redefining. These are just weakrefs so they
- # should not cause any leaks.
- if __debug__:
- import weakref
- FunctionIntervals = weakref.WeakKeyDictionary()
- @classmethod
- def replaceMethod(self, oldFunction, newFunction):
- import types
- count = 0
- for ival in self.FunctionIntervals:
- # print 'testing: ', ival.function, oldFunction
- # Note: you can only replace methods currently
- if type(ival.function) == types.MethodType:
- if ival.function.__func__ == oldFunction:
- # print 'found: ', ival.function, oldFunction
- if sys.version_info >= (3, 0):
- ival.function = types.MethodType(newFunction,
- ival.function.__self__)
- else:
- ival.function = types.MethodType(newFunction,
- ival.function.__self__,
- ival.function.__self__.__class__)
- count += 1
- return count
- # create FunctionInterval DirectNotify category
- notify = directNotify.newCategory('FunctionInterval')
- # Class methods
- def __init__(self, function, **kw):
- """__init__(function, name = None, openEnded = 1, extraArgs = [])
- """
- name = kw.pop('name', None)
- openEnded = kw.pop('openEnded', 1)
- extraArgs = kw.pop('extraArgs', [])
- # Record instance variables
- self.function = function
- # Create a unique name for the interval if necessary
- if name is None:
- name = self.makeUniqueName(function)
- assert isinstance(name, str)
- # Record any arguments
- self.extraArgs = extraArgs
- self.kw = kw
- # Initialize superclass
- # Set openEnded true if privInitialize after end time cause interval
- # function to be called. If false, privInitialize calls have no effect
- # Event, Accept, Ignore intervals default to openEnded = 0
- # Parent, Pos, Hpr, etc intervals default to openEnded = 1
- Interval.Interval.__init__(self, name, duration = 0.0, openEnded = openEnded)
- # For rebinding, let's remember this function interval on the class
- if __debug__:
- self.FunctionIntervals[self] = 1
- @staticmethod
- def makeUniqueName(func, suffix = ''):
- func_name = getattr(func, '__name__', None)
- if func_name is None:
- func_name = str(func)
- name = 'Func-%s-%d' % (func_name, FunctionInterval.functionIntervalNum)
- FunctionInterval.functionIntervalNum += 1
- if suffix:
- name = '%s-%s' % (name, str(suffix))
- return name
- def privInstant(self):
- # Evaluate the function
- self.function(*self.extraArgs, **self.kw)
- # Print debug information
- self.notify.debug(
- 'updateFunc() - %s: executing Function' % self.name)
- ### FunctionInterval subclass for throwing events ###
- class EventInterval(FunctionInterval):
- # Initialization
- def __init__(self, event, sentArgs=[]):
- """__init__(event, sentArgs)
- """
- def sendFunc(event = event, sentArgs = sentArgs):
- messenger.send(event, sentArgs)
- # Create function interval
- FunctionInterval.__init__(self, sendFunc, name = event)
- ### FunctionInterval subclass for accepting hooks ###
- class AcceptInterval(FunctionInterval):
- # Initialization
- def __init__(self, dirObj, event, function, name = None):
- """__init__(dirObj, event, function, name)
- """
- def acceptFunc(dirObj = dirObj, event = event, function = function):
- dirObj.accept(event, function)
- # Determine name
- if (name == None):
- name = 'Accept-' + event
- # Create function interval
- FunctionInterval.__init__(self, acceptFunc, name = name)
- ### FunctionInterval subclass for ignoring events ###
- class IgnoreInterval(FunctionInterval):
- # Initialization
- def __init__(self, dirObj, event, name = None):
- """__init__(dirObj, event, name)
- """
- def ignoreFunc(dirObj = dirObj, event = event):
- dirObj.ignore(event)
- # Determine name
- if (name == None):
- name = 'Ignore-' + event
- # Create function interval
- FunctionInterval.__init__(self, ignoreFunc, name = name)
- ### Function Interval subclass for adjusting scene graph hierarchy ###
- class ParentInterval(FunctionInterval):
- # ParentInterval counter
- parentIntervalNum = 1
- # Initialization
- def __init__(self, nodePath, parent, name = None):
- """__init__(nodePath, parent, name)
- """
- def reparentFunc(nodePath = nodePath, parent = parent):
- nodePath.reparentTo(parent)
- # Determine name
- if (name == None):
- name = 'ParentInterval-%d' % ParentInterval.parentIntervalNum
- ParentInterval.parentIntervalNum += 1
- # Create function interval
- FunctionInterval.__init__(self, reparentFunc, name = name)
- ### Function Interval subclass for adjusting scene graph hierarchy ###
- class WrtParentInterval(FunctionInterval):
- # WrtParentInterval counter
- wrtParentIntervalNum = 1
- # Initialization
- def __init__(self, nodePath, parent, name = None):
- """__init__(nodePath, parent, name)
- """
- def wrtReparentFunc(nodePath = nodePath, parent = parent):
- nodePath.wrtReparentTo(parent)
- # Determine name
- if (name == None):
- name = ('WrtParentInterval-%d' %
- WrtParentInterval.wrtParentIntervalNum)
- WrtParentInterval.wrtParentIntervalNum += 1
- # Create function interval
- FunctionInterval.__init__(self, wrtReparentFunc, name = name)
- ### Function Interval subclasses for instantaneous pose changes ###
- class PosInterval(FunctionInterval):
- # PosInterval counter
- posIntervalNum = 1
- # Initialization
- def __init__(self, nodePath, pos, duration = 0.0,
- name = None, other = None):
- """__init__(nodePath, pos, duration, name)
- """
- # Create function
- def posFunc(np = nodePath, pos = pos, other = other):
- if other:
- np.setPos(other, pos)
- else:
- np.setPos(pos)
- # Determine name
- if (name == None):
- name = 'PosInterval-%d' % PosInterval.posIntervalNum
- PosInterval.posIntervalNum += 1
- # Create function interval
- FunctionInterval.__init__(self, posFunc, name = name)
- class HprInterval(FunctionInterval):
- # HprInterval counter
- hprIntervalNum = 1
- # Initialization
- def __init__(self, nodePath, hpr, duration = 0.0,
- name = None, other = None):
- """__init__(nodePath, hpr, duration, name)
- """
- # Create function
- def hprFunc(np = nodePath, hpr = hpr, other = other):
- if other:
- np.setHpr(other, hpr)
- else:
- np.setHpr(hpr)
- # Determine name
- if (name == None):
- name = 'HprInterval-%d' % HprInterval.hprIntervalNum
- HprInterval.hprIntervalNum += 1
- # Create function interval
- FunctionInterval.__init__(self, hprFunc, name = name)
- class ScaleInterval(FunctionInterval):
- # ScaleInterval counter
- scaleIntervalNum = 1
- # Initialization
- def __init__(self, nodePath, scale, duration = 0.0,
- name = None, other = None):
- """__init__(nodePath, scale, duration, name)
- """
- # Create function
- def scaleFunc(np = nodePath, scale = scale, other = other):
- if other:
- np.setScale(other, scale)
- else:
- np.setScale(scale)
- # Determine name
- if (name == None):
- name = 'ScaleInterval-%d' % ScaleInterval.scaleIntervalNum
- ScaleInterval.scaleIntervalNum += 1
- # Create function interval
- FunctionInterval.__init__(self, scaleFunc, name = name)
- class PosHprInterval(FunctionInterval):
- # PosHprInterval counter
- posHprIntervalNum = 1
- # Initialization
- def __init__(self, nodePath, pos, hpr, duration = 0.0,
- name = None, other = None):
- """__init__(nodePath, pos, hpr, duration, name)
- """
- # Create function
- def posHprFunc(np = nodePath, pos = pos, hpr = hpr, other = other):
- if other:
- np.setPosHpr(other, pos, hpr)
- else:
- np.setPosHpr(pos, hpr)
- # Determine name
- if (name == None):
- name = 'PosHprInterval-%d' % PosHprInterval.posHprIntervalNum
- PosHprInterval.posHprIntervalNum += 1
- # Create function interval
- FunctionInterval.__init__(self, posHprFunc, name = name)
- class HprScaleInterval(FunctionInterval):
- # HprScaleInterval counter
- hprScaleIntervalNum = 1
- # Initialization
- def __init__(self, nodePath, hpr, scale, duration = 0.0,
- name = None, other = None):
- """__init__(nodePath, hpr, scale, duration, other, name)
- """
- # Create function
- def hprScaleFunc(np=nodePath, hpr=hpr, scale=scale,
- other = other):
- if other:
- np.setHprScale(other, hpr, scale)
- else:
- np.setHprScale(hpr, scale)
- # Determine name
- if (name == None):
- name = ('HprScale-%d' %
- HprScaleInterval.hprScaleIntervalNum)
- HprScaleInterval.hprScaleIntervalNum += 1
- # Create function interval
- FunctionInterval.__init__(self, hprScaleFunc, name = name)
- class PosHprScaleInterval(FunctionInterval):
- # PosHprScaleInterval counter
- posHprScaleIntervalNum = 1
- # Initialization
- def __init__(self, nodePath, pos, hpr, scale, duration = 0.0,
- name = None, other = None):
- """__init__(nodePath, pos, hpr, scale, duration, other, name)
- """
- # Create function
- def posHprScaleFunc(np=nodePath, pos=pos, hpr=hpr, scale=scale,
- other = other):
- if other:
- np.setPosHprScale(other, pos, hpr, scale)
- else:
- np.setPosHprScale(pos, hpr, scale)
- # Determine name
- if (name == None):
- name = ('PosHprScale-%d' %
- PosHprScaleInterval.posHprScaleIntervalNum)
- PosHprScaleInterval.posHprScaleIntervalNum += 1
- # Create function interval
- FunctionInterval.__init__(self, posHprScaleFunc, name = name)
- class Func(FunctionInterval):
- def __init__(self, *args, **kw):
- function = args[0]
- assert hasattr(function, '__call__')
- extraArgs = args[1:]
- kw['extraArgs'] = extraArgs
- FunctionInterval.__init__(self, function, **kw)
- class Wait(WaitInterval):
- def __init__(self, duration):
- WaitInterval.__init__(self, duration)
- """
- SAMPLE CODE
- from IntervalGlobal import *
- i1 = Func(base.transitions.fadeOut)
- i2 = Func(base.transitions.fadeIn)
- def caughtIt():
- print 'Caught here-is-an-event'
- class DummyAcceptor(DirectObject):
- pass
- da = DummyAcceptor()
- i3 = Func(da.accept, 'here-is-an-event', caughtIt)
- i4 = Func(messenger.send, 'here-is-an-event')
- i5 = Func(da.ignore, 'here-is-an-event')
- # Using a function
- def printDone():
- print 'done'
- i6 = Func(printDone)
- # Create track
- t1 = Sequence([
- # Fade out
- (0.0, i1),
- # Fade in
- (2.0, i2),
- # Accept event
- (4.0, i3),
- # Throw it,
- (5.0, i4),
- # Ignore event
- (6.0, i5),
- # Throw event again and see if ignore worked
- (7.0, i4),
- # Print done
- (8.0, i6)], name = 'demo')
- # Play track
- t1.play()
- ### Specifying interval start times during track construction ###
- # Interval start time can be specified relative to three different points:
- # PREVIOUS_END
- # PREVIOUS_START
- # TRACK_START
- startTime = 0.0
- def printStart():
- global startTime
- startTime = globalClock.getFrameTime()
- print 'Start'
- def printPreviousStart():
- global startTime
- currTime = globalClock.getFrameTime()
- print 'PREVIOUS_END %0.2f' % (currTime - startTime)
- def printPreviousEnd():
- global startTime
- currTime = globalClock.getFrameTime()
- print 'PREVIOUS_END %0.2f' % (currTime - startTime)
- def printTrackStart():
- global startTime
- currTime = globalClock.getFrameTime()
- print 'TRACK_START %0.2f' % (currTime - startTime)
- i1 = Func(printStart)
- # Just to take time
- i2 = LerpPosInterval(camera, 2.0, Point3(0, 10, 5))
- # This will be relative to end of camera move
- i3 = FunctionInterval(printPreviousEnd)
- # Just to take time
- i4 = LerpPosInterval(camera, 2.0, Point3(0, 0, 5))
- # This will be relative to the start of the camera move
- i5 = FunctionInterval(printPreviousStart)
- # This will be relative to track start
- i6 = FunctionInterval(printTrackStart)
- # Create the track, if you don't specify offset type in tuple it defaults to
- # relative to TRACK_START (first entry below)
- t2 = Track([(0.0, i1), # i1 start at t = 0, duration = 0.0
- (1.0, i2, TRACK_START), # i2 start at t = 1, duration = 2.0
- (2.0, i3, PREVIOUS_END), # i3 start at t = 5, duration = 0.0
- (1.0, i4, PREVIOUS_END), # i4 start at t = 6, duration = 2.0
- (3.0, i5, PREVIOUS_START), # i5 start at t = 9, duration = 0.0
- (10.0, i6, TRACK_START)], # i6 start at t = 10, duration = 0.0
- name = 'startTimeDemo')
- t2.play()
- smiley = loader.loadModel('models/misc/smiley')
- from direct.actor import Actor
- donald = Actor.Actor()
- donald.loadModel("phase_6/models/char/donald-wheel-1000")
- donald.loadAnims({"steer":"phase_6/models/char/donald-wheel-wheel"})
- donald.reparentTo(render)
- seq = Sequence(Func(donald.setPos, 0, 0, 0),
- donald.actorInterval('steer', duration=1.0),
- donald.posInterval(1, Point3(0, 0, 1)),
- Parallel(donald.actorInterval('steer', duration=1.0),
- donald.posInterval(1, Point3(0, 0, 0)),
- ),
- Wait(1.0),
- Func(base.toggleWireframe),
- Wait(1.0),
- Parallel(donald.actorInterval('steer', duration=1.0),
- donald.posInterval(1, Point3(0, 0, -1)),
- Sequence(donald.hprInterval(1, Vec3(180, 0, 0)),
- donald.hprInterval(1, Vec3(0, 0, 0)),
- ),
- ),
- Func(base.toggleWireframe),
- Func(messenger.send, 'hello'),
- )
- """
|