Beispiel #1
0
class Bullet(DirectObject):
    def __init__(self, ship, bulletPos, bulletVelocityVec, collisionHandler):
        self.model = game.loader.loadModel("Models/bullet.egg.pz")
        self.model.setPos(bulletPos)
        self.model.setScale(BULLET_SIZE)
        self.model.reparentTo(render)
        self.model.setPythonTag("owner", self)
        self.ship = ship
        finalPosition = bulletPos + (bulletVelocityVec * BULLET_TRAVEL_TIME)
        self.trajectory = self.model.posInterval(BULLET_TRAVEL_TIME,
                                                 finalPosition).start()

        self.collisionNode = self.model.attachNewNode(CollisionNode("bullet"))
        self.collisionNode.node().addSolid(CollisionSphere(0, 0, 0, 1))
        base.cTrav.addCollider(self.collisionNode, collisionHandler)

        # Add Point Light to the bullet
        self.plight = PointLight('plight' + str(random()))
        self.plight.setColor(Vec4(1, 1, 1, 1))
        self.plight.setAttenuation(Vec3(0.7, 0.05, 0))
        self.plnp = self.model.attachNewNode(self.plight)
        render.setLight(self.plnp)
        render.setShaderInput("light", self.plnp)

    ###
    # Bullet.remove
    #
    #  Removes this asteroid from rendering and registering collisions.
    ##
    def remove(self):
        self.ignoreAll()
        self.model.remove()
        self.collisionNode.remove()
    def setupLights(self):
        base.setBackgroundColor(0.0, 0.0, 0.0, 1)
        base.setFrameRateMeter(True)
        # Add a light to the scene.
        self.lightpivot = render.attachNewNode("lightpivot")
        self.lightpivot.setPos(0, 0, 5)
        self.lightpivot.hprInterval(10, Point3(360, 0, 0)).loop()
        plight = PointLight('plight')
        plight.setColor(Vec4(1, 0, 0, 1))
        plight.setAttenuation(Vec3(0.37, 0.025, 0))
        plnp = self.lightpivot.attachNewNode(plight)
        plnp.setPos(45, 0, 0)
        plnp.lookAt(*Vec3(0, 0, 0, ))

        # Light
        alight = AmbientLight('ambientLight')
        alight.setColor(Vec4(0.2, 0.2, 0.2, 1))
        alightNP = render.attachNewNode(alight)

        #   dlight = DirectionalLight('directionalLight')
        #   dlight.setDirection(Vec3(1, 1, -1))
        #   dlight.setColor(Vec4(0.7, 0.7, 0.7, 1))
        #   dlightNP = render.attachNewNode(dlight)

        render.clearLight()
        render.setLight(alightNP)
        #   render.setLight(dlightNP)
        render.setLight(plnp)

        # create a sphere to denote the light
        sphere = loader.loadModel("models/sphere")
        sphere.reparentTo(plnp)

        render.setShaderAuto()
Beispiel #3
0
    def generate(self, helperInfo):
        color = self.mapObject.getPropertyValue("_light",
                                                default=Vec4(
                                                    255, 255, 255, 255))
        color = CIGlobals.colorFromRGBScalar255(color)
        color = CIGlobals.vec3GammaToLinear(color)

        constant = float(
            self.mapObject.getPropertyValue("_constant_attn", default="0.0"))
        linear = float(
            self.mapObject.getPropertyValue("_linear_attn", default="0.0"))
        quadratic = float(
            self.mapObject.getPropertyValue("_quadratic_attn", default="1.0"))

        # Scale intensity for unit 100 distance
        ratio = (constant + 100 * linear + 100 * 100 * quadratic)
        if ratio > 0:
            color *= ratio

        pl = PointLight("lightHelper-light")
        pl.setColor(Vec4(color[0], color[1], color[2], 1.0))
        pl.setAttenuation(Vec3(constant, linear, quadratic))
        self.light = self.mapObject.helperRoot.attachNewNode(pl)
        if self.mapObject.doc.numlights < 128:
            self.mapObject.doc.render.setLight(self.light)
            self.mapObject.doc.numlights += 1
            self.hasLight = True
    def __init__(self):
        ShowBase.__init__(self)

        self.cap = cv2.VideoCapture(0)
        self.classifier = cv2.CascadeClassifier(self.haar)

        self.scene = self.loader.loadModel('models/abstractroom')
        self.scene.reparentTo(self.render)

        self.scene.setPos(-10, 100, 0)

        self.shaderenable = 1
        self.scene.setShaderAuto()

        # Add ambient light
        alight = AmbientLight('alight')
        alight.setColor((0.1, 0.11, 0.11, 1))
        alnp = self.render.attachNewNode(alight)
        self.scene.setLight(alnp)

        # Add point light.
        plight = PointLight('plight')
        plight.setColor((1, 1, 1, 1))
        plight.setAttenuation(LVector3(0.1, 0.02, 0))
        plnp = self.render.attachNewNode(plight)
        plnp.setPos(-27, 100, 0)
        self.scene.setLight(plnp)
        # Create a sphere to denote the light
        sphere = self.loader.loadModel("models/icosphere")
        sphere.reparentTo(plnp)

        self.taskMgr.add(self.display, 'Display')

        print("%.1f, %.1f, %.1f" % (self.x, self.y, self.z))
Beispiel #5
0
class Bullet(DirectObject):
  def __init__(self, ship, bulletPos, bulletVelocityVec, collisionHandler):
    self.model = game.loader.loadModel("Models/bullet.egg.pz")
    self.model.setPos(bulletPos)
    self.model.setScale(BULLET_SIZE)
    self.model.reparentTo(render)
    self.model.setPythonTag("owner", self)
    self.ship = ship
    finalPosition = bulletPos + (bulletVelocityVec * BULLET_TRAVEL_TIME)
    self.trajectory = self.model.posInterval(BULLET_TRAVEL_TIME, finalPosition).start()

    self.collisionNode = self.model.attachNewNode(CollisionNode("bullet"))
    self.collisionNode.node().addSolid(CollisionSphere(0,0,0,1))
    base.cTrav.addCollider(self.collisionNode, collisionHandler)

    # Add Point Light to the bullet
    self.plight = PointLight('plight'+str(random()))
    self.plight.setColor(Vec4(1,1,1,1))
    self.plight.setAttenuation(Vec3(0.7, 0.05, 0))
    self.plnp = self.model.attachNewNode(self.plight)
    render.setLight(self.plnp)
    render.setShaderInput("light", self.plnp)


  ###
  # Bullet.remove
  #
  #  Removes this asteroid from rendering and registering collisions.
  ## 
  def remove(self):
    self.ignoreAll()
    self.model.remove()
    self.collisionNode.remove()
    def __init__(self):
        super().__init__()
        self.set_background_color(0, 0, 0, 1)
        self.jack = self.loader.loadModel("models/jack")
        self.jack.setHpr(0, 180, 180)
        self.jack.setPos(0, 0, 0)
        self.jack.reparentTo(self.render)

        self.light_model = self.loader.loadModel('models/misc/sphere')
        self.light_model.setScale(0.2, 0.2, 0.2)
        self.light_model.setPos(4, 0, 0)
        self.light_model.reparentTo(self.render)

        self.cam.setPos(0, -12, 0)

        plight = PointLight("plight")
        plight.setColor((1, 1, 1, 1))
        self.plnp = self.light_model.attachNewNode(plight)
        # self.plnp.setPos(2, 0, 0)
        plight.setAttenuation((1, 0, 0))
        self.jack.setLight(self.plnp)

        alight = AmbientLight("aLight")
        alight.setColor((0.04, 0.04, 0.04, 1))
        alnp = self.render.attachNewNode(alight)
        self.jack.setLight(alnp)

        self.taskMgr.add(self.move_light, "move-light")
    def __init__(self):
        base.disableMouse()
        base.cam.node().getLens().setNear(10.0)
        base.cam.node().getLens().setFar(9999999)
        camera.setPos(0, -50, 0)
        
        # Check video card capabilities.
        
        if (base.win.getGsg().getSupportsBasicShaders() == 0):
            addTitle("Toon Shader: Video driver reports that shaders are not supported.")
            return
        
        # Enable a 'light ramp' - this discretizes the lighting,
        # which is half of what makes a model look like a cartoon.
        # Light ramps only work if shader generation is enabled,
        # so we call 'setShaderAuto'.

        tempnode = NodePath(PandaNode("temp node"))
        tempnode.setAttrib(LightRampAttrib.makeSingleThreshold(0.5, 0.4))
        tempnode.setShaderAuto()
        base.cam.node().setInitialState(tempnode.getState())
        
        # Use class 'CommonFilters' to enable a cartoon inking filter.
        # This can fail if the video card is not powerful enough, if so,
        # display an error and exit.
        
        self.separation = 1 # Pixels
        self.filters = CommonFilters(base.win, base.cam)
        filterok = self.filters.setCartoonInk(separation=self.separation)
        if (filterok == False):
            addTitle("Toon Shader: Video card not powerful enough to do image postprocessing")
            return
        
        # Create a non-attenuating point light and an ambient light.
        
        plightnode = PointLight("point light")
        plightnode.setAttenuation(Vec3(1,0,0))
        plight = render.attachNewNode(plightnode)
        plight.setPos(30,-50,0)
        alightnode = AmbientLight("ambient light")
        alightnode.setColor(Vec4(0.8,0.8,0.8,1))
        alight = render.attachNewNode(alightnode)
        render.setLight(alight)
        render.setLight(plight)
        
        # Panda contains a built-in viewer that lets you view the 
        # results of all render-to-texture operations.  This lets you
        # see what class CommonFilters is doing behind the scenes.
        
        self.accept("v", base.bufferViewer.toggleEnable)
        self.accept("V", base.bufferViewer.toggleEnable)
        base.bufferViewer.setPosition("llcorner")
        self.accept("s", self.filters.manager.resizeBuffers)
        
        # These allow you to change cartooning parameters in realtime
        
        self.accept("escape", sys.exit, [0])
Beispiel #8
0
    def __init__(self, **kwargs):

        self.type = 'ambient'  # ambient or directional for now
        self.color = color.rgb(0.3, 0.3, 0.3,
                               1)  # a modest amount of full-spectrum light
        self.direction = Vec3(
            -1, -1, -1)  # shining down from top-right corner, behind camera
        self.position = None
        self.attenuation = None
        self.node = None

        for key, value in kwargs.items():

            if key == 'type':
                if value in ('ambient', 'directional', 'point'):
                    self.type = value
                else:
                    print("ERR Light type is not 'ambient' or 'directional'")
            elif key == 'color':
                self.color = value
            elif key == 'direction':
                self.direction = value
            elif key == 'attenuation':
                self.attenuation = value
            elif key == 'position':
                self.position = value
            else:
                print("Err ", key, " is not a valid keyword")

        scene.lights.append(self)  # light added for all subsequent entities

        if self.type == 'ambient':
            ambientLight = AmbientLight('ambientLight')
            ambientLight.setColor(self.color)
            self.node = scene.attachNewNode(ambientLight)

        elif self.type == 'directional':
            directionalLight = DirectionalLight('directionalLight')
            directionalLight.setColor(self.color)
            self.node = scene.attachNewNode(directionalLight)
            # This light should be facing straight down, but clearly it isn't.
            self.node.setHpr(
                self.direction)  # convert vector to Hpr (in degrees!?) first

        elif self.type == 'point':
            pointLight = PointLight('pointLight')
            pointLight.setColor(self.color)

            if self.attenuation is None:
                self.attenuation = Vec3(1, 0, 0)
            pointLight.setAttenuation(self.attenuation)

            if self.position is None:
                self.position = Vec3(0, 0, 0)

            self.node = scene.attachNewNode(pointLight)
            self.node.setPos(self.position)
Beispiel #9
0
def makePointLight(name, color, pos, falloff=1.0):
    point = PointLight(name + "-point")
    point.setColor(color)
    ATTN_FCTR = 0.0625
    point.setAttenuation((0, 0, falloff * ATTN_FCTR))
    pnp = render.attachNewNode(point)
    pnp.setPos(pos)
    if False:
        sm = loader.loadModel("models/smiley.egg.pz")
        sm.reparentTo(pnp)
    return pnp
Beispiel #10
0
    def __init__(self):
        camera_hpr = base.camera.getHpr()
        self.name = "missle"
        self.core = loader.loadModel("./Models/sphere.egg")
        self.ttl = 2  # Time to live in seconds
        self.core.setPos(base.camera, (0, 0, 0))
        self.core.setHpr(camera_hpr)
        self.core.setScale(600, 600, 600)
        self.glow = loader.loadModel("./Models/sphere.egg")
        self.core.setTransparency(TransparencyAttrib.MAlpha)
        self.glow.setScale(2, 2, 2)
        self.glow.reparentTo(self.core)
        self.core.setColor(colors.get("white"))
        self.glow.setColor(colors.get("white-transparent"))
        self.glow.setPos(0, 0, 0)  #relative to parent
        self.core.setLightOff(
        )  # remove all other lights from missle so it is a bright white
        missle_total.append(self)

        #Create the light so the missle glows
        plight = PointLight('plight')
        plight.setColor(colors.get("white"))
        plight.setAttenuation(LVector3(0, 0.00008, 0))
        plight.setMaxDistance(1000)
        self.plnp = self.core.attachNewNode(plight)  #point light node point
        render.setLight(self.plnp)

        # Create hitsphere
        cNode = CollisionNode(self.name)
        cNode.addSolid(CollisionSphere(0, 0, 0, 1))
        self.c_np = self.core.attachNewNode(cNode)

        # Create and run the missle animation

        end_location = Location(self.core).obj.getPos()
        start_location = base.camera.getPos()
        dt = globalClock.getDt()
        start_location[0] += spaceship_speed_x * dt
        start_location[1] += spaceship_speed_y * dt
        start_location[2] += spaceship_speed_z * dt

        self.asteroid_lerp = LerpPosInterval(
            self.core,  # Object being manipulated. The missle in this case.
            500,  # How long it will take the missle to go from point a to b in seconds
            end_location,  # future location at end of lerp
            start_location,  # The start position of the missle
            fluid=1)  # Allow for colisions during the lerp
        self.asteroid_lerp.start()
        del end_location

        self.core.reparentTo(render)
    def __init__(self,
                 game,
                 duration=None,
                 storage_path="storage/3d/frame",
                 fps=30,
                 as_gif=False,
                 gif_name=None,
                 size=(480, 480)):
        self.game = game
        self.duration = duration
        self.storage_path = storage_path
        self.fps = fps
        self.as_gif = as_gif
        self.gif_name = gif_name
        self.base = ShowBase(windowType='none')
        self.base.openWindow(type=('offscreen' if as_gif else 'onscreen'),
                             size=size)

        depth, height, width = game.shape
        self.rhomdos = []

        for z in range(depth):
            self.rhomdos.append([])
            for y in range(height):
                self.rhomdos[-1].append([])
                for x in range(width):
                    rr = RhomdoRender((z, y, x), game.shape)
                    render.attachNewNode(rr.geomnode)
                    self.rhomdos[-1][-1].append(rr)

        plight = PointLight('plight')
        plight.setColor(VBase4(1, 1, 1, 1))
        plight.setAttenuation((0, 0, .0005))
        self.plnp = render.attachNewNode(plight)
        self.plnp.setPos(0, 0, (game.shape[0] * SR2) + 40)
        render.setLight(self.plnp)

        if self.as_gif:
            self.base.movie(self.storage_path,
                            duration=self.duration,
                            fps=self.fps)

        self.base.taskMgr.add(self.spinCameraTask, "SpinCameraTask")
        self.base.taskMgr.add(self.updateClock, "UpdateClock")

        self.frame = 0
        self.game_step = 0
Beispiel #12
0
    def basic_point_light(self,
                          position,
                          color,
                          name,
                          attenuation=(1, 0, 0.02)):
        light = PointLight(name)
        light.setColor(color)
        light.setAttenuation(attenuation)
        # light.setShadowCaster(True)
        # light.getLens().setNearFar(5, 20)
        plight = self.centerlight_np.attachNewNode(light)
        plight.setPos(position)
        self.render.setLight(plight)

        light_cube = self.loader.loadModel("cuby.gltf")
        light_cube.reparentTo(plight)
        light_cube.setScale(0.25)
        material = Material()
        material.setEmission(color)
        light_cube.setMaterial(material)
Beispiel #13
0
    def _set_explosion_lights(self):
        """Prepare three explosion lights.

        Build a list-pool of light objects to
        be used in different explosions.

        Returns:
            list: List of lights to be used for explosions.
        """
        lights = []
        for num in range(3):
            light = PointLight("explosion_light_" + str(num))
            light.setColor((1, 0.9, 0.55, 1))
            light.setAttenuation((0, 0, 1))
            light_np = render.attachNewNode(light)  # noqa: F821
            light_np.setPos(0, 0, -5)
            render.setLight(light_np)  # noqa: F821
            lights.append(light_np)

        return lights
	def setupLightSources(self, base, scene):
		for np in self.model.findAllMatches('**/=Light'):
			if np.getTag('Light') == 'Point':
				light = PointLight('PointLight.%d' % (len(self.lights) + 1,))
			elif np.getTag('Light') == 'Spot':
				light = Spotlight('Spotlight.%d' % (len(self.lights) + 1,))
				
				fov = np.getTag('Fov')
				if fov:
					light.getLens().setFov(float(fov))
					
				nf = np.getTag('NearFar').split(',')
				if len(nf) > 1:
					light.getLens().setNearFar(float(nf[0]), float(nf[1]))
				
				exp = np.getTag('Exponent')
				if exp:
					light.setExponent(float(exp))
					
			elif np.getTag('Light') == 'Directional':
				light = DirectionalLight('DirectionalLight.%d' % (len(self.lights) + 1,))	
			
			materials = np.findAllMaterials()
			if len(materials) > 0:
				light.setColor(materials[0].getDiffuse())
			
			attenuation = np.getTag('Attenuation').split(',')
			if len(attenuation) > 0 and not isinstance(light, DirectionalLight):
				light.setAttenuation(tuple([float(a) for a in attenuation]))
				
# 			if np.getTag('Shadow'):
# 				self.model.setShaderAuto()
# 				light.setShadowCaster(True)
			
			self.lights.append(light)
			
			lightNP = self.model.attachNewNode(light)
			lightNP.setPos(np.getPos())
			lightNP.setHpr(np.getHpr())
# 			lightNP.setCompass()
			self.model.setLight(lightNP)
Beispiel #15
0
    def _set_lights(self):
        """Configure the locomotive lights.

        Sets the main locomotive lighter and lights above the doors.

        Returns:
            list: NodePath's of the Train lights.
        """
        lens = PerspectiveLens()
        lens.setNearFar(0, 50)
        lens.setFov(60, 60)

        floodlight = Spotlight("train_main_lighter")
        floodlight.setColor((0.5, 0.5, 0.5, 1))
        floodlight.setLens(lens)
        floodlight.setExponent(0.4)
        floodlight_np = self.model.attachNewNode(floodlight)
        floodlight_np.setPos(0, 0.34, 50)
        render.setLight(floodlight_np)  # noqa: F821

        train_lights = [floodlight_np]

        for name, coors in (
            ("train_right_door_light", (0.073, -0.17, 50)),
            ("train_left_door_light", (-0.073, -0.17, 50)),
            ("train_back_door_light", (0, -0.63, 50)),
        ):
            lamp = PointLight(name)
            lamp.setColor((0.89, 0.81, 0.55, 1))
            lamp.setAttenuation(3)
            lamp_np = self.model.attachNewNode(lamp)
            lamp_np.setPos(*coors)
            render.setLight(lamp_np)  # noqa: F821

            train_lights.append(lamp_np)

        return train_lights
Beispiel #16
0
    def __init__(self, position, value):
        #Invisiible point so that both spheres have the same parent
        self.name = "pointball"
        self.center = NodePath(PandaNode("Pointball center"))
        self.ttl = 15  #Time to live in seconds
        self.ttl_max = 15
        self.max_size = 9000
        self.attraction_distance = 900000
        self.center.setPos(position)
        self.center.setTag("value", str(value))
        # Create 1st sphere
        self.one = loader.loadModel("./Models/sphere.egg")
        self.one.setColor(colors.get("blue-transparent"))
        self.one.setScale(self.max_size, self.max_size, self.max_size)
        self.one.setLightOff()
        self.one.reparentTo(self.center)
        #Create 2nd sphere
        self.two = loader.loadModel("./Models/sphere.egg")
        self.two.setColor(colors.get("lightblue-transparent"))
        self.two.setScale(self.max_size, self.max_size, self.max_size)
        self.two.setLightOff()
        self.two.reparentTo(self.center)

        #Create the light so the missle glows
        plight = PointLight('plight')
        plight.setColor(colors.get("blue"))
        plight.setAttenuation(LVector3(0, 0.000008, 0))
        plight.setMaxDistance(100)
        self.plnp = self.center.attachNewNode(plight)  #point light node point
        render.setLight(self.plnp)

        # Create Collision hitsphere
        cNode = CollisionNode(self.name)
        cNode.addSolid(CollisionSphere(0, 0, 0, self.max_size * 20))
        self.c_np = self.center.attach_new_node(cNode)
        #Render to scene
        self.center.reparentTo(render)
Beispiel #17
0
    def __init__(self):
        # Configure the parallax mapping settings (these are just the defaults)
        loadPrcFileData(
            "", "parallax-mapping-samples 3\n"
            "parallax-mapping-scale 0.1")

        # Initialize the ShowBase class from which we inherit, which will
        # create a window and set up everything we need for rendering into it.
        ShowBase.__init__(self)

        # Check video card capabilities.
        if not self.win.getGsg().getSupportsBasicShaders():
            addTitle("Bump Mapping: "
                     "Video driver reports that Cg shaders are not supported.")
            return

        # Post the instructions
        self.title = addTitle("Panda3D: Tutorial - Bump Mapping")
        self.inst1 = addInstructions(0.06, "Press ESC to exit")
        self.inst2 = addInstructions(0.12, "Move mouse to rotate camera")
        self.inst3 = addInstructions(0.18, "Left mouse button: Move forwards")
        self.inst4 = addInstructions(0.24,
                                     "Right mouse button: Move backwards")
        self.inst5 = addInstructions(0.30, "Enter: Turn bump maps Off")

        # Load the 'abstract room' model.  This is a model of an
        # empty room containing a pillar, a pyramid, and a bunch
        # of exaggeratedly bumpy textures.

        self.room = loader.loadModel("models/abstractroom")
        self.room.reparentTo(render)

        # Make the mouse invisible, turn off normal mouse controls
        self.disableMouse()
        props = WindowProperties()
        props.setCursorHidden(True)
        self.win.requestProperties(props)
        self.camLens.setFov(60)

        # Set the current viewing target
        self.focus = LVector3(55, -55, 20)
        self.heading = 180
        self.pitch = 0
        self.mousex = 0
        self.mousey = 0
        self.last = 0
        self.mousebtn = [0, 0, 0]

        # Start the camera control task:
        taskMgr.add(self.controlCamera, "camera-task")
        self.accept("escape", sys.exit, [0])
        self.accept("mouse1", self.setMouseBtn, [0, 1])
        self.accept("mouse1-up", self.setMouseBtn, [0, 0])
        self.accept("mouse2", self.setMouseBtn, [1, 1])
        self.accept("mouse2-up", self.setMouseBtn, [1, 0])
        self.accept("mouse3", self.setMouseBtn, [2, 1])
        self.accept("mouse3-up", self.setMouseBtn, [2, 0])
        self.accept("enter", self.toggleShader)
        self.accept("j", self.rotateLight, [-1])
        self.accept("k", self.rotateLight, [1])
        self.accept("arrow_left", self.rotateCam, [-1])
        self.accept("arrow_right", self.rotateCam, [1])

        # Add a light to the scene.
        self.lightpivot = render.attachNewNode("lightpivot")
        self.lightpivot.setPos(0, 0, 25)
        self.lightpivot.hprInterval(10, LPoint3(360, 0, 0)).loop()
        plight = PointLight('plight')
        plight.setColor((1, 1, 1, 1))
        plight.setAttenuation(LVector3(0.7, 0.05, 0))
        plnp = self.lightpivot.attachNewNode(plight)
        plnp.setPos(45, 0, 0)
        self.room.setLight(plnp)

        # Add an ambient light
        alight = AmbientLight('alight')
        alight.setColor((0.2, 0.2, 0.2, 1))
        alnp = render.attachNewNode(alight)
        self.room.setLight(alnp)

        # Create a sphere to denote the light
        sphere = loader.loadModel("models/icosphere")
        sphere.reparentTo(plnp)

        # Tell Panda that it should generate shaders performing per-pixel
        # lighting for the room.
        self.room.setShaderAuto()

        self.shaderenable = 1
Beispiel #18
0
    def __init__(self):
        # Initialize the ShowBase class from which we inherit, which will
        # create a window and set up everything we need for rendering into it.
        ShowBase.__init__(self)

        self.disableMouse()
        self.cam.node().getLens().setNear(10.0)
        self.cam.node().getLens().setFar(200.0)
        camera.setPos(0, -50, 0)

        # Check video card capabilities.
        if not self.win.getGsg().getSupportsBasicShaders():
            addTitle("Toon Shader: Video driver reports that Cg shaders are not supported.")
            return

        # Enable a 'light ramp' - this discretizes the lighting,
        # which is half of what makes a model look like a cartoon.
        # Light ramps only work if shader generation is enabled,
        # so we call 'setShaderAuto'.

        tempnode = NodePath(PandaNode("temp node"))
        tempnode.setAttrib(LightRampAttrib.makeSingleThreshold(0.5, 0.4))
        tempnode.setShaderAuto()
        self.cam.node().setInitialState(tempnode.getState())

        # Use class 'CommonFilters' to enable a cartoon inking filter.
        # This can fail if the video card is not powerful enough, if so,
        # display an error and exit.

        self.separation = 1  # Pixels
        self.filters = CommonFilters(self.win, self.cam)
        filterok = self.filters.setCartoonInk(separation=self.separation)
        if (filterok == False):
            addTitle(
                "Toon Shader: Video card not powerful enough to do image postprocessing")
            return

        # Show instructions in the corner of the window.
        self.title = addTitle(
            "Panda3D: Tutorial - Toon Shading with Normals-Based Inking")
        self.inst1 = addInstructions(0.06, "ESC: Quit")
        self.inst2 = addInstructions(0.12, "Up/Down: Increase/Decrease Line Thickness")
        self.inst3 = addInstructions(0.18, "V: View the render-to-texture results")

        # Load a dragon model and animate it.
        self.character = Actor()
        self.character.loadModel('models/nik-dragon')
        self.character.reparentTo(render)
        self.character.loadAnims({'win': 'models/nik-dragon'})
        self.character.loop('win')
        self.character.hprInterval(15, (360, 0, 0)).loop()

        # Create a non-attenuating point light and an ambient light.
        plightnode = PointLight("point light")
        plightnode.setAttenuation((1, 0, 0))
        plight = render.attachNewNode(plightnode)
        plight.setPos(30, -50, 0)
        alightnode = AmbientLight("ambient light")
        alightnode.setColor((0.8, 0.8, 0.8, 1))
        alight = render.attachNewNode(alightnode)
        render.setLight(alight)
        render.setLight(plight)

        # Panda contains a built-in viewer that lets you view the
        # results of all render-to-texture operations.  This lets you
        # see what class CommonFilters is doing behind the scenes.
        self.accept("v", self.bufferViewer.toggleEnable)
        self.accept("V", self.bufferViewer.toggleEnable)
        self.bufferViewer.setPosition("llcorner")
        self.accept("s", self.filters.manager.resizeBuffers)

        # These allow you to change cartooning parameters in realtime
        self.accept("escape", sys.exit, [0])
        self.accept("arrow_up", self.increaseSeparation)
        self.accept("arrow_down", self.decreaseSeparation)
