예제 #1
0
파일: Grid.py 프로젝트: crempp/psg
	def drawSquare(self, x1,y1,z1, x2,y2,z2):
		format=GeomVertexFormat.getV3n3cpt2()
		vdata=GeomVertexData('square', format, Geom.UHStatic)
		
		vertex=GeomVertexWriter(vdata, 'vertex')
		normal=GeomVertexWriter(vdata, 'normal')
		color=GeomVertexWriter(vdata, 'color')
		texcoord=GeomVertexWriter(vdata, 'texcoord')
		
		#make sure we draw the sqaure in the right plane
		#if x1!=x2:
		vertex.addData3f(x1, y1, z1)
		vertex.addData3f(x2, y1, z1)
		vertex.addData3f(x2, y2, z2)
		vertex.addData3f(x1, y2, z2)

		normal.addData3f(self.myNormalize(Vec3(2*x1-1, 2*y1-1, 2*z1-1)))
		normal.addData3f(self.myNormalize(Vec3(2*x2-1, 2*y1-1, 2*z1-1)))
		normal.addData3f(self.myNormalize(Vec3(2*x2-1, 2*y2-1, 2*z2-1)))
		normal.addData3f(self.myNormalize(Vec3(2*x1-1, 2*y2-1, 2*z2-1)))
		
		#adding different colors to the vertex for visibility
		color.addData4f(0.0,0.5,0.0,0.5)
		color.addData4f(0.0,0.5,0.0,0.5)
		color.addData4f(0.0,0.5,0.0,0.5)
		color.addData4f(0.0,0.5,0.0,0.5)
		
		texcoord.addData2f(0.0, 1.0)
		texcoord.addData2f(0.0, 0.0)
		texcoord.addData2f(1.0, 0.0)
		texcoord.addData2f(1.0, 1.0)

		#quads arent directly supported by the Geom interface
		#you might be interested in the CardMaker class if you are
		#interested in rectangle though
		tri1=GeomTriangles(Geom.UHStatic)
		tri2=GeomTriangles(Geom.UHStatic)
		
		tri1.addVertex(0)
		tri1.addVertex(1)
		tri1.addVertex(3)
		
		tri2.addConsecutiveVertices(1,3)
		
		tri1.closePrimitive()
		tri2.closePrimitive()
		
		square=Geom(vdata)
		square.addPrimitive(tri1)
		square.addPrimitive(tri2)
		#square.setIntoCollideMask(BitMask32.bit(1))
		
		squareNP = NodePath(GeomNode('square gnode')) 
		squareNP.node().addGeom(square)
		squareNP.setTransparency(1) 
		squareNP.setAlphaScale(.5) 
		squareNP.setTwoSided(True)
		squareNP.setCollideMask(BitMask32.bit(1))
		return squareNP
예제 #2
0
파일: dirlight.py 프로젝트: figo-sh/naith
class DirLight:
    """Creates a simple directional light"""

    def __init__(self, manager, xml):
        self.light = PDirectionalLight("dlight")
        self.lightNode = NodePath(self.light)
        self.lightNode.setCompass()
        if hasattr(self.lightNode.node(), "setCameraMask"):
            self.lightNode.node().setCameraMask(BitMask32.bit(3))

        self.reload(manager, xml)

    def reload(self, manager, xml):
        color = xml.find("color")
        if color != None:
            self.light.setColor(VBase4(float(color.get("r")), float(color.get("g")), float(color.get("b")), 1.0))

        pos = xml.find("pos")
        if pos != None:
            self.lightNode.setPos(float(pos.get("x")), float(pos.get("y")), float(pos.get("z")))
        else:
            self.lightNode.setPos(0, 0, 0)

        lookAt = xml.find("lookAt")
        if lookAt != None:
            self.lightNode.lookAt(float(lookAt.get("x")), float(lookAt.get("y")), float(lookAt.get("z")))

        lens = xml.find("lens")
        if lens != None and hasattr(self.lightNode.node(), "getLens"):
            if bool(int(lens.get("auto"))):
                self.lightNode.reparentTo(base.camera)
            else:
                self.lightNode.reparentTo(render)
            lobj = self.lightNode.node().getLens()
            lobj.setNearFar(float(lens.get("near", 1.0)), float(lens.get("far", 100000.0)))
            lobj.setFilmSize(float(lens.get("width", 1.0)), float(lens.get("height", 1.0)))
            lobj.setFilmOffset(float(lens.get("x", 0.0)), float(lens.get("y", 0.0)))

        if hasattr(self.lightNode.node(), "setShadowCaster"):
            shadows = xml.find("shadows")
            if shadows != None:
                self.lightNode.node().setShadowCaster(
                    True, int(shadows.get("width", 512)), int(shadows.get("height", 512)), int(shadows.get("sort", -10))
                )
                # self.lightNode.node().setPushBias(float(shadows.get('bias', 0.5)))
            else:
                self.lightNode.node().setShadowCaster(False)

    def start(self):
        render.setLight(self.lightNode)

    def stop(self):
        render.clearLight(self.lightNode)
    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
예제 #4
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
예제 #5
0
class Camera( NodePath ):
    
    """Class representing a camera."""
    
    class Target( NodePath ):
            
        """Class representing the camera's point of interest."""
            
        def __init__( self, pos=Vec3( 0, 0, 0 ) ):
            NodePath.__init__( self, 'target' )
            
            self.defaultPos = pos
            
    class Axes( NodePath ):
        
        """Class representing the viewport camera axes."""
        
        def __Create( self, thickness, length ):
            
            # Build line segments
            ls = LineSegs()
            ls.setThickness( thickness )
            
            # X Axis - Red
            ls.setColor( 1.0, 0.0, 0.0, 1.0 )
            ls.moveTo( 0.0, 0.0, 0.0 )
            ls.drawTo( length, 0.0, 0.0 )
            
            # Y Axis - Green
            ls.setColor( 0.0, 1.0, 0.0, 1.0 )
            ls.moveTo( 0.0,0.0,0.0 )
            ls.drawTo( 0.0, length, 0.0 )
            
            # Z Axis - Blue
            ls.setColor( 0.0, 0.0, 1.0, 1.0 )
            ls.moveTo( 0.0,0.0,0.0 )
            ls.drawTo( 0.0, 0.0, length )
            
            return ls.create()
        
        def __init__( self, thickness=1, length=25 ):
            ls = self.__Create( thickness, length )
            NodePath.__init__( self, ls )
    
    def __init__( self, 
                  name='camera', 
                  pos=Vec3( 0, 0, 0 ), 
                  targetPos=Vec3( 0, 0, 0 ),
                  style=CAM_DEFAULT_STYLE ):
                      
        self.zoomLevel = 2
        self.defaultPos = pos
        self.style = style
        
        # Use Panda's default camera
        if self.style & CAM_USE_DEFAULT:
            self.cam = getBase().cam
            #self.camNode = getBase().camNode
            
        # Otherwise create a new one
        else:
            
            # Create camera
            self.cam = NodePath( PCamera( name ) )
            
            # Create lens
            lens = PerspectiveLens()
            lens.setAspectRatio( 800.0 / 300.0 )
            self.cam.node().setLens( lens )
            
        # Wrap the camera in this node path class
        NodePath.__init__( self, self.cam )
        
        # Create camera styles
        if self.style & CAM_VIEWPORT_AXES:
            self.axes = self.Axes()
            self.axes.reparentTo( pixel2d )
        
        # Create camera target
        self.target = self.Target( pos=targetPos )
        
        self.Reset()
        
    def Reset( self ):
        
        # Reset camera and target back to default positions
        self.target.setPos( self.target.defaultPos )
        self.setPos( self.defaultPos )
        
        # Set camera to look at target
        self.lookAt( self.target.getPos() )
        self.target.setQuat( self.getQuat() )
        
        
    def Move( self, moveVec ):
            
        # Modify the move vector by the distance to the target, so the further
        # away the camera is the faster it moves
        cameraVec = self.getPos() - self.target.getPos()
        cameraDist = cameraVec.length()
        moveVec *= cameraDist / 300
        
        # Move the camera
        self.setPos( self, moveVec )
        
        # Move the target so it stays with the camera
        self.target.setQuat( self.getQuat() )
        test = Vec3( moveVec.getX(), 0, moveVec.getZ() )
        self.target.setPos( self.target, test )
        
    def Orbit( self, delta ):
        
        # Get new hpr
        newHpr = Vec3()
        newHpr.setX( self.getH() + delta.getX() )
        newHpr.setY( self.getP() + delta.getY() )
        newHpr.setZ( self.getR() )
        
        # Set camera to new hpr
        self.setHpr( newHpr )
            
        # Get the H and P in radians
        radX = newHpr.getX() * ( math.pi / 180.0 )
        radY = newHpr.getY() * ( math.pi / 180.0 )
            
        # Get distance from camera to target
        cameraVec = self.getPos() - self.target.getPos()
        cameraDist = cameraVec.length()
            
        # Get new camera pos
        newPos = Vec3()
        newPos.setX( cameraDist * math.sin( radX ) * math.cos( radY ) )
        newPos.setY( -cameraDist * math.cos( radX ) * math.cos( radY ) )
        newPos.setZ( -cameraDist * math.sin( radY ) )
        newPos += self.target.getPos()
            
        # Set camera to new pos
        self.setPos( newPos )
        
    def cameraMovement( self, task ):
        x,y,z = self.cube.getPos()
        #smoothly follow the cube...
        self.setX( self.getX() - ( ( self.getX() - x - 18 * self.zoomLevel ) * 5 * globalClock.getDt() ) )
        self.setY( self.getY() - ( ( self.getY() - y + 5 * self.zoomLevel ) * 5 * globalClock.getDt() ) )
        self.setZ( 15 * self.ZOOMLEVEL )
        self.setHpr( 75, -37, 0 )
        return Task.cont
    
    def AxesTask( self, task ):
        
        # Position axes 30 pixels from bottom left corner
        #posY = 100# self.GetSize()[1]
        self.axes.setPos( Vec3( 1120, 0, -60 ) )
        
        # Set rotation to inverse of camera rotation
        cameraQuat = Quat( self.getQuat() )
        cameraQuat.invertInPlace()
        self.axes.setQuat( cameraQuat )
        
        return Task.cont
    
    def Start( self ):
        if self.style & CAM_VIEWPORT_AXES:
            taskMgr.add( self.AxesTask, 'cameraAxesTask' )
    
    def Stop( self ):
        taskMgr.remove( self.Task )
        
    def GetLens( self ):
        return self.cam.node().getLens()
예제 #6
0
class Square(object):
    #Draws a square from lower left (x1, y2, z1) to upper right (x2, y2, z2)
    def __init__(self, parent, p1, p2, color):
        self.parent = parent
        self.x1 = p1.getX()
        self.y1 = p1.getY()
        self.z1 = p1.getZ()
        self.x2 = p2.getX()
        self.y2 = p2.getY()
        self.z2 = p2.getZ()
        
        self.r = color.getX()
        self.g = color.getY()
        self.b = color.getZ()
        self.a = color.getW()
        
        self.draw()
    
    def draw(self):
        format=GeomVertexFormat.getV3n3cpt2()
        vdata=GeomVertexData('square', format, Geom.UHStatic)
        
        vertex=GeomVertexWriter(vdata, 'vertex')
        normal=GeomVertexWriter(vdata, 'normal')
        color=GeomVertexWriter(vdata, 'color')
        texcoord=GeomVertexWriter(vdata, 'texcoord')
        
        #make sure we draw the sqaure in the right plane
        #if x1!=x2:
        vertex.addData3f(self.x1, self.y1, self.z1)
        vertex.addData3f(self.x2, self.y1, self.z1)
        vertex.addData3f(self.x2, self.y2, self.z2)
        vertex.addData3f(self.x1, self.y2, self.z2)
    
        normal.addData3f(Vec3(2*self.x1-1, 2*self.y1-1, 2*self.z1-1).normalize())
        normal.addData3f(Vec3(2*self.x2-1, 2*self.y1-1, 2*self.z1-1).normalize())
        normal.addData3f(Vec3(2*self.x2-1, 2*self.y2-1, 2*self.z2-1).normalize())
        normal.addData3f(Vec3(2*self.x1-1, 2*self.y2-1, 2*self.z2-1).normalize())
        
        #adding different colors to the vertex for visibility
        color.addData4f(self.r, self.g, self.b, self.a)
        color.addData4f(self.r, self.g, self.b, self.a)
        color.addData4f(self.r, self.g, self.b, self.a)
        color.addData4f(self.r, self.g, self.b, self.a)
        
        texcoord.addData2f(0.0, 1.0)
        texcoord.addData2f(0.0, 0.0)
        texcoord.addData2f(1.0, 0.0)
        texcoord.addData2f(1.0, 1.0)
    
        #quads arent directly supported by the Geom interface
        #you might be interested in the CardMaker class if you are
        #interested in rectangle though
        tri1=GeomTriangles(Geom.UHStatic)
        tri2=GeomTriangles(Geom.UHStatic)
        
        tri1.addVertex(0)
        tri1.addVertex(1)
        tri1.addVertex(3)
        
        tri2.addConsecutiveVertices(1,3)
        
        tri1.closePrimitive()
        tri2.closePrimitive()
        
        square=Geom(vdata)
        square.addPrimitive(tri1)
        square.addPrimitive(tri2)
        #square.setIntoCollideMask(BitMask32.bit(1))
        
        self.squareNP = NodePath(GeomNode('square gnode')) 
        self.squareNP.node().addGeom(square)
        self.squareNP.setTransparency(1) 
        self.squareNP.setAlphaScale(.5) 
        self.squareNP.setTwoSided(True)
        #squareNP.setCollideMask(BitMask32.bit(1))
        self.squareNP.reparentTo(self.parent)
        
        return self.squareNP
