Exemple #1
0
class FPSCamera(DirectObject):

    MaxP = 90.0
    MinP = -90.0
    PitchUpdateEpsilon = 0.1
    ViewModelFOV = 70.0

    BobCycleMin = 1.0
    BobCycleMax = 0.45
    Bob = 0.002
    BobUp = 0.5

    PunchDamping = 9.0
    PunchSpring = 65.0

    PrintAnimLengths = False

    def __init__(self):
        DirectObject.__init__(self)

        self.mouseEnabled = False

        self.lastCamRoot2Quat = Quat(Quat.identQuat())

        self.punchAngleVel = Vec3(0)
        self.punchAngle = Vec3(0)

        self.lastFacing = Vec3(0)

        self.lastMousePos = Point2(0)
        self.currMousePos = Point2(0)

        self.bobTime = 0
        self.lastBobTime = 0

        self.lastVMPos = Point3(0)

        self.camRoot = NodePath("camRoot")
        self.camRoot2 = self.camRoot.attachNewNode("camRoot2")
        self.lastPitch = 0

        self.lastEyeHeight = 0.0

        # Updates to the transform of camRoot
        self.vmRender = NodePath(
            BSPRender('vmRender', BSPLoader.getGlobalPtr()))
        self.vmRender.setShaderAuto()
        self.vmRoot = self.vmRender.attachNewNode('vmRoot')
        self.vmRoot2 = self.vmRoot.attachNewNode(ModelRoot('vmRoot2'))
        self.viewModel = Actor(
            "phase_14/models/char/v_toon_arms.bam",
            {
                "zero": "phase_14/models/char/v_toon_arms.egg",

                # Squirt gun viewmodel animations
                "sg_draw": "phase_14/models/char/v_toon_arms-draw.egg",
                "sg_idle": "phase_14/models/char/v_toon_arms-idle.egg",
                "sg_inspect": "phase_14/models/char/v_toon_arms-inspect.egg",
                "sg_shoot_begin":
                "phase_14/models/char/v_toon_arms-shoot_begin.egg",
                "sg_shoot_loop":
                "phase_14/models/char/v_toon_arms-shoot_loop.egg",
                "sg_shoot_end":
                "phase_14/models/char/v_toon_arms-shoot_end.egg",
                "pie_draw": "phase_14/models/char/v_toon_arms-pie_draw.egg",
                "pie_idle": "phase_14/models/char/v_toon_arms-pie_idle.egg",
                "button_draw":
                "phase_14/models/char/v_toon_arms-button_draw.egg",
                "button_idle":
                "phase_14/models/char/v_toon_arms-button_idle.egg",
                "button_press":
                "phase_14/models/char/v_toon_arms-button_press.egg",
                "gumball_draw":
                "phase_14/models/char/v_toon_arms-gumball_draw.egg",
                "gumball_idle":
                "phase_14/models/char/v_toon_arms-gumball_idle.egg",
                "gumball_fire":
                "phase_14/models/char/v_toon_arms-gumball_fire.egg",
                "hose_draw": "phase_14/models/char/v_toon_arms-hose_draw.egg",
                "hose_idle": "phase_14/models/char/v_toon_arms-hose_idle.egg",
                "hose_shoot_begin":
                "phase_14/models/char/v_toon_arms-hose_shoot_begin.egg",
                "hose_shoot_loop":
                "phase_14/models/char/v_toon_arms-hose_shoot_loop.egg",
                "hose_shoot_end":
                "phase_14/models/char/v_toon_arms-hose_shoot_end.egg",
                "tnt_draw": "phase_14/models/char/v_toon_arms-tnt_draw.egg",
                "tnt_idle": "phase_14/models/char/v_toon_arms-tnt_idle.egg",
                "tnt_throw": "phase_14/models/char/v_toon_arms-tnt_throw.egg",
                "slap_idle": "phase_14/models/char/v_toon_arms-slap_idle.egg",
                "slap_hit": "phase_14/models/char/v_toon_arms-slap_hit.egg",
                "sound": "phase_14/models/char/v_toon_arms-sound.egg"
            })
        self.viewModel.setBlend(
            frameBlend=base.config.GetBool("interpolate-frames", False))
        self.viewModel.reparentTo(self.vmRoot2)
        self.viewModel.find("**/hands").setTwoSided(True)
        self.viewModel.hide()

        self.defaultViewModel = self.viewModel
        self.idealFov = self.ViewModelFOV

        precacheActor(self.viewModel)
        #self.viewModel.clearMaterial()
        #self.viewModel.setMaterial(CIGlobals.getCharacterMaterial(specular = (0, 0, 0, 1)), 1)
        self.viewportLens = PerspectiveLens()
        self.viewportLens.setMinFov(self.ViewModelFOV / (4. / 3.))
        self.viewportLens.setNear(0.3)
        # Updates to the transform of base.camera
        self.viewportCam = base.makeCamera(base.win,
                                           clearDepth=True,
                                           camName='fpsViewport',
                                           mask=CIGlobals.ViewModelCamMask,
                                           lens=self.viewportLens)
        # Pretend to be the main camera so the viewmodel gets ambient probes updated
        self.viewportCam.node().setTag("__mainpass__", "1")
        self.viewportCam.reparentTo(self.vmRoot)

        self.vmGag = None
        self.vmAnimTrack = None
        self.dmgFade = OnscreenImage(image="phase_14/maps/damage_effect.png",
                                     parent=render2d)
        self.dmgFade.setBin('gui-popup', 100)
        self.dmgFade.setTransparency(1)
        self.dmgFade.setColorScale(1, 1, 1, 0)
        self.dmgFadeIval = None

        #self.accept('v', self.vmRender.ls)

        #base.bspLoader.addDynamicNode(self.vmRoot)

        if self.PrintAnimLengths:
            print "v_toon_arms animation lengths:"
            for anim in self.viewModel.getAnimNames():
                print "\t{0}\t:\t{1}".format(anim,
                                             self.viewModel.getDuration(anim))

        taskMgr.add(self.__vpDebugTask, "vpdebutask", sort=-100)

    def setViewModelFOV(self, fov):
        self.idealFov = fov

    def restoreViewModelFOV(self):
        self.idealFov = self.ViewModelFOV

    def swapViewModel(self, newViewModel, fov=70.0):
        if newViewModel.isEmpty():
            return

        isHidden = False
        if not self.viewModel.isEmpty():
            self.viewModel.reparentTo(hidden)
            isHidden = self.viewModel.isHidden()

        self.viewModel = newViewModel
        self.viewModel.reparentTo(self.vmRoot2)
        if isHidden:
            self.viewModel.hide()
        else:
            self.viewModel.show()

        self.setViewModelFOV(fov)

    def restoreViewModel(self):
        isHidden = False
        if not self.viewModel.isEmpty():
            self.viewModel.reparentTo(hidden)
            isHidden = self.viewModel.isHidden()

        self.viewModel = self.defaultViewModel
        self.viewModel.reparentTo(self.vmRoot2)
        if isHidden:
            self.viewModel.hide()
        else:
            self.viewModel.show()

        self.restoreViewModelFOV()

    def addViewPunch(self, punch):
        self.punchAngleVel += punch * 20

    def resetViewPunch(self, tolerance=0.0):
        if tolerance != 0.0:
            tolerance *= tolerance
            check = self.punchAngleVel.lengthSquared(
            ) + self.punchAngle.lengthSquared()
            if check > tolerance:
                return

        self.punchAngle = Vec3(0)
        self.punchAngleVel = Vec3(0)

    def decayPunchAngle(self):
        if self.punchAngle.lengthSquared(
        ) > 0.001 or self.punchAngleVel.lengthSquared() > 0.001:
            dt = globalClock.getDt()
            self.punchAngle += self.punchAngleVel * dt
            damping = 1 - (self.PunchDamping * dt)

            if damping < 0:
                damping = 0
            self.punchAngleVel *= damping

            # Torsional spring
            springForceMag = self.PunchSpring * dt
            springForceMag = CIGlobals.clamp(springForceMag, 0.0, 2.0)
            self.punchAngleVel -= self.punchAngle * springForceMag

            # Don't wrap around
            self.punchAngle.set(CIGlobals.clamp(self.punchAngle[0], -179, 179),
                                CIGlobals.clamp(self.punchAngle[1], -89, 89),
                                CIGlobals.clamp(self.punchAngle[2], -89, 89))
        else:
            self.punchAngle = Vec3(0)
            self.punchAngleVel = Vec3(0)

    def hideViewModel(self):
        self.viewModel.hide(BitMask32.allOn())

    def showViewModel(self):
        if not base.localAvatar.isFirstPerson():
            return

        self.viewModel.showThrough(CIGlobals.ViewModelCamMask)

    def __vpDebugTask(self, task):
        if self.vmRender.getState() != render.getState():
            # pretend like the view model is part of the main scene
            self.vmRender.setState(render.getState())

        self.viewportLens.setAspectRatio(base.getAspectRatio())
        self.viewportLens.setMinFov(self.idealFov / (4. / 3.))
        self.vmRoot.setTransform(render, self.camRoot.getTransform(render))
        self.viewportCam.setTransform(render, base.camera.getTransform(render))

        # Since the viewmodel is not underneath BSPRender, it's not going to be automatically
        # influenced by the ambient probes. We need to do this explicitly.
        #base.bspLoader.updateDynamicNode(self.vmRoot)

        #self.viewportDebug.setImage(self.viewportCam.node().getDisplayRegion(0).getScreenshot())

        return task.cont

    def handleSuitAttack(self, attack):
        print "FPSCamera handleSuitAttack:", attack

    def doDamageFade(self, r, g, b, severity=1.0):
        if self.dmgFadeIval:
            self.dmgFadeIval.finish()
            self.dmgFadeIval = None
        severity = min(1.0, severity)
        self.dmgFadeIval = Sequence(
            LerpColorScaleInterval(self.dmgFade,
                                   0.25, (r, g, b, severity), (r, g, b, 0),
                                   blendType='easeOut'), Wait(1.0),
            LerpColorScaleInterval(self.dmgFade,
                                   2.0, (r, g, b, 0), (r, g, b, severity),
                                   blendType='easeInOut'))
        self.dmgFadeIval.start()

    def setVMAnimTrack(self, track, loop=False):
        self.clearVMAnimTrack()

        self.vmAnimTrack = track
        if loop:
            self.vmAnimTrack.loop()
        else:
            self.vmAnimTrack.start()

    def clearVMAnimTrack(self):
        if self.vmAnimTrack:
            self.vmAnimTrack.pause()
            self.vmAnimTrack = None

    def setVMGag(self,
                 gag,
                 pos=(0, 0, 0),
                 hpr=(0, 0, 0),
                 scale=(1, 1, 1),
                 hand=0,
                 animate=True):
        self.clearVMGag()

        handNode = NodePath()
        if hand == ATTACK_HOLD_RIGHT:
            handNode = self.getViewModelRightHand()
        elif hand == ATTACK_HOLD_LEFT:
            handNode = self.getViewModelLeftHand()

        if isinstance(gag, Actor) and animate:
            self.vmGag = Actor(other=gag)
            self.vmGag.reparentTo(handNode)
            self.vmGag.loop('chan')
        else:
            self.vmGag = gag.copyTo(handNode)
        self.vmGag.setPos(pos)
        self.vmGag.setHpr(hpr)
        self.vmGag.setScale(scale)

    def clearVMGag(self):
        if self.vmGag:
            if isinstance(self.vmGag, Actor):
                self.vmGag.cleanup()
            self.vmGag.removeNode()
            self.vmGag = None

    def setup(self):
        try:
            # Match the arm color with the torso color of local avatar
            self.viewModel.find("**/arms").setColorScale(
                base.localAvatar.getTorsoColor(), 1)
            # Same with glove cover
            self.viewModel.find("**/hands").setColorScale(
                base.localAvatar.getGloveColor(), 1)
        except:
            pass

        self.attachCamera()

    def attachCamera(self, reset=True):
        if reset:
            self.camRoot.reparentTo(base.localAvatar)
            if base.localAvatar.isFirstPerson():
                self.camRoot.setPos(base.localAvatar.getEyePoint())
            else:
                self.camRoot.setPos(0, 0, max(base.localAvatar.getHeight(),
                                              3.0))
            self.camRoot.setHpr(0, 0, 0)
            self.camRoot2.setPosHpr(0, 0, 0, 0, 0, 0)

        base.camera.reparentTo(self.camRoot2)

        if base.localAvatar.isFirstPerson():
            base.camera.setPosHpr(0, 0, 0, 0, 0, 0)
        elif base.localAvatar.isThirdPerson():
            pos, lookAt = self.getThirdPersonBattleCam()
            base.localAvatar.smartCamera.setIdealCameraPos(pos)
            base.localAvatar.smartCamera.setLookAtPoint(lookAt)

    def getThirdPersonBattleCam(self):
        camHeight = max(base.localAvatar.getHeight(), 3.0)
        heightScaleFactor = camHeight * 0.3333333333

        return ((1, -5 * heightScaleFactor, 0), (1, 10, 0))

    def getViewModelLeftHand(self):
        return self.viewModel.find("**/def_left_hold")

    def getViewModelRightHand(self):
        return self.viewModel.find("**/def_right_hold")

    def getViewModel(self):
        return self.viewModel

    def acceptEngageKeys(self):
        self.acceptOnce("escape", self.__handleEscapeKey)

    def ignoreEngageKeys(self):
        self.ignore("escape")

    def enableMouseMovement(self):
        props = WindowProperties()
        props.setMouseMode(WindowProperties.MConfined)
        props.setCursorHidden(True)
        base.win.requestProperties(props)

        self.attachCamera(False)
        if base.localAvatar.isFirstPerson():
            base.localAvatar.getGeomNode().hide()

        base.win.movePointer(0,
                             base.win.getXSize() / 2,
                             base.win.getYSize() / 2)

        base.taskMgr.add(self.__updateTask, "mouseUpdateFPSCamera", sort=-40)
        self.acceptEngageKeys()

        self.mouseEnabled = True

        base.localAvatar.enableGagKeys()

    def disableMouseMovement(self, allowEnable=False, showAvatar=True):
        props = WindowProperties()
        props.setMouseMode(WindowProperties.MAbsolute)
        props.setCursorHidden(False)
        base.win.requestProperties(props)

        base.taskMgr.remove("mouseUpdateFPSCamera")

        base.localAvatar.disableGagKeys()

        if allowEnable:
            self.acceptEngageKeys()
        else:
            self.ignoreEngageKeys()
            if showAvatar or base.localAvatar.isThirdPerson():
                base.localAvatar.getGeomNode().show()
            else:
                base.localAvatar.getGeomNode().hide()

        self.mouseEnabled = False

    def __handleEscapeKey(self):
        if self.mouseEnabled:
            self.disableMouseMovement(True)
        else:
            self.enableMouseMovement()

    #def doCameraJolt(self, amplitude, horizRange = [-1, 1], vertRange = [1]):
    #h = random.choice(horizRange) * amplitude
    #p = random.choice(vertRange) * amplitude
    #nquat = Quat(Quat.identQuat())
    #nquat.setHpr((h, p, 0))
    #self.lastCamRoot2Quat = self.lastCamRoot2Quat + nquat

    #Effects.createPBounce(self.camRoot2, 3, self.camRoot2.getHpr(), 1, amplitude).start()
    #Effects.createHBounce(self.camRoot2, 3, self.camRoot2.getHpr(), 1, amplitude).start()

    def handleJumpHardLand(self):
        down = Parallel(
            LerpPosInterval(base.cam,
                            0.1, (-0.1, 0, -0.2), (0, 0, 0),
                            blendType='easeOut'),
            LerpHprInterval(base.cam,
                            0.1, (0, 0, -2.5), (0, 0, 0),
                            blendType='easeOut'))
        up = Parallel(
            LerpPosInterval(base.cam,
                            0.7, (0, 0, 0), (-0.1, 0, -0.2),
                            blendType='easeInOut'),
            LerpHprInterval(base.cam,
                            0.7, (0, 0, 0), (0, 0, -2.5),
                            blendType='easeInOut'))
        Sequence(down, up).start()

    def __updateTask(self, task):
        # TODO -- This function does a lot of math, I measured it to take .5 ms on my laptop
        #         That's a lot of time for something miniscule like sway and bob.

        dt = globalClock.getDt()
        time = globalClock.getFrameTime()

        if base.localAvatar.isFirstPerson():
            eyePoint = base.localAvatar.getEyePoint()
            if base.localAvatar.walkControls.crouching:
                eyePoint[2] = eyePoint[2] / 2.0
            eyePoint[2] = CIGlobals.lerpWithRatio(eyePoint[2],
                                                  self.lastEyeHeight, 0.4)
            self.lastEyeHeight = eyePoint[2]

        camRootAngles = Vec3(0)

        # Mouse look around
        mw = base.mouseWatcherNode
        if mw.hasMouse():
            md = base.win.getPointer(0)
            center = Point2(base.win.getXSize() / 2, base.win.getYSize() / 2)

            xDist = md.getX() - center.getX()
            yDist = md.getY() - center.getY()

            sens = self.__getMouseSensitivity()

            angular = -(xDist * sens) / dt
            base.localAvatar.walkControls.controller.setAngularMovement(
                angular)
            camRootAngles.setY(self.lastPitch - yDist * sens)

            if camRootAngles.getY() > FPSCamera.MaxP:
                camRootAngles.setY(FPSCamera.MaxP)
                yDist = 0
            elif camRootAngles.getY() < FPSCamera.MinP:
                yDist = 0
                camRootAngles.setY(FPSCamera.MinP)

            base.win.movePointer(0, int(center.getX()), int(center.getY()))

        if base.localAvatar.isFirstPerson():
            # Camera / viewmodel bobbing
            vmBob = Point3(0)
            vmAngles = Vec3(0)
            vmRaise = Point3(0)
            camBob = Point3(0)

            maxSpeed = base.localAvatar.walkControls.BattleRunSpeed * 16.0

            speed = base.localAvatar.walkControls.speeds.length() * 16.0
            speed = max(-maxSpeed, min(maxSpeed, speed))

            bobOffset = CIGlobals.remapVal(speed, 0, maxSpeed, 0.0, 1.0)

            self.bobTime += (time - self.lastBobTime) * bobOffset
            self.lastBobTime = time

            # Calculate the vertical bob
            cycle = self.bobTime - int(
                self.bobTime / self.BobCycleMax) * self.BobCycleMax
            cycle /= self.BobCycleMax
            if cycle < self.BobUp:
                cycle = math.pi * cycle / self.BobUp
            else:
                cycle = math.pi + math.pi * (cycle - self.BobUp) / (1.0 -
                                                                    self.BobUp)

            verticalBob = speed * 0.005
            verticalBob = verticalBob * 0.3 + verticalBob * 0.7 * math.sin(
                cycle)
            verticalBob = max(-7.0, min(4.0, verticalBob))
            verticalBob /= 16.0

            # Calculate the lateral bob
            cycle = self.bobTime - int(
                self.bobTime / self.BobCycleMax * 2) * self.BobCycleMax * 2
            cycle /= self.BobCycleMax * 2
            if cycle < self.BobUp:
                cycle = math.pi * cycle / self.BobUp
            else:
                cycle = math.pi + math.pi * (cycle - self.BobUp) / (1.0 -
                                                                    self.BobUp)

            lateralBob = speed * 0.005
            lateralBob = lateralBob * 0.3 + lateralBob * 0.7 * math.sin(cycle)
            lateralBob = max(-7.0, min(4.0, lateralBob))
            lateralBob /= 16.0

            # Apply bob, but scaled down a bit
            vmBob.set(lateralBob * 0.8, 0, verticalBob * 0.1)
            # Z bob a bit more
            vmBob[2] += verticalBob * 0.1
            # Bob the angles
            vmAngles[2] += verticalBob * 0.5
            vmAngles[1] -= verticalBob * 0.4
            vmAngles[0] -= lateralBob * 0.3

            # ================================================================
            # Viewmodel lag/sway

            angles = self.camRoot.getHpr(render)
            quat = Quat()
            quat.setHpr(angles)
            invQuat = Quat()
            invQuat.invertFrom(quat)

            maxVMLag = 1.5
            lagforward = quat.getForward()
            if dt != 0.0:
                lagdifference = lagforward - self.lastFacing
                lagspeed = 5.0
                lagdiff = lagdifference.length()
                if (lagdiff > maxVMLag) and (maxVMLag > 0.0):
                    lagscale = lagdiff / maxVMLag
                    lagspeed *= lagscale

                self.lastFacing = CIGlobals.extrude(self.lastFacing,
                                                    lagspeed * dt,
                                                    lagdifference)
                self.lastFacing.normalize()
                lfLocal = invQuat.xform(lagdifference)
                vmBob = CIGlobals.extrude(vmBob, 5.0 / 16.0, lfLocal * -1.0)

            pitch = angles[1]
            if pitch > 180:
                pitch -= 360
            elif pitch < -180:
                pitch += 360

            vmBob = CIGlobals.extrude(vmBob, pitch * (0.035 / 16),
                                      Vec3.forward())
            vmBob = CIGlobals.extrude(vmBob, pitch * (0.03 / 16), Vec3.right())
            vmBob = CIGlobals.extrude(vmBob, pitch * (0.02 / 16), Vec3.up())

            # ================================================================

            vmRaise.set(
                0, 0, 0
            )  #(0, abs(camRootAngles.getY()) * -0.002, camRootAngles.getY() * 0.002)
            camBob.set(0, 0, 0)

            # Apply bob, raise, and sway to the viewmodel.
            self.viewModel.setPos(vmBob + vmRaise + self.lastVMPos)
            self.vmRoot2.setHpr(vmAngles)
            self.camRoot.setPos(eyePoint + camBob)

        newPitch = camRootAngles.getY()

        if abs(newPitch - self.lastPitch) > self.PitchUpdateEpsilon:
            # Broadcast where our head is looking
            head = base.localAvatar.getPart("head")
            if head and not head.isEmpty():
                # Constrain the head pitch a little bit so it doesn't look like their head snapped
                headPitch = max(-47, newPitch)
                headPitch = min(75, headPitch)
                base.localAvatar.b_setLookPitch(headPitch)

        self.lastPitch = newPitch

        if base.localAvatar.isFirstPerson():
            # Apply punch angle
            self.decayPunchAngle()
            camRootAngles += self.punchAngle

        self.camRoot.setHpr(camRootAngles)

        return task.cont

    def __getMouseSensitivity(self):
        return CIGlobals.getSettingsMgr().getSetting('fpmgms').getValue()

    def cleanup(self):
        taskMgr.remove("vpdebutask")
        self.disableMouseMovement(False, False)
        self.clearVMAnimTrack()
        self.clearVMGag()
        if self.viewModel:
            self.viewModel.cleanup()
            self.viewModel.removeNode()
        self.viewModel = None
        if self.vmRender:
            self.vmRender.removeNode()
        self.vmRender = None
        self.vmRoot = None
        self.vmRoot2 = None
        self.viewportLens = None
        if self.viewportCam:
            self.viewportCam.removeNode()
        self.viewportCam = None
        if self.camRoot:
            self.camRoot.removeNode()
        self.camRoot = None
        self.camRoot2 = None
        self.lastEyeHeight = None
        self.lastPitch = None
        self.bobTime = None
        self.lastBobTime = None
        self.mouseEnabled = None
        self.lastCamRoot2Quat = None
        self.punchAngleVel = None
        self.punchAngle = None
        self.lastFacing = None
        self.lastMousePos = None
        self.currMousePos = None
        self.lastVMPos = None
        self.defaultViewModel = None
        self.idealFov = None
        self.vmGag = None
        self.vmAnimTrack = None
        self.dmgFade = None
        self.dmgFadeIval = None
        self.ignoreAll()
 def setup(self):
   
   num_sectors = 6
   sector_length = 100    
   angle_incr = 360.0/num_sectors    
   angle_offset = -180
   radius = 0.5*sector_length/sin(deg2Rad(0.5*angle_incr))
   y_offset = radius*cos(deg2Rad(0.5*angle_incr))
   z_incr = 8
   logging.info("radius = " + str(radius) + ' sector length = ' + str(2*radius*sin(deg2Rad(angle_incr))) )
   
   dummy_node = NodePath('dummy-node')
   dummy_node.reparentTo(self)
   for i in range(0,num_sectors):
     
     # updating z value
     z = i*z_incr
     
     # placing dummy node
     dummy_node.clearTransform(self)
     dummy_node.setZ(self,z)
     dummy_node.setHpr(self,i*angle_incr,0,0)
     dummy_node.setY(dummy_node,-y_offset)
     dummy_node.setX(dummy_node,-0.5*sector_length)      
     
     # creating sector
     tf = dummy_node.getTransform(self)
     sector = self.createSector(tf,'sector' + str(i))
     self.__createPlatforms__(sector,i == 0) 
     self.__createBoxes__(sector)   
     
   # adding sector transitions
   sector = None
   dest_sector = None
   for i in range(0,num_sectors-1):
     
     sector = self.getSectors()[i]
     dest_sector = self.getSectors()[i+1]
     sector.connect(dest_sector,Vec3(100,0,28),True)
      
     continue
   
     # TODO: Unreachable code below left here for reference only, will get removed
     #        after the whole sector transition functionality becomes more stable.
     if i == 0:        
       # following sector
       dest_sector = self.getSectors()[i+1]
       sector.addTransition(dest_sector,Vec3(100,0,28),True)
       
     elif i > 0 and i < num_sectors - 1:
       # following sector
       dest_sector = self.getSectors()[i+1]
       sector.addTransition(dest_sector,Vec3(100,0,28),True)
       
       # preceeding sector
       dest_sector = self.getSectors()[i-1]
       sector.addTransition(dest_sector,Vec3(0,0,20),False)
       
     else:
       # preceeding sector
       dest_sector = self.getSectors()[i-1]
       sector.addTransition(dest_sector,Vec3(0,0,20),False)
     
   dummy_node.removeNode()