FunctionInterval.py 11 KB

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