예제 #1
0
    def test_windows_setup(self):
        self.store.storeNode('files/node.bam', '', 'window_r')
        self.store.storeNode('files/hood_node.bam', '', 'window_l')

        windows = DNAWindows('windows')

        x = .1
        y = .4
        np = NodePath('window_root')
        code = 'window_l'
        scale = 1.25
        color = Vec4(.842, .167, .361, 1)

        windows.makeWindows(x, y, np, code, scale, color, self.store, False)

        # Check if the nodes attributes are correct
        model = np.find('**/node')
        self.assertFalse(model.isEmpty())
        self.assertEqual(model.getPos(np), Point3(x, 0, y))
        self.assertEqual(model.getScale(np), Vec3(scale))

        # Now test with flip = True
        np.removeNode()
        np = NodePath('window_root')

        windows.makeWindows(x, y, np, code, scale, color, self.store, True)
        # Check if the nodes attributes are correct
        model = np.find('**/hood_node')
        self.assertFalse(model.isEmpty())
        self.assertEqual(model.getPos(np), Point3(x, 0, y))
        self.assertEqual(model.getScale(np), Vec3(scale))
예제 #2
0
    def test_windows_setup(self):
        self.store.storeNode('files/node.bam', '', 'window_r')
        self.store.storeNode('files/hood_node.bam', '', 'window_l')

        windows = DNAWindows('windows')

        x = .1
        y = .4
        np = NodePath('window_root')
        code = 'window_l'
        scale = 1.25
        color = Vec4(.842, .167, .361, 1)

        windows.makeWindows(x, y, np, code, scale, color, self.store, False)

        # Check if the nodes attributes are correct
        model = np.find('**/node')
        self.assertFalse(model.isEmpty())
        self.assertEqual(model.getPos(np), Point3(x, 0, y))
        self.assertEqual(model.getScale(np), Vec3(scale))

        # Now test with flip = True
        np.removeNode()
        np = NodePath('window_root')

        windows.makeWindows(x, y, np, code, scale, color, self.store, True)
        # Check if the nodes attributes are correct
        model = np.find('**/hood_node')
        self.assertFalse(model.isEmpty())
        self.assertEqual(model.getPos(np), Point3(x, 0, y))
        self.assertEqual(model.getScale(np), Vec3(scale))
예제 #3
0
    def createCamNodes(self):
        """Creates a few empty nodes around a plane which the camera might be
        parented to. It looks if there are cameras inside the model file and
        uses those if possible. Where everything named "camera CamType" is
        considered a camera. At least ThirdPerson, FirstPerson and Cockpit
        should be defined inside the egg file, otherwise some guessed defaults
        are taken.
        """

        # Look for cameras inside the model (loaded egg file)
        cameras = NodePath("cameras")
        _c = self.parent.node.findAllMatches("**/camera ?*")
        _c.removeDuplicatePaths()
        _c.reparentTo(cameras)

        if not _c.isEmpty():
            self.notifier.info("Cameras found under model:\n%s"
                               % _c)
        else:
            self.notifier.info("No cameras found under model.")

        # FirstPerson camera is a must-have. Set up a guessed one if none
        # defined yet.
        if cameras.find("camera FirstPerson").isEmpty():
            assert self.notifier.debug("No first person camera found in %s. "
                                  "Guessing best position." % self.parent.name)
            first_person = NodePath("camera FirstPerson")
            # TODO: Guess best position based on bounding box.
            first_person.setY(5)
            first_person.reparentTo(cameras)

        # ThirdPerson camera is a must-have. Set up a guessed one if none
        # defined yet.
        if cameras.find("camera ThirdPerson").isEmpty():
            assert self.notifier.debug("No third person camera found in %s. "
                                  "Guessing best position." % self.parent.name)
            third_person = NodePath("camera ThirdPerson")
            # TODO: Guess best position based on bounding box.
            third_person.setPos(0, -30, 5)
            #third_person.setP(-80)
            third_person.reparentTo(cameras)

        # Cockpit needs to be accurate. Don't try to guess it.
        if cameras.find("camera Cockpit").isEmpty():
            assert self.notifier.debug("No cockpit camera found in "
                                       "%s. Cockpit camera disabled."
                                       % self.parent.name)
        self.sideview_cam = NodePath("camera Sideview")
        self.sideview_cam.reparentTo(render)

        self.__cameras = cameras
        # Store the cams at parent node..
        # You can edit the camera nodes from outside as well.
        # If you attach new camera nodes, though, you'll have to call this
        # function again.
        cameras.reparentTo(self.parent.node)
예제 #4
0
    def load(self):
        self.root = NodePath('root')
        self.root.reparentTo(render)
        self.root.stash()

        self.world = loadMockup("cogdominium/mockup.egg")
        self.world.reparentTo(self.root)
        self.world.stash()

        # Setup and placement of starting platform
        self.startPlatform = loadMockup("cogdominium/start_platform.egg")
        startPlatformLoc = self.world.find("**/start_platform_loc")
        self.startPlatform.reparentTo(startPlatformLoc)
        colModel = self.startPlatform.find("**/col_floor")
        colModel.setTag('start_platform', '%s' % base.localAvatar.doId)

        # Here we set the current platform for the local player
        self.localPlayer.setCheckpointPlatform(self.startPlatform)

        # Setup and placement of the end platform
        self.endPlatform = loadMockup("cogdominium/end_platform.egg")
        endPlatformLoc = self.world.find("**/end_platform_loc")
        self.endPlatform.reparentTo(endPlatformLoc)
        colModel = self.endPlatform.find("**/col_floor")
        colModel.setTag('end_platform', '%s' % base.localAvatar.doId)

        # Setup and placement for all the fuel platforms
        fuelPlatformModel = loadMockup("cogdominium/fuel_platform.egg")
        fuelIndex = 1
        fuelLoc = self.world.find('**/fuel_platform_loc_%d' % fuelIndex)
        while not fuelLoc.isEmpty():
            fuelModel = NodePath("fuel_platform_%d" % fuelIndex)
            fuelPlatformModel.copyTo(fuelModel)
            fuelModel.reparentTo(fuelLoc)
            colModel = fuelModel.find("**/col_floor")
            colModel.setTag('fuel_platform', '%s' % base.localAvatar.doId)
            colModel.setTag('isUsed', '%s' % 0)
            self.fuelPlatforms[fuelModel.getName()] = fuelModel
            fuelIndex += 1
            fuelLoc = self.world.find('**/fuel_platform_loc_%d' % fuelIndex)

        self.accept("entercol_floor", self.handleCollision)

        self.skybox = self.world.find("**/skybox")
        self.upLimit = self.world.find("**/limit_up").getPos(render).getZ()
        self.downLimit = self.world.find("**/limit_down").getPos(render).getZ()
        self.leftLimit = self.world.find("**/limit_left").getPos(render).getX()
        self.rightLimit = self.world.find("**/limit_right").getPos(
            render).getX()

        del fuelPlatformModel

        self._initFog()