예제 #7
0
class Sprite2d:

	class Cell:
		def __init__(self, col, row):
			self.col = col
			self.row = row

		def __str__(self):
			return "Cell - Col %d, Row %d" % (self.col, self.row)

	class Animation:
		def __init__(self, cells, fps):
			self.cells = cells
			self.fps = fps
			self.playhead = 0

	ALIGN_CENTER = "Center"
	ALIGN_LEFT = "Left"
	ALIGN_RIGHT = "Right"
	ALIGN_BOTTOM = "Bottom"
	ALIGN_TOP = "Top"

	TRANS_ALPHA = TransparencyAttrib.MAlpha
	TRANS_DUAL = TransparencyAttrib.MDual
	# One pixel is divided by this much. If you load a 100x50 image with PIXEL_SCALE of 10.0
	# you get a card that is 1 unit wide, 0.5 units high
	PIXEL_SCALE = 20.0

	def __init__(self, image_path, rowPerFace, name=None,\
				  rows=1, cols=1, scale=1.0,\
				  twoSided=False, alpha=TRANS_ALPHA,\
				  repeatX=1, repeatY=1,\
				  anchorX=ALIGN_CENTER, anchorY=ALIGN_BOTTOM):
		"""
		Create a card textured with an image. The card is sized so that the ratio between the
		card and image is the same.
		"""

		global SpriteId
		self.spriteNum = str(SpriteId)
		SpriteId += 1

		scale *= self.PIXEL_SCALE

		self.animations = {}

		self.scale = scale
		self.repeatX = repeatX
		self.repeatY = repeatY
		self.flip = {'x':False,'y':False}
		self.rows = rows
		self.cols = cols

		self.currentFrame = 0
		self.currentAnim = None
		self.loopAnim = False
		self.frameInterrupt = True

		# Create the NodePath
		if name:
			self.node = NodePath("Sprite2d:%s" % name)
		else:
			self.node = NodePath("Sprite2d:%s" % image_path)

		# Set the attribute for transparency/twosided
		self.node.node().setAttrib(TransparencyAttrib.make(alpha))
		if twoSided:
			self.node.setTwoSided(True)

		# Make a filepath
		self.imgFile = Filename(image_path)
		if self.imgFile.empty():
			raise IOError, "File not found"

		# Instead of loading it outright, check with the PNMImageHeader if we can open
		# the file.
		imgHead = PNMImageHeader()
		if not imgHead.readHeader(self.imgFile):
			raise IOError, "PNMImageHeader could not read file. Try using absolute filepaths"

		# Load the image with a PNMImage
		image = PNMImage()
		image.read(self.imgFile)

		self.sizeX = image.getXSize()
		self.sizeY = image.getYSize()

		# We need to find the power of two size for the another PNMImage
		# so that the texture thats loaded on the geometry won't have artifacts
		textureSizeX = self.nextsize(self.sizeX)
		textureSizeY = self.nextsize(self.sizeY)

		# The actual size of the texture in memory
		self.realSizeX = textureSizeX
		self.realSizeY = textureSizeY

		self.paddedImg = PNMImage(textureSizeX, textureSizeY)
		if image.hasAlpha():
			self.paddedImg.alphaFill(0)
		# Copy the source image to the image we're actually using
		self.paddedImg.blendSubImage(image, 0, 0)
		# We're done with source image, clear it
		image.clear()

		# The pixel sizes for each cell
		self.colSize = self.sizeX/self.cols
		self.rowSize = self.sizeY/self.rows

		# How much padding the texture has
		self.paddingX = textureSizeX - self.sizeX
		self.paddingY = textureSizeY - self.sizeY

		# Set UV padding
		self.uPad = float(self.paddingX)/textureSizeX
		self.vPad = float(self.paddingY)/textureSizeY

		# The UV dimensions for each cell
		self.uSize = (1.0 - self.uPad) / self.cols
		self.vSize = (1.0 - self.vPad) / self.rows
	
		self.cards = []
		self.rowPerFace = rowPerFace
		for i in range(len(rowPerFace)):
			card = CardMaker("Sprite2d-Geom")

			# The positions to create the card at
			if anchorX == self.ALIGN_LEFT:
				posLeft = 0
				posRight = (self.colSize/scale)*repeatX
			elif anchorX == self.ALIGN_CENTER:
				posLeft = -(self.colSize/2.0/scale)*repeatX
				posRight = (self.colSize/2.0/scale)*repeatX
			elif anchorX == self.ALIGN_RIGHT:
				posLeft = -(self.colSize/scale)*repeatX
				posRight = 0

			if anchorY == self.ALIGN_BOTTOM:
				posTop = 0
				posBottom = (self.rowSize/scale)*repeatY
			elif anchorY == self.ALIGN_CENTER:
				posTop = -(self.rowSize/2.0/scale)*repeatY
				posBottom = (self.rowSize/2.0/scale)*repeatY
			elif anchorY == self.ALIGN_TOP:
				posTop = -(self.rowSize/scale)*repeatY
				posBottom = 0

			card.setFrame(posLeft, posRight, posTop, posBottom)
			card.setHasUvs(True)
			self.cards.append(self.node.attachNewNode(card.generate()))
			self.cards[-1].setH(i * 360/len(rowPerFace))

		# Since the texture is padded, we need to set up offsets and scales to make
		# the texture fit the whole card
		self.offsetX = (float(self.colSize)/textureSizeX)
		self.offsetY = (float(self.rowSize)/textureSizeY)

		# self.node.setTexScale(TextureStage.getDefault(), self.offsetX * repeatX, self.offsetY * repeatY)
		# self.node.setTexOffset(TextureStage.getDefault(), 0, 1-self.offsetY)
		
		self.texture = Texture()

		self.texture.setXSize(textureSizeX)
		self.texture.setYSize(textureSizeY)
		self.texture.setZSize(1)

		# Load the padded PNMImage to the texture
		self.texture.load(self.paddedImg)

		self.texture.setMagfilter(Texture.FTNearest)
		self.texture.setMinfilter(Texture.FTNearest)

		#Set up texture clamps according to repeats
		if repeatX > 1:
			self.texture.setWrapU(Texture.WMRepeat)
		else:
			self.texture.setWrapU(Texture.WMClamp)
		if repeatY > 1:
			self.texture.setWrapV(Texture.WMRepeat)
		else:
			self.texture.setWrapV(Texture.WMClamp)

		self.node.setTexture(self.texture)
		self.setFrame(0)

	def nextsize(self, num):
		""" Finds the next power of two size for the given integer. """
		p2x=max(1,log(num,2))
		notP2X=modf(p2x)[0]>0
		return 2**int(notP2X+p2x)

	def setFrame(self, frame=0):
		""" Sets the current sprite to the given frame """
		self.frameInterrupt = True # A flag to tell the animation task to shut it up ur face
		self.currentFrame = frame
		self.flipTexture()

	def playAnim(self, animName, loop=False):
		""" Sets the sprite to animate the given named animation. Booleon to loop animation"""
		if not taskMgr.hasTaskNamed("Animate sprite" + self.spriteNum):
			if hasattr(self, "task"):
					taskMgr.remove("Animate sprite" + self.spriteNum)
					del self.task
			self.frameInterrupt = False # Clear any previous interrupt flags
			self.loopAnim = loop
			self.currentAnim = self.animations[animName]
			self.currentAnim.playhead = 0
			self.task = taskMgr.doMethodLater(1.0/self.currentAnim.fps,self.animPlayer, "Animate sprite" + self.spriteNum)

	def createAnim(self, animName, frameCols, fps=12):
		""" Create a named animation. Takes the animation name and a tuple of frame numbers """
		self.animations[animName] = Sprite2d.Animation(frameCols, fps)
		return self.animations[animName]

	def flipX(self, val=None):
		""" Flip the sprite on X. If no value given, it will invert the current flipping."""
		if val:
			self.flip['x'] = val
		else:
			if self.flip['x']:
				self.flip['x'] = False
			else:
				self.flip['x'] = True
		self.flipTexture()
		return self.flip['x']

	def flipY(self, val=None):
		""" See flipX """
		if val:
			self.flip['y'] = val
		else:
			if self.flip['y']:
				self.flip['y'] = False
			else:
				self.flip['y'] = True
		self.flipTexture()
		return self.flip['y']

	def updateCameraAngle(self, cameraNode):
		baseH =  cameraNode.getH(render) - self.node.getH(render)
		degreesBetweenCards = 360/len(self.cards)
		bestCard = int(((baseH)+degreesBetweenCards/2)%360 / degreesBetweenCards)
		#print baseH, bestCard
		for i in range(len(self.cards)):
			if i == bestCard:
				self.cards[i].show()
			else:
				self.cards[i].hide()

	def flipTexture(self):
		""" Sets the texture coordinates of the texture to the current frame"""
		for i in range(len(self.cards)):
			currentRow = self.rowPerFace[i]

			sU = self.offsetX * self.repeatX
			sV = self.offsetY * self.repeatY
			oU = 0 + self.currentFrame * self.uSize
			#oU = 0 + self.frames[self.currentFrame].col * self.uSize
			#oV = 1 - self.frames[self.currentFrame].row * self.vSize - self.offsetY
			oV = 1 - currentRow * self.vSize - self.offsetY
			if self.flip['x'] ^ i==1: ##hack to fix side view
				#print "flipping, i = ",i
				sU *= -1
				#oU = self.uSize + self.frames[self.currentFrame].col * self.uSize
				oU = self.uSize + self.currentFrame * self.uSize
			if self.flip['y']:
				sV *= -1
				#oV = 1 - self.frames[self.currentFrame].row * self.vSize
				oV = 1 - currentRow * self.vSize
			self.cards[i].setTexScale(TextureStage.getDefault(), sU, sV)
			self.cards[i].setTexOffset(TextureStage.getDefault(), oU, oV)

	def clear(self):
		""" Free up the texture memory being used """
		self.texture.clear()
		self.paddedImg.clear()
		self.node.removeNode()

	def animPlayer(self, task):
		if self.frameInterrupt:
			return task.done
		#print "Playing",self.currentAnim.cells[self.currentAnim.playhead]
		self.currentFrame = self.currentAnim.cells[self.currentAnim.playhead]
		self.flipTexture()
		if self.currentAnim.playhead+1 < len(self.currentAnim.cells):
			self.currentAnim.playhead += 1
			return task.again
		if self.loopAnim:
			self.currentAnim.playhead = 0
			return task.again
예제 #8
0
    def createSector(self, sectorId):
        (sectorX, sectorY) = sectorId
        #    print "creating sector %s" % str(sectorId)
        # init seed depending on quadrant we are currently in
        random.seed(sectorId)

        if self.usingLod:
            plantLodNpChilds = [NodePath("lod-0-%s" % str(sectorId)), NodePath("lod-1-%s" % str(sectorId))]
        else:
            tileNode = self.plantClassNp.attachNewNode("tileNode-%s" % str(sectorId))
            tempTileNode = NodePath("tempTileNode-%s" % str(sectorId))

        # create each plant with the given chance in the sector
        for (
            plantName,
            [plantChance, plantModel, plantMinScale, plantScaleVariance, [noiseFunc, distFunc, distParams]],
        ) in self.plantModelDict.items():
            # maximum number of plants of this type
            averagePlantCount = (plantChance / 100.0) * self.sizeOfTile ** 2
            # well use ceil, if not some plants may never be generated
            plantCount = math.ceil(averagePlantCount)

            distFuncResultAccumulated = 0.0
            # print "planning to create %i plants" % plantCount  [commented by Finn]
            # creating plantCount number of plants
            placedPlantCounter = 0
            for plantId in xrange(int(plantCount)):
                # select position the plant will have
                posX = random.randint(0, self.sizeOfTile) + (sectorX * self.sizeOfTile)
                posY = random.randint(0, self.sizeOfTile) + (sectorY * self.sizeOfTile)
                # get z position of ground
                posZ = self.heightfield.get_elevation([posX, posY])
                # the absolue world position of the plant
                absoluteWorldPosition = Vec3(posX, posY, posZ)

                # decide if we want to place this plant based on the noise function
                noiseFuncResult = noiseFunc(posX, posY)
                distFuncResult = distFunc(noiseFuncResult, *distParams)
                # make sure the plants are placed evenly
                distFuncResultAccumulated += distFuncResult

                if distFuncResultAccumulated > 1.0:
                    placedPlantCounter += 1
                    # print "plant"
                    # place a plant
                    distFuncResultAccumulated -= 1.0

                    # select scale & rotation of plant
                    scale = random.random()
                    rotation = random.randint(0, 360)

                    # load model
                    if self.usingLod:
                        # save that we are using lod, we cant flatten if we are
                        # usingLod = True
                        # setup lod nodepath
                        # plantLodNp = NodePath(FadeLODNode('lod'))
                        # plantLodNp.reparentTo(self.plantClassNp)
                        i = 0
                        for [maxLodDist, minLodDistance, lodModelName] in plantModel:
                            # print "creating lod %i of plant %s" % (i, plantName)  [commented by Finn]
                            tempPlantNp = loader.loadModel(lodModelName + ".egg")
                            plantNp = NodePath("model-%s" % str(absoluteWorldPosition))
                            tempPlantNp.getChildren().reparentTo(plantNp)
                            # flatten the nodepath
                            # plantNp.flattenStrong()
                            # set position of plant
                            plantNp.setPos(absoluteWorldPosition)
                            plantNp.setHpr(rotation, 0, 0)
                            finalScale = plantMinScale + scale * plantScaleVariance
                            plantNp.setScale(finalScale)
                            # add plant to tile
                            plantNp.reparentTo(plantLodNpChilds[i])
                            #
                            i += 1
                    else:
                        # plantNp = loader.loadModelCopy( plantModel+".egg" )
                        # plantNp.reparentTo( tileNode )
                        tempPlantNp = loader.loadModelCopy(plantModel + ".egg")
                        plantNp = NodePath("model-%s" % str(absoluteWorldPosition))
                        tempPlantNp.getChildren().reparentTo(plantNp)
                        tempPlantNp.removeNode()
                        # flatten the nodepath
                        # plantNp.flattenStrong()
                        # add plant to tile
                        plantNp.reparentTo(tempTileNode)

                        # set position of plant
                        plantNp.setPos(absoluteWorldPosition)
                        plantNp.setHpr(rotation, 0, 0)
                        finalScale = plantMinScale + scale * plantScaleVariance
                        plantNp.setScale(finalScale)

            # print "planted %i plants" % placedPlantCounter

        # flatten the tile if not using lod
        if self.usingLod:
            plantLodNpChilds[0].flattenStrong()
            plantLodNpChilds[1].flattenStrong()

            fadeLodNode = FadeLODNode("lod-%s" % str(sectorId))
            absolutePosX = (sectorX * self.sizeOfTile) + self.sizeOfTile / 2.0
            absolutePosY = (sectorY * self.sizeOfTile) + self.sizeOfTile / 2.0
            absolutePosZ = self.heightfield.get_elevation([absolutePosX, absolutePosY])
            fadeLodNode.setCenter(Point3(absolutePosX, absolutePosY, absolutePosZ))

            plantLodNp = NodePath(fadeLodNode)
            # plantLodNp = NodePath('lod-%s' % str(sectorId))

            plantLodNpChilds[0].reparentTo(plantLodNp)
            plantLodNp.node().addSwitch(9999, self.sizeOfTile * 2.0)

            plantLodNpChilds[1].reparentTo(plantLodNp)
            plantLodNp.node().addSwitch(self.sizeOfTile * 2.0, 0)

            self.tileDict[sectorId] = plantLodNp
            plantLodNp.reparentTo(self.plantClassNp)
            if FADEIN:
                self.makeFadeIn(plantLodNp)
        else:
            # reassign plants to sectorNode
            tempTileNode.getChildren().reparentTo(tileNode)
            tempTileNode.removeNode()
            tempTileNode = None
            # tileNode.flattenMedium()
            tileNode.flattenStrong()
            tileNode.reparentTo(self.plantClassNp)
            self.tileDict[sectorId] = tileNode
            if FADEIN:
                self.makeFadeIn(tileNode)
예제 #9
0
class Camera( NodePath, p3d.SingleTask ):
    
    """Class representing a camera."""
    
    class Target( NodePath ):
            
        """Class representing the camera's point of interest."""
            
        def __init__( self, pos=Vec3( 0, 0, 0 ) ):
            NodePath.__init__( self, 'target' )
            
            self.defaultPos = pos
    
    def __init__( self, name='camera', *args, **kwargs ):
        pos = kwargs.pop( 'pos', (0, 0, 0) )
        targetPos = kwargs.pop( 'targetPos', (0, 0, 0) )
        style = kwargs.pop( 'style', CAM_DEFAULT_STYLE )
        p3d.SingleTask.__init__( self, name, *args, **kwargs )
                      
        self.zoomLevel = 2
        self.defaultPos = pos
        self.style = style
        
        # Use Panda's default camera
        if self.style & CAM_USE_DEFAULT:
            self.cam = getBase().cam
            #self.camNode = getBase().camNode
            
        # Otherwise create a new one
        else:
            
            # Create camera
            self.cam = NodePath( PCamera( name ) )
            
            # Create lens
            lens = PerspectiveLens()
            lens.setAspectRatio( 800.0 / 300.0 )
            self.cam.node().setLens( lens )
            
        # Wrap the camera in this node path class
        NodePath.__init__( self, self.cam )
        
        # Create camera styles
        if self.style & CAM_VIEWPORT_AXES:
            self.axes = pm.NodePath( p3d.geometry.Axes() )
            self.axes.reparentTo( self.rootP2d )
        
        # Create camera target
        self.target = self.Target( pos=targetPos )
        
        self.Reset()
        
    def Reset( self ):
        
        # Reset camera and target back to default positions
        self.target.setPos( self.target.defaultPos )
        self.setPos( self.defaultPos )
        
        # Set camera to look at target
        self.lookAt( self.target.getPos() )
        self.target.setQuat( self.getQuat() )
        
    def Move( self, moveVec ):
            
        # Modify the move vector by the distance to the target, so the further
        # away the camera is the faster it moves
        cameraVec = self.getPos() - self.target.getPos()
        cameraDist = cameraVec.length()
        moveVec *= cameraDist / 300
        
        # Move the camera
        self.setPos( self, moveVec )
        
        # Move the target so it stays with the camera
        self.target.setQuat( self.getQuat() )
        test = Vec3( moveVec.getX(), 0, moveVec.getZ() )
        self.target.setPos( self.target, test )
        
    def Orbit( self, delta ):
        
        # Get new hpr
        newHpr = Vec3()
        newHpr.setX( self.getH() + delta.getX() )
        newHpr.setY( self.getP() + delta.getY() )
        newHpr.setZ( self.getR() )
        
        # Set camera to new hpr
        self.setHpr( newHpr )
            
        # Get the H and P in radians
        radX = newHpr.getX() * ( math.pi / 180.0 )
        radY = newHpr.getY() * ( math.pi / 180.0 )
            
        # Get distance from camera to target
        cameraVec = self.getPos() - self.target.getPos()
        cameraDist = cameraVec.length()
            
        # Get new camera pos
        newPos = Vec3()
        newPos.setX( cameraDist * math.sin( radX ) * math.cos( radY ) )
        newPos.setY( -cameraDist * math.cos( radX ) * math.cos( radY ) )
        newPos.setZ( -cameraDist * math.sin( radY ) )
        newPos += self.target.getPos()
            
        # Set camera to new pos
        self.setPos( newPos )
        
    def Frame( self, nps ):
        
        # Get a list of bounding spheres for each NodePath in world space.
        allBnds = []
        allCntr = pm.Vec3()
        for np in nps:
            bnds = np.getBounds()
            if bnds.isInfinite():
                continue
            mat = np.getParent().getMat( self.rootNp )
            bnds.xform( mat )
            allBnds.append( bnds )
            allCntr += bnds.getCenter()
        
        # Now create a bounding sphere at the center point of all the 
        # NodePaths and extend it to encapsulate each one.
        bnds = pm.BoundingSphere( pm.Point3( allCntr / len( nps ) ), 0 )
        for bnd in allBnds:
            bnds.extendBy( bnd )
        
        # Move the camera and the target the the bounding sphere's center.
        self.target.setPos( bnds.getCenter() )
        self.setPos( bnds.getCenter() )

        # Now move the camera back so the view accomodates all NodePaths.
        # Default the bounding radius to something reasonable if the object
        # has no size.
        fov = self.GetLens().getFov()
        radius = bnds.getRadius() or 0.5
        dist = radius / math.tan( math.radians( min( fov[0], fov[1] ) * 0.5 ) )
        self.setY( self, -dist )
        
    def cameraMovement( self, task ):
        x,y,z = self.cube.getPos()
        #smoothly follow the cube...
        self.setX( self.getX() - ( ( self.getX() - x - 18 * self.zoomLevel ) * 5 * globalClock.getDt() ) )
        self.setY( self.getY() - ( ( self.getY() - y + 5 * self.zoomLevel ) * 5 * globalClock.getDt() ) )
        self.setZ( 15 * self.ZOOMLEVEL )
        self.setHpr( 75, -37, 0 )
        
        return task.cont
    
    def OnUpdate( self, task ):
        
        # Position axes 30 pixels from top left corner
        self.axes.setPos( Vec3( 30, 0, -30 ) )
        
        # Set rotation to inverse of camera rotation
        cameraQuat = Quat( self.getQuat() )
        cameraQuat.invertInPlace()
        self.axes.setQuat( cameraQuat )
        
    def GetLens( self ):
        return self.cam.node().getLens()
