Beispiel #1
0
 def addFirefly(self):
     pos1 = Point3(random.uniform(-50, 50), random.uniform(-100, 150),
                   random.uniform(-10, 80))
     dir = Vec3(random.uniform(-1, 1), random.uniform(-1, 1),
                random.uniform(-1, 1))
     dir.normalize()
     pos2 = pos1 + (dir * 20)
     fly = self.lightroot.attachNewNode(PandaNode("fly"))
     glow = fly.attachNewNode(PandaNode("glow"))
     dot = fly.attachNewNode(PandaNode("dot"))
     color_r = random.uniform(0.7, 1.0)
     color_g = 1.0
     color_b = 0.8
     fly.setShaderInput("lightcolor", color_r, color_g, color_b, 1.0)
     int1 = fly.posInterval(random.uniform(7, 12), pos1, pos2)
     int2 = fly.posInterval(random.uniform(7, 12), pos2, pos1)
     si1 = fly.scaleInterval(random.uniform(0.8, 1.5),
                             Point3(0.2, 0.2, 0.2), Point3(0.2, 0.2, 0.2))
     si2 = fly.scaleInterval(random.uniform(1.5, 0.8),
                             Point3(1.0, 1.0, 1.0), Point3(0.2, 0.2, 0.2))
     si3 = fly.scaleInterval(random.uniform(1.0, 2.0),
                             Point3(0.2, 0.2, 0.2), Point3(1.0, 1.0, 1.0))
     siseq = Sequence(si1, si2, si3)
     siseq.loop()
     siseq.setT(random.uniform(0, 1000))
     seq = Sequence(int1, int2)
     seq.loop()
     self.spheremodel.instanceTo(glow)
     self.spheremodel.instanceTo(dot)
     glow.setScale(self.fireflysize * 1.1)
     glow.hide(BitMask32(self.modelMask | self.plainMask))
     dot.setScale(0.6)
     dot.hide(BitMask32(self.modelMask | self.lightMask))
     dot.setColor(color_r, color_g, color_b, 1.0)
     self.fireflies.append(fly)
     self.sequences.append(seq)
     self.glowspheres.append(glow)
     self.scaleseqs.append(siseq)