예제 #5
0
class AreaMap(Map):
    def __init__(self, area):
        Map.__init__(self, "map-" + area.getName())
        self.capturePoints = {}
        mapNode = area.getMapNode()
        if mapNode and not mapNode.isEmpty():
            geom = mapNode.getChild(0)
            geom.setScale(mapNode.getScale())
            geom.flattenStrong()
            mapNode.setScale(1)
            self.worldNode = mapNode
            self.map = self.worldNode.copyTo(NodePath())
            (a, b) = self.map.getTightBounds()
            diff = b - a
            h = diff[1]
            w = diff[0]
        else:
            self.worldNode = area
            self.map = NodePath("no map found")
            (a, b) = self.worldNode.geom.getTightBounds()
            diff = b - a
            h = diff[1]
            w = diff[0]
        ratio = h / w
        if ratio < 0.98999999999999999:
            normalScale = 2 / w
            screenScale = 1
        else:
            normalScale = 2 / h
            screenScale = 0.75
        self.map.clearTransform()
        self.map.show()
        self.screenNode = NodePath("Minimap-screenNode")
        self.screenNode.setP(90)
        self.screenNode.setScale(screenScale * normalScale)
        self.screenNode.hide()
        self.map.reparentTo(self.screenNode)
        self.mapOverlay = self.map.attachNewNode("mapOverlay")
        self.mapOverlay.wrtReparentTo(self.screenNode)
        self.radarTransformNode = NodePath("radarTransform")
        self.radarTransformNode.setScale(self.worldNode.getScale()[0])
        self.map.instanceTo(self.radarTransformNode)
        localAvatar.guiMgr.addMinimap(self)
        if self.allowOnScreen():
            self.addObject(MinimapFootprint(area))

        if self.allowOnScreen():
            if area.getUniqueId() not in [LocationIds.RAVENS_COVE_ISLAND]:
                for shop in area.getShopNodes():
                    uid = shop.getTag("Uid")
                    shopType = shop.getTag("ShopType")
                    self.addObject(MinimapShop(uid, shop, shopType))

            self.map.findAllMatches("**/=Holiday").stash()
            if base.cr.newsManager:
                for holiday in base.cr.newsManager.getHolidayList():
                    self.handleHolidayStarted(area, HolidayGlobals.getHolidayName(holiday))

        self.zoomLevels = area.getZoomLevels()
        self.accept("landMapRadarAxisChanged", self.setRadarAxis)

    def destroy(self):
        self.ignore("landMapRadarAxisChanged")
        if hasattr(base, "localAvatar"):
            localAvatar.guiMgr.removeMinimap(self)

        for holiday in self.capturePoints.keys():
            zones = self.capturePoints.pop(holiday, {})
            for object in zones.itervalues():
                self.removeObject(object)

        Map.destroy(self)

    def allowOnScreen(self):
        return self.map.find("minimap-card").isEmpty()

    def getZoomLevels(self):
        return self.zoomLevels

    def getWorldNode(self):
        return self.worldNode

    def getScreenNode(self):
        return self.screenNode

    def getOverlayNode(self):
        return self.mapOverlay

    def getCapturePoint(self, holidayId, zone):
        if self.capturePoints.has_key(holidayId):
            return self.capturePoints[holidayId][zone]

    def updateTask(self, task):
        self.update()
        return task.cont

    def update(self):
        for obj in self.objects:
            obj.updateOnMap(self)

    def addObject(self, object):
        Map.addObject(self, object)
        mapNode = object.getMapNode()
        mapNode.reparentTo(self.map, sort=object.SORT)
        object.getOverlayNode().reparentTo(self.mapOverlay, sort=object.SORT)
        object.addedToMap(self)

    def removeObject(self, object):
        Map.removeObject(self, object)
        object.getMapNode().detachNode()
        object.getOverlayNode().detachNode()
        object.removedFromMap(self)

    def updateRadarTransform(self, av):
        if self.radarAxis == Options.RadarAxisMap:
            self.radarTransformNode.setPosHprScale(-av.getPos(self.worldNode), VBase3(0), VBase3(1))
        else:
            holdHpr = av.getHpr()
            av.setH(camera.getH(render) - self.worldNode.getH(render))
            self.radarTransformNode.setTransform(self.worldNode.getTransform(av))
            av.setHpr(holdHpr)
        localAvatar.guiMgr.radarGui.updateDial(self)

    def getRadarNode(self):
        return self.radarTransformNode

    def handleHolidayStarted(self, area, holiday):
        self.map.findAllMatches("**/=Holiday=%s;+s" % (holiday,)).unstash()
        for node in area.getCapturePointNodes(holiday):
            zones = self.capturePoints.setdefault(holiday, {})
            zone = int(node.getTag("Zone"))
            if zone not in zones:
                object = MinimapCapturePoint(node, holiday, zone)
                zones[zone] = object
                self.addObject(object)
                continue

    handleHolidayStarted = report(types=["frameCount", "args"], dConfigParam="minimap")(handleHolidayStarted)

    def handleHolidayEnded(self, area, holiday, override=False):
        if holiday in InvasionGlobals.INVASION_IDS and not override:
            taskMgr.doMethodLater(10, self.handleInvasionEnded, "handleInvasionEnded", extraArgs=[area, holiday])
        else:
            self.map.findAllMatches("**/=Holiday=%s;+s" % (holiday,)).stash()
            for object in self.capturePoints.pop(holiday, {}).itervalues():
                self.removeObject(object)

    handleHolidayEnded = report(types=["frameCount", "args"], dConfigParam="minimap")(handleHolidayEnded)

    def handleInvasionEnded(self, area, holiday):
        if not localAvatar.guiMgr.invasionScoreboard:
            self.map.findAllMatches("**/=Holiday=%s;+s" % (holiday,)).stash()
            for object in self.capturePoints.pop(holiday, {}).itervalues():
                self.removeObject(object)
    def getShip(
        self,
        shipClass,
        style=ShipGlobals.Styles.Undefined,
        logo=ShipGlobals.Logos.Undefined,
        hullDesign=None,
        detailLevel=2,
        wantWheel=True,
        hullMaterial=None,
        sailMaterial=None,
        sailPattern=None,
        prowType=None,
    ):
        Ship = Ship
        import pirates.ship

        modelClass = ShipGlobals.getModelClass(shipClass)
        shipConfig = ShipGlobals.getShipConfig(shipClass)
        if style == ShipGlobals.Styles.Undefined:
            style = shipConfig["defaultStyle"]

        complexCustomization = 0
        if sailPattern and sailMaterial and hullMaterial or SailReplace.has_key(shipClass):
            complexCustomization = 1

        if not prowType:
            prowType = shipConfig["prow"]

        if not hullMaterial:
            hullMaterial = style

        if not sailMaterial:
            if SailReplace.has_key(shipClass):
                sailMaterial = SailReplace[shipClass]
            else:
                sailMaterial = style

        if not sailPattern:
            sailPattern = style

        shipHullTexture = ShipBlueprints.getShipTexture(hullMaterial)
        shipTextureSail = ShipBlueprints.getShipTexture(sailMaterial)
        logoTex = None
        if logo:
            logoTex = ShipBlueprints.getLogoTexture(logo)

        sailPatternTex = None
        if sailPattern:
            sailPatternTex = ShipBlueprints.getSailTexture(sailPattern)

        self.notify.debug("%s %s" % (sailPattern, logo))
        if logo == ShipGlobals.Logos.Undefined:
            logo = shipConfig["sailLogo"]

        if logo in ShipGlobals.MAST_LOGO_PLACEMENT_LIST:
            placeLogos = 1
        else:
            placeLogos = 0
        if modelClass <= ShipGlobals.INTERCEPTORL3:
            mastHax = True
        else:
            mastHax = False
        customHull = hullDesign is not None
        if not logo != 0:
            pass
        customMasts = sailPattern != 0
        hull = self.getHull(modelClass, customHull)
        breakAnims = {}
        metaAnims = {}
        hitAnims = {}
        root = NodePath("Ship")
        hull.locators.reparentTo(root)
        charRoot = root.attachNewNode(Character("ShipChar"))
        collisions = root.attachNewNode("collisions")
        lodNode = charRoot.attachNewNode(LODNode("lod"))
        if detailLevel == 0:
            lodNode.node().addSwitch(200, 0)
            lodNode.node().addSwitch(800, 200)
            lodNode.node().addSwitch(100000, 800)
            high = lodNode.attachNewNode("high")
            low = lodNode.attachNewNode("low")
            med = NodePath("med")
            superlow = lodNode.attachNewNode("superlow")
        elif detailLevel == 1:
            lodNode.node().addSwitch(300, 0)
            lodNode.node().addSwitch(1000, 300)
            lodNode.node().addSwitch(2000, 1000)
            lodNode.node().addSwitch(100000, 2000)
            high = lodNode.attachNewNode("high")
            med = lodNode.attachNewNode("med")
            low = lodNode.attachNewNode("low")
            superlow = lodNode.attachNewNode("superlow")
        else:
            lodNode.node().addSwitch(750, 0)
            lodNode.node().addSwitch(3000, 750)
            lodNode.node().addSwitch(8000, 3000)
            lodNode.node().addSwitch(100000, 8000)
            high = lodNode.attachNewNode("high")
            med = lodNode.attachNewNode("med")
            low = lodNode.attachNewNode("low")
            superlow = lodNode.attachNewNode("superlow")
        mastSetup = ShipGlobals.getMastSetup(shipClass)
        for data in [
            (0, "location_mainmast_0"),
            (1, "location_mainmast_1"),
            (2, "location_mainmast_2"),
            (3, "location_aftmast*"),
            (4, "location_foremast*"),
        ]:
            mastData = mastSetup.get(data[0])
            if mastData:
                mast = self.mastSets[mastData[0]].getMastSet(mastData[1] - 1, customMasts)
                mastRoot = hull.locators.find("**/%s" % data[1]).getTransform(hull.locators)
                model = NodePath(mast.charRoot)
                model.setTransform(mastRoot)
                if complexCustomization:
                    model.setTexture(shipTextureSail)

                useLogoTex = logoTex
                if placeLogos:
                    mastNum = data[0]
                    if mastNum not in ShipGlobals.MAST_LOGO_PLACEMENT.get(modelClass):
                        useLogoTex = None

                charBundle = mast.charRoot.getBundle(0)
                if data[0] < 3:
                    for side in ["left", "right"]:
                        ropeNode = hull.locators.find("**/location_ropeLadder_%s_%s" % (side, data[0]))
                        if ropeNode:
                            transform = ropeNode.getTransform(NodePath(mast.charRoot))
                            charBundle.findChild("def_ladder_0_%s" % side).applyFreeze(transform)
                            continue

                if sailPatternTex and useLogoTex:
                    for node in model.findAllMatches("**/sails"):
                        node.setTextureOff(TextureStage.getDefault())
                        node.setTexture(self.colorLayer, sailPatternTex)
                        node.setTexture(self.logoLayer, logoTex)
                        node.setTexture(self.vertLayer, shipTextureSail)
                        node.setTexture(self.baseLayer, shipTextureSail)

                elif sailPatternTex:
                    for node in model.findAllMatches("**/sails"):
                        node.setTextureOff(TextureStage.getDefault())
                        node.setTexture(self.colorLayer, sailPatternTex)
                        node.setTexture(self.vertLayer, shipTextureSail)
                        node.setTexture(self.baseLayer, shipTextureSail)

                elif useLogoTex:
                    for node in model.findAllMatches("**/sails"):
                        node.setTextureOff(TextureStage.getDefault())
                        node.setTexture(self.logoLayerNoColor, logoTex)
                        node.setTexture(self.vertLayer, shipTextureSail)
                        node.setTexture(self.baseLayer, shipTextureSail)

                model.flattenLight()
                if detailLevel == 0:
                    model.find("**/low").copyTo(high)
                    model.find("**/low").copyTo(low)
                    model.find("**/superlow").copyTo(superlow)
                elif detailLevel == 1:
                    model.find("**/med").copyTo(high)
                    model.find("**/med").copyTo(med)
                    low.node().stealChildren(model.find("**/low").node())
                    superlow.node().stealChildren(model.find("**/superlow").node())
                elif detailLevel == 2:
                    high.node().stealChildren(model.find("**/high").node())
                    med.node().stealChildren(model.find("**/med").node())
                    low.node().stealChildren(model.find("**/low").node())
                    superlow.node().stealChildren(model.find("**/superlow").node())

                mastRoot = mast.collisions.find("**/collision_masts")
                if modelClass > ShipGlobals.INTERCEPTORL3 or data[0] != 3:
                    mastCode = str(data[0])
                    mastRoot.setTag("Mast Code", mastCode)
                else:
                    mastRoot.setName("colldision_sub_mast")
                    mastRoot.reparentTo(collisions.find("**/collision_masts"))
                    mastCode = "0"
                for coll in mast.collisions.findAllMatches("**/collision_sail_*"):
                    coll.setName("Sail-%s" % data[0])
                    coll.setTag("Mast Code", mastCode)

                for coll in mast.collisions.findAllMatches("**/sail_*"):
                    coll.setName("Sail-%s" % data[0])
                    coll.setTag("Mast Code", mastCode)

                collisions.node().stealChildren(mast.collisions.node())
                charBundle = mast.charRoot.getBundle(0)
                if mastHax and data[0] == 3:
                    breakAnims[0][0].storeAnim(
                        charBundle.loadBindAnim(loader.loader, mast.breakAnim[0], -1, MastSubset, True), "1"
                    )
                    breakAnims[0][1].storeAnim(
                        charBundle.loadBindAnim(loader.loader, mast.breakAnim[1], -1, MastSubset, True), "1"
                    )
                    tempHit = hitAnims[0]
                    tempHit[0].storeAnim(
                        charBundle.loadBindAnim(loader.loader, mast.hitAnim, -1, HitMastSubset, True), "1"
                    )
                    tempHit[1].storeAnim(
                        charBundle.loadBindAnim(loader.loader, mast.hitAnim, -1, PartSubset(), True), "1"
                    )
                else:
                    breakAnims[data[0]] = (AnimControlCollection(), AnimControlCollection())
                    breakAnims[data[0]][0].storeAnim(
                        charBundle.loadBindAnim(loader.loader, mast.breakAnim[0], -1, MastSubset, True), "0"
                    )
                    breakAnims[data[0]][1].storeAnim(
                        charBundle.loadBindAnim(loader.loader, mast.breakAnim[1], -1, MastSubset, True), "0"
                    )
                    tempHit = [AnimControlCollection(), AnimControlCollection()]
                    tempHit[0].storeAnim(
                        charBundle.loadBindAnim(loader.loader, mast.hitAnim, -1, HitMastSubset, True), "0"
                    )
                    tempHit[1].storeAnim(
                        charBundle.loadBindAnim(loader.loader, mast.hitAnim, -1, PartSubset(), True), "0"
                    )
                    hitAnims[data[0]] = tempHit
                for (anim, fileName) in mast.metaAnims.iteritems():
                    if anim not in metaAnims:
                        metaAnims[anim] = AnimControlCollection()

                    if anim not in MissingAnims.get(modelClass, []):
                        ac = charBundle.loadBindAnim(loader.loader, fileName, -1, SailSubset, True)
                        if ac:
                            metaAnims[anim].storeAnim(ac, str(metaAnims[anim].getNumAnims()))

                charRoot.node().combineWith(mast.charRoot)
                continue

        if self.wantProws and prowType:
            (highSprit, medSprit, lowSprit) = self.sprits[prowType].getAsset()
            transform = hull.locators.find("**/location_bowsprit").getTransform(hull.locators)
            highSprit.setTransform(transform)
            medSprit.setTransform(transform)
            lowSprit.setTransform(transform)
            highSprit.reparentTo(hull.geoms[0])
            medSprit.reparentTo(hull.geoms[1])
            lowSprit.reparentTo(hull.geoms[2])

        if wantWheel:
            shipWheel = ShipBlueprints.getWheel()
            wheelPoint = hull.locators.find("**/location_wheel;+s").getTransform(hull.locators)
            shipWheel.setTransform(wheelPoint)
            shipWheel.flattenLight()
            shipWheel.find("**/collisions").copyTo(collisions)
            hull.geoms[0].node().stealChildren(shipWheel.find("**/high").node())
            hull.geoms[1].node().stealChildren(shipWheel.find("**/med").node())
            hull.geoms[2].node().stealChildren(shipWheel.find("**/low").node())

        if complexCustomization:
            hull.geoms[0].setTexture(shipHullTexture)
            hull.geoms[0].flattenLight()
            hull.geoms[1].setTexture(shipHullTexture)
            hull.geoms[1].flattenLight()
            hull.geoms[2].setTexture(shipHullTexture)
            hull.geoms[2].flattenLight()
            hull.geoms[3].setTexture(shipHullTexture)
            hull.geoms[3].flattenLight()

        high.attachNewNode(ModelNode("non-animated")).node().stealChildren(hull.geoms[0].node())
        med.attachNewNode(ModelNode("non-animated")).node().stealChildren(hull.geoms[1].node())
        low.attachNewNode(ModelNode("non-animated")).node().stealChildren(hull.geoms[2].node())
        superlow.attachNewNode(ModelNode("non-animated")).node().stealChildren(hull.geoms[3].node())
        collisions.node().stealChildren(hull.collisions.node())
        hull.locators.stash()
        charRoot.flattenStrong()
        ship = Ship.Ship(shipClass, root, breakAnims, hitAnims, metaAnims, collisions, hull.locators)
        if not complexCustomization:
            ship.char.setTexture(shipHullTexture)

        return ship