예제 #10
0
파일: test.py 프로젝트: crempp/Fire-Water
class Square(object):
    #drawSquare
    #Draws a square from lower left (x1, y2, z1) to upper right (x2, y2, z2)
    def __init__(self, parent, p1, p2, color):
        self.parent = parent
        self.x1 = p1.getX()
        self.y1 = p1.getY()
        self.z1 = p1.getZ()
        self.x2 = p2.getX()
        self.y2 = p2.getY()
        self.z2 = p2.getZ()

        self.r = color.getX()
        self.g = color.getY()
        self.b = color.getZ()
        self.a = color.getW()

        self.draw()

    def draw(self):
        format = GeomVertexFormat.getV3n3cpt2()
        vdata = GeomVertexData('square', format, Geom.UHStatic)

        vertex = GeomVertexWriter(vdata, 'vertex')
        normal = GeomVertexWriter(vdata, 'normal')
        color = GeomVertexWriter(vdata, 'color')
        texcoord = GeomVertexWriter(vdata, 'texcoord')

        #make sure we draw the sqaure in the right plane
        #if x1!=x2:
        vertex.addData3f(self.x1, self.y1, self.z1)
        vertex.addData3f(self.x2, self.y1, self.z1)
        vertex.addData3f(self.x2, self.y2, self.z2)
        vertex.addData3f(self.x1, self.y2, self.z2)

        normal.addData3f(
            Vec3(2 * self.x1 - 1, 2 * self.y1 - 1,
                 2 * self.z1 - 1).normalize())
        normal.addData3f(
            Vec3(2 * self.x2 - 1, 2 * self.y1 - 1,
                 2 * self.z1 - 1).normalize())
        normal.addData3f(
            Vec3(2 * self.x2 - 1, 2 * self.y2 - 1,
                 2 * self.z2 - 1).normalize())
        normal.addData3f(
            Vec3(2 * self.x1 - 1, 2 * self.y2 - 1,
                 2 * self.z2 - 1).normalize())

        #adding different colors to the vertex for visibility
        color.addData4f(self.r, self.g, self.b, self.a)
        color.addData4f(self.r, self.g, self.b, self.a)
        color.addData4f(self.r, self.g, self.b, self.a)
        color.addData4f(self.r, self.g, self.b, self.a)

        texcoord.addData2f(0.0, 1.0)
        texcoord.addData2f(0.0, 0.0)
        texcoord.addData2f(1.0, 0.0)
        texcoord.addData2f(1.0, 1.0)

        #quads arent directly supported by the Geom interface
        #you might be interested in the CardMaker class if you are
        #interested in rectangle though
        tri1 = GeomTriangles(Geom.UHStatic)
        tri2 = GeomTriangles(Geom.UHStatic)

        tri1.addVertex(0)
        tri1.addVertex(1)
        tri1.addVertex(3)

        tri2.addConsecutiveVertices(1, 3)

        tri1.closePrimitive()
        tri2.closePrimitive()

        square = Geom(vdata)
        square.addPrimitive(tri1)
        square.addPrimitive(tri2)
        #square.setIntoCollideMask(BitMask32.bit(1))

        self.squareNP = NodePath(GeomNode('square gnode'))
        self.squareNP.node().addGeom(square)
        self.squareNP.setTransparency(1)
        self.squareNP.setAlphaScale(.5)
        self.squareNP.setTwoSided(True)
        #squareNP.setCollideMask(BitMask32.bit(1))
        self.squareNP.reparentTo(self.parent)

        return self.squareNP
예제 #11
0
class Character:

    """A character with an animated avatar that moves left, right or forward
       according to the controls turned on or off in self.controlMap.

    Public fields:
    self.controlMap -- The character's movement controls
    self.actor -- The character's Actor (3D animated model)

    Public functions:
    __init__ -- Initialise the character
    move -- Move and animate the character for one frame. This is a task
            function that is called every frame by Panda3D.
    setControl -- Set one of the character's controls on or off.

    """
    
    
    def __init__(self, agent_simulator, model, actions, startPos, scale):
        """Initialize the character.

        Arguments:
        model -- The path to the character's model file (string)
           run : The path to the model's run animation (string)
           walk : The path to the model's walk animation (string)
           startPos : Where in the world the character will begin (pos)
           scale : The amount by which the size of the model will be scaled 
                   (float)

           """

        self.agent_simulator = agent_simulator
	
        self.controlMap = {"turn_left":0, "turn_right":0, "move_forward":0, "move_backward":0,\
                           "look_up":0, "look_down":0, "look_left":0, "look_right":0}

        self.actor = Actor(model,actions)
        self.actor.reparentTo(render)
        self.actor.setScale(scale)
        self.actor.setPos(startPos)
        
        self.actor.setHpr(0,0,0)
    

        # Expose agent's right hand joint to attach objects to 
        self.actor_right_hand = self.actor.exposeJoint(None, 'modelRoot', 'RightHand')
        self.actor_left_hand  = self.actor.exposeJoint(None, 'modelRoot', 'LeftHand')
        
        self.right_hand_holding_object = False
        self.left_hand_holding_object  = False

        # speech bubble
        self.last_spoke = 0
        self.speech_bubble=DirectLabel(parent=self.actor, text="", text_wordwrap=10, pad=(3,3), relief=None, text_scale=(.5,.5), pos = (0,0,6), frameColor=(.6,.2,.1,.5), textMayChange=1, text_frame=(0,0,0,1), text_bg=(1,1,1,1))
        self.speech_bubble.component('text0').textNode.setCardDecal(1)
        self.speech_bubble.setBillboardAxis()
        
        # visual processing
        self.actor_eye = self.actor.exposeJoint(None, 'modelRoot', 'LeftEyeLid')
        # put a camera on ralph
        self.fov = NodePath(Camera('RaphViz'))
        self.fov.reparentTo(self.actor_eye)
        self.fov.setHpr(180,0,0)
        #lens = OrthographicLens()
        #lens.setFilmSize(20,15)
        #self.fov.node().setLens(lens)
        lens = self.fov.node().getLens()
        lens.setFov(60) #  degree field of view (expanded from 40)
        lens.setNear(0.2)
        #self.fov.node().showFrustum() # displays a box around his head


        self.actor_neck = self.actor.controlJoint(None, 'modelRoot', 'Neck')
	
        # Define subpart of agent for when he's standing around
        self.actor.makeSubpart("arms", ["LeftShoulder", "RightShoulder"])
        taskMgr.add(self.move,"moveTask") # Note: deriving classes DO NOT need
                                          # to add their own move tasks to the
                                          # task manager. If they override
                                          # self.move, then their own self.move
                                          # function will get called by the
                                          # task manager (they must then
                                          # explicitly call Character.move in
                                          # that function if they want it).
        self.prevtime = 0
        self.isMoving = False
	
        self.current_frame_count = 0.0
	
        # We will detect the height of the terrain by creating a collision
        # ray and casting it downward toward the terrain.  One ray will
        # start above ralph's head, and the other will start above the camera.
        # A ray may hit the terrain, or it may hit a rock or a tree.  If it
        # hits the terrain, we can detect the height.  If it hits anything
        # else, we rule that the move is illegal.
        
        self.initialize_collision_handling()

    def initialize_collision_handling(self):
        self.collision_handling_mutex = Lock()
        
        self.cTrav = CollisionTraverser()
        
        self.groundRay = CollisionRay()
        self.groundRay.setOrigin(0,0,1000)
        self.groundRay.setDirection(0,0,-1)
        self.groundCol = CollisionNode('ralphRay')
        self.groundCol.setIntoCollideMask(BitMask32.bit(0))
        self.groundCol.setFromCollideMask(BitMask32.bit(0))
        self.groundCol.addSolid(self.groundRay)
        self.groundColNp = self.actor.attachNewNode(self.groundCol)
        self.groundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.groundColNp, self.groundHandler)

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

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

    def destroy_collision_handling(self):
        self.collision_handling_mutex.acquire()
    
    def handle_collisions(self):
        self.collision_handling_mutex.acquire()
        self.groundCol.setIntoCollideMask(BitMask32.bit(0))
        self.groundCol.setFromCollideMask(BitMask32.bit(1))

        # Now check for collisions.
        self.cTrav.traverse(render)
        
        # Adjust the character's Z coordinate.  If the character's ray hit terrain,
        # update his Z. If it hit anything else, or didn't hit anything, put
        # him back where he was last frame.
        
        entries = []
        for i in range(self.groundHandler.getNumEntries()):
            entry = self.groundHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
            self.actor.setZ(entries[0].getSurfacePoint(render).getZ())
        else:
            self.actor.setPos(self.startpos)
        
        self.groundCol.setIntoCollideMask(BitMask32.bit(0))
        self.groundCol.setFromCollideMask(BitMask32.bit(0))
        self.collision_handling_mutex.release()

    def position(self):
        return self.actor.getPos()
	
    def forward_normal_vector(self):
        backward = self.actor.getNetTransform().getMat().getRow3(1)
        backward.setZ(0)
        backward.normalize()
        return -backward

    def step_simulation_time(self, seconds):
        # save the character's initial position so that we can restore it,
        # in case he falls off the map or runs into something.

        self.startpos = self.actor.getPos()

        def bound(i, mn = -1, mx = 1): return min(max(i, mn), mx) # enforces bounds on a numeric value
        # move the character if any of the move controls are activated.

        if (self.controlMap["turn_left"]!=0):
            self.actor.setH(self.actor.getH() + seconds*30)
        if (self.controlMap["turn_right"]!=0):
            self.actor.setH(self.actor.getH() - seconds*30)
        if (self.controlMap["move_forward"]!=0):
            self.actor.setPos(self.actor.getPos() + self.forward_normal_vector() * (seconds*0.5))
        if (self.controlMap["move_backward"]!=0):
            self.actor.setPos(self.actor.getPos() - self.forward_normal_vector() * (seconds*0.5))
        if (self.controlMap["look_left"]!=0):
            self.actor_neck.setP(bound(self.actor_neck.getP(),-60,60)+1*(seconds*50))
        if (self.controlMap["look_right"]!=0):
            self.actor_neck.setP(bound(self.actor_neck.getP(),-60,60)-1*(seconds*50))
        if (self.controlMap["look_up"]!=0):
            self.actor_neck.setH(bound(self.actor_neck.getH(),-60,80)+1*(seconds*50))
        if (self.controlMap["look_down"]!=0):
            self.actor_neck.setH(bound(self.actor_neck.getH(),-60,80)-1*(seconds*50))

        # allow dialogue window to gradually decay (changing transparancy) and then disappear
        self.last_spoke += seconds
        self.speech_bubble['text_bg']=(1,1,1,1/(2*self.last_spoke+0.01))
        self.speech_bubble['frameColor']=(.6,.2,.1,.5/(2*self.last_spoke+0.01))
        if self.last_spoke > 2:
            self.speech_bubble['text'] = ""

        # If the character is moving, loop the run animation.
        # If he is standing still, stop the animation.
	
        if (self.controlMap["move_forward"]!=0) or (self.controlMap["move_backward"]!=0):
            if self.isMoving is False:
                self.isMoving = True
        else:
            if self.isMoving:
                self.current_frame_count = 5.0
                self.isMoving = False
	
	total_frame_num = self.actor.getNumFrames('walk')
	if self.isMoving:
		self.current_frame_count = self.current_frame_count + (seconds*10.0)
		while (self.current_frame_count >= total_frame_num + 1):
			self.current_frame_count -= total_frame_num
		while (self.current_frame_count < 0):
			self.current_frame_count += total_frame_num
	self.actor.pose('walk', self.current_frame_count)
	
        self.handle_collisions()

    def move(self, task):
        """Move and animate the character for one frame.

        This is a task function that is called every frame by Panda3D.
        The character is moved according to which of it's movement controls
        are set, and the function keeps the character's feet on the ground
        and stops the character from moving if a collision is detected.
        This function also handles playing the characters movement
        animations.

        Arguments:
        task -- A direct.task.Task object passed to this function by Panda3D.

        Return:
        Task.cont -- To tell Panda3D to call this task function again next
                     frame.
        """

        elapsed = task.time - self.prevtime

        # Store the task time and continue.
        self.prevtime = task.time
        return Task.cont
    
    def setControl(self, control, value):
        """Set the state of one of the character's movement controls.

        Arguments
        See self.controlMap in __init__.
        control -- The control to be set, must be a string matching one of
                   the strings in self.controlMap.
        value -- The value to set the control to.

        """

        # FIXME: this function is duplicated in Camera and Character, and
        # keyboard control settings are spread throughout the code. Maybe
        # add a Controllable class?

        self.controlMap[control] = value

    # these are simple commands that can be exported over xml-rpc (or attached to the keyboard)


    def get_objects(self):
        """ Looks up all of the model nodes that are 'isInView' of the camera
        and returns them in the in_view dictionary (as long as they are also
        in the self.world_objects -- otherwise this includes points defined
        within the environment/terrain). 

        TODO:  1) include more geometric information about the object (size, mass, etc)
        """

        def map3dToAspect2d(node, point):
            """Maps the indicated 3-d point (a Point3), which is relative to 
            the indicated NodePath, to the corresponding point in the aspect2d 
            scene graph. Returns the corresponding Point3 in aspect2d. 
            Returns None if the point is not onscreen. """ 
            # Convert the point to the 3-d space of the camera 
            p3 = self.fov.getRelativePoint(node, point) 

            # Convert it through the lens to render2d coordinates 
            p2 = Point2()
            if not self.fov.node().getLens().project(p3, p2):
                return None 
            r2d = Point3(p2[0], 0, p2[1])
            # And then convert it to aspect2d coordinates 
            a2d = aspect2d.getRelativePoint(render2d, r2d)
            return a2d

        objs = render.findAllMatches("**/+ModelNode")
        in_view = {}
        for o in objs:
            o.hideBounds() # in case previously turned on
            o_pos = o.getPos(self.fov)
            if self.fov.node().isInView(o_pos):
                if self.agent_simulator.world_objects.has_key(o.getName()):
                    b_min, b_max =  o.getTightBounds()
                    a_min = map3dToAspect2d(render, b_min)
                    a_max = map3dToAspect2d(render, b_max)
                    if a_min == None or a_max == None:
                        continue
                    x_diff = math.fabs(a_max[0]-a_min[0])
                    y_diff = math.fabs(a_max[2]-a_min[2])
                    area = 100*x_diff*y_diff  # percentage of screen
                    object_dict = {'x_pos': (a_min[2]+a_max[2])/2.0,\
                                   'y_pos': (a_min[0]+a_max[0])/2.0,\
                                   'distance':o.getDistance(self.fov), \
                                   'area':area,\
                                   'orientation': o.getH(self.fov)}
                    in_view[o.getName()]=object_dict
                    print o.getName(), object_dict
        return in_view

    def control__turn_left__start(self):
        self.setControl("turn_left",  1)
        self.setControl("turn_right", 0)

    def control__turn_left__stop(self):
        self.setControl("turn_left",  0)

    def control__turn_right__start(self):
        self.setControl("turn_left",  0)
        self.setControl("turn_right", 1)

    def control__turn_right__stop(self):
        self.setControl("turn_right", 0)

    def control__move_forward__start(self):
        self.setControl("move_forward",  1)
        self.setControl("move_backward", 0)

    def control__move_forward__stop(self):
        self.setControl("move_forward",  0)

    def control__move_backward__start(self):
        self.setControl("move_forward",  0)
        self.setControl("move_backward", 1)

    def control__move_backward__stop(self):
        self.setControl("move_backward", 0)

    def control__look_left__start(self):
        self.setControl("look_left",  1)
        self.setControl("look_right", 0)

    def control__look_left__stop(self):
        self.setControl("look_left",  0)

    def control__look_right__start(self):
        self.setControl("look_right",  1)
        self.setControl("look_left", 0)

    def control__look_right__stop(self):
        self.setControl("look_right",  0)

    def control__look_up__start(self):
        self.setControl("look_up",  1)
        self.setControl("look_down", 0)

    def control__look_up__stop(self):
        self.setControl("look_up",  0)
    
    def control__look_down__start(self):
        self.setControl("look_down",  1)
        self.setControl("look_up",  0)
    
    def control__look_down__stop(self):
        self.setControl("look_down",  0)

    def can_grasp(self, object_name):
        objects = self.get_objects()
        if objects.has_key(object_name):
            object_view = objects[object_name]
            distance = object_view['distance']
            if (distance < 5.0):
                return True
        return False

    def control__say(self, message):
       self.speech_bubble['text'] = message
       self.last_spoke = 0

    def control__pick_up_with_right_hand(self, pick_up_object):
        print "attempting to pick up " + pick_up_object + " with right hand.\n"
        if self.right_hand_holding_object:
            return 'right hand is already holding ' + self.right_hand_holding_object.getName() + '.'
	if self.can_grasp(pick_up_object):
	    world_object = self.agent_simulator.world_objects[pick_up_object]
	    object_parent = world_object.getParent()
	    if (object_parent == self.agent_simulator.env):
		world_object.wrtReparentTo(self.actor_right_hand)
		world_object.setPos(0, 0, 0)
		world_object.setHpr(0, 0, 0)
		self.right_hand_holding_object = world_object
		return 'success'
	    else:
		return 'object (' + pick_up_object + ') is already held by something or someone.'
	else:
	    return 'object (' + pick_up_object + ') is not graspable (i.e. in view and close enough).'

    def put_object_in_empty_left_hand(self, object_name):
	if (self.left_hand_holding_object is not False):
	    return False
	world_object = self.agent_simulator.world_objects[object_name]
	world_object.wrtReparentTo(self.actor_left_hand)
	world_object.setPos(0, 0, 0)
	world_object.setHpr(0, 0, 0)
	self.left_hand_holding_object = world_object
	return True
    
    def control__pick_up_with_left_hand(self, pick_up_object):
        print "attempting to pick up " + pick_up_object + " with left hand.\n"
        if self.left_hand_holding_object:
            return 'left hand is already holding ' + self.left_hand_holding_object.getName() + '.'
        if self.can_grasp(pick_up_object):
	    world_object = self.agent_simulator.world_objects[pick_up_object]
	    object_parent = world_object.getParent()
	    if (object_parent == self.agent_simulator.env):
		self.put_object_in_empty_left_hand(pick_up_object)
		return 'success'
	    else:
		return 'object (' + pick_up_object + ') is already held by something or someone.'
        else:
            return 'object (' + pick_up_object + ') is not graspable (i.e. in view and close enough).'

    def control__drop_from_right_hand(self):
        print "attempting to drop object from right hand.\n"
        if self.right_hand_holding_object is False:
            return 'right hand is not holding an object.'
        world_object = self.right_hand_holding_object
        self.right_hand_holding_object = False
        world_object.wrtReparentTo(self.agent_simulator.env)
        world_object.setHpr(0, 0, 0)
        world_object.setPos(self.position() + self.forward_normal_vector() * 0.5)
        world_object.setZ(world_object.getZ() + 1.0)
        return 'success'
    
    def control__drop_from_left_hand(self):
        print "attempting to drop object from left hand.\n"
        if self.left_hand_holding_object is False:
            return 'left hand is not holding an object.'
        world_object = self.left_hand_holding_object
        self.left_hand_holding_object = False
        world_object.wrtReparentTo(self.agent_simulator.env)
        world_object.setHpr(0, 0, 0)
        world_object.setPos(self.position() + self.forward_normal_vector() * 0.5)
        world_object.setZ(world_object.getZ() + 1.0)
	return 'success'

    def is_holding(self, object_name):
	return ((self.left_hand_holding_object  and (self.left_hand_holding_object.getName()  == object_name)) or
		(self.right_hand_holding_object and (self.right_hand_holding_object.getName() == object_name)))
    
    def empty_hand(self):
        if (self.left_hand_holding_object is False):
            return self.actor_left_hand
        elif (self.right_hand_holding_object is False):
            return self.actor_right_hand
        return False

    def has_empty_hand(self):
        return (self.empty_hand() is not False)

    def control__use_object_with_object(self, use_object, with_object):
	if ((use_object == 'knife') and (with_object == 'loaf_of_bread')):
	    if self.is_holding('knife'):
		if self.can_grasp('loaf_of_bread'):
		    if self.has_empty_hand():
			empty_hand      = self.empty_hand()
			new_object_name = self.agent_simulator.create_object__slice_of_bread([float(x) for x in empty_hand.getPos()])
			if (empty_hand == self.actor_left_hand):
			    self.put_object_in_empty_left_hand(new_object_name)
			elif (empty_hand == self.actor_right_hand):
			    self.put_object_in_empty_right_hand(new_object_name)
			else:
			    return "simulator error: empty hand is not left or right.  (are there others?)"
			return 'success'
		    else:
			return 'failure: one hand must be empty to hold loaf_of_bread in place while using knife.'
		else:
		    return 'failure: loaf of bread is not graspable (in view and close enough)'
	    else:
		return 'failure: must be holding knife object to use it.'
        return 'failure: don\'t know how to use ' + use_object + ' with ' + with_object + '.'