Beispiel #2
0
    def __init__(self):
        
        self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0}
        base.win.setClearColor(Vec4(0,0,0,1))

        # Post the instructions

        self.title = addTitle("Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)")
        self.inst1 = addInstructions(0.95, "[ESC]: Quit")
        self.inst2 = addInstructions(0.90, "[Left Arrow]: Rotate Ralph Left")
        self.inst3 = addInstructions(0.85, "[Right Arrow]: Rotate Ralph Right")
        self.inst4 = addInstructions(0.80, "[Up Arrow]: Run Ralph Forward")
        self.inst6 = addInstructions(0.70, "[A]: Rotate Camera Left")
        self.inst7 = addInstructions(0.65, "[S]: Rotate Camera Right")
        
        # Set up the environment
        #
        # This environment model contains collision meshes.  If you look
        # in the egg file, you will see the following:
        #
        #    <Collide> { Polyset keep descend }
        #
        # This tag causes the following mesh to be converted to a collision
        # mesh -- a mesh which is optimized for collision, not rendering.
        # It also keeps the original mesh, so there are now two copies ---
        # one optimized for rendering, one for collisions.  

        self.environ = loader.loadModel("models/samples/roaming_ralph/world")
        self.environ.reparentTo(render)
        self.environ.setPos(0,0,0)
        
        # Create the main character, Ralph

        ralphStartPos = self.environ.find("**/start_point").getPos()
        self.ralph = Actor("models/samples/roaming_ralph/ralph",
            {"run":"models/samples/roaming_ralph/ralph_run",
             "walk":"models/samples/roaming_ralph/ralph_walk"})
        self.ralph.reparentTo(render)
        self.ralph.setScale(.2)
        self.ralph.setPos(ralphStartPos)

        # Create a floater object.  We use the "floater" as a temporary
        # variable in a variety of calculations.
        
        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(render)

        # Accept the control keys for movement and rotation

        self.accept("escape", sys.exit)
        self.accept("arrow_left", self.setKey, ["left",1])
        self.accept("arrow_right", self.setKey, ["right",1])
        self.accept("arrow_up", self.setKey, ["forward",1])
        self.accept("a", self.setKey, ["cam-left",1])
        self.accept("s", self.setKey, ["cam-right",1])
        self.accept("arrow_left-up", self.setKey, ["left",0])
        self.accept("arrow_right-up", self.setKey, ["right",0])
        self.accept("arrow_up-up", self.setKey, ["forward",0])
        self.accept("a-up", self.setKey, ["cam-left",0])
        self.accept("s-up", self.setKey, ["cam-right",0])

        taskMgr.add(self.move,"moveTask")

        # Game state variables
        self.isMoving = False

        # Set up the camera
        
        base.disableMouse()
        base.camera.setPos(self.ralph.getX(),self.ralph.getY()+10,2)
        
        # We will detect the height of the terrain by creating a collision
        # ray and casting it downward toward the terrain.  One ray will
        # start above ralph's head, and the other will start above the camera.
        # A ray may hit the terrain, or it may hit a rock or a tree.  If it
        # hits the terrain, we can detect the height.  If it hits anything
        # else, we rule that the move is illegal.

        self.cTrav = CollisionTraverser()

        self.ralphGroundRay = CollisionRay()
        self.ralphGroundRay.setOrigin(0,0,1000)
        self.ralphGroundRay.setDirection(0,0,-1)
        self.ralphGroundCol = CollisionNode('ralphRay')
        self.ralphGroundCol.addSolid(self.ralphGroundRay)
        self.ralphGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.ralphGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.ralphGroundColNp = self.ralph.attachNewNode(self.ralphGroundCol)
        self.ralphGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler)

        self.camGroundRay = CollisionRay()
        self.camGroundRay.setOrigin(0,0,1000)
        self.camGroundRay.setDirection(0,0,-1)
        self.camGroundCol = CollisionNode('camRay')
        self.camGroundCol.addSolid(self.camGroundRay)
        self.camGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.camGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol)
        self.camGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)
