示例#1
0
 def label(self, text, x, y):
   result = OnscreenText(
     parent    = self.frame, 
     mayChange = True,
     text      = text,
     scale     = 1,
     fg        = self.TEXT_COLOR,
     align     = panda.TextNode.ALeft
  )
   result.setPos(x, self.top - y * self.V_SPACING)
   return result
示例#2
0
    def __init__(self):
        #Standard title and instruction text
        self.title = OnscreenText(text="Panda3D: Tutorial - Particles",
                                  font=font,
                                  style=1,
                                  fg=(1, 1, 1, 1),
                                  pos=(0.8, -0.95),
                                  scale=.07)
        self.escapeEvent = OnscreenText(text=HELPTEXT,
                                        font=font,
                                        style=1,
                                        fg=(1, 1, 1, 1),
                                        pos=(-1.3, 0.95),
                                        align=TextNode.ALeft,
                                        scale=.05)

        #More standard initialization
        self.accept('escape', sys.exit)
        self.accept('1', self.loadParticleConfig , \
          [os.path.join(PANDA_FILE_PATH, \
          'models/samples/particles/steam.ptf')])
        self.accept('2', self.loadParticleConfig , \
          [os.path.join(PANDA_FILE_PATH, \
          'models/samples/particles/dust.ptf')])
        self.accept('3', self.loadParticleConfig , \
          [os.path.join(PANDA_FILE_PATH, \
          'models/samples/particles/fountain.ptf')])
        self.accept('4', self.loadParticleConfig , \
          [os.path.join(PANDA_FILE_PATH, \
          'models/samples/particles/smoke.ptf')])
        self.accept('5', self.loadParticleConfig , \
          [os.path.join(PANDA_FILE_PATH, \
          'models/samples/particles/smokering.ptf')])
        self.accept('6', self.loadParticleConfig , \
          [os.path.join(PANDA_FILE_PATH, \
          'models/samples/particles/fireish.ptf')])

        self.accept('escape', sys.exit)
        base.disableMouse()
        camera.setPos(0, -20, 2)
        base.setBackgroundColor(0, 0, 0)

        #This command is required for Panda to render particles
        base.enableParticles()
        self.t = loader.loadModel("models/teapot")
        self.t.setPos(0, 10, 0)
        self.t.reparentTo(render)
        self.setupLights()
        self.p = ParticleEffect()
        self.loadParticleConfig(
            os.path.join(PANDA_FILE_PATH,
                         'models/samples/particles/steam.ptf'))
示例#3
0
def genLabelText(text, i):
    return OnscreenText(text=text,
                        pos=(-1.3, .95 - .06 * i),
                        fg=(1, 1, 1, 1),
                        align=TextNode.ALeft,
                        scale=.05,
                        font=font)
示例#4
0
def addInstructions(pos, msg):
    return OnscreenText(text=msg,
                        style=1,
                        fg=(1, 1, 1, 1),
                        font=font,
                        pos=(-1.3, pos),
                        align=TextNode.ALeft,
                        scale=.05)
示例#5
0
def addTitle(text):
    return OnscreenText(text=text,
                        style=1,
                        fg=(1, 1, 1, 1),
                        font=font,
                        pos=(1.3, -0.95),
                        align=TextNode.ARight,
                        scale=.07)
示例#6
0
def addTitle(text):
    return OnscreenText(text=text,
                        style=1,
                        fg=(0, 0, 0, 1),
                        font=font,
                        pos=(1.3, -0.95),
                        align=TextNode.ARight,
                        scale=.07,
                        shadow=(1, 1, 1, 1),
                        shadowOffset=(0.05, 0.05))
示例#7
0
def addInstructions(pos, msg):
    return OnscreenText(text=msg,
                        style=1,
                        fg=(0, 0, 0, 1),
                        mayChange=1,
                        font=font,
                        pos=(-1.3, pos),
                        align=TextNode.ALeft,
                        scale=.05,
                        shadow=(1, 1, 1, 1),
                        shadowOffset=(0.1, 0.1))
示例#8
0
    def __init__(self):
        #This code puts the standard title and instruction text on screen
        self.title = OnscreenText(text="Panda3D: Tutorial - Tasks",
                                  style=1,
                                  fg=(1, 1, 0, 1),
                                  pos=(0.8, -0.95),
                                  scale=.07,
                                  font=font)
        self.escapeText = genLabelText("ESC: Quit", 0)
        self.leftkeyText = genLabelText("[Left Arrow]: Turn Left (CCW)", 1)
        self.rightkeyText = genLabelText("[Right Arrow]: Turn Right (CW)", 2)
        self.upkeyText = genLabelText("[Up Arrow]: Accelerate", 3)
        self.spacekeyText = genLabelText("[Space Bar]: Fire", 4)

        base.disableMouse()  #Disable default mouse-based camera control

        self.bg = loadObject(
            "stars", scale=146, depth=200,
            transparency=False)  #Load the background starfield

        self.ship = loadObject("ship")  #Load the ship
        self.setVelocity(self.ship, Vec3(0, 0, 0))  #Initial velocity

        #A dictionary of what keys are currently being pressed
        #The key events update this list, and our task will query it as input
        self.keys = {"turnLeft": 0, "turnRight": 0, "accel": 0, "fire": 0}

        self.accept("escape", sys.exit)  #Escape quits
        #Other keys events set the appropriate value in our key dictionary
        self.accept("arrow_left", self.setKey, ["turnLeft", 1])
        self.accept("arrow_left-up", self.setKey, ["turnLeft", 0])
        self.accept("arrow_right", self.setKey, ["turnRight", 1])
        self.accept("arrow_right-up", self.setKey, ["turnRight", 0])
        self.accept("arrow_up", self.setKey, ["accel", 1])
        self.accept("arrow_up-up", self.setKey, ["accel", 0])
        self.accept("space", self.setKey, ["fire", 1])

        #Now we create the task. taskMgr is the task manager that actually calls
        #The function each frame. The add method creates a new task. The first
        #argument is the function to be called, and the second argument is the name
        #for the task. It returns a task object, that is passed to the function
        #each frame
        self.gameTask = taskMgr.add(self.gameLoop, "gameLoop")
        #The task object is a good place to put variables that should stay
        #persistant for the task function from frame to frame
        self.gameTask.last = 0  #Task time of the last frame
        self.gameTask.nextBullet = 0  #Task time when the next bullet may be fired

        self.bullets = []  #This empty list will contain fired bullets
        self.spawnAsteroids(
        )  #Complete initialization by spawning the asteroids
示例#9
0
  def __init__(self):
    formatArray=GeomVertexArrayFormat()
    formatArray.addColumn(InternalName.make("drawFlag"), 1, Geom.NTUint8, Geom.COther)

    format=GeomVertexFormat(GeomVertexFormat.getV3n3cpt2())
    format.addArray(formatArray)
    self.format=GeomVertexFormat.registerFormat(format)

    bodydata=GeomVertexData("body vertices", format, Geom.UHStatic)

    self.barkTexture=loader.loadTexture( \
      "models/samples/fractal_plants/bark.jpg")
    treeNodePath=NodePath("Tree Holder")
    makeFractalTree(bodydata,treeNodePath,Vec3(4,4,7))

    treeNodePath.setTexture(self.barkTexture,1)
    treeNodePath.reparentTo(render)

    self.accept("q", self.regenTree)
    self.accept("w", self.addTree)
    self.accept("arrow_up", self.upIterations)
    self.accept("arrow_down", self.downIterations)
    self.accept("arrow_right", self.upCopies)
    self.accept("arrow_left", self.downCopies)

    self.numIterations=11
    self.numCopies=4


    self.upDownEvent = OnscreenText(
      text="Up/Down: Increase/Decrease the number of iterations ("+str(self.numIterations)+")",
          style=1, fg=(1,1,1,1), pos=(-1.3, 0.85), font = font,
      align=TextNode.ALeft, scale = .05, mayChange=True)

    self.leftRightEvent = OnscreenText(
      text="Left/Right: Increase/Decrease branching("+str(self.numCopies)+")",
          style=1, fg=(1,1,1,1), pos=(-1.3, 0.80), font = font,
      align=TextNode.ALeft, scale = .05, mayChange=True)