예제 #12
0
파일: camera.py 프로젝트: Derfies/p3d
class Camera(NodePath, p3d.SingleTask):
    """Class representing a camera."""
    class Target(NodePath):
        """Class representing the camera's point of interest."""
        def __init__(self, pos=Vec3(0, 0, 0)):
            NodePath.__init__(self, 'target')

            self.defaultPos = pos

    def __init__(self, name='camera', *args, **kwargs):
        pos = kwargs.pop('pos', (0, 0, 0))
        targetPos = kwargs.pop('targetPos', (0, 0, 0))
        style = kwargs.pop('style', CAM_DEFAULT_STYLE)
        p3d.SingleTask.__init__(self, name, *args, **kwargs)

        self.zoomLevel = 2
        self.defaultPos = pos
        self.style = style

        # Use Panda's default camera
        if self.style & CAM_USE_DEFAULT:
            self.cam = getBase().cam
            #self.camNode = getBase().camNode

        # Otherwise create a new one
        else:

            # Create camera
            self.cam = NodePath(PCamera(name))

            # Create lens
            lens = PerspectiveLens()
            lens.setAspectRatio(800.0 / 300.0)
            self.cam.node().setLens(lens)

        # Wrap the camera in this node path class
        NodePath.__init__(self, self.cam)

        # Create camera styles
        if self.style & CAM_VIEWPORT_AXES:
            self.axes = pm.NodePath(p3d.geometry.Axes())
            self.axes.reparentTo(self.rootP2d)

        # Create camera target
        self.target = self.Target(pos=targetPos)

        self.Reset()

    def Reset(self):

        # Reset camera and target back to default positions
        self.target.setPos(self.target.defaultPos)
        self.setPos(self.defaultPos)

        # Set camera to look at target
        self.lookAt(self.target.getPos())
        self.target.setQuat(self.getQuat())

    def Move(self, moveVec):

        # Modify the move vector by the distance to the target, so the further
        # away the camera is the faster it moves
        cameraVec = self.getPos() - self.target.getPos()
        cameraDist = cameraVec.length()
        moveVec *= cameraDist / 300

        # Move the camera
        self.setPos(self, moveVec)

        # Move the target so it stays with the camera
        self.target.setQuat(self.getQuat())
        test = Vec3(moveVec.getX(), 0, moveVec.getZ())
        self.target.setPos(self.target, test)

    def Orbit(self, delta):

        # Get new hpr
        newHpr = Vec3()
        newHpr.setX(self.getH() + delta.getX())
        newHpr.setY(self.getP() + delta.getY())
        newHpr.setZ(self.getR())

        # Set camera to new hpr
        self.setHpr(newHpr)

        # Get the H and P in radians
        radX = newHpr.getX() * (math.pi / 180.0)
        radY = newHpr.getY() * (math.pi / 180.0)

        # Get distance from camera to target
        cameraVec = self.getPos() - self.target.getPos()
        cameraDist = cameraVec.length()

        # Get new camera pos
        newPos = Vec3()
        newPos.setX(cameraDist * math.sin(radX) * math.cos(radY))
        newPos.setY(-cameraDist * math.cos(radX) * math.cos(radY))
        newPos.setZ(-cameraDist * math.sin(radY))
        newPos += self.target.getPos()

        # Set camera to new pos
        self.setPos(newPos)

    def Frame(self, nps):

        # Get a list of bounding spheres for each NodePath in world space.
        allBnds = []
        allCntr = pm.Vec3()
        for np in nps:
            bnds = np.getBounds()
            if bnds.isInfinite():
                continue
            mat = np.getParent().getMat(self.rootNp)
            bnds.xform(mat)
            allBnds.append(bnds)
            allCntr += bnds.getCenter()

        # Now create a bounding sphere at the center point of all the
        # NodePaths and extend it to encapsulate each one.
        bnds = pm.BoundingSphere(pm.Point3(allCntr / len(nps)), 0)
        for bnd in allBnds:
            bnds.extendBy(bnd)

        # Move the camera and the target the the bounding sphere's center.
        self.target.setPos(bnds.getCenter())
        self.setPos(bnds.getCenter())

        # Now move the camera back so the view accomodates all NodePaths.
        # Default the bounding radius to something reasonable if the object
        # has no size.
        fov = self.GetLens().getFov()
        radius = bnds.getRadius() or 0.5
        dist = radius / math.tan(math.radians(min(fov[0], fov[1]) * 0.5))
        self.setY(self, -dist)

    def cameraMovement(self, task):
        x, y, z = self.cube.getPos()
        #smoothly follow the cube...
        self.setX(self.getX() - (
            (self.getX() - x - 18 * self.zoomLevel) * 5 * globalClock.getDt()))
        self.setY(self.getY() - (
            (self.getY() - y + 5 * self.zoomLevel) * 5 * globalClock.getDt()))
        self.setZ(15 * self.ZOOMLEVEL)
        self.setHpr(75, -37, 0)

        return task.cont

    def OnUpdate(self, task):

        # Position axes 30 pixels from top left corner
        self.axes.setPos(Vec3(30, 0, -30))

        # Set rotation to inverse of camera rotation
        cameraQuat = Quat(self.getQuat())
        cameraQuat.invertInPlace()
        self.axes.setQuat(cameraQuat)

    def GetLens(self):
        return self.cam.node().getLens()
예제 #13
0
class DirLight:
  """Creates a simple directional light"""
  def __init__(self,manager,xml):
    self.light = PDirectionalLight('dlight')
    self.lightNode = NodePath(self.light)
    self.lightNode.setCompass()
    if hasattr(self.lightNode.node(), "setCameraMask"):
      self.lightNode.node().setCameraMask(BitMask32.bit(3))

    self.reload(manager,xml)


  def reload(self,manager,xml):
    color = xml.find('color')
    if color!=None:
      self.light.setColor(VBase4(float(color.get('r')),
                                 float(color.get('g')),
                                 float(color.get('b')), 1.0))

    pos = xml.find('pos')
    if pos!=None:
      self.lightNode.setPos(float(pos.get('x')),
                            float(pos.get('y')),
                            float(pos.get('z')))
    else:
      self.lightNode.setPos(0, 0, 0)

    lookAt = xml.find('lookAt')
    if lookAt!=None:
      self.lightNode.lookAt(float(lookAt.get('x')),
                            float(lookAt.get('y')),
                            float(lookAt.get('z')))

    lens = xml.find('lens')
    if lens!=None and hasattr(self.lightNode.node(), 'getLens'):
      if bool(int(lens.get('auto'))):
        self.lightNode.reparentTo(base.camera)
      else:
        self.lightNode.reparentTo(render)
      lobj = self.lightNode.node().getLens()

      lobj.setNearFar(float(lens.get('near', 1.0)),
                      float(lens.get('far', 100000.0)))

      lobj.setFilmSize(float(lens.get('width', 1.0)),
                       float(lens.get('height', 1.0)))

      lobj.setFilmOffset(float(lens.get('x', 0.0)),
                         float(lens.get('y', 0.0)))

    if hasattr(self.lightNode.node(), 'setShadowCaster'):
      shadows = xml.find('shadows')
      if shadows!=None:
        self.lightNode.node().setShadowCaster(True, int(shadows.get('width', 512)),
                                                    int(shadows.get('height', 512)),
                                                    int(shadows.get('sort', -10)))
        #self.lightNode.node().setPushBias(float(shadows.get('bias', 0.5)))
      else:
        self.lightNode.node().setShadowCaster(False)

  def start(self):
    render.setLight(self.lightNode)

  def stop(self):
    render.clearLight(self.lightNode)
