Exemple #1
0
class YourClass(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        self.disableMouse()
        self.camera.setPos(campos[0], campos[1], campos[2])
        self.camera.lookAt(bcenter[0], bcenter[1], bcenter[2])
        self.plane = Plane(Vec3(pvector[0], pvector[1], pvector[2]),
                           Point3(bcenter[0], bcenter[1], bcenter[2]))
        taskMgr.add(self.__getMousePos, "_YourClass__getMousePos")

    def __getMousePos(self, task):
        poslst = []
        for mpos in (LPoint2f(-1, -1), LPoint2f(1, -1), LPoint2f(1, 1),
                     LPoint2f(-1, 1)):
            pos3d = Point3()
            nearPoint = Point3()
            farPoint = Point3()
            base.camLens.extrude(mpos, nearPoint, farPoint)
            if self.plane.intersectsLine(
                    pos3d, render.getRelativePoint(camera, nearPoint),
                    render.getRelativePoint(camera, farPoint)):
                pass
            poslst.append(pos3d)
            global count
            count = count + 1
        if count > 9:
            print_message(poslst)
            exit()
        else:
            return task.again
Exemple #2
0
 def getMousePlaneIntersect(self, mPos3Dref, normVec):
     mPos = base.mouseWatcherNode.getMouse()
     plane = Plane(normVec, self.grabModelNP.getPos())
     nearPoint = Point3()
     farPoint = Point3()
     base.camLens.extrude(mPos, nearPoint, farPoint)
     if plane.intersectsLine(mPos3Dref,
         render.getRelativePoint(camera, nearPoint),
         render.getRelativePoint(camera, farPoint)):
         return True
     return False
Exemple #3
0
class YourClass(ShowBase):
	def __init__(self):
		ShowBase.__init__(self)
		self.disableMouse()
		self.camera.setPos(campos[0], campos[1], campos[2])
		self.camera.lookAt(bcenter[0], bcenter[1], bcenter[2])
		self.plane = Plane(Vec3(pvector[0], pvector[1], pvector[2]), Point3(bcenter[0], bcenter[1], bcenter[2]))
		taskMgr.add(self.__getMousePos, "_YourClass__getMousePos")
		
	def __getMousePos(self, task):
		coords = []
		for pixel in pixels:
			mpos = LPoint2f((pixel[0]-250)/250, (250-pixel[1])/250)
			pos3d = Point3()
			nearPoint = Point3()
			farPoint = Point3()
			base.camLens.extrude(mpos, nearPoint, farPoint)
			if self.plane.intersectsLine(pos3d,	render.getRelativePoint(camera, nearPoint),	render.getRelativePoint(camera, farPoint)):
				pass
			coords.append([pos3d[0], pos3d[1], pos3d[2]])
		coordls['coord'] = coords
		with open(filename, "w") as lujs: json.dump(coordls, lujs)
		exit()
Exemple #4
0
class Scene():
    def __init__(self, root, loader, show_base):
        ''' Main scene class
        @param root: root node for the scene
        @param loader: models loader
        @param show_base: link to the ShowBase exemplar, i.e. base 
            or app, which inherited from ShowBase
        @param path_dict: dictionary with pathes to search 
            resources (sounds, meshes, images, shaders) type:path
        '''
        self.root = root
        self.loader = loader
        self.show_base = show_base
        self.path_dict = {
            'sounds': 'res',
            'meshes': 'res',
            'images': 'res',
            'materials': 'res'
        }
        # Raw data, which should loaded from JSON file
        self.data_dict = {
            'objects': {},
            'assets': {},
            'scene': {},
            'materials': {}
        }
        # Data after passing through import extension strored in
        # variables below this comment
        self.objects = {}
        self.lights = {}
        self.sounds = {}
        self.cameras = {}
        self.textures = {}
        self.meshes = {}
        # Container for different options which can be used by extensions
        self.flags = {}

        # Builtin variables
        self._current_cam_number = 0
        self._level_plane = Plane(Vec3(0, 0, 1), Point3(0, 0, 0))

    def get_mouse_level_pos(self, task=None):
        if base.mouseWatcherNode.hasMouse():
            mpos = base.mouseWatcherNode.getMouse()
            pos3d = Point3()
            nearPoint = Point3()
            farPoint = Point3()
            self.show_base.camLens.extrude(mpos, nearPoint, farPoint)
            #if self.plane.intersectsLine(pos3d,
            #    render.getRelativePoint(camera, nearPoint),
            #    render.getRelativePoint(camera, farPoint)):
            #  print "Mouse ray intersects ground plane at ", pos3d
            self._level_plane.intersectsLine(
                pos3d, render.getRelativePoint(self.show_base.camera,
                                               nearPoint),
                render.getRelativePoint(self.show_base.camera, farPoint))
        if task:
            self._mouse_hit = pos3d
            return task.again
        else:
            return pos3d

    def pass_through_ext(self, action):

        for ext in extensions:
            if ext.target == 'prepare':
                ext.invoke(self, action)

        for ext in extensions:
            if ext.target == 'scene':
                ext.invoke(self, self.data_dict['scene'], action)
            elif ext.target == 'asset':
                for asset in self.data_dict['assets'].values():
                    ex.invoke(self, asset, action)
            elif ext.target == 'object':
                for obj in self.data_dict['objects'].values():
                    ext.invoke(self, obj, action)
            elif ext.target == 'material':
                for material in self.data_dict['materials'].values():
                    ext.invoke(self, material, action)
            elif ext.target not in ('prepare', 'finishing'):
                print 'ERROR:EXTENSION: unknown target "%s"' % ext.target

        for ext in extensions:
            if ext.target == 'finishing':
                ext.invoke(self, action)

    def load(self, fname):
        self.jsd_file = fname
        f = open(fname, 'r')
        data_dict = json.loads(f.read())
        f.close()
        self.data_dict = data_dict
        self.pass_through_ext('LOAD')

    def unload(self):
        self.pass_through_ext('UNLOAD')

    def switch_camera(self, camera=None):
        if self.cameras:
            if camera:
                if type(camera) == int:
                    t_cam = self.cameras.values()[camera]
                else:
                    t_cam = self.cameras[camera]
            else:
                self._current_cam_number += 1
                if self._current_cam_number >= len(self.cameras):
                    self._current_cam_number = 0
                t_cam = self.cameras.values()[self._current_cam_number]

            self.show_base.disableMouse()
            #self.show_base.camera.setMat(t_cam.getMat())
            self.show_base.camera.reparentTo(t_cam)
            self.show_base.cam.node().setLens(t_cam.node().getLens())

    def debug(self, frustum=True, light_pos=True, buffers=False):
        z = loader.loadModel('zup-axis')
        z.flattenStrong()
        if frustum:
            for cam in self.cameras.values():
                z.copyTo(cam)
                cam.node().showFrustum()
        for light in self.lights.values():
            if light_pos:
                z.copyTo(light['NP'])
            if 'shadow_cam' in light and frustum:
                light['shadow_cam'].node().showFrustum()
        if buffers:
            self.show_base.bufferViewer.toggleEnable()
        self.show_base.oobe()
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.damagePerSecond = -5.0

        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)

        if keys["shoot"]:
            if self.rayQueue.getNumEntries() > 0:
                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)

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

                self.beamModel.show()
        else:
            self.beamModel.hide()

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

        self.lastMousePos = mousePos

    def cleanup(self):
        base.cTrav.removeCollider(self.rayNodePath)

        GameObject.cleanup(self)
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)
Exemple #7
0
class CameraHandler(DirectObject):
    def __init__(self, showbase):
        DirectObject.__init__(self)

        self.showbase = showbase
        self.showbase.disableMouse()
        # This disables the default mouse based camera control used by panda. This default control is awkward, and won't be used.

        self.showbase.camera.setPos(0, -150, 200)
        self.showbase.camera.lookAt(0, 0, 0)
        # Gives the camera an initial position and rotation.

        self.mx, self.my = 0, 0
        # Sets up variables for storing the mouse coordinates

        self.orbiting = False
        # A boolean variable for specifying whether the camera is in orbiting mode. Orbiting mode refers to when the camera is being moved
        # because the user is holding down the right mouse button.

        self.target = Vec3()
        # sets up a vector variable for the camera's target. The target will be the coordinates that the camera is currently focusing on.

        self.camDist = 150
        # A variable that will determine how far the camera is from it's target focus

        self.panRateDivisor = 10
        # This variable is used as a divisor when calculating how far to move the camera when panning. Higher numbers will yield slower panning
        # and lower numbers will yield faster panning. This must not be set to 0.

        self.panZoneSize = .1
        # This variable controls how close the mouse cursor needs to be to the edge of the screen to start panning the camera. It must be less than 1,
        # and I recommend keeping it less than .2

        self.panLimitsX = Vec2(-1000, 1000)
        self.panLimitsY = Vec2(-1000, 1000)
        # These two vairables will serve as limits for how far the camera can pan, so you don't scroll away from the map.

        self.maxZoomOut = 500
        self.maxZoomIn = 25
        # These two variables set the max distance a person can zoom in or out

        self.orbitRate = 75
        # This is the rate of speed that the camera will rotate when middle mouse is pressed and mouse moved
        # recommended rate 50-100

        self.setTarget(0, 0, 0)
        # calls the setTarget function to set the current target position to the origin.

        self.turnCameraAroundPoint(0, 0)
        # calls the turnCameraAroundPoint function with a turn amount of 0 to set the camera position based on the target and camera distance

        self.accept("mouse2", self.startOrbit)
        # sets up the camrea handler to accept a right mouse click and start the "drag" mode.

        self.accept("mouse2-up", self.stopOrbit)
        # sets up the camrea handler to understand when the right mouse button has been released, and ends the "drag" mode when
        # the release is detected.

        self.storeX = 0
        self.storeY = 0
        # for storing of the x and y for the orbit

        # The next pair of lines use lambda, which creates an on-the-spot one-shot function.

        self.accept("wheel_up", self.zoomIn)
        # sets up the camera handler to detet when the mouse wheel is rolled upwards and uses a lambda function to call the
        # adjustCamDist function  with the argument 0.9

        self.accept("wheel_down", self.zoomOut)
        # sets up the camera handler to detet when the mouse wheel is rolled upwards and uses a lambda function to call the
        # adjustCamDist function  with the argument 1.1

        # Keys array (down if 1, up if 0)
        self.keys = {"cam-left": 0, "cam-right": 0, "cam-up": 0, "cam-down": 0}

        # Using Arrow Keys
        self.accept("arrow_left", self.setValue, [self.keys, "cam-left", 1])
        self.accept("arrow_right", self.setValue, [self.keys, "cam-right", 1])
        self.accept("arrow_up", self.setValue, [self.keys, "cam-up", 1])
        self.accept("arrow_down", self.setValue, [self.keys, "cam-down", 1])
        self.accept("arrow_left-up", self.setValue, [self.keys, "cam-left", 0])
        self.accept("arrow_right-up", self.setValue,
                    [self.keys, "cam-right", 0])
        self.accept("arrow_up-up", self.setValue, [self.keys, "cam-up", 0])
        self.accept("arrow_down-up", self.setValue, [self.keys, "cam-down", 0])

        self.keyPanRate = 1.5
        # pan rate for when user presses the arrow keys

        # set up plane for checking collision with for mouse-3d world
        self.plane = Plane(Vec3(0, 0, 1), Point3(0, 0, 0))

    def destroy(self):
        self.ignoreAll()

    def setValue(self, array, key, value):
        array[key] = value

    def clamp(self, val, minVal, maxVal):
        val = min(max(val, minVal), maxVal)
        return val

    def zoomOut(self):
        if self.camDist <= self.maxZoomOut:
            self.adjustCamDist(1.1)
        return True

    def zoomIn(self):
        if self.camDist >= self.maxZoomIn:
            self.adjustCamDist(0.9)
        return True

    def turnCameraAroundPoint(self, deltaX, deltaY):
        # This function performs two important tasks. First, it is used for the camera orbital movement that occurs when the
        # right mouse button is held down. It is also called with 0s for the rotation inputs to reposition the camera during the
        # panning and zooming movements.
        # The delta inputs represent the change in rotation of the camera, which is also used to determine how far the camera
        # actually moves along the orbit.

        newCamHpr = Vec3()
        newCamPos = Vec3()
        # Creates temporary containers for the new rotation and position values of the camera.

        camHpr = self.showbase.camera.getHpr()
        # Creates a container for the current HPR of the camera and stores those values.

        newCamHpr.setX(camHpr.getX() + deltaX)
        newCamHpr.setY(self.clamp(camHpr.getY() - deltaY, -85, -10))
        newCamHpr.setZ(camHpr.getZ())
        # Adjusts the newCamHpr values according to the inputs given to the function. The Y value is clamped to prevent
        # the camera from orbiting beneath the ground plane and to prevent it from reaching the apex of the orbit, which
        # can cause a disturbing fast-rotation glitch.

        self.showbase.camera.setHpr(newCamHpr)
        # Sets the camera's rotation to the new values.

        angleradiansX = newCamHpr.getX() * (math.pi / 180.0)
        angleradiansY = newCamHpr.getY() * (math.pi / 180.0)
        # Generates values to be used in the math that will calculate the new position of the camera.

        newCamPos.setX(self.camDist * math.sin(angleradiansX) *
                       math.cos(angleradiansY) + self.target.getX())
        newCamPos.setY(-self.camDist * math.cos(angleradiansX) *
                       math.cos(angleradiansY) + self.target.getY())
        newCamPos.setZ(-self.camDist * math.sin(angleradiansY) +
                       self.target.getZ())
        self.showbase.camera.setPos(newCamPos.getX(), newCamPos.getY(),
                                    newCamPos.getZ())
        # Performs the actual math to calculate the camera's new position and sets the camera to that position.
        # Unfortunately, this math is over my head, so I can't fully explain it.

        self.showbase.camera.lookAt(self.target.getX(), self.target.getY(),
                                    self.target.getZ())

    # Points the camera at the target location.

    def getTarget(self):
        return self.target

    # returns the cur

    def setTarget(self, x, y, z):
        # This function is used to give the camera a new target position.
        x = self.clamp(x, self.panLimitsX.getX(), self.panLimitsX.getY())
        self.target.setX(x)
        y = self.clamp(y, self.panLimitsY.getX(), self.panLimitsY.getY())
        self.target.setY(y)
        self.target.setZ(z)

    # Stores the new target position values in the target variable. The x and y values are clamped to the pan limits.

    def setPanLimits(self, xMin, xMax, yMin, yMax):
        # This function is used to set the limitations of the panning movement.

        self.panLimitsX = (xMin, xMax)
        self.panLimitsY = (yMin, yMax)

    # Sets the inputs into the limit variables.

    def startOrbit(self):
        # This function puts the camera into orbiting mode.

        # Get windows properties
        props = WindowProperties()
        # Set Hide Cursor Property
        # props.setCursorHidden(True)
        # Set properties
        self.showbase.win.requestProperties(props)
        # hide cursor

        if self.showbase.mouseWatcherNode.hasMouse():
            # We're going to use the mouse, so we have to make sure it's in the game window. If it's not and we try to use it, we'll get
            # a crash error.
            mpos = self.showbase.mouseWatcherNode.getMouse()
            self.storeX = mpos.getX()
            self.storeY = mpos.getY()
        # take current cursor values

        self.showbase.win.movePointer(0,
                                      self.showbase.win.getXSize() / 2,
                                      self.showbase.win.getYSize() / 2)
        # set to center
        self.mx = 0
        self.my = 0

        self.orbiting = True

    # Sets the orbiting variable to true to designate orbiting mode as on.

    def stopOrbit(self):
        # This function takes the camera out of orbiting mode.

        self.orbiting = False
        # Sets the orbiting variable to false to designate orbiting mode as off.

        self.showbase.win.movePointer(
            0, int((self.storeX + 1.0) / 2 * self.showbase.win.getXSize()),
            int(self.showbase.win.getYSize() -
                ((self.storeY + 1.0) / 2 * self.showbase.win.getYSize())))
        # set to taken cursor values from startOrbit
        if self.showbase.mouseWatcherNode.hasMouse():
            # We're going to use the mouse, so we have to make sure it's in the game window. If it's not and we try to use it, we'll get
            # a crash error.
            mpos = self.showbase.mouseWatcherNode.getMouse()
            self.mx = mpos.getX()
            self.my = mpos.getY()

        # Get windows properties
        props = WindowProperties()
        # Set Hide Cursor Property
        props.setCursorHidden(False)
        # Set properties
        self.showbase.win.requestProperties(props)

    # reshow cursor

    def adjustCamDist(self, distFactor):
        # This function increases or decreases the distance between the camera and the target position to simulate zooming in and out.
        # The distFactor input controls the amount of camera movement.
        # For example, inputing 0.9 will set the camera to 90% of it's previous distance.

        self.camDist = self.camDist * distFactor
        # Sets the new distance into self.camDist.

        self.turnCameraAroundPoint(0, 0)

    # Calls turnCameraAroundPoint with 0s for the rotation to reset the camera to the new position.

    def camMoveTask(self, dt):
        # This task is the camera handler's work house. It's set to be called every frame and will control both orbiting and panning the camera.

        if self.showbase.mouseWatcherNode.hasMouse():
            # We're going to use the mouse, so we have to make sure it's in the game window. If it's not and we try to use it, we'll get
            # a crash error.

            mpos = self.showbase.mouseWatcherNode.getMouse()
            # Gets the mouse position

            if self.orbiting:
                # Checks to see if the camera is in orbiting mode. Orbiting mode overrides panning, because it would be problematic if, while
                # orbiting the camera the mouse came close to the screen edge and started panning the camera at the same time.

                self.turnCameraAroundPoint(
                    (self.mx - mpos.getX()) * self.orbitRate * dt,
                    (self.my - mpos.getY()) * self.orbitRate * dt)

            else:
                # If the camera isn't in orbiting mode, we check to see if the mouse is close enough to the edge of the screen to start panning

                moveY = False
                moveX = False
                # these two booleans are used to denote if the camera needs to pan. X and Y refer to the mouse position that causes the
                # panning. X is the left or right edge of the screen, Y is the top or bottom.

                if self.my > (1 - self.panZoneSize):
                    angleradiansX1 = self.showbase.camera.getH() * (math.pi /
                                                                    180.0)
                    panRate1 = (1 - self.my - self.panZoneSize) * (
                        self.camDist / self.panRateDivisor)
                    moveY = True
                if self.my < (-1 + self.panZoneSize):
                    angleradiansX1 = self.showbase.camera.getH() * (
                        math.pi / 180.0) + math.pi
                    panRate1 = (1 + self.my - self.panZoneSize) * (
                        self.camDist / self.panRateDivisor)
                    moveY = True
                if self.mx > (1 - self.panZoneSize):
                    angleradiansX2 = self.showbase.camera.getH() * (
                        math.pi / 180.0) + math.pi * 0.5
                    panRate2 = (1 - self.mx - self.panZoneSize) * (
                        self.camDist / self.panRateDivisor)
                    moveX = True
                if self.mx < (-1 + self.panZoneSize):
                    angleradiansX2 = self.showbase.camera.getH() * (
                        math.pi / 180.0) - math.pi * 0.5
                    panRate2 = (1 + self.mx - self.panZoneSize) * (
                        self.camDist / self.panRateDivisor)
                    moveX = True
                # These four blocks check to see if the mouse cursor is close enough to the edge of the screen to start panning and then
                # perform part of the math necessary to find the new camera position. Once again, the math is a bit above my head, so
                # I can't properly explain it. These blocks also set the move booleans to true so that the next lines will move the camera.

                # If up or down keys are pressed
                if self.keys["cam-up"] ^ self.keys["cam-down"]:
                    moveY = True
                    panRate1 = self.keyPanRate
                    # Update warlock position on z plane
                    if self.keys["cam-up"]:
                        angleradiansX1 = self.showbase.camera.getH() * (
                            math.pi / 180.0) + math.pi
                    if self.keys["cam-down"]:
                        angleradiansX1 = self.showbase.camera.getH() * (
                            math.pi / 180.0)

                # If left or right keys are pressed
                if self.keys["cam-left"] ^ self.keys["cam-right"]:
                    moveX = True
                    panRate2 = self.keyPanRate
                    # Update warlock position on x plane
                    if self.keys["cam-left"]:
                        angleradiansX2 = self.showbase.camera.getH() * (
                            math.pi / 180.0) + math.pi * 0.5
                    if self.keys["cam-right"]:
                        angleradiansX2 = self.showbase.camera.getH() * (
                            math.pi / 180.0) - math.pi * 0.5

                if moveY:
                    tempX = self.target.getX(
                    ) + math.sin(angleradiansX1) * panRate1 * dt * 50
                    tempX = self.clamp(tempX, self.panLimitsX.getX(),
                                       self.panLimitsX.getY())
                    self.target.setX(tempX)
                    tempY = self.target.getY(
                    ) - math.cos(angleradiansX1) * panRate1 * dt * 50
                    tempY = self.clamp(tempY, self.panLimitsY.getX(),
                                       self.panLimitsY.getY())
                    self.target.setY(tempY)
                    self.turnCameraAroundPoint(0, 0)
                if moveX:
                    tempX = self.target.getX(
                    ) - math.sin(angleradiansX2) * panRate2 * dt * 50
                    tempX = self.clamp(tempX, self.panLimitsX.getX(),
                                       self.panLimitsX.getY())
                    self.target.setX(tempX)
                    tempY = self.target.getY(
                    ) + math.cos(angleradiansX2) * panRate2 * dt * 50
                    tempY = self.clamp(tempY, self.panLimitsY.getX(),
                                       self.panLimitsY.getY())
                    self.target.setY(tempY)
                    self.turnCameraAroundPoint(0, 0)
                # These two blocks finalize the math necessary to find the new camera position and apply the transformation to the
                # camera's TARGET. Then turnCameraAroundPoint is called with 0s for rotation, and it resets the camera position based
                # on the position of the target. The x and y values are clamped to the pan limits before they are applied.
                # print self.target)
                self.mx = mpos.getX()
                self.my = mpos.getY()
                # The old mouse positions are updated to the current mouse position as the final step.

    # Finds 3d world point on the z = 0 plane for destination/target
    def getMouse3D(self):
        # make sure process has the mouse to not cause error
        if self.showbase.mouseWatcherNode.hasMouse():
            # get screen coordinates of mouse
            mpos = self.showbase.mouseWatcherNode.getMouse()
            pos3d = Point3()
            nearPoint = Point3()
            farPoint = Point3()
            # find vector of cameras facing from mouse screen coordinates and get near and far points on frustrum
            self.showbase.camLens.extrude(mpos, nearPoint, farPoint)
            # check for intersection with z = 0 plane
            if self.plane.intersectsLine(
                    pos3d,
                    self.showbase.render.getRelativePoint(
                        self.showbase.camera, nearPoint),
                    self.showbase.render.getRelativePoint(
                        self.showbase.camera, farPoint)):
                # return this position if exists
                return pos3d
        # or return (-1, -1, -1)
        return Vec3(-1, -1, -1)