Beispiel #19
0
class MyApp(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        dir(self)
        self.disableMouse()

        # Load the environment model.
        self.environ = self.loader.loadModel("../levels/level01.egg")
        # Reparent the model to render.
        self.environ.reparentTo(self.render)
        '''add a light'''
        self.light = PointLight("dLight")
        self.light.setAttenuation((.01, .01, .01))
        self.light.setSpecularColor(VBase4(1, 1, 0, 1))
        self.lightNode = render.attachNewNode(self.light)
        self.lightNode.setZ(10)
        render.setLight(self.lightNode)
        '''move light constants'''
        self.moveLightDirection = -1000

        self.taskMgr.add(self.moveLight, "lightMove")
        self.taskMgr.add(self.fpsInput, "fpsInput")
        '''fps cam controls'''
        self.keymap = {
            "w": 0,
            "a": 0,
            "s": 0,
            "d": 0,
            "e": 0,
            "q": 0,
            "j": 0,
            "k": 0,
            "l": 0,
            "i": 0
        }

        self.fps = FpsCam(self.camera)
        self.accept("a", self.setKey, ["a", 1])
        self.accept("a-up", self.setKey, ['a', 0])
        self.accept("w", self.setKey, ["w", 1])
        self.accept("w-up", self.setKey, ["w", 0])
        self.accept("s", self.setKey, ["s", 1])
        self.accept("s-up", self.setKey, ["s", 0])
        self.accept("d", self.setKey, ["d", 1])
        self.accept("d-up", self.setKey, ["d", 0])
        self.accept("e", self.setKey, ["e", 1])
        self.accept("e-up", self.setKey, ["e", 0])
        self.accept("q", self.setKey, ["q", 1])
        self.accept("q-up", self.setKey, ["q", 0])
        self.accept("j", self.setKey, ["j", 1])
        self.accept("j-up", self.setKey, ["j", 0])
        self.accept("k", self.setKey, ["k", 1])
        self.accept("k-up", self.setKey, ["k", 0])
        self.accept("l", self.setKey, ["l", 1])
        self.accept("l-up", self.setKey, ["l", 0])
        self.accept("i", self.setKey, ["i", 1])
        self.accept("i-up", self.setKey, ["i", 0])
        self.accept("escape", sys.exit)

    def setKey(self, key, value):
        self.keymap[key] = value
        return

    def fpsInput(self, task):
        self.fps.moveX(self.keymap["d"] - self.keymap["a"])
        self.fps.moveY(self.keymap["w"] - self.keymap["s"])
        self.fps.moveZ(self.keymap["e"] - self.keymap["q"])
        self.fps.yaw(self.keymap["j"] - self.keymap["l"])
        self.fps.pitch(self.keymap["i"] - self.keymap["k"])
        return task.cont

    def moveLight(self, task):
        #print dir(self.lightNode)
        where = self.lightNode.getX()
        #print where
        self.lightNode.setX(where - task.getDt() * self.moveLightDirection)
        if self.lightNode.getX() < -10:
            self.moveLightDirection *= -1
        elif self.lightNode.getX() > 10:
            self.moveLightDirection *= -1

        return task.cont
Beispiel #20
0
    def __init__(self,
                 cad_file=None,
                 output_size=(512, 512),
                 light_on=True,
                 cast_shadow=True):
        # acquire lock since showbase cannot be created twice
        Panda3DRenderer.__lock.acquire()

        # set output size and init the base
        loadPrcFileData('', f'win-size {output_size[0]} {output_size[1]}')
        base = ShowBase(windowType='offscreen')

        # coordinate for normalized and centered object
        obj_node = base.render.attach_new_node('normalized_obj')

        # ambient
        alight = AmbientLight('alight')
        alight.set_color(VBase4(0.5, 0.5, 0.5, 1.0))
        alnp = base.render.attachNewNode(alight)
        base.render.setLight(alnp)

        # directional light for ambient
        dlight1 = DirectionalLight('dlight1')
        dlight1.set_color(VBase4(0.235, 0.235, 0.235, 1.0))
        dlnp1 = base.render.attach_new_node(dlight1)
        dlnp1.set_pos(-2, 3, 1)
        dlnp1.look_at(obj_node)
        base.render.set_light(dlnp1)

        # point light for ambient
        plight1 = PointLight('plight1')
        plight1.set_color(VBase4(1.75, 1.75, 1.75, 1.0))
        plight1.setAttenuation((1, 1, 1))
        plnp1 = base.render.attach_new_node(plight1)
        plnp1.set_pos(0, 0, 3)
        plnp1.look_at(obj_node)
        base.render.set_light(plnp1)

        plight2 = PointLight('plight2')
        plight2.set_color(VBase4(1.5, 1.5, 1.5, 1.0))
        plight2.setAttenuation((1, 0, 1))
        plnp2 = base.render.attach_new_node(plight2)
        plnp2.set_pos(0, -3, 0)
        plnp2.look_at(obj_node)
        base.render.set_light(plnp2)

        dlight2 = DirectionalLight('dlight2')
        dlight2.set_color(VBase4(0.325, 0.325, 0.325, 1.0))
        dlnp2 = base.render.attach_new_node(dlight2)
        dlnp2.set_pos(-1, 1, -1.65)
        dlnp2.look_at(obj_node)
        base.render.set_light(dlnp2)

        dlight3 = DirectionalLight('dlight3')
        dlight3.set_color(VBase4(0.15, 0.15, 0.15, 1.0))
        dlnp3 = base.render.attach_new_node(dlight3)
        dlnp3.set_pos(-2.5, 2.5, 2.0)
        dlnp3.look_at(obj_node)
        base.render.set_light(dlnp3)
        if cast_shadow:
            lens = PerspectiveLens()
            dlight3.set_lens(lens)
            dlight3.set_shadow_caster(True, 1024, 1024)

        dlight4 = DirectionalLight('dlight4')
        dlight4.set_color(VBase4(0.17, 0.17, 0.17, 1.0))
        dlnp4 = base.render.attach_new_node(dlight4)
        dlnp4.set_pos(1.2, -2.0, 2.5)
        dlnp4.look_at(obj_node)
        base.render.set_light(dlnp4)
        if cast_shadow:
            lens = PerspectiveLens()
            dlight4.set_lens(lens)
            dlight4.set_shadow_caster(True, 1024, 1024)

        self.direct_node = direct_node = base.render.attach_new_node(
            'direct_light')
        dlnp2.reparent_to(direct_node)
        dlnp3.reparent_to(direct_node)
        dlnp4.reparent_to(direct_node)

        # auto shader for shadow
        if cast_shadow:
            base.render.setShaderAuto()
        # no culling
        base.render.set_two_sided(True)
        # anti-alias
        base.render.setAntialias(AntialiasAttrib.MMultisample, 8)
        # init camera position
        self.coverage = 0.5
        # the default clear color
        self.clear_color = (0.0, 0.0, 0.0, 0.0)
        # translate in rendered image
        self.obj_translate = (0, 0)
        # light rotation
        self.light_hpr = (0, 0, 0)
        # object rotation
        self.obj_hpr = (0, 0, 0)

        self.base = base
        self.obj = None
        self.obj_node = obj_node
        self.cast_shadow = cast_shadow
        self.camera = base.camera
        if cad_file is not None:
            self.set_obj(cad_file)

        if not light_on:
            base.render.set_light_off()
Beispiel #21
0
class Light(PropertiesTableAbstract, XMLExportable):
    def __init__(self, attributes, parent):

        self.plnp = -1
        self.parent = parent
        self.typeName = 'light'
        self.properties = {
            'distance': '',
            'attenuation': '',
            'type': '',
            'on': '',
            'color': '',
            'id': ''
        }

        self.propertiesUpdateFactor = {'distance': 0.1, 'attenuation': 0.01}

        if 'distance' in attributes:
            self.properties['distance'] = distance = float(
                attributes['distance'].value)
        else:
            distance = 1.0

        if 'attenuation' in attributes:
            self.properties[
                'attenuation'] = self.attenuation = attenuation = float(
                    attributes['attenuation'].value)
        else:
            self.properties[
                'attenuation'] = self.attenuation = attenuation = 0.0

        if 'type' in attributes:
            self.properties['type'] = ltype = attributes['type'].value
        else:
            self.properties['type'] = ltype = 'point'

        if 'on' in attributes:
            if attributes['on'].value == "false":
                self.properties['on'] = 'false'
                self.on = False
            else:
                self.properties['on'] = 'true'
                self.on = True
        else:
            self.on = True

        if 'color' in attributes:
            self.properties['color'] = color = attributes['color'].value
        else:
            color = '1,1,1,1'

        if 'id' in attributes:
            self.properties['id'] = self.uid = uid = attributes['id'].value
        else:
            self.properties['id'] = self.uid = uid = 'light'

        self.generateNode()

    '''
    Used in editor mode to add an object that visibly represents the light
    '''

    def showVisibleObject():
        pass
        #TODO IMPLEMENT!!

    def destroy(self):
        if self.plnp != -1:
            render.clearLight(self.plnp)

    def generateNode(self):
        rgba = self.properties['color'].split(',')
        if len(rgba) < 3:
            print(
                "ERROR: please define a correct color for light. (example: r,g,b,a in float values)!"
            )
        realcolor = VBase4(
            float(rgba[0]) / 255,
            float(rgba[1]) / 255,
            float(rgba[2]) / 255, 1.0)

        if self.properties['type'] == 'spot':
            self.plight = Spotlight('slight')
            self.plight.setColor(realcolor)
            self.lens = PerspectiveLens()
            self.plight.setLens(self.lens)
            self.plnp = self.parent.attachNewNode(self.plight)
            self.plnp.setPos(0.5, -self.properties['distance'], 0.5)
            self.plnp.lookAt(Point3(0.5, 0, 0.5))

        if self.properties['type'] == 'point':
            self.plight = PointLight('plight')
            self.plight.setColor(realcolor)
            if self.on == True:
                self.plight.setAttenuation(self.properties['attenuation'])
            else:
                self.plight.setAttenuation((1.0, 0, 1))
            self.plnp = self.parent.getNode().attachNewNode(self.plight)
            self.plnp.setPos(0.5, -self.properties['distance'], 0.5)

        render.setLight(self.plnp)

        if self.on:
            self.setOn()

        #set unique id
        self.plnp.setTag("id", self.properties['id'])
        self.plnp.setPythonTag("gamenode", self)

    def getName(self):
        return 'Point Light: ' + self.properties['id']

    def xmlAttributes(self):
        return self.properties

    def xmlTypeName(self):
        return self.typeName

    '''
    Sanitize properties data to be of correct type from string
    '''

    def sanitizeProperties(self):
        #sanitizing data
        self.properties['distance'] = float(self.properties['distance'])
        self.properties['attenuation'] = float(self.properties['attenuation'])

    #interface needed by PropertiesTable
    # regenerates the node at every change
    def onPropertiesUpdated(self):
        self.sanitizeProperties()

        rgba = self.properties['color'].split(',')
        if len(rgba) < 3:
            print(
                "ERROR: please define a correct color for light. (example: r,g,b,a in float values)!"
            )
        realcolor = VBase4(
            float(rgba[0]) / 255,
            float(rgba[1]) / 255,
            float(rgba[2]) / 255, 1.0)

        self.plnp.setY(-self.properties['distance'])
        self.plight.setColor(realcolor)
        self.plight.setAttenuation((self.properties['attenuation']))

    def getPropertyList(self):
        return self.properties

    def setProperty(self, key, value):
        self.properties[key] = value

    def increaseProperty(self, key, multiplier):
        if key in self.propertiesUpdateFactor:
            self.setProperty(
                key, self.properties[key] +
                self.propertiesUpdateFactor[key] * multiplier)

    def decreaseProperty(self, key, multiplier):
        if key in self.propertiesUpdateFactor:
            self.setProperty(
                key, self.properties[key] -
                self.propertiesUpdateFactor[key] * multiplier)

    def copyProperties(self):
        return self.getPropertyList()

    def pasteProperties(self, props):
        for key, value in props.items():
            if key in self.properties:
                self.properties[key] = value
        self.onPropertiesUpdated()

    def getNode(self):
        return self.plnp

    def setOn(self):
        self.plight.setAttenuation(self.attenuation)
        self.on = True

    def setOff(self):
        self.plight.setAttenuation(1.0)
        self.on = False

    def toggle(self):
        if self.on:
            self.setOff()
        else:
            self.setOn()
Beispiel #22
0
class World(DirectObject):

    def __init__(self):
        self.last_mousex = 0
        self.last_mousey = 0

        self.zone = None
        self.zone_reload_name = None
        
        self.winprops = WindowProperties( )

        # simple console output
        self.consoleNode = NodePath(PandaNode("console_root"))
        self.consoleNode.reparentTo(aspect2d)

        self.console_num_lines = 24
        self.console_cur_line = -1
        self.console_lines = []
        for i in range(0, self.console_num_lines):
            self.console_lines.append(OnscreenText(text='', style=1, fg=(1,1,1,1),
                        pos=(-1.3, .4-i*.05), align=TextNode.ALeft, scale = .035, parent = self.consoleNode))

        # Configuration
        self.consoleOut('zonewalk v.%s loading configuration' % VERSION)
        self.configurator = Configurator(self)
        cfg = self.configurator.config
        resaveRes = False
        if 'xres' in cfg:
            self.xres = int(cfg['xres'])
        else:
            self.xres = 1024
            resaveRes = True

        if 'yres' in cfg:
            self.yres = int(cfg['yres'])
        else:
            self.yres = 768
            resaveRes = True

        if resaveRes:
            self.saveDefaultRes()

        self.xres_half = self.xres / 2
        self.yres_half = self.yres / 2
        self.mouse_accum = MouseAccume( lambda: (self.xres_half,self.yres_half))

        self.eyeHeight = 7.0
        self.rSpeed = 80
        self.flyMode = 1

        # application window setup
        base.win.setClearColor(Vec4(0,0,0,1))
        self.winprops.setTitle( 'zonewalk')
        self.winprops.setSize(self.xres, self.yres) 
        
        base.win.requestProperties( self.winprops ) 
        base.disableMouse()

        # network test stuff
        self.login_client = None
        if 'testnet' in cfg:
            if cfg['testnet'] == '1':
                self.doLogin()
        
        # Post the instructions
        self.title = addTitle('zonewalk v.' + VERSION)
        self.inst0 = addInstructions(0.95, "[FLYMODE][1]")
        self.inst1 = addInstructions(-0.95, "Camera control with WSAD/mouselook. Press K for hotkey list, ESC to exit.")
        self.inst2 = addInstructions(0.9,  "Loc:")
        self.inst3 = addInstructions(0.85, "Hdg:")
        self.error_inst = addInstructions(0, '')
        self.kh = []
        
        self.campos = Point3(155.6, 41.2, 4.93)
        base.camera.setPos(self.campos)
        
        # Accept the application control keys: currently just esc to exit navgen       
        self.accept("escape", self.exitGame)
        self.accept("window-event", self.resizeGame)
        
        # Create some lighting
        ambient_level = .6
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor(Vec4(ambient_level, ambient_level, ambient_level, 1.0))
        render.setLight(render.attachNewNode(ambientLight))

        direct_level = 0.8
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection(Vec3(0.0, 0.0, -1.0))
        directionalLight.setColor(Vec4(direct_level, direct_level, direct_level, 1))
        directionalLight.setSpecularColor(Vec4(direct_level, direct_level, direct_level, 1))
        render.setLight(render.attachNewNode(directionalLight))
        
        # create a point light that will follow our view point (the camera for now)
        # attenuation is set so that this point light has a torch like effect
        self.plight = PointLight('plight')
        self.plight.setColor(VBase4(0.8, 0.8, 0.8, 1.0))
        self.plight.setAttenuation(Point3(0.0, 0.0, 0.0002))
        
        self.plnp = base.camera.attachNewNode(self.plight)
        self.plnp.setPos(0, 0, 0)
        render.setLight(self.plnp)
        self.cam_light = 1
        
        self.keyMap = {"left":0, "right":0, "forward":0, "backward":0, "cam-left":0, \
            "cam-right":0, "mouse3":0, "flymode":1 }

        # setup FOG
        self.fog_colour = (0.8,0.8,0.8,1.0)
        self.linfog = Fog("A linear-mode Fog node")
        self.linfog.setColor(self.fog_colour)
        self.linfog.setLinearRange(700, 980)         # onset, opaque distances as params
        # linfog.setLinearFallback(45,160,320)
        base.camera.attachNewNode(self.linfog)
        render.setFog(self.linfog)
        self.fog = 1
        
        # camera control
        self.campos = Point3(0, 0, 0)
        self.camHeading = 0.0
        self.camPitch = 0.0
        base.camLens.setFov(65.0)
        base.camLens.setFar(1200) 
        
        self.cam_speed = 0  # index into self.camp_speeds
        self.cam_speeds = [40.0, 80.0, 160.0, 320.0, 640.0]
        
        
        # Collision Detection for "WALKMODE"
        # We will detect the height of the terrain by creating a collision
        # ray and casting it downward toward the terrain.  The ray 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.camGroundRay = CollisionRay()
        self.camGroundRay.setOrigin(0.0, 0.0, 0.0)
        self.camGroundRay.setDirection(0,0,-1)      # straight down
        self.camGroundCol = CollisionNode('camRay')
        self.camGroundCol.addSolid(self.camGroundRay)
        self.camGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.camGroundCol.setIntoCollideMask(BitMask32.allOff())
        
        # attach the col node to the camCollider dummy node
        self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol)  
        self.camGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)
        
        
        # Uncomment this line to see the collision rays
        # self.camGroundColNp.show()
       
        # Uncomment this line to show a visual representation of the 
        # collisions occuring
        # self.cTrav.showCollisions(render)
        
        # Add the spinCameraTask procedure to the task manager.
        # taskMgr.add(self.spinCameraTask, "SpinCameraTask")
        taskMgr.add(self.camTask, "camTask")

        self.toggleControls(1)

        # need to step the task manager once to make our fake console work
        taskMgr.step()

    # CONSOLE ---------------------------------------------------------------------
    def consoleScroll(self):
        for i in range(0, self.console_num_lines-1):
            self.console_lines[i].setText(self.console_lines[i+1].getText())
            
    def consoleOut(self, text):
        print text  # output to stdout/log too

        if self.console_cur_line == self.console_num_lines-1:
            self.consoleScroll()
        elif self.console_cur_line < self.console_num_lines-1:
            self.console_cur_line += 1

        self.console_lines[self.console_cur_line].setText(text)

        taskMgr.step()
    
    def consoleOn(self):
        self.consoleNode.show()
        
    def consoleOff(self):
        self.consoleNode.hide()
        
    # User controls -----------------------------------------------------------
    def toggleControls(self, on):

        cfg = self.configurator.config

        if on == 1:
            self.accept("escape", self.exitGame)

            self.accept("1", self.setSpeed, ["speed", 0])
            self.accept("2", self.setSpeed, ["speed", 1])
            self.accept("3", self.setSpeed, ["speed", 2])
            self.accept("4", self.setSpeed, ["speed", 3])
            self.accept("5", self.setSpeed, ["speed", 4])

            self.accept("alt-f", self.fogToggle)

            self.accept(cfg['control_lighting'], self.camLightToggle)
            self.accept(cfg['control_help'], self.displayKeyHelp)
            self.accept(cfg['control_flymode'], self.toggleFlymode)
            self.accept(cfg['control_reload-zone'], self.reloadZone)
            # Deactivate this for now
            #self.accept("z", self.saveDefaultZone)
            self.accept(cfg['control_cam-left'], self.setKey, ["cam-left",1])
            self.accept(cfg['control_cam-right'], self.setKey, ["cam-right",1])
            self.accept(cfg['control_forward'], self.setKey, ["forward",1])
            # Mouse1 should be for clicking on objects
            #self.accept("mouse1", self.setKey, ["forward",1])
            self.accept("mouse3", self.setKey, ["mouse3",1])
            self.accept(cfg['control_backward'], self.setKey, ["backward",1])
        
            self.accept("k-up", self.hideKeyHelp)
            self.accept(cfg['control_cam-left']+"-up", self.setKey, ["cam-left",0])
            self.accept(cfg['control_cam-right']+"-up", self.setKey, ["cam-right",0])
            self.accept(cfg['control_forward']+"-up", self.setKey, ["forward",0])
            # Mouse1 should be for clicking on objects
            #self.accept("mouse1-up", self.setKey, ["forward",0])
            self.accept("mouse3-up", self.setKey, ["mouse3",0])
            self.accept(cfg['control_backward']+"-up", self.setKey, ["backward",0])
        else:
            messenger.clear()
            
    def setSpeed(self, key, value):
        self.cam_speed = value
        self.setFlymodeText()
        
    def fogToggle(self):
        if self.fog == 1:
            render.clearFog()
            base.camLens.setFar(100000) 
            self.fog = 0
        else:
            render.setFog(self.linfog)
            base.camLens.setFar(1200) 
            self.fog = 1
            
    def camLightToggle(self):
        if self.cam_light == 0:
            render.setLight(self.plnp)
            self.cam_light = 1
        else:
            render.clearLight(self.plnp)
            self.cam_light = 0
        
    def displayKeyHelp(self):
        self.kh = []
        msg = 'HOTKEYS:'
        pos = 0.75
        self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(-0.5, pos), align=TextNode.ALeft, scale = .04))
        msg = '------------------'
        pos -= 0.05
        self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(-0.5, pos), align=TextNode.ALeft, scale = .04))
        msg = 'W: camera fwd, S: camera bck, A: rotate view left, D: rotate view right'
        pos -= 0.05
        self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(-0.5, pos), align=TextNode.ALeft, scale = .04))
        msg = '1-5: set camera movement speed'
        pos -= 0.05
        self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(-0.5, pos), align=TextNode.ALeft, scale = .04))
        msg = 'F: toggle Flymode/Walkmode'
        pos -= 0.05
        self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(-0.5, pos), align=TextNode.ALeft, scale = .04))
        msg = 'L: load a zone'
        pos -= 0.05
        self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(-0.5, pos), align=TextNode.ALeft, scale = .04))
        msg = 'ALT-F: toggle FOG and FAR plane on/off'
        pos -= 0.05
        self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(-0.5, pos), align=TextNode.ALeft, scale = .04))
        msg = 'T: toggle additional camera "torch" light on/off'
        pos -= 0.05
        self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(-0.5, pos), align=TextNode.ALeft, scale = .04))
        msg = 'Z: set currently loaded zone as new startup default'
        pos -= 0.05
        self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(-0.5, pos), align=TextNode.ALeft, scale = .04))
        msg = 'ESC: exit zonewalk'
        pos -= 0.05
        self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(-0.5, pos), align=TextNode.ALeft, scale = .04))
     
    def hideKeyHelp(self):
        for n in self.kh:
            n.removeNode()
                        
    def setFlymodeText(self):
        zname = ''
        if self.zone:
            zname = self.zone.name
            
        if self.flyMode == 0:
            self.inst0.setText("[WALKMODE][%i] %s" % (self.cam_speed+1, zname))
        else:
            self.inst0.setText("[FLYMODE][%i] %s " % (self.cam_speed+1, zname))
        
    def toggleFlymode(self):
        zname = ''
        if self.zone:
            zname = self.zone.name

        if self.flyMode == 0:
            self.flyMode = 1
        else:
            self.flyMode = 0
            
        self.setFlymodeText()

    # Define a procedure to move the camera.
    def spinCameraTask(self, task):
        angleDegrees = task.time * 6.0
        angleRadians = angleDegrees * (pi / 180.0)
        base.camera.setPos(20 * sin(angleRadians), -20.0 * cos(angleRadians), 3)
        base.camera.setHpr(angleDegrees, 0, 0)
        return task.cont


    def camTask(self, task):
        # query the mouse
        mouse_dx = 0
        mouse_dy = 0


        # if we have a mouse and the right button is depressed
        if base.mouseWatcherNode.hasMouse():
            if self.keyMap["mouse3"] != 0:
                self.mouse_accum.update()
            else:
                self.mouse_accum.reset()

        mouse_dx = self.mouse_accum.dx
        mouse_dy = self.mouse_accum.dy

        self.rXSpeed = fabs(self.mouse_accum.dx) * (self.cam_speed+1) * max(5 * 1000/self.xres,3)
        self.rYSpeed = fabs(self.mouse_accum.dy) * (self.cam_speed+1) * max(3 * 1000/self.yres,1)
            
        if (self.keyMap["cam-left"]!=0 or mouse_dx < 0):
            if self.rSpeed < 160:
                self.rSpeed += 80 * globalClock.getDt()

            if mouse_dx != 0:
                self.camHeading += self.rXSpeed * globalClock.getDt()
            else:
                self.camHeading += self.rSpeed * globalClock.getDt()

            if self.camHeading > 360.0:
                self.camHeading = self.camHeading - 360.0
        elif (self.keyMap["cam-right"]!=0 or mouse_dx > 0):
            if self.rSpeed < 160:
                self.rSpeed += 80 * globalClock.getDt()

            if mouse_dx != 0:
                self.camHeading -= self.rXSpeed * globalClock.getDt()
            else:
                self.camHeading -= self.rSpeed * globalClock.getDt()

            if self.camHeading < 0.0:
                self.camHeading = self.camHeading + 360.0
        else:
            self.rSpeed = 80

        if mouse_dy > 0:
            self.camPitch += self.rYSpeed * globalClock.getDt()
        elif mouse_dy < 0:
            self.camPitch -= self.rYSpeed * globalClock.getDt()
            
        # set camera heading and pitch
        base.camera.setHpr(self.camHeading, self.camPitch, 0)

        # viewer position (camera) movement control
        v = render.getRelativeVector(base.camera, Vec3.forward())
        if not self.flyMode:
            v.setZ(0.0)
        
        move_speed = self.cam_speeds[self.cam_speed]
        if self.keyMap["forward"] == 1:
            self.campos += v * move_speed * globalClock.getDt()
        if self.keyMap["backward"] == 1:
            self.campos -= v * move_speed * globalClock.getDt()            

        # actually move the camera
        lastPos = base.camera.getPos()
        base.camera.setPos(self.campos)
        # self.plnp.setPos(self.campos)      # move the point light with the viewer position

        # WALKMODE: simple collision detection
        # we simply check a ray from slightly below the "eye point" straight down
        # for geometry collisions and if there are any we detect the point of collision
        # and adjust the camera's Z accordingly
        if self.flyMode == 0:   
            # move the camera to where it would be if it made the move 
            # the colliderNode moves with it
            # base.camera.setPos(self.campos)
            # check for collissons
            self.cTrav.traverse(render)
            entries = []
            for i in range(self.camGroundHandler.getNumEntries()):
                entry = self.camGroundHandler.getEntry(i)
                entries.append(entry)
                # print 'collision'
            entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                         x.getSurfacePoint(render).getZ()))
                                     
            if (len(entries) > 0): # and (entries[0].getIntoNode().getName() == "terrain"):
                # print len(entries)
                self.campos.setZ(entries[0].getSurfacePoint(render).getZ()+self.eyeHeight)
            else:
                self.campos = lastPos
                base.camera.setPos(self.campos)
        
            #if (base.camera.getZ() < self.player.getZ() + 2.0):
            #    base.camera.setZ(self.player.getZ() + 2.0)


        # update loc and hpr display
        pos = base.camera.getPos()
        hpr = base.camera.getHpr()
        self.inst2.setText('Loc: %.2f, %.2f, %.2f' % (pos.getX(), pos.getY(), pos.getZ()))
        self.inst3.setText('Hdg: %.2f, %.2f, %.2f' % (hpr.getX(), hpr.getY(), hpr.getZ()))
        return task.cont

        
    def exitGame(self):           
        sys.exit(0)

    def resizeGame(self,win):
        props = base.win.getProperties() 
        self.xres = props.getXSize()
        self.yres = props.getYSize()
        self.xres_half = self.xres / 2
        self.yres_half = self.yres / 2
        self.saveDefaultRes()
                
    #Records the state of the arrow keys
    # this is used for camera control
    def setKey(self, key, value):
        self.keyMap[key] = value

    # -------------------------------------------------------------------------
    # this is the mythical MAIN LOOP :)
    def update(self):

        if self.zone_reload_name != None:
            self.doReload(self.zone_reload_name)
            self.zone_reload_name = None

        if self.zone != None:
            self.zone.update()

        taskMgr.step()
   
        if self.login_client != None:
            self.login_client.update()  
        
        
    # ZONE loading ------------------------------------------------------------
    
    # general zone loader driver
    # removes existing zone (if any) and load the new one 
    def loadZone(self, name, path):
        if path[len(path)-1] != '/':
            path += '/'

        if self.zone:
            self.zone.rootNode.removeNode()
            
        self.zone = Zone(self, name, path)
        error = self.zone.load()
        if error == 0:
            self.consoleOff()
            self.setFlymodeText()
            base.setBackgroundColor(self.fog_colour)
        
    def saveDefaultRes(self):
        cfg = self.configurator.config
        cfg['xres'] = str(self.xres)
        cfg['yres'] = str(self.yres)
        #self.configurator.saveConfig()

    # initial world load after bootup
    def load(self):       
        cfg = self.configurator.config
        
        if self.login_client != None:
            return
            
        zone_name = cfg['default_zone']
        basepath = cfg['basepath']
        self.loadZone(zone_name, basepath)
    

    # config save user interfacce
    def saveDefaultZone(self):
        if self.zone:
            cfg = self.configurator.config
            cfg['default_zone'] = self.zone.name
            #self.configurator.saveConfig()

    # zone reload user interface
    
    # this gets called from our update loop when it detects that zone_reload_name has been set
    # we do this in this convoluted fashion in order to keep the main loop taskMgr updates ticking
    # because otherwise our status console output at various stages during the zone load would not
    # be displayed. Yes, this is hacky.
    def doReload(self, name):
        cfg = self.configurator.config
        basepath = cfg['basepath']
        self.loadZone(name, basepath)

    # form dialog callback
    # this gets called from the form when the user has entered a something
    # (hopefully a correct zone short name)
    def reloadZoneDialogCB(self, name):
        self.frmDialog.end()
        self.zone_reload_name = name
        self.toggleControls(1)

    # this is called when the user presses "l"
    # it disables normal controls and fires up our query form dialog
    def reloadZone(self):
        base.setBackgroundColor((0,0,0))
        self.toggleControls(0)
        self.consoleOn()
        self.frmDialog = FileDialog(
            "Please enter the shortname of the zone you wish to load:", 
            "Examples: qrg, blackburrow, freportn, crushbone etc.",
            self.reloadZoneDialogCB) 
        
        self.frmDialog.activate()   # relies on the main update loop to run

    ###############################
    # EXPERIMENTAL         
    def doLogin(self):
        
        self.login_client = UDPClientStream('127.0.0.1', 5998)

    #####################################
    # Custom methods
    #####################################


    # What happens when a user clicks on a model
    def onModelClick():
        # Code adapted freely from http://www.panda3d.org/forums/viewtopic.php?t=12717
        global picker, selected_model
        namedNode, thePoint, rawNode = picker.pick()
        if namedNode:
            if "_mesh" not in namedNode.getName():  # rough test to avoid printing infos on global zone mesh (ie: "freporte_mesh")
                name = namedNode.getName()
                p = namedNode.getParent()
                pos = p.getPos()
                selected_model = namedNode
                print namedNode.getName()
                print "Collision Point: ", thePoint

                namedNode.ls()
            else:
                print "Clicked location point (y, x, z):", thePoint
                #selected_model.setPos(thePoint.getX(), thePoint.getY(), thePoint.getZ())

                m.setPos(thePoint.getX(), thePoint.getY(), thePoint.getZ())
                print "Moved !"

    # Handles populating the zone with spawn data from the EQEmu DB
    # also makes each spawner model pickable
    def PopulateSpawns(self, cursor, numrows):
        spawn_coords = list()
        globals.model_list = list()
        for x in range(0, numrows):
            row = cursor.fetchone()
            point = Point3(long(row["Spawn2Y"]), long(row["Spawn2X"]), long(row["Spawn2Z"]))
            if point not in spawn_coords:
                s = loader.loadModel("models/cube.egg")
                s.reparentTo(render)
                s.setPos(row["Spawn2Y"], row["Spawn2X"], row["Spawn2Z"])
                min,macks= s.getTightBounds()
                radius = max([macks.getY() - min.getY(), macks.getX() - min.getX()])/2
                cs = CollisionSphere(row["Spawn2X"], row["Spawn2Y"], row["Spawn2Z"], radius)
                csNode = s.attachNewNode(CollisionNode("modelCollide"))
                csNode.node().addSolid(cs)
                s.setTag("name", row["name"])
                picker.makePickable(s)
                globals.model_list.append(s)
                spawn_coords.append(point)

    # Establishes a connection to the EQEmu database
    def ConnectToDatabase(self):
        configurator = Configurator(world)
        cfg = configurator.config
        conn = MySQLdb.Connection(
            host=cfg['host'],
            user=cfg['user'],
            passwd=cfg['password'],
            db=cfg['db'])

        return conn

    # Queries the Database in order to get spawn data
    # (this should be refactored at some point)
    def GetDbSpawnData(self, connection):
        cursor = connection.cursor(MySQLdb.cursors.DictCursor)

        query = """SELECT nt.name, s2.zone, s2.x as Spawn2X, s2.y as Spawn2Y, s2.z as Spawn2Z, sg.name as spawngroup_name,sg.id as Spawngroup_id, sg.min_x as Spawngroup_minX, sg.max_x as Spawngroup_maxX, sg.min_y as Spawngroup_minY, sg.max_y as Spawngroup_maxY, sg.dist as Spawngroup_dist, sg.mindelay as Spawngroup_mindelay,
                sg.delay as Spawngroup_delay FROM spawn2 s2
                JOIN spawngroup sg ON sg.id = s2.spawngroupid
                JOIN spawnentry se
                ON se.spawngroupid = sg.id
                JOIN npc_types nt
                ON nt.id = se.npcid
                WHERE s2.zone = 'freporte'"""
        cursor.execute(query)
        return cursor

    # Initializes the camera position upon startup
    def InitCameraPosition(self):
        world.campos = Point3(-155.6, 41.2, 4.9 + world.eyeHeight)
        world.camHeading = 270.0

        base.camera.setPos(world.campos)

    def GetCamera(self):
        return base.camera