예제 #7
0
    def getShip(self,
                shipClass,
                style=ShipGlobals.Styles.Undefined,
                logo=ShipGlobals.Logos.Undefined,
                hullDesign=None,
                detailLevel=2,
                wantWheel=True,
                hullMaterial=None,
                sailMaterial=None,
                sailPattern=None,
                prowType=None,
                invertLogo=False):
        Ship = Ship
        import pirates.ship
        modelClass = ShipGlobals.getModelClass(shipClass)
        shipConfig = ShipGlobals.getShipConfig(shipClass)
        if style == ShipGlobals.Styles.Undefined:
            style = shipConfig['defaultStyle']

        complexCustomization = 0
        if sailPattern and sailMaterial and hullMaterial or SailReplace.has_key(
                shipClass):
            complexCustomization = 1

        if not prowType:
            prowType = shipConfig['prow']

        if not hullMaterial:
            hullMaterial = style

        if not sailMaterial:
            if SailReplace.has_key(shipClass):
                sailMaterial = SailReplace[shipClass]
            else:
                sailMaterial = style

        if not sailPattern:
            sailPattern = style

        shipHullTexture = ShipBlueprints.getShipTexture(hullMaterial)
        shipTextureSail = ShipBlueprints.getShipTexture(sailMaterial)
        logoTex = None
        if logo:
            logoTex = ShipBlueprints.getLogoTexture(logo)

        sailPatternTex = None
        if sailPattern:
            sailPatternTex = ShipBlueprints.getSailTexture(sailPattern)

        self.notify.debug('%s %s' % (sailPattern, logo))
        if logo == ShipGlobals.Logos.Undefined:
            logo = shipConfig['sailLogo']

        if logo in ShipGlobals.MAST_LOGO_PLACEMENT_LIST:
            placeLogos = 1
        else:
            placeLogos = 0
        if modelClass <= ShipGlobals.INTERCEPTORL3:
            mastHax = True
        else:
            mastHax = False
        customHull = hullDesign is not None
        if not logo != 0:
            pass
        customMasts = sailPattern != 0
        hull = self.getHull(modelClass, customHull)
        breakAnims = {}
        metaAnims = {}
        hitAnims = {}
        root = NodePath('Ship')
        hull.locators.reparentTo(root)
        charRoot = root.attachNewNode(Character('ShipChar'))
        collisions = root.attachNewNode('collisions')
        lodNode = charRoot.attachNewNode(LODNode('lod'))
        if detailLevel == 0:
            lodNode.node().addSwitch(200, 0)
            lodNode.node().addSwitch(800, 200)
            lodNode.node().addSwitch(100000, 800)
            high = lodNode.attachNewNode('high')
            low = lodNode.attachNewNode('low')
            med = NodePath('med')
            superlow = lodNode.attachNewNode('superlow')
        elif detailLevel == 1:
            lodNode.node().addSwitch(300, 0)
            lodNode.node().addSwitch(1000, 300)
            lodNode.node().addSwitch(2000, 1000)
            lodNode.node().addSwitch(100000, 2000)
            high = lodNode.attachNewNode('high')
            med = lodNode.attachNewNode('med')
            low = lodNode.attachNewNode('low')
            superlow = lodNode.attachNewNode('superlow')
        else:
            lodNode.node().addSwitch(750, 0)
            lodNode.node().addSwitch(3000, 750)
            lodNode.node().addSwitch(8000, 3000)
            lodNode.node().addSwitch(100000, 8000)
            high = lodNode.attachNewNode('high')
            med = lodNode.attachNewNode('med')
            low = lodNode.attachNewNode('low')
            superlow = lodNode.attachNewNode('superlow')
        mastSetup = ShipGlobals.getMastSetup(shipClass)
        for data in [(0, 'location_mainmast_0'), (1, 'location_mainmast_1'),
                     (2, 'location_mainmast_2'), (3, 'location_aftmast*'),
                     (4, 'location_foremast*')]:
            mastData = mastSetup.get(data[0])
            if mastData:
                mast = self.mastSets[mastData[0]].getMastSet(
                    mastData[1] - 1, customMasts)
                mastRoot = hull.locators.find('**/%s' % data[1]).getTransform(
                    hull.locators)
                model = NodePath(mast.charRoot)
                model.setTransform(mastRoot)
                if complexCustomization:
                    model.setTexture(shipTextureSail)

                useLogoTex = logoTex
                if placeLogos:
                    mastNum = data[0]
                    if mastNum not in ShipGlobals.MAST_LOGO_PLACEMENT.get(
                            modelClass):
                        useLogoTex = None

                charBundle = mast.charRoot.getBundle(0)
                if data[0] < 3:
                    for side in ['left', 'right']:
                        ropeNode = hull.locators.find(
                            '**/location_ropeLadder_%s_%s' % (side, data[0]))
                        if ropeNode:
                            transform = ropeNode.getTransform(
                                NodePath(mast.charRoot))
                            charBundle.findChild('def_ladder_0_%s' %
                                                 side).applyFreeze(transform)
                            continue

                if sailPatternTex and useLogoTex:
                    for node in model.findAllMatches('**/sails'):
                        node.setTextureOff(TextureStage.getDefault())
                        node.setTexture(self.colorLayer, sailPatternTex)
                        if invertLogo:
                            node.setTexture(self.logoLayerInv, logoTex)
                        else:
                            node.setTexture(self.logoLayer, logoTex)
                        node.setTexture(self.vertLayer, shipTextureSail)
                        node.setTexture(self.baseLayer, shipTextureSail)

                elif sailPatternTex:
                    for node in model.findAllMatches('**/sails'):
                        node.setTextureOff(TextureStage.getDefault())
                        node.setTexture(self.colorLayer, sailPatternTex)
                        node.setTexture(self.vertLayer, shipTextureSail)
                        node.setTexture(self.baseLayer, shipTextureSail)

                elif useLogoTex:
                    for node in model.findAllMatches('**/sails'):
                        node.setTextureOff(TextureStage.getDefault())
                        if invertLogo:
                            node.setTexture(self.logoLayerNoColorInv, logoTex)
                        else:
                            node.setTexture(self.logoLayerNoColor, logoTex)
                        node.setTexture(self.vertLayer, shipTextureSail)
                        node.setTexture(self.baseLayer, shipTextureSail)

                model.flattenLight()
                if detailLevel == 0:
                    model.find('**/low').copyTo(high)
                    model.find('**/low').copyTo(low)
                    model.find('**/superlow').copyTo(superlow)
                elif detailLevel == 1:
                    model.find('**/med').copyTo(high)
                    model.find('**/med').copyTo(med)
                    low.node().stealChildren(model.find('**/low').node())
                    superlow.node().stealChildren(
                        model.find('**/superlow').node())
                elif detailLevel == 2:
                    high.node().stealChildren(model.find('**/high').node())
                    med.node().stealChildren(model.find('**/med').node())
                    low.node().stealChildren(model.find('**/low').node())
                    superlow.node().stealChildren(
                        model.find('**/superlow').node())

                mastRoot = mast.collisions.find('**/collision_masts')
                if modelClass > ShipGlobals.INTERCEPTORL3 or data[0] != 3:
                    mastCode = str(data[0])
                    mastRoot.setTag('Mast Code', mastCode)
                else:
                    mastRoot.setName('colldision_sub_mast')
                    mastRoot.reparentTo(collisions.find('**/collision_masts'))
                    mastCode = '0'
                for coll in mast.collisions.findAllMatches(
                        '**/collision_sail_*'):
                    coll.setName('Sail-%s' % data[0])
                    coll.setTag('Mast Code', mastCode)

                for coll in mast.collisions.findAllMatches('**/sail_*'):
                    coll.setName('Sail-%s' % data[0])
                    coll.setTag('Mast Code', mastCode)

                collisions.node().stealChildren(mast.collisions.node())
                charBundle = mast.charRoot.getBundle(0)
                if mastHax and data[0] == 3:
                    breakAnims[0][0].storeAnim(
                        charBundle.loadBindAnim(loader.loader,
                                                mast.breakAnim[0], -1,
                                                MastSubset, True), '1')
                    breakAnims[0][1].storeAnim(
                        charBundle.loadBindAnim(loader.loader,
                                                mast.breakAnim[1], -1,
                                                MastSubset, True), '1')
                    tempHit = hitAnims[0]
                    tempHit[0].storeAnim(
                        charBundle.loadBindAnim(loader.loader, mast.hitAnim,
                                                -1, HitMastSubset, True), '1')
                    tempHit[1].storeAnim(
                        charBundle.loadBindAnim(loader.loader, mast.hitAnim,
                                                -1, PartSubset(), True), '1')
                else:
                    breakAnims[data[0]] = (AnimControlCollection(),
                                           AnimControlCollection())
                    breakAnims[data[0]][0].storeAnim(
                        charBundle.loadBindAnim(loader.loader,
                                                mast.breakAnim[0], -1,
                                                MastSubset, True), '0')
                    breakAnims[data[0]][1].storeAnim(
                        charBundle.loadBindAnim(loader.loader,
                                                mast.breakAnim[1], -1,
                                                MastSubset, True), '0')
                    tempHit = [
                        AnimControlCollection(),
                        AnimControlCollection()
                    ]
                    tempHit[0].storeAnim(
                        charBundle.loadBindAnim(loader.loader, mast.hitAnim,
                                                -1, HitMastSubset, True), '0')
                    tempHit[1].storeAnim(
                        charBundle.loadBindAnim(loader.loader, mast.hitAnim,
                                                -1, PartSubset(), True), '0')
                    hitAnims[data[0]] = tempHit
                for (anim, fileName) in mast.metaAnims.iteritems():
                    if anim not in metaAnims:
                        metaAnims[anim] = AnimControlCollection()

                    if anim not in MissingAnims.get(modelClass, []):
                        ac = charBundle.loadBindAnim(loader.loader, fileName,
                                                     -1, SailSubset, True)
                        if ac:
                            metaAnims[anim].storeAnim(
                                ac, str(metaAnims[anim].getNumAnims()))

                charRoot.node().combineWith(mast.charRoot)
                continue

        if self.wantProws and prowType:
            (highSprit, medSprit, lowSprit) = self.sprits[prowType].getAsset()
            transform = hull.locators.find(
                '**/location_bowsprit').getTransform(hull.locators)
            highSprit.setTransform(transform)
            medSprit.setTransform(transform)
            lowSprit.setTransform(transform)
            highSprit.reparentTo(hull.geoms[0])
            medSprit.reparentTo(hull.geoms[1])
            lowSprit.reparentTo(hull.geoms[2])

        if wantWheel:
            shipWheel = ShipBlueprints.getWheel()
            wheelPoint = hull.locators.find(
                '**/location_wheel;+s').getTransform(hull.locators)
            shipWheel.setTransform(wheelPoint)
            shipWheel.flattenLight()
            shipWheel.find('**/collisions').copyTo(collisions)
            hull.geoms[0].node().stealChildren(
                shipWheel.find('**/high').node())
            hull.geoms[1].node().stealChildren(shipWheel.find('**/med').node())
            hull.geoms[2].node().stealChildren(shipWheel.find('**/low').node())

        if complexCustomization:
            hull.geoms[0].setTexture(shipHullTexture)
            hull.geoms[0].flattenLight()
            hull.geoms[1].setTexture(shipHullTexture)
            hull.geoms[1].flattenLight()
            hull.geoms[2].setTexture(shipHullTexture)
            hull.geoms[2].flattenLight()
            hull.geoms[3].setTexture(shipHullTexture)
            hull.geoms[3].flattenLight()

        high.attachNewNode(ModelNode('non-animated')).node().stealChildren(
            hull.geoms[0].node())
        med.attachNewNode(ModelNode('non-animated')).node().stealChildren(
            hull.geoms[1].node())
        low.attachNewNode(ModelNode('non-animated')).node().stealChildren(
            hull.geoms[2].node())
        superlow.attachNewNode(ModelNode('non-animated')).node().stealChildren(
            hull.geoms[3].node())
        collisions.node().stealChildren(hull.collisions.node())
        hull.locators.stash()
        charRoot.flattenStrong()
        ship = Ship.Ship(shipClass, root, breakAnims, hitAnims, metaAnims,
                         collisions, hull.locators)
        if not complexCustomization:
            ship.char.setTexture(shipHullTexture)

        return ship