示例#10
0
    def __init__(self):
        #Standard initialization stuff
        #Standard title that's on screen in every tutorial
        self.title = OnscreenText(
            text='Panda3D: Tutorial - Texture "Movies" (Elevator)',
            style=1,
            fg=(1, 1, 1, 1),
            pos=(0.6, -0.95),
            scale=.07,
            font=loader.loadFont("cmss12"))

        #Load the elevator and attach it to render
        self.elevator = loader.loadModel(
            'models/samples/texture_swapping/elevator')
        self.elevator.reparentTo(render)

        #Load the plane that will be animated and attach it to the elevator iteslf
        self.shadowPlane = loader.loadModel( \
          'models/samples/texture_swapping/shadow_plane')
        self.shadowPlane.reparentTo(self.elevator)
        self.shadowPlane.setPos(0, 0, .01)
        #Load the textures that will be applied to the polygon
        self.shadowTexs = loadTextureMovie(60, \
          'models/samples/texture_swapping/shadow/bar_shadows.', 'jpg')

        #Add the task that will animate the plane
        taskMgr.add(self.elevatorShadows, 'elevatorTask')

        #Builds the shaft, which is a 30ft repeatable segment
        self.shaft = []
        for i in range(-1, 2):
            sh = loader.loadModel('models/samples/texture_swapping/shaft')
            sh.reparentTo(render)
            sh.setPos(-6.977, 0, 30 * i)
            self.shaft.append(sh)

        #Linearly move the elevator's height using an interval.
        #If you replaced this with some other way of moving the elevator, the
        #texture would compensate since it's based on height and not time
        LerpFunc(self.elevator.setZ, fromData=30, toData=-30,
                 duration=5).loop()

        #Puts the camera relative to the elevator in a position that
        #shows off the texture movie
        base.disableMouse()
        camera.reparentTo(self.elevator)
        camera.setPosHpr(-9, 0, 20, -90, -60, 0)
示例#11
0
class MyTapper(DirectObject):
  def __init__(self):
    formatArray=GeomVertexArrayFormat()
    formatArray.addColumn(InternalName.make("drawFlag"), 1, Geom.NTUint8, Geom.COther)

    format=GeomVertexFormat(GeomVertexFormat.getV3n3cpt2())
    format.addArray(formatArray)
    self.format=GeomVertexFormat.registerFormat(format)

    bodydata=GeomVertexData("body vertices", format, Geom.UHStatic)

    self.barkTexture=loader.loadTexture( \
      "models/samples/fractal_plants/bark.jpg")
    treeNodePath=NodePath("Tree Holder")
    makeFractalTree(bodydata,treeNodePath,Vec3(4,4,7))

    treeNodePath.setTexture(self.barkTexture,1)
    treeNodePath.reparentTo(render)

    self.accept("q", self.regenTree)
    self.accept("w", self.addTree)
    self.accept("arrow_up", self.upIterations)
    self.accept("arrow_down", self.downIterations)
    self.accept("arrow_right", self.upCopies)
    self.accept("arrow_left", self.downCopies)

    self.numIterations=11
    self.numCopies=4


    self.upDownEvent = OnscreenText(
      text="Up/Down: Increase/Decrease the number of iterations ("+str(self.numIterations)+")",
          style=1, fg=(1,1,1,1), pos=(-1.3, 0.85), font = font,
      align=TextNode.ALeft, scale = .05, mayChange=True)

    self.leftRightEvent = OnscreenText(
      text="Left/Right: Increase/Decrease branching("+str(self.numCopies)+")",
          style=1, fg=(1,1,1,1), pos=(-1.3, 0.80), font = font,
      align=TextNode.ALeft, scale = .05, mayChange=True)


  def upIterations(self):
    self.numIterations+=1
    self.upDownEvent.setText("Up/Down: Increase/Decrease the number of iterations ("+str(self.numIterations)+")")

  def downIterations(self):
    self.numIterations-=1
    self.upDownEvent.setText("Up/Down: Increase/Decrease the number of Iteratations("+str(self.numIterations)+")")

  def upCopies(self):
    self.numCopies+=1
    self.leftRightEvent.setText("Left/Right: Increase/Decrease branching("+str(self.numCopies)+")")

  def downCopies(self):
    self.numCopies-=1
    self.leftRightEvent.setText("Left/Right: Increase/Decrease branching("+str(self.numCopies)+")")

  def regenTree(self):
    forest=	render.findAllMatches("Tree Holder")
    forest.detach()


    bodydata=GeomVertexData("body vertices", self.format, Geom.UHStatic)

    treeNodePath=NodePath("Tree Holder")
    makeFractalTree(bodydata, treeNodePath,Vec3(4,4,7), Vec3(0,0,0),self.numIterations, self.numCopies)

    treeNodePath.setTexture(self.barkTexture,1)
    treeNodePath.reparentTo(render)

  def addTree(self):

    bodydata=GeomVertexData("body vertices", self.format, Geom.UHStatic)

    randomPlace=Vec3(200*random.random()-100, 200*random.random()-100, 0)
    #randomPlace.normalize()


    treeNodePath=NodePath("Tree Holder")
    makeFractalTree(bodydata, treeNodePath,Vec3(4,4,7), randomPlace, self.numIterations, self.numCopies)

    treeNodePath.setTexture(self.barkTexture,1)
    treeNodePath.reparentTo(render)
示例#12
0
from panda3d.pandac import NodePath
from panda3d.pandac import Vec3,Vec4,Mat4
from panda3d.direct.task.Task import Task
from panda3d.direct.gui.OnscreenText import OnscreenText
from panda3d.direct.showbase.DirectObject import DirectObject
import math, random, time, sys, os


random.seed()
base.disableMouse()
base.camera.setPos(0,-180,30)
numPrimitives=0

font = loader.loadFont("cmss12")
title = OnscreenText(text="Panda3D: Tutorial - Procdurally Making a Tree",
                      style=1, fg=(1,1,1,1), font = font,
                      pos=(0.6,-0.95), scale = .07)
qEvent = OnscreenText(
      text="Q: Start Scene Over", font = font,
          style=1, fg=(1,1,1,1), pos=(-1.3, 0.95),
      align=TextNode.ALeft, scale = .05)
wEvent = OnscreenText(
      text="W: Add Another Tree", font = font,
          style=1, fg=(1,1,1,1), pos=(-1.3, 0.90),
      align=TextNode.ALeft, scale = .05)