Beispiel #23
0
    def __init__(self):
        ShowBase.__init__(self)
        """ SETUP CONFIG VARS  """
        # self.render.setShaderAuto()
        self.globalClock = ClockObject().getGlobalClock()
        self.bullet_world = BulletWorld()
        self.bullet_world.setGravity((0, 0, -9.81))

        """ PLAYER SETUP """
        # player camera
        self.ref_node = self.render.attachNewNode('camparent')

        self.debugNP = self.render.attachNewNode(BulletDebugNode('Debug'))
        self.debugNP.show()

        self.player_body_geom = make_cube_geom(geom_color=(1, 0, 0, 1))
        player_body_geom_node = GeomNode('player')
        player_body_geom_node.addGeom(self.player_body_geom)
        self.player_body_geom_np = self.render.attachNewNode(player_body_geom_node)

        # Box
        shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5))


        self.box_np = self.render.attachNewNode(BulletRigidBodyNode('Box'))
        self.box_np.node().setMass(1.0)
        self.box_np.node().addShape(shape)
        self.box_np.node().setDeactivationEnabled(False)
        self.player_body_geom_np.reparentTo(self.box_np)
        self.box_np.setPos(10, 10, 10)
        self.box_np.setCollideMask(BitMask32.allOn())
        self.bullet_world.attachRigidBody(self.box_np.node())


        # TODO: move player stuff to a new class
        # TODO: add cross hairs on player hud
        self.player_ray_end = NodePath('player-ray')
        self.player_ray_end.reparentTo(self.render)
        self.player_ray_end.reparentTo(self.ref_node)
        self.player_ray_end.setY(+10)  # put this in front of the player
        self.ref_node.lookAt(self.player_ray_end)

        """ SETUP VARS AND USE UTIL CLASSES """

        self.map_scale = 10
        self.map_size = 100
        self.camLens.setFov(90)
        total_size = 32 * 8

        PlayerMovement(self)
        World(self, n_grids=32)

        # self.ref_node.reparentTo(self.box_np)


        """ SKY BOX SETUP """

        skybox = GeomNode('skybox')
        skybox.addGeom(make_cube_geom(pos=(0, 0, 0), geom_color=(0.2, 0.2, 0.7, 1)))
        skybox_np = self.render.attachNewNode(skybox)
        skybox_np.reparentTo(self.ref_node)
        skybox_np.setPos((0, 1200, 0))
        skybox_np.setScale(1200)

        """ ADD LIGHTS """

        # ambient light
        ambientLight = AmbientLight('ambientLight')
        ambientLight.setColor((0.2, 0.2, 0.2, 1))
        ambientLightNP = self.render.attachNewNode(ambientLight)
        self.render.setLight(ambientLightNP)

        # a geom to represent the sun
        sun_geom_node = GeomNode('sun')
        sun_geom_node.addGeom(make_cube_geom(geom_color=(0.5, 0.5, 0.3, 1)))
        sun_geom_node_path = self.render.attachNewNode(sun_geom_node)
        sun_geom_node_path.setScale(10)

        # sun
        sun = PointLight('sun')
        sun.setColor((0.4, 0.3, 0.27, 1))
        sun.setAttenuation((0.1, 0, 0))
        sun_np = self.render.attachNewNode(sun)
        sun_geom_node_path.reparentTo(sun_np)
        self.render.setLight(sun_np)
        sun_np.setPos(total_size / 2, total_size / 2, 200)

        """ SETUP FOR ONSCREEN TEXT """

        # TODO: add chunk coords to display
        self.text = OnscreenText(text='fps', pos=(-1, -0.95), fg=(0, 1, 0, 1), align=TextNode.ALeft, scale=0.1)
        self.location_text = OnscreenText(text='location', pos=(-1, 0.8), fg=(0, 1, 0, 1), align=TextNode.ALeft,
                                          scale=0.1)
        self.previous_time = time.time()
        self.taskMgr.add(self.update_text, 'fps')
        self.taskMgr.add(self.update, 'physics')
class Player(GameObject):
    def __init__(self):
        GameObject.__init__(
            self, Vec3(0, 0, 0), "Models/PandaChan/act_p3d_chan", {
                "stand": "Models/PandaChan/a_p3d_chan_idle",
                "walk": "Models/PandaChan/a_p3d_chan_run"
            }, 5, 10, "player")
        self.actor.getChild(0).setH(180)

        mask = BitMask32()
        mask.setBit(1)

        self.collider.node().setIntoCollideMask(mask)

        mask = BitMask32()
        mask.setBit(1)

        self.collider.node().setFromCollideMask(mask)

        base.pusher.addCollider(self.collider, self.actor)
        base.cTrav.addCollider(self.collider, base.pusher)

        self.lastMousePos = Vec2(0, 0)

        self.groundPlane = Plane(Vec3(0, 0, 1), Vec3(0, 0, 0))

        self.ray = CollisionRay(0, 0, 0, 0, 1, 0)

        rayNode = CollisionNode("playerRay")
        rayNode.addSolid(self.ray)

        mask = BitMask32()

        mask.setBit(2)
        rayNode.setFromCollideMask(mask)

        mask = BitMask32()
        rayNode.setIntoCollideMask(mask)

        self.rayNodePath = render.attachNewNode(rayNode)
        self.rayQueue = CollisionHandlerQueue()

        base.cTrav.addCollider(self.rayNodePath, self.rayQueue)

        self.beamModel = loader.loadModel("Models/Misc/bambooLaser")
        self.beamModel.reparentTo(self.actor)
        self.beamModel.setZ(1.5)
        self.beamModel.setLightOff()
        self.beamModel.hide()

        self.beamHitModel = loader.loadModel("Models/Misc/bambooLaserHit")
        self.beamHitModel.reparentTo(render)
        self.beamHitModel.setZ(1.5)
        self.beamHitModel.setLightOff()
        self.beamHitModel.hide()

        self.beamHitPulseRate = 0.15
        self.beamHitTimer = 0

        self.damagePerSecond = -5.0

        self.score = 0

        self.scoreUI = OnscreenText(text="0",
                                    pos=(-1.3, 0.825),
                                    mayChange=True,
                                    align=TextNode.ALeft)

        self.healthIcons = []
        for i in range(self.maxHealth):
            icon = OnscreenImage(image="UI/health.png",
                                 pos=(-1.275 + i * 0.075, 0, 0.95),
                                 scale=0.04)
            icon.setTransparency(True)
            self.healthIcons.append(icon)

        self.damageTakenModel = loader.loadModel("Models/Misc/playerHit")
        self.damageTakenModel.setLightOff()
        self.damageTakenModel.setZ(1.0)
        self.damageTakenModel.reparentTo(self.actor)
        self.damageTakenModel.hide()

        self.damageTakenModelTimer = 0
        self.damageTakenModelDuration = 0.15

        self.laserSoundNoHit = loader.loadSfx("Sounds/laserNoHit.ogg")
        self.laserSoundNoHit.setLoop(True)
        self.laserSoundHit = loader.loadSfx("Sounds/laserHit.ogg")
        self.laserSoundHit.setLoop(True)

        self.beamHitLight = PointLight("beamHitLight")
        self.beamHitLight.setColor(Vec4(0.1, 1.0, 0.2, 1))
        self.beamHitLight.setAttenuation((1.0, 0.1, 0.5))
        self.beamHitLightNodePath = render.attachNewNode(self.beamHitLight)

        self.hurtSound = loader.loadSfx("Sounds/FemaleDmgNoise.ogg")

        self.yVector = Vec2(0, 1)

        self.actor.loop("stand")

    def update(self, keys, dt):
        GameObject.update(self, dt)

        self.walking = False

        if keys["up"]:
            self.walking = True
            self.velocity.addY(self.acceleration * dt)
        if keys["down"]:
            self.walking = True
            self.velocity.addY(-self.acceleration * dt)
        if keys["left"]:
            self.walking = True
            self.velocity.addX(-self.acceleration * dt)
        if keys["right"]:
            self.walking = True
            self.velocity.addX(self.acceleration * dt)

        if self.walking:
            standControl = self.actor.getAnimControl("stand")
            if standControl.isPlaying():
                standControl.stop()

            walkControl = self.actor.getAnimControl("walk")
            if not walkControl.isPlaying():
                self.actor.loop("walk")
        else:
            standControl = self.actor.getAnimControl("stand")
            if not standControl.isPlaying():
                self.actor.stop("walk")
                self.actor.loop("stand")

        mouseWatcher = base.mouseWatcherNode
        if mouseWatcher.hasMouse():
            mousePos = mouseWatcher.getMouse()
        else:
            mousePos = self.lastMousePos

        mousePos3D = Point3()
        nearPoint = Point3()
        farPoint = Point3()

        base.camLens.extrude(mousePos, nearPoint, farPoint)
        self.groundPlane.intersectsLine(
            mousePos3D, render.getRelativePoint(base.camera, nearPoint),
            render.getRelativePoint(base.camera, farPoint))

        firingVector = Vec3(mousePos3D - self.actor.getPos())
        firingVector2D = firingVector.getXy()
        firingVector2D.normalize()
        firingVector.normalize()

        heading = self.yVector.signedAngleDeg(firingVector2D)

        self.actor.setH(heading)

        self.beamHitTimer -= dt
        if self.beamHitTimer <= 0:
            self.beamHitTimer = self.beamHitPulseRate
            self.beamHitModel.setH(random.uniform(0.0, 360.0))
        self.beamHitModel.setScale(
            math.sin(self.beamHitTimer * 3.142 / self.beamHitPulseRate) * 0.4 +
            0.9)

        if keys["shoot"]:
            if self.rayQueue.getNumEntries() > 0:
                scoredHit = False

                self.rayQueue.sortEntries()
                rayHit = self.rayQueue.getEntry(0)
                hitPos = rayHit.getSurfacePoint(render)

                hitNodePath = rayHit.getIntoNodePath()
                if hitNodePath.hasPythonTag("owner"):
                    hitObject = hitNodePath.getPythonTag("owner")
                    if not isinstance(hitObject, TrapEnemy):
                        hitObject.alterHealth(self.damagePerSecond * dt)
                        scoredHit = True

                beamLength = (hitPos - self.actor.getPos()).length()
                self.beamModel.setSy(beamLength)

                self.beamModel.show()

                if scoredHit:
                    if self.laserSoundNoHit.status() == AudioSound.PLAYING:
                        self.laserSoundNoHit.stop()
                    if self.laserSoundHit.status() != AudioSound.PLAYING:
                        self.laserSoundHit.play()

                    self.beamHitModel.show()

                    self.beamHitModel.setPos(hitPos)
                    self.beamHitLightNodePath.setPos(hitPos + Vec3(0, 0, 0.5))

                    if not render.hasLight(self.beamHitLightNodePath):
                        render.setLight(self.beamHitLightNodePath)
                else:
                    if self.laserSoundHit.status() == AudioSound.PLAYING:
                        self.laserSoundHit.stop()
                    if self.laserSoundNoHit.status() != AudioSound.PLAYING:
                        self.laserSoundNoHit.play()

                    if render.hasLight(self.beamHitLightNodePath):
                        render.clearLight(self.beamHitLightNodePath)

                    self.beamHitModel.hide()
        else:
            if render.hasLight(self.beamHitLightNodePath):
                render.clearLight(self.beamHitLightNodePath)

            self.beamModel.hide()
            self.beamHitModel.hide()

            if self.laserSoundNoHit.status() == AudioSound.PLAYING:
                self.laserSoundNoHit.stop()
            if self.laserSoundHit.status() == AudioSound.PLAYING:
                self.laserSoundHit.stop()

        if firingVector.length() > 0.001:
            self.ray.setOrigin(self.actor.getPos())
            self.ray.setDirection(firingVector)

        self.lastMousePos = mousePos

        if self.damageTakenModelTimer > 0:
            self.damageTakenModelTimer -= dt
            self.damageTakenModel.setScale(2.0 - self.damageTakenModelTimer /
                                           self.damageTakenModelDuration)
            if self.damageTakenModelTimer <= 0:
                self.damageTakenModel.hide()

    def updateScore(self):
        self.scoreUI.setText(str(self.score))

    def alterHealth(self, dHealth):
        GameObject.alterHealth(self, dHealth)

        self.updateHealthUI()

        self.damageTakenModel.show()
        self.damageTakenModel.setH(random.uniform(0.0, 360.0))
        self.damageTakenModelTimer = self.damageTakenModelDuration

        self.hurtSound.play()

    def updateHealthUI(self):
        for index, icon in enumerate(self.healthIcons):
            if index < self.health:
                icon.show()
            else:
                icon.hide()

    def cleanup(self):
        self.scoreUI.removeNode()

        for icon in self.healthIcons:
            icon.removeNode()

        self.beamHitModel.removeNode()

        base.cTrav.removeCollider(self.rayNodePath)

        self.laserSoundHit.stop()
        self.laserSoundNoHit.stop()

        render.clearLight(self.beamHitLightNodePath)
        self.beamHitLightNodePath.removeNode()

        GameObject.cleanup(self)
Beispiel #25
0
    def loadLights(self):
        # Set a simple light
        dlight = DirectionalLight('DirectLight')
        dlnp = render.attachNewNode(dlight)
        dlnp.setHpr(-30, 0, 0)
        render.setLight(dlnp)
        self.directLight = dlnp

        self.discoLights = []

        p1 = PointLight("PointLight1")
        p1.setColor(VBase4(1, 0, 0, 1))
        p1.setAttenuation((0.08, 0, 0.05))
        p1np = render.attachNewNode(p1)
        p1np.setPos(0, -5, 0)
        render.setLight(p1np)
        self.discoLights.append(p1)

        p2 = PointLight("PointLight2")
        p2.setColor(VBase4(0, 1, 0, 1))
        p2.setAttenuation((0.08, 0, 0.05))
        p2np = render.attachNewNode(p2)
        p2np.setPos(5, -5, 0)
        render.setLight(p2np)
        self.discoLights.append(p2)

        p3 = PointLight("PointLight3")
        p3.setColor(VBase4(0, 0, 1, 1))
        p3.setAttenuation((0.08, 0, 0.05))
        p3np = render.attachNewNode(p3)
        p3np.setPos(-5, -5, 0)
        render.setLight(p3np)
        self.discoLights.append(p3)

        p4 = PointLight("PointLight4")
        p4.setColor(VBase4(0, 0, 1, 1))
        p4.setAttenuation((0.08, 0, 0.05))
        p4np = render.attachNewNode(p4)
        p4np.setPos(-5, -5, 5)
        render.setLight(p4np)
        self.discoLights.append(p4)

        p5 = PointLight("PointLight1")
        p5.setColor(VBase4(0, 0, 1, 1))
        p5.setAttenuation((0.08, 0, 0.05))
        p5np = render.attachNewNode(p5)
        p5np.setPos(0, -5, 5)
        render.setLight(p5np)
        self.discoLights.append(p5)

        p6 = PointLight("PointLight1")
        p6.setColor(VBase4(0, 0, 1, 1))
        p6.setAttenuation((0.08, 0, 0.05))
        p6np = render.attachNewNode(p6)
        p6np.setPos(5, -5, 5)
        render.setLight(p6np)
        self.discoLights.append(p6)
Beispiel #26
0
    def __init__(self):

        # Check video card capabilities.

        if (base.win.getGsg().getSupportsBasicShaders() == 0):
            addTitle("Bump Mapping: Video driver reports that shaders are not supported.")
            return

        # Post the instructions
        self.title = addTitle("Panda3D: Tutorial - Bump Mapping")
        self.inst1 = addInstructions(0.95, "Press ESC to exit")
        self.inst2 = addInstructions(0.90, "Move mouse to rotate camera")
        self.inst3 = addInstructions(0.85, "Left mouse button: Move forwards")
        self.inst4 = addInstructions(0.80, "Right mouse button: Move backwards")
        self.inst5 = addInstructions(0.75, "Enter: Turn bump maps Off")

        # Load the 'abstract room' model.  This is a model of an
        # empty room containing a pillar, a pyramid, and a bunch
        # of exaggeratedly bumpy textures.

        self.room = loader.loadModel("models/abstractroom")
        self.room.reparentTo(render)

        # Make the mouse invisible, turn off normal mouse controls
        base.disableMouse()
        props = WindowProperties()
        props.setCursorHidden(True)
        base.win.requestProperties(props)

        # Set the current viewing target
        self.focus = Vec3(55,-55,20)
        self.heading = 180
        self.pitch = 0
        self.mousex = 0
        self.mousey = 0
        self.last = 0
        self.mousebtn = [0,0,0]

        # Start the camera control task:
        taskMgr.add(self.controlCamera, "camera-task")
        self.accept("escape", sys.exit, [0])
        self.accept("mouse1", self.setMouseBtn, [0, 1])
        self.accept("mouse1-up", self.setMouseBtn, [0, 0])
        self.accept("mouse2", self.setMouseBtn, [1, 1])
        self.accept("mouse2-up", self.setMouseBtn, [1, 0])
        self.accept("mouse3", self.setMouseBtn, [2, 1])
        self.accept("mouse3-up", self.setMouseBtn, [2, 0])
        self.accept("enter", self.toggleShader)
        self.accept("j", self.rotateLight, [-1])
        self.accept("k", self.rotateLight, [1])
        self.accept("arrow_left", self.rotateCam, [-1])
        self.accept("arrow_right", self.rotateCam, [1])

        # Add a light to the scene.
        self.lightpivot = render.attachNewNode("lightpivot")
        self.lightpivot.setPos(0,0,25)
        self.lightpivot.hprInterval(10,Point3(360,0,0)).loop()
        plight = PointLight('plight')
        plight.setColor(Vec4(1, 1, 1, 1))
        plight.setAttenuation(Vec3(0.7,0.05,0))
        plnp = self.lightpivot.attachNewNode(plight)
        plnp.setPos(45, 0, 0)
        self.room.setLight(plnp)
        
        # Add an ambient light
        alight = AmbientLight('alight')
        alight.setColor(Vec4(0.2, 0.2, 0.2, 1))
        alnp = render.attachNewNode(alight)
        self.room.setLight(alnp)

        # create a sphere to denote the light
        sphere = loader.loadModel("models/sphere")
        sphere.reparentTo(plnp)

        # load and apply the shader.  This is using panda's
        # built-in shader generation capabilities to create the
        # shader for you.  However, if desired, you can supply
        # the shader manually.  Change this line of code to:
        #   self.room.setShaderInput("light", plnp)
        #   self.room.setShader(Shader.load("bumpMapper.sha"))
        self.room.setShaderAuto()

        self.shaderenable = 1
Beispiel #27
0
    def __init__(self):
        # Configure the parallax mapping settings (these are just the defaults)
        loadPrcFileData("", "parallax-mapping-samples 3\n"
                            "parallax-mapping-scale 0.1")

        # Initialize the ShowBase class from which we inherit, which will
        # create a window and set up everything we need for rendering into it.
        ShowBase.__init__(self)

        # Check video card capabilities.
        if not self.win.getGsg().getSupportsBasicShaders():
            addTitle("Bump Mapping: "
                "Video driver reports that Cg shaders are not supported.")
            return

        # Post the instructions
        self.title = addTitle("Panda3D: Tutorial - Bump Mapping")
        self.inst1 = addInstructions(0.06, "Press ESC to exit")
        self.inst2 = addInstructions(0.12, "Move mouse to rotate camera")
        self.inst3 = addInstructions(0.18, "Left mouse button: Move forwards")
        self.inst4 = addInstructions(0.24, "Right mouse button: Move backwards")
        self.inst5 = addInstructions(0.30, "Enter: Turn bump maps Off")

        # Load the 'abstract room' model.  This is a model of an
        # empty room containing a pillar, a pyramid, and a bunch
        # of exaggeratedly bumpy textures.

        self.room = loader.loadModel("models/abstractroom")
        self.room.reparentTo(render)

        # Make the mouse invisible, turn off normal mouse controls
        self.disableMouse()
        props = WindowProperties()
        props.setCursorHidden(True)
        self.win.requestProperties(props)
        self.camLens.setFov(60)

        # Set the current viewing target
        self.focus = LVector3(55, -55, 20)
        self.heading = 180
        self.pitch = 0
        self.mousex = 0
        self.mousey = 0
        self.last = 0
        self.mousebtn = [0, 0, 0]

        # Start the camera control task:
        taskMgr.add(self.controlCamera, "camera-task")
        self.accept("escape", sys.exit, [0])
        self.accept("mouse1", self.setMouseBtn, [0, 1])
        self.accept("mouse1-up", self.setMouseBtn, [0, 0])
        self.accept("mouse2", self.setMouseBtn, [1, 1])
        self.accept("mouse2-up", self.setMouseBtn, [1, 0])
        self.accept("mouse3", self.setMouseBtn, [2, 1])
        self.accept("mouse3-up", self.setMouseBtn, [2, 0])
        self.accept("enter", self.toggleShader)
        self.accept("j", self.rotateLight, [-1])
        self.accept("k", self.rotateLight, [1])
        self.accept("arrow_left", self.rotateCam, [-1])
        self.accept("arrow_right", self.rotateCam, [1])

        # Add a light to the scene.
        self.lightpivot = render.attachNewNode("lightpivot")
        self.lightpivot.setPos(0, 0, 25)
        self.lightpivot.hprInterval(10, LPoint3(360, 0, 0)).loop()
        plight = PointLight('plight')
        plight.setColor((1, 1, 1, 1))
        plight.setAttenuation(LVector3(0.7, 0.05, 0))
        plnp = self.lightpivot.attachNewNode(plight)
        plnp.setPos(45, 0, 0)
        self.room.setLight(plnp)

        # Add an ambient light
        alight = AmbientLight('alight')
        alight.setColor((0.2, 0.2, 0.2, 1))
        alnp = render.attachNewNode(alight)
        self.room.setLight(alnp)

        # Create a sphere to denote the light
        sphere = loader.loadModel("models/icosphere")
        sphere.reparentTo(plnp)

        # Tell Panda that it should generate shaders performing per-pixel
        # lighting for the room.
        self.room.setShaderAuto()

        self.shaderenable = 1
