home *** CD-ROM | disk | FTP | other *** search
/ Hackers Magazine 57 / CdHackersMagazineNr57.iso / Software / Multimedia / k3d-setup-0.7.11.0.exe / lib / site-packages / cgkit / slideshow.py < prev    next >
Encoding:
Python Source  |  2007-01-11  |  12.3 KB  |  380 lines

  1. # ***** BEGIN LICENSE BLOCK *****
  2. # Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3. #
  4. # The contents of this file are subject to the Mozilla Public License Version
  5. # 1.1 (the "License"); you may not use this file except in compliance with
  6. # the License. You may obtain a copy of the License at
  7. # http://www.mozilla.org/MPL/
  8. #
  9. # Software distributed under the License is distributed on an "AS IS" basis,
  10. # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11. # for the specific language governing rights and limitations under the
  12. # License.
  13. #
  14. # The Original Code is the Python Computer Graphics Kit.
  15. #
  16. # The Initial Developer of the Original Code is Matthias Baas.
  17. # Portions created by the Initial Developer are Copyright (C) 2004
  18. # the Initial Developer. All Rights Reserved.
  19. #
  20. # Contributor(s):
  21. #
  22. # Alternatively, the contents of this file may be used under the terms of
  23. # either the GNU General Public License Version 2 or later (the "GPL"), or
  24. # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  25. # in which case the provisions of the GPL or the LGPL are applicable instead
  26. # of those above. If you wish to allow use of your version of this file only
  27. # under the terms of either the GPL or the LGPL, and not to allow others to
  28. # use your version of this file under the terms of the MPL, indicate your
  29. # decision by deleting the provisions above and replace them with the notice
  30. # and other provisions required by the GPL or the LGPL. If you do not delete
  31. # the provisions above, a recipient may use your version of this file under
  32. # the terms of any one of the MPL, the GPL or the LGPL.
  33. #
  34. # ***** END LICENSE BLOCK *****
  35.  
  36. from _OpenGL.GL import *
  37. import _Image as Image
  38. import _ImageDraw as ImageDraw
  39. import glob, types
  40. import component
  41. from eventmanager import eventManager
  42. from events import *
  43. from scene import getScene
  44. from targetcamera import TargetCamera
  45. from plane import Plane
  46. from quadrics import Sphere
  47. from glmaterial import GLMaterial, GLTexture
  48. from sl import *
  49. from slots import *
  50. from cgtypes import *
  51. from math import *
  52. import cmds
  53. import _core
  54.  
  55. # Cube transition
  56. class XCube:
  57.     def __init__(self, duration=2.0):
  58.         self.duration = duration
  59.     
  60.     # preTransition
  61.     def preTransition(self, slideshow):
  62.         """Prepare transition.
  63.  
  64.         This method is called at the beginning of a transition.
  65.         """
  66.         slideshow.backplate.rot = mat3().rotation(pi/2, vec3(0,1,0))
  67.         slideshow.backplate.pos = vec3(2,0,-2)
  68.         slideshow.helper.pos = vec3(0,0,-2)
  69.         slideshow.helper.rot = mat3(1)
  70.         
  71.         cmds.link(slideshow.frontplate, slideshow.helper)
  72.         cmds.link(slideshow.backplate, slideshow.helper)
  73.  
  74.     # doTransition
  75.     def doTransition(self, slideshow, t):
  76.         """Do the transition.
  77.  
  78.         This method is called every frame during the transition.
  79.         t is the current transition value (0-1).
  80.         At t=0 the frontplate shows and the backplate is not visible,
  81.         at t=1 the frontplate should not be visible anymore and the
  82.         backplate has come to sight
  83.         """
  84.         w = smoothstep(0,1,smoothstep(0, 1, t))
  85.         slideshow.helper.rot = mat3().rotation(-w*pi/2, vec3(0,1,0))
  86.  
  87.     # postTransition
  88.     def postTransition(self, slideshow):
  89.         """Post transition.
  90.  
  91.         This method is called at the end of a transition.
  92.         post: frontplate must be visible
  93.         """
  94.         slideshow.helper.rot = mat3(1)
  95.         cmds.link(slideshow.frontplate, None)
  96.         cmds.link(slideshow.backplate, None)
  97.  
  98.  
  99. # Crossfade
  100. class XFade:
  101.     def __init__(self, duration=2.0, zmove=0.0):
  102.         self.duration = duration
  103.         self.zmove = zmove
  104.  
  105.     ############ XFade transition ####################
  106.  
  107.     def preTransition(self, slideshow):
  108.         slideshow.backplate.pos = slideshow.frontplate.pos+vec3(0,0,-0.001)
  109.         mat = slideshow.frontplate.getMaterial()
  110.         mat.blend_sfactor = GL_SRC_ALPHA
  111.         mat.blend_dfactor = GL_ONE_MINUS_SRC_ALPHA
  112.  
  113.     def doTransition(self, slideshow, t):
  114.         w = smoothstep(0,1,t)
  115.         mat = slideshow.frontplate.getMaterial()
  116.         mat.diffuse = vec4(1,1,1,1-w)
  117.         slideshow.frontplate.pos = vec3(0,0,self.zmove*t*t)
  118.  
  119.     def postTransition(self, slideshow):
  120.         mat = slideshow.frontplate.getMaterial()
  121.         mat.diffuse = vec4(1,1,1,1)
  122.         mat.blend_sfactor = -1
  123.         mat.blend_dfactor = -1
  124.         mat = slideshow.backplate.getMaterial()
  125.         mat.diffuse = vec4(1,1,1,1)
  126.  
  127. ######################################################################
  128.  
  129. # Slide
  130. class Slide:
  131.     def __init__(self, filepattern, transition=XCube()):
  132.         self.files = glob.glob(filepattern)
  133.         self.transition = transition
  134.  
  135. ######################################################################
  136.  
  137. # SlideShow
  138. class SlideShow(component.Component):
  139.     """Slide show component.
  140.     """
  141.     
  142.     def __init__(self, name="SlideShow", slides=[], auto_insert=True):
  143.         
  144.         component.Component.__init__(self, name, auto_insert)
  145.  
  146.         if isinstance(slides, types.StringTypes):
  147.             slides = Slide(slides)
  148.  
  149.         try:
  150.             len(slides)
  151.         except:
  152.             slides = [slides]
  153.  
  154.         self.images = []
  155.         for s in slides:
  156.             for f in s.files:
  157.                 self.images.append((f, s.transition))
  158.  
  159.         # Currently displayed image index
  160.         self.imageidx = 0
  161.  
  162.         self.setup()
  163.  
  164.         em = eventManager()
  165.         em.connect(STEP_FRAME, self)
  166.         em.connect(LEFT_DOWN, self)
  167.         em.connect(KEY_PRESS, self)
  168.  
  169.         self.transition = self.images[0][1]
  170.  
  171.         # Global time when the next transition starts
  172. #        self.transition_start = 3.0
  173.         self.transition_start = 999999.0
  174.         # Slide show state
  175.         self.state = 0
  176.  
  177.  
  178.     # setup
  179.     def setup(self):
  180.         """Setup the scene.
  181.         """
  182.         scene = getScene()
  183.  
  184.         # Set up direction
  185.         scene.up = (0,1,0)
  186.  
  187.         # Camera
  188.         self.cam = TargetCamera(
  189.             name = "SlideShow_Cam",
  190.             pos = (0,0,5.6),
  191.             fov = 30
  192.         )
  193.  
  194.         # Set background...
  195.         gradient = Image.new("RGB", (2,128))
  196.         draw = ImageDraw.Draw(gradient)
  197.         colbottom = vec3(0.1, 0.1, 0.3)
  198.         colmid = vec3(0.95,0.95,1)
  199.         coltop = vec3(0.2, 0.2, 0.4)
  200.         colormap = [colbottom, colbottom, colmid, coltop, coltop]
  201.         for y in range(128):
  202.             t = float(y)/128
  203.             c = spline(t, colormap)
  204.             draw.line([0,y, 1,y], fill=(int(c.x*255), int(c.y*255), int(c.z*255)))
  205.  
  206.         back = Plane(
  207.             lx=4,
  208.             ly=3,
  209.             pos=(0,0,-5),
  210.             scale=2.4,
  211.             material = GLMaterial( diffuse = (0,1,1),
  212.                                    texture = GLTexture(image = gradient,
  213.                                                        mode  = GL_REPLACE))
  214.         )
  215.  
  216.  
  217.         # Create plate materials...
  218.         initial = Image.new("RGB", (4,4))
  219.         invY = mat4(1).translate(vec3(0,1,0)).scale(vec3(1,-1,1))
  220.         
  221.         self.mat1 = GLMaterial(
  222.            diffuse = (1,1,1,1),
  223.            texture = GLTexture( image = initial,
  224.                                 mode = GL_REPLACE,
  225. #                                size = (512,512),
  226.                                 transform = invY,
  227.                                 wrap_s = GL_CLAMP,
  228.                                 wrap_t = GL_CLAMP
  229.                                )
  230.         )
  231.         self.backmaterial = self.mat1
  232.         self.setBackImage(self.images[0][0])
  233.  
  234.         self.mat2 = GLMaterial(
  235.            diffuse = (1,1,1,1),
  236.            texture = GLTexture( image = initial,
  237.                                 mode = GL_REPLACE,
  238. #                                size = (512,512),
  239.                                 transform = invY,
  240.                                 wrap_s = GL_CLAMP,
  241.                                 wrap_t = GL_CLAMP
  242.                                )
  243.         )
  244.         self.backmaterial = self.mat2
  245.         self.setBackImage(self.images[1][0])
  246.  
  247.         self.frontmaterial = self.mat1
  248.         self.backmaterial = self.mat2
  249.  
  250.         # Create plates...
  251.         self.frontplate = Plane(lx = 4, ly = 3, material = self.frontmaterial)
  252.  
  253.         self.backplate = Plane(lx = 4, ly = 3,
  254.                                pos = (0,0,-0.1),
  255.                                material = self.backmaterial
  256.                                )
  257.  
  258.         self.helper = Sphere(radius=0.1, pos=(0,0,-1))
  259.  
  260.  
  261.     # onLeftDown
  262.     def onLeftDown(self, e):
  263.         if self.state==0:
  264.             self.transition_start = getScene().timer().time
  265.  
  266.     def onKeyPress(self, e):
  267.         # Page down or Enter?
  268.         if e.keycode==281 or e.keycode==13:
  269.             self.transition_start = getScene().timer().time
  270.         # Page up
  271.         elif e.keycode==280:
  272.             pass
  273.         # q (reset cam)
  274.         elif e.key=="q":
  275.             getScene().up = vec3(0,1,0)
  276.             self.cam.pos = vec3(0,0,5.6)
  277.             self.cam.target = vec3(0,0,0)
  278.             self.cam.fov = 30
  279.             cmds.link(self.cam)
  280.         
  281.     # onStepFrame
  282.     def onStepFrame(self):
  283.         timer = getScene().timer()
  284.  
  285.         ### State 0: Waiting for the transition
  286.         if self.state==0:
  287.             if timer.time>=self.transition_start:
  288.                 self.state = 1
  289.  
  290.         ### State 1: Begin of transition
  291.         if self.state==1:
  292.             self.transition.preTransition(self)
  293.             eventManager().event("SlidePreTransition", self.images[self.imageidx][0])
  294.             self.state = 2
  295.             
  296.         ### State 2: Transition
  297.         if self.state==2:
  298.             if self.transition.duration>0:
  299.                 t = (timer.time-self.transition_start)/self.transition.duration
  300.             else:
  301.                 t = 1.0
  302.             if t>1.0:
  303.                 t = 1.0
  304.             self.transition.doTransition(self, t)
  305.             eventManager().event("SlideDoTransition", t)
  306.             if t==1.0:
  307.                 self.state = 3
  308.                 
  309.         ### State 3: Transition is over
  310.         elif self.state==3:
  311.             eventManager().event("SlidePostTransition")
  312.             self.transition.postTransition(self)
  313.             self.switchSlide()
  314.  
  315.             self.frontplate.transform = mat4(1)
  316.             self.backplate.transform = mat4(1)
  317.             self.backplate.pos = vec3(0,0,-1)
  318.                        
  319. #            self.transition_start += 5.0
  320.             self.transition_start = 999999.0
  321.             self.state = 0
  322.  
  323.     # switchSlide
  324.     def switchSlide(self):
  325.         """Prepare everything for the next slide.
  326.         """
  327.         # Swap front and back material...
  328.         dummy = self.frontmaterial
  329.         self.frontmaterial = self.backmaterial
  330.         self.backmaterial = dummy
  331.  
  332.         # Update the materials of the plates
  333.         self.frontplate.setMaterial(self.frontmaterial)
  334.         self.backplate.setMaterial(self.backmaterial)
  335.  
  336.         # Set the next image on the back material
  337.         idx = (self.imageidx+2)%len(self.images)
  338.         self.setBackImage(self.images[idx][0])
  339.         self.imageidx = (self.imageidx+1)%len(self.images)
  340.  
  341.         # Set the new transition object
  342.         self.transition = self.images[self.imageidx][1]
  343.         
  344.  
  345.     # setBackImage
  346.     def setBackImage(self, name):
  347.         """Set a new image on the back material."""
  348.         self.backmaterial.texture.imagename = name
  349.         img = Image.open(name)
  350.         if img.mode!="RGB" and img.mode!="RGBA":
  351.             img = img.convert("RGB")
  352.         self.backmaterial.texture.image = img
  353.         w,h = img.size
  354.         f = (4.0*h)/(3.0*w)
  355.         if f>=1.0:
  356.             S = mat4(1).scale(vec3(f,1,1))
  357.             S.translate(vec3(-0.5+0.5/f,0,0))
  358.             draw = ImageDraw.Draw(img)
  359.             draw.line([(0,0), (0,h)], fill=(0,0,0))
  360.             draw.line([(1,0), (1,h)], fill=(0,0,0))
  361.             draw.line([(w-1,0), (w-1,h)], fill=(0,0,0))
  362.             draw.line([(w-2,0), (w-2,h)], fill=(0,0,0))
  363.         else:
  364.             f = (3.0*w)/(4.0*h)
  365.             S = mat4(1).scale(vec3(1,f,1))
  366.             S.translate(vec3(0,-0.5+0.5/f,0))
  367.             draw = ImageDraw.Draw(img)
  368.             draw.line([(0,0), (w,0)], fill=(0,0,0))
  369.             draw.line([(0,1), (w,1)], fill=(0,0,0))
  370.             draw.line([(0,h-1), (w,h-1)], fill=(0,0,0))
  371.             draw.line([(0,h-2), (w,h-2)], fill=(0,0,0))
  372.         invY = mat4(1).translate(vec3(0,1,0)).scale(vec3(1,-1,1))
  373.         self.backmaterial.texture.transform = invY*S
  374.                
  375.             
  376.  
  377. ######################################################################
  378.  
  379. #sl = SlideShow()
  380.