#this is a helper function you can use to make a circle in the x-y plane
#i didnt end up needing it but this comes up fairly often so I thought
#I should keep this in the code. Feel free to use.
示例#13
0
    def __init__(self):
        #This code puts the standard title and instruction text on screen
        self.title = OnscreenText(text="Panda3D: Tutorial - Actors",
                                  style=1,
                                  fg=(0, 0, 0, 1),
                                  font=font,
                                  pos=(0.8, -0.95),
                                  scale=.07)
        self.escapeEventText = self.genLabelText("ESC: Quit", 0)
        self.akeyEventText = self.genLabelText("[A]: Robot 1 Left Punch", 1)
        self.skeyEventText = self.genLabelText("[S]: Robot 1 Right Punch", 2)
        self.kkeyEventText = self.genLabelText("[K]: Robot 2 Left Punch", 3)
        self.lkeyEventText = self.genLabelText("[L]: Robot 2 Right Punch", 4)

        #Set the camera in a fixed position
        base.disableMouse()
        camera.setPosHpr(14.5, -15.4, 14, 45, -14, 0)
        base.setBackgroundColor(0, 0, 0)

        #Add lighting so that the objects are not drawn flat
        self.setupLights()

        #Load the ring
        self.ring = loader.loadModel('models/samples/boxing_robots/ring')
        self.ring.reparentTo(render)

        #Models that use skeletal animation are known as Actors instead of models
        #Instead of just one file, the have one file for the main model, and an
        #additional file for each playable animation.
        #They are loaded using Actor.Actor instead of loader.LoadModel.
        #The constructor takes the location of the main object as with a normal
        #model and a dictionary (A fancy python structure that is like a lookup
        #table) that contains names for animations, and paths to the appropriate
        #files
        self.robot1 = Actor.Actor(
            'models/samples/boxing_robots/robot', {
                'leftPunch': 'models/samples/boxing_robots/robot_left_punch',
                'rightPunch': 'models/samples/boxing_robots/robot_right_punch',
                'headUp': 'models/samples/boxing_robots/robot_head_up',
                'headDown': 'models/samples/boxing_robots/robot_head_down'
            })

        #Actors need to be positioned and parented like normal objects
        self.robot1.setPosHprScale(-1, -2.5, 4, 45, 0, 0, 1.25, 1.25, 1.25)
        self.robot1.reparentTo(render)

        #We'll repeat the process for the second robot. The only thing that changes
        #here is the robot's color and position
        self.robot2 = Actor.Actor(
            'models/samples/boxing_robots/robot', {
                'leftPunch': 'models/samples/boxing_robots/robot_left_punch',
                'rightPunch': 'models/samples/boxing_robots/robot_right_punch',
                'headUp': 'models/samples/boxing_robots/robot_head_up',
                'headDown': 'models/samples/boxing_robots/robot_head_down'
            })

        #Set the properties of this robot
        self.robot2.setPosHprScale(1, 1.5, 4, 225, 0, 0, 1.25, 1.25, 1.25)
        self.robot2.setColor(Vec4(.7, 0, 0, 1))
        self.robot2.reparentTo(render)

        #Now we define how the animated models will move. Animations are played
        #through special intervals. In this case we use actor intervals in a
        #sequence to play the part of the punch animation where the arm extends,
        #call a function to check if the punch landed, and then play the part of the
        #animation where the arm retracts

        #Punch sequence for robot 1's left arm
        self.robot1.punchLeft = Sequence(
            #Interval for the outstreched animation
            self.robot1.actorInterval('leftPunch', startFrame=1, endFrame=10),
            Func(self.checkPunch,
                 2),  #Function to check if the punch was successful
            #Interval for the retract animation
            self.robot1.actorInterval('leftPunch', startFrame=11, endFrame=32))

        #Punch sequence for robot 1's right arm
        self.robot1.punchRight = Sequence(
            self.robot1.actorInterval('rightPunch', startFrame=1, endFrame=10),
            Func(self.checkPunch, 2),
            self.robot1.actorInterval('rightPunch', startFrame=11,
                                      endFrame=32))

        #Punch sequence for robot 2's left arm
        self.robot2.punchLeft = Sequence(
            self.robot2.actorInterval('leftPunch', startFrame=1, endFrame=10),
            Func(self.checkPunch, 1),
            self.robot2.actorInterval('leftPunch', startFrame=11, endFrame=32))

        #Punch sequence for robot 2's right arm
        self.robot2.punchRight = Sequence(
            self.robot2.actorInterval('rightPunch', startFrame=1, endFrame=10),
            Func(self.checkPunch, 1),
            self.robot2.actorInterval('rightPunch', startFrame=11,
                                      endFrame=32))

        #We use the same techinique to create a sequence for when a robot is knocked
        #out where the head pops up, waits a while, and then resets

        #Head animation for robot 1
        self.robot1.resetHead = Sequence(
            #Interval for the head going up. Since no start or end frames were given,
            #the entire animation is played.
            self.robot1.actorInterval('headUp'),
            Wait(3),
            #The head down animation was animated a little too quickly, so this will
            #play it at 75% of it's normal speed
            self.robot1.actorInterval('headDown', playRate=.75))

        #Head animation for robot 2
        self.robot2.resetHead = Sequence(
            self.robot2.actorInterval('headUp'), Wait(3),
            self.robot2.actorInterval('headDown', playRate=.75))

        #Now that we have defined the motion, we can define our key input.
        #Each fist is bound to a key. When a key is pressed, self.tryPunch checks to
        #make sure that the both robots have their heads down, and if they do it
        #plays the given interval
        self.accept('escape', sys.exit)
        self.accept('a', self.tryPunch, [self.robot1.punchLeft])
        self.accept('s', self.tryPunch, [self.robot1.punchRight])
        self.accept('k', self.tryPunch, [self.robot2.punchLeft])
        self.accept('l', self.tryPunch, [self.robot2.punchRight])