예제 #14
0
class IsisAgent(kinematicCharacterController, DirectObject):
    @classmethod
    def setPhysics(cls, physics):
        """ This method is set in src.loader when the generators are loaded
        into the namespace.  This frees the environment definitions (in 
        scenario files) from having to pass around the physics parameter 
        that is required for all IsisObjects """
        cls.physics = physics

    def __init__(self, name, queueSize=100):

        # load the model and the different animations for the model into an Actor object.
        self.actor = Actor(
            "media/models/boxman", {"walk": "media/models/boxman-walk", "idle": "media/models/boxman-idle"}
        )
        self.actor.setScale(1.0)
        self.actor.setH(0)
        # self.actor.setLODAnimation(10,5,2) # slows animation framerate when actor is far from camera, if you can figure out reasonable params
        self.actor.setColorScale(random.random(), random.random(), random.random(), 1.0)
        self.actorNodePath = NodePath("agent-%s" % name)
        self.activeModel = self.actorNodePath

        self.actorNodePath.reparentTo(render)

        self.actor.reparentTo(self.actorNodePath)
        self.name = name
        self.isMoving = False

        # initialize ODE controller
        kinematicCharacterController.__init__(self, IsisAgent.physics, self.actorNodePath)
        self.setGeomPos(self.actorNodePath.getPos(render))
        """
        Additional Direct Object that I use for convenience.
        """
        self.specialDirectObject = DirectObject()

        """
        How high above the center of the capsule you want the camera to be
        when walking and when crouching. It's related to the values in KCC.
        """
        self.walkCamH = 0.7
        self.crouchCamH = 0.2
        self.camH = self.walkCamH

        """
        This tells the Player Controller what we're aiming at.
        """
        self.aimed = None

        self.isSitting = False
        self.isDisabled = False

        """
        The special direct object is used for trigger messages and the like.
        """
        # self.specialDirectObject.accept("ladder_trigger_enter", self.setFly, [True])
        # self.specialDirectObject.accept("ladder_trigger_exit", self.setFly, [False])

        self.actor.makeSubpart("arms", ["LeftShoulder", "RightShoulder"])

        # Expose agent's right hand joint to attach objects to
        self.player_right_hand = self.actor.exposeJoint(None, "modelRoot", "Hand.R")
        self.player_left_hand = self.actor.exposeJoint(None, "modelRoot", "Hand.L")

        self.right_hand_holding_object = None
        self.left_hand_holding_object = None

        # don't change the color of things you pick up
        self.player_right_hand.setColorScaleOff()
        self.player_left_hand.setColorScaleOff()

        self.player_head = self.actor.exposeJoint(None, "modelRoot", "Head")
        self.neck = self.actor.controlJoint(None, "modelRoot", "Head")

        self.controlMap = {
            "turn_left": 0,
            "turn_right": 0,
            "move_forward": 0,
            "move_backward": 0,
            "move_right": 0,
            "move_left": 0,
            "look_up": 0,
            "look_down": 0,
            "look_left": 0,
            "look_right": 0,
            "jump": 0,
        }
        # see update method for uses, indices are [turn left, turn right, move_forward, move_back, move_right, move_left, look_up, look_down, look_right, look_left]
        # turns are in degrees per second, moves are in units per second
        self.speeds = [270, 270, 5, 5, 5, 5, 60, 60, 60, 60]

        self.originalPos = self.actor.getPos()

        bubble = loader.loadTexture("media/textures/thought_bubble.png")
        # bubble.setTransparency(TransparencyAttrib.MAlpha)

        self.speech_bubble = DirectLabel(
            parent=self.actor,
            text="",
            text_wordwrap=10,
            pad=(3, 3),
            relief=None,
            text_scale=(0.3, 0.3),
            pos=(0, 0, 3.6),
            frameColor=(0.6, 0.2, 0.1, 0.5),
            textMayChange=1,
            text_frame=(0, 0, 0, 1),
            text_bg=(1, 1, 1, 1),
        )
        # self.myImage=
        self.speech_bubble.setTransparency(TransparencyAttrib.MAlpha)
        # stop the speech bubble from being colored like the agent
        self.speech_bubble.setColorScaleOff()
        self.speech_bubble.component("text0").textNode.setCardDecal(1)
        self.speech_bubble.setBillboardAxis()
        # hide the speech bubble from IsisAgent's own camera
        self.speech_bubble.hide(BitMask32.bit(1))

        self.thought_bubble = DirectLabel(
            parent=self.actor,
            text="",
            text_wordwrap=9,
            text_frame=(1, 0, -2, 1),
            text_pos=(0, 0.5),
            text_bg=(1, 1, 1, 0),
            relief=None,
            frameSize=(0, 1.5, -2, 3),
            text_scale=(0.18, 0.18),
            pos=(0, 0.2, 3.6),
            textMayChange=1,
            image=bubble,
            image_pos=(0, 0.1, 0),
            sortOrder=5,
        )
        self.thought_bubble.setTransparency(TransparencyAttrib.MAlpha)
        # stop the speech bubble from being colored like the agent
        self.thought_bubble.setColorScaleOff()
        self.thought_bubble.component("text0").textNode.setFrameColor(1, 1, 1, 0)
        self.thought_bubble.component("text0").textNode.setFrameAsMargin(0.1, 0.1, 0.1, 0.1)
        self.thought_bubble.component("text0").textNode.setCardDecal(1)
        self.thought_bubble.setBillboardAxis()
        # hide the thought bubble from IsisAgent's own camera
        self.thought_bubble.hide(BitMask32.bit(1))
        # disable by default
        self.thought_bubble.hide()
        self.thought_filter = {}  # only show thoughts whose values are in here
        self.last_spoke = 0  # timers to keep track of last thought/speech and
        self.last_thought = 0  # hide visualizations

        # put a camera on ralph
        self.fov = NodePath(Camera("RaphViz"))
        self.fov.node().setCameraMask(BitMask32.bit(1))

        # position the camera to be infront of Boxman's face.
        self.fov.reparentTo(self.player_head)
        # x,y,z are not in standard orientation when parented to player-Head
        self.fov.setPos(0, 0.2, 0)
        # if P=0, canrea is looking directly up. 90 is back of head. -90 is on face.
        self.fov.setHpr(0, -90, 0)

        lens = self.fov.node().getLens()
        lens.setFov(60)  #  degree field of view (expanded from 40)
        lens.setNear(0.2)
        # self.fov.node().showFrustum() # displays a box around his head
        # self.fov.place()

        self.prevtime = 0
        self.current_frame_count = 0

        self.isSitting = False
        self.isDisabled = False
        self.msg = None
        self.actorNodePath.setPythonTag("agent", self)

        # Initialize the action queue, with a maximum length of queueSize
        self.queue = []
        self.queueSize = queueSize
        self.lastSense = 0

    def setLayout(self, layout):
        """ Dummy method called by spatial methods for use with objects. 
        Doesn't make sense for an agent that can move around."""
        pass

    def setPos(self, pos):
        """ Wrapper to set the position of the ODE geometry, which in turn 
        sets the visual model's geometry the next time the update() method
        is called. """
        self.setGeomPos(pos)

    def setPosition(self, pos):
        self.setPos(pos)

    def reparentTo(self, parent):
        self.actorNodePath.reparentTo(parent)

    def setControl(self, control, value):
        """Set the state of one of the character's movement controls.  """
        self.controlMap[control] = value

    def get_objects_in_field_of_vision(self, exclude=["isisobject"]):
        """ This works in an x-ray style. Fast. Works best if you listen to
        http://en.wikipedia.org/wiki/Rock_Art_and_the_X-Ray_Style while
        you use it.
        
        needs to exclude isisobjects since they cannot be serialized  
        """
        objects = {}
        for obj in base.render.findAllMatches("**/IsisObject*"):
            if not obj.hasPythonTag("isisobj"):
                continue
            o = obj.getPythonTag("isisobj")
            bounds = o.activeModel.getBounds()
            bounds.xform(o.activeModel.getMat(self.fov))
            if self.fov.node().isInView(o.activeModel.getPos(self.fov)):
                pos = o.activeModel.getPos(render)
                pos = (pos[0], pos[1], pos[2] + o.getHeight() / 2)
                p1 = self.fov.getRelativePoint(render, pos)
                p2 = Point2()
                self.fov.node().getLens().project(p1, p2)
                p3 = aspect2d.getRelativePoint(render2d, Point3(p2[0], 0, p2[1]))
                object_dict = {}
                if "x_pos" not in exclude:
                    object_dict["x_pos"] = p3[0]
                if "y_pos" not in exclude:
                    object_dict["y_pos"] = p3[2]
                if "distance" not in exclude:
                    object_dict["distance"] = o.activeModel.getDistance(self.fov)
                if "orientation" not in exclude:
                    object_dict["orientation"] = o.activeModel.getH(self.fov)
                if "actions" not in exclude:
                    object_dict["actions"] = o.list_actions()
                if "isisobject" not in exclude:
                    object_dict["isisobject"] = o
                # add item to dinctionary
                objects[o] = object_dict
        return objects

    def get_agents_in_field_of_vision(self):
        """ This works in an x-ray vision style as well"""
        agents = {}
        for agent in base.render.findAllMatches("**/agent-*"):
            if not agent.hasPythonTag("agent"):
                continue
            a = agent.getPythonTag("agent")
            bounds = a.actorNodePath.getBounds()
            bounds.xform(a.actorNodePath.getMat(self.fov))
            pos = a.actorNodePath.getPos(self.fov)
            if self.fov.node().isInView(pos):
                p1 = self.fov.getRelativePoint(render, pos)
                p2 = Point2()
                self.fov.node().getLens().project(p1, p2)
                p3 = aspect2d.getRelativePoint(render2d, Point3(p2[0], 0, p2[1]))
                agentDict = {
                    "x_pos": p3[0],
                    "y_pos": p3[2],
                    "distance": a.actorNodePath.getDistance(self.fov),
                    "orientation": a.actorNodePath.getH(self.fov),
                }
                agents[a] = agentDict
        return agents

    def in_view(self, isisobj):
        """ Returns true iff a particular isisobject is in view """
        return len(
            filter(lambda x: x["isisobject"] == isisobj, self.get_objects_in_field_of_vision(exclude=[]).values())
        )

    def get_objects_in_view(self):
        """ Gets objects through ray tracing.  Slow"""
        return self.picker.get_objects_in_view()

    def control__turn_left__start(self, speed=None):
        self.setControl("turn_left", 1)
        self.setControl("turn_right", 0)
        if speed:
            self.speeds[0] = speed
        return "success"

    def control__turn_left__stop(self):
        self.setControl("turn_left", 0)
        return "success"

    def control__turn_right__start(self, speed=None):
        self.setControl("turn_left", 0)
        self.setControl("turn_right", 1)
        if speed:
            self.speeds[1] = speed
        return "success"

    def control__turn_right__stop(self):
        self.setControl("turn_right", 0)
        return "success"

    def control__move_forward__start(self, speed=None):
        self.setControl("move_forward", 1)
        self.setControl("move_backward", 0)
        if speed:
            self.speeds[2] = speed
        return "success"

    def control__move_forward__stop(self):
        self.setControl("move_forward", 0)
        return "success"

    def control__move_backward__start(self, speed=None):
        self.setControl("move_forward", 0)
        self.setControl("move_backward", 1)
        if speed:
            self.speeds[3] = speed
        return "success"

    def control__move_backward__stop(self):
        self.setControl("move_backward", 0)
        return "success"

    def control__move_left__start(self, speed=None):
        self.setControl("move_left", 1)
        self.setControl("move_right", 0)
        if speed:
            self.speeds[4] = speed
        return "success"

    def control__move_left__stop(self):
        self.setControl("move_left", 0)
        return "success"

    def control__move_right__start(self, speed=None):
        self.setControl("move_right", 1)
        self.setControl("move_left", 0)
        if speed:
            self.speeds[5] = speed
        return "success"

    def control__move_right__stop(self):
        self.setControl("move_right", 0)
        return "success"

    def control__look_left__start(self, speed=None):
        self.setControl("look_left", 1)
        self.setControl("look_right", 0)
        if speed:
            self.speeds[9] = speed
        return "success"

    def control__look_left__stop(self):
        self.setControl("look_left", 0)
        return "success"

    def control__look_right__start(self, speed=None):
        self.setControl("look_right", 1)
        self.setControl("look_left", 0)
        if speed:
            self.speeds[8] = speed
        return "success"

    def control__look_right__stop(self):
        self.setControl("look_right", 0)
        return "success"

    def control__look_up__start(self, speed=None):
        self.setControl("look_up", 1)
        self.setControl("look_down", 0)
        if speed:
            self.speeds[6] = speed
        return "success"

    def control__look_up__stop(self):
        self.setControl("look_up", 0)
        return "success"

    def control__look_down__start(self, speed=None):
        self.setControl("look_down", 1)
        self.setControl("look_up", 0)
        if speed:
            self.speeds[7] = speed
        return "success"

    def control__look_down__stop(self):
        self.setControl("look_down", 0)
        return "success"

    def control__jump(self):
        self.setControl("jump", 1)
        return "success"

    def control__view_objects(self):
        """ calls a raytrace to to all objects in view """
        objects = self.get_objects_in_field_of_vision()
        self.control__say("If I were wearing x-ray glasses, I could see %i items" % len(objects))
        print "Objects in view:", objects
        return objects

    def control__sense(self):
        """ perceives the world, returns percepts dict """
        percepts = dict()
        # eyes: visual matricies
        # percepts['vision'] = self.sense__get_vision()
        # objects in purview (cheating object recognition)
        percepts["objects"] = self.sense__get_objects()
        # global position in environment - our robots can have GPS :)
        percepts["position"] = self.sense__get_position()
        # language: get last utterances that were typed
        percepts["language"] = self.sense__get_utterances()
        # agents: returns a map of agents to a list of actions that have been sensed
        percepts["agents"] = self.sense__get_agents()
        print percepts
        return percepts

    def control__think(self, message, layer=0):
        """ Changes the contents of an agent's thought bubble"""
        # only say things that are checked in the controller
        if self.thought_filter.has_key(layer):
            self.thought_bubble.show()
            self.thought_bubble["text"] = message
            # self.thought_bubble.component('text0').textNode.setShadow(0.05, 0.05)
            # self.thought_bubble.component('text0').textNode.setShadowColor(self.thought_filter[layer])
            self.last_thought = 0
        return "success"

    def control__say(self, message="Hello!"):
        self.speech_bubble["text"] = message
        self.last_spoke = 0
        return "success"

    """

    Methods explicitly for IsisScenario files 

    """

    def put_in_front_of(self, isisobj):
        # find open direction
        pos = isisobj.getGeomPos()
        direction = render.getRelativeVector(isisobj, Vec3(0, 1.0, 0))
        closestEntry, closestObject = IsisAgent.physics.doRaycastNew("aimRay", 5, [pos, direction], [isisobj.geom])
        print "CLOSEST", closestEntry, closestObject
        if closestObject == None:
            self.setPosition(pos + Vec3(0, 2, 0))
        else:
            print "CANNOT PLACE IN FRONT OF %s BECAUSE %s IS THERE" % (isisobj, closestObject)
            direction = render.getRelativeVector(isisobj, Vec3(0, -1.0, 0))
            closestEntry, closestObject = IsisAgent.physics.doRaycastNew("aimRay", 5, [pos, direction], [isisobj.geom])
            if closestEntry == None:
                self.setPosition(pos + Vec3(0, -2, 0))
            else:
                print "CANNOT PLACE BEHIND %s BECAUSE %s IS THERE" % (isisobj, closestObject)
                direction = render.getRelativeVector(isisobj, Vec3(1, 0, 0))
                closestEntry, closestObject = IsisAgent.physics.doRaycastNew(
                    "aimRay", 5, [pos, direction], [isisobj.geom]
                )
                if closestEntry == None:
                    self.setPosition(pos + Vec3(2, 0, 0))
                else:
                    print "CANNOT PLACE TO LEFT OF %s BECAUSE %s IS THERE" % (isisobj, closestObject)
                    # there's only one option left, do it anyway
                    self.setPosition(pos + Vec3(-2, 0, 0))
        # rotate agent to look at it
        self.actorNodePath.setPos(self.getGeomPos())
        self.actorNodePath.lookAt(pos)
        self.setH(self.actorNodePath.getH())

    def put_in_right_hand(self, target):
        return self.pick_object_up_with(target, self.right_hand_holding_object, self.player_right_hand)

    def put_in_left_hand(self, target):
        return self.pick_object_up_with(target, self.left_hand_holding_object, self.player_left_hand)

    def __get_object_in_center_of_view(self):
        direction = render.getRelativeVector(self.fov, Vec3(0, 1.0, 0))
        pos = self.fov.getPos(render)
        exclude = []  # [base.render.find("**/kitchenNode*").getPythonTag("isisobj").geom]
        closestEntry, closestObject = IsisAgent.physics.doRaycastNew("aimRay", 5, [pos, direction], exclude)
        return closestObject

    def pick_object_up_with(self, target, hand_slot, hand_joint):
        """ Attaches an IsisObject, target, to the hand joint.  Does not check anything first,
        other than the fact that the hand joint is not currently holding something else."""
        if hand_slot != None:
            print "already holding " + hand_slot.getName() + "."
            return None
        else:
            if target.layout:
                target.layout.remove(target)
                target.layout = None
            # store original position
            target.originalHpr = target.getHpr(render)
            target.disable()  # turn off physics
            if target.body:
                target.body.setGravityMode(0)
            target.reparentTo(hand_joint)
            target.setPosition(hand_joint.getPos(render))
            target.setTag("heldBy", self.name)
            if hand_joint == self.player_right_hand:
                self.right_hand_holding_object = target
            elif hand_joint == self.player_left_hand:
                self.left_hand_holding_object = target
            hand_slot = target
            return target

    def control__pick_up_with_right_hand(self, target=None):
        if not target:
            target = self.__get_object_in_center_of_view()
            if not target:
                print "no target in reach"
                return "error: no target in reach"
        else:
            target = render.find("**/*" + target + "*").getPythonTag("isisobj")
        print "attempting to pick up " + target.name + " with right hand.\n"
        if self.can_grasp(target):  # object within distance
            return self.pick_object_up_with(target, self.right_hand_holding_object, self.player_right_hand)
        else:
            print "object (" + target.name + ") is not graspable (i.e. in view and close enough)."
            return "error: object not graspable"

    def control__pick_up_with_left_hand(self, target=None):
        if not target:
            target = self.__get_object_in_center_of_view()
            if not target:
                print "no target in reach"
                return
        else:
            target = render.find("**/*" + target + "*").getPythonTag("isisobj")
        print "attempting to pick up " + target.name + " with left hand.\n"
        if self.can_grasp(target):  # object within distance
            return self.pick_object_up_with(target, self.left_hand_holding_object, self.player_left_hand)
        else:
            print "object (" + target.name + ") is not graspable (i.e. in view and close enough)."
            return "error: object not graspable"

    def control__drop_from_right_hand(self):
        print "attempting to drop object from right hand.\n"

        if self.right_hand_holding_object is None:
            print "right hand is not holding an object."
            return False
        if self.right_hand_holding_object.getNetTag("heldBy") == self.name:
            self.right_hand_holding_object.reparentTo(render)
            direction = render.getRelativeVector(self.fov, Vec3(0, 1.0, 0))
            pos = self.player_right_hand.getPos(render)
            heldPos = self.right_hand_holding_object.geom.getPosition()
            self.right_hand_holding_object.setPosition(pos)
            self.right_hand_holding_object.synchPosQuatToNode()
            self.right_hand_holding_object.setTag("heldBy", "")
            self.right_hand_holding_object.setRotation(self.right_hand_holding_object.originalHpr)
            self.right_hand_holding_object.enable()
            if self.right_hand_holding_object.body:
                quat = self.getQuat()
                # throw object
                force = 5
                self.right_hand_holding_object.body.setGravityMode(1)
                self.right_hand_holding_object.getBody().setForce(quat.xform(Vec3(0, force, 0)))
            self.right_hand_holding_object = None
            return "success"
        else:
            return "Error: not being held by agent %s" % (self.name)

    def control__drop_from_left_hand(self):
        print "attempting to drop object from left hand.\n"
        if self.left_hand_holding_object is None:
            return "left hand is not holding an object."
        if self.left_hand_holding_object.getNetTag("heldBy") == self.name:
            self.left_hand_holding_object.reparentTo(render)
            direction = render.getRelativeVector(self.fov, Vec3(0, 1.0, 0))
            pos = self.player_left_hand.getPos(render)
            heldPos = self.left_hand_holding_object.geom.getPosition()
            self.left_hand_holding_object.setPosition(pos)
            self.left_hand_holding_object.synchPosQuatToNode()
            self.left_hand_holding_object.setTag("heldBy", "")
            self.left_hand_holding_object.setRotation(self.left_hand_holding_object.originalHpr)
            self.left_hand_holding_object.enable()
            if self.left_hand_holding_object.body:
                quat = self.getQuat()
                # throw object
                force = 5
                self.left_hand_holding_object.body.setGravityMode(1)
                self.left_hand_holding_object.getBody().setForce(quat.xform(Vec3(0, force, 0)))
            self.left_hand_holding_object = None
            return "success"
        else:
            return "Error: not being held by agent %s" % (self.name)

    def control__use_right_hand(self, target=None, action=None):
        # TODO, rename this to use object with
        if not action:
            if self.msg:
                action = self.msg
            else:
                action = "divide"
        if not target:
            target = self.__get_object_in_center_of_view()
            if not target:
                print "no target in reach"
                return
        else:
            target = render.find("**/*" + target + "*").getPythonTag("isisobj")
        print "Trying to use object", target
        if self.can_grasp(target):
            if target.call(self, action, self.right_hand_holding_object) or (
                self.right_hand_holding_object and self.right_hand_holding_object.call(self, action, target)
            ):
                return "success"
            return str(action) + " not associated with either target or object"
        return "target not within reach"

    def control__use_left_hand(self, target=None, action=None):
        if not action:
            if self.msg:
                action = self.msg
            else:
                action = "divide"
        if not target:
            target = self.__get_object_in_center_of_view()
            if not target:
                print "no target in reach"
                return
        else:
            target = render.find("**/*" + target + "*").getPythonTag("isisobj")
        if self.can_grasp(target):
            if target.call(self, action, self.left_hand_holding_object) or (
                self.left_hand_holding_object and self.left_hand_holding_object.call(self, action, target)
            ):
                return "success"
            return str(action) + " not associated with either target or object"
        return "target not within reach"

    def can_grasp(self, isisobject):
        distance = isisobject.activeModel.getDistance(self.fov)
        print "distance = ", distance
        return distance < 5.0

    def is_holding(self, object_name):
        return (
            self.left_hand_holding_object
            and (self.left_hand_holding_object.getPythonTag("isisobj").name == object_name)
        ) or (
            self.right_hand_holding_object
            and (self.right_hand_holding_object.getPythonTag("isisobj").name == object_name)
        )

    def empty_hand(self):
        if self.left_hand_holding_object is None:
            return self.player_left_hand
        elif self.right_hand_holding_object is None:
            return self.player_right_hand
        return False

    def has_empty_hand(self):
        return self.empty_hand() is not False

    def control__use_aimed(self):
        """
        Try to use the object that we aim at, by calling its callback method.
        """
        target = self.__get_object_in_center_of_view()
        if target.selectionCallback:
            target.selectionCallback(self, dir)
        return "success"

    def sense__get_position(self):
        x, y, z = self.actorNodePath.getPos()
        h, p, r = self.actorNodePath.getHpr()
        # FIXME
        # neck is not positioned in Blockman nh,np,nr = self.agents[agent_id].actor_neck.getHpr()
        left_hand_obj = ""
        right_hand_obj = ""
        if self.left_hand_holding_object:
            left_hand_obj = self.left_hand_holding_object.getName()
        if self.right_hand_holding_object:
            right_hand_obj = self.right_hand_holding_object.getName()
        return {
            "body_x": x,
            "body_y": y,
            "body_z": z,
            "body_h": h,
            "body_p": p,
            "body_r": r,
            "in_left_hand": left_hand_obj,
            "in_right_hand": right_hand_obj,
        }

    def sense__get_vision(self):
        self.fov.node().saveScreenshot("temp.jpg")
        image = Image.open("temp.jpg")
        os.remove("temp.jpg")
        return image

    def sense__get_objects(self):
        return dict([x.getName(), y] for (x, y) in self.get_objects_in_field_of_vision().items())

    def sense__get_agents(self):
        curSense = time()
        agents = {}
        for k, v in self.get_agents_in_field_of_vision().items():
            v["actions"] = k.get_other_agents_actions(self.lastSense, curSense)
            agents[k.name] = v
        self.lastSense = curSense
        return agents

    def sense__get_utterances(self):
        """ Clear out the buffer of things that the teacher has typed,
        FIXME: this doesn't work right now """
        return []
        utterances = self.teacher_utterances
        self.teacher_utterances = []
        return utterances

    def debug__print_objects(self):
        text = "Objects in FOV: " + ", ".join(self.sense__get_objects().keys())
        print text

    def add_action_to_history(self, action, args, result=0):
        self.queue.append((time(), action, args, result))
        if len(self.queue) > self.queueSize:
            self.queue.pop(0)

    def get_other_agents_actions(self, start=0, end=None):
        if not end:
            end = time()
        actions = []
        for act in self.queue:
            if act[0] >= start:
                if act[0] < end:
                    actions.append(act)
                else:
                    break
        return actions

    def update(self, stepSize=0.1):
        self.speed = [0.0, 0.0]
        self.actorNodePath.setPos(self.geom.getPosition() + Vec3(0, 0, -0.70))
        self.actorNodePath.setQuat(self.getQuat())
        # the values in self.speeds are used as coefficientes for turns and movements
        if self.controlMap["turn_left"] != 0:
            self.addToH(stepSize * self.speeds[0])
        if self.controlMap["turn_right"] != 0:
            self.addToH(-stepSize * self.speeds[1])
        if self.verticalState == "ground":
            # these actions require contact with the ground
            if self.controlMap["move_forward"] != 0:
                self.speed[1] = self.speeds[2]
            if self.controlMap["move_backward"] != 0:
                self.speed[1] = -self.speeds[3]
            if self.controlMap["move_left"] != 0:
                self.speed[0] = -self.speeds[4]
            if self.controlMap["move_right"] != 0:
                self.speed[0] = self.speeds[5]
            if self.controlMap["jump"] != 0:
                kinematicCharacterController.jump(self)
                # one jump at a time!
                self.controlMap["jump"] = 0
        if self.controlMap["look_left"] != 0:
            self.neck.setR(bound(self.neck.getR(), -60, 60) + stepSize * 80)
        if self.controlMap["look_right"] != 0:
            self.neck.setR(bound(self.neck.getR(), -60, 60) - stepSize * 80)
        if self.controlMap["look_up"] != 0:
            self.neck.setP(bound(self.neck.getP(), -60, 80) + stepSize * 80)
        if self.controlMap["look_down"] != 0:
            self.neck.setP(bound(self.neck.getP(), -60, 80) - stepSize * 80)

        kinematicCharacterController.update(self, stepSize)

        """
        Update the held object position to be in the hands
        """
        if self.right_hand_holding_object != None:
            self.right_hand_holding_object.setPosition(self.player_right_hand.getPos(render))
        if self.left_hand_holding_object != None:
            self.left_hand_holding_object.setPosition(self.player_left_hand.getPos(render))

        # Update the dialog box and thought windows
        # This allows dialogue window to gradually decay (changing transparancy) and then disappear
        self.last_spoke += stepSize / 2
        self.last_thought += stepSize / 2
        self.speech_bubble["text_bg"] = (1, 1, 1, 1 / (self.last_spoke + 0.01))
        self.speech_bubble["frameColor"] = (0.6, 0.2, 0.1, 0.5 / (self.last_spoke + 0.01))
        if self.last_spoke > 2:
            self.speech_bubble["text"] = ""
        if self.last_thought > 1:
            self.thought_bubble.hide()

        # If the character is moving, loop the run animation.
        # If he is standing still, stop the animation.
        if (
            (self.controlMap["move_forward"] != 0)
            or (self.controlMap["move_backward"] != 0)
            or (self.controlMap["move_left"] != 0)
            or (self.controlMap["move_right"] != 0)
        ):
            if self.isMoving is False:
                self.isMoving = True
        else:
            if self.isMoving:
                self.current_frame_count = 5.0
                self.isMoving = False

        total_frame_num = self.actor.getNumFrames("walk")
        if self.isMoving:
            self.current_frame_count = self.current_frame_count + (stepSize * 250.0)
            if self.current_frame_count > total_frame_num:
                self.current_frame_count = self.current_frame_count % total_frame_num
            self.actor.pose("walk", self.current_frame_count)
        elif self.current_frame_count != 0:
            self.current_frame_count = 0
            self.actor.pose("idle", 0)
        return Task.cont

    def destroy(self):
        self.disable()
        self.specialDirectObject.ignoreAll()
        self.actorNodePath.removeNode()
        del self.specialDirectObject

        kinematicCharacterController.destroy(self)

    def disable(self):
        self.isDisabled = True
        self.geom.disable()
        self.footRay.disable()

    def enable(self):
        self.footRay.enable()
        self.geom.enable()
        self.isDisabled = False

    """
    Set camera to correct height above the center of the capsule
    when crouching and when standing up.
    """

    def crouch(self):
        kinematicCharacterController.crouch(self)
        self.camH = self.crouchCamH

    def crouchStop(self):
        """
        Only change the camera's placement when the KCC allows standing up.
        See the KCC to find out why it might not allow it.
        """
        if kinematicCharacterController.crouchStop(self):
            self.camH = self.walkCamH