예제 #8
0
파일: Minimap.py 프로젝트: Kealigal/POS2013
class AreaMap(Map):
    
    def __init__(self, area):
        Map.__init__(self, 'map-' + area.getName())
        self.capturePoints = { }
        mapNode = area.getMapNode()
        if mapNode and not mapNode.isEmpty():
            geom = mapNode.getChild(0)
            geom.setScale(mapNode.getScale())
            geom.flattenStrong()
            mapNode.setScale(1)
            self.worldNode = mapNode
            self.map = self.worldNode.copyTo(NodePath())
            (a, b) = self.map.getTightBounds()
            diff = b - a
            h = diff[1]
            w = diff[0]
        else:
            self.worldNode = area
            self.map = NodePath('no map found')
            (a, b) = self.worldNode.geom.getTightBounds()
            diff = b - a
            h = diff[1]
            w = diff[0]
        ratio = h / w
        if ratio < 0.98999999999999999:
            normalScale = 2 / w
            screenScale = 1
        else:
            normalScale = 2 / h
            screenScale = 0.75
        self.map.clearTransform()
        self.map.show()
        self.screenNode = NodePath('Minimap-screenNode')
        self.screenNode.setP(90)
        self.screenNode.setScale(screenScale * normalScale)
        self.screenNode.hide()
        self.map.reparentTo(self.screenNode)
        self.mapOverlay = self.map.attachNewNode('mapOverlay')
        self.mapOverlay.wrtReparentTo(self.screenNode)
        self.radarTransformNode = NodePath('radarTransform')
        self.radarTransformNode.setScale(self.worldNode.getScale()[0])
        self.map.instanceTo(self.radarTransformNode)
        localAvatar.guiMgr.addMinimap(self)
        if self.allowOnScreen():
            self.addObject(MinimapFootprint(area))
        
        self.shops = set()
        if self.allowOnScreen():
            if area.getUniqueId() not in [
                LocationIds.RAVENS_COVE_ISLAND]:
                for shop in area.getShopNodes():
                    uid = shop.getTag('Uid')
                    shopType = shop.getTag('ShopType')
                    self.addObject(MinimapShop(uid, shop, shopType))
                
            
            self.map.findAllMatches('**/=Holiday').stash()
            if base.cr.newsManager:
                for holiday in base.cr.newsManager.getHolidayList():
                    self.handleHolidayStarted(area, HolidayGlobals.getHolidayName(holiday))
                
            
        
        self.zoomLevels = area.getZoomLevels()
        self.accept('landMapRadarAxisChanged', self.setRadarAxis)

    
    def destroy(self):
        self.ignore('landMapRadarAxisChanged')
        if hasattr(base, 'localAvatar'):
            localAvatar.guiMgr.removeMinimap(self)
        
        for shop in self.shops:
            self.removeObject(shop)
        
        self.shops = set()
        for holiday in self.capturePoints.keys():
            zones = self.capturePoints.pop(holiday, { })
            for object in zones.itervalues():
                self.removeObject(object)
            
        
        Map.destroy(self)

    
    def allowOnScreen(self):
        return self.map.find('minimap-card').isEmpty()

    
    def getZoomLevels(self):
        return self.zoomLevels

    
    def getWorldNode(self):
        return self.worldNode

    
    def getScreenNode(self):
        return self.screenNode

    
    def getOverlayNode(self):
        return self.mapOverlay

    
    def getCapturePoint(self, holidayId, zone):
        if self.capturePoints.has_key(holidayId):
            return self.capturePoints[holidayId][zone]
        

    
    def updateTask(self, task):
        self.update()
        return task.cont

    
    def update(self):
        for obj in self.objects:
            obj.updateOnMap(self)
        

    
    def addObject(self, object):
        Map.addObject(self, object)
        mapNode = object.getMapNode()
        mapNode.reparentTo(self.map, sort = object.SORT)
        object.getOverlayNode().reparentTo(self.mapOverlay, sort = object.SORT)
        object.addedToMap(self)

    
    def removeObject(self, object):
        Map.removeObject(self, object)
        object.getMapNode().detachNode()
        object.getOverlayNode().detachNode()
        object.removedFromMap(self)

    
    def updateRadarTransform(self, av):
        if self.radarAxis == Options.RadarAxisMap:
            self.radarTransformNode.setPosHprScale(-av.getPos(self.worldNode), VBase3(0), VBase3(1))
        else:
            holdHpr = av.getHpr()
            av.setH(camera.getH(render) - self.worldNode.getH(render))
            self.radarTransformNode.setTransform(self.worldNode.getTransform(av))
            av.setHpr(holdHpr)
        localAvatar.guiMgr.radarGui.updateDial(self)

    
    def getRadarNode(self):
        return self.radarTransformNode

    
    def handleHolidayStarted(self, area, holiday):
        self.map.findAllMatches('**/=Holiday=%s;+s' % (holiday,)).unstash()
        for node in area.getCapturePointNodes(holiday):
            zones = self.capturePoints.setdefault(holiday, { })
            zone = int(node.getTag('Zone'))
            if zone not in zones:
                object = MinimapCapturePoint(node, holiday, zone)
                zones[zone] = object
                self.addObject(object)
                continue
        

    handleHolidayStarted = report(types = [
        'frameCount',
        'args'], dConfigParam = 'minimap')(handleHolidayStarted)
    
    def handleHolidayEnded(self, area, holiday, override = False):
        if holiday in InvasionGlobals.INVASION_IDS and not override:
            taskMgr.doMethodLater(10, self.handleInvasionEnded, 'handleInvasionEnded', extraArgs = [
                area,
                holiday])
        else:
            self.map.findAllMatches('**/=Holiday=%s;+s' % (holiday,)).stash()
            for object in self.capturePoints.pop(holiday, { }).itervalues():
                self.removeObject(object)
            

    handleHolidayEnded = report(types = [
        'frameCount',
        'args'], dConfigParam = 'minimap')(handleHolidayEnded)
    
    def handleInvasionEnded(self, area, holiday):
        if not localAvatar.guiMgr.invasionScoreboard:
            self.map.findAllMatches('**/=Holiday=%s;+s' % (holiday,)).stash()
            for object in self.capturePoints.pop(holiday, { }).itervalues():
                self.removeObject(object)