示例#14
0
  def __init__( self ):
  #The main initialization of our class
    #This creates the on screen title that is in every tutorial
    self.title = OnscreenText(text="Panda3D: Tutorial - Lighting",
                              style=1, fg=(1,1,0,1), font = font,
                              pos=(0.87,-0.95), scale = .07)

    #Creates labels used for onscreen instructions
    self.ambientText = self.makeStatusLabel(0)
    self.directionalText = self.makeStatusLabel(1)
    self.spotlightText = self.makeStatusLabel(2)
    self.pointLightText = self.makeStatusLabel(3)
    self.spinningText = self.makeStatusLabel(4)
    self.ambientBrightnessText = self.makeStatusLabel(5)
    self.directionalBrightnessText = self.makeStatusLabel(6)
    self.spotlightBrightnessText = self.makeStatusLabel(7)
    self.spotlightExponentText = self.makeStatusLabel(8)
    self.lightingPerPixelText = self.makeStatusLabel(9)

    self.disco = loader.loadModel("models/samples/disco_lights/disco_hall")
    self.disco.reparentTo(render)
    self.disco.setPosHpr(0, 50, -4, 90, 0, 0)

    # First we create an ambient light. All objects are affected by ambient
    # light equally
    #Create and name the ambient light
    self.ambientLight = render.attachNewNode( AmbientLight( "ambientLight" ) )
    #Set the color of the ambient light
    self.ambientLight.node().setColor( Vec4( .1, .1, .1, 1 ) )
    #add the newly created light to the lightAttrib

    # Now we create a directional light. Directional lights add shading from a
    # given angle. This is good for far away sources like the sun
    self.directionalLight = render.attachNewNode( DirectionalLight(
"directionalLight" ) )
    self.directionalLight.node().setColor( Vec4( .35, .35, .35, 1 ) )
    # The direction of a directional light is set as a 3D vector
    self.directionalLight.node().setDirection( Vec3( 1, 1, -2 ) )

    # Now we create a spotlight. Spotlights light objects in a given cone
    # They are good for simulating things like flashlights
    self.spotlight = camera.attachNewNode( Spotlight( "spotlight" ) )
    self.spotlight.node().setColor( Vec4( .45, .45, .45, 1 ) )
    #The cone of a spotlight is controlled by it's lens. This creates the lens
    self.spotlight.node().setLens( PerspectiveLens() )
    #This sets the Field of View (fov) of the lens, in degrees for width and
    #height. The lower the numbers, the tighter the spotlight.
    self.spotlight.node().getLens().setFov( 16, 16 )
    # Attenuation controls how the light fades with distance. The numbers are
    # The three values represent the three constants (constant, linear, and
    # quadratic) in the internal lighting equation. The higher the numbers the
    # shorter the light goes.
    self.spotlight.node().setAttenuation( Vec3( 1, 0.0, 0.0 ) ) 
    # This exponent value sets how soft the edge of the spotlight is. 0 means a
    # hard edge. 128 means a very soft edge.
    self.spotlight.node().setExponent( 60.0 )

    # Now we create three colored Point lights. Point lights are lights that
    # radiate from a single point, like a light bulb. Like spotlights, they
    # are given position by attaching them to NodePaths in the world
    self.redHelper = loader.loadModel('models/samples/disco_lights/sphere')
    self.redHelper.setColor( Vec4( 1, 0, 0, 1 ) )
    self.redHelper.setPos( -6.5, -3.75, 0 )
    self.redHelper.setScale(.25)
    self.redPointLight = self.redHelper.attachNewNode( PointLight(
"redPointLight" ) )
    self.redPointLight.node().setColor( Vec4( .35, 0, 0, 1 ) )
    self.redPointLight.node().setAttenuation( Vec3( .1, 0.04, 0.0 ) ) 

    #The green point light and helper
    self.greenHelper = loader.loadModel('models/samples/disco_lights/sphere')
    self.greenHelper.setColor( Vec4( 0, 1, 0, 1 ) )
    self.greenHelper.setPos( 0, 7.5, 0 )
    self.greenHelper.setScale(.25)
    self.greenPointLight = self.greenHelper.attachNewNode( PointLight(
"greenPointLight" ) )
    self.greenPointLight.node().setAttenuation( Vec3( .1, .04, .0 ) ) 
    self.greenPointLight.node().setColor( Vec4( 0, .35, 0, 1 ) )

    #The blue point light and helper
    self.blueHelper = loader.loadModel('models/samples/disco_lights/sphere')
    self.blueHelper.setColor( Vec4( 0, 0, 1, 1 ) )
    self.blueHelper.setPos( 6.5, -3.75, 0 )
    self.blueHelper.setScale(.25)
    self.bluePointLight = self.blueHelper.attachNewNode( PointLight( "bluePointLight" ) )
    self.bluePointLight.node().setAttenuation( Vec3( .1, 0.04, 0.0 ) ) 
    self.bluePointLight.node().setColor( Vec4( 0, 0, .35, 1 ) )
    self.bluePointLight.node().setSpecularColor( Vec4( 1 ) )

    #Create a dummy node so the lights can be spun with one command
    self.pointLightHelper = render.attachNewNode( "pointLightHelper" )
    self.pointLightHelper.setPos(0, 50, 11)
    self.redHelper.reparentTo( self.pointLightHelper )
    self.greenHelper.reparentTo( self.pointLightHelper )
    self.blueHelper.reparentTo( self.pointLightHelper )

    #Finally we store the lights on the root of the scene graph.
    #This will cause them to affect everything in the scene.

    render.setLight( self.ambientLight )
    render.setLight( self.directionalLight )
    render.setLight( self.spotlight )
    render.setLight( self.redPointLight )
    render.setLight( self.greenPointLight )
    render.setLight( self.bluePointLight )

    # Create and start interval to spin the lights, and a variable to
    # manage them.
    self.pointLightsSpin = self.pointLightHelper.hprInterval(6, Vec3(360, 0, 0))
    self.pointLightsSpin.loop()
    self.arePointLightsSpinning = True

    # Per-pixel lighting is initially off
    self.perPixelEnabled = False

    # listen to keys for controlling the lights
    self.accept( "escape", sys.exit)
    self.accept( "a", self.toggleLights, [[self.ambientLight]] )
    self.accept( "d", self.toggleLights, [[self.directionalLight]] )
    self.accept( "s", self.toggleLights, [[self.spotlight]] )
    self.accept( "p", self.toggleLights, [[self.redPointLight,
                                           self.greenPointLight,
                                           self.bluePointLight]] )
    self.accept( "r", self.toggleSpinningPointLights )
    self.accept( "l", self.togglePerPixelLighting )
    self.accept( "z", self.addBrightness, [self.ambientLight, -.05] )
    self.accept( "x", self.addBrightness, [self.ambientLight, .05] )
    self.accept( "c", self.addBrightness, [self.directionalLight, -.05] )
    self.accept( "v", self.addBrightness, [self.directionalLight, .05] )
    self.accept( "b", self.addBrightness, [self.spotlight, -.05] )
    self.accept( "n", self.addBrightness, [self.spotlight, .05] )
    self.accept( "q", self.adjustSpotlightExponent, [self.spotlight, -1] )
    self.accept( "w", self.adjustSpotlightExponent, [self.spotlight, 1] )

    #Finally call the function that builds the instruction texts
    self.updateStatusLabel()
示例#15
0
    def __init__(self):

        # create a texture into which we can copy the main window.

        self.tex = Texture()
        self.tex.setMinfilter(Texture.FTLinear)
        base.win.addRenderTexture(self.tex,
                                  GraphicsOutput.RTMTriggeredCopyTexture)

        # Create another 2D camera. Tell it to render before the main camera.

        self.backcam = base.makeCamera2d(base.win, sort=-10)
        self.background = NodePath("background")
        self.backcam.reparentTo(self.background)
        self.background.setDepthTest(0)
        self.background.setDepthWrite(0)
        self.backcam.node().getDisplayRegion(0).setClearDepthActive(0)

        # Obtain two texture cards. One renders before the dragon, the other after.
        self.bcard = base.win.getTextureCard()
        self.bcard.reparentTo(self.background)
        self.bcard.setTransparency(1)
        self.fcard = base.win.getTextureCard()
        self.fcard.reparentTo(render2d)
        self.fcard.setTransparency(1)

        # Initialize one of the nice effects.
        self.chooseEffectGhost()

        # Add the task that initiates the screenshots.
        taskMgr.add(self.takeSnapShot, "takeSnapShot")

        # Create some black squares on top of which we will
        # place the instructions.
        blackmaker = CardMaker("blackmaker")
        blackmaker.setColor(0, 0, 0, 1)
        blackmaker.setFrame(-1.00, -0.50, 0.65, 1.00)
        instcard = NodePath(blackmaker.generate())
        instcard.reparentTo(render2d)
        blackmaker.setFrame(-0.5, 0.5, -1.00, -0.85)
        titlecard = NodePath(blackmaker.generate())
        titlecard.reparentTo(render2d)

        # Panda does its best to hide the differences between DirectX and
        # OpenGL.  But there are a few differences that it cannot hide.
        # One such difference is that when OpenGL copies from a
        # visible window to a texture, it gets it right-side-up.  When
        # DirectX does it, it gets it upside-down.  There is nothing panda
        # can do to compensate except to expose a flag and let the
        # application programmer deal with it.  You should only do this
        # in the rare event that you're copying from a visible window
        # to a texture.

        if (base.win.getGsg().getCopyTextureInverted()):
            print "Copy texture is inverted."
            self.bcard.setScale(1, 1, -1)
            self.fcard.setScale(1, 1, -1)

        # Put up the instructions
        title = OnscreenText(text="Panda3D: Tutorial - Motion Trails",
                             style=1,
                             fg=(1, 1, 1, 1),
                             font=font,
                             pos=(0, -0.95),
                             scale=.07)

        instr0 = addInstructions(0.95, "Press ESC to exit")
        instr1 = addInstructions(0.90, "Press 1: Ghost effect")
        instr2 = addInstructions(0.85, "Press 2: PaintBrush effect")
        instr3 = addInstructions(0.80, "Press 3: Double Vision effect")
        instr4 = addInstructions(0.75, "Press 4: Wings of Blue effect")
        instr5 = addInstructions(0.70, "Press 5: Whirlpool effect")

        # enable the key events
        self.accept("escape", sys.exit, [0])
        self.accept("1", self.chooseEffectGhost)
        self.accept("2", self.chooseEffectPaintBrush)
        self.accept("3", self.chooseEffectDoubleVision)
        self.accept("4", self.chooseEffectWingsOfBlue)
        self.accept("5", self.chooseEffectWhirlpool)