Beispiel #3
0
    def __init__(self):
        base.disableMouse()
        base.setBackgroundColor(0, 0, 0)
        taskMgr.add(self.updateScene, "updateScene")

        # Show the instructions
        self.title = addTitle("Panda3D: Tutorial - Distortion Effect")
        self.inst1 = addInstructions(0.95, "ESC: Quit")
        self.inst2 = addInstructions(0.90,
                                     "Space: Toggle distortion filter On/Off")
        self.inst4 = addInstructions(0.85,
                                     "V: View the render-to-texture results")

        # Load background
        self.seascape = loader.loadModel("models/samples/distortion/plane")
        self.seascape.reparentTo(render)
        self.seascape.setPosHpr(0, 145, 0, 0, 0, 0)
        self.seascape.setScale(100)

        self.seascape.setTexture(loader.loadTexture( \
          "models/samples/distortion/ocean.jpg"))

        # Create the distortion buffer. This buffer renders like a normal scene,

        self.distortionBuffer = self.makeFBO("model buffer")
        self.distortionBuffer.setSort(-3)
        self.distortionBuffer.setClearColor(Vec4(0, 0, 0, 0))

        # We have to attach a camera to the distortion buffer. The distortion
        # camera must have the same frustum as the main camera. As long
        # as the aspect ratios match, the rest will take care of itself.
        distortionCamera = base.makeCamera(self.distortionBuffer, scene = \
          render, lens = base.cam.node().getLens(), mask = BitMask32.bit(4))

        # load the object with the distortion
        self.distortionObject = loader.loadModel( \
          "models/samples/distortion/boat")
        self.distortionObject.setScale(1)
        self.distortionObject.setPos(0, 20, -3)
        self.distortionObject.hprInterval(10, Point3(360, 0, 0)).loop()
        self.distortionObject.reparentTo(render)

        # Create the shader that will determime what parts of the scene will
        # distortion
        distortionShader = loader.loadShader(os.path.join(PANDA_SHADER_PATH, \
          "samples/distortion/distortion.sha"))
        self.distortionObject.setShader(distortionShader)
        self.distortionObject.hide(BitMask32.bit(4))

        # Textures
        tex1 = loader.loadTexture("models/samples/distortion/water.png")
        self.distortionObject.setShaderInput("waves", tex1)

        self.texDistortion = Texture()
        self.distortionBuffer.addRenderTexture(self.texDistortion,
                                               GraphicsOutput.RTMBindOrCopy,
                                               GraphicsOutput.RTPColor)
        self.distortionObject.setShaderInput("screen", self.texDistortion)

        # Panda contains a built-in viewer that lets you view the results of
        # your render-to-texture operations.  This code configures the viewer.
        self.accept("v", base.bufferViewer.toggleEnable)
        self.accept("V", base.bufferViewer.toggleEnable)
        base.bufferViewer.setPosition("llcorner")
        base.bufferViewer.setLayout("hline")
        base.bufferViewer.setCardSize(0.652, 0)

        # event handling
        self.accept("space", self.toggleDistortion)
        self.accept("escape", exit, [0])
        self.distortionOn = True
Beispiel #4
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()
Beispiel #5
0
    def __init__(self):
        base.disableMouse()
        base.setBackgroundColor(0, 0, 0)
        taskMgr.add(self.updateScene, "updateScene")
        
        # Show the instructions
        self.title = addTitle("Panda3D: Tutorial - Distortion Effect")
        self.inst1 = addInstructions(0.95,"ESC: Quit")
        self.inst2 = addInstructions(0.90,"Space: Toggle distortion filter On/Off")
        self.inst4 = addInstructions(0.85,"V: View the render-to-texture results")
        
        # Load background
        self.seascape = loader.loadModel("models/samples/distortion/plane")
        self.seascape.reparentTo(render)
        self.seascape.setPosHpr(0, 145, 0, 0, 0, 0)
        self.seascape.setScale(100)

        self.seascape.setTexture(loader.loadTexture( \
          "models/samples/distortion/ocean.jpg"))
        
        # Create the distortion buffer. This buffer renders like a normal scene,
      
        self.distortionBuffer = self.makeFBO("model buffer")
        self.distortionBuffer.setSort(-3)
        self.distortionBuffer.setClearColor(Vec4(0, 0, 0, 0))
        
        # We have to attach a camera to the distortion buffer. The distortion
        # camera must have the same frustum as the main camera. As long
        # as the aspect ratios match, the rest will take care of itself.
        distortionCamera = base.makeCamera(self.distortionBuffer, scene = \
          render, lens = base.cam.node().getLens(), mask = BitMask32.bit(4))
        
        # load the object with the distortion
        self.distortionObject = loader.loadModel( \
          "models/samples/distortion/boat")
        self.distortionObject.setScale(1)
        self.distortionObject.setPos(0, 20, -3)
        self.distortionObject.hprInterval(10, Point3(360, 0, 0)).loop()
        self.distortionObject.reparentTo(render)
        
        # Create the shader that will determime what parts of the scene will
        # distortion
        distortionShader = loader.loadShader(os.path.join(PANDA_SHADER_PATH, \
          "samples/distortion/distortion.sha"))
        self.distortionObject.setShader(distortionShader)
        self.distortionObject.hide(BitMask32.bit(4))
        
        # Textures
        tex1 = loader.loadTexture("models/samples/distortion/water.png")
        self.distortionObject.setShaderInput("waves", tex1)
        
        self.texDistortion = Texture()
        self.distortionBuffer.addRenderTexture(self.texDistortion, GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPColor)
        self.distortionObject.setShaderInput("screen", self.texDistortion)
        
        # Panda contains a built-in viewer that lets you view the results of
        # your render-to-texture operations.  This code configures the viewer.
        self.accept("v", base.bufferViewer.toggleEnable)
        self.accept("V", base.bufferViewer.toggleEnable)
        base.bufferViewer.setPosition("llcorner")
        base.bufferViewer.setLayout("hline")
        base.bufferViewer.setCardSize(0.652, 0)
        
        # event handling
        self.accept("space", self.toggleDistortion)
        self.accept("escape", exit, [0])
        self.distortionOn = True
