コード例 #1
0
    def replaceCollisionPolysWithPlanes(self, model):
        newCollisionNode = PM.CollisionNode('collisions')
        newCollideMask = PM.BitMask32(0)
        planes = []
        collList = model.findAllMatches('**/+CollisionNode')
        if not collList:
            collList = [model]
        for cnp in collList:
            cn = cnp.node()
            if not isinstance(cn, PM.CollisionNode):
                self.notify.warning('Not a collision node: %s' % repr(cnp))
                break
            newCollideMask = newCollideMask | cn.getIntoCollideMask()
            for i in range(cn.getNumSolids()):
                solid = cn.getSolid(i)
                if isinstance(solid, PM.CollisionPolygon):
                    plane = PM.Plane(solid.getPlane())
                    planes.append(plane)
                else:
                    self.notify.warning('Unexpected collision solid: %s' %
                                        repr(solid))
                    newCollisionNode.addSolid(plane)

        newCollisionNode.setIntoCollideMask(newCollideMask)
        threshold = 0.1
        planes.sort(lambda p1, p2: p1.compareTo(p2, threshold))
        lastPlane = None
        for plane in planes:
            if lastPlane == None or plane.compareTo(lastPlane, threshold) != 0:
                cp = PM.CollisionPlane(plane)
                newCollisionNode.addSolid(cp)
                lastPlane = plane

        return PM.NodePath(newCollisionNode)
コード例 #2
0
def RebuildGeomNodesToColPolys(incomingNodes):
    """
    Converts GeomNodes into CollisionPolys in a straight 1-to-1 conversion 

    Returns a new NodePath containing the CollisionNodes 
    """
    parent = pm.NodePath('cGeomConversionParent')
    for c in incomingNodes:
        gni = 0
        geomNode = c.node()
        for g in range(geomNode.getNumGeoms()):
            geom = geomNode.getGeom(g).decompose()
            vdata = geom.getVertexData()
            vreader = pm.GeomVertexReader(vdata, 'vertex')
            cChild = pm.CollisionNode('cGeom-%s-gni%i' % (c.getName(), gni))
            gni += 1
            for p in range(geom.getNumPrimitives()):
                prim = geom.getPrimitive(p)
                for p2 in range(prim.getNumPrimitives()):
                    s = prim.getPrimitiveStart(p2)
                    e = prim.getPrimitiveEnd(p2)
                    v = []
                    for vi in range(s, e):
                        vreader.setRow(prim.getVertex(vi))
                        v.append(vreader.getData3f())
                    colPoly = pm.CollisionPolygon(*v)
                    cChild.addSolid(colPoly)

            parent.attachNewNode(cChild)

    return parent
コード例 #3
0
 def privGotSpec(self, levelSpec):
     DistCogdoLevelGame.privGotSpec(self, levelSpec)
     levelMgr = self.getEntity(LevelConstants.LevelMgrEntId)
     self.endVault = levelMgr.geom
     self.endVault.reparentTo(self.geomRoot)
     self.endVault.findAllMatches('**/MagnetArms').detach()
     self.endVault.findAllMatches('**/Safes').detach()
     self.endVault.findAllMatches('**/MagnetControlsAll').detach()
     cn = self.endVault.find('**/wallsCollision').node()
     cn.setIntoCollideMask(OTPGlobals.WallBitmask
                           | ToontownGlobals.PieBitmask
                           | PM.BitMask32.lowerOn(3) << 21)
     walls = self.endVault.find('**/RollUpFrameCillison')
     walls.detachNode()
     self.evWalls = self.replaceCollisionPolysWithPlanes(walls)
     self.evWalls.reparentTo(self.endVault)
     self.evWalls.stash()
     floor = self.endVault.find('**/EndVaultFloorCollision')
     floor.detachNode()
     self.evFloor = self.replaceCollisionPolysWithPlanes(floor)
     self.evFloor.reparentTo(self.endVault)
     self.evFloor.setName('floor')
     plane = PM.CollisionPlane(
         PM.Plane(PM.Vec3(0, 0, 1), PM.Point3(0, 0, -50)))
     planeNode = PM.CollisionNode('dropPlane')
     planeNode.addSolid(plane)
     planeNode.setCollideMask(ToontownGlobals.PieBitmask)
     self.geomRoot.attachNewNode(planeNode)