示例#16
0
  def __init__(self):
    #This code puts the standard title and instruction text on screen
    self.title = OnscreenText(text="Panda3D: Tutorial - Mouse Picking",
                              style=1, fg=(1,1,1,1), font = font,
                              pos=(0.8,-0.95), scale = .07)
    self.escapeEvent = OnscreenText( 
      text="ESC: Quit", font = font,
      style=1, fg=(1,1,1,1), pos=(-1.3, 0.95),
      align=TextNode.ALeft, scale = .05)
    self.mouse1Event = OnscreenText(
      text="Left-click and drag: Pick up and drag piece",
      style=1, fg=(1,1,1,1), pos=(-1.3, 0.90), font = font,
      align=TextNode.ALeft, scale = .05)

    self.accept('escape', sys.exit)              #Escape quits
    base.disableMouse()                          #Disble mouse camera control
    camera.setPosHpr(0, -13.75, 6, 0, -25, 0)    #Set the camera
    self.setupLights()                           #Setup default lighting
    
    #Since we are using collision detection to do picking, we set it up like
    #any other collision detection system with a traverser and a handler
    self.picker = CollisionTraverser()            #Make a traverser
    self.pq     = CollisionHandlerQueue()         #Make a handler
    #Make a collision node for our picker ray
    self.pickerNode = CollisionNode('mouseRay')
    #Attach that node to the camera since the ray will need to be positioned
    #relative to it
    self.pickerNP = camera.attachNewNode(self.pickerNode)
    #Everything to be picked will use bit 1. This way if we were doing other
    #collision we could seperate it
    self.pickerNode.setFromCollideMask(BitMask32.bit(1))
    self.pickerRay = CollisionRay()               #Make our ray
    self.pickerNode.addSolid(self.pickerRay)      #Add it to the collision node
    #Register the ray as something that can cause collisions
    self.picker.addCollider(self.pickerNP, self.pq)
    #self.picker.showCollisions(render)

    #Now we create the chess board and its pieces

    #We will attach all of the squares to their own root. This way we can do the
    #collision pass just on the sqaures and save the time of checking the rest
    #of the scene
    self.squareRoot = render.attachNewNode("squareRoot")
    
    #For each square
    self.squares = [None for i in range(64)]
    self.pieces = [None for i in range(64)]
    for i in range(64):
      #Load, parent, color, and position the model (a single square polygon)
      self.squares[i] = loader.loadModel("models/samples/chessboard/square")
      self.squares[i].reparentTo(self.squareRoot)
      self.squares[i].setPos(SquarePos(i))
      self.squares[i].setColor(SquareColor(i))
      #Set the model itself to be collideable with the ray. If this model was
      #any more complex than a single polygon, you should set up a collision
      #sphere around it instead. But for single polygons this works fine.
      self.squares[i].find("**/polygon").node().setIntoCollideMask(
        BitMask32.bit(1))
      #Set a tag on the square's node so we can look up what square this is
      #later during the collision pass
      self.squares[i].find("**/polygon").node().setTag('square', str(i))

      #We will use this variable as a pointer to whatever piece is currently
      #in this square

    #The order of pieces on a chessboard from white's perspective. This list
    #contains the constructor functions for the piece classes defined below
    pieceOrder = (Rook, Knight, Bishop, Queen, King, Bishop, Knight, Rook)

    for i in range (8,16):
      #Load the white pawns
      self.pieces[i] = Pawn(i, WHITE)
    for i in range (48,56):
      #load the black pawns
      self.pieces[i] = Pawn(i, PIECEBLACK)
    for i in range(8):
      #Load the special pieces for the front row and color them white
      self.pieces[i] = pieceOrder[i](i, WHITE)
      #Load the special pieces for the back row and color them black
      self.pieces[i+56] = pieceOrder[i](i+56, PIECEBLACK)

    #This will represent the index of the currently highlited square
    self.hiSq = False
    #This wil represent the index of the square where currently dragged piece
    #was grabbed from
    self.dragging = False

    #Start the task that handles the picking
    self.mouseTask = taskMgr.add(self.mouseTask, 'mouseTask')
    self.accept("mouse1", self.grabPiece)       #left-click grabs a piece
    self.accept("mouse1-up", self.releasePiece) #releasing places it