Beispiel #6
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()
Beispiel #7
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
Beispiel #8
0
    def __init__(self):

        # Preliminary capabilities check.

        if (base.win.getGsg().getSupportsBasicShaders() == 0):
            self.t = addTitle(
                "Firefly Demo: Video driver reports that shaders are not supported."
            )
            return
        if (base.win.getGsg().getSupportsDepthTexture() == 0):
            self.t = addTitle(
                "Firefly Demo: Video driver reports that depth textures are not supported."
            )
            return

        # This algorithm uses two offscreen buffers, one of which has
        # an auxiliary bitplane, and the offscreen buffers share a single
        # depth buffer.  This is a heck of a complicated buffer setup.

        self.modelbuffer = self.makeFBO("model buffer", 1)
        self.lightbuffer = self.makeFBO("light buffer", 0)

        # Creation of a high-powered buffer can fail, if the graphics card
        # doesn't support the necessary OpenGL extensions.

        if (self.modelbuffer == None) or (self.lightbuffer == None):
            self.t = addTitle(
                "Toon Shader: Video driver does not support multiple render targets"
            )
            return

        # Create four render textures: depth, normal, albedo, and final.
        # attach them to the various bitplanes of the offscreen buffers.

        self.texDepth = Texture()
        self.texDepth.setFormat(Texture.FDepthStencil)
        self.texAlbedo = Texture()
        self.texNormal = Texture()
        self.texFinal = Texture()

        self.modelbuffer.addRenderTexture(self.texDepth,
                                          GraphicsOutput.RTMBindOrCopy,
                                          GraphicsOutput.RTPDepthStencil)
        self.modelbuffer.addRenderTexture(self.texAlbedo,
                                          GraphicsOutput.RTMBindOrCopy,
                                          GraphicsOutput.RTPColor)
        self.modelbuffer.addRenderTexture(self.texNormal,
                                          GraphicsOutput.RTMBindOrCopy,
                                          GraphicsOutput.RTPAuxRgba0)

        self.lightbuffer.addRenderTexture(self.texFinal,
                                          GraphicsOutput.RTMBindOrCopy,
                                          GraphicsOutput.RTPColor)

        # Set the near and far clipping planes.

        base.cam.node().getLens().setNear(50.0)
        base.cam.node().getLens().setFar(500.0)
        lens = base.cam.node().getLens()

        # This algorithm uses three cameras: one to render the models into the
        # model buffer, one to render the lights into the light buffer, and
        # one to render "plain" stuff (non-deferred shaded) stuff into the light
        # buffer.  Each camera has a bitmask to identify it.

        self.modelMask = 1
        self.lightMask = 2
        self.plainMask = 4

        self.modelcam = base.makeCamera(self.modelbuffer,
                                        lens=lens,
                                        scene=render,
                                        mask=self.modelMask)
        self.lightcam = base.makeCamera(self.lightbuffer,
                                        lens=lens,
                                        scene=render,
                                        mask=self.lightMask)
        self.plaincam = base.makeCamera(self.lightbuffer,
                                        lens=lens,
                                        scene=render,
                                        mask=self.plainMask)

        # Panda's main camera is not used.

        base.cam.node().setActive(0)

        # Take explicit control over the order in which the three
        # buffers are rendered.

        self.modelbuffer.setSort(1)
        self.lightbuffer.setSort(2)
        base.win.setSort(3)

        # Within the light buffer, control the order of the two cams.

        self.lightcam.node().getDisplayRegion(0).setSort(1)
        self.plaincam.node().getDisplayRegion(0).setSort(2)

        # By default, panda usually clears the screen before every
        # camera and before every window.  Tell it not to do that.
        # Then, tell it specifically when to clear and what to clear.

        self.modelcam.node().getDisplayRegion(0).disableClears()
        self.lightcam.node().getDisplayRegion(0).disableClears()
        self.plaincam.node().getDisplayRegion(0).disableClears()
        base.cam.node().getDisplayRegion(0).disableClears()
        base.cam2d.node().getDisplayRegion(0).disableClears()
        self.modelbuffer.disableClears()
        base.win.disableClears()

        self.modelbuffer.setClearColorActive(1)
        self.modelbuffer.setClearDepthActive(1)
        self.lightbuffer.setClearColorActive(1)
        self.lightbuffer.setClearColor(Vec4(0, 0, 0, 1))

        # Miscellaneous stuff.

        base.disableMouse()
        base.camera.setPos(-9.112, -211.077, 46.951)
        base.camera.setHpr(0, -7.5, 2.4)
        base.setBackgroundColor(Vec4(0, 0, 0, 0))
        random.seed()

        # Calculate the projection parameters for the final shader.
        # The math here is too complex to explain in an inline comment,
        # I've put in a full explanation into the HTML intro.

        proj = base.cam.node().getLens().getProjectionMat()
        proj_x = 0.5 * proj.getCell(3, 2) / proj.getCell(0, 0)
        proj_y = 0.5 * proj.getCell(3, 2)
        proj_z = 0.5 * proj.getCell(3, 2) / proj.getCell(2, 1)
        proj_w = -0.5 - 0.5 * proj.getCell(1, 2)

        # Configure the render state of the model camera.

        tempnode = NodePath(PandaNode("temp node"))
        tempnode.setAttrib(
            AlphaTestAttrib.make(RenderAttrib.MGreaterEqual, 0.5))
        tempnode.setShader(Shader.load(os.path.join(PANDA_SHADER_PATH, \
          "samples/fireflies/fireflies_model.sha")))
        tempnode.setAttrib(DepthTestAttrib.make(RenderAttrib.MLessEqual))
        self.modelcam.node().setInitialState(tempnode.getState())

        # Configure the render state of the light camera.

        tempnode = NodePath(PandaNode("temp node"))
        tempnode.setShader(Shader.load(os.path.join(PANDA_SHADER_PATH, \
          "samples/fireflies/fireflies_lighting.sha")))
        tempnode.setShaderInput("texnormal", self.texNormal)
        tempnode.setShaderInput("texalbedo", self.texAlbedo)
        tempnode.setShaderInput("texdepth", self.texDepth)
        tempnode.setShaderInput("proj", Vec4(proj_x, proj_y, proj_z, proj_w))
        tempnode.setAttrib(
            ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OOne,
                                  ColorBlendAttrib.OOne))
        tempnode.setAttrib(
            CullFaceAttrib.make(CullFaceAttrib.MCullCounterClockwise))
        # The next line causes problems on Linux.
        #tempnode.setAttrib(DepthTestAttrib.make(RenderAttrib.MGreaterEqual))
        tempnode.setAttrib(DepthWriteAttrib.make(DepthWriteAttrib.MOff))
        self.lightcam.node().setInitialState(tempnode.getState())

        # Configure the render state of the plain camera.

        rs = RenderState.makeEmpty()
        self.plaincam.node().setInitialState(rs)

        # Clear any render attribs on the root node. This is necessary
        # because by default, panda assigns some attribs to the root
        # node.  These default attribs will override the
        # carefully-configured render attribs that we just attached
        # to the cameras.  The simplest solution is to just clear
        # them all out.

        render.setState(RenderState.makeEmpty())

        # My artist created a model in which some of the polygons
        # don't have textures.  This confuses the shader I wrote.
        # This little hack guarantees that everything has a texture.

        white = loader.loadTexture("models/samples/fireflies/white.jpg")
        render.setTexture(white, 0)

        # Create two subroots, to help speed cull traversal.

        self.lightroot = NodePath(PandaNode("lightroot"))
        self.lightroot.reparentTo(render)
        self.modelroot = NodePath(PandaNode("modelroot"))
        self.modelroot.reparentTo(render)
        self.lightroot.hide(BitMask32(self.modelMask))
        self.modelroot.hide(BitMask32(self.lightMask))
        self.modelroot.hide(BitMask32(self.plainMask))

        # Load the model of a forest. Make it visible to the model camera.

        self.forest = NodePath(PandaNode("Forest Root"))
        self.forest.reparentTo(render)

        loader.loadModel( \
          "models/samples/fireflies/background").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage01").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage02").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage03").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage04").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage05").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage06").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage07").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage08").reparentTo(self.forest)
        loader.loadModel( \
          "models/samples/fireflies/foliage09").reparentTo(self.forest)
        self.forest.hide(BitMask32(self.lightMask | self.plainMask))

        # Cause the final results to be rendered into the main window on a card.

        cm = CardMaker("card")
        cm.setFrameFullscreenQuad()
        self.card = render2d.attachNewNode(cm.generate())
        self.card.setTexture(self.texFinal)

        # Post the instructions.

        self.title = addTitle(
            "Panda3D: Tutorial - Fireflies using Deferred Shading")
        self.inst1 = addInstructions(0.95, "ESC: Quit")
        self.inst2 = addInstructions(
            0.90, "Up/Down: More / Fewer Fireflies (Count: unknown)")
        self.inst3 = addInstructions(
            0.85, "Right/Left: Bigger / Smaller Fireflies (Radius: unknown)")
        self.inst4 = addInstructions(0.80,
                                     "V: View the render-to-texture results")

        # Panda contains a built-in viewer that lets you view the results of
        # your render-to-texture operations.  This code configures the viewer.

        base.bufferViewer.setPosition("llcorner")
        base.bufferViewer.setCardSize(0, 0.40)
        base.bufferViewer.setLayout("vline")
        self.toggleCards()
        self.toggleCards()

        # Firefly parameters

        self.fireflies = []
        self.sequences = []
        self.scaleseqs = []
        self.glowspheres = []
        self.fireflysize = 1.0
        self.spheremodel = loader.loadModel("models/misc/sphere.flt")
        self.setFireflySize(25.0)
        while (len(self.fireflies) < 5):
            self.addFirefly()
        self.updateReadout()

        # these allow you to change parameters in realtime

        self.accept("escape", sys.exit, [0])
        self.accept("arrow_up", self.incFireflyCount, [1.1111111])
        self.accept("arrow_down", self.decFireflyCount, [0.9000000])
        self.accept("arrow_right", self.setFireflySize, [1.1111111])
        self.accept("arrow_left", self.setFireflySize, [0.9000000])
        self.accept("v", self.toggleCards)
        self.accept("V", self.toggleCards)

        self.nextadd = 0
        taskMgr.add(self.spawnTask, "spawner")