예제 #9
0
class PlaneCamera(FSM, DirectObject):
    """Give this class a plane as argument and it will create
    some nodes around it which you can parent the camera to (if there are no
    such nodes yet). Keep in mind, that it only uses base.camera the whole
    time - no other cams are involved.

    Usage:
    plane_camera = PlaneCamera(aeroplane)
    plane_camera.setView("ThirdPerson")
    plane_camera.setView("Next")
    """
    def __init__(self, parent):
        """Arguments:
        parent -- Aeroplane which the camera should follow
        """

        # Used for debugging. Verbosity is set in config file.
        # Usually this is called self.notify, but in this case it would
        # override FSM's own.
        self.notifier = DirectNotify().newCategory("azure-camera")
        self.parent = parent
        # Replaced by a NodePath with all available cameras as children and
        # plane node as parent.
        self.cameras = None

        #if parent.__class__.__name__ is not "Aeroplane":
        if not isinstance(self.parent, Aeroplane):
            raise ParamError, "Parent must be an Aeroplane instance, " + \
                              "but is %s" % type(self.parent)

        FSM.__init__(self, "PlaneCamera: %s" % self.parent.name)
        DirectObject.__init__(self)

        try:
            self.camera = base.camera
        except:
            raise BaseMissing

        self.cameras = self.parent.node.find("cameras")
        if self.cameras.isEmpty():
            self.createCamNodes()
        self.updateCamArray()

        self.sideview_direction = 0

        # Set up the default camera
        self.setView("ThirdPerson")

    def createCamNodes(self):
        """Creates a few empty nodes around a plane which the camera might be
        parented to. It looks if there are cameras inside the model file and
        uses those if possible. Where everything named "camera CamType" is
        considered a camera. At least ThirdPerson, FirstPerson and Cockpit
        should be defined inside the egg file, otherwise some guessed defaults
        are taken.
        """

        # Look for cameras inside the model (loaded egg file)
        self.cameras = NodePath("cameras")
        found_cams = self.parent.node.findAllMatches("**/camera ?*")
        found_cams.removeDuplicatePaths()
        found_cams.reparentTo(self.cameras)

        if not found_cams.isEmpty():
            self.notifier.info("Cameras found under model:\n%s"
                               % found_cams)
        else:
            self.notifier.info("No cameras found under model.")

        # FirstPerson camera is a must-have. Set up a guessed one if none
        # defined yet.
        if self.cameras.find("camera FirstPerson").isEmpty():
            assert self.notifier.debug("No first person camera found in %s. "
                                  "Guessing best position." % self.parent.name)
            first_person = NodePath("camera FirstPerson")
            # TODO: Guess best position based on bounding box.
            first_person.setY(5)
            first_person.reparentTo(cameras)

        # ThirdPerson camera is a must-have. Set up a guessed one if none
        # defined yet.
        if self.cameras.find("camera ThirdPerson").isEmpty():
            assert self.notifier.debug("No third person camera found in %s. "
                                  "Guessing best position." % self.parent.name)
            third_person = NodePath("camera ThirdPerson")
            # TODO: Guess best position based on bounding box.
            third_person.setPos(0, -30, 5)
            #third_person.setP(-80)
            third_person.reparentTo(cameras)

        # Cockpit needs to be accurate. Don't try to guess it.
        if self.cameras.find("camera Cockpit").isEmpty():
            assert self.notifier.debug("No cockpit camera found in "
                                       "%s. Cockpit camera disabled."
                                       % self.parent.name)
        self.sideview_cam = NodePath("camera Sideview")
        self.sideview_cam.reparentTo(render)

        # Store the cams at parent node..
        # You can edit the camera nodes from outside as well.
        # If you attach new camera nodes, though, you'll have to call this
        # function again.
        self.cameras.reparentTo(self.parent.node)

    def updateCamArray(self, cameramodes=None):
        """Set the cameras which next and previous will switch to. Expects a
        list or tuple. Defaults to all available cameras."""
        a = []
        if not cameramodes:
            for c in self.cameras.getChildren():
                if c.getName().startswith("camera "):
                    a.append(c.getName().strip("camera "))
            self.setStateArray(a)
        else:
            self.setStateArray(cameramodes)

    def getView(self):
        """Returns the current view mode."""
        return self.getCurrentOrNextState()

    def setView(self, mode, *args):
        """Convenience function."""
        return self.request(mode, args)

    def defaultEnter(self, *args):
        """Executed by the FSM every time an undefined state is entered.
        Note: this function is called AFTER the responsible filter."""

        assert self.notifier.debug("Changing state from %s to %s with args: %s."
                                   % (self.oldState, self.newState, args))
        request = self.newState

        target_cam = self.cameras.find("camera " + request)
        if not target_cam.isEmpty():
            try:
                self.camera.reparentTo(target_cam)
                self.camera.setPosHpr(0, 0, 0, 0, 0, 0)
            except:
                self.notifier.warning(
                        "Ok, now this really shouldn't happen! Filter said the "
                        "camera is there and enter can't find it...")



    def defaultFilter(self, request, args):
        """Executed by the FSM every time an undefined state is requested."""
        assert self.notifier.debug("Requested %s with args: %s"
                                   % (request, args))

        self.camera.setPosHpr(0, 0, 0, 0, 0, 0)

        # Always available.
        if request == "Off":   # implemented in FSM.py
            return (request,) + args
        if request == "Next":  # implemented in FSM.py
            return self.requestNext(args)
        if request == "Prev":  # implemented in FSM.py
            return self.requestPrev(args)
        if request == "Detached":
            return (request,) + args
        if request == "Sideview":
            return (request,) + args
        
        # Depending on airplane.
        if not self.cameras.find("camera " + request).isEmpty():
            # TODO(Nemesis13, 26.10.09): add some nice camera transition
            return (request,) + args
        assert self.notifier.info("Sorry, no %s camera found." % request)
        return None


    def enterOff(self, *args):
        """Clean up everything by reparenting the camera to the airplane."""
        self.camera.reparentTo(self.parent.node)
        self.camera.setPosHpr(0, 0, 0, 0, 0, 0)

    def enterSideview(self, *args):
        self.sideview_direction += 90
        self.camera.reparentTo(self.sideview_cam)
        self.camera.setY(-30)
        self.sideview_cam.setH(self.sideview_direction)
        self.addTask(self.updateSideview, "sideview camera", taskChain="world")

    def exitSideview(self, *args):
        self.removeTask("sideview camera")

    def updateSideview(self, task):
        self.sideview_cam.setPos(self.parent.node.getPos())
        return Task.cont

    def enterDetached(self, *args):
        """Lets the camera view the plane from far away."""
        self.camera.reparentTo(render)
        self.camera.setPosHpr(0, 0, 10, 0, 0, 0)
        self.addTask(self.updateDetachedCam, "detached camera",
                     taskChain="world")

    def exitDetached(self, *args):
        self.removeTask("detached camera")

    def updateDetachedCam(self, task):
        """Updates camera position and rotation for Detached camera."""
        try:
            self.camera.lookAt(self.parent.node)
        except:
            self.notifier.warning("Error on detached cam task. Exit.")
            return Task.done
        return Task.cont

    def enterThirdPerson(self, *args):
        """Lets the camera view the plane from far away."""
        self._hist = []
        self.camera.reparentTo(self.cameras.find("camera ThirdPerson"))
        self.addTask(self.updateThirdPersonCam, "third person camera",
                     taskChain="world")
        #print "entering third person"

    def exitThirdPerson(self, *args):
        self.removeTask("third person camera")
        del self._hist
        #print "third person exited"

    def updateThirdPersonCam(self, task):
        """Updates camera position and rotation for ThirdPerson camera."""
        #speed = self.parent.speed()
        #plane = self.parent.node
        #self._hist.insert(0, [task.time, camera.getPos(plane)])
        #while len(self._hist) > 50:
        #    self._hist.pop()
        #
        #for snapshot in self._hist:
        #    if snapshot[0] > task.time:
        #        break
        #time_delta = snapshot[0] - task.time
        #self.camera.setPos(plane, snapshot[1])

        #print snapshot
        #self.camera.setPos(render, snapshot[1])
        #self.camera.lookAt(plane, (0, 20+1*speed, 0))

        #self.camera.setY(5+0.1*speed)
        #self.camera.setZ(5-0.1*speed)

        return Task.cont

    def destroy(self):
        self.removeAllTasks()
        self.demand("Off")