Beispiel #28
0
    def __init__(self, shipSpec):
        GameObject.__init__(self, Vec3(0, 0,
                                       0), None, None, shipSpec.maxShields,
                            shipSpec.maxSpeed, "player", MASK_INTO_PLAYER, 2)
        ArmedObject.__init__(self)

        self.acceleration = shipSpec.acceleration
        self.turnRate = shipSpec.turnRate

        self.numGuns = len(shipSpec.gunPositions)
        self.numMissiles = shipSpec.numMissiles
        self.maxEnergy = shipSpec.maxEnergy
        self.energyRechargeRate = shipSpec.energyRechargeRate
        self.shieldRechargeRate = shipSpec.shieldRechargeRate

        self.energy = shipSpec.maxEnergy

        for gunPos in shipSpec.gunPositions:
            np = self.actor.attachNewNode(PandaNode("gun node"))
            np.setPos(gunPos)

            gun = BlasterWeapon()
            self.addWeapon(gun, 0, np)

        missileSetCounter = 1
        for missilePos in shipSpec.missilePositions:
            np = self.actor.attachNewNode(PandaNode("missile node"))
            np.setPos(missilePos)

            gun = RocketWeapon()
            self.addWeapon(gun, missileSetCounter, np)
            missileSetCounter += 1

        self.numMissileSets = missileSetCounter - 1
        self.missileSetIndex = 0

        light = PointLight("basic light")
        light.setColor(Vec4(1, 1, 1, 1))
        light.setAttenuation((1, 0.01, 0.001))
        self.lightNP = self.root.attachNewNode(light)
        self.lightNP.setZ(1)
        Common.framework.showBase.render.setLight(self.lightNP)

        self.colliderNP.node().setFromCollideMask(MASK_WALLS
                                                  | MASK_FROM_PLAYER)

        Common.framework.pusher.addCollider(self.colliderNP, self.root)
        Common.framework.traverser.addCollider(self.colliderNP,
                                               Common.framework.pusher)

        Common.framework.showBase.camera.reparentTo(self.actor)
        Common.framework.showBase.camera.setPos(0, 0, 0)
        Common.framework.showBase.camera.setHpr(0, 0, 0)

        lens = Common.framework.showBase.camLens

        lens.setNear(0.03)

        ratio = lens.getAspectRatio()

        lens.setFov(75 * ratio)

        self.lastMousePos = Vec2(0, 0)
        self.mouseSpeedHori = 50.0
        self.mouseSpeedVert = 30.0
        self.mouseSensitivity = 1.0

        self.targetingRay = CollisionSegment(0, 0, 0, 0, 100, 0)
        self.targetingRayNode = CollisionNode("lock ray")
        self.targetingRayNode.addSolid(self.targetingRay)
        self.targetingRayNode.setFromCollideMask(MASK_ENEMY_LOCK_SPHERE)
        self.targetingRayNode.setIntoCollideMask(0)
        self.targetingRayNP = self.actor.attachNewNode(self.targetingRayNode)
        self.targetingQueue = CollisionHandlerQueue()

        self.prospectiveLockTarget = None
        self.lockTargetTimer = 0
        self.lockDuration = 1

        Common.framework.traverser.addCollider(self.targetingRayNP,
                                               self.targetingQueue)

        #rayNodePath.show()

        self.uiRoot = aspect2d.attachNewNode(PandaNode("player UI"))

        cardMaker = CardMaker("UI maker")
        cardMaker.setFrame(-1, 1, -1, 1)

        self.centreSpot = self.uiRoot.attachNewNode(cardMaker.generate())
        self.centreSpot.setTexture(
            Common.framework.showBase.loader.loadTexture(
                "../Section2SpaceflightDocking/UI/spot.png"))
        self.centreSpot.setTransparency(True)
        self.centreSpot.setPos(0, 0, 0)
        self.centreSpot.setScale(0.01)
        self.centreSpot.setAlphaScale(0.5)

        self.directionIndicator = self.uiRoot.attachNewNode(
            cardMaker.generate())
        self.directionIndicator.setTexture(
            Common.framework.showBase.loader.loadTexture(
                "../Section2SpaceflightDocking/UI/directionIndicator.png"))
        self.directionIndicator.setTransparency(True)
        self.directionIndicator.setScale(0.05)
        self.directionIndicator.hide()

        self.lockMarkerRoot = self.uiRoot.attachNewNode(
            PandaNode("lock marker root"))
        for i in range(4):
            markerRotationNP = self.lockMarkerRoot.attachNewNode(
                PandaNode("lock marker rotation"))
            marker = markerRotationNP.attachNewNode(cardMaker.generate())
            marker.setTexture(
                Common.framework.showBase.loader.loadTexture(
                    "../Section2SpaceflightDocking/UI/lockMarker.png"))
            marker.setTransparency(True)
            markerRotationNP.setScale(0.04)
            markerRotationNP.setR(i * 90)
        self.lockMarkerRoot.hide()

        self.lockBar = Common.framework.showBase.loader.loadModel(
            "../Section2SpaceflightDocking/UI/uiLockBar")
        self.lockBar.reparentTo(self.uiRoot)
        self.lockBar.setScale(0.15)
        #self.lockBar.hide()

        cardMaker.setFrame(-1, 1, 0, 1)

        self.cockpit = Common.framework.showBase.loader.loadModel(
            "../Section2SpaceflightDocking/Models/{0}".format(
                shipSpec.cockpitModelFile))
        self.cockpit.reparentTo(self.actor)

        healthBarRoot = self.cockpit.find("**/healthBar")
        if healthBarRoot is None or healthBarRoot.isEmpty():
            healthBarRoot = self.uiRoot.attachNewNode(
                PandaNode("health bar root"))
            print("No health bar root found!")

        energyBarRoot = self.cockpit.find("**/energyBar")
        if energyBarRoot is None or energyBarRoot.isEmpty():
            energyBarRoot = self.uiRoot.attachNewNode(
                PandaNode("energy bar root"))
            print("No energy bar root found!")

        missileCounterRoot = self.cockpit.find("**/missileCounter")
        if missileCounterRoot is None or missileCounterRoot.isEmpty():
            missileCounterRoot = self.uiRoot.attachNewNode(
                PandaNode("missile counter root"))
            print("No missile counter root found!")

        radarRoot = self.cockpit.find("**/radar")
        if radarRoot is None or radarRoot.isEmpty():
            radarRoot = self.uiRoot.attachNewNode(PandaNode("radar root"))
            print("No radar root found!")

        speedometerRoot = self.cockpit.find("**/speedometer")
        if speedometerRoot is None or speedometerRoot.isEmpty():
            speedometerRoot = self.uiRoot.attachNewNode(
                PandaNode("speedometer root"))
            print("No speedometer root found!")

        self.radarDrawer = MeshDrawer()
        self.radarDrawer.setBudget(4096)

        self.radarDrawerNP = self.radarDrawer.getRoot()
        self.radarDrawerNP.reparentTo(radarRoot)
        self.radarDrawerNP.setTwoSided(True)
        self.radarDrawerNP.setLightOff()
        self.radarDrawerNP.setDepthWrite(False)
        self.radarDrawerNP.setTransparency(True)

        self.healthBar = healthBarRoot.attachNewNode(cardMaker.generate())
        self.healthBar.setSx(0.05)

        self.energyBar = energyBarRoot.attachNewNode(cardMaker.generate())
        self.energyBar.setSx(0.05)

        self.healthBarScalar = 0.00175
        self.energyBarScalar = 0.00175

        self.missileCounter = DirectLabel(text="",
                                          text_mayChange=True,
                                          scale=0.09,
                                          relief=None,
                                          parent=missileCounterRoot)

        self.maxRadarRange = 700
        self.radarSize = 0.3

        self.speedometer = DirectLabel(text="",
                                       text_mayChange=True,
                                       scale=0.09,
                                       relief=None,
                                       parent=speedometerRoot)

        self.updateHealthUI()
        self.updateEnergyUI()
        self.updateMissileUI()
        self.updateRadar()
        self.updateSpeedometer()

        self.updatingEffects = []
Beispiel #29
0
class World(DirectObject):
    cfg = None
    def __init__(self):
        self.last_mousex = 0
        self.last_mousey = 0

        self.zone = None
        self.zone_reload_name = None
        
        self.winprops = WindowProperties( )

        # simple console output
        self.consoleNode = NodePath(PandaNode("console_root"))
        self.consoleNode.reparentTo(aspect2d)

        self.console_num_lines = 24
        self.console_cur_line = -1
        self.console_lines = []
        for i in range(0, self.console_num_lines):
            self.console_lines.append(OnscreenText(text='', style=1, fg=(1,1,1,1),
                        pos=(-1.3, .4-i*.05), align=TextNode.ALeft, scale = .035, parent = self.consoleNode))

        # Configuration
        self.consoleOut('World Forge v.%s loading configuration' % VERSION)
        self.configurator = Configurator(self)
        cfg = self.configurator.config
        resaveRes = False
        if 'xres' in cfg:
            self.xres = int(cfg['xres'])
        else:
            self.xres = 1024
            resaveRes = True

        if 'yres' in cfg:
            self.yres = int(cfg['yres'])
        else:
            self.yres = 768
            resaveRes = True

        if resaveRes:
            self.saveDefaultRes()

        self.xres_half = self.xres / 2
        self.yres_half = self.yres / 2
        self.mouse_accum = MouseAccume( lambda: (self.xres_half,self.yres_half))

        self.eyeHeight = 7.0
        self.rSpeed = 80
        self.flyMode = 1

        # application window setup
        base.win.setClearColor(Vec4(0,0,0,1))
        self.winprops.setTitle( 'World Forge')
        self.winprops.setSize(self.xres, self.yres) 
        
        base.win.requestProperties( self.winprops ) 
        base.disableMouse()
        
        # Post the instructions
        self.title = addTitle('World Forge v.' + VERSION)
        self.inst0 = addInstructions(0.95, "[FLYMODE][1]")
        self.inst1 = addInstructions(-0.95, "Camera control with WSAD/mouselook. Press K for hotkey list, ESC to exit.")
        self.inst2 = addInstructions(0.9,  "Loc:")
        self.inst3 = addInstructions(0.85, "Hdg:")
        self.error_inst = addInstructions(0, '')
        self.kh = []
        
        self.campos = Point3(155.6, 41.2, 4.93)
        base.camera.setPos(self.campos)
        
        # Accept the application control keys: currently just esc to exit navgen       
        self.accept("escape", self.exitGame)
        self.accept("window-event", self.resizeGame)
        
        # Create some lighting
        ambient_level = .6
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor(Vec4(ambient_level, ambient_level, ambient_level, 1.0))
        render.setLight(render.attachNewNode(ambientLight))

        direct_level = 0.8
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection(Vec3(0.0, 0.0, -1.0))
        directionalLight.setColor(Vec4(direct_level, direct_level, direct_level, 1))
        directionalLight.setSpecularColor(Vec4(direct_level, direct_level, direct_level, 1))
        render.setLight(render.attachNewNode(directionalLight))
        
        # create a point light that will follow our view point (the camera for now)
        # attenuation is set so that this point light has a torch like effect
        self.plight = PointLight('plight')
        self.plight.setColor(VBase4(0.8, 0.8, 0.8, 1.0))
        self.plight.setAttenuation(Point3(0.0, 0.0, 0.0002))
        
        self.plnp = base.camera.attachNewNode(self.plight)
        self.plnp.setPos(0, 0, 0)
        render.setLight(self.plnp)
        self.cam_light = 1
        
        self.keyMap = {"left":0, "right":0, "forward":0, "backward":0, "cam-left":0, \
            "cam-right":0, "mouse3":0, "flymode":1 }

        # setup FOG
        self.fog_colour = (0.8,0.8,0.8,1.0)
        self.linfog = Fog("A linear-mode Fog node")
        self.linfog.setColor(self.fog_colour)
        self.linfog.setLinearRange(700, 980)         # onset, opaque distances as params
        # linfog.setLinearFallback(45,160,320)
        base.camera.attachNewNode(self.linfog)
        render.setFog(self.linfog)
        self.fog = 1
        
        # camera control
        self.campos = Point3(0, 0, 0)
        self.camHeading = 0.0
        self.camPitch = 0.0
        base.camLens.setFov(65.0)
        base.camLens.setFar(1200) 
        
        self.cam_speed = 0  # index into self.camp_speeds
        self.cam_speeds = [40.0, 80.0, 160.0, 320.0, 640.0]
        
        
        # Collision Detection for "WALKMODE"
        # We will detect the height of the terrain by creating a collision
        # ray and casting it downward toward the terrain.  The ray 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.camGroundRay = CollisionRay()
        self.camGroundRay.setOrigin(0.0, 0.0, 0.0)
        self.camGroundRay.setDirection(0,0,-1)      # straight down
        self.camGroundCol = CollisionNode('camRay')
        self.camGroundCol.addSolid(self.camGroundRay)
        self.camGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.camGroundCol.setIntoCollideMask(BitMask32.allOff())
        
        # attach the col node to the camCollider dummy node
        self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol)  
        self.camGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)
        
        
        # Uncomment this line to see the collision rays
        # self.camGroundColNp.show()
       
        # Uncomment this line to show a visual representation of the 
        # collisions occuring
        # self.cTrav.showCollisions(render)
        
        # Add the spinCameraTask procedure to the task manager.
        # taskMgr.add(self.spinCameraTask, "SpinCameraTask")
        globals.hasClickedSpawn = False;
        globals.hasClickedGrid = False;
        taskMgr.add(self.camTask, "camTask")

        self.toggleControls(1)

        # need to step the task manager once to make our fake console work
        taskMgr.step()

    # CONSOLE ---------------------------------------------------------------------
    def consoleScroll(self):
        for i in range(0, self.console_num_lines-1):
            self.console_lines[i].setText(self.console_lines[i+1].getText())
            
    def consoleOut(self, text):
        print text  # output to stdout/log too

        if self.console_cur_line == self.console_num_lines-1:
            self.consoleScroll()
        elif self.console_cur_line < self.console_num_lines-1:
            self.console_cur_line += 1

        self.console_lines[self.console_cur_line].setText(text)

        taskMgr.step()
    
    def consoleOn(self):
        self.consoleNode.show()
        
    def consoleOff(self):
        self.consoleNode.hide()
        
    # User controls -----------------------------------------------------------
    def toggleControls(self, on):

        cfg = self.configurator.config

        if on == 1:
            self.accept("escape", self.exitGame)

            self.accept("1", self.setSpeed, ["speed", 0])
            self.accept("2", self.setSpeed, ["speed", 1])
            self.accept("3", self.setSpeed, ["speed", 2])
            self.accept("4", self.setSpeed, ["speed", 3])
            self.accept("5", self.setSpeed, ["speed", 4])

            self.accept("alt-f", self.fogToggle)

            self.accept(cfg['control_lighting'], self.camLightToggle)
            self.accept(cfg['control_help'], self.displayKeyHelp)
            self.accept(cfg['control_flymode'], self.toggleFlymode)
            self.accept(cfg['control_reload-zone'], self.reloadZone)
            self.accept(cfg['control_cam-left'], self.setKey, ["cam-left",1])
            self.accept(cfg['control_cam-right'], self.setKey, ["cam-right",1])
            self.accept(cfg['control_forward'], self.setKey, ["forward",1])
            self.accept("mouse3", self.setKey, ["mouse3",1])
            self.accept(cfg['control_backward'], self.setKey, ["backward",1])
        
            self.accept("k-up", self.hideKeyHelp)
            self.accept(cfg['control_cam-left']+"-up", self.setKey, ["cam-left",0])
            self.accept(cfg['control_cam-right']+"-up", self.setKey, ["cam-right",0])
            self.accept(cfg['control_forward']+"-up", self.setKey, ["forward",0])
            self.accept("mouse3-up", self.setKey, ["mouse3",0])
            self.accept(cfg['control_backward']+"-up", self.setKey, ["backward",0])
            self.accept(cfg['toggle_edit-mode'], self.toggleEditMode)
            self.accept(cfg['toggle_insert-mode'], self.toggleInsertMode)
            self.accept(cfg['toggle_explore-mode'], self.toggleExploreMode)
            self.accept(cfg['toggle_grid-mode'], self.toggleGridMode)
            # Accept both single-presses and long presses for rotating models
            self.accept(cfg['rotate-right'] + "-repeat", self.rotateModelRight)
            self.accept(cfg['rotate-left'] + "-repeat", self.rotateModelLeft)
            self.accept(cfg['rotate-right'], self.rotateModelRight)
            self.accept(cfg['rotate-left'], self.rotateModelLeft)
            self.accept(cfg['clear-selection'], self.clearSelection)
        else:
            messenger.clear()

    def rotateModelRight(self):
        if globals.editMode == True:
            if globals.selectedSpawn:
                cfg = self.configurator.config
                globals.selectedSpawn.model.setH(globals.selectedSpawn.model.getH() + int(cfg['rotation-amount']))
                # Really not sure about that...
                if globals.selectedSpawn.model.getH() > 360:
                    globals.selectedSpawn.model.setH(0)
                print globals.selectedSpawn.model.getH()
                globals.selectedSpawn.setheadingfromworld(globals.selectedSpawn.model.getH())
                globals.spawndialog.m_spawnEntryHeadingTextCtrl.SetValue(str(globals.selectedSpawn.spawnentry_heading))
                if globals.config['autosave_edit-mode'] == 'True':
                    globals.database.UpdateSpawn(globals.selectedSpawn)
                print globals.selectedSpawn.spawnentry_heading

    def rotateModelLeft(self):
        if globals.editMode == True:
            if globals.selectedSpawn:
                cfg = self.configurator.config
                globals.selectedSpawn.model.setH(globals.selectedSpawn.model.getH() - int(cfg['rotation-amount']))
                # Really not sure about that either...
                if globals.selectedSpawn.model.getH() < -360:
                    globals.selectedSpawn.model.setH(0)
                print globals.selectedSpawn.model.getH()
                globals.selectedSpawn.setheadingfromworld(globals.selectedSpawn.model.getH())
                globals.spawndialog.m_spawnEntryHeadingTextCtrl.SetValue(str(globals.selectedSpawn.spawnentry_heading))
                if globals.config['autosave_edit-mode'] == 'True':
                    globals.database.UpdateSpawn(globals.selectedSpawn)
                print globals.selectedSpawn.spawnentry_heading

    def clearSelection(self, eraseNpcId = True):
        globals.selectedspawn = None
        globals.selectedgrid = None
        globals.picker.lastSelectedObject = None
        if self.inst6:
            self.inst6.destroy()
        self.inst6 = addInstructions(0.7, "Current selection: None")
        npcid = globals.spawndialog.m_spawnEntryNpcIdTextCtrl.Value
        globals.spawndialog.Reset()
        # f*****g hacky shit man
        if eraseNpcId == False:
            globals.spawndialog.m_spawnEntryNpcIdTextCtrl.SetValue(npcid)
        gridmanager = GridpointManager()
        gridmanager.ResetGridList()
        print "Cleared all selections !"

    def toggleDefaultMode(self):
        globals.editMode = False
        globals.insertMode = False
        globals.exploreMode = True
        globals.gridMode = False
        print "STARTUP Explore mode ACTIVATED"
        print "STARTUP Grid mode DEACTIVATED"
        self.inst4 = addInstructions(0.8, "Explore mode ON")
        self.inst5 = addInstructions(0.75, "Grid mode OFF")
        self.inst6 = addInstructions(0.7, "Current selection: None")

    def toggleEditMode(self):
        globals.editMode = True
        globals.insertMode = False
        globals.exploreMode = False
        print "Edit mode ACTIVATED"
        if self.inst4:
            self.inst4.destroy()
        self.inst4 = addInstructions(0.8, "Edit mode ON")

    def toggleInsertMode(self):
        globals.editMode = False
        globals.insertMode = True
        globals.exploreMode = False
        print "Insert mode ACTIVATED"
        if self.inst4:
            self.inst4.destroy()
        self.inst4 = addInstructions(0.8, "Insert mode ON")

    def toggleExploreMode(self):
        globals.editMode = False
        globals.insertMode = False
        globals.exploreMode = True
        print "Explore mode ACTIVATED"
        if self.inst4:
            self.inst4.destroy()
        self.inst4 = addInstructions(0.8, "Explore mode ON")

    def toggleGridMode(self):
        if globals.gridMode == False:
            globals.gridMode = True
            print "Grid mode ACTIVATED"
            if self.inst5:
                self.inst5.destroy()
            self.inst5 = addInstructions(0.75, "Grid mode ON")
        else:
            globals.gridMode = False
            print "Grid mode DEACTIVATED"
            if self.inst5:
                self.inst5.destroy()
            self.inst5 = addInstructions(0.75, "Grid mode OFF")

    def setSpeed(self, key, value):
        self.cam_speed = value
        self.setFlymodeText()
        
    def fogToggle(self):
        if self.fog == 1:
            render.clearFog()
            base.camLens.setFar(100000) 
            self.fog = 0
        else:
            render.setFog(self.linfog)
            base.camLens.setFar(1200) 
            self.fog = 1
            
    def camLightToggle(self):
        if self.cam_light == 0:
            render.setLight(self.plnp)
            self.cam_light = 1
        else:
            render.clearLight(self.plnp)
            self.cam_light = 0
        
    def displayKeyHelp(self):
        self.kh = []
        msg = 'HOTKEYS:'
        pos = 0.75
        self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(-0.5, pos), align=TextNode.ALeft, scale = .04))
        msg = '------------------'
        pos -= 0.05
        self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(-0.5, pos), align=TextNode.ALeft, scale = .04))
        msg = 'W: camera fwd, S: camera bck, A: rotate view left, D: rotate view right'
        pos -= 0.05
        self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(-0.5, pos), align=TextNode.ALeft, scale = .04))
        msg = '1-5: set camera movement speed'
        pos -= 0.05
        self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(-0.5, pos), align=TextNode.ALeft, scale = .04))
        msg = 'F: toggle Flymode/Walkmode'
        pos -= 0.05
        self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(-0.5, pos), align=TextNode.ALeft, scale = .04))
        msg = 'L: load a zone'
        pos -= 0.05
        self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(-0.5, pos), align=TextNode.ALeft, scale = .04))
        msg = 'ALT-F: toggle FOG and FAR plane on/off'
        pos -= 0.05
        self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(-0.5, pos), align=TextNode.ALeft, scale = .04))
        msg = 'T: toggle additional camera "torch" light on/off'
        pos -= 0.05
        self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(-0.5, pos), align=TextNode.ALeft, scale = .04))
        msg = 'Z: set currently loaded zone as new startup default'
        pos -= 0.05
        self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(-0.5, pos), align=TextNode.ALeft, scale = .04))
        msg = 'ESC: exit World Forge'
        pos -= 0.05
        self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(-0.5, pos), align=TextNode.ALeft, scale = .04))
     
    def hideKeyHelp(self):
        for n in self.kh:
            n.removeNode()
                        
    def setFlymodeText(self):
        zname = ''
        if self.zone:
            zname = self.zone.name
            
        if self.flyMode == 0:
            self.inst0.setText("[WALKMODE][%i] %s" % (self.cam_speed+1, zname))
        else:
            self.inst0.setText("[FLYMODE][%i] %s " % (self.cam_speed+1, zname))
        
    def toggleFlymode(self):
        zname = ''
        if self.zone:
            zname = self.zone.name

        if self.flyMode == 0:
            self.flyMode = 1
        else:
            self.flyMode = 0
            
        self.setFlymodeText()

    # Define a procedure to move the camera.
    def spinCameraTask(self, task):
        angleDegrees = task.time * 6.0
        angleRadians = angleDegrees * (pi / 180.0)
        base.camera.setPos(20 * sin(angleRadians), -20.0 * cos(angleRadians), 3)
        base.camera.setHpr(angleDegrees, 0, 0)
        return task.cont


    def camTask(self, task):
        if globals.hasClickedSpawn:
           base.camera.setPos(globals.selectedSpawnPoint3D)
           self.campos = globals.selectedSpawnPoint3D
           globals.hasClickedSpawn = False
        elif globals.hasClickedGrid:
            base.camera.setPos(globals.selectedGridPoint3D)
            self.campos = globals.selectedGridPoint3D
            globals.hasClickedGrid = False
        else:
            # query the mouse
            mouse_dx = 0
            mouse_dy = 0


            # if we have a mouse and the right button is depressed
            if base.mouseWatcherNode.hasMouse():
                if self.keyMap["mouse3"] != 0:
                    self.mouse_accum.update()
                else:
                    self.mouse_accum.reset()

            mouse_dx = self.mouse_accum.dx
            mouse_dy = self.mouse_accum.dy

            self.rXSpeed = fabs(self.mouse_accum.dx) * (self.cam_speed+1) * max(5 * 1000/self.xres,3)
            self.rYSpeed = fabs(self.mouse_accum.dy) * (self.cam_speed+1) * max(3 * 1000/self.yres,1)
            
            if (self.keyMap["cam-left"]!=0 or mouse_dx < 0):
                if self.rSpeed < 160:
                    self.rSpeed += 80 * globalClock.getDt()

                if mouse_dx != 0:
                    self.camHeading += self.rXSpeed * globalClock.getDt()
                else:
                    self.camHeading += self.rSpeed * globalClock.getDt()

                if self.camHeading > 360.0:
                    self.camHeading = self.camHeading - 360.0
            elif (self.keyMap["cam-right"]!=0 or mouse_dx > 0):
                if self.rSpeed < 160:
                    self.rSpeed += 80 * globalClock.getDt()

                if mouse_dx != 0:
                    self.camHeading -= self.rXSpeed * globalClock.getDt()
                else:
                    self.camHeading -= self.rSpeed * globalClock.getDt()

                if self.camHeading < 0.0:
                    self.camHeading = self.camHeading + 360.0
            else:
                self.rSpeed = 80

            if mouse_dy > 0:
                self.camPitch += self.rYSpeed * globalClock.getDt()
            elif mouse_dy < 0:
                self.camPitch -= self.rYSpeed * globalClock.getDt()
            
            # set camera heading and pitch
            base.camera.setHpr(self.camHeading, self.camPitch, 0)

            # viewer position (camera) movement control
            v = render.getRelativeVector(base.camera, Vec3.forward())
            if not self.flyMode:
                v.setZ(0.0)
        
            move_speed = self.cam_speeds[self.cam_speed]
            if self.keyMap["forward"] == 1:
                self.campos += v * move_speed * globalClock.getDt()
            if self.keyMap["backward"] == 1:
                self.campos -= v * move_speed * globalClock.getDt()            

            # actually move the camera
            lastPos = base.camera.getPos()
            base.camera.setPos(self.campos)
            # self.plnp.setPos(self.campos)      # move the point light with the viewer position

            # WALKMODE: simple collision detection
            # we simply check a ray from slightly below the "eye point" straight down
            # for geometry collisions and if there are any we detect the point of collision
            # and adjust the camera's Z accordingly
            if self.flyMode == 0:   
                # move the camera to where it would be if it made the move 
                # the colliderNode moves with it
                # base.camera.setPos(self.campos)
                # check for collissons
                self.cTrav.traverse(render)
                entries = []
                for i in range(self.camGroundHandler.getNumEntries()):
                    entry = self.camGroundHandler.getEntry(i)
                    entries.append(entry)
                    # print 'collision'
                entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                             x.getSurfacePoint(render).getZ()))
                                     
                if (len(entries) > 0): # and (entries[0].getIntoNode().getName() == "terrain"):
                    # print len(entries)
                    self.campos.setZ(entries[0].getSurfacePoint(render).getZ()+self.eyeHeight)
                else:
                    self.campos = lastPos
                    base.camera.setPos(self.campos)
        
                #if (base.camera.getZ() < self.player.getZ() + 2.0):
                #    base.camera.setZ(self.player.getZ() + 2.0)


            # update loc and hpr display
            pos = base.camera.getPos()
            hpr = base.camera.getHpr()
            self.inst2.setText('Loc: %.2f, %.2f, %.2f' % (pos.getX(), pos.getY(), pos.getZ()))
            self.inst3.setText('Hdg: %.2f, %.2f, %.2f' % (hpr.getX(), hpr.getY(), hpr.getZ()))
        return task.cont

    def exitGame(self):
        globals.database.conn.close()
        print "DB connection closed !"
        sys.exit(0)

    def resizeGame(self,win):
        props = base.win.getProperties() 
        self.xres = props.getXSize()
        self.yres = props.getYSize()
        self.xres_half = self.xres / 2
        self.yres_half = self.yres / 2
        self.saveDefaultRes()
                
    #Records the state of the arrow keys
    # this is used for camera control
    def setKey(self, key, value):
        self.keyMap[key] = value

    # -------------------------------------------------------------------------
    # this is the mythical MAIN LOOP :)
    def update(self):

        if self.zone_reload_name != None:
            self.doReload(self.zone_reload_name)
            self.zone_reload_name = None

        if self.zone != None:
            self.zone.update()

        taskMgr.step()
        
        
    # ZONE loading ------------------------------------------------------------
    
    # general zone loader driver
    # removes existing zone (if any) and load the new one 
    def loadZone(self, name, path):
        if path[len(path)-1] != '/':
            path += '/'

        if self.zone:
            self.zone.rootNode.removeNode()
            
        self.zone = Zone(self, name, path)
        error = self.zone.load()
        if error == 0:
            self.consoleOff()
            self.setFlymodeText()
            base.setBackgroundColor(self.fog_colour)
        
    def saveDefaultRes(self):
        cfg = self.configurator.config
        cfg['xres'] = str(self.xres)
        cfg['yres'] = str(self.yres)

    # initial world load after bootup
    def load(self):       
        cfg = self.configurator.config
            
        zone_name = cfg['default_zone']
        globals.currentZone = zone_name
        basepath = cfg['basepath']
        self.loadZone(zone_name, basepath)

    # zone reload user interface
    
    # this gets called from our update loop when it detects that zone_reload_name has been set
    # we do this in this convoluted fashion in order to keep the main loop taskMgr updates ticking
    # because otherwise our status console output at various stages during the zone load would not
    # be displayed. Yes, this is hacky.
    def doReload(self, name):
        cfg = self.configurator.config
        basepath = cfg['basepath']
        self.loadZone(name, basepath)

    # form dialog callback
    # this gets called from the form when the user has entered a something
    # (hopefully a correct zone short name)
    def reloadZoneDialogCB(self, name):
        self.frmDialog.end()
        self.zone_reload_name = name
        self.toggleControls(1)

    # this is called when the user presses "l"
    # it disables normal controls and fires up our query form dialog
    def reloadZone(self):
        base.setBackgroundColor((0,0,0))
        self.toggleControls(0)
        self.consoleOn()
        self.frmDialog = FileDialog(
            "Please enter the shortname of the zone you wish to load:", 
            "Examples: qrg, blackburrow, freportn, crushbone etc.",
            self.reloadZoneDialogCB) 
        
        self.frmDialog.activate()   # relies on the main update loop to run

    #####################################
    # Custom methods
    #####################################


    # Handles populating the zone with spawn data from the EQEmu DB
    # also makes each spawner model pickable
    def PopulateSpawns(self, cursor, numrows):
        spawn_coords = list()
        globals.spawn_list = list()
        cfg = self.configurator.config
        for x in range(0, numrows):
            row = cursor.fetchone()
            point = Point3(long(row["Spawn2Y"]), long(row["Spawn2X"]), long(row["Spawn2Z"]))
            if cfg['ignore_duplicate_spawns'] == 'True':
                if point not in spawn_coords:
                    self.PlaceSpawnPointOn3dMap(row)
                    spawn_coords.append(point)
            else:
                self.PlaceSpawnPointOn3dMap(row)

    def PlaceSpawnPointOn3dMap(self, row):
        spawn = Spawn()
        self.InitSpawnData(spawn, row)
        spawn.model = loader.loadModel(spawn.modelname)
        spawn.initmodel()
        spawn.model.reparentTo(render)
        spawn.initheadingfromdb(row["Spawn2Heading"])
        spawn.placeintoworld(row["Spawn2Y"], row["Spawn2X"], row["Spawn2Z"])
        min, macks = spawn.model.getTightBounds()
        radius = max([macks.getY() - min.getY(), macks.getX() - min.getX()]) / 2
        cs = CollisionSphere(row["Spawn2X"], row["Spawn2Y"], row["Spawn2Z"], radius)
        csNode = spawn.model.attachNewNode(CollisionNode("modelCollide"))
        csNode.node().addSolid(cs)
        # TODO: ADD MORE TAGS??
        spawn.model.setTag("name", row["NpcName"])
        spawn.model.setTag("spawngroup_name", row["spawngroup_name"])
        spawn.model.setTag("spawn2id", str(row["Spawn2Id"]))
        spawn.model.setTag("type", "spawn")
        globals.picker.makePickable(spawn.model)
        globals.spawn_list.append(spawn)


    # Initializes a spawn object with database values
    def InitSpawnData(self, spawn, row):
        spawn.spawngroup_id = row["Spawngroup_id"]
        spawn.spawngroup_name = row["spawngroup_name"]
        spawn.spawngroup_minx = row["Spawngroup_minX"]
        spawn.spawngroup_maxx= row["Spawngroup_maxX"]
        spawn.spawngroup_miny = row["Spawngroup_minY"]
        spawn.spawngroup_maxy = row["Spawngroup_maxY"]
        spawn.spawngroup_dist = row["Spawngroup_dist"]
        spawn.spawngroup_mindelay = row["Spawngroup_mindelay"]
        spawn.spawngroup_delay = row["Spawngroup_delay"]
        spawn.spawngroup_despawn = row["Spawngroup_despawntimer"]
        spawn.spawngroup_despawntimer = row["Spawngroup_despawntimer"]
        spawn.spawngroup_spawnlimit = row["Spawngroup_spawnlimit"]


        spawn.spawnentry_id = row["Spawn2Id"]
        spawn.spawnentry_npcid = row["NpcId"]
        spawn.spawnentry_npcname = row["NpcName"]
        spawn.spawnentry_chance = row["Spawnentry_chance"]
        spawn.spawnentry_x = row["Spawn2X"]
        spawn.spawnentry_y = row["Spawn2Y"]
        spawn.spawnentry_z = row["Spawn2Z"]
        spawn.spawnentry_heading = row["Spawn2Heading"]
        spawn.spawnentry_respawn = row["Spawn2Respawn"]
        spawn.spawnentry_variance = row["Spawn2Variance"]
        spawn.spawnentry_pathgrid = row["Spawn2Grid"]
        spawn.spawnentry_condition = row["Spawn2Condition"]
        spawn.spawnentry_condvalue = row["Spawn2CondValue"]
        spawn.spawnentry_version = row["Spawn2Version"]
        spawn.spawnentry_enabled = row["Spawn2Enabled"]
        spawn.spawnentry_animation = row["Spawn2Animation"]
        spawn.spawnentry_zone = row["Spawn2Zone"]

        spawn.spawnentry_originalx = row["Spawn2X"]
        spawn.spawnentry_originaly = row["Spawn2Y"]
        spawn.spawnentry_originalz = row["Spawn2Z"]
        spawn.spawnentry_originalheading = row["Spawn2Heading"]


    # Initializes the camera position upon startup
    def InitCameraPosition(self):
        world.campos = Point3(-155.6, 41.2, 4.9 + world.eyeHeight)
        world.camHeading = 270.0

        base.camera.setPos(world.campos)

    def GetCamera(self):
        return base.camera