예제 #15
0
class Sprite2d:
    class Cell:
        def __init__(self, col, row):
            self.col = col
            self.row = row

        def __str__(self):
            return "Cell - Col %d, Row %d" % (self.col, self.row)

    class Animation:
        def __init__(self, cells, fps):
            self.cells = cells
            self.fps = fps
            self.playhead = 0

    ALIGN_CENTER = "Center"
    ALIGN_LEFT = "Left"
    ALIGN_RIGHT = "Right"
    ALIGN_BOTTOM = "Bottom"
    ALIGN_TOP = "Top"

    TRANS_ALPHA = TransparencyAttrib.MAlpha
    TRANS_DUAL = TransparencyAttrib.MDual
    # One pixel is divided by this much. If you load a 100x50 image with PIXEL_SCALE of 10.0
    # you get a card that is 1 unit wide, 0.5 units high
    PIXEL_SCALE = 20.0

    def __init__(self, image_path, rowPerFace, name=None,\
         rows=1, cols=1, scale=1.0,\
         twoSided=False, alpha=TRANS_ALPHA,\
         repeatX=1, repeatY=1,\
         anchorX=ALIGN_CENTER, anchorY=ALIGN_BOTTOM):
        """
		Create a card textured with an image. The card is sized so that the ratio between the
		card and image is the same.
		"""

        global SpriteId
        self.spriteNum = str(SpriteId)
        SpriteId += 1

        scale *= self.PIXEL_SCALE

        self.animations = {}

        self.scale = scale
        self.repeatX = repeatX
        self.repeatY = repeatY
        self.flip = {'x': False, 'y': False}
        self.rows = rows
        self.cols = cols

        self.currentFrame = 0
        self.currentAnim = None
        self.loopAnim = False
        self.frameInterrupt = True

        # Create the NodePath
        if name:
            self.node = NodePath("Sprite2d:%s" % name)
        else:
            self.node = NodePath("Sprite2d:%s" % image_path)

        # Set the attribute for transparency/twosided
        self.node.node().setAttrib(TransparencyAttrib.make(alpha))
        if twoSided:
            self.node.setTwoSided(True)

        # Make a filepath
        self.imgFile = Filename(image_path)
        if self.imgFile.empty():
            raise IOError, "File not found"

        # Instead of loading it outright, check with the PNMImageHeader if we can open
        # the file.
        imgHead = PNMImageHeader()
        if not imgHead.readHeader(self.imgFile):
            raise IOError, "PNMImageHeader could not read file. Try using absolute filepaths"

        # Load the image with a PNMImage
        image = PNMImage()
        image.read(self.imgFile)

        self.sizeX = image.getXSize()
        self.sizeY = image.getYSize()

        # We need to find the power of two size for the another PNMImage
        # so that the texture thats loaded on the geometry won't have artifacts
        textureSizeX = self.nextsize(self.sizeX)
        textureSizeY = self.nextsize(self.sizeY)

        # The actual size of the texture in memory
        self.realSizeX = textureSizeX
        self.realSizeY = textureSizeY

        self.paddedImg = PNMImage(textureSizeX, textureSizeY)
        if image.hasAlpha():
            self.paddedImg.alphaFill(0)
        # Copy the source image to the image we're actually using
        self.paddedImg.blendSubImage(image, 0, 0)
        # We're done with source image, clear it
        image.clear()

        # The pixel sizes for each cell
        self.colSize = self.sizeX / self.cols
        self.rowSize = self.sizeY / self.rows

        # How much padding the texture has
        self.paddingX = textureSizeX - self.sizeX
        self.paddingY = textureSizeY - self.sizeY

        # Set UV padding
        self.uPad = float(self.paddingX) / textureSizeX
        self.vPad = float(self.paddingY) / textureSizeY

        # The UV dimensions for each cell
        self.uSize = (1.0 - self.uPad) / self.cols
        self.vSize = (1.0 - self.vPad) / self.rows

        self.cards = []
        self.rowPerFace = rowPerFace
        for i in range(len(rowPerFace)):
            card = CardMaker("Sprite2d-Geom")

            # The positions to create the card at
            if anchorX == self.ALIGN_LEFT:
                posLeft = 0
                posRight = (self.colSize / scale) * repeatX
            elif anchorX == self.ALIGN_CENTER:
                posLeft = -(self.colSize / 2.0 / scale) * repeatX
                posRight = (self.colSize / 2.0 / scale) * repeatX
            elif anchorX == self.ALIGN_RIGHT:
                posLeft = -(self.colSize / scale) * repeatX
                posRight = 0

            if anchorY == self.ALIGN_BOTTOM:
                posTop = 0
                posBottom = (self.rowSize / scale) * repeatY
            elif anchorY == self.ALIGN_CENTER:
                posTop = -(self.rowSize / 2.0 / scale) * repeatY
                posBottom = (self.rowSize / 2.0 / scale) * repeatY
            elif anchorY == self.ALIGN_TOP:
                posTop = -(self.rowSize / scale) * repeatY
                posBottom = 0

            card.setFrame(posLeft, posRight, posTop, posBottom)
            card.setHasUvs(True)
            self.cards.append(self.node.attachNewNode(card.generate()))
            self.cards[-1].setH(i * 360 / len(rowPerFace))

        # Since the texture is padded, we need to set up offsets and scales to make
        # the texture fit the whole card
        self.offsetX = (float(self.colSize) / textureSizeX)
        self.offsetY = (float(self.rowSize) / textureSizeY)

        # self.node.setTexScale(TextureStage.getDefault(), self.offsetX * repeatX, self.offsetY * repeatY)
        # self.node.setTexOffset(TextureStage.getDefault(), 0, 1-self.offsetY)

        self.texture = Texture()

        self.texture.setXSize(textureSizeX)
        self.texture.setYSize(textureSizeY)
        self.texture.setZSize(1)

        # Load the padded PNMImage to the texture
        self.texture.load(self.paddedImg)

        self.texture.setMagfilter(Texture.FTNearest)
        self.texture.setMinfilter(Texture.FTNearest)

        #Set up texture clamps according to repeats
        if repeatX > 1:
            self.texture.setWrapU(Texture.WMRepeat)
        else:
            self.texture.setWrapU(Texture.WMClamp)
        if repeatY > 1:
            self.texture.setWrapV(Texture.WMRepeat)
        else:
            self.texture.setWrapV(Texture.WMClamp)

        self.node.setTexture(self.texture)
        self.setFrame(0)

    def nextsize(self, num):
        """ Finds the next power of two size for the given integer. """
        p2x = max(1, log(num, 2))
        notP2X = modf(p2x)[0] > 0
        return 2**int(notP2X + p2x)

    def setFrame(self, frame=0):
        """ Sets the current sprite to the given frame """
        self.frameInterrupt = True  # A flag to tell the animation task to shut it up ur face
        self.currentFrame = frame
        self.flipTexture()

    def playAnim(self, animName, loop=False):
        """ Sets the sprite to animate the given named animation. Booleon to loop animation"""
        if not taskMgr.hasTaskNamed("Animate sprite" + self.spriteNum):
            if hasattr(self, "task"):
                taskMgr.remove("Animate sprite" + self.spriteNum)
                del self.task
            self.frameInterrupt = False  # Clear any previous interrupt flags
            self.loopAnim = loop
            self.currentAnim = self.animations[animName]
            self.currentAnim.playhead = 0
            self.task = taskMgr.doMethodLater(
                1.0 / self.currentAnim.fps, self.animPlayer,
                "Animate sprite" + self.spriteNum)

    def createAnim(self, animName, frameCols, fps=12):
        """ Create a named animation. Takes the animation name and a tuple of frame numbers """
        self.animations[animName] = Sprite2d.Animation(frameCols, fps)
        return self.animations[animName]

    def flipX(self, val=None):
        """ Flip the sprite on X. If no value given, it will invert the current flipping."""
        if val:
            self.flip['x'] = val
        else:
            if self.flip['x']:
                self.flip['x'] = False
            else:
                self.flip['x'] = True
        self.flipTexture()
        return self.flip['x']

    def flipY(self, val=None):
        """ See flipX """
        if val:
            self.flip['y'] = val
        else:
            if self.flip['y']:
                self.flip['y'] = False
            else:
                self.flip['y'] = True
        self.flipTexture()
        return self.flip['y']

    def updateCameraAngle(self, cameraNode):
        baseH = cameraNode.getH(render) - self.node.getH(render)
        degreesBetweenCards = 360 / len(self.cards)
        bestCard = int(
            ((baseH) + degreesBetweenCards / 2) % 360 / degreesBetweenCards)
        #print baseH, bestCard
        for i in range(len(self.cards)):
            if i == bestCard:
                self.cards[i].show()
            else:
                self.cards[i].hide()

    def flipTexture(self):
        """ Sets the texture coordinates of the texture to the current frame"""
        for i in range(len(self.cards)):
            currentRow = self.rowPerFace[i]

            sU = self.offsetX * self.repeatX
            sV = self.offsetY * self.repeatY
            oU = 0 + self.currentFrame * self.uSize
            #oU = 0 + self.frames[self.currentFrame].col * self.uSize
            #oV = 1 - self.frames[self.currentFrame].row * self.vSize - self.offsetY
            oV = 1 - currentRow * self.vSize - self.offsetY
            if self.flip['x'] ^ i == 1:  ##hack to fix side view
                #print "flipping, i = ",i
                sU *= -1
                #oU = self.uSize + self.frames[self.currentFrame].col * self.uSize
                oU = self.uSize + self.currentFrame * self.uSize
            if self.flip['y']:
                sV *= -1
                #oV = 1 - self.frames[self.currentFrame].row * self.vSize
                oV = 1 - currentRow * self.vSize
            self.cards[i].setTexScale(TextureStage.getDefault(), sU, sV)
            self.cards[i].setTexOffset(TextureStage.getDefault(), oU, oV)

    def clear(self):
        """ Free up the texture memory being used """
        self.texture.clear()
        self.paddedImg.clear()
        self.node.removeNode()

    def animPlayer(self, task):
        if self.frameInterrupt:
            return task.done
        #print "Playing",self.currentAnim.cells[self.currentAnim.playhead]
        self.currentFrame = self.currentAnim.cells[self.currentAnim.playhead]
        self.flipTexture()
        if self.currentAnim.playhead + 1 < len(self.currentAnim.cells):
            self.currentAnim.playhead += 1
            return task.again
        if self.loopAnim:
            self.currentAnim.playhead = 0
            return task.again
예제 #16
0
class Game(ShowBase):
    '''
    '''
    def __init__(self):
        '''
        '''
        # loadPrcFileData("", "want-pstats 1\n pstats-host 127.0.0.1\n pstats-tasks 1\n task-timer-verbose 1")
        # loadPrcFileData("", "pstatshost 192.168.220.121")
        ShowBase.__init__(self)

        # PStatClient.connect() #activate to start performance measuring with pstats
        base.setFrameRateMeter(True)  # Show the Framerate
        # base.toggleWireframe()
        self.accept("space", self.onSpace)
        self.accept("tab", self.onTab)
        self.startGame()
        self.cam_on = True
        # -----------------------------------------------------------------

    # -----------------------------------------------------------------

    def onSpace(self, evt=None):
        '''
        '''
        if self.trackmesh2.getParent() == render:
            self.trackmesh.reparentTo(render)
            self.trackmesh2.detachNode()
        else:
            self.trackmesh.detachNode()
            self.trackmesh2.reparentTo(render)
        # base.toggleWireframe()

    # -----------------------------------------------------------------

    def startGame(self):
        '''
        Start the game
        '''
        # Create the Track

        self.track = trackgen3d.Track3d(1000, 800, 600, 200, 5)

        self.trackmesh = NodePath(self.track.createRoadMesh())
        tex = loader.loadTexture('data/textures/street.png')
        self.trackmesh.setTexture(tex)

        self.trackmesh2 = NodePath(self.track.createUninterpolatedRoadMesh())
        self.trackmesh2.setTexture(tex)
        # nodePath.setTwoSided(True)

        self.trackmesh.reparentTo(render)

        # LICHT
        self.plight = PointLight('kkkplight')
        self.plight.setColor(VBase4(21, 0, 0, 1))
        self.plnp = NodePath(self.plight)
        self.plnp.reparentTo(render)
        self.plnp.setPos(0, 0, 2000)
        self.plnp.node().setAttenuation(Point3(0, 0, 1))
        self.plnp.setScale(.5, .5, .5)

        # self.plnp.setHpr(0,-90,0)
        # print plight.getAttenuation()
        # plnp.setPos(-10, -800, 20)
        render.setLight(self.plnp)

        self.accept("w", self.setA, [100])
        self.accept("s", self.setA, [-10])
        self.accept("e", self.setB, [10])
        self.accept("d", self.setB, [-10])
        self.accept("r", self.setC, [100])
        self.accept("f", self.setC, [-100])

        self.accept("z", self.setRotation, [0, 10])
        self.accept("h", self.setRotation, [0, -10])
        self.accept("u", self.setRotation, [1, 10])
        self.accept("j", self.setRotation, [1, -10])
        self.accept("i", self.setRotation, [2, 10])
        self.accept("k", self.setRotation, [2, -10])

        self.accept("n", self.setExponent, [-50])
        self.accept("m", self.setExponent, [50])

        # load our model
        tron = loader.loadModel("data/models/vehicles/vehicle02")
        self.tron = tron
        # self.tron.loadAnims({"running":"models/tron_anim"})
        tron.reparentTo(render)
        tron.setPos(0, 0, 15)
        tron.setHpr(0, -90, 0)
        # nodePath2 = self.render.attachNewNode(self.track.createBorderLeftMesh())
        # tex2 = loader.loadTexture('data/textures/border.png')
        # nodePath2.setTexture(tex2)
        #
        # nodePath3 = self.render.attachNewNode(self.track.createBorderRightMesh())
        # tex2 = loader.loadTexture('data/textures/border.png')
        # nodePath3.setTexture(tex2)
        ring = loader.loadModel("data/models/ring.egg")
        ring.setScale(24)
        ring.setZ(-25)
        ring.setY(100)
        ring.setTransparency(TransparencyAttrib.MAlpha)
        ring.reparentTo(render)

        # Load the Lights
        ambilight = AmbientLight('ambilight')
        ambilight.setColor(VBase4(0.8, 0.8, 0.8, 1))
        render.setLight(render.attachNewNode(ambilight))

    # -----------------------------------------------------------------

    def setA(self, val):
        '''
        '''
        tpos = self.tron.getPos()
        tpos[0] += val
        self.tron.setPos(tpos)
        pos = self.plnp.getPos()
        pos[0] += val
        print(pos)
        self.plnp.setPos(pos)

    def setB(self, val):
        '''
        '''
        tpos = self.tron.getPos()
        tpos[1] += val
        self.tron.setPos(tpos)
        pos = self.plnp.getPos()
        pos[1] += val
        print(pos)
        self.plnp.setPos(pos)

    def setC(self, val):
        '''
        '''
        tpos = self.tron.getPos()
        tpos[2] += val
        self.tron.setPos(tpos)
        pos = self.plnp.getPos()
        pos[2] += val
        print(pos)
        self.plnp.setPos(pos)

    def setRotation(self, var, val):
        '''
        '''
        hpr = self.plnp.getHpr()
        hpr[var] += val
        print(("hpr", hpr))
        self.plnp.setHpr(hpr)

    def setExponent(self, val):
        '''
        '''
        val = self.plight.getExponent() + val
        print(val)
        self.plight.setExponent(val)

    def onTab(self):
        '''
        '''
        if self.cam_on:
            base.disableMouse()
            base.camera.setPos(-293.807, 91.2993, 3984.4)
            base.camera.setHpr(-76.0078, -85.4581, -71.7315)

            # base.camera.setPos(39.3053, -376.205, -3939.89)
            # base.camera.setHpr(5.33686, -82.7432, 8.26239)

            # print base.camera.getPos(), base.camera.getHpr()
            self.cam_on = False
        else:
            base.enableMouse()
            self.cam_on = True