Beispiel #9
0
    def __init__(self):

        self.keyMap = {
            "left": 0,
            "right": 0,
            "forward": 0,
            "cam-left": 0,
            "cam-right": 0
        }
        base.win.setClearColor(Vec4(0, 0, 0, 1))

        # Post the instructions

        self.title = addTitle(
            "Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)")
        self.inst1 = addInstructions(0.95, "[ESC]: Quit")
        self.inst2 = addInstructions(0.90, "[Left Arrow]: Rotate Ralph Left")
        self.inst3 = addInstructions(0.85, "[Right Arrow]: Rotate Ralph Right")
        self.inst4 = addInstructions(0.80, "[Up Arrow]: Run Ralph Forward")
        self.inst6 = addInstructions(0.70, "[A]: Rotate Camera Left")
        self.inst7 = addInstructions(0.65, "[S]: Rotate Camera Right")

        # Set up the environment
        #
        # This environment model contains collision meshes.  If you look
        # in the egg file, you will see the following:
        #
        #    <Collide> { Polyset keep descend }
        #
        # This tag causes the following mesh to be converted to a collision
        # mesh -- a mesh which is optimized for collision, not rendering.
        # It also keeps the original mesh, so there are now two copies ---
        # one optimized for rendering, one for collisions.

        self.environ = loader.loadModel("models/samples/roaming_ralph/world")
        self.environ.reparentTo(render)
        self.environ.setPos(0, 0, 0)

        # Create the main character, Ralph

        ralphStartPos = self.environ.find("**/start_point").getPos()
        self.ralph = Actor(
            "models/samples/roaming_ralph/ralph", {
                "run": "models/samples/roaming_ralph/ralph_run",
                "walk": "models/samples/roaming_ralph/ralph_walk"
            })
        self.ralph.reparentTo(render)
        self.ralph.setScale(.2)
        self.ralph.setPos(ralphStartPos)

        # Create a floater object.  We use the "floater" as a temporary
        # variable in a variety of calculations.

        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(render)

        # Accept the control keys for movement and rotation

        self.accept("escape", sys.exit)
        self.accept("arrow_left", self.setKey, ["left", 1])
        self.accept("arrow_right", self.setKey, ["right", 1])
        self.accept("arrow_up", self.setKey, ["forward", 1])
        self.accept("a", self.setKey, ["cam-left", 1])
        self.accept("s", self.setKey, ["cam-right", 1])
        self.accept("arrow_left-up", self.setKey, ["left", 0])
        self.accept("arrow_right-up", self.setKey, ["right", 0])
        self.accept("arrow_up-up", self.setKey, ["forward", 0])
        self.accept("a-up", self.setKey, ["cam-left", 0])
        self.accept("s-up", self.setKey, ["cam-right", 0])

        taskMgr.add(self.move, "moveTask")

        # Game state variables
        self.isMoving = False

        # Set up the camera

        base.disableMouse()
        base.camera.setPos(self.ralph.getX(), self.ralph.getY() + 10, 2)

        # We will detect the height of the terrain by creating a collision
        # ray and casting it downward toward the terrain.  One ray will
        # start above ralph's head, and the other will start above the camera.
        # A ray may hit the terrain, or it may hit a rock or a tree.  If it
        # hits the terrain, we can detect the height.  If it hits anything
        # else, we rule that the move is illegal.

        self.cTrav = CollisionTraverser()

        self.ralphGroundRay = CollisionRay()
        self.ralphGroundRay.setOrigin(0, 0, 1000)
        self.ralphGroundRay.setDirection(0, 0, -1)
        self.ralphGroundCol = CollisionNode('ralphRay')
        self.ralphGroundCol.addSolid(self.ralphGroundRay)
        self.ralphGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.ralphGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.ralphGroundColNp = self.ralph.attachNewNode(self.ralphGroundCol)
        self.ralphGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler)

        self.camGroundRay = CollisionRay()
        self.camGroundRay.setOrigin(0, 0, 1000)
        self.camGroundRay.setDirection(0, 0, -1)
        self.camGroundCol = CollisionNode('camRay')
        self.camGroundCol.addSolid(self.camGroundRay)
        self.camGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.camGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol)
        self.camGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)