def runViewer(mesh):
    scene_members = getSceneMembers(mesh)

    loadPrcFileData('', 'win-size 300 300')
    base = ShowBase()
    globNode = GeomNode("collada")
    nodePath = base.render.attachNewNode(globNode)

    rotateNode = GeomNode("rotater")
    rotatePath = nodePath.attachNewNode(rotateNode)
    matrix = numpy.identity(4)
    if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP:
        r = collada.scene.RotateTransform(0, 1, 0, 90)
        matrix = r.matrix
    elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP:
        r = collada.scene.RotateTransform(1, 0, 0, 90)
        matrix = r.matrix
    rotatePath.setMat(Mat4(*matrix.T.flatten().tolist()))

    basecollada = GeomNode("basecollada")
    basecolladaNP = rotatePath.attachNewNode(basecollada)
    for geom, renderstate, mat4 in scene_members:
        node = GeomNode("primitive")
        node.addGeom(geom)
        if renderstate is not None:
            node.setGeomState(0, renderstate)
        geomPath = basecolladaNP.attachNewNode(node)
        geomPath.setMat(mat4)

    for boundlight in mesh.scene.objects('light'):

        if len(boundlight.color) == 3:
            color = (boundlight.color[0], boundlight.color[1],
                     boundlight.color[2], 1)
        else:
            color = boundlight.color

        if isinstance(boundlight, collada.light.BoundDirectionalLight):
            dl = DirectionalLight('dirLight')
            dl.setColor(Vec4(color[0], color[1], color[2], color[3]))
            lightNP = rotatePath.attachNewNode(dl)
            lightNP.lookAt(
                Point3(boundlight.direction[0], boundlight.direction[1],
                       boundlight.direction[2]))
        elif isinstance(boundlight, collada.light.BoundAmbientLight):
            ambientLight = AmbientLight('ambientLight')
            ambientLight.setColor(Vec4(color[0], color[1], color[2], color[3]))
            lightNP = rotatePath.attachNewNode(ambientLight)
        elif isinstance(boundlight, collada.light.BoundPointLight):
            pointLight = PointLight('pointLight')
            pointLight.setColor(Vec4(color[0], color[1], color[2], color[3]))
            pointLight.setAttenuation(
                Vec3(boundlight.constant_att, boundlight.linear_att,
                     boundlight.quad_att))
            lightNP = rotatePath.attachNewNode(pointLight)
            lightNP.setPos(
                Vec3(boundlight.position[0], boundlight.position[1],
                     boundlight.position[2]))
        elif isinstance(boundlight, collada.light.BoundSpotLight):
            spotLight = Spotlight('spotLight')
            spotLight.setColor(Vec4(color[0], color[1], color[2], color[3]))
            spotLight.setAttenuation(
                Vec3(boundlight.constant_att, boundlight.linear_att,
                     boundlight.quad_att))
            spotLight.setExponent(boundlight.falloff_exp)
            lightNP = rotatePath.attachNewNode(spotLight)
            lightNP.setPos(
                Vec3(boundlight.position[0], boundlight.position[1],
                     boundlight.position[2]))
            lightNP.lookAt(
                Point3(boundlight.direction[0], boundlight.direction[1],
                       boundlight.direction[2]),
                Vec3(boundlight.up[0], boundlight.up[1], boundlight.up[2]))
        else:
            print 'Unknown light type', boundlight
            continue

        base.render.setLight(lightNP)

    for boundcam in mesh.scene.objects('camera'):
        if isinstance(boundcam, collada.camera.BoundPerspectiveCamera):
            base.camera.reparentTo(rotatePath)
            base.camLens.setNear(boundcam.znear)
            base.camLens.setFar(boundcam.zfar)

            if boundcam.xfov is not None and boundcam.yfov is not None:
                #xfov + yfov
                base.camLens.setFov(boundcam.xfov, boundcam.yfov)
            elif boundcam.xfov is not None and boundcam.aspect_ratio is not None:
                #xfov + aspect_ratio
                base.camLens.setFov(boundcam.xfov)
                base.camLens.setAspectRatio(boundcam.aspect_ratio)
            elif boundcam.yfov is not None and boundcam.aspect_ratio is not None:
                #yfov + aspect_ratio
                #aspect_ratio = tan(0.5*xfov) / tan(0.5*yfov)
                xfov = math.degrees(
                    2.0 *
                    math.atan(boundcam.aspect_ratio *
                              math.tan(math.radians(0.5 * boundcam.yfov))))
                base.camLens.setFov(xfov, boundcam.yfov)
            elif boundcam.yfov is not None:
                #yfov only
                #aspect_ratio = tan(0.5*xfov) / tan(0.5*yfov)
                xfov = math.degrees(
                    2.0 *
                    math.atan(base.camLens.getAspectRatio() *
                              math.tan(math.radians(0.5 * boundcam.yfov))))
                base.camLens.setFov(xfov, boundcam.yfov)
            elif boundcam.xfov is not None:
                base.camLens.setFov(boundcam.xfov)

            base.camera.setPos(
                Vec3(boundcam.position[0], boundcam.position[1],
                     boundcam.position[2]))
            base.camera.lookAt(
                Point3(boundcam.direction[0], boundcam.direction[1],
                       boundcam.direction[2]),
                Vec3(boundcam.up[0], boundcam.up[1], boundcam.up[2]))
        elif isinstance(boundcam, collada.camera.BoundOrthographicCamera):

            lens = OrthographicLens()
            base.cam.node().setLens(lens)
            base.camLens = lens
            base.camera.reparentTo(rotatePath)
            base.camLens.setNear(boundcam.znear)
            base.camLens.setFar(boundcam.zfar)

            if boundcam.xmag is not None and boundcam.ymag is not None:
                #xmag + ymag
                base.camLens.setFilmSize(boundcam.xmag, boundcam.ymag)
            elif boundcam.xmag is not None and boundcam.aspect_ratio is not None:
                #xmag + aspect_ratio
                base.camLens.setFilmSize(boundcam.xmag)
                base.camLens.setAspectRatio(boundcam.aspect_ratio)
            elif boundcam.ymag is not None and boundcam.aspect_ratio is not None:
                #ymag + aspect_ratio
                xmag = boundcam.aspect_ratio * boundcam.ymag
                base.camLens.setFilmSize(xmag, boundcam.ymag)
            elif boundcam.ymag is not None:
                #ymag only
                xmag = base.camLens.getAspectRatio() * boundcam.ymag
                base.camLens.setFilmSize(xmag, boundcam.ymag)
            elif boundcam.xmag is not None:
                base.camLens.setFilmSize(boundcam.xmag)

            base.camera.setPos(
                Vec3(boundcam.position[0], boundcam.position[1],
                     boundcam.position[2]))
            base.camera.lookAt(
                Point3(boundcam.direction[0], boundcam.direction[1],
                       boundcam.direction[2]),
                Vec3(boundcam.up[0], boundcam.up[1], boundcam.up[2]))

        else:
            print 'Unknown camera type', boundcam
            continue

    base.disableMouse()
    base.render.setShaderAuto()
    base.render.setTransparency(TransparencyAttrib.MDual, 1)

    KeyboardMovement()
    MouseDrag(basecolladaNP)
    MouseScaleZoom(basecolladaNP)

    base.run()
 def __setPointLight(self, props):
     light = PointLight(props['name'])
     light.setAttenuation(props['attenuation'])
     return self.__createLight(light, props)
Beispiel #32
0
class Light(PropertiesTableAbstract, XMLExportable):
    def __init__(self, attributes, parent):

        self.plnp = -1
        self.parent = parent
        self.typeName = 'light'
        self.properties = {
            'distance': '',
            'attenuation': '',
            'type': '',
            'on': '',
            'color': '',
            'id': ''
        }

        if attributes.has_key('distance'):
            self.properties['distance'] = distance = float(
                attributes['distance'].value)
        else:
            distance = 1.0

        if attributes.has_key('attenuation'):
            self.properties[
                'attenuation'] = self.attenuation = attenuation = float(
                    attributes['attenuation'].value)
        else:
            self.properties[
                'attenuation'] = self.attenuation = attenuation = 0.0

        if attributes.has_key('type'):
            self.properties['type'] = ltype = attributes['type'].value
        else:
            self.properties['type'] = ltype = 'point'

        if attributes.has_key('on'):
            if attributes['on'].value == "false":
                self.properties['on'] = 'false'
                self.on = False
            else:
                self.properties['on'] = 'true'
                self.on = True
        else:
            self.on = True

        if attributes.has_key('color'):
            self.properties['color'] = color = attributes['color'].value
        else:
            color = '1,1,1,1'

        if attributes.has_key('id'):
            self.properties['id'] = self.uid = uid = attributes['id'].value
        else:
            self.properties['id'] = self.uid = uid = 'light'

        self.generateNode()

    def destroy(self):
        if self.plnp != -1:
            render.clearLight(self.plnp)

    def generateNode(self):
        rgba = self.properties['color'].split(',')
        if len(rgba) < 3:
            print "ERROR: please define a correct color for light. (example: r,g,b,a in float values)!"
        realcolor = VBase4(
            float(rgba[0]) / 255,
            float(rgba[1]) / 255,
            float(rgba[2]) / 255, 1.0)

        if self.properties['type'] == 'spot':
            self.plight = Spotlight('slight')
            self.plight.setColor(realcolor)
            self.lens = PerspectiveLens()
            self.plight.setLens(self.lens)
            self.plnp = self.parent.attachNewNode(self.plight)
            self.plnp.setPos(0.5, -self.properties['distance'], 0.5)
            self.plnp.lookAt(Point3(0.5, 0, 0.5))

        if self.properties['type'] == 'point':
            self.plight = PointLight('plight')
            self.plight.setColor(realcolor)
            if self.on == True:
                self.plight.setAttenuation(self.properties['attenuation'])
            else:
                self.plight.setAttenuation((1.0, 0, 1))
            self.plnp = self.parent.getNode().attachNewNode(self.plight)
            self.plnp.setPos(0.5, -self.properties['distance'], 0.5)

        render.setLight(self.plnp)

        if self.on:
            self.setOn()

        #set unique id
        self.plnp.setTag("id", self.properties['id'])
        self.plnp.setPythonTag("gamenode", self)

    def getName(self):
        return 'Point Light: ' + self.properties['id']

    def xmlAttributes(self):
        return self.properties

    def xmlTypeName(self):
        return self.typeName

    '''
    Sanitize properties data to be of correct type from string
    '''

    def sanitizeProperties(self):
        #sanitizing data
        self.properties['distance'] = float(self.properties['distance'])
        self.properties['attenuation'] = float(self.properties['attenuation'])

    #interface needed by PropertiesTable
    # regenerates the node at every change
    def onPropertiesUpdated(self):
        self.sanitizeProperties()

        rgba = self.properties['color'].split(',')
        if len(rgba) < 3:
            print "ERROR: please define a correct color for light. (example: r,g,b,a in float values)!"
        realcolor = VBase4(
            float(rgba[0]) / 255,
            float(rgba[1]) / 255,
            float(rgba[2]) / 255, 1.0)

        self.plnp.setY(-self.properties['distance'])
        self.plight.setColor(realcolor)
        self.plight.setAttenuation((self.properties['attenuation']))

    def getPropertyList(self):
        return self.properties

    def setProperty(self, key, value):
        self.properties[key] = value

    def getNode(self):
        return self.plnp

    def setOn(self):
        self.plight.setAttenuation(self.attenuation)
        self.on = True

    def setOff(self):
        self.plight.setAttenuation(1.0)
        self.on = False

    def toggle(self):
        if self.on:
            self.setOff()
        else:
            self.setOn()