예제 #17
0
class Camera( NodePath, p3d.SingleTask ):
    
    """Class representing a camera."""
    
    class Target( NodePath ):
            
        """Class representing the camera's point of interest."""
            
        def __init__( self, pos=Vec3( 0, 0, 0 ) ):
            NodePath.__init__( self, 'target' )
            
            self.defaultPos = pos
            
    class Axes( NodePath ):
        
        """Class representing the viewport camera axes."""
        
        def __Create( self, thickness, length ):
            
            # Build line segments
            ls = LineSegs()
            ls.setThickness( thickness )
            
            # X Axis - Red
            ls.setColor( 1.0, 0.0, 0.0, 1.0 )
            ls.moveTo( 0.0, 0.0, 0.0 )
            ls.drawTo( length, 0.0, 0.0 )
            
            # Y Axis - Green
            ls.setColor( 0.0, 1.0, 0.0, 1.0 )
            ls.moveTo( 0.0,0.0,0.0 )
            ls.drawTo( 0.0, length, 0.0 )
            
            # Z Axis - Blue
            ls.setColor( 0.0, 0.0, 1.0, 1.0 )
            ls.moveTo( 0.0,0.0,0.0 )
            ls.drawTo( 0.0, 0.0, length )
            
            return ls.create()
        
        def __init__( self, thickness=1, length=25 ):
            ls = self.__Create( thickness, length )
            NodePath.__init__( self, ls )
    
    def __init__( self, name='camera', *args, **kwargs ):
        pos = kwargs.pop( 'pos', (0, 0, 0) )
        targetPos = kwargs.pop( 'targetPos', (0, 0, 0) )
        style = kwargs.pop( 'style', CAM_DEFAULT_STYLE )
        p3d.SingleTask.__init__( self, name, *args, **kwargs )
                      
        self.zoomLevel = 2
        self.defaultPos = pos
        self.style = style
        
        # Use Panda's default camera
        if self.style & CAM_USE_DEFAULT:
            self.cam = getBase().cam
            #self.camNode = getBase().camNode
            
        # Otherwise create a new one
        else:
            
            # Create camera
            self.cam = NodePath( PCamera( name ) )
            
            # Create lens
            lens = PerspectiveLens()
            lens.setAspectRatio( 800.0 / 300.0 )
            self.cam.node().setLens( lens )
            
        # Wrap the camera in this node path class
        NodePath.__init__( self, self.cam )
        
        # Create camera styles
        if self.style & CAM_VIEWPORT_AXES:
            self.axes = self.Axes()
            self.axes.reparentTo( self.rootP2d )
        
        # Create camera target
        self.target = self.Target( pos=targetPos )
        
        self.Reset()
        
    def Reset( self ):
        
        # Reset camera and target back to default positions
        self.target.setPos( self.target.defaultPos )
        self.setPos( self.defaultPos )
        
        # Set camera to look at target
        self.lookAt( self.target.getPos() )
        self.target.setQuat( self.getQuat() )
        
    def Move( self, moveVec ):
            
        # Modify the move vector by the distance to the target, so the further
        # away the camera is the faster it moves
        cameraVec = self.getPos() - self.target.getPos()
        cameraDist = cameraVec.length()
        moveVec *= cameraDist / 300
        
        # Move the camera
        self.setPos( self, moveVec )
        
        # Move the target so it stays with the camera
        self.target.setQuat( self.getQuat() )
        test = Vec3( moveVec.getX(), 0, moveVec.getZ() )
        self.target.setPos( self.target, test )
        
    def Orbit( self, delta ):
        
        # Get new hpr
        newHpr = Vec3()
        newHpr.setX( self.getH() + delta.getX() )
        newHpr.setY( self.getP() + delta.getY() )
        newHpr.setZ( self.getR() )
        
        # Set camera to new hpr
        self.setHpr( newHpr )
            
        # Get the H and P in radians
        radX = newHpr.getX() * ( math.pi / 180.0 )
        radY = newHpr.getY() * ( math.pi / 180.0 )
            
        # Get distance from camera to target
        cameraVec = self.getPos() - self.target.getPos()
        cameraDist = cameraVec.length()
            
        # Get new camera pos
        newPos = Vec3()
        newPos.setX( cameraDist * math.sin( radX ) * math.cos( radY ) )
        newPos.setY( -cameraDist * math.cos( radX ) * math.cos( radY ) )
        newPos.setZ( -cameraDist * math.sin( radY ) )
        newPos += self.target.getPos()
            
        # Set camera to new pos
        self.setPos( newPos )
        
    def Frame( self, nps ):
        
        # Create a bounding volume which includes all node paths
        parent = self.rootNp.attachNewNode( 'parent' )
        dupeNps = []
        for np in nps:
            dupeNp = np.copyTo( parent )
            dupeNp.setTransform( np.getTransform( parent ) )
            dupeNps.append( dupeNp )
        bounds = parent.getBounds()
        parent.removeNode()
        
        # Bail if the bounds are infinite
        if bounds.isInfinite():
            return
        
        # Move the camera and the target the the bounding center
        self.target.setPos( bounds.getCenter() )
        self.setPos( bounds.getCenter() )

        # Now move the camera back so the view accomodates all object(s)
        # Default the bounding radius to something reasonable if the object
        # has no size
        fov = self.GetLens().getFov()
        radius = bounds.getRadius()
        if not radius:
            radius = 0.5
        distance = radius / math.tan( math.radians( min( fov[0], fov[1] ) * 0.5 ) )
        self.setY( self, -distance )
        
    def cameraMovement( self, task ):
        x,y,z = self.cube.getPos()
        #smoothly follow the cube...
        self.setX( self.getX() - ( ( self.getX() - x - 18 * self.zoomLevel ) * 5 * globalClock.getDt() ) )
        self.setY( self.getY() - ( ( self.getY() - y + 5 * self.zoomLevel ) * 5 * globalClock.getDt() ) )
        self.setZ( 15 * self.ZOOMLEVEL )
        self.setHpr( 75, -37, 0 )
        
        return task.cont
    
    def OnUpdate( self, task ):
        
        # Position axes 30 pixels from top left corner
        self.axes.setPos( Vec3( 30, 0, -30 ) )
        
        # Set rotation to inverse of camera rotation
        cameraQuat = Quat( self.getQuat() )
        cameraQuat.invertInPlace()
        self.axes.setQuat( cameraQuat )
        
    def GetLens( self ):
        return self.cam.node().getLens()