示例#17
0
    def __init__(self):
        #This code puts the standard title and instruction text on screen
        self.title = OnscreenText(
            text="Panda3D: Tutorial - Collision Detection",
            style=1,
            fg=(1, 1, 1, 1),
            pos=(0.7, -0.95),
            scale=.07,
            font=font)
        self.instructions = OnscreenText(text="Mouse pointer tilts the board",
                                         pos=(-1.3, .95),
                                         fg=(1, 1, 1, 1),
                                         font=font,
                                         align=TextNode.ALeft,
                                         scale=.05)

        self.accept("escape", sys.exit)  #Escape quits
        base.disableMouse()  #Disable mouse-based camera control
        camera.setPosHpr(0, 0, 25, 0, -90, 0)  #Place the camera

        #Load the maze and place it in the scene
        self.maze = loader.loadModel("models/samples/ball_in_maze/maze")
        self.maze.reparentTo(render)

        #Most times, you want collisions to be tested against invisible geometry
        #rather than every polygon. This is because testing against every polygon
        #in the scene is usually too slow. You can have simplified or approximate
        #geometry for the solids and still get good results.
        #
        #Sometimes you'll want to create and position your own collision solids in
        #code, but it's often easier to have them built automatically. This can be
        #done by adding special tags into an egg file. Check maze.egg and ball.egg
        #and look for lines starting with <Collide>. The part is brackets tells
        #Panda exactly what to do. Polyset means to use the polygons in that group
        #as solids, while Sphere tells panda to make a collision sphere around them
        #Keep means to keep the polygons in the group as visable geometry (good
        #for the ball, not for the triggers), and descend means to make sure that
        #the settings are applied to any subgroups.
        #
        #Once we have the collision tags in the models, we can get to them using
        #NodePath's find command

        #Find the collision node named wall_collide
        self.walls = self.maze.find("**/wall_collide")

        #Collision objects are sorted using BitMasks. BitMasks are ordinary numbers
        #with extra methods for working with them as binary bits. Every collision
        #solid has both a from mask and an into mask. Before Panda tests two
        #objects, it checks to make sure that the from and into collision masks
        #have at least one bit in common. That way things that shouldn't interact
        #won't. Normal model nodes have collision masks as well. By default they
        #are set to bit 20. If you want to collide against actual visable polygons,
        #set a from collide mask to include bit 20
        #
        #For this example, we will make everything we want the ball to collide with
        #include bit 0
        self.walls.node().setIntoCollideMask(BitMask32.bit(0))
        #CollisionNodes are usually invisible but can be shown. Uncomment the next
        #line to see the collision walls
        #self.walls.show()

        #We will now find the triggers for the holes and set their masks to 0 as
        #well. We also set their names to make them easier to identify during
        #collisions
        self.loseTriggers = []
        for i in range(6):
            trigger = self.maze.find("**/hole_collide" + str(i))
            trigger.node().setIntoCollideMask(BitMask32.bit(0))
            trigger.node().setName("loseTrigger")
            self.loseTriggers.append(trigger)
            #Uncomment this line to see the triggers
            #trigger.show()

        #Ground_collide is a single polygon on the same plane as the ground in the
        #maze. We will use a ray to collide with it so that we will know exactly
        #what height to put the ball at every frame. Since this is not something
        #that we want the ball itself to collide with, it has a different
        #bitmask.
        self.mazeGround = self.maze.find("**/ground_collide")
        self.mazeGround.node().setIntoCollideMask(BitMask32.bit(1))

        #Load the ball and attach it to the scene
        #It is on a root dummy node so that we can rotate the ball itself without
        #rotating the ray that will be attached to it
        self.ballRoot = render.attachNewNode("ballRoot")
        self.ball = loader.loadModel("models/samples/ball_in_maze/ball")
        self.ball.reparentTo(self.ballRoot)

        #Find the collison sphere for the ball which was created in the egg file
        #Notice that it has a from collision mask of bit 0, and an into collison
        #mask of no bits. This means that the ball can only cause collisions, not
        #be collided into
        self.ballSphere = self.ball.find("**/ball")
        self.ballSphere.node().setFromCollideMask(BitMask32.bit(0))
        self.ballSphere.node().setIntoCollideMask(BitMask32.allOff())

        #No we create a ray to start above the ball and cast down. This is to
        #Determine the height the ball should be at and the angle the floor is
        #tilting. We could have used the sphere around the ball itself, but it
        #would not be as reliable
        self.ballGroundRay = CollisionRay()  #Create the ray
        self.ballGroundRay.setOrigin(0, 0, 10)  #Set its origin
        self.ballGroundRay.setDirection(0, 0, -1)  #And its direction
        #Collision solids go in CollisionNode
        self.ballGroundCol = CollisionNode(
            'groundRay')  #Create and name the node
        self.ballGroundCol.addSolid(self.ballGroundRay)  #Add the ray
        self.ballGroundCol.setFromCollideMask(
            BitMask32.bit(1))  #Set its bitmasks
        self.ballGroundCol.setIntoCollideMask(BitMask32.allOff())
        #Attach the node to the ballRoot so that the ray is relative to the ball
        #(it will always be 10 feet over the ball and point down)
        self.ballGroundColNp = self.ballRoot.attachNewNode(self.ballGroundCol)
        #Uncomment this line to see the ray
        #self.ballGroundColNp.show()

        #Finally, we create a CollisionTraverser. CollisionTraversers are what
        #do the job of calculating collisions
        self.cTrav = CollisionTraverser()
        #Collision traverservs tell collision handlers about collisions, and then
        #the handler decides what to do with the information. We are using a
        #CollisionHandlerQueue, which simply creates a list of all of the
        #collisions in a given pass. There are more sophisticated handlers like
        #one that sends events and another that tries to keep collided objects
        #apart, but the results are often better with a simple queue
        self.cHandler = CollisionHandlerQueue()
        #Now we add the collision nodes that can create a collision to the
        #traverser. The traverser will compare these to all others nodes in the
        #scene. There is a limit of 32 CollisionNodes per traverser
        #We add the collider, and the handler to use as a pair
        self.cTrav.addCollider(self.ballSphere, self.cHandler)
        self.cTrav.addCollider(self.ballGroundColNp, self.cHandler)

        #Collision traversers have a built in tool to help visualize collisions.
        #Uncomment the next line to see it.
        #self.cTrav.showCollisions(render)

        #This section deals with lighting for the ball. Only the ball was lit
        #because the maze has static lighting pregenerated by the modeler
        lAttrib = LightAttrib.makeAllOff()
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor(Vec4(.55, .55, .55, 1))
        lAttrib = lAttrib.addLight(ambientLight)
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection(Vec3(0, 0, -1))
        directionalLight.setColor(Vec4(0.375, 0.375, 0.375, 1))
        directionalLight.setSpecularColor(Vec4(1, 1, 1, 1))
        lAttrib = lAttrib.addLight(directionalLight)
        self.ballRoot.node().setAttrib(lAttrib)

        #This section deals with adding a specular highlight to the ball to make
        #it look shiny
        m = Material()
        m.setSpecular(Vec4(1, 1, 1, 1))
        m.setShininess(96)
        self.ball.setMaterial(m, 1)

        #Finally, we call start for more initialization
        self.start()