Beispiel #33
0
class World(DirectObject):
    def __init__(self):
        self.last_mousex = 0
        self.last_mousey = 0

        self.zone = None
        self.zone_reload_name = None

        self.winprops = WindowProperties()

        # simple console output
        self.consoleNode = NodePath(PandaNode("console_root"))
        self.consoleNode.reparentTo(aspect2d)

        self.console_num_lines = 24
        self.console_cur_line = -1
        self.console_lines = []
        for i in range(0, self.console_num_lines):
            self.console_lines.append(
                OnscreenText(
                    text="",
                    style=1,
                    fg=(1, 1, 1, 1),
                    pos=(-1.3, 0.4 - i * 0.05),
                    align=TextNode.ALeft,
                    scale=0.035,
                    parent=self.consoleNode,
                )
            )

        # Configuration
        self.consoleOut("zonewalk v.%s loading configuration" % VERSION)
        self.configurator = Configurator(self)
        cfg = self.configurator.config
        resaveRes = False
        if "xres" in cfg:
            self.xres = int(cfg["xres"])
        else:
            self.xres = 1024
            resaveRes = True

        if "yres" in cfg:
            self.yres = int(cfg["yres"])
        else:
            self.yres = 768
            resaveRes = True

        if resaveRes:
            self.saveDefaultRes()

        self.xres_half = self.xres / 2
        self.yres_half = self.yres / 2
        self.mouse_accum = MouseAccume(lambda: (self.xres_half, self.yres_half))

        self.eyeHeight = 7.0
        self.rSpeed = 80
        self.flyMode = 1

        # application window setup
        base.win.setClearColor(Vec4(0, 0, 0, 1))
        self.winprops.setTitle("zonewalk")
        self.winprops.setSize(self.xres, self.yres)

        base.win.requestProperties(self.winprops)
        base.disableMouse()

        # network test stuff
        self.login_client = None
        if "testnet" in cfg:
            if cfg["testnet"] == "1":
                self.doLogin()

        # Post the instructions
        self.title = addTitle("zonewalk v." + VERSION)
        self.inst0 = addInstructions(0.95, "[FLYMODE][1]")
        self.inst1 = addInstructions(-0.95, "Camera control with WSAD/mouselook. Press K for hotkey list, ESC to exit.")
        self.inst2 = addInstructions(0.9, "Loc:")
        self.inst3 = addInstructions(0.85, "Hdg:")
        self.error_inst = addInstructions(0, "")
        self.kh = []

        self.campos = Point3(155.6, 41.2, 4.93)
        base.camera.setPos(self.campos)

        # Accept the application control keys: currently just esc to exit navgen
        self.accept("escape", self.exitGame)
        self.accept("window-event", self.resizeGame)

        # Create some lighting
        ambient_level = 0.6
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor(Vec4(ambient_level, ambient_level, ambient_level, 1.0))
        render.setLight(render.attachNewNode(ambientLight))

        direct_level = 0.8
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection(Vec3(0.0, 0.0, -1.0))
        directionalLight.setColor(Vec4(direct_level, direct_level, direct_level, 1))
        directionalLight.setSpecularColor(Vec4(direct_level, direct_level, direct_level, 1))
        render.setLight(render.attachNewNode(directionalLight))

        # create a point light that will follow our view point (the camera for now)
        # attenuation is set so that this point light has a torch like effect
        self.plight = PointLight("plight")
        self.plight.setColor(VBase4(0.8, 0.8, 0.8, 1.0))
        self.plight.setAttenuation(Point3(0.0, 0.0, 0.0002))

        self.plnp = base.camera.attachNewNode(self.plight)
        self.plnp.setPos(0, 0, 0)
        render.setLight(self.plnp)
        self.cam_light = 1

        self.keyMap = {
            "left": 0,
            "right": 0,
            "forward": 0,
            "backward": 0,
            "cam-left": 0,
            "cam-right": 0,
            "mouse3": 0,
            "flymode": 1,
        }

        # setup FOG
        self.fog_colour = (0.8, 0.8, 0.8, 1.0)
        self.linfog = Fog("A linear-mode Fog node")
        self.linfog.setColor(self.fog_colour)
        self.linfog.setLinearRange(700, 980)  # onset, opaque distances as params
        # linfog.setLinearFallback(45,160,320)
        base.camera.attachNewNode(self.linfog)
        render.setFog(self.linfog)
        self.fog = 1

        # camera control
        self.campos = Point3(0, 0, 0)
        self.camHeading = 0.0
        self.camPitch = 0.0
        base.camLens.setFov(65.0)
        base.camLens.setFar(1200)

        self.cam_speed = 0  # index into self.camp_speeds
        self.cam_speeds = [40.0, 80.0, 160.0, 320.0, 640.0]

        # Collision Detection for "WALKMODE"
        # We will detect the height of the terrain by creating a collision
        # ray and casting it downward toward the terrain.  The ray 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.camGroundRay = CollisionRay()
        self.camGroundRay.setOrigin(0.0, 0.0, 0.0)
        self.camGroundRay.setDirection(0, 0, -1)  # straight down
        self.camGroundCol = CollisionNode("camRay")
        self.camGroundCol.addSolid(self.camGroundRay)
        self.camGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.camGroundCol.setIntoCollideMask(BitMask32.allOff())

        # attach the col node to the camCollider dummy node
        self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol)
        self.camGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)

        # Uncomment this line to see the collision rays
        # self.camGroundColNp.show()

        # Uncomment this line to show a visual representation of the
        # collisions occuring
        # self.cTrav.showCollisions(render)

        # Add the spinCameraTask procedure to the task manager.
        # taskMgr.add(self.spinCameraTask, "SpinCameraTask")
        taskMgr.add(self.camTask, "camTask")

        self.toggleControls(1)

        # need to step the task manager once to make our fake console work
        taskMgr.step()

    # CONSOLE ---------------------------------------------------------------------
    def consoleScroll(self):
        for i in range(0, self.console_num_lines - 1):
            self.console_lines[i].setText(self.console_lines[i + 1].getText())

    def consoleOut(self, text):
        print text  # output to stdout/log too

        if self.console_cur_line == self.console_num_lines - 1:
            self.consoleScroll()
        elif self.console_cur_line < self.console_num_lines - 1:
            self.console_cur_line += 1

        self.console_lines[self.console_cur_line].setText(text)

        taskMgr.step()

    def consoleOn(self):
        self.consoleNode.show()

    def consoleOff(self):
        self.consoleNode.hide()

    # User controls -----------------------------------------------------------
    def toggleControls(self, on):
        if on == 1:
            self.accept("escape", self.exitGame)

            self.accept("1", self.setSpeed, ["speed", 0])
            self.accept("2", self.setSpeed, ["speed", 1])
            self.accept("3", self.setSpeed, ["speed", 2])
            self.accept("4", self.setSpeed, ["speed", 3])
            self.accept("5", self.setSpeed, ["speed", 4])

            self.accept("alt-f", self.fogToggle)
            self.accept("t", self.camLightToggle)
            self.accept("k", self.displayKeyHelp)
            self.accept("f", self.toggleFlymode)
            self.accept("l", self.reloadZone)
            self.accept("z", self.saveDefaultZone)
            self.accept("a", self.setKey, ["cam-left", 1])
            self.accept("d", self.setKey, ["cam-right", 1])
            self.accept("w", self.setKey, ["forward", 1])
            self.accept("mouse1", self.setKey, ["forward", 1])
            self.accept("mouse3", self.setKey, ["mouse3", 1])
            self.accept("s", self.setKey, ["backward", 1])

            self.accept("k-up", self.hideKeyHelp)
            self.accept("a-up", self.setKey, ["cam-left", 0])
            self.accept("d-up", self.setKey, ["cam-right", 0])
            self.accept("w-up", self.setKey, ["forward", 0])
            self.accept("mouse1-up", self.setKey, ["forward", 0])
            self.accept("mouse3-up", self.setKey, ["mouse3", 0])
            self.accept("s-up", self.setKey, ["backward", 0])
        else:
            messenger.clear()

    def setSpeed(self, key, value):
        self.cam_speed = value
        self.setFlymodeText()

    def fogToggle(self):
        if self.fog == 1:
            render.clearFog()
            base.camLens.setFar(100000)
            self.fog = 0
        else:
            render.setFog(self.linfog)
            base.camLens.setFar(1200)
            self.fog = 1

    def camLightToggle(self):
        if self.cam_light == 0:
            render.setLight(self.plnp)
            self.cam_light = 1
        else:
            render.clearLight(self.plnp)
            self.cam_light = 0

    def displayKeyHelp(self):
        self.kh = []
        msg = "HOTKEYS:"
        pos = 0.75
        self.kh.append(
            OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04)
        )
        msg = "------------------"
        pos -= 0.05
        self.kh.append(
            OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04)
        )
        msg = "W: camera fwd, S: camera bck, A: rotate view left, D: rotate view right"
        pos -= 0.05
        self.kh.append(
            OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04)
        )
        msg = "1-5: set camera movement speed"
        pos -= 0.05
        self.kh.append(
            OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04)
        )
        msg = "F: toggle Flymode/Walkmode"
        pos -= 0.05
        self.kh.append(
            OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04)
        )
        msg = "L: load a zone"
        pos -= 0.05
        self.kh.append(
            OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04)
        )
        msg = "ALT-F: toggle FOG and FAR plane on/off"
        pos -= 0.05
        self.kh.append(
            OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04)
        )
        msg = 'T: toggle additional camera "torch" light on/off'
        pos -= 0.05
        self.kh.append(
            OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04)
        )
        msg = "Z: set currently loaded zone as new startup default"
        pos -= 0.05
        self.kh.append(
            OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04)
        )
        msg = "ESC: exit zonewalk"
        pos -= 0.05
        self.kh.append(
            OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04)
        )

    def hideKeyHelp(self):
        for n in self.kh:
            n.removeNode()

    def setFlymodeText(self):
        zname = ""
        if self.zone:
            zname = self.zone.name

        if self.flyMode == 0:
            self.inst0.setText("[WALKMODE][%i] %s" % (self.cam_speed + 1, zname))
        else:
            self.inst0.setText("[FLYMODE][%i] %s " % (self.cam_speed + 1, zname))

    def toggleFlymode(self):
        zname = ""
        if self.zone:
            zname = self.zone.name

        if self.flyMode == 0:
            self.flyMode = 1
        else:
            self.flyMode = 0

        self.setFlymodeText()

    # Define a procedure to move the camera.
    def spinCameraTask(self, task):
        angleDegrees = task.time * 6.0
        angleRadians = angleDegrees * (pi / 180.0)
        base.camera.setPos(20 * sin(angleRadians), -20.0 * cos(angleRadians), 3)
        base.camera.setHpr(angleDegrees, 0, 0)
        return task.cont

    def camTask(self, task):
        # query the mouse
        mouse_dx = 0
        mouse_dy = 0

        # if we have a mouse and the right button is depressed
        if base.mouseWatcherNode.hasMouse():
            if self.keyMap["mouse3"] != 0:
                self.mouse_accum.update()
            else:
                self.mouse_accum.reset()

        mouse_dx = self.mouse_accum.dx
        mouse_dy = self.mouse_accum.dy

        self.rXSpeed = fabs(self.mouse_accum.dx) * (self.cam_speed + 1) * max(5 * 1000 / self.xres, 3)
        self.rYSpeed = fabs(self.mouse_accum.dy) * (self.cam_speed + 1) * max(3 * 1000 / self.yres, 1)

        if self.keyMap["cam-left"] != 0 or mouse_dx < 0:
            if self.rSpeed < 160:
                self.rSpeed += 80 * globalClock.getDt()

            if mouse_dx != 0:
                self.camHeading += self.rXSpeed * globalClock.getDt()
            else:
                self.camHeading += self.rSpeed * globalClock.getDt()

            if self.camHeading > 360.0:
                self.camHeading = self.camHeading - 360.0
        elif self.keyMap["cam-right"] != 0 or mouse_dx > 0:
            if self.rSpeed < 160:
                self.rSpeed += 80 * globalClock.getDt()

            if mouse_dx != 0:
                self.camHeading -= self.rXSpeed * globalClock.getDt()
            else:
                self.camHeading -= self.rSpeed * globalClock.getDt()

            if self.camHeading < 0.0:
                self.camHeading = self.camHeading + 360.0
        else:
            self.rSpeed = 80

        if mouse_dy > 0:
            self.camPitch += self.rYSpeed * globalClock.getDt()
        elif mouse_dy < 0:
            self.camPitch -= self.rYSpeed * globalClock.getDt()

        # set camera heading and pitch
        base.camera.setHpr(self.camHeading, self.camPitch, 0)

        # viewer position (camera) movement control
        v = render.getRelativeVector(base.camera, Vec3.forward())
        if not self.flyMode:
            v.setZ(0.0)

        move_speed = self.cam_speeds[self.cam_speed]
        if self.keyMap["forward"] == 1:
            self.campos += v * move_speed * globalClock.getDt()
        if self.keyMap["backward"] == 1:
            self.campos -= v * move_speed * globalClock.getDt()

        # actually move the camera
        lastPos = base.camera.getPos()
        base.camera.setPos(self.campos)
        # self.plnp.setPos(self.campos)      # move the point light with the viewer position

        # WALKMODE: simple collision detection
        # we simply check a ray from slightly below the "eye point" straight down
        # for geometry collisions and if there are any we detect the point of collision
        # and adjust the camera's Z accordingly
        if self.flyMode == 0:
            # move the camera to where it would be if it made the move
            # the colliderNode moves with it
            # base.camera.setPos(self.campos)
            # check for collissons
            self.cTrav.traverse(render)
            entries = []
            for i in range(self.camGroundHandler.getNumEntries()):
                entry = self.camGroundHandler.getEntry(i)
                entries.append(entry)
                # print 'collision'
            entries.sort(lambda x, y: cmp(y.getSurfacePoint(render).getZ(), x.getSurfacePoint(render).getZ()))

            if len(entries) > 0:  # and (entries[0].getIntoNode().getName() == "terrain"):
                # print len(entries)
                self.campos.setZ(entries[0].getSurfacePoint(render).getZ() + self.eyeHeight)
            else:
                self.campos = lastPos
                base.camera.setPos(self.campos)

            # if (base.camera.getZ() < self.player.getZ() + 2.0):
            #    base.camera.setZ(self.player.getZ() + 2.0)

        # update loc and hpr display
        pos = base.camera.getPos()
        hpr = base.camera.getHpr()
        self.inst2.setText("Loc: %.2f, %.2f, %.2f" % (pos.getX(), pos.getY(), pos.getZ()))
        self.inst3.setText("Hdg: %.2f, %.2f, %.2f" % (hpr.getX(), hpr.getY(), hpr.getZ()))
        return task.cont

    def exitGame(self):
        sys.exit(0)

    def resizeGame(self, win):
        props = base.win.getProperties()
        self.xres = props.getXSize()
        self.yres = props.getYSize()
        self.xres_half = self.xres / 2
        self.yres_half = self.yres / 2
        self.saveDefaultRes()

    # Records the state of the arrow keys
    # this is used for camera control
    def setKey(self, key, value):
        self.keyMap[key] = value

    # -------------------------------------------------------------------------
    # this is the mythical MAIN LOOP :)
    def update(self):

        if self.zone_reload_name != None:
            self.doReload(self.zone_reload_name)
            self.zone_reload_name = None

        if self.zone != None:
            self.zone.update()

        taskMgr.step()

        if self.login_client != None:
            self.login_client.update()

    # ZONE loading ------------------------------------------------------------

    # general zone loader driver
    # removes existing zone (if any) and load the new one
    def loadZone(self, name, path):
        if path[len(path) - 1] != "/":
            path += "/"

        if self.zone:
            self.zone.rootNode.removeNode()

        self.zone = Zone(self, name, path)
        error = self.zone.load()
        if error == 0:
            self.consoleOff()
            self.setFlymodeText()
            base.setBackgroundColor(self.fog_colour)

    def saveDefaultRes(self):
        cfg = self.configurator.config
        cfg["xres"] = str(self.xres)
        cfg["yres"] = str(self.yres)
        self.configurator.saveConfig()

    # initial world load after bootup
    def load(self):
        cfg = self.configurator.config

        if self.login_client != None:
            return

        zone_name = cfg["default_zone"]
        basepath = cfg["basepath"]
        self.loadZone(zone_name, basepath)

    # config save user interfacce
    def saveDefaultZone(self):
        if self.zone:
            cfg = self.configurator.config
            cfg["default_zone"] = self.zone.name
            self.configurator.saveConfig()

    # zone reload user interface

    # this gets called from our update loop when it detects that zone_reload_name has been set
    # we do this in this convoluted fashion in order to keep the main loop taskMgr updates ticking
    # because otherwise our status console output at various stages during the zone load would not
    # be displayed. Yes, this is hacky.
    def doReload(self, name):
        cfg = self.configurator.config
        basepath = cfg["basepath"]
        self.loadZone(name, basepath)

    # form dialog callback
    # this gets called from the form when the user has entered a something
    # (hopefully a correct zone short name)
    def reloadZoneDialogCB(self, name):
        self.frmDialog.end()
        self.zone_reload_name = name
        self.toggleControls(1)

    # this is called when the user presses "l"
    # it disables normal controls and fires up our query form dialog
    def reloadZone(self):
        base.setBackgroundColor((0, 0, 0))
        self.toggleControls(0)
        self.consoleOn()
        self.frmDialog = FileDialog(
            "Please enter the shortname of the zone you wish to load:",
            "Examples: qrg, blackburrow, freportn, crushbone etc.",
            self.reloadZoneDialogCB,
        )

        self.frmDialog.activate()  # relies on the main update loop to run

    ###############################
    # EXPERIMENTAL
    def doLogin(self):

        self.login_client = UDPClientStream("127.0.0.1", 5998)
    def __init__(self):

        # Check video card capabilities.

        if base.win.getGsg().getSupportsBasicShaders() == 0:
            addTitle("Bump Mapping: Video driver reports that shaders are not supported.")
            return

        # Post the instructions
        self.title = addTitle("Panda3D: Tutorial - Bump Mapping")
        self.inst1 = addInstructions(0.95, "Press ESC to exit")
        self.inst2 = addInstructions(0.90, "Move mouse to rotate camera")
        self.inst3 = addInstructions(0.85, "Left mouse button: Move forwards")
        self.inst4 = addInstructions(0.80, "Right mouse button: Move backwards")
        self.inst5 = addInstructions(0.75, "Enter: Turn bump maps Off")

        # Load the 'abstract room' model.  This is a model of an
        # empty room containing a pillar, a pyramid, and a bunch
        # of exaggeratedly bumpy textures.

        self.room = loader.loadModel("models/abstractroom")
        self.room.reparentTo(render)

        # Make the mouse invisible, turn off normal mouse controls
        base.disableMouse()
        props = WindowProperties()
        props.setCursorHidden(True)
        base.win.requestProperties(props)

        # Set the current viewing target
        self.focus = Vec3(55, -55, 20)
        self.heading = 180
        self.pitch = 0
        self.mousex = 0
        self.mousey = 0
        self.last = 0
        self.mousebtn = [0, 0, 0]

        # Start the camera control task:
        taskMgr.add(self.controlCamera, "camera-task")
        self.accept("escape", sys.exit, [0])
        self.accept("mouse1", self.setMouseBtn, [0, 1])
        self.accept("mouse1-up", self.setMouseBtn, [0, 0])
        self.accept("mouse2", self.setMouseBtn, [1, 1])
        self.accept("mouse2-up", self.setMouseBtn, [1, 0])
        self.accept("mouse3", self.setMouseBtn, [2, 1])
        self.accept("mouse3-up", self.setMouseBtn, [2, 0])
        self.accept("enter", self.toggleShader)
        self.accept("j", self.rotateLight, [-1])
        self.accept("k", self.rotateLight, [1])
        self.accept("arrow_left", self.rotateCam, [-1])
        self.accept("arrow_right", self.rotateCam, [1])

        # Add a light to the scene.
        self.lightpivot = render.attachNewNode("lightpivot")
        self.lightpivot.setPos(0, 0, 25)
        self.lightpivot.hprInterval(10, Point3(360, 0, 0)).loop()
        plight = PointLight("plight")
        plight.setColor(Vec4(1, 1, 1, 1))
        plight.setAttenuation(Vec3(0.7, 0.05, 0))
        plnp = self.lightpivot.attachNewNode(plight)
        plnp.setPos(45, 0, 0)
        self.room.setLight(plnp)

        # Add an ambient light
        alight = AmbientLight("alight")
        alight.setColor(Vec4(0.2, 0.2, 0.2, 1))
        alnp = render.attachNewNode(alight)
        self.room.setLight(alnp)

        # create a sphere to denote the light
        sphere = loader.loadModel("models/sphere")
        sphere.reparentTo(plnp)

        # load and apply the shader.  This is using panda's
        # built-in shader generation capabilities to create the
        # shader for you.  However, if desired, you can supply
        # the shader manually.  Change this line of code to:
        #   self.room.setShaderInput("light", plnp)
        #   self.room.setShader(Shader.load("bumpMapper.sha"))
        self.room.setShaderAuto()

        self.shaderenable = 1
Beispiel #35
0
class MyApp(ShowBase):
 
	def __init__(self):
		ShowBase.__init__(self)
		dir(self)
		self.disableMouse()
 
		# Load the environment model.
		self.environ = self.loader.loadModel("../levels/level01.egg")
		# Reparent the model to render.
		self.environ.reparentTo(self.render)
		'''add a light'''
		self.light = PointLight("dLight")
		self.light.setAttenuation( (.01,.01,.01 ) )
		self.light.setSpecularColor ( VBase4(1,1,0,1 ) )
		self.lightNode = render.attachNewNode(self.light)
		self.lightNode.setZ(10)
		render.setLight(self.lightNode)

		'''move light constants'''
		self.moveLightDirection = -1000

		self.taskMgr.add(self.moveLight,"lightMove")
		self.taskMgr.add(self.fpsInput,"fpsInput")

		'''fps cam controls'''
		self.keymap={"w":0,"a":0,"s":0,"d":0,"e":0,"q":0,
				"j":0,"k":0,"l":0,"i":0}
		
		self.fps = FpsCam(self.camera)
		self.accept("a", self.setKey,     ["a",1] )
		self.accept("a-up", self.setKey,  ['a',0] )
		self.accept("w", self.setKey,     ["w",1] )
		self.accept("w-up", self.setKey,  ["w",0] )
		self.accept("s", self.setKey,     ["s",1] )
		self.accept("s-up", self.setKey,  ["s",0] )
		self.accept("d", self.setKey,     ["d",1] )
		self.accept("d-up", self.setKey,  ["d",0] )
		self.accept("e", self.setKey,     ["e",1] )
		self.accept("e-up", self.setKey,  ["e",0] )
		self.accept("q", self.setKey,     ["q",1] )
		self.accept("q-up", self.setKey,  ["q",0] )
		self.accept("j", self.setKey,     ["j",1] )
		self.accept("j-up", self.setKey,  ["j",0] )
		self.accept("k", self.setKey,     ["k",1] )
		self.accept("k-up", self.setKey,  ["k",0] )
		self.accept("l", self.setKey,     ["l",1] )
		self.accept("l-up", self.setKey,  ["l",0] )
		self.accept("i", self.setKey,     ["i",1] )
		self.accept("i-up", self.setKey,  ["i",0] )
		self.accept("escape",sys.exit )




	def setKey(self,key,value):
		self.keymap[key]=value
		return

	def fpsInput(self,task):
		self.fps.moveX( self.keymap["d"]-self.keymap["a"])
		self.fps.moveY( self.keymap["w"]-self.keymap["s"])
		self.fps.moveZ( self.keymap["e"]-self.keymap["q"])
		self.fps.yaw  ( self.keymap["j"]-self.keymap["l"])
		self.fps.pitch( self.keymap["i"]-self.keymap["k"])
		return task.cont

	def moveLight(self,task):
		#print dir(self.lightNode)
		where = self.lightNode.getX()
		#print where
		self.lightNode.setX(where-task.getDt()*self.moveLightDirection)
		if self.lightNode.getX()< -10:
			self.moveLightDirection *= -1
		elif self.lightNode.getX() > 10:
			self.moveLightDirection *= -1

		return task.cont
Beispiel #36
0
    def __init__(self):
        # Initialize the ShowBase class from which we inherit, which will
        # create a window and set up everything we need for rendering into it.
        ShowBase.__init__(self)

        self.disableMouse()
        self.cam.node().getLens().setNear(10.0)
        self.cam.node().getLens().setFar(200.0)
        camera.setPos(0, -50, 0)

        # Check video card capabilities.
        if not self.win.getGsg().getSupportsBasicShaders():
            addTitle(
                "Toon Shader: Video driver reports that Cg shaders are not supported."
            )
            return

        # Enable a 'light ramp' - this discretizes the lighting,
        # which is half of what makes a model look like a cartoon.
        # Light ramps only work if shader generation is enabled,
        # so we call 'setShaderAuto'.

        tempnode = NodePath(PandaNode("temp node"))
        tempnode.setAttrib(LightRampAttrib.makeSingleThreshold(0.5, 0.4))
        tempnode.setShaderAuto()
        self.cam.node().setInitialState(tempnode.getState())

        # Use class 'CommonFilters' to enable a cartoon inking filter.
        # This can fail if the video card is not powerful enough, if so,
        # display an error and exit.

        self.separation = 1  # Pixels
        self.filters = CommonFilters(self.win, self.cam)
        filterok = self.filters.setCartoonInk(separation=self.separation)
        if (filterok == False):
            addTitle(
                "Toon Shader: Video card not powerful enough to do image postprocessing"
            )
            return

        # Show instructions in the corner of the window.
        self.title = addTitle(
            "Panda3D: Tutorial - Toon Shading with Normals-Based Inking")
        self.inst1 = addInstructions(0.06, "ESC: Quit")
        self.inst2 = addInstructions(
            0.12, "Up/Down: Increase/Decrease Line Thickness")
        self.inst3 = addInstructions(0.18,
                                     "V: View the render-to-texture results")

        # Load a dragon model and animate it.
        self.character = Actor()
        self.character.loadModel('models/nik-dragon')
        self.character.reparentTo(render)
        self.character.loadAnims({'win': 'models/nik-dragon'})
        self.character.loop('win')
        self.character.hprInterval(15, (360, 0, 0)).loop()

        # Create a non-attenuating point light and an ambient light.
        plightnode = PointLight("point light")
        plightnode.setAttenuation((1, 0, 0))
        plight = render.attachNewNode(plightnode)
        plight.setPos(30, -50, 0)
        alightnode = AmbientLight("ambient light")
        alightnode.setColor((0.8, 0.8, 0.8, 1))
        alight = render.attachNewNode(alightnode)
        render.setLight(alight)
        render.setLight(plight)

        # Panda contains a built-in viewer that lets you view the
        # results of all render-to-texture operations.  This lets you
        # see what class CommonFilters is doing behind the scenes.
        self.accept("v", self.bufferViewer.toggleEnable)
        self.accept("V", self.bufferViewer.toggleEnable)
        self.bufferViewer.setPosition("llcorner")
        self.accept("s", self.filters.manager.resizeBuffers)

        # These allow you to change cartooning parameters in realtime
        self.accept("escape", sys.exit, [0])
        self.accept("arrow_up", self.increaseSeparation)
        self.accept("arrow_down", self.decreaseSeparation)
def runViewer(mesh):
    scene_members = getSceneMembers(mesh)
    
    loadPrcFileData('', 'win-size 300 300')
    base = ShowBase()
    globNode = GeomNode("collada")
    nodePath = base.render.attachNewNode(globNode)
    
    rotateNode = GeomNode("rotater")
    rotatePath = nodePath.attachNewNode(rotateNode)
    matrix = numpy.identity(4)
    if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP:
        r = collada.scene.RotateTransform(0,1,0,90)
        matrix = r.matrix
    elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP:
        r = collada.scene.RotateTransform(1,0,0,90)
        matrix = r.matrix
    rotatePath.setMat(Mat4(*matrix.T.flatten().tolist()))
    
    basecollada = GeomNode("basecollada")
    basecolladaNP = rotatePath.attachNewNode(basecollada)
    for geom, renderstate, mat4 in scene_members:
        node = GeomNode("primitive")
        node.addGeom(geom)
        if renderstate is not None:
            node.setGeomState(0, renderstate)
        geomPath = basecolladaNP.attachNewNode(node)
        geomPath.setMat(mat4)

    for boundlight in mesh.scene.objects('light'):
        
        if len(boundlight.color) == 3:
            color = (boundlight.color[0], boundlight.color[1], boundlight.color[2], 1)
        else:
            color = boundlight.color
        
        if isinstance(boundlight, collada.light.BoundDirectionalLight):
            dl = DirectionalLight('dirLight')
            dl.setColor(Vec4(color[0], color[1], color[2], color[3]))
            lightNP = rotatePath.attachNewNode(dl)
            lightNP.lookAt(Point3(boundlight.direction[0],boundlight.direction[1],boundlight.direction[2]))
        elif isinstance(boundlight, collada.light.BoundAmbientLight):
            ambientLight = AmbientLight('ambientLight')
            ambientLight.setColor(Vec4(color[0], color[1], color[2], color[3]))
            lightNP = rotatePath.attachNewNode(ambientLight)
        elif isinstance(boundlight, collada.light.BoundPointLight):
            pointLight = PointLight('pointLight')
            pointLight.setColor(Vec4(color[0], color[1], color[2], color[3]))
            pointLight.setAttenuation(Vec3(boundlight.constant_att, boundlight.linear_att, boundlight.quad_att))
            lightNP = rotatePath.attachNewNode(pointLight)
            lightNP.setPos(Vec3(boundlight.position[0], boundlight.position[1], boundlight.position[2]))
        elif isinstance(boundlight, collada.light.BoundSpotLight):
            spotLight = Spotlight('spotLight')
            spotLight.setColor(Vec4(color[0], color[1], color[2], color[3]))
            spotLight.setAttenuation(Vec3(boundlight.constant_att, boundlight.linear_att, boundlight.quad_att))
            spotLight.setExponent(boundlight.falloff_exp)
            lightNP = rotatePath.attachNewNode(spotLight)
            lightNP.setPos(Vec3(boundlight.position[0], boundlight.position[1], boundlight.position[2]))
            lightNP.lookAt(Point3(boundlight.direction[0], boundlight.direction[1], boundlight.direction[2]),
                               Vec3(boundlight.up[0], boundlight.up[1], boundlight.up[2]))
        else:
            print('Unknown light type', boundlight)
            continue
            
        base.render.setLight(lightNP)

    for boundcam in mesh.scene.objects('camera'):
        if isinstance(boundcam, collada.camera.BoundPerspectiveCamera):
            base.camera.reparentTo(rotatePath)
            base.camLens.setNear(boundcam.znear)
            base.camLens.setFar(boundcam.zfar)
            
            if boundcam.xfov is not None and boundcam.yfov is not None:
                #xfov + yfov
                base.camLens.setFov(boundcam.xfov, boundcam.yfov)
            elif boundcam.xfov is not None and boundcam.aspect_ratio is not None:
                #xfov + aspect_ratio
                base.camLens.setFov(boundcam.xfov)
                base.camLens.setAspectRatio(boundcam.aspect_ratio)
            elif boundcam.yfov is not None and boundcam.aspect_ratio is not None:
                #yfov + aspect_ratio
                #aspect_ratio = tan(0.5*xfov) / tan(0.5*yfov)
                xfov = math.degrees(2.0 * math.atan(boundcam.aspect_ratio * math.tan(math.radians(0.5 * boundcam.yfov))))
                base.camLens.setFov(xfov, boundcam.yfov)
            elif boundcam.yfov is not None:
                #yfov only
                #aspect_ratio = tan(0.5*xfov) / tan(0.5*yfov)
                xfov = math.degrees(2.0 * math.atan(base.camLens.getAspectRatio() * math.tan(math.radians(0.5 * boundcam.yfov))))
                base.camLens.setFov(xfov, boundcam.yfov)
            elif boundcam.xfov is not None:
                base.camLens.setFov(boundcam.xfov)
            
            base.camera.setPos(Vec3(boundcam.position[0], boundcam.position[1], boundcam.position[2]))
            base.camera.lookAt(Point3(boundcam.direction[0], boundcam.direction[1], boundcam.direction[2]),
                               Vec3(boundcam.up[0], boundcam.up[1], boundcam.up[2]))
        elif isinstance(boundcam, collada.camera.BoundOrthographicCamera):
            
            lens = OrthographicLens()
            base.cam.node().setLens(lens)
            base.camLens = lens
            base.camera.reparentTo(rotatePath)
            base.camLens.setNear(boundcam.znear)
            base.camLens.setFar(boundcam.zfar)
            
            if boundcam.xmag is not None and boundcam.ymag is not None:
                #xmag + ymag
                base.camLens.setFilmSize(boundcam.xmag, boundcam.ymag)
            elif boundcam.xmag is not None and boundcam.aspect_ratio is not None:
                #xmag + aspect_ratio
                base.camLens.setFilmSize(boundcam.xmag)
                base.camLens.setAspectRatio(boundcam.aspect_ratio)
            elif boundcam.ymag is not None and boundcam.aspect_ratio is not None:
                #ymag + aspect_ratio
                xmag = boundcam.aspect_ratio * boundcam.ymag
                base.camLens.setFilmSize(xmag, boundcam.ymag)
            elif boundcam.ymag is not None:
                #ymag only
                xmag = base.camLens.getAspectRatio() * boundcam.ymag
                base.camLens.setFilmSize(xmag, boundcam.ymag)
            elif boundcam.xmag is not None:
                base.camLens.setFilmSize(boundcam.xmag)
            
            base.camera.setPos(Vec3(boundcam.position[0], boundcam.position[1], boundcam.position[2]))
            base.camera.lookAt(Point3(boundcam.direction[0], boundcam.direction[1], boundcam.direction[2]),
                               Vec3(boundcam.up[0], boundcam.up[1], boundcam.up[2]))
            
        else:
            print('Unknown camera type', boundcam)
            continue

    base.disableMouse()
    base.render.setShaderAuto()
    base.render.setTransparency(TransparencyAttrib.MDual, 1)
    
    KeyboardMovement()
    MouseDrag(basecolladaNP)
    MouseScaleZoom(basecolladaNP)
    
    base.run()
Beispiel #38
0
    def __init__(self, img_size=512, screen_off=True):
        self.img_size = img_size
        loadPrcFileData("", "transform-cache false")
        loadPrcFileData("", "audio-library-name null")  # Prevent ALSA errors
        loadPrcFileData("", "win-size %d %d" % (img_size, img_size))
        loadPrcFileData("", "parallax-mapping-samples 3\n"
                            "parallax-mapping-scale 0.1")

        if screen_off:
            # Spawn an offscreen buffer
            loadPrcFileData("", "window-type offscreen")
        # Initialize the ShowBase class from which we inherit, which will
        # create a window and set up everything we need for rendering into it.
        ShowBase.__init__(self)

        # Load the 'abstract room' model.  This is a model of an
        # empty room containing a pillar, a pyramid, and a bunch
        # of exaggeratedly bumpy textures.

        self.room = loader.loadModel("models/abstractroom")
        self.room.reparentTo(render)

        # Create the main character, Ralph

        self.ralph = Actor("models/ralph",
                           {"run": "models/ralph-run",
                            "walk": "models/ralph-walk"})
        self.ralph.reparentTo(render)
        self.ralph.setScale(.2)
        self.reset()

        self.pieces = [Piece(self.room) for _ in range(200)]
        ##################################################
        cnodePath = self.room.attachNewNode(CollisionNode('cnode'))
        plane = CollisionPlane(Plane(Vec3(1, 0, 0), Point3(-60, 0, 0)))  # left
        cnodePath.node().addSolid(plane)
        plane = CollisionPlane(
            Plane(Vec3(-1, 0, 0), Point3(60, 0, 0)))  # right
        cnodePath.node().addSolid(plane)
        plane = CollisionPlane(Plane(Vec3(0, 1, 0), Point3(0, -60, 0)))  # back
        cnodePath.node().addSolid(plane)
        plane = CollisionPlane(
            Plane(Vec3(0, -1,  0), Point3(0, 60,  0)))  # front
        cnodePath.node().addSolid(plane)

        sphere = CollisionSphere(-25, -25, 0, 12.5)
        cnodePath.node().addSolid(sphere)

        box = CollisionBox(Point3(5, 5, 0), Point3(45, 45, 10))
        cnodePath.node().addSolid(box)

        # Make the mouse invisible, turn off normal mouse controls
        self.disableMouse()
        self.camLens.setFov(80)

        # Set the current viewing target
        self.focus = LVector3(55, -55, 20)
        self.heading = 180
        self.pitch = 0
        self.mousex = 0
        self.mousey = 0
        self.last = 0
        self.mousebtn = [0, 0, 0]

        # Add a light to the scene.
        self.lightpivot = render.attachNewNode("lightpivot")
        self.lightpivot.setPos(0, 0, 25)
        self.lightpivot.hprInterval(10, LPoint3(360, 0, 0)).loop()
        plight = PointLight('plight')
        plight.setColor((5, 5, 5, 1))
        plight.setAttenuation(LVector3(0.7, 0.05, 0))
        plnp = self.lightpivot.attachNewNode(plight)
        plnp.setPos(45, 0, 0)
        self.room.setLight(plnp)

        # Add an ambient light
        alight = AmbientLight('alight')
        alight.setColor((0.2, 0.2, 0.2, 1))
        alnp = render.attachNewNode(alight)
        self.room.setLight(alnp)

        # Create a sphere to denote the light
        sphere = loader.loadModel("models/icosphere")
        sphere.reparentTo(plnp)

        self.cameraModel = self.ralph
        camera.reparentTo(self.cameraModel)
        camera.setZ(2)

        self.cTrav = CollisionTraverser()

        cs = CollisionSphere(0, 0, 0, 1)
        cnodePath = self.ralph.attachNewNode(CollisionNode('cnode'))
        cnodePath.node().addSolid(cs)

        cnodePath.show()
        self.ralphGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(cnodePath, self.ralphGroundHandler)

        self.cnodePath = cnodePath

        # Tell Panda that it should generate shaders performing per-pixel
        # lighting for the room.
        self.room.setShaderAuto()

        self.shaderenable = 1

        tex = Texture()
        self.depthmap = tex
        tex.setFormat(Texture.FDepthComponent)
        altBuffer = self.win.makeTextureBuffer(
            "hello", img_size, img_size, tex, True)
        self.altBuffer = altBuffer
        altCam = self.makeCamera(altBuffer)
        altCam.reparentTo(self.ralph)  # altRender)
        altCam.setZ(2)
        l = altCam.node().getLens()
        l.setFov(80)