コード例 #4
0
    def privGotSpec(self, levelSpec):
        DistCogdoLevelGame.privGotSpec(self, levelSpec)

        levelMgr = self.getEntity(LevelConstants.LevelMgrEntId)
        self.endVault = levelMgr.geom
        self.endVault.reparentTo(self.geomRoot)

        # Clear out unneeded backstage models from the EndVault, if
        # they're in the file.
        self.endVault.findAllMatches('**/MagnetArms').detach()
        self.endVault.findAllMatches('**/Safes').detach()
        self.endVault.findAllMatches('**/MagnetControlsAll').detach()

        # Flag the collisions in the end vault so safes and magnets
        # don't try to go through the wall.
        cn = self.endVault.find('**/wallsCollision').node()
        cn.setIntoCollideMask(OTPGlobals.WallBitmask
                              | ToontownGlobals.PieBitmask
                              | (PM.BitMask32.lowerOn(3) << 21))

        # Find all the wall polygons and replace them with planes,
        # which are solid, so there will be zero chance of safes or
        # toons slipping through a wall.
        walls = self.endVault.find('**/RollUpFrameCillison')
        walls.detachNode()
        self.evWalls = self.replaceCollisionPolysWithPlanes(walls)
        self.evWalls.reparentTo(self.endVault)

        # Initially, these new planar walls are stashed, so they don't
        # cause us trouble in the intro movie or in battle one.  We
        # will unstash them when we move to battle three.
        self.evWalls.stash()

        # Also replace the floor polygon with a plane, and rename it
        # so we can detect a collision with it.
        floor = self.endVault.find('**/EndVaultFloorCollision')
        floor.detachNode()
        self.evFloor = self.replaceCollisionPolysWithPlanes(floor)
        self.evFloor.reparentTo(self.endVault)
        self.evFloor.setName('floor')

        # Also, put a big plane across the universe a few feet below
        # the floor, to catch things that fall out of the world.
        plane = PM.CollisionPlane(
            PM.Plane(PM.Vec3(0, 0, 1), PM.Point3(0, 0, -50)))
        planeNode = PM.CollisionNode('dropPlane')
        planeNode.addSolid(plane)
        planeNode.setCollideMask(ToontownGlobals.PieBitmask)
        self.geomRoot.attachNewNode(planeNode)
コード例 #5
0
def fromCol(parent, handler, type, mask=P.BitMask32.allOn()):
    """Setup a from collision solid.

    Last I checked CollisionPolygon 's and CollisionTube 's can't be used
    as from solids. If you pass one, it won't hit anything"""
    nodepath = parent.attachNewNode(P.CollisionNode('frmcol'))
    nodepath.node().addSolid(type)  #add the solid to the new collisionNode
    nodepath.node().setFromCollideMask(mask)  #allow selective masking
    nodepath.setCollideMask(P.BitMask32.allOff())  #it's a from solid only.
    ####uncomment this line to make the collision solid visible:
    ##nodepath.show()
    base.cTrav.addCollider(nodepath, handler)  #add to the traverser
    try:  #the next line doesn't work on queues. (not necessary)
        handler.addCollider(nodepath, parent)  #keep the ward out of trouble
    except:
        pass  #Don't care. This method needs to work on queues too.
    return nodepath  #we might need the new CollisionNode again later.
コード例 #6
0
    def enterLoaded(self):
        DistCogdoLevelGameAI.enterLoaded(self)
        self.scene = PM.NodePath('scene')
        cn = PM.CollisionNode('walls')
        cs = PM.CollisionSphere(0, 0, 0, 13)
        cn.addSolid(cs)
        cs = PM.CollisionInvSphere(0, 0, 0, 42)
        cn.addSolid(cs)
        self.attachNewNode(cn)
        for i in xrange(CogdoGameConsts.MaxPlayers):
            crane = DistCogdoCraneAI(self.air, self, i)
            crane.generateWithRequired(self.zoneId)
            self._cranes[i] = crane

        for i in xrange(len(self._moneyBags)):
            mBag = DistCogdoCraneMoneyBagAI(self.air, self, i)
            mBag.generateWithRequired(self.zoneId)
            self._moneyBags[i] = mBag
コード例 #7
0
    def replaceCollisionPolysWithPlanes(self, model):
        newCollisionNode = PM.CollisionNode('collisions')
        newCollideMask = PM.BitMask32(0)
        planes = []

        collList = model.findAllMatches('**/+CollisionNode')
        if not collList:
            collList = [model]

        for cnp in collList:
            cn = cnp.node()
            if not isinstance(cn, PM.CollisionNode):
                self.notify.warning("Not a collision node: %s" % (repr(cnp)))
                break

            newCollideMask = newCollideMask | cn.getIntoCollideMask()
            for i in range(cn.getNumSolids()):
                solid = cn.getSolid(i)
                if isinstance(solid, PM.CollisionPolygon):
                    # Save the plane defined by this polygon
                    plane = PM.Plane(solid.getPlane())
                    planes.append(plane)
                else:
                    self.notify.warning("Unexpected collision solid: %s" %
                                        (repr(solid)))
                    newCollisionNode.addSolid(plane)

        newCollisionNode.setIntoCollideMask(newCollideMask)

        # Now sort all of the planes and remove the nonunique ones.
        # We can't use traditional dictionary-based tricks, because we
        # want to use Plane.compareTo(), not Plane.__hash__(), to make
        # the comparison.
        threshold = 0.1
        planes.sort(lambda p1, p2: p1.compareTo(p2, threshold))
        lastPlane = None
        for plane in planes:
            if lastPlane == None or plane.compareTo(lastPlane, threshold) != 0:
                cp = PM.CollisionPlane(plane)
                newCollisionNode.addSolid(cp)
                lastPlane = plane

        return PM.NodePath(newCollisionNode)