예제 #18
0
class IsisAgent(kinematicCharacterController, DirectObject):
    @classmethod
    def setPhysics(cls, physics):
        """ This method is set in src.loader when the generators are loaded
        into the namespace.  This frees the environment definitions (in 
        scenario files) from having to pass around the physics parameter 
        that is required for all IsisObjects """
        cls.physics = physics

    def __init__(self, name, queueSize=100):

        # load the model and the different animations for the model into an Actor object.
        self.actor = Actor("media/models/boxman", {
            "walk": "media/models/boxman-walk",
            "idle": "media/models/boxman-idle"
        })
        self.actor.setScale(1.0)
        self.actor.setH(0)
        #self.actor.setLODAnimation(10,5,2) # slows animation framerate when actor is far from camera, if you can figure out reasonable params
        self.actor.setColorScale(random.random(), random.random(),
                                 random.random(), 1.0)
        self.actorNodePath = NodePath('agent-%s' % name)
        self.activeModel = self.actorNodePath

        self.actorNodePath.reparentTo(render)

        self.actor.reparentTo(self.actorNodePath)
        self.name = name
        self.isMoving = False

        # initialize ODE controller
        kinematicCharacterController.__init__(self, IsisAgent.physics,
                                              self.actorNodePath)
        self.setGeomPos(self.actorNodePath.getPos(render))
        """
        Additional Direct Object that I use for convenience.
        """
        self.specialDirectObject = DirectObject()
        """
        How high above the center of the capsule you want the camera to be
        when walking and when crouching. It's related to the values in KCC.
        """
        self.walkCamH = 0.7
        self.crouchCamH = 0.2
        self.camH = self.walkCamH
        """
        This tells the Player Controller what we're aiming at.
        """
        self.aimed = None

        self.isSitting = False
        self.isDisabled = False
        """
        The special direct object is used for trigger messages and the like.
        """
        #self.specialDirectObject.accept("ladder_trigger_enter", self.setFly, [True])
        #self.specialDirectObject.accept("ladder_trigger_exit", self.setFly, [False])

        self.actor.makeSubpart("arms", ["LeftShoulder", "RightShoulder"])

        # Expose agent's right hand joint to attach objects to
        self.player_right_hand = self.actor.exposeJoint(
            None, 'modelRoot', 'Hand.R')
        self.player_left_hand = self.actor.exposeJoint(None, 'modelRoot',
                                                       'Hand.L')

        self.right_hand_holding_object = None
        self.left_hand_holding_object = None

        # don't change the color of things you pick up
        self.player_right_hand.setColorScaleOff()
        self.player_left_hand.setColorScaleOff()

        self.player_head = self.actor.exposeJoint(None, 'modelRoot', 'Head')
        self.neck = self.actor.controlJoint(None, 'modelRoot', 'Head')

        self.controlMap = {
            "turn_left": 0,
            "turn_right": 0,
            "move_forward": 0,
            "move_backward": 0,
            "move_right": 0,
            "move_left": 0,
            "look_up": 0,
            "look_down": 0,
            "look_left": 0,
            "look_right": 0,
            "jump": 0
        }
        # see update method for uses, indices are [turn left, turn right, move_forward, move_back, move_right, move_left, look_up, look_down, look_right, look_left]
        # turns are in degrees per second, moves are in units per second
        self.speeds = [270, 270, 5, 5, 5, 5, 60, 60, 60, 60]

        self.originalPos = self.actor.getPos()

        bubble = loader.loadTexture("media/textures/thought_bubble.png")
        #bubble.setTransparency(TransparencyAttrib.MAlpha)

        self.speech_bubble = DirectLabel(parent=self.actor,
                                         text="",
                                         text_wordwrap=10,
                                         pad=(3, 3),
                                         relief=None,
                                         text_scale=(.3, .3),
                                         pos=(0, 0, 3.6),
                                         frameColor=(.6, .2, .1, .5),
                                         textMayChange=1,
                                         text_frame=(0, 0, 0, 1),
                                         text_bg=(1, 1, 1, 1))
        #self.myImage=
        self.speech_bubble.setTransparency(TransparencyAttrib.MAlpha)
        # stop the speech bubble from being colored like the agent
        self.speech_bubble.setColorScaleOff()
        self.speech_bubble.component('text0').textNode.setCardDecal(1)
        self.speech_bubble.setBillboardAxis()
        # hide the speech bubble from IsisAgent's own camera
        self.speech_bubble.hide(BitMask32.bit(1))

        self.thought_bubble = DirectLabel(parent=self.actor,
                                          text="",
                                          text_wordwrap=9,
                                          text_frame=(1, 0, -2, 1),
                                          text_pos=(0, .5),
                                          text_bg=(1, 1, 1, 0),
                                          relief=None,
                                          frameSize=(0, 1.5, -2, 3),
                                          text_scale=(.18, .18),
                                          pos=(0, 0.2, 3.6),
                                          textMayChange=1,
                                          image=bubble,
                                          image_pos=(0, 0.1, 0),
                                          sortOrder=5)
        self.thought_bubble.setTransparency(TransparencyAttrib.MAlpha)
        # stop the speech bubble from being colored like the agent
        self.thought_bubble.setColorScaleOff()
        self.thought_bubble.component('text0').textNode.setFrameColor(
            1, 1, 1, 0)
        self.thought_bubble.component('text0').textNode.setFrameAsMargin(
            0.1, 0.1, 0.1, 0.1)
        self.thought_bubble.component('text0').textNode.setCardDecal(1)
        self.thought_bubble.setBillboardAxis()
        # hide the thought bubble from IsisAgent's own camera
        self.thought_bubble.hide(BitMask32.bit(1))
        # disable by default
        self.thought_bubble.hide()
        self.thought_filter = {}  # only show thoughts whose values are in here
        self.last_spoke = 0  # timers to keep track of last thought/speech and
        self.last_thought = 0  # hide visualizations

        # put a camera on ralph
        self.fov = NodePath(Camera('RaphViz'))
        self.fov.node().setCameraMask(BitMask32.bit(1))

        # position the camera to be infront of Boxman's face.
        self.fov.reparentTo(self.player_head)
        # x,y,z are not in standard orientation when parented to player-Head
        self.fov.setPos(0, 0.2, 0)
        # if P=0, canrea is looking directly up. 90 is back of head. -90 is on face.
        self.fov.setHpr(0, -90, 0)

        lens = self.fov.node().getLens()
        lens.setFov(60)  #  degree field of view (expanded from 40)
        lens.setNear(0.2)
        #self.fov.node().showFrustum() # displays a box around his head
        #self.fov.place()

        self.prevtime = 0
        self.current_frame_count = 0

        self.isSitting = False
        self.isDisabled = False
        self.msg = None
        self.actorNodePath.setPythonTag("agent", self)

        # Initialize the action queue, with a maximum length of queueSize
        self.queue = []
        self.queueSize = queueSize
        self.lastSense = 0

    def setLayout(self, layout):
        """ Dummy method called by spatial methods for use with objects. 
        Doesn't make sense for an agent that can move around."""
        pass

    def setPos(self, pos):
        """ Wrapper to set the position of the ODE geometry, which in turn 
        sets the visual model's geometry the next time the update() method
        is called. """
        self.setGeomPos(pos)

    def setPosition(self, pos):
        self.setPos(pos)

    def reparentTo(self, parent):
        self.actorNodePath.reparentTo(parent)

    def setControl(self, control, value):
        """Set the state of one of the character's movement controls.  """
        self.controlMap[control] = value

    def get_objects_in_field_of_vision(self, exclude=['isisobject']):
        """ This works in an x-ray style. Fast. Works best if you listen to
        http://en.wikipedia.org/wiki/Rock_Art_and_the_X-Ray_Style while
        you use it.
        
        needs to exclude isisobjects since they cannot be serialized  
        """
        objects = {}
        for obj in base.render.findAllMatches("**/IsisObject*"):
            if not obj.hasPythonTag("isisobj"):
                continue
            o = obj.getPythonTag("isisobj")
            bounds = o.activeModel.getBounds()
            bounds.xform(o.activeModel.getMat(self.fov))
            if self.fov.node().isInView(o.activeModel.getPos(self.fov)):
                pos = o.activeModel.getPos(render)
                pos = (pos[0], pos[1], pos[2] + o.getHeight() / 2)
                p1 = self.fov.getRelativePoint(render, pos)
                p2 = Point2()
                self.fov.node().getLens().project(p1, p2)
                p3 = aspect2d.getRelativePoint(render2d,
                                               Point3(p2[0], 0, p2[1]))
                object_dict = {}
                if 'x_pos' not in exclude: object_dict['x_pos'] = p3[0]
                if 'y_pos' not in exclude: object_dict['y_pos'] = p3[2]
                if 'distance' not in exclude:
                    object_dict['distance'] = o.activeModel.getDistance(
                        self.fov)
                if 'orientation' not in exclude:
                    object_dict['orientation'] = o.activeModel.getH(self.fov)
                if 'actions' not in exclude:
                    object_dict['actions'] = o.list_actions()
                if 'isisobject' not in exclude: object_dict['isisobject'] = o
                # add item to dinctionary
                objects[o] = object_dict
        return objects

    def get_agents_in_field_of_vision(self):
        """ This works in an x-ray vision style as well"""
        agents = {}
        for agent in base.render.findAllMatches("**/agent-*"):
            if not agent.hasPythonTag("agent"):
                continue
            a = agent.getPythonTag("agent")
            bounds = a.actorNodePath.getBounds()
            bounds.xform(a.actorNodePath.getMat(self.fov))
            pos = a.actorNodePath.getPos(self.fov)
            if self.fov.node().isInView(pos):
                p1 = self.fov.getRelativePoint(render, pos)
                p2 = Point2()
                self.fov.node().getLens().project(p1, p2)
                p3 = aspect2d.getRelativePoint(render2d,
                                               Point3(p2[0], 0, p2[1]))
                agentDict = {'x_pos': p3[0],\
                             'y_pos': p3[2],\
                             'distance':a.actorNodePath.getDistance(self.fov),\
                             'orientation': a.actorNodePath.getH(self.fov)}
                agents[a] = agentDict
        return agents

    def in_view(self, isisobj):
        """ Returns true iff a particular isisobject is in view """
        return len(
            filter(lambda x: x['isisobject'] == isisobj,
                   self.get_objects_in_field_of_vision(exclude=[]).values()))

    def get_objects_in_view(self):
        """ Gets objects through ray tracing.  Slow"""
        return self.picker.get_objects_in_view()

    def control__turn_left__start(self, speed=None):
        self.setControl("turn_left", 1)
        self.setControl("turn_right", 0)
        if speed:
            self.speeds[0] = speed
        return "success"

    def control__turn_left__stop(self):
        self.setControl("turn_left", 0)
        return "success"

    def control__turn_right__start(self, speed=None):
        self.setControl("turn_left", 0)
        self.setControl("turn_right", 1)
        if speed:
            self.speeds[1] = speed
        return "success"

    def control__turn_right__stop(self):
        self.setControl("turn_right", 0)
        return "success"

    def control__move_forward__start(self, speed=None):
        self.setControl("move_forward", 1)
        self.setControl("move_backward", 0)
        if speed:
            self.speeds[2] = speed
        return "success"

    def control__move_forward__stop(self):
        self.setControl("move_forward", 0)
        return "success"

    def control__move_backward__start(self, speed=None):
        self.setControl("move_forward", 0)
        self.setControl("move_backward", 1)
        if speed:
            self.speeds[3] = speed
        return "success"

    def control__move_backward__stop(self):
        self.setControl("move_backward", 0)
        return "success"

    def control__move_left__start(self, speed=None):
        self.setControl("move_left", 1)
        self.setControl("move_right", 0)
        if speed:
            self.speeds[4] = speed
        return "success"

    def control__move_left__stop(self):
        self.setControl("move_left", 0)
        return "success"

    def control__move_right__start(self, speed=None):
        self.setControl("move_right", 1)
        self.setControl("move_left", 0)
        if speed:
            self.speeds[5] = speed
        return "success"

    def control__move_right__stop(self):
        self.setControl("move_right", 0)
        return "success"

    def control__look_left__start(self, speed=None):
        self.setControl("look_left", 1)
        self.setControl("look_right", 0)
        if speed:
            self.speeds[9] = speed
        return "success"

    def control__look_left__stop(self):
        self.setControl("look_left", 0)
        return "success"

    def control__look_right__start(self, speed=None):
        self.setControl("look_right", 1)
        self.setControl("look_left", 0)
        if speed:
            self.speeds[8] = speed
        return "success"

    def control__look_right__stop(self):
        self.setControl("look_right", 0)
        return "success"

    def control__look_up__start(self, speed=None):
        self.setControl("look_up", 1)
        self.setControl("look_down", 0)
        if speed:
            self.speeds[6] = speed
        return "success"

    def control__look_up__stop(self):
        self.setControl("look_up", 0)
        return "success"

    def control__look_down__start(self, speed=None):
        self.setControl("look_down", 1)
        self.setControl("look_up", 0)
        if speed:
            self.speeds[7] = speed
        return "success"

    def control__look_down__stop(self):
        self.setControl("look_down", 0)
        return "success"

    def control__jump(self):
        self.setControl("jump", 1)
        return "success"

    def control__view_objects(self):
        """ calls a raytrace to to all objects in view """
        objects = self.get_objects_in_field_of_vision()
        self.control__say(
            "If I were wearing x-ray glasses, I could see %i items" %
            len(objects))
        print "Objects in view:", objects
        return objects

    def control__sense(self):
        """ perceives the world, returns percepts dict """
        percepts = dict()
        # eyes: visual matricies
        #percepts['vision'] = self.sense__get_vision()
        # objects in purview (cheating object recognition)
        percepts['objects'] = self.sense__get_objects()
        # global position in environment - our robots can have GPS :)
        percepts['position'] = self.sense__get_position()
        # language: get last utterances that were typed
        percepts['language'] = self.sense__get_utterances()
        # agents: returns a map of agents to a list of actions that have been sensed
        percepts['agents'] = self.sense__get_agents()
        print percepts
        return percepts

    def control__think(self, message, layer=0):
        """ Changes the contents of an agent's thought bubble"""
        # only say things that are checked in the controller
        if self.thought_filter.has_key(layer):
            self.thought_bubble.show()
            self.thought_bubble['text'] = message
            #self.thought_bubble.component('text0').textNode.setShadow(0.05, 0.05)
            #self.thought_bubble.component('text0').textNode.setShadowColor(self.thought_filter[layer])
            self.last_thought = 0
        return "success"

    def control__say(self, message="Hello!"):
        self.speech_bubble['text'] = message
        self.last_spoke = 0
        return "success"

    """

    Methods explicitly for IsisScenario files 

    """

    def put_in_front_of(self, isisobj):
        # find open direction
        pos = isisobj.getGeomPos()
        direction = render.getRelativeVector(isisobj, Vec3(0, 1.0, 0))
        closestEntry, closestObject = IsisAgent.physics.doRaycastNew(
            'aimRay', 5, [pos, direction], [isisobj.geom])
        print "CLOSEST", closestEntry, closestObject
        if closestObject == None:
            self.setPosition(pos + Vec3(0, 2, 0))
        else:
            print "CANNOT PLACE IN FRONT OF %s BECAUSE %s IS THERE" % (
                isisobj, closestObject)
            direction = render.getRelativeVector(isisobj, Vec3(0, -1.0, 0))
            closestEntry, closestObject = IsisAgent.physics.doRaycastNew(
                'aimRay', 5, [pos, direction], [isisobj.geom])
            if closestEntry == None:
                self.setPosition(pos + Vec3(0, -2, 0))
            else:
                print "CANNOT PLACE BEHIND %s BECAUSE %s IS THERE" % (
                    isisobj, closestObject)
                direction = render.getRelativeVector(isisobj, Vec3(1, 0, 0))
                closestEntry, closestObject = IsisAgent.physics.doRaycastNew(
                    'aimRay', 5, [pos, direction], [isisobj.geom])
                if closestEntry == None:
                    self.setPosition(pos + Vec3(2, 0, 0))
                else:
                    print "CANNOT PLACE TO LEFT OF %s BECAUSE %s IS THERE" % (
                        isisobj, closestObject)
                    # there's only one option left, do it anyway
                    self.setPosition(pos + Vec3(-2, 0, 0))
        # rotate agent to look at it
        self.actorNodePath.setPos(self.getGeomPos())
        self.actorNodePath.lookAt(pos)
        self.setH(self.actorNodePath.getH())

    def put_in_right_hand(self, target):
        return self.pick_object_up_with(target, self.right_hand_holding_object,
                                        self.player_right_hand)

    def put_in_left_hand(self, target):
        return self.pick_object_up_with(target, self.left_hand_holding_object,
                                        self.player_left_hand)

    def __get_object_in_center_of_view(self):
        direction = render.getRelativeVector(self.fov, Vec3(0, 1.0, 0))
        pos = self.fov.getPos(render)
        exclude = [
        ]  #[base.render.find("**/kitchenNode*").getPythonTag("isisobj").geom]
        closestEntry, closestObject = IsisAgent.physics.doRaycastNew(
            'aimRay', 5, [pos, direction], exclude)
        return closestObject

    def pick_object_up_with(self, target, hand_slot, hand_joint):
        """ Attaches an IsisObject, target, to the hand joint.  Does not check anything first,
        other than the fact that the hand joint is not currently holding something else."""
        if hand_slot != None:
            print 'already holding ' + hand_slot.getName() + '.'
            return None
        else:
            if target.layout:
                target.layout.remove(target)
                target.layout = None
            # store original position
            target.originalHpr = target.getHpr(render)
            target.disable()  #turn off physics
            if target.body: target.body.setGravityMode(0)
            target.reparentTo(hand_joint)
            target.setPosition(hand_joint.getPos(render))
            target.setTag('heldBy', self.name)
            if hand_joint == self.player_right_hand:
                self.right_hand_holding_object = target
            elif hand_joint == self.player_left_hand:
                self.left_hand_holding_object = target
            hand_slot = target
            return target

    def control__pick_up_with_right_hand(self, target=None):
        if not target:
            target = self.__get_object_in_center_of_view()
            if not target:
                print "no target in reach"
                return "error: no target in reach"
        else:
            target = render.find("**/*" + target + "*").getPythonTag("isisobj")
        print "attempting to pick up " + target.name + " with right hand.\n"
        if self.can_grasp(target):  # object within distance
            return self.pick_object_up_with(target,
                                            self.right_hand_holding_object,
                                            self.player_right_hand)
        else:
            print 'object (' + target.name + ') is not graspable (i.e. in view and close enough).'
            return 'error: object not graspable'

    def control__pick_up_with_left_hand(self, target=None):
        if not target:
            target = self.__get_object_in_center_of_view()
            if not target:
                print "no target in reach"
                return
        else:
            target = render.find("**/*" + target + "*").getPythonTag("isisobj")
        print "attempting to pick up " + target.name + " with left hand.\n"
        if self.can_grasp(target):  # object within distance
            return self.pick_object_up_with(target,
                                            self.left_hand_holding_object,
                                            self.player_left_hand)
        else:
            print 'object (' + target.name + ') is not graspable (i.e. in view and close enough).'
            return 'error: object not graspable'

    def control__drop_from_right_hand(self):
        print "attempting to drop object from right hand.\n"

        if self.right_hand_holding_object is None:
            print 'right hand is not holding an object.'
            return False
        if self.right_hand_holding_object.getNetTag('heldBy') == self.name:
            self.right_hand_holding_object.reparentTo(render)
            direction = render.getRelativeVector(self.fov, Vec3(0, 1.0, 0))
            pos = self.player_right_hand.getPos(render)
            heldPos = self.right_hand_holding_object.geom.getPosition()
            self.right_hand_holding_object.setPosition(pos)
            self.right_hand_holding_object.synchPosQuatToNode()
            self.right_hand_holding_object.setTag('heldBy', '')
            self.right_hand_holding_object.setRotation(
                self.right_hand_holding_object.originalHpr)
            self.right_hand_holding_object.enable()
            if self.right_hand_holding_object.body:
                quat = self.getQuat()
                # throw object
                force = 5
                self.right_hand_holding_object.body.setGravityMode(1)
                self.right_hand_holding_object.getBody().setForce(
                    quat.xform(Vec3(0, force, 0)))
            self.right_hand_holding_object = None
            return 'success'
        else:
            return "Error: not being held by agent %s" % (self.name)

    def control__drop_from_left_hand(self):
        print "attempting to drop object from left hand.\n"
        if self.left_hand_holding_object is None:
            return 'left hand is not holding an object.'
        if self.left_hand_holding_object.getNetTag('heldBy') == self.name:
            self.left_hand_holding_object.reparentTo(render)
            direction = render.getRelativeVector(self.fov, Vec3(0, 1.0, 0))
            pos = self.player_left_hand.getPos(render)
            heldPos = self.left_hand_holding_object.geom.getPosition()
            self.left_hand_holding_object.setPosition(pos)
            self.left_hand_holding_object.synchPosQuatToNode()
            self.left_hand_holding_object.setTag('heldBy', '')
            self.left_hand_holding_object.setRotation(
                self.left_hand_holding_object.originalHpr)
            self.left_hand_holding_object.enable()
            if self.left_hand_holding_object.body:
                quat = self.getQuat()
                # throw object
                force = 5
                self.left_hand_holding_object.body.setGravityMode(1)
                self.left_hand_holding_object.getBody().setForce(
                    quat.xform(Vec3(0, force, 0)))
            self.left_hand_holding_object = None
            return 'success'
        else:
            return "Error: not being held by agent %s" % (self.name)

    def control__use_right_hand(self, target=None, action=None):
        # TODO, rename this to use object with
        if not action:
            if self.msg:
                action = self.msg
            else:
                action = "divide"
        if not target:
            target = self.__get_object_in_center_of_view()
            if not target:
                print "no target in reach"
                return
        else:
            target = render.find("**/*" + target + "*").getPythonTag('isisobj')
        print "Trying to use object", target
        if self.can_grasp(target):
            if (target.call(self, action, self.right_hand_holding_object) or
                (self.right_hand_holding_object and
                 self.right_hand_holding_object.call(self, action, target))):
                return "success"
            return str(action) + " not associated with either target or object"
        return "target not within reach"

    def control__use_left_hand(self, target=None, action=None):
        if not action:
            if self.msg:
                action = self.msg
            else:
                action = "divide"
        if not target:
            target = self.__get_object_in_center_of_view()
            if not target:
                print "no target in reach"
                return
        else:
            target = render.find("**/*" + target + "*").getPythonTag('isisobj')
        if self.can_grasp(target):
            if (target.call(self, action, self.left_hand_holding_object) or
                (self.left_hand_holding_object and
                 self.left_hand_holding_object.call(self, action, target))):
                return "success"
            return str(action) + " not associated with either target or object"
        return "target not within reach"

    def can_grasp(self, isisobject):
        distance = isisobject.activeModel.getDistance(self.fov)
        print "distance = ", distance
        return distance < 5.0

    def is_holding(self, object_name):
        return ((self.left_hand_holding_object and (self.left_hand_holding_object.getPythonTag('isisobj').name  == object_name)) \
             or (self.right_hand_holding_object and (self.right_hand_holding_object.getPythonTag('isisobj').name == object_name)))

    def empty_hand(self):
        if (self.left_hand_holding_object is None):
            return self.player_left_hand
        elif (self.right_hand_holding_object is None):
            return self.player_right_hand
        return False

    def has_empty_hand(self):
        return (self.empty_hand() is not False)

    def control__use_aimed(self):
        """
        Try to use the object that we aim at, by calling its callback method.
        """
        target = self.__get_object_in_center_of_view()
        if target.selectionCallback:
            target.selectionCallback(self, dir)
        return "success"

    def sense__get_position(self):
        x, y, z = self.actorNodePath.getPos()
        h, p, r = self.actorNodePath.getHpr()
        #FIXME
        # neck is not positioned in Blockman nh,np,nr = self.agents[agent_id].actor_neck.getHpr()
        left_hand_obj = ""
        right_hand_obj = ""
        if self.left_hand_holding_object:
            left_hand_obj = self.left_hand_holding_object.getName()
        if self.right_hand_holding_object:
            right_hand_obj = self.right_hand_holding_object.getName()
        return {'body_x': x, 'body_y': y, 'body_z': z,'body_h':h,\
                'body_p': p, 'body_r': r,  'in_left_hand': left_hand_obj, 'in_right_hand':right_hand_obj}

    def sense__get_vision(self):
        self.fov.node().saveScreenshot("temp.jpg")
        image = Image.open("temp.jpg")
        os.remove("temp.jpg")
        return image

    def sense__get_objects(self):
        return dict([x.getName(), y]
                    for (x,
                         y) in self.get_objects_in_field_of_vision().items())

    def sense__get_agents(self):
        curSense = time()
        agents = {}
        for k, v in self.get_agents_in_field_of_vision().items():
            v['actions'] = k.get_other_agents_actions(self.lastSense, curSense)
            agents[k.name] = v
        self.lastSense = curSense
        return agents

    def sense__get_utterances(self):
        """ Clear out the buffer of things that the teacher has typed,
        FIXME: this doesn't work right now """
        return []
        utterances = self.teacher_utterances
        self.teacher_utterances = []
        return utterances

    def debug__print_objects(self):
        text = "Objects in FOV: " + ", ".join(self.sense__get_objects().keys())
        print text

    def add_action_to_history(self, action, args, result=0):
        self.queue.append((time(), action, args, result))
        if len(self.queue) > self.queueSize:
            self.queue.pop(0)

    def get_other_agents_actions(self, start=0, end=None):
        if not end:
            end = time()
        actions = []
        for act in self.queue:
            if act[0] >= start:
                if act[0] < end:
                    actions.append(act)
                else:
                    break
        return actions

    def update(self, stepSize=0.1):
        self.speed = [0.0, 0.0]
        self.actorNodePath.setPos(self.geom.getPosition() + Vec3(0, 0, -0.70))
        self.actorNodePath.setQuat(self.getQuat())
        # the values in self.speeds are used as coefficientes for turns and movements
        if (self.controlMap["turn_left"] != 0):
            self.addToH(stepSize * self.speeds[0])
        if (self.controlMap["turn_right"] != 0):
            self.addToH(-stepSize * self.speeds[1])
        if self.verticalState == 'ground':
            # these actions require contact with the ground
            if (self.controlMap["move_forward"] != 0):
                self.speed[1] = self.speeds[2]
            if (self.controlMap["move_backward"] != 0):
                self.speed[1] = -self.speeds[3]
            if (self.controlMap["move_left"] != 0):
                self.speed[0] = -self.speeds[4]
            if (self.controlMap["move_right"] != 0):
                self.speed[0] = self.speeds[5]
            if (self.controlMap["jump"] != 0):
                kinematicCharacterController.jump(self)
                # one jump at a time!
                self.controlMap["jump"] = 0
        if (self.controlMap["look_left"] != 0):
            self.neck.setR(bound(self.neck.getR(), -60, 60) + stepSize * 80)
        if (self.controlMap["look_right"] != 0):
            self.neck.setR(bound(self.neck.getR(), -60, 60) - stepSize * 80)
        if (self.controlMap["look_up"] != 0):
            self.neck.setP(bound(self.neck.getP(), -60, 80) + stepSize * 80)
        if (self.controlMap["look_down"] != 0):
            self.neck.setP(bound(self.neck.getP(), -60, 80) - stepSize * 80)

        kinematicCharacterController.update(self, stepSize)
        """
        Update the held object position to be in the hands
        """
        if self.right_hand_holding_object != None:
            self.right_hand_holding_object.setPosition(
                self.player_right_hand.getPos(render))
        if self.left_hand_holding_object != None:
            self.left_hand_holding_object.setPosition(
                self.player_left_hand.getPos(render))

        #Update the dialog box and thought windows
        #This allows dialogue window to gradually decay (changing transparancy) and then disappear
        self.last_spoke += stepSize / 2
        self.last_thought += stepSize / 2
        self.speech_bubble['text_bg'] = (1, 1, 1, 1 / (self.last_spoke + 0.01))
        self.speech_bubble['frameColor'] = (.6, .2, .1,
                                            .5 / (self.last_spoke + 0.01))
        if self.last_spoke > 2:
            self.speech_bubble['text'] = ""
        if self.last_thought > 1:
            self.thought_bubble.hide()

        # If the character is moving, loop the run animation.
        # If he is standing still, stop the animation.
        if (self.controlMap["move_forward"] !=
                0) or (self.controlMap["move_backward"] !=
                       0) or (self.controlMap["move_left"] !=
                              0) or (self.controlMap["move_right"] != 0):
            if self.isMoving is False:
                self.isMoving = True
        else:
            if self.isMoving:
                self.current_frame_count = 5.0
                self.isMoving = False

        total_frame_num = self.actor.getNumFrames('walk')
        if self.isMoving:
            self.current_frame_count = self.current_frame_count + (stepSize *
                                                                   250.0)
            if self.current_frame_count > total_frame_num:
                self.current_frame_count = self.current_frame_count % total_frame_num
            self.actor.pose('walk', self.current_frame_count)
        elif self.current_frame_count != 0:
            self.current_frame_count = 0
            self.actor.pose('idle', 0)
        return Task.cont

    def destroy(self):
        self.disable()
        self.specialDirectObject.ignoreAll()
        self.actorNodePath.removeNode()
        del self.specialDirectObject

        kinematicCharacterController.destroy(self)

    def disable(self):
        self.isDisabled = True
        self.geom.disable()
        self.footRay.disable()

    def enable(self):
        self.footRay.enable()
        self.geom.enable()
        self.isDisabled = False

    """
    Set camera to correct height above the center of the capsule
    when crouching and when standing up.
    """

    def crouch(self):
        kinematicCharacterController.crouch(self)
        self.camH = self.crouchCamH

    def crouchStop(self):
        """
        Only change the camera's placement when the KCC allows standing up.
        See the KCC to find out why it might not allow it.
        """
        if kinematicCharacterController.crouchStop(self):
            self.camH = self.walkCamH