Beispiel #39
0
    def __init__(self):
        GameObject.__init__(self, Vec3(0, 0, 0), None, None, 100, 15, "player",
                            1, MASK_INTO_PLAYER)
        Walker.__init__(self)
        ArmedObject.__init__(self)

        self.weaponNP = self.actor

        light = PointLight("basic light")
        light.setColor(Vec4(1, 1, 1, 1))
        light.setAttenuation((1, 0.01, 0.005))
        self.lightNP = self.root.attachNewNode(light)
        self.lightNP.setZ(1)
        render.setLight(self.lightNP)

        self.collider.node().setFromCollideMask(MASK_WALLS | MASK_FROM_PLAYER)

        self.actor.setZ(self.height)

        base.camera.reparentTo(self.actor)
        base.camera.setPos(0, 0, 0)
        base.camera.setHpr(0, 0, 0)

        lens = base.camLens
        ratio = lens.getAspectRatio()

        lens.setFov(80 * ratio)
        lens.setNear(0.03)

        self.lastMousePos = Vec2(0, 0)
        self.mouseSpeedHori = 50.0
        self.mouseSpeedVert = 30.0
        self.mouseSensitivity = 1.0

        self.healthLeft = -0.9
        self.healthRight = 0.9
        self.healthWidth = self.healthRight - self.healthLeft

        self.uiRoot = base.a2dBottomCenter.attachNewNode(
            PandaNode("player UI"))

        self.healthBar = loader.loadModel("UI/healthBar")
        self.healthBar.reparentTo(self.uiRoot)
        self.healthBar.setZ(0.05)
        self.healthBar.setX(self.healthLeft)
        self.healthBar.getChild(0).setScale(self.healthWidth / 6.0)

        self.weaponUIRoot = self.uiRoot.attachNewNode(
            PandaNode("player weapon UI"))
        self.weaponUIRoot.setPos(0, 0, 0.1)

        self.addWeapon(RapidShotgunWeapon(self.weaponUIRoot))
        self.addWeapon(BlasterWeapon(self.weaponUIRoot))

        self.weapons[0].setAvailable(True)

        self.setCurrentWeapon(0)

        self.updateHealthUI()

        self.inventory = []

        self.updatingEffects = []

        self.interactionSegment = CollisionSegment(0, 0, 0, 0, 1.5, 0)

        rayNode = CollisionNode("player interaction ray")
        rayNode.addSolid(self.interactionSegment)

        rayNode.setFromCollideMask(MASK_WALLS | MASK_FLOORS | MASK_INTO_ENEMY)
        rayNode.setIntoCollideMask(0)

        self.interactionSegmentNodePath = self.actor.attachNewNode(rayNode)
        #self.interactionSegmentNodePath.show()
        self.interactionSegmentQueue = CollisionHandlerQueue()

        self.interactionSegmentTraverser = CollisionTraverser()
        self.interactionSegmentTraverser.addCollider(
            self.interactionSegmentNodePath, self.interactionSegmentQueue)
	def __setPointLight(self,props):		
		light = PointLight(props['name'])
		light.setAttenuation(props['attenuation'])
		return self.__createLight(light,props)
    def __init__(self):
        # Set up the window, camera, etc.
        ShowBase.__init__(self)
	#self.setupCD()

        # Set the background color to black
       # self.win.setClearColor((0.6, 0.6, 1.0, 1.0))