コード例 #8
0
    def __init__(self,
                 pos=None,
                 color=(0.6, 0.8, 0.5, 1),
                 scale=12,
                 h=8,
                 size=33,
                 trees=0.7):

        # Initialise primary NodePath which everything else is parented to
        if pos is None: pos = P.Vec3(0, 0, 0)
        self.pos = pos
        self.prime = P.NodePath('Terrain primary NodePath')
        self.prime.setPos(self.pos)

        # Create terrain models (rendering and collision)
        self.tnp, self.collnp = makeTerrain(size=size, h=h)
        self.tnp.reparentTo(self.prime)
        self.tnp.setColor(*color)
        self.tnp.setScale(scale)
        # Shift the collision terrain a bit so rays from trees hit
        self.collnp.setPos(self.collnp, .0001, .0001, 0)
        self.collnp.setCollideMask(C.floorMASK)

        # All trees in the scene are parented to one NodePath for flattening
        self.trees = self.prime.attachNewNode(P.PandaNode('trees'))
        self.treesColl = self.prime.attachNewNode(P.CollisionNode('treesColl'))
        self.treesColl.node().setIntoCollideMask(offMASK)
        self.treesColl.node().setFromCollideMask(obstacleMASK)
        #self.treesColl.show()
        vehicleCTrav.addCollider(self.treesColl, obstacleHandler)

        # Initialise trees
        img = greenNoise(imgSize=(size, size), scale=0.25)
        for x in range(0, size - 1):
            for y in range(0, size - 1):
                if img.getGreen(x, y) > trees:
                    treepos = P.Vec3(x * scale + 0.5 * scale,
                                     y * scale + 0.5 * scale, 50)
                    tree = Tree(pos=treepos)
                    tree.prime.reparentTo(self.trees)

        taskMgr.add(self.flatten, "Terrain flatten task")
コード例 #9
0
    def __init__(self, pos=None):
        """Initialise the tree."""

        # Models and CollisionSolids are parented to one prime NodePath
        if pos is None: pos = P.Vec3(0, 0, 0)
        self.pos = pos
        self.prime = P.NodePath('tree')
        self.prime.setPos(self.pos)

        dir = "models/trees"  # FIXME: hardcoded models dir

        # Choose a random model from dir and load it.
        trees = [
            f for f in os.listdir(dir)
            if os.path.isfile(os.path.join(dir, f)) and f.endswith('.egg')
        ]
        tree = random.choice(trees)
        self.np = loadModel(os.path.join(dir, tree), self.prime)

        # TODO: Give each tree a random orientation

        # Initialise the Tree's CollisionRay which is used with a
        # CollisionHandlerQueue to find the height of the terrain below the
        # tree and move the tree to that height (see self.step)
        self.raynp = self.prime.attachNewNode(P.CollisionNode('colNode'))
        self.raynp.node().addSolid(P.CollisionRay(0, 0, 3, 0, 0, -1))
        self.handler = P.CollisionHandlerQueue()
        cTrav.addCollider(self.raynp, self.handler)
        #self.raynp.show()
        # We only want our CollisionRay to collide with the collision
        # geometry of the terrain, se we set a mask here.
        self.raynp.node().setFromCollideMask(C.floorMASK)
        self.raynp.node().setIntoCollideMask(C.offMASK)

        # Add a task for this Tree to the global task manager.
        taskMgr.add(self.step, "Tree step task")