示例#18
0
    def __init__(self):

        #Our standard title and instructions text
        self.title = OnscreenText(text="Panda3D: Tutorial - Musicbox(sounds)",
                                  font=font,
                                  style=1,
                                  fg=(1, 1, 1, 1),
                                  pos=(0.7, -0.95),
                                  scale=.07)
        self.escapeEventText = OnscreenText(text="ESC: Quit",
                                            font=font,
                                            style=1,
                                            fg=(1, 1, 1, 1),
                                            pos=(-1.3, 0.95),
                                            align=TextNode.ALeft,
                                            scale=.05)

        #Set up the key input
        self.accept('escape', sys.exit)

        #Fix the camera position
        base.disableMouse()

        #Loading sounds is done in a similar way to loading other things
        #Loading the main music box song
        self.musicBoxSound = base.loadMusic(
            'models/samples/music_box/musicbox.mp3')
        self.musicBoxSound.setVolume(.5)  #Volume is a percentage from 0 to 1
        self.musicBoxSound.setLoopCount(
            0)  #0 means loop forever, 1 (default) means
        #play once. 2 or higher means play that
        #many times

        #Sound objects do not have a pause function, just play and stop. So we will
        #Use this variable to keep track of where the sound is at when it was stoped
        #to impliment pausing
        self.musicTime = 0

        #Loading the open/close effect
        #loadSFX and loadMusic are identical. They are often used for organization
        #(loadMusic is used for background music, loadSfx is used for other effects)
        self.lidSfx = base.loadSfx('models/samples/music_box/openclose.mp3')
        #The open/close file has both effects in it. Fortunatly we can use intervals
        #to easily define parts of a sound file to play
        self.lidOpenSfx = SoundInterval(self.lidSfx, duration=2, startTime=0)
        self.lidCloseSfx = SoundInterval(self.lidSfx, startTime=5)

        #For this tutorial, it seemed appropriate to have on screen controls. The
        #following code creates them
        #This is a label for a slider
        self.sliderText = OnscreenText("Volume",
                                       font=font,
                                       style=1,
                                       fg=(1, 1, 1, 1),
                                       pos=(0, 0.8),
                                       scale=.07)
        #The slider itself. It calls self.setMusicBoxVolume when changed
        self.slider = DirectSlider(pos=Vec3(0, 0, .7),
                                   value=.50,
                                   command=self.setMusicBoxVolume)
        #A button that calls self.toggleMusicBox when pressed
        self.button = DirectButton(pos=Vec3(.7, 0, .7),
                                   text="Open Box",
                                   scale=.1,
                                   pad=(.5, .5),
                                   text_font=font,
                                   rolloverSound=None,
                                   clickSound=None,
                                   command=self.toggleMusicBox)

        #A variable to represent the state of the simulation. It starts closed
        self.boxOpen = False

        #Here we load and set up the music box. It was modeled in a complex way, so
        #setting it up will be complicated
        self.musicBox = loader.loadModel('models/samples/music_box/musicbox')
        self.musicBox.setPos(0, 60, -10)
        self.musicBox.reparentTo(render)
        #Just like the scene graph contains hierarchies of nodes, so can
        #models. You can get the NodePath for the node using the find
        #function, and then you can animate the model by moving its parts
        #To see the hierarchy of a model, use, the ls function
        #self.musicBox.ls() prints out the entire hierarchy of the model

        #Finding pieces of the model
        self.Lid = self.musicBox.find('**/lid')
        self.Panda = self.musicBox.find('**/turningthing')

        #This model was made with the hinge in the wrong place
        #this is here so we have something to turn
        self.HingeNode = self.musicBox.find('**/box').attachNewNode(
            'nHingeNode')
        self.HingeNode.setPos(.8659, 6.5, 5.4)
        #WRT - ie with respect to. Reparents the object without changing
        #its position, size, or orientation
        self.Lid.wrtReparentTo(self.HingeNode)
        self.HingeNode.setHpr(0, 90, 0)

        #This sets up an interval to play the close sound and actually close the box
        #at the same time.
        self.lidClose = Parallel(
            self.lidCloseSfx,
            LerpFunc(self.HingeNode.setP,
                     duration=2,
                     fromData=0,
                     toData=90,
                     blendType='easeInOut'))

        #Same thing for opening the box
        self.lidOpen = Parallel(
            self.lidOpenSfx,
            LerpFunc(self.HingeNode.setP,
                     duration=2,
                     fromData=90,
                     toData=0,
                     blendType='easeInOut'))

        #The interval for turning the panda
        self.PandaTurn = self.Panda.hprInterval(7, Vec3(360, 0, 0))
        #Do a quick loop and pause to set it as a looping interval so it can be
        #started with resume and loop properly
        self.PandaTurn.loop()
        self.PandaTurn.pause()
示例#19
0
    def __init__(self):
        #This code puts the standard title and instruction text on screen
        self.title = OnscreenText(
            text="Panda3D: Tutorial - Joint Manipulation",
            style=1,
            fg=(1, 1, 1, 1),
            font=font,
            pos=(0.7, -0.95),
            scale=.07)
        self.onekeyText = genLabelText("ESC: Quit", 0)
        self.onekeyText = genLabelText("[1]: Teapot", 1)
        self.twokeyText = genLabelText("[2]: Candy cane", 2)
        self.threekeyText = genLabelText("[3]: Banana", 3)
        self.fourkeyText = genLabelText("[4]: Sword", 4)

        #setup key input
        self.accept('escape', sys.exit)
        self.accept('1', self.setObject, [0])
        self.accept('2', self.setObject, [1])
        self.accept('3', self.setObject, [2])
        self.accept('4', self.setObject, [3])

        base.disableMouse()  #Disable mouse-based camera-control
        camera.setPos(0, -15, 2)  #Position the camera

        self.eve = Actor(
            "models/samples/looking_and_gripping/eve",
            #Load our animated charachter
            {'walk': "models/samples/looking_and_gripping/eve_walk"})
        self.eve.reparentTo(render)  #Put it in the scene

        #Now we use controlJoint to get a NodePath that's in control of her neck
        #This must be done before any animations are played
        self.eveNeck = self.eve.controlJoint(None, 'modelRoot', 'Neck')

        #We now play an animation. An animation must be played, or at least posed
        #for the nodepath we just got from controlJoint to actually effect the model
        self.eve.actorInterval("walk", playRate=2).loop()

        #Now we add a task that will take care of turning the head
        taskMgr.add(self.turnHead, "turnHead")

        #Now we will expose the joint the hand joint. ExposeJoint allows us to
        #get the position of a joint while it is animating. This is different than
        #controlJonit which stops that joint from animating but lets us move it.
        #This is particularly usefull for putting an object (like a weapon) in an
        #actor's hand
        self.rightHand = self.eve.exposeJoint(None, 'modelRoot', 'RightHand')

        #This is a table with models, positions, rotations, and scales of objects to
        #be attached to our exposed joint. These are stock models and so they needed
        #to be repositioned to look right.
        positions = [("models/samples/looking_and_gripping/teapot", \
                        (0,-.66,-.95), (90,0,90), .4),
                     ("models/samples/looking_and_gripping/candycane", \
                        (.15,-.99,-.22), (90,0,90), 1),
                     ("models/samples/looking_and_gripping/banana", \
                        (.08,-.1,.09), (0,-90,0), 1.75),
                     ("models/samples/looking_and_gripping/sword", \
                        (.11,.19,.06), (0,0,90), 1)]
        self.models = []  #A list that will store our models objects
        for row in positions:
            np = loader.loadModel(row[0])  #Load the model
            np.setPos(row[1][0], row[1][1], row[1][2])  #Position it
            np.setHpr(row[2][0], row[2][1], row[2][2])  #Rotate it
            np.setScale(row[3])  #Scale it
            #Reparent the model to the exposed joint. That way when the joint moves,
            #the model we just loaded will move with it.
            np.reparentTo(self.rightHand)
            self.models.append(np)  #Add it to our models list

        self.setObject(0)  #Make object 0 the first shown
        self.setupLights()  #Put in some default lighting
