FunctionInterval.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. """FunctionInterval module: contains the FunctionInterval class"""
  2. from PandaModules import *
  3. from Interval import *
  4. from MessengerGlobal import *
  5. #############################################################
  6. ### ###
  7. ### See examples of function intervals in IntervalTest.py ###
  8. ### ###
  9. #############################################################
  10. class FunctionInterval(Interval):
  11. # Name counter
  12. functionIntervalNum = 1
  13. # create FunctionInterval DirectNotify category
  14. notify = directNotify.newCategory('FunctionInterval')
  15. # Class methods
  16. def __init__(self, function, name = None, openEnded = 1, extraArgs = []):
  17. """__init__(function, name = None)
  18. """
  19. # Record instance variables
  20. self.function = function
  21. # Create a unique name for the interval if necessary
  22. if (name == None):
  23. name = 'FunctionInterval-%d' % FunctionInterval.functionIntervalNum
  24. FunctionInterval.functionIntervalNum += 1
  25. # Record any arguments
  26. self.extraArgs = extraArgs
  27. # Initialize superclass
  28. # Set openEnded true if IVAL_INIT calls after end time cause interval
  29. # function to be called. If false, IVAL_INIT calls have no effect
  30. # Event, Accept, Ignore intervals default to fOpenEnded = 0
  31. # Parent, Pos, Hpr, etc intervals default to fOpenEnded = 1
  32. Interval.__init__(self, name, duration = 0.0, openEnded = openEnded)
  33. def updateFunc(self, t, event = IVAL_NONE):
  34. """ updateFunc(t, event)
  35. Go to time t
  36. """
  37. # Evaluate the function
  38. apply(self.function, self.extraArgs)
  39. # Print debug information
  40. self.notify.debug(
  41. 'updateFunc() - %s: executing Function' % self.name)
  42. ### FunctionInterval subclass for throwing events ###
  43. class EventInterval(FunctionInterval):
  44. # Initialization
  45. def __init__(self, event, sentArgs=[]):
  46. """__init__(event, sentArgs)
  47. """
  48. def sendFunc(event = event, sentArgs = sentArgs):
  49. messenger.send(event, sentArgs)
  50. # Create function interval
  51. FunctionInterval.__init__(self, sendFunc, name = event,
  52. openEnded = 0)
  53. ### FunctionInterval subclass for accepting hooks ###
  54. class AcceptInterval(FunctionInterval):
  55. # Initialization
  56. def __init__(self, dirObj, event, function, name = None):
  57. """__init__(dirObj, event, function, name)
  58. """
  59. def acceptFunc(dirObj = dirObj, event = event, function = function):
  60. dirObj.accept(event, function)
  61. # Determine name
  62. if (name == None):
  63. name = 'Accept-' + event
  64. # Create function interval
  65. FunctionInterval.__init__(self, acceptFunc, name = name,
  66. openEnded = 0)
  67. ### FunctionInterval subclass for ignoring events ###
  68. class IgnoreInterval(FunctionInterval):
  69. # Initialization
  70. def __init__(self, dirObj, event, name = None):
  71. """__init__(dirObj, event, name)
  72. """
  73. def ignoreFunc(dirObj = dirObj, event = event):
  74. dirObj.ignore(event)
  75. # Determine name
  76. if (name == None):
  77. name = 'Ignore-' + event
  78. # Create function interval
  79. FunctionInterval.__init__(self, ignoreFunc, name = name,
  80. openEnded = 0)
  81. ### Function Interval subclass for adjusting scene graph hierarchy ###
  82. class ParentInterval(FunctionInterval):
  83. # ParentInterval counter
  84. parentIntervalNum = 1
  85. # Initialization
  86. def __init__(self, nodePath, parent, name = None):
  87. """__init__(nodePath, parent, name)
  88. """
  89. def reparentFunc(nodePath = nodePath, parent = parent):
  90. nodePath.reparentTo(parent)
  91. # Determine name
  92. if (name == None):
  93. name = 'ParentInterval-%d' % ParentInterval.parentIntervalNum
  94. ParentInterval.parentIntervalNum += 1
  95. # Create function interval
  96. FunctionInterval.__init__(self, reparentFunc, name = name)
  97. ### Function Interval subclass for adjusting scene graph hierarchy ###
  98. class WrtParentInterval(FunctionInterval):
  99. # WrtParentInterval counter
  100. wrtParentIntervalNum = 1
  101. # Initialization
  102. def __init__(self, nodePath, parent, name = None):
  103. """__init__(nodePath, parent, name)
  104. """
  105. def wrtReparentFunc(nodePath = nodePath, parent = parent):
  106. nodePath.wrtReparentTo(parent)
  107. # Determine name
  108. if (name == None):
  109. name = ('WrtParentInterval-%d' %
  110. WrtParentInterval.wrtParentIntervalNum)
  111. WrtParentInterval.wrtParentIntervalNum += 1
  112. # Create function interval
  113. FunctionInterval.__init__(self, wrtReparentFunc, name = name)
  114. ### Function Interval subclasses for instantaneous pose changes ###
  115. class PosInterval(FunctionInterval):
  116. # PosInterval counter
  117. posIntervalNum = 1
  118. # Initialization
  119. def __init__(self, nodePath, pos, duration = 0.0,
  120. name = None, other = None):
  121. """__init__(nodePath, pos, duration, name)
  122. """
  123. # Create function
  124. def posFunc(np = nodePath, pos = pos, other = other):
  125. if other:
  126. np.setPos(other, pos)
  127. else:
  128. np.setPos(pos)
  129. # Determine name
  130. if (name == None):
  131. name = 'PosInterval-%d' % PosInterval.posIntervalNum
  132. PosInterval.posIntervalNum += 1
  133. # Create function interval
  134. FunctionInterval.__init__(self, posFunc, name = name)
  135. class HprInterval(FunctionInterval):
  136. # HprInterval counter
  137. hprIntervalNum = 1
  138. # Initialization
  139. def __init__(self, nodePath, hpr, duration = 0.0,
  140. name = None, other = None):
  141. """__init__(nodePath, hpr, duration, name)
  142. """
  143. # Create function
  144. def hprFunc(np = nodePath, hpr = hpr, other = other):
  145. if other:
  146. np.setHpr(other, hpr)
  147. else:
  148. np.setHpr(hpr)
  149. # Determine name
  150. if (name == None):
  151. name = 'HprInterval-%d' % HprInterval.hprIntervalNum
  152. HprInterval.hprIntervalNum += 1
  153. # Create function interval
  154. FunctionInterval.__init__(self, hprFunc, name = name)
  155. class ScaleInterval(FunctionInterval):
  156. # ScaleInterval counter
  157. scaleIntervalNum = 1
  158. # Initialization
  159. def __init__(self, nodePath, scale, duration = 0.0,
  160. name = None, other = None):
  161. """__init__(nodePath, scale, duration, name)
  162. """
  163. # Create function
  164. def scaleFunc(np = nodePath, scale = scale, other = other):
  165. if other:
  166. np.setScale(other, scale)
  167. else:
  168. np.setScale(scale)
  169. # Determine name
  170. if (name == None):
  171. name = 'ScaleInterval-%d' % ScaleInterval.scaleIntervalNum
  172. ScaleInterval.scaleIntervalNum += 1
  173. # Create function interval
  174. FunctionInterval.__init__(self, scaleFunc, name = name)
  175. class PosHprInterval(FunctionInterval):
  176. # PosHprInterval counter
  177. posHprIntervalNum = 1
  178. # Initialization
  179. def __init__(self, nodePath, pos, hpr, duration = 0.0,
  180. name = None, other = None):
  181. """__init__(nodePath, pos, hpr, duration, name)
  182. """
  183. # Create function
  184. def posHprFunc(np = nodePath, pos = pos, hpr = hpr, other = other):
  185. if other:
  186. np.setPosHpr(other, pos, hpr)
  187. else:
  188. np.setPosHpr(pos, hpr)
  189. # Determine name
  190. if (name == None):
  191. name = 'PosHprInterval-%d' % PosHprInterval.posHprIntervalNum
  192. PosHprInterval.posHprIntervalNum += 1
  193. # Create function interval
  194. FunctionInterval.__init__(self, posHprFunc, name = name)
  195. class PosHprScaleInterval(FunctionInterval):
  196. # PosHprScaleInterval counter
  197. posHprScaleIntervalNum = 1
  198. # Initialization
  199. def __init__(self, nodePath, pos, hpr, scale, duration = 0.0,
  200. name = None, other = None):
  201. """__init__(nodePath, pos, hpr, scale, duration, other, name)
  202. """
  203. # Create function
  204. def posHprScaleFunc(np=nodePath, pos=pos, hpr=hpr, scale=scale,
  205. other = other):
  206. if other:
  207. np.setPosHprScale(other, pos, hpr, scale)
  208. else:
  209. np.setPosHprScale(pos, hpr, scale)
  210. # Determine name
  211. if (name == None):
  212. name = ('PosHprScale-%d' %
  213. PosHprScaleInterval.posHprScaleIntervalNum)
  214. PosHprScaleInterval.posHprScaleIntervalNum += 1
  215. # Create function interval
  216. FunctionInterval.__init__(self, posHprScaleFunc, name = name)
  217. """
  218. SAMPLE CODE
  219. from IntervalGlobal import *
  220. ### Using lambdas and functions ###
  221. # Using a lambda
  222. i1 = FunctionInterval(lambda: base.transitions.fadeOut())
  223. i2 = FunctionInterval(lambda: base.transitions.fadeIn())
  224. def caughtIt():
  225. print 'Caught here-is-an-event'
  226. class DummyAcceptor(DirectObject):
  227. pass
  228. da = DummyAcceptor()
  229. i3 = AcceptInterval(da, 'here-is-an-event', caughtIt)
  230. i4 = EventInterval('here-is-an-event')
  231. i5 = IgnoreInterval(da, 'here-is-an-event')
  232. # Using a function
  233. def printDone():
  234. print 'done'
  235. i6 = FunctionInterval(printDone)
  236. # Create track
  237. t1 = Track([
  238. # Fade out
  239. (0.0, i1),
  240. # Fade in
  241. (2.0, i2),
  242. # Accept event
  243. (4.0, i3),
  244. # Throw it,
  245. (5.0, i4),
  246. # Ignore event
  247. (6.0, i5),
  248. # Throw event again and see if ignore worked
  249. (7.0, i4),
  250. # Print done
  251. (8.0, i6)], name = 'demo')
  252. # Play track
  253. t1.play()
  254. ### Specifying interval start times during track construction ###
  255. # Interval start time can be specified relative to three different points:
  256. # PREVIOUS_END
  257. # PREVIOUS_START
  258. # TRACK_START
  259. startTime = 0.0
  260. def printStart():
  261. global startTime
  262. startTime = globalClock.getFrameTime()
  263. print 'Start'
  264. def printPreviousStart():
  265. global startTime
  266. currTime = globalClock.getFrameTime()
  267. print 'PREVIOUS_END %0.2f' % (currTime - startTime)
  268. def printPreviousEnd():
  269. global startTime
  270. currTime = globalClock.getFrameTime()
  271. print 'PREVIOUS_END %0.2f' % (currTime - startTime)
  272. def printTrackStart():
  273. global startTime
  274. currTime = globalClock.getFrameTime()
  275. print 'TRACK_START %0.2f' % (currTime - startTime)
  276. i1 = FunctionInterval(printStart)
  277. # Just to take time
  278. i2 = LerpPosInterval(camera, 2.0, Point3(0,10,5))
  279. # This will be relative to end of camera move
  280. i3 = FunctionInterval(printPreviousEnd)
  281. # Just to take time
  282. i4 = LerpPosInterval(camera, 2.0, Point3(0,0,5))
  283. # This will be relative to the start of the camera move
  284. i5 = FunctionInterval(printPreviousStart)
  285. # This will be relative to track start
  286. i6 = FunctionInterval(printTrackStart)
  287. # Create the track, if you don't specify offset type in tuple it defaults to
  288. # relative to TRACK_START (first entry below)
  289. t2 = Track([(0.0, i1), # i1 start at t = 0, duration = 0.0
  290. (1.0, i2, TRACK_START), # i2 start at t = 1, duration = 2.0
  291. (2.0, i3, PREVIOUS_END), # i3 start at t = 5, duration = 0.0
  292. (1.0, i4, PREVIOUS_END), # i4 start at t = 6, duration = 2.0
  293. (3.0, i5, PREVIOUS_START), # i5 start at t = 9, duration = 0.0
  294. (10.0, i6, TRACK_START)], # i6 start at t = 10, duration = 0.0
  295. name = 'startTimeDemo')
  296. t2.play()
  297. """