コード例 #10
0
    def __init__(self):
        """Initialise the scene."""

        # Show the framerate
        base.setFrameRateMeter(True)

        # Initialise terrain:
        # Make 4 terrain nodepath objects with different hilliness values
        # and arrange them side-by-side in a 2x2 grid, giving a big terrain
        # with variable hilly and flat areas.

        color = (0.6, 0.8, 0.5, 1)  # Bright green-ish
        scale = 12
        height = 18  # FIXME: For now we are raising the terrain so it
        # floats above the sea to prevent lakes from
        # appearing (but you still get them sometimes)

        t1 = Terrain(color=color,
                     scale=scale,
                     trees=0.7,
                     pos=P.Point3(0, 0, height))
        t1.prime.reparentTo(render)
        t2 = Terrain(color=color,
                     scale=scale,
                     h=24,
                     pos=P.Point3(32 * scale, 0, height),
                     trees=0.5)
        t2.prime.reparentTo(render)
        t3 = Terrain(color=color,
                     scale=scale,
                     h=16,
                     pos=P.Point3(32 * scale, 32 * scale, height),
                     trees=0.3)
        t3.prime.reparentTo(render)
        t4 = Terrain(color=color,
                     scale=scale,
                     h=2,
                     pos=P.Point3(0, 32 * scale, height),
                     trees=0.9)
        t4.prime.reparentTo(render)

        #tnp1.setPos(tnp1,-32,-32,terrainHeight)

        # Initialise sea
        sea = Sea()

        # Initialise skybox.
        self.box = loader.loadModel("models/skybox/space_sky_box.x")
        self.box.setScale(6)
        self.box.reparentTo(render)

        # Initialise characters
        self.characters = []
        self.player = C.Character(model='models/eve',
                                  run='models/eve-run',
                                  walk='models/eve-walk')
        self.player.prime.setZ(100)
        self.player._pos = SteerVec(32 * 12 + random.random() * 100,
                                    32 * 12 + random.random() * 100)
        self.player.maxforce = 0.4
        self.player.maxspeed = 0.55
        EdgeScreenTracker(self.player.prime, dist=200)  # Setup camera
        for i in range(0, 11):
            self.characters.append(C.Character())
            self.characters[i].prime.setZ(100)
            self.characters[i].wander()
            self.characters[i].maxforce = 0.3
            self.characters[i].maxspeed = 0.2
            self.characters[i]._pos = SteerVec(32 * 12 + random.random() * 100,
                                               32 * 12 + random.random() * 100)

        C.setContainer(
            ContainerSquare(pos=SteerVec(32 * 12, 32 * 12), radius=31 * 12))

        #C.toggleAnnotation()

        # Initialise keyboard controls.
        self.accept("c", C.toggleAnnotation)
        self.accept("escape", sys.exit)

        # Setup CollisionRay and CollisionHandlerQueue for mouse picking.
        self.pickerQ = P.CollisionHandlerQueue()
        self.picker = camera.attachNewNode(
            P.CollisionNode('Picker CollisionNode'))
        self.picker.node().addSolid(P.CollisionRay())
        # We want the picker ray to collide with the floor and nothing else.
        self.picker.node().setFromCollideMask(C.floorMASK)
        self.picker.setCollideMask(P.BitMask32.allOff())
        base.cTrav.addCollider(self.picker, self.pickerQ)
        try:
            handler.addCollider(self.picker, camera)
        except:
            pass
        self.accept('mouse1', self.onClick)

        # Set the far clipping plane to be far enough away that we can see the
        # skybox.
        base.camLens.setFar(10000)

        # Initialise lighting
        self.alight = AmbientLight('alight')
        self.alight.setColor(VBase4(0.35, 0.35, 0.35, 1))
        self.alnp = render.attachNewNode(self.alight)
        render.setLight(self.alnp)

        self.dlight = DirectionalLight('dlight')
        self.dlight.setColor(VBase4(0.4, 0.4, 0.4, 1))
        self.dlnp = render.attachNewNode(self.dlight)
        self.dlnp.setHpr(45, -45, 0)
        render.setLight(self.dlnp)

        self.plight = PointLight('plight')
        self.plight.setColor(VBase4(0.8, 0.8, 0.5, 1))
        self.plnp = render.attachNewNode(self.plight)
        self.plnp.setPos(160, 160, 50)

        self.slight = Spotlight('slight')
        self.slight.setColor(VBase4(1, 1, 1, 1))
        lens = PerspectiveLens()
        self.slight.setLens(lens)
        self.slnp = render.attachNewNode(self.slight)
        self.slnp.setPos(-20, -20, 20)
        self.slnp.lookAt(50, 50, 0)

        # Initialise some scene-wide exponential fog
        colour = (0.5, 0.8, 0.8)
        self.expfog = Fog("Scene-wide exponential Fog object")
        self.expfog.setColor(*colour)
        self.expfog.setExpDensity(0.0005)
        render.setFog(self.expfog)
        base.setBackgroundColor(*colour)

        # Add a task for this Plant to the global task manager.
        self.stepcount = 0
        taskMgr.add(self.step, "Plant step task")