示例#20
0
    def __init__(self):
        #Standard initialization stuff
        #Standard title that's on screen in every tutorial
        self.title = OnscreenText(text='Panda3D: Tutorial - Texture "Movies"',
                                  style=1,
                                  fg=(1, 1, 1, 1),
                                  pos=(0.7, -0.95),
                                  scale=.07,
                                  font=font)

        #Text to show the keyboard keys and their functions on screen
        self.escapeEventText = OnscreenText(text="ESC: Quit",
                                            style=1,
                                            fg=(1, 1, 1, 1),
                                            pos=(-1.3, 0.95),
                                            align=TextNode.ALeft,
                                            scale=.05,
                                            font=font)
        self.onekeyEventText = OnscreenText(text="[1]: Freeview camera",
                                            style=1,
                                            fg=(1, 1, 1, 1),
                                            pos=(-1.3, 0.90),
                                            align=TextNode.ALeft,
                                            scale=.05,
                                            font=font)
        self.twokeyEventText = OnscreenText(
            text="[2]: Preset Camera Angle 2 (Verify billboard effect)",
            style=1,
            fg=(1, 1, 1, 1),
            pos=(-1.3, 0.85),
            font=font,
            align=TextNode.ALeft,
            scale=.05,
            mayChange=1)

        base.setBackgroundColor(0, 0, 0)  #Set the background color

        #Set up the key input
        self.accept('escape', sys.exit)  #Escape quits
        self.accept('1', self.setViewMain)  #Free view
        self.accept('2', self.setViewBillboard)  #Billboard effect view

        #Initialization specific to this world
        #Load a polygon plane (4 sided square) to put an animated duck sprite on
        self.duckPlane = loader.loadModel(
            'models/samples/texture_swapping/plane')
        self.duckPlane.setPos(-2, 8, 0)  #set its position
        self.duckPlane.reparentTo(render)  #reparent to render

        #Enable tranparency: this attribute needs to be set for Panda to render the
        #transparency in the duck's texture as transparent rather than opaque
        self.duckPlane.setTransparency(1)

        #Now we call our special 'loadTextureMovie' function that returns a list
        #containing all of the textures for the duck sprite.
        #Check the function definition later in this file for its parameters
        self.duckTexs = self.loadTextureMovie(
            24,
            'models/samples/texture_swapping/duck/duck_fly_left',
            'png',
            padding=2)

        #Next we add a task to our task list that will animate the texture on the
        #duck plane according to the time elapsed.
        self.duckTask = taskMgr.add(self.textureMovie, "duckTask")
        #The function self.textureMovie is set to run any texture movie that
        #animates and loops based on time (rather that some other value like
        #position). To do that, it is set up to expect a number of parameters set
        #in the task object. The following lines set those parameters

        #Framerate: The texture will be changed 36 times per second
        self.duckTask.fps = 36
        #self.duckPlane is the object whose texture should be changed
        self.duckTask.obj = self.duckPlane
        #self.duckTexs (which we created earlier with self.oadTextureMovie)
        #contains the list of textures to animate from
        self.duckTask.textures = self.duckTexs

        #Now, instead of a duck, we will put an animated explosion onto a polygon
        #This is the same as loading the duck animation, with the expection that
        #we will "billboard" the explosion so that it always faces the camera
        self.expPlane = loader.loadModel(
            'models/samples/texture_swapping/plane')
        #load the object
        self.expPlane.setPos(2, 8, 0)  #set the position
        self.expPlane.reparentTo(render)  #reparent to render
        self.expPlane.setTransparency(1)  #enable transparency
        #load the texture movie
        self.expTexs = self.loadTextureMovie(
            51,
            'models/samples/texture_swapping/explosion/explosion',
            'png',
            padding=4)

        #create the animation task
        self.expTask = taskMgr.add(self.textureMovie, "explosionTask")
        self.expTask.fps = 30  #set framerate
        self.expTask.obj = self.expPlane  #set object
        self.expTask.textures = self.expTexs  #set texture list

        #This create the "billboard" effect that will rotate the object so that it
        #is always rendered as facing the eye (camera)
        self.expPlane.node().setEffect(BillboardEffect.makePointEye())

        #The code below generates the plane you see with the numbers and arrows.
        #This is just to give a sense of orientation as the camera is moved around.
        self.orientPlane = loader.loadModel(
            'models/samples/texture_swapping/plane')
        #Load the object
        #load the texture
        self.orientTex = \
          loader.loadTexture("models/samples/texture_swapping/orientation.png")
        self.orientPlane.setTexture(self.orientTex, 1)  #Set the texture
        self.orientPlane.reparentTo(render)  #Parent to render
        #Set the position, orientation, and scale
        self.orientPlane.setPosHprScale(0, 8, -1, 0, -90, 0, 10, 10, 10)
示例#21
0
 def makeStatusLabel(self, i):
   return OnscreenText(
     style=1, fg=(1,1,0,1), pos=(-1.3, 0.95 - (.05 * i)), font = font,
     align=TextNode.ALeft, scale = .05, mayChange = 1)
示例#22
0
文件: tunnel.py 项目: kralf/panda3d
    def __init__(self):
        ###Standard initialization stuff
        #Standard title that's on screen in every tutorial
        self.title = OnscreenText(text="Panda3D: Tutorial - Fog",
                                  style=1,
                                  fg=(1, 1, 1, 1),
                                  pos=(0.9, -0.95),
                                  scale=.07,
                                  font=font)

        #Code to generate the on screen instructions
        self.escapeEventText = self.genLabelText("ESC: Quit", 0)
        self.pkeyEventText = self.genLabelText("[P]: Pause", 1)
        self.tkeyEventText = self.genLabelText("[T]: Toggle Fog", 2)
        self.dkeyEventText = self.genLabelText("[D]: Make fog color black", 3)
        self.sdkeyEventText = self.genLabelText(
            "[SHIFT+D]: Make background color black", 4)
        self.rkeyEventText = self.genLabelText("[R]: Make fog color red", 5)
        self.srkeyEventText = self.genLabelText(
            "[SHIFT+R]: Make background color red", 6)
        self.bkeyEventText = self.genLabelText("[B]: Make fog color blue", 7)
        self.sbkeyEventText = self.genLabelText(
            "[SHIFT+B]: Make background color blue", 8)
        self.gkeyEventText = self.genLabelText("[G]: Make fog color green", 9)
        self.sgkeyEventText = self.genLabelText(
            "[SHIFT+G]: Make background color green", 10)
        self.lkeyEventText = self.genLabelText(
            "[L]: Make fog color light grey", 11)
        self.slkeyEventText = self.genLabelText(
            "[SHIFT+L]: Make background color light grey", 12)
        self.pluskeyEventText = self.genLabelText("[+]: Increase fog density",
                                                  13)
        self.minuskeyEventText = self.genLabelText("[-]: Decrease fog density",
                                                   14)

        base.disableMouse(
        )  #disable mouse control so that we can place the camera
        camera.setPosHpr(0, 0, 10, 0, -90, 0)
        base.setBackgroundColor(0, 0, 0)  #set the background color to black

        ###World specific-code

        #Create an instance of fog called 'distanceFog'.
        #'distanceFog' is just a name for our fog, not a specific type of fog.
        self.fog = Fog('distanceFog')
        #Set the initial color of our fog to black.
        self.fog.setColor(0, 0, 0)
        #Set the density/falloff of the fog.  The range is 0-1.
        #The higher the numer, the "bigger" the fog effect.
        self.fog.setExpDensity(.08)
        #We will set fog on render which means that everything in our scene will
        #be affected by fog. Alternatively, you could only set fog on a specific
        #object/node and only it and the nodes below it would be affected by
        #the fog.
        render.setFog(self.fog)

        #Define the keyboard input
        #Escape closes the demo
        self.accept('escape', sys.exit)
        #Handle pausing the tunnel
        self.accept('p', self.handlePause)
        #Handle turning the fog on and off
        self.accept('t', ToggleFog, [render, self.fog])
        #Sets keys to set the fog to various colors
        self.accept('r', self.fog.setColor, [1, 0, 0])
        self.accept('g', self.fog.setColor, [0, 1, 0])
        self.accept('b', self.fog.setColor, [0, 0, 1])
        self.accept('l', self.fog.setColor, [.7, .7, .7])
        self.accept('d', self.fog.setColor, [0, 0, 0])
        #Sets keys to change the background colors
        self.accept('shift-r', base.setBackgroundColor, [1, 0, 0])
        self.accept('shift-g', base.setBackgroundColor, [0, 1, 0])
        self.accept('shift-b', base.setBackgroundColor, [0, 0, 1])
        self.accept('shift-l', base.setBackgroundColor, [.7, .7, .7])
        self.accept('shift-d', base.setBackgroundColor, [0, 0, 0])
        #Increases the fog density when "+" key is pressed
        self.accept('+', self.addFogDensity, [.01])
        #This is to handle the other "+" key (it's over = on the keyboard)
        self.accept('=', self.addFogDensity, [.01])
        self.accept('shift-=', self.addFogDensity, [.01])
        #Decreases the fog density when the "-" key is pressed
        self.accept('-', self.addFogDensity, [-.01])

        #Load the tunel and start the tunnel
        self.initTunnel()
        self.contTunnel()