| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434 |
- """Undocumented Module"""
- __all__ = ['Transitions']
- from pandac.PandaModules import *
- from direct.gui.DirectGui import *
- from direct.task import Task
- from direct.interval.IntervalGlobal import *
- class Transitions:
- # These may be reassigned before the fade or iris transitions are
- # actually invoked to change the models that will be used.
- IrisModelName = "models/misc/iris"
- FadeModelName = "models/misc/fade"
- def __init__(self, loader,
- model=None,
- scale=3.0,
- pos=Vec3(0, 0, 0)):
- self.transitionIval = None
- self.letterboxIval = None
- self.iris = None
- self.fade = None
- self.letterbox = None
- self.fadeModel = model
- self.imagePos = pos
- if model:
- self.alphaOff = Vec4(1, 1, 1, 0)
- self.alphaOn = Vec4(1, 1, 1, 1)
- model.setTransparency(1)
- self.lerpFunc = LerpColorScaleInterval
- else:
- self.alphaOff = Vec4(0, 0, 0, 0)
- self.alphaOn = Vec4(0, 0, 0, 1)
- self.lerpFunc = LerpColorInterval
- self.irisTaskName = "irisTask"
- self.fadeTaskName = "fadeTask"
- self.letterboxTaskName = "letterboxTask"
- def __del__(self):
- if self.fadeModel:
- self.fadeModel.removeNode()
- self.fadeModel = None
- ##################################################
- # Fade
- ##################################################
- # We can set a custom model for the fade before using it for the first time
- def setFadeModel(self, model, scale=1.0):
- self.fadeModel = model
- # We have to change some default parameters for a custom fadeModel
- self.alphaOn = Vec4(1, 1, 1, 1)
- # Reload fade if its already been created
- if self.fade:
- del self.fade
- self.fade = None
- self.loadFade()
- def loadFade(self):
- if not self.fadeModel:
- self.fadeModel = loader.loadModel(self.FadeModelName)
- if self.fade == None:
- # We create a DirectFrame for the fade polygon, instead of
- # simply loading the polygon model and using it directly,
- # so that it will also obscure mouse events for objects
- # positioned behind it.
- self.fade = DirectFrame(
- parent = hidden,
- guiId = 'fade',
- relief = None,
- image = self.fadeModel,
- image_scale = 2,
- state = DGG.NORMAL,
- )
- self.fade.setBin('unsorted', 0)
- self.fade.setColor(0,0,0,0)
-
- def getFadeInIval(self, t=0.5, finishIval=None):
- """
- Returns an interval without starting it. This is particularly useful in
- cutscenes, so when the cutsceneIval is escaped out of we can finish the fade immediately
- """
- #self.noTransitions() masad: this creates a one frame pop, is it necessary?
- self.loadFade()
- transitionIval = Sequence(Func(self.fade.reparentTo, render2d, FADE_SORT_INDEX),
- self.lerpFunc(self.fade, t,
- self.alphaOff,
- # self.alphaOn,
- ),
- Func(self.fade.detachNode),
- name = self.fadeTaskName,
- )
- if finishIval:
- transitionIval.append(finishIval)
- return transitionIval
- def getFadeOutIval(self, t=0.5, finishIval=None):
- """
- Create a sequence that lerps the color out, then
- parents the fade to hidden
- """
- self.noTransitions()
- self.loadFade()
- transitionIval = Sequence(Func(self.fade.reparentTo,render2d,FADE_SORT_INDEX),
- self.lerpFunc(self.fade, t,
- self.alphaOn,
- # self.alphaOff,
- ),
- name = self.fadeTaskName,
- )
- if finishIval:
- transitionIval.append(finishIval)
- return transitionIval
-
- def fadeIn(self, t=0.5, finishIval=None):
- """
- Play a fade in transition over t seconds.
- Places a polygon on the aspect2d plane then lerps the color
- from black to transparent. When the color lerp is finished, it
- parents the fade polygon to hidden.
- """
- if (t == 0):
- # Fade in immediately with no lerp
- #print "transitiosn: fadeIn 0.0"
- self.noTransitions()
- self.loadFade()
- self.fade.detachNode()
- else:
- # Create a sequence that lerps the color out, then
- # parents the fade to hidden
- self.transitionIval = self.getFadeInIval(t, finishIval)
- self.transitionIval.start()
- def fadeOut(self, t=0.5, finishIval=None):
- """
- Play a fade out transition over t seconds.
- Places a polygon on the aspect2d plane then lerps the color
- from transparent to full black. When the color lerp is finished,
- it leaves the fade polygon covering the aspect2d plane until you
- fadeIn or call noFade.
- lerp
- """
- if base.config.GetBool('no-loading-screen',0):
- return
- if (t == 0):
- # Fade out immediately with no lerp
- self.noTransitions()
- self.loadFade()
- self.fade.reparentTo(render2d, FADE_SORT_INDEX)
- self.fade.setColor(self.alphaOn)
- else:
- # Create a sequence that lerps the color out, then
- # parents the fade to hidden
- self.transitionIval = self.getFadeOutIval(t,finishIval)
- self.transitionIval.start()
- def fadeOutActive(self):
- return self.fade and self.fade.getColor()[3] > 0
- def fadeScreen(self, alpha=0.5):
- """
- Put a semitransparent screen over the camera plane
- to darken out the world. Useful for drawing attention to
- a dialog box for instance
- """
- #print "transitiosn: fadeScreen"
- self.noTransitions()
- self.loadFade()
- self.fade.reparentTo(render2d, FADE_SORT_INDEX)
- self.fade.setColor(self.alphaOn[0],
- self.alphaOn[1],
- self.alphaOn[2],
- alpha)
- def fadeScreenColor(self, color):
- """
- Put a semitransparent screen over the camera plane
- to darken out the world. Useful for drawing attention to
- a dialog box for instance
- """
- #print "transitiosn: fadeScreenColor"
- self.noTransitions()
- self.loadFade()
- self.fade.reparentTo(render2d, FADE_SORT_INDEX)
- self.fade.setColor(color)
- def noFade(self):
- """
- Removes any current fade tasks and parents the fade polygon away
- """
- #print "transitiosn: noFade"
- if self.transitionIval:
- self.transitionIval.pause()
- self.transitionIval = None
- if self.fade:
- # Make sure to reset the color, since fadeOutActive() is looking at it
- self.fade.setColor(self.alphaOff)
- self.fade.detachNode()
- def setFadeColor(self, r, g, b):
- self.alphaOn.set(r, g, b, 1)
- self.alphaOff.set(r, g, b, 0)
- ##################################################
- # Iris
- ##################################################
- def loadIris(self):
- if self.iris == None:
- self.iris = loader.loadModel(self.IrisModelName)
- self.iris.setPos(0, 0, 0)
- def irisIn(self, t=0.5, finishIval=None):
- """
- Play an iris in transition over t seconds.
- Places a polygon on the aspect2d plane then lerps the scale
- of the iris polygon up so it looks like we iris in. When the
- scale lerp is finished, it parents the iris polygon to hidden.
- """
- self.noTransitions()
- self.loadIris()
- if (t == 0):
- self.iris.detachNode()
- else:
- self.iris.reparentTo(aspect2d, FADE_SORT_INDEX)
- self.transitionIval = Sequence(LerpScaleInterval(self.iris, t,
- scale = 0.18,
- startScale = 0.01),
- Func(self.iris.detachNode),
- name = self.irisTaskName,
- )
- if finishIval:
- self.transitionIval.append(finishIval)
- self.transitionIval.start()
- def irisOut(self, t=0.5, finishIval=None):
- """
- Play an iris out transition over t seconds.
- Places a polygon on the aspect2d plane then lerps the scale
- of the iris down so it looks like we iris out. When the scale
- lerp is finished, it leaves the iris polygon covering the
- aspect2d plane until you irisIn or call noIris.
- """
- self.noTransitions()
- self.loadIris()
- self.loadFade() # we need this to cover up the hole.
- if (t == 0):
- self.iris.detachNode()
- self.fadeOut(0)
- else:
- self.iris.reparentTo(aspect2d, FADE_SORT_INDEX)
- self.transitionIval = Sequence(LerpScaleInterval(self.iris, t,
- scale = 0.01,
- startScale = 0.18),
- Func(self.iris.detachNode),
- # Use the fade to cover up the hole that the iris would leave
- Func(self.fadeOut, 0),
- name = self.irisTaskName,
- )
- if finishIval:
- self.transitionIval.append(finishIval)
- self.transitionIval.start()
- def noIris(self):
- """
- Removes any current iris tasks and parents the iris polygon away
- """
- if self.transitionIval:
- self.transitionIval.pause()
- self.transitionIval = None
- if self.iris != None:
- self.iris.detachNode()
- # Actually we need to remove the fade too,
- # because the iris effect uses it.
- self.noFade()
- def noTransitions(self):
- """
- This call should immediately remove any and all transitions running
- """
- self.noFade()
- self.noIris()
- # Letterbox is not really a transition, it is a screen overlay
- # self.noLetterbox()
- ##################################################
- # Letterbox
- ##################################################
- def loadLetterbox(self):
- if not self.letterbox:
- # We create a DirectFrame for the fade polygon, instead of
- # simply loading the polygon model and using it directly,
- # so that it will also obscure mouse events for objects
- # positioned behind it.
- self.letterbox = NodePath("letterbox")
- # Allow fade in and out of the bars
- self.letterbox.setTransparency(1)
- # Allow DirectLabels to be parented to the letterbox sensibly
- self.letterbox.setBin('unsorted', 0)
-
- # Allow a custom look to the letterbox graphic.
- # TODO: This model isn't available everywhere. We should
- # pass it in as a parameter. In the meantime, at least
- # set the LoaderOptions so there will be no error message
- # if it fails to load.
- options = LoaderOptions()
- options.setFlags(options.getFlags() & ~options.LFReportErrors)
- button = loader.loadModel('models/gui/toplevel_gui',
- loaderOptions = options)
-
- barImage = None
- if button:
- barImage = button.find('**/generic_button')
-
- self.letterboxTop = DirectFrame(
- parent = self.letterbox,
- guiId = 'letterboxTop',
- relief = DGG.FLAT,
- state = DGG.NORMAL,
- frameColor = (0, 0, 0, 1),
- borderWidth = (0, 0),
- frameSize = (-1, 1, 0, 0.2),
- pos = (0, 0, 0.8),
- image = barImage,
- image_scale = (2.25,1,.5),
- image_pos = (0,0,.1),
- image_color = (0.3,0.3,0.3,1),
- sortOrder = 0,
- )
- self.letterboxBottom = DirectFrame(
- parent = self.letterbox,
- guiId = 'letterboxBottom',
- relief = DGG.FLAT,
- state = DGG.NORMAL,
- frameColor = (0, 0, 0, 1),
- borderWidth = (0, 0),
- frameSize = (-1, 1, 0, 0.2),
- pos = (0, 0, -1),
- image = barImage,
- image_scale = (2.25,1,.5),
- image_pos = (0,0,.1),
- image_color = (0.3,0.3,0.3,1),
- sortOrder = 0,
- )
- # masad: always place these at the bottom of render
- self.letterboxTop.setBin('sorted',0)
- self.letterboxBottom.setBin('sorted',0)
- self.letterbox.reparentTo(render2d, -1)
- self.letterboxOff(0)
-
- def noLetterbox(self):
- """
- Removes any current letterbox tasks and parents the letterbox polygon away
- """
- if self.letterboxIval:
- self.letterboxIval.pause()
- self.letterboxIval = None
- if self.letterbox:
- self.letterbox.stash()
- def letterboxOn(self, t=0.25, finishIval=None):
- """
- Move black bars in over t seconds.
- """
- self.noLetterbox()
- self.loadLetterbox()
- self.letterbox.unstash()
- if (t == 0):
- self.letterboxBottom.setPos(0, 0, -1)
- self.letterboxTop.setPos(0, 0, 0.8)
- else:
- self.letterboxIval = Sequence(Parallel(
- LerpPosInterval(self.letterboxBottom,
- t,
- pos = Vec3(0, 0, -1),
- #startPos = Vec3(0, 0, -1.2),
- ),
- LerpPosInterval(self.letterboxTop,
- t,
- pos = Vec3(0, 0, 0.8),
- # startPos = Vec3(0, 0, 1),
- ),
- ),
- name = self.letterboxTaskName,
- )
- if finishIval:
- self.letterboxIval.append(finishIval)
- self.letterboxIval.start()
- def letterboxOff(self, t=0.25, finishIval=None):
- """
- Move black bars away over t seconds.
- """
- self.noLetterbox()
- self.loadLetterbox()
- self.letterbox.unstash()
- if (t == 0):
- self.letterbox.stash()
- else:
- self.letterboxIval = Sequence(Parallel(
- LerpPosInterval(self.letterboxBottom,
- t,
- pos = Vec3(0, 0, -1.2),
- # startPos = Vec3(0, 0, -1),
- ),
- LerpPosInterval(self.letterboxTop,
- t,
- pos = Vec3(0, 0, 1),
- # startPos = Vec3(0, 0, 0.8),
- ),
- ),
- Func(self.letterbox.stash),
- Func(messenger.send,'letterboxOff'),
- name = self.letterboxTaskName,
- )
- if finishIval:
- self.letterboxIval.append(finishIval)
- self.letterboxIval.start()
|