#	self.fog = Fog('myFog')
#	self.fog.setColor(0, 0, 0)
#	self.fog.setExpDensity(.05)
#	render.setFog(self.fog)	
       # This is used to store which keys are currently pressed.
        self.keyMap = {
            "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0, "c":0, "back":0, "space":0}

        # Post the instructions
        #self.title = addTitle(
         #   "Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)")
        self.inst1 = addInstructions(0.06, "[ESC]: Quit")
        self.inst2 = addInstructions(0.12, "[Left Arrow]: Rotate Ralph Left")
        self.inst3 = addInstructions(0.18, "[Right Arrow]: Rotate Ralph Right")
        self.inst4 = addInstructions(0.24, "[Up Arrow]: Run Ralph Forward")
        #self.inst6 = addInstructions(0.30, "[A]: Rotate Camera Left")
        #self.inst7 = addInstructions(0.36, "[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/world")
        #self.environ.reparentTo(render)

        self.room = loader.loadModel("models/room2.egg")
        self.room.reparentTo(render)
        #self.room.setScale(.1)
        self.room.setPos(0,0,-5)
        self.room.setShaderAuto()
	#self.room.writeBamFile("myRoom1.bam")
	#self.room.setColor(1,.3,.3,1)

	self.room2 = loader.loadModel("models/abstractroom2")
        self.room2.reparentTo(render)
        self.room2.setScale(.1)
        self.room2.setPos(-12,0,0)

        # Create the main character, Ralph

        #ralphStartPos = LVecBase3F(0,0,0) #self.room.find("**/start_point").getPos()

        self.ralph = Actor("models/ralph",
                           {"run": "models/ralph-run",
                            "walk": "models/ralph-walk"})
        self.ralph.reparentTo(render)
        self.ralph.setScale(.2)
        self.ralph.setPos(0,0,0)
	#cs = CollisionSphere(0, 0, 0, 1)
	#cnodePath = self.ralph.attachNewNode(CollisionNode('cnode'))
	#cnodePath.node().addSolid(cs)
	#cnodePath.node().setPos(0,0,0)
	#cnodePath.show()	
	
	self.gianteye = loader.loadModel("models/gianteye")
	self.gianteye.reparentTo(render)
	self.gianteye.setScale(.1)
	self.gianteye.setPos(10,10,0)	
	
	#self.bluefinal = loader.loadModel("models/chrysalis")
	#self.bluefinal.reparentTo(render)
	#self.bluefinal.setScale(.1)
	#self.bluefinal.setPos(7,7,0)	
	
	#self.blue = loader.loadModel("models/blue1")
	#self.blue.reparentTo(render)
	#self.blue.setScale(.1)
	#self.blue.setPos(10,5,0)
	
	self.chik = loader.loadModel("models/chik")
	self.chik.reparentTo(render)
	self.chik.setScale(.1)
	self.chik.setPos(3,13,0)	

        self.pawn = loader.loadModel("pawn")
        self.pawn.reparentTo(render)
        self.pawn.setPos(0,0,0)

        self.shot = loader.loadModel("models/icosphere.egg")
        self.shot.reparentTo(render)
        self.shot.setScale(.5)
        self.shot.setPos(0,0,1)
        self.shot.setColor(1,.3,.3,1)

        self.myShot = loader.loadModel("models/icosphere.egg")
        #self.myShot.reparentTo(render)
        self.myShot.setScale(.1)
        self.myShot.setPos(0,0,1)
        self.myShotVec = LVector3(0,0,0)

        self.lightpivot3 = render.attachNewNode("lightpivot3")
        self.lightpivot3.setPos(0, 0, 0)
        self.lightpivot3.hprInterval(10, LPoint3(0, 0, 0)).loop()
        plight3 = PointLight('plight2')
        plight3.setColor((0, .3,0, 1))
        plight3.setAttenuation(LVector3(0.7, 0.05, 0))
        plnp3 = self.lightpivot3.attachNewNode(plight3)
        plnp3.setPos(0, 0, 0)
        self.room2.setLight(plnp3)
        self.room.setLight(plnp3)
        sphere3 = loader.loadModel("models/icosphere")
        sphere3.reparentTo(plnp3)
        sphere3.setScale(0.1)
        sphere3.setColor((0,1,0,1))

        # Create a floater object, which floats 2 units above ralph.  We
        # use this as a target for the camera to look at.

        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(self.ralph)
        self.floater.setZ(8.0)

        # Accept the control keys for movement and rotation

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

        self.accept("space", self.setKey, ["space", True])
        self.accept("space-up", self.setKey, ["space", False])

        self.accept("c",self.setKey,["c",True])
        self.accept("c-up",self.setKey,["c",False])

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

        # Game state variables
        self.isMoving = False
        self.jumping = False
        self.vz = 0

        # Set up the camera
        self.disableMouse()
        self.camera.setPos(self.ralph.getX(), self.ralph.getY() + 7, 3)
        self.camLens.setFov(60)

        # 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.

        def setupCollision(self):
	    cs = CollisionSphere(0,0,2,1)
	    cnodePath = self.ralph.attachNewNode(CollisionNode('cnode'))
	    cnodePath.node().addSolid(cs)
	    cnodePath.show()
	    #for o in self.OBS:
		#ct = CollisionTube(0,0,0, 0,0,1, 0.5)
		#cn = o.attachNewNode(CollisionNode('ocnode'))
		#cn.node().addSolid(ct)
		#cn.show()
	    eyecs = CollisionSphere(0,0,4,5)
	    cnodePath = self.gianteye.attachNewNode(CollisionNode('cnode'))
	    cnodePath.node().addSolid(eyecs)
	    cnodePath.show()	 
	    eyecs = CollisionSphere(0,0,4,2)
	    cnodePath = self.chik.attachNewNode(CollisionNode('cnode'))
	    cnodePath.node().addSolid(eyecs)
	    cnodePath.show()	    
    
	    pusher = CollisionHandlerPusher()
	    pusher.addCollider(cnodePath, self.player)
	    self.cTrav = CollisionTraverser()
	    self.cTrav.add_collider(cnodePath,pusher)
	    self.cTrav.showCollisions(render)
	self.walls = self.room2.find("**/wall_collide")
	#self.walls.node().setIntoCollideMask(BitMask32.bit(0))

        self.cTrav = CollisionTraverser()
        self.ralphGroundRay = CollisionRay()
        self.ralphGroundRay.setOrigin(0, 0, 9)
        self.ralphGroundRay.setDirection(0, 0, -1)
        self.ralphGroundCol = CollisionNode('ralphRay')
        self.ralphGroundCol.addSolid(self.ralphGroundRay)
        self.ralphGroundCol.setFromCollideMask(CollideMask.bit(0))
        self.ralphGroundCol.setIntoCollideMask(CollideMask.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, 9)
        self.camGroundRay.setDirection(0, 0, -1)
        self.camGroundCol = CollisionNode('camRay')
        self.camGroundCol.addSolid(self.camGroundRay)
        self.camGroundCol.setFromCollideMask(CollideMask.bit(0))
        self.camGroundCol.setIntoCollideMask(CollideMask.allOff())
        self.camGroundColNp = self.camera.attachNewNode(self.camGroundCol)
        self.camGroundHandler = CollisionHandlerQueue()

        self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)

        self.sphere = CollisionSphere(0,0,4,2)
        self.sphere2 = CollisionSphere(0,0,2,2)
        self.cnodePath = self.ralph.attachNewNode((CollisionNode('cnode')))
        self.cnodePath.node().addSolid(self.sphere)
        self.cnodePath.node().addSolid(self.sphere2)
        self.cnodePath.show()
        self.pusher = CollisionHandlerPusher()
        self.pusher.addCollider(self.cnodePath, self.ralph)
        self.cTrav.add_collider(self.cnodePath, self.pusher)
	
	self.eyecs = CollisionSphere(0,0,22,25)
	self.cnodePath1 = self.gianteye.attachNewNode(CollisionNode('cnode'))
	self.cnodePath1.node().addSolid(self.eyecs)
	self.cnodePath1.show()	
	self.pusher1 = CollisionHandlerPusher()
	self.pusher1.addCollider(self.cnodePath1, self.gianteye)
	self.cTrav.add_collider(self.cnodePath1, self.pusher1)	
	self.cTrav.showCollisions(render)
	
	self.eyeGroundRay = CollisionRay()
        self.eyeGroundRay.setOrigin(0, 0, 9)
        self.eyeGroundRay.setDirection(0, 0, -1)
        self.eyeGroundCol = CollisionNode('eyeRay')
        self.eyeGroundCol.addSolid(self.eyeGroundRay)
        self.eyeGroundCol.setFromCollideMask(CollideMask.bit(0))
        self.eyeGroundCol.setIntoCollideMask(CollideMask.allOff())
        self.eyeGroundColNp = self.gianteye.attachNewNode(self.eyeGroundCol)
        self.eyeGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.eyeGroundColNp, self.eyeGroundHandler)		

	self.chikcs = CollisionSphere(0,0,11,20)
	self.cnodePath2 = self.chik.attachNewNode(CollisionNode('cnode'))
	self.cnodePath2.node().addSolid(self.chikcs)
	self.cnodePath2.show()
	self.pusher2 = CollisionHandlerPusher()
	self.pusher2.addCollider(self.cnodePath, self.chik)
	self.cTrav.add_collider(self.cnodePath, self.pusher2)	
	self.cTrav.showCollisions(render)	
	
	self.chikGroundRay = CollisionRay()
        self.chikGroundRay.setOrigin(0, 0, 9)
        self.chikGroundRay.setDirection(0, 0, -1)
        self.chikGroundCol = CollisionNode('chikRay')
        self.chikGroundCol.addSolid(self.chikGroundRay)
        self.chikGroundCol.setFromCollideMask(CollideMask.bit(0))
        self.chikGroundCol.setIntoCollideMask(CollideMask.allOff())
        self.chikGroundColNp = self.chik.attachNewNode(self.chikGroundCol)
        self.chikGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.chikGroundColNp, self.chikGroundHandler)	
	

        # Uncomment this line to see the collision rays
        self.ralphGroundColNp.show()
        self.camGroundColNp.show()
	#self.ralphroom1ColNp.show()

        # Uncomment this line to show a visual representation of the
        # collisions occuring
        #self.cTrav.showCollisions(render)

        # Create some lighting
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor((.3, .3, .3, .4))
        ambientLight2 = AmbientLight("ambientLight2")
        ambientLight2.setColor((1, 1, 1, 10))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection((0, 0, -2))
        directionalLight.setColor((1, 1, 1, 1))
        directionalLight.setSpecularColor((1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        #self.environ.setLight(self.environ.attachNewNode(ambientLight2))
        render.setLight(render.attachNewNode(directionalLight))

        # Add a light to the scene.
        self.lightpivot = render.attachNewNode("lightpivot")
        self.lightpivot.setPos(0, 0, 1.6)
        self.lightpivot.hprInterval(20, LPoint3(360, 0, 0)).loop()
        plight = PointLight('plight')
        plight.setColor((.7, .3, 0, 1))
        plight.setAttenuation(LVector3(0.7, 0.05, 0))
        plnp = self.lightpivot.attachNewNode(plight)
        plnp.setPos(5, 0, 0)
        self.room.setLight(plnp)
        sphere = loader.loadModel("models/icosphere")
        sphere.reparentTo(plnp)
        sphere.setScale(0.1)
        sphere.setColor((1,1,0,1))

        self.lightpivot2 = render.attachNewNode("lightpivot")
        self.lightpivot2.setPos(-16, 0, 1.6)
        self.lightpivot2.hprInterval(20, LPoint3(360, 0, 0)).loop()
        plight2 = PointLight('plight2')
        plight2.setColor((0, .4,.8, 1))
        plight2.setAttenuation(LVector3(0.7, 0.05, 0))
        plnp2 = self.lightpivot2.attachNewNode(plight2)
        plnp2.setPos(5, 0, 0)
        self.room2.setLight(plnp2)
        sphere2 = loader.loadModel("models/icosphere")
        sphere2.reparentTo(plnp2)
        sphere2.setScale(0.2)
        sphere2.setColor((0,0,1,1))

        self.vec = LVector3(0,1,0) 
Beispiel #42
0
    def __init__(self, img_size=512, screen_off=True, target_area_radius=5, initial_area_radius=10, keyboard_input=False, random_reset_around_target=False, test=False):
        logging.info('random_reset_around_target :%s',
                     random_reset_around_target)
        self.random_reset_around_target = random_reset_around_target
        self.keyboard_input = keyboard_input
        # Configure the parallax mapping settings (these are just the defaults)
        self.img_size = img_size
        self.initial_area_radius = initial_area_radius
        self.target_area_radius = target_area_radius
        loadPrcFileData("", "side-by-side-stereo 1")
        if test:
            loadPrcFileData("", "load-display p3tinydisplay")
        loadPrcFileData("", "transform-cache false")
        loadPrcFileData("", "audio-library-name null")  # Prevent ALSA errors
        loadPrcFileData("", "win-size %d %d" % (2 * img_size, img_size))
        loadPrcFileData("", "parallax-mapping-samples 3\n"
                            "parallax-mapping-scale 0.1")

        if screen_off:
            # Spawn an offscreen buffer
            loadPrcFileData("", "window-type offscreen")
        # Initialize the ShowBase class from which we inherit, which will
        # create a window and set up everything we need for rendering into it.
        ShowBase.__init__(self)

        self.keyMap = {
            "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0}

        # Load the 'abstract room' model.  This is a model of an
        # empty room containing a pillar, a pyramid, and a bunch
        # of exaggeratedly bumpy textures.

        self.room = loader.loadModel("models/abstractroom")
        self.room.reparentTo(render)

        # Create the main character, Ralph

        ghost = BulletGhostNode('Ghost')
        ghostNP = render.attachNewNode(ghost)
      #  self.agent = Actor("models/agent",
      #                     {"run": "models/agent-run",
      #                      "walk": "models/agent-walk"})
        self.agent = ghostNP
        self.agent.reparentTo(render)
#        self.agent.setScale(.2)
        target = BulletGhostNode('target')
        self.navigation_target = render.attachNewNode(target)
        self.navigation_target.reparentTo(render)

        # knghit=Knight((0,0,0),(0.3,.3,.3,1))
        self.pieces = [Piece(self.room) for _ in range(200)]
        ##################################################
        cnodePath = self.room.attachNewNode(CollisionNode('room'))
        plane = CollisionPlane(Plane(Vec3(1, 0, 0), Point3(-60, 0, 0)))  # left
        cnodePath.node().addSolid(plane)
        plane = CollisionPlane(
            Plane(Vec3(-1, 0, 0), Point3(60, 0, 0)))  # right
        cnodePath.node().addSolid(plane)
        plane = CollisionPlane(Plane(Vec3(0, 1, 0), Point3(0, -60, 0)))  # back
        cnodePath.node().addSolid(plane)
        plane = CollisionPlane(
            Plane(Vec3(0, -1, 0), Point3(0, 60, 0)))  # front
        cnodePath.node().addSolid(plane)

        sphere = CollisionSphere(-25, -25, 0, 12.5)
        # tube = CollisionTube(-25, -25,0 , -25, -25, 1, 12.5)
        cnodePath.node().addSolid(sphere)

        box = CollisionBox(Point3(5, 5, 0), Point3(45, 45, 10))
        cnodePath.node().addSolid(box)

      #  cnodePath.show()

        # Make the mouse invisible, turn off normal mouse controls
        self.disableMouse()
        # props = WindowProperties()
        # props.setCursorHidden(True)
        # self.win.requestProperties(props)
        # self.camLens.setFov(60)
        self.camLens.setFov(80)

        # Set the current viewing target
        self.focus = LVector3(55, -55, 20)
        self.heading = 180
        self.pitch = 0
        self.mousex = 0
        self.mousey = 0
        self.last = 0
        self.mousebtn = [0, 0, 0]

        # Start the camera control task:
        # taskMgr.add(self.controlCamera, "camera-task")
        # self.accept("escape", sys.exit, [0])
        # self.accept("enter", self.toggleShader)
        # self.accept("j", self.rotateLight, [-1])
        # self.accept("k", self.rotateLight, [1])
        # self.accept("arrow_left", self.rotateCam, [-1])
        # self.accept("arrow_right", self.rotateCam, [1])

        # Accept the control keys for movement and rotation

        self.accept("escape", sys.exit)
        self.accept("arrow_left", self.setKey, ["left", True])
        self.accept("arrow_right", self.setKey, ["right", True])
        self.accept("arrow_up", self.setKey, ["forward", True])
        self.accept("a", self.setKey, ["cam-left", True])
        self.accept("s", self.setKey, ["cam-right", True])
        self.accept("arrow_left-up", self.setKey, ["left", False])
        self.accept("arrow_right-up", self.setKey, ["right", False])
        self.accept("arrow_up-up", self.setKey, ["forward", False])
        self.accept("a-up", self.setKey, ["cam-left", False])
        self.accept("s-up", self.setKey, ["cam-right", False])
        # Add a light to the scene.
        self.lightpivot = render.attachNewNode("lightpivot")
        self.lightpivot.setPos(0, 0, 25)
        self.lightpivot.hprInterval(10, LPoint3(360, 0, 0)).loop()
        plight = PointLight('plight')
        plight.setColor((5, 5, 5, 1))
        plight.setAttenuation(LVector3(0.7, 0.05, 0))
        plnp = self.lightpivot.attachNewNode(plight)
        plnp.setPos(45, 0, 0)
        self.room.setLight(plnp)

        # Add an ambient light
        alight = AmbientLight('alight')
        alight.setColor((0.2, 0.2, 0.2, 1))
        alnp = render.attachNewNode(alight)
        self.room.setLight(alnp)

        # Create a sphere to denote the light
        sphere = loader.loadModel("models/icosphere")
        sphere.reparentTo(plnp)

#         self.cameraModel = self.agent

#        self.win2 = self.openWindow()
#        self.win2.removeAllDisplayRegions()
#        self.dr2 = self.win2.makeDisplayRegion()
#        camNode = Camera('cam')
#        camNP = NodePath(camNode)
#        camNP.reparentTo(self.cameraModel)
#        camNP.setZ(150)
#        camNP.lookAt(self.cameraModel)
#        self.dr2.setCamera(camNP)
#        self.cam2 = camNP  # Camera('cam')p

        # 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 agent'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()

        cs = CollisionSphere(0, 0, 0, 0.2)
        cnodePath = self.agent.attachNewNode(CollisionNode('agent'))
        cnodePath.node().addSolid(cs)

      #  cnodePath.show()
        self.ralphGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(cnodePath, self.ralphGroundHandler)

        cnodePath = self.navigation_target.attachNewNode(
            CollisionNode('target'))
        cnodePath.node().addSolid(CollisionSphere(0, 0, 0, 2))
        self.cTrav.addCollider(cnodePath, self.ralphGroundHandler)

        # Tell Panda that it should generate shaders performing per-pixel
        # lighting for the room.
        self.room.setShaderAuto()

        self.shaderenable = 1

        # tex = self.win.getScreenshot()
        # tex.setFormat(Texture.FDepthComponent)

        tex = Texture()
        self.depthmap = tex
        tex.setFormat(Texture.FDepthComponent)
        altBuffer = self.win.makeTextureBuffer(
            "hello", img_size, img_size, tex, True)
        self.altBuffer = altBuffer
        altCam = self.makeCamera(altBuffer)
        altCam.reparentTo(self.agent)  # altRender)
        altCam.setZ(0.4)
        l = altCam.node().getLens()
        l.setFov(80)
        l.setNear(.1)

        camera.reparentTo(self.agent)
        camera.setZ(0.4)
        l = self.camLens
        # l.setFov(80)
        l.setNear(.1)
Beispiel #43
0
class RacingGame(ShowBase):
    # method completely taken from RoamingRalph demo:
    def addInstructions(self, pos, msg):
        return OnscreenText(text=msg,
                            style=1,
                            fg=(1, 1, 1, 1),
                            scale=.05,
                            shadow=(0, 0, 0, 1),
                            parent=base.a2dTopLeft,
                            pos=(0.08, -pos - 0.04),
                            align=TextNode.ALeft)

    def addWin(self, time):
        msg = (
            "You finished the course in: \n%d seconds \n press z to race again"
            % (time))
        self.winText = OnscreenText(text=msg,
                                    style=1,
                                    fg=(1, 1, 1, 1),
                                    scale=.2,
                                    shadow=(0, 0, 0, 1),
                                    parent=base.a2dTopLeft,
                                    pos=(0.10, -0.5),
                                    align=TextNode.ALeft)

    def destroyWin(self):
        if (self.winText != None):
            self.winText.destroy()

    def setUpFlyingInstructions(self):
        self.inst[0] = self.addInstructions(.06, "Arrow Keys to move around")
        self.inst[1] = self.addInstructions(.12, "w and s to control pitch")
        self.inst[2] = self.addInstructions(.18, "a and d to control yaw")
        self.inst[3] = self.addInstructions(.24, "h to switch to driving mode")
        self.inst[4] = self.addInstructions(.3, "mouse click to add object")
        self.inst[5] = self.addInstructions(.36, "m to go to main")

    def startMovement(self):
        taskMgr.add(self.move, "moveTask")

    def destroyInstructions(self):
        # got way to destroy text from:
        # https://www.panda3d.org/manual/index.php/OnscreenText
        for element in self.inst:
            element.destroy()

    def startCreating(self):
        self.switchToCreateMode()
        self.destroyStartScreenButtons()
        self.startMovement()

    def startDriving(self):
        self.switchToDrivingMode()
        self.destroyStartScreenButtons()
        self.startMovement()

    def startTutorial(self):
        self.mode = self.modeTutorial
        self.setUpTutorial()
        self.destroyStartScreenButtons()
        self.startMovement()

    def setUpStartScreenButtons(self):
        self.creatingButton = DirectButton(text="Start Creating",
                                           scale=.1,
                                           command=self.startCreating,
                                           pos=(0, 0, .2))
        self.drivingButton = DirectButton(text="Start Driving",
                                          scale=.1,
                                          command=self.startDriving,
                                          pos=(0, 0, 0))
        self.tutorialButton = DirectButton(text="Start Tutorial",
                                           scale=.1,
                                           command=self.startTutorial,
                                           pos=(0, 0, -.2))

    def destroyStartScreenButtons(self):
        self.creatingButton.destroy()
        self.drivingButton.destroy()
        self.tutorialButton.destroy()

    def setAddObjectTree(self):
        self.createdObject = self.createTree

    def setAddObjectRock(self):
        self.createdObject = self.createRock

    def setAddObjectPole(self):
        self.createdObject = self.createPole

    def setUpCreateButtons(self):
        # todo: add toggle for instructions so that they do not always interfere with button
        self.treeButton = DirectButton(text="Add Block",
                                       scale=.1,
                                       command=self.setAddObjectTree,
                                       pos=(0, 0, .85))
        #self.rockButton = DirectButton(text="Add Rock", scale=.1, command=self.setAddObjectRock, pos=(-.5,.9,.85))
        self.poleButton = DirectButton(text="Add Pole",
                                       scale=.1,
                                       command=self.setAddObjectPole,
                                       pos=(.5, 0, .85))

    def setUpCreateObjects(self):
        self.createdObject = 0
        self.createTree = 0
        self.createRock = 1
        self.createPole = 2

    def destroyCreateButtons(self):
        self.treeButton.destroy()
        #self.rockButton.destroy()
        self.poleButton.destroy()

    def setUpDrivingInstructions(self):
        self.inst[0] = self.addInstructions(
            .06, "Right arrow and left arrow to turn")
        self.inst[1] = self.addInstructions(
            .12, "Forward and Backward arrow to go forward and backward")
        self.inst[2] = self.addInstructions(.18,
                                            "h to switch to add object mode")
        self.inst[3] = self.addInstructions(.24,
                                            "z to switch to start the race")
        self.inst[4] = self.addInstructions(.30, "m to go to main")

    def setUpWindow(self):
        # set up the egg files needed
        # since this method is made for python 2.7 but these objects are made for python 3.5, seems to be incompatible
        #m = Mountain("TestMountain", 60)
        #m.editFile()
        #p = Pole("TestPole", 0, 0, 0)
        #p.editFile()
        #c = Car("TestCar", 0,0,0)
        #c.editFile()
        #b = BeaconLight("BeaconLight",0,0,0)
        #b.editFile()
        # Set up the window, camera, etc
        ShowBase.__init__(self)

        # Set the background color to black
        self.win.setClearColor((0, 1, 1, 1))
        # this is the model I created using mountainMaker.py
        self.environ = loader.loadModel("TestMountain1")
        self.environ.reparentTo(render)

        self.car = loader.loadModel("TestCar")
        # found how to solve the problem of only being able to see objects from
        # certain angles with this:
        # http://www.panda3d.org/manual/index.php/Backface_Culling_and_Frontface_Culling
        self.car.setTwoSided(True)
        self.car.reparentTo(render)

        # Create some lighting
        # this is a part that is completely unchanged from demo
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor((.3, .3, .3, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection((-5, -5, -5))
        directionalLight.setColor((1, 1, 1, 1))
        directionalLight.setSpecularColor((1, 1, 1, 1))
        # to get light from other direction to light up things on both sides
        directionalLight2 = DirectionalLight("directionalLight")
        directionalLight2.setDirection((5, 5, 5))
        directionalLight2.setColor((1, 1, 1, 1))
        directionalLight2.setSpecularColor((1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))
        render.setLight(render.attachNewNode(directionalLight2))

    def setUpCar(self):
        # for adjusting so that the position is the center of the car
        self.adjustedXForCenter = 10 / 2
        self.adjustedYForCenter = 20 / 2

        # for some reason can't change this or the collisions do not work
        self.carPositionX = 20
        self.carPositionY = 20
        self.carPositionZ = 100
        # note for rotating camera: from this website:
        # https://www.panda3d.org/manual/index.php/Common_State_Changes
        # setHpr(Yaw, Pitch, Roll)

        # setting up initial conditions for which way camera is rotated
        self.carYaw = 0
        self.carPitch = 0
        (actualXPos, actualYPos) = RacingGame.findActualCenter(
            self, self.carPositionX, self.carPositionY,
            self.adjustedXForCenter, self.adjustedYForCenter, self.carYaw)
        self.car.setX(actualXPos)
        self.car.setY(actualYPos)
        self.car.setZ(self.carPositionZ)
        self.car.setHpr(self.carYaw, self.carPitch, 0)

    def setUpCamera(self):
        # for flying mode
        self.cameraPositionX = 500
        self.cameraPositionY = 500
        self.cameraPositionZ = 40
        # note for rotating camera: from this website:
        # https://www.panda3d.org/manual/index.php/Common_State_Changes
        # setHpr(Yaw, Pitch, Roll)

        # setting up initial conditions for which way camera is rotated
        self.cameraYaw = 0
        self.cameraPitch = 0

        # Set up the camera
        self.disableMouse()

        # should probably clean up these magic numbers
        self.camera.setPos(self.cameraPositionX, self.cameraPositionY,
                           self.cameraPositionZ)

    def setUpKeyMap(self):
        # This is used to store which keys are currently pressed.
        self.keyMap = {
            "left": 0,
            "right": 0,
            "forward": 0,
            "cam-left": 0,
            "cam-right": 0,
            "backward": 0,
            "cam-up": 0,
            "cam-down": 0,
            "add-car": 0,
            "switch-mode": 0,
            "mouse-click": 0,
            "race-start": 0,
            "to-main": 0
        }
        # Accept the control keys for movement and rotation

        #setting up keys for movement
        self.accept("escape", sys.exit)
        self.accept("arrow_left", self.setKey, ["left", True])
        self.accept("arrow_right", self.setKey, ["right", True])
        self.accept("arrow_up", self.setKey, ["forward", True])
        self.accept("arrow_down", self.setKey, ["backward", True])
        self.accept("arrow_left-up", self.setKey, ["left", False])
        self.accept("arrow_right-up", self.setKey, ["right", False])
        self.accept("arrow_up-up", self.setKey, ["forward", False])
        self.accept("arrow_down-up", self.setKey, ["backward", False])

        self.accept("m", self.setKey, ["to-main", True])
        self.accept("m-up", self.setKey, ["to-main", False])

        # starting race
        self.accept("z", self.setKey, ["race-start", True])
        self.accept("z-up", self.setKey, ["race-start", False])

        # adding car
        self.accept("mouse1", self.setKey, ["mouse-click", True])
        self.accept("mouse1-up", self.setKey, ["mouse-click", False])

        # setting up orientation of the camera
        self.accept("a", self.setKey, ["cam-left", True])
        self.accept("s", self.setKey, ["cam-down", True])
        self.accept("a-up", self.setKey, ["cam-left", False])
        self.accept("s-up", self.setKey, ["cam-down", False])
        self.accept("d", self.setKey, ["cam-right", True])
        self.accept("d-up", self.setKey, ["cam-right", False])
        self.accept("w", self.setKey, ["cam-up", True])
        self.accept("w-up", self.setKey, ["cam-up", False])

        # to switch between tasks
        self.accept("h", self.setKey, ["switch-mode", True])
        self.accept("h-up", self.setKey, ["switch-mode", False])

    def __init__(self):
        self.setUpWindow()
        self.setUpKeyMap()
        #instructions
        self.inst = [""] * 6
        self.setUpFlyingInstructions()

        self.mouseClicked = False

        self.winText = None

        # important for setting the size relative to everything else
        # found it here : https://www.panda3d.org/manual/index.php/Common_State_Changes
        # set the mode that the player is currently in
        self.mode = 0
        self.modeFly = 2
        self.modeRace = 1
        self.modeStart = 0
        self.modeTutorial = 3
        # to ensure that when pressing h it only switches once each press
        self.hasSwitched = False
        self.raceBegan = False
        self.raceTime = 0
        self.poleOn = 0

        self.setUpCamera()
        self.setUpCar()
        self.setUpCarCollider()
        self.setUpMouseCollider()
        self.setUpStartScreenButtons()
        # make the rocks and other stuff that will show up
        self.setUpCreateObjects()
        self.objects = []
        self.poles = []
        self.beaconLight = None
        self.beaconLightZ = 50
        self.target = None

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

    def findCollisionTube(self):
        # using bassically same formula as Y position
        # decided not to use this because possible problems with ground getting
        # hit instead of things in front
        degToRad = math.pi / 180
        xAddition = (
            self.adjustedXForCenter * math.cos(self.carYaw * degToRad) +
            self.adjustedYForCenter * math.sin(self.carYaw * degToRad)) / 2
        yAddition = (
            self.adjustedXForCenter * math.cos(self.carYaw * degToRad) +
            self.adjustedYForCenter * math.sin(self.carYaw * degToRad))

    def findCarFrontDir(self):
        degToRad = math.pi / 180
        xDir = -1 * math.sin(degToRad * self.carYaw) * math.cos(
            degToRad * self.carPitch)
        yDir = 1 * math.cos(degToRad * self.carYaw) * math.cos(
            degToRad * self.carPitch)
        zDir = 1 * math.sin(degToRad * self.carPitch)
        return (xDir, yDir, zDir)

    def setUpCarCollider(self):
        self.carCollideTrav = CollisionTraverser()
        base.cTrav = self.carCollideTrav
        self.handler = CollisionHandlerQueue()
        self.carRay = CollisionRay(self.carPositionX, self.carPositionY,
                                   self.carPositionZ, 0, 0, -1)
        self.carForwardHandler = CollisionHandlerQueue()
        # so that it doesn't collide with things forward and backward.
        degToRad = math.pi / 180
        (xDir, yDir, zDir) = self.findCarFrontDir()
        self.carRayForward = CollisionRay(self.carPositionX, self.carPositionY,
                                          self.carPositionZ, xDir, yDir, zDir)
        self.carForwardCollision = CollisionNode("forwardCollision")
        self.carForwardCollision.addSolid(self.carRayForward)
        self.carForwardCollision.setIntoCollideMask(CollideMask.allOff())
        self.carForwardCollisionNode = self.car.attachNewNode(
            self.carForwardCollision)
        (centerX,
         centerY) = self.findActualCenter(0, 0, self.adjustedXForCenter,
                                          self.adjustedYForCenter, self.carYaw)
        self.carRayForward.setOrigin(5, 10, 5)
        self.carCollision = CollisionNode("groundCollision")
        self.carCollision.addSolid(self.carRay)
        self.carCollision.setIntoCollideMask(CollideMask.allOff())
        self.carCollisionNode = self.car.attachNewNode(self.carCollision)
        self.carCollideTrav.addCollider(self.carCollisionNode, self.handler)
        self.carCollideTrav.addCollider(self.carForwardCollisionNode,
                                        self.carForwardHandler)
        self.carForwardCollisionNode.show()

    def setUpMouseCollider(self):
        # clicking on objects stuff came from here:
        # https://www.panda3d.org/manual/index.php/Collision_Traversers
        # https://www.panda3d.org/manual/index.php/Collision_Handlers
        # will not use the traverser set up by car because slow
        # instead we will render each time clicked
        self.mouseCollideTrav = CollisionTraverser("mouseTraverse")
        self.mousehandler = CollisionHandlerQueue()
        # edit this so that from Object is the camera
        # self.mouseCollideTrav.addCollider(fromObject, queue)
        # self.mouseCollideTrav.traverse(render)
        # this next part came from:
        # https://www.panda3d.org/manual/index.php/Clicking_on_3D_Objects
        pickerNode = CollisionNode("mouseRay")
        pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
        pickerNode.setIntoCollideMask(CollideMask.allOff())
        self.pickerRay = CollisionRay()
        pickerNode.addSolid(self.pickerRay)
        pickerNp = camera.attachNewNode(pickerNode)
        self.mouseCollideTrav.addCollider(pickerNp, self.mousehandler)

    # Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value

    def switchToCreateMode(self):
        self.mode = self.modeFly
        self.destroyInstructions()
        self.setUpFlyingInstructions()
        self.hasSwitched = True
        self.setUpCreateButtons()

    def switchToDrivingMode(self):
        self.mode = self.modeRace
        self.destroyInstructions()
        self.setUpDrivingInstructions()
        self.hasSwitched = True

    def switchToMainMode(self):
        self.mode = 0
        self.setUpStartScreenButtons()

    def setTutorialText(self, str):
        # reusing inst so that it is easy to erase
        self.inst[0] = self.addInstructions(.06, str)

    def move(self, task):
        if (self.keyMap["to-main"]):
            self.switchToMainMode()
        elif (self.mode == self.modeFly):
            if self.keyMap["switch-mode"] and not self.hasSwitched:
                self.switchToDrivingMode()
                self.destroyCreateButtons()
            elif not self.keyMap["switch-mode"]:
                # to ensure switch mode only happens once per button pressed
                self.hasSwitched = False
            self.findNewCameraPosition()
            self.checkAndAddNewObject()
        elif (self.mode == self.modeRace):
            if self.keyMap["switch-mode"] and not self.hasSwitched:
                self.destroyWin()
                self.switchToCreateMode()
            elif not self.keyMap["switch-mode"]:
                # this ensures that when key is pressed only switch states once
                self.hasSwitched = False
            self.findCarNewXandY()
            # when implementing the use of the mouse look here:
            # https://www.panda3d.org/manual/index.php/Clicking_on_3D_Objects
            self.setCarZ()
            self.setCameraPositionBehindCar()
            if (self.keyMap["race-start"] and not self.raceBegan
                    and len(self.poles) >= 2):
                self.destroyWin()
                # try so that if there are not enough poles then the game
                # doesn't crash
                try:
                    self.raceBegan = True
                    self.raceTime = time.time()
                    # puts in the car where the first two poles are
                    # first col of poles is model, second x coord, thrid y coord, fourth z coord
                    self.carPositionX = (self.poles[0][1] +
                                         self.poles[1][1]) / 2
                    self.carPositionY = (self.poles[0][2] +
                                         self.poles[1][2]) / 2
                    # meant to show where car should go
                    # got info on how to do point lights from here:
                    # https://www.panda3d.org/manual/index.php/Lighting
                    self.beaconLight = PointLight("beaconLight")
                    self.beaconLight.setColor((1, 1, 1, 1))
                    self.beaconLight.setAttenuation((0, 0, 1))
                    self.beaconLightHolder = render.attachNewNode(
                        self.beaconLight)
                    (beaconLightX, beaconLightY) = self.getNextGateCenter()
                    # target for driver
                    if (self.target == None):
                        self.target = loader.loadModel("BeaconLight.egg")
                    self.target.setTwoSided(True)
                    self.target.reparentTo(render)
                    if (beaconLightX != None):
                        self.beaconLightHolder.setPos(beaconLightX,
                                                      beaconLightY,
                                                      self.beaconLightZ)
                        render.setLight(self.beaconLightHolder)
                        self.target.setPos(beaconLightX, beaconLightY,
                                           self.beaconLightZ)
                except:
                    # not enough poles
                    pass
            if (self.raceBegan):
                # minus 1 just in case non even
                if (self.poleOn + 1 >= len(self.poles)):
                    self.raceBegan = False
                    self.addWin(time.time() - self.raceTime)
                    # since race ended
                    try:
                        self.target.destroy()
                    except:
                        pass
                    self.beaconLight = None  # use object + lights
                    self.beaconLightHolder = None
                    self.poleOn = 0
                else:
                    acceptableError = 100
                    # formula I created: (p2y-p1y)/(p2x-p1x)*(p2x-pAx)+p2y =
                    # expected pAy
                    # so if the actual car positionY is within acceptableError of
                    # pAy then the car is between the two poles
                    # if in between poles
                    middleX = (self.poles[self.poleOn][1] +
                               self.poles[self.poleOn + 1][1]) / 2
                    middleY = (self.poles[self.poleOn][2] +
                               self.poles[self.poleOn + 1][2]) / 2
                    expectedCarY = (
                        (self.poles[self.poleOn][2] -
                         self.poles[self.poleOn + 1][2]) /
                        (self.poles[self.poleOn][1] -
                         self.poles[self.poleOn + 1][1]) *
                        (self.poles[self.poleOn][1] - self.carPositionX) +
                        self.poles[self.poleOn][2])
                    # do not really care about car being inbetween pole in z axis
                    # because 2 demensional
                    if (expectedCarY + acceptableError > self.carPositionY
                            and expectedCarY - acceptableError <
                            self.carPositionY):
                        self.poleOn += 2
                        # only when last pole found is it necesary to add light
                        # to guide to next place elsewhere
                        (beaconLightX, beaconLightY) = self.getNextGateCenter()
                        if (beaconLightX != None):
                            self.beaconLightHolder.setPos(
                                beaconLightX, beaconLightY, self.beaconLightZ)
                            self.target.setPos(beaconLightX, beaconLightY,
                                               self.beaconLightZ)
        elif (self.mode == self.modeTutorial):
            self.destroyWin()
            # do the tutorial part for the creating
            timeBeforeNext = 2
            if (self.tutorialPause == True):
                if (time.time() - self.tutorialActionTime > timeBeforeNext):
                    self.tutorialPause = False
            else:
                if (self.tutorialStep == -1):
                    self.destroyInstructions()
                    self.setTutorialText(
                        "use w and s to move camera up and down")
                    self.tutorialStep += 1
                # do this until the user has completed all of the task
                self.checkTutorialStep(
                    0, (self.keyMap["cam-up"] or self.keyMap["cam-down"]),
                    "use a and d to rotate camera right and left")
                self.checkTutorialStep(
                    1, (self.keyMap["cam-left"] or self.keyMap["cam-right"]),
                    "use up-arrow and down-arrow to turn camera forward and backward"
                )
                self.checkTutorialStep(
                    2, (self.keyMap["forward"] or self.keyMap["backward"]),
                    "use left-arrow and right-arrow to slide camera left and right"
                )
                self.checkTutorialStep(
                    3, (self.keyMap["left"] or self.keyMap["right"]),
                    "use mouse click to place objects on terrain")
                self.checkTutorialStep(
                    4, (self.keyMap["mouse-click"]),
                    "use up-arrow and down-arrow to move car forward and backward",
                    (self.switchToDrivingMode, self.destroyInstructions))
                # need to ensure that the mode stays as tutorial
                self.mode = self.modeTutorial
                # then tutorial part for the driving
                self.checkTutorialStep(
                    5, (self.keyMap["forward"] or self.keyMap["backward"]),
                    "use right-arrow and left-arrow to rotate car left and right"
                )
                self.checkTutorialStep(
                    6, (self.keyMap["left"] or self.keyMap["right"]),
                    "Use poles to make the race course\n use z to start race")
                self.checkTutorialStep(
                    7, True,
                    "Follow yellow block through the gates till you win")
                self.checkTutorialStep(
                    8, True,
                    "Watch for high Terrain and blocks because you can not get through those"
                )
                self.checkTutorialStep(9, True, "")
                if (self.tutorialStep > 9):
                    # switch to main
                    self.switchToMainMode()
            # for movement
            if (self.tutorialStep <= 4):
                self.findNewCameraPosition()
                self.checkAndAddNewObject()
            if (self.tutorialStep > 4 and self.tutorialStep <= 9):
                self.findCarNewXandY()
                self.setCarZ()
                self.setCameraPositionBehindCar()
        return task.cont

    def getNextGateCenter(self):
        if (len(self.poles) > self.poleOn + 1):
            positionX = (self.poles[self.poleOn][1] +
                         self.poles[self.poleOn + 1][1]) / 2
            positionY = (self.poles[self.poleOn][2] +
                         self.poles[self.poleOn + 1][2]) / 2
            return (positionX, positionY)
        else:
            return (None, None)

    def checkTutorialStep(self, step, keysNeeded, nextText, functions=None):
        if (self.tutorialStep == step and self.tutorialNextStep == True):
            if (functions != None):
                for func in functions:
                    func()
            self.destroyInstructions()
            self.setTutorialText(nextText)
            self.tutorialStep += 1
            self.tutorialNextStep = False
        elif (self.tutorialStep == step and keysNeeded):
            self.tutorialNextStep = True
            self.tutorialActionTime = time.time()
            self.tutorialPause = True

    def setUpTutorial(self):
        self.tutorialStep = -1
        self.tutorialPause = False
        # this records when last tutorial action taken
        self.tutorialActionTime = 0
        self.tutorialNextStep = False

    def checkAndAddNewObject(self):
        # clicking on 3D objects comes from here:
        # https://www.panda3d.org/manual/index.php/Clicking_on_3D_Objects
        # checks if it needs to add any objects:
        if (self.keyMap["mouse-click"] and self.mouseClicked == False):
            self.mouseClicked = True
            # found way to speed this up by only doing collision check
            # when mouse clicked by not using cTrav like in this method
            # the way I did it I found here:
            # https://www.panda3d.org/manual/index.php/Clicking_on_3D_Objects
            # self.mouseCollideTrav.traverse(render)
            if (base.mouseWatcherNode.hasMouse()):
                mousePos = base.mouseWatcherNode.getMouse()
                self.pickerRay.setFromLens(base.camNode, mousePos.getX(),
                                           mousePos.getY())
                # do not put this before previous line, will get the coordinates
                # of last mouse click and where pickerRay was
                # ahhhhhhh!!!!!!!!!!!
                self.mouseCollideTrav.traverse(render)
                if (self.mousehandler.getNumEntries() > 0):
                    entries = list(self.mousehandler.getEntries())
                    # pathagorean formula for sorting
                    entries.sort(
                        key=lambda x: ((x.getSurfacePoint(render).getX(
                        ) - self.cameraPositionX)**2 + (x.getSurfacePoint(
                            render).getY() - self.cameraPositionY)**2)**.5)
                    newX = entries[0].getSurfacePoint(render).getX()
                    newY = entries[0].getSurfacePoint(render).getY()
                    newZ = entries[0].getSurfacePoint(render).getZ()
                    adjustedX = 10 / 2
                    adjustedY = 20 / 2
                    yaw = 0
                    # have to adjust this once there are different sized
                    # objects added
                    (actualXPos, actualYPos) = RacingGame.findActualCenter(
                        self, newX, newY, adjustedX, adjustedY, yaw)
                    if (self.createdObject == self.createPole):
                        self.poles.append([
                            loader.loadModel("TestPole.egg"), actualXPos,
                            actualYPos, newZ
                        ])
                        self.poles[len(self.poles) - 1][0].reparentTo(render)
                        self.poles[len(self.poles) - 1][0].setTwoSided(True)
                        self.poles[len(self.poles) - 1][0].setPos(
                            actualXPos, actualYPos, newZ)
                    else:
                        newCar = loader.loadModel("TestCar.egg")
                        newCar.reparentTo(render)
                        newCar.setPos(actualXPos, actualYPos, newZ)
                        # should take out because slow, but objects can not be
                        # seen without this because only seen from one direction
                        # even though normal vectors set up.
                        newCar.setTwoSided(True)
                        self.objects.append(newCar)
        elif (not self.keyMap["mouse-click"]):
            # elif because for some reason mouseClicked was becoming false
            # while click still pressed
            self.mouseClicked = False

    def findNewCameraPosition(self):
        # Get the time that elapsed since last frame.  We multiply this with
        # the desired speed in order to find out with which distance to move
        # in order to achieve that desired speed.
        dt = globalClock.getDt()
        # the angle is in degrees with 360 equal to full rotation
        angleAdjustment = 100
        if self.keyMap["cam-left"]:
            self.cameraYaw += angleAdjustment * dt
        if self.keyMap["cam-right"]:
            self.cameraYaw -= angleAdjustment * dt
        if self.keyMap["cam-up"]:
            self.cameraPitch += angleAdjustment * dt
        if self.keyMap["cam-down"]:
            self.cameraPitch -= angleAdjustment * dt

        positionAdjustment = 500
        # should switch rad and Deg in variable name
        radToDeg = math.pi / 180
        # the x and y component of left and right moves, do not need to
        # compensate in z axis because not doing any roll, so there should be
        # no zComponent
        xComponent = math.cos(self.cameraYaw * radToDeg)
        yComponent = math.sin(self.cameraYaw * radToDeg)

        if self.keyMap["left"]:
            self.cameraPositionX -= positionAdjustment * dt * xComponent
            self.cameraPositionY -= positionAdjustment * dt * yComponent
        if self.keyMap["right"]:
            self.cameraPositionX += positionAdjustment * dt * xComponent
            self.cameraPositionY += positionAdjustment * dt * yComponent

        # for going forward, the orientation is rotated 90 degrees so need to
        # change components
        xComponent = math.cos(self.cameraYaw * radToDeg + math.pi /
                              2) * math.cos(self.cameraPitch * radToDeg)
        yComponent = math.sin(self.cameraYaw * radToDeg + math.pi /
                              2) * math.cos(self.cameraPitch * radToDeg)
        zComponent = math.sin(self.cameraPitch * radToDeg)

        if self.keyMap["forward"]:
            self.cameraPositionX += positionAdjustment * dt * xComponent
            self.cameraPositionY += positionAdjustment * dt * yComponent
            self.cameraPositionZ += positionAdjustment * dt * zComponent
        if self.keyMap["backward"]:
            self.cameraPositionX -= positionAdjustment * dt * xComponent
            self.cameraPositionY -= positionAdjustment * dt * yComponent
            self.cameraPositionZ -= positionAdjustment * dt * zComponent

        self.camera.setX(self.cameraPositionX)
        self.camera.setY(self.cameraPositionY)
        self.camera.setZ(self.cameraPositionZ)
        self.camera.setHpr(self.cameraYaw, self.cameraPitch, 0)

    def carForwardImpact(self):
        # update position so that it is pointing right directions
        #(dirX, dirY, dirZ) = self.findCarFrontDir()
        #self.carRayForward.setDirection(dirX, dirY, dirZ)
        degToRad = math.pi / 180
        # + math.pi since it is taking corner and going to center rather
        # than opposite that function actually does
        #(centerX,centerY) = self.findActualCenter(0,0,self.adjustedXForCenter,
        #                                   self.adjustedYForCenter, self.carYaw
        #                                   +math.pi)
        posAboveGround = 5
        # need to update with new coordinates
        self.carCollideTrav.traverse(render)
        collisions = list(self.carForwardHandler.getEntries())
        # closest collision using pythagorean formula
        collisions.sort(
            key=lambda x:
            (x.getSurfacePoint(render).getX() - self.carPositionX)**2 +
            (x.getSurfacePoint(render).getY() - self.carPositionY)**2)
        if (len(collisions) > 0):
            (actualX, actualY) = RacingGame.findActualCenter(
                self, self.carPositionX, self.carPositionY,
                self.adjustedXForCenter, self.adjustedYForCenter, self.carYaw)
            distance = (
                (collisions[0].getSurfacePoint(render).getX() - actualX)**2 +
                (collisions[0].getSurfacePoint(render).getY() - actualY)**
                2)**.5
            error = .9  # so that the collisionray does not detect car itself
            return distance / 2 <= self.adjustedYForCenter * .9
        else:
            return False

    def findCarNewXandY(self):
        # Get the time that elapsed since last frame.  We multiply this with
        # the desired speed in order to find out with which distance to move
        # in order to achieve that desired speed.
        deltaTime = globalClock.getDt()
        degreeAdjustment = 60
        positionAdjustment = 100
        # should switch rad and Deg in variable name
        radToDeg = math.pi / 180
        # the x and y component of left and right moves, do not need to
        # compensate in z axis because not doing any roll, so there should be
        # no zComponent
        xComponent = math.sin(self.carYaw * radToDeg)
        yComponent = math.cos(self.carYaw * radToDeg)
        if self.keyMap["left"]:
            self.carYaw += degreeAdjustment * deltaTime
        if self.keyMap["right"]:
            self.carYaw -= degreeAdjustment * deltaTime
        if (self.keyMap["forward"] and not self.carForwardImpact()):
            self.carPositionX -= positionAdjustment * deltaTime * xComponent
            self.carPositionY += positionAdjustment * deltaTime * yComponent
        if self.keyMap["backward"]:
            self.carPositionX += positionAdjustment * deltaTime * xComponent
            self.carPositionY -= positionAdjustment * deltaTime * yComponent
        # need to consider both the x and y component of offset for both
        # because x slowly changes to y as it turns
        (actualXPos, actualYPos) = RacingGame.findActualCenter(
            self, self.carPositionX, self.carPositionY,
            self.adjustedXForCenter, self.adjustedYForCenter, self.carYaw)
        self.car.setX(actualXPos)
        self.car.setY(actualYPos)
        self.car.setZ(self.carPositionZ)
        self.car.setHpr(self.carYaw, self.carPitch, 0)

    def setCarZ(self):
        # almost directly taken from ralph example
        entries = list(self.handler.getEntries())
        entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())
        # worry about which thing it collides with later
        if (len(entries) > 0):
            # and entries[0].getIntoNode().getName() == "mountainCollide":
            self.carPositionZ = (entries[0].getSurfacePoint(render).getZ())
        else:
            # because at 25 everything should be below car and do not want
            # to continually go up or else it may go up forever.
            self.carPositionZ = 25
        self.setCameraPositionBehindCar()

    def setCameraPositionBehindCar(self):
        # Modify view of camera so that it is behind car
        # should be named degToRad
        radToDeg = math.pi / 180
        distanceBehind = 200
        distanceAbove = 60
        self.camera.setHpr(self.carYaw, -.5, 0)
        (actualXPos, actualYPos) = self.findActualCenter(
            self.carPositionX, self.carPositionY, self.adjustedXForCenter,
            self.adjustedXForCenter, self.carYaw)
        camX = actualXPos + distanceBehind * math.sin(radToDeg * self.carYaw)
        camY = actualYPos - distanceBehind * math.cos(radToDeg * self.carYaw)
        camZ = self.carPositionZ + distanceAbove
        self.camera.setPos(camX, camY, camZ)

    def findActualCenter(self, positionX, positionY, adjustedX, adjustedY,
                         yaw):
        # will need to fix this later, it seems to be adjusting wrong
        # so that it is puting box away from click instead of on it
        # update, I think this is fixed?!?
        degToRad = math.pi / 180
        actualXPos = (positionX - adjustedX * math.cos(degToRad * yaw) +
                      adjustedY * math.sin(degToRad * yaw))
        actualYPos = (positionY - adjustedY * math.cos(degToRad * yaw) -
                      adjustedX * math.sin(degToRad * yaw))
        return (actualXPos, actualYPos)