예제 #10
0
class PlaneView(FSM, DirectObject):
    """Give this class a plane as argument and it will create
    some nodes around it which you can parent the camera to (if there are no
    such nodes yet).

    Usage:
    plane_camera = PlaneCamera(aeroplane, camera)
    plane_camera.setView("ThirdPerson")
    plane_camera.setView("Next")
    """
    def __init__(self, camera, parent):
        """Arguments:
        camera -- Camera to be used
        parent -- Aeroplane which the camera should follow
        """

        self.notifier = DirectNotify().newCategory("azure-camera")
        self.camera = camera
        self.parent = parent
        # This gets replaced by a NodePath with all available cameras as
        # children and plane node as parent in createCamNodes()
        self.cameras = None

        #if parent.__class__.__name__ is not "Aeroplane":
        if not isinstance(self.parent, Aeroplane):
            raise ParamError, "Parent must be an Aeroplane instance, " + \
                              "but is %s" % type(self.parent)

        FSM.__init__(self, "PlaneCamera: %s" % self.parent.name)
        DirectObject.__init__(self)

        self.cameras = self.parent.node.find("cameras")
        if self.cameras.isEmpty():
            self.createCamNodes()
        self.updateCamArray()

        self.sideview_direction = 0

        # Set up the default camera
        self.setView("ThirdPerson")

    def createCamNodes(self):
        """Creates a few empty nodes around a plane which the camera might be
        parented to. It looks if there are cameras inside the model file and
        uses those if possible. Where everything named "camera CamType" is
        considered a camera. At least ThirdPerson, FirstPerson and Cockpit
        should be defined inside the egg file, otherwise some guessed defaults
        are taken.
        """

        # Look for cameras inside the model (loaded egg file)
        self.cameras = NodePath("cameras")
        found_cams = self.parent.node.findAllMatches("**/camera ?*")
        found_cams.removeDuplicatePaths()
        found_cams.reparentTo(self.cameras)

        if not found_cams.isEmpty():
            self.notifier.info("Cameras found under model:\n%s"
                               % found_cams)
        else:
            self.notifier.info("No cameras found under model.")

        # FirstPerson camera is a must-have. Set up a guessed one if none
        # defined yet.
        if self.cameras.find("camera FirstPerson").isEmpty():
            assert self.notifier.debug("No first person camera found in %s. "
                                  "Guessing best position." % self.parent.name)
            first_person = NodePath("camera FirstPerson")
            # TODO: Guess best position based on bounding box.
            first_person.setY(5)
            first_person.reparentTo(cameras)

        # ThirdPerson camera is a must-have. Set up a guessed one if none
        # defined yet.
        if self.cameras.find("camera ThirdPerson").isEmpty():
            assert self.notifier.debug("No third person camera found in %s. "
                                  "Guessing best position." % self.parent.name)
            third_person = NodePath("camera ThirdPerson")
            # TODO: Guess best position based on bounding box.
            third_person.setPos(0, -30, 5)
            #third_person.setP(-80)
            third_person.reparentTo(cameras)

        # Cockpit needs to be accurate. Don't try to guess it.
        if self.cameras.find("camera Cockpit").isEmpty():
            assert self.notifier.debug("No cockpit camera found in "
                                       "%s. Cockpit camera disabled."
                                       % self.parent.name)
        self.sideview_cam = NodePath("camera Sideview")
        self.sideview_cam.reparentTo(render)

        # Store the cams at parent node..
        # You can edit the camera nodes from outside as well.
        # If you attach new camera nodes, though, you'll have to call this
        # function again.
        self.cameras.reparentTo(self.parent.node)

    def updateCamArray(self, cameramodes=None):
        """Set the cameras which next and previous will switch to. Expects a
        list or tuple. Defaults to all available cameras."""
        a = []
        if not cameramodes:
            for c in self.cameras.getChildren():
                if c.getName().startswith("camera "):
                    a.append(c.getName().strip("camera "))
            self.setStateArray(a)
        else:
            self.setStateArray(cameramodes)

    def getView(self):
        """Returns the current view mode."""
        return self.getCurrentOrNextState()

    def setView(self, mode, *args):
        """Convenience function."""
        return self.request(mode, args)

    def defaultEnter(self, *args):
        """Executed by the FSM every time an undefined state is entered.
        Note: this function is called AFTER the responsible filter."""

        assert self.notifier.debug("Changing state from %s to %s with args: %s."
                                   % (self.oldState, self.newState, args))
        request = self.newState

        target_cam = self.cameras.find("camera " + request)
        if not target_cam.isEmpty():
            try:
                self.camera.reparentTo(target_cam)
                self.camera.setPosHpr(0, 0, 0, 0, 0, 0)
            except:
                self.notifier.warning(
                        "Ok, now this really shouldn't happen! Filter said the "
                        "camera is there and enter can't find it...")



    def defaultFilter(self, request, args):
        """Executed by the FSM every time an undefined state is requested."""
        assert self.notifier.debug("Requested %s with args: %s"
                                   % (request, args))

        self.camera.setPosHpr(0, 0, 0, 0, 0, 0)

        # Always available.
        if request == "Off":   # implemented in FSM.py
            return (request,) + args
        if request == "Next":  # implemented in FSM.py
            return self.requestNext(args)
        if request == "Prev":  # implemented in FSM.py
            return self.requestPrev(args)
        if request == "Detached":
            return (request,) + args
        if request == "Sideview":
            return (request,) + args
        
        # Depending on airplane.
        if not self.cameras.find("camera " + request).isEmpty():
            return (request,) + args
        assert self.notifier.info("Sorry, no %s camera found." % request)
        return None


    def enterOff(self, *args):
        """Clean up everything by reparenting the camera to the airplane."""
        self.camera.reparentTo(self.parent.node)
        self.camera.setPosHpr(0, 0, 0, 0, 0, 0)

    def enterSideview(self, *args):
        self.sideview_direction += 90
        self.camera.reparentTo(self.sideview_cam)
        self.camera.setY(-30)
        self.sideview_cam.setH(self.sideview_direction)
        #self.addTask(self.updateSideview, "sideview camera", taskChain="world")
        self.task = self.updateSideview

    def exitSideview(self, *args):
        #self.removeTask("sideview camera")
        self.task = lambda x: Task.cont

    def updateSideview(self, task):
        self.sideview_cam.setPos(self.parent.node.getPos())
        return Task.cont

    def enterDetached(self, *args):
        """Lets the camera view the plane from far away."""
        self.camera.reparentTo(render)
        self.camera.setPosHpr(0, 0, 10, 0, 0, 0)
        #self.addTask(self.updateDetachedCam, "detached camera",
        #             taskChain="world")
        self.task = self.updateDetachedCam

    def exitDetached(self, *args):
        #self.removeTask("detached camera")
        self.task = lambda x: Task.cont

    def updateDetachedCam(self, task):
        """Updates camera position and rotation for Detached camera."""
        try:
            self.camera.lookAt(self.parent.node)
        except:
            self.notifier.warning("Error on detached cam task. Exit.")
            return Task.done
        return Task.cont

    def enterThirdPerson(self, *args):
        """Lets the camera view the plane from far away."""
        self._hist = []
        self.camera.reparentTo(self.cameras.find("camera ThirdPerson"))
        self.cameras.find("camera ThirdPerson").setPos(0, -30, 0)
        #self.addTask(self.updateThirdPersonCam, "third person camera",
        #             taskChain="world")
        self.task = self.updateThirdPersonCam
        #print "entering third person"

    def exitThirdPerson(self, *args):
        #self.removeTask("third person camera")
        self.task = lambda x: Task.cont
        del self._hist

    def updateThirdPersonCam(self, task):
        """Updates camera position and rotation for ThirdPerson camera."""
        speed = self.parent.physics.speed()
        velocity = self.parent.physics.velocity()
        #v = Point3(self.parent.physics.angVelVector())
        v = Point3(self.parent.physics.angVelBodyHpr())
        print round(v.getX(), 2), round(v.getY(), 2), round(v.getZ(), 2)

        #self.segs = LineSegs("lines");
        #self.segs.setColor(1,1,1,1)
        #self.segs.drawTo(-1, 0)
        #self.segsnode = self.segs.create()
        #render2d.attachNewNode(self.segsnode) 

        vec = Point3(self.parent.physics.angVelBodyHpr())
        # Y hiervon ist pitch, Z ist roll
        #print round(vec.getY(), 2), round(vec.getZ(), 2)
        self.camera.lookAt(self.parent.node)
        self.camera.setR(self.camera, vec.getZ()*3)
        #self.camera.setPos(abs(v.getX()), 0,  vec.getY())

        

        #plane = self.parent.node
        #self._hist.insert(0, [task.time, camera.getPos(plane)])
        #while len(self._hist) > 50:
        #    self._hist.pop()
        #
        #for snapshot in self._hist:
        #    if snapshot[0] > task.time:
        #        break
        #time_delta = snapshot[0] - task.time
        #self.camera.setPos(plane, snapshot[1])

        #print snapshot
        #self.camera.setPos(render, snapshot[1])
        #self.camera.lookAt(plane, (0, 20+1*speed, 0))

        #self.camera.setY(5+0.1*speed)
        #self.camera.setZ(5-0.1*speed)

        return Task.cont

    def update(self, task):
        return self.task(task)
    
    def destroy(self):
        self.removeAllTasks()
        self.demand("Off")