def __call__(self, node):

        # Would use NodePath.findAllVertexColumns (string name)
        # but that also searchs child nodes
        # And does not require all geoms to have it.

        n = node.node()
        if not n.isOfType(GeomNode.getClassType()): return False
        for p in self.requiredPeoperties:
            for g in n.getGeoms():
                found = False
                for a in g.getVertexData().getArrays():
                    if a.hasColumn(p):
                        found = True
                        break
                if not found: return False
        return True
 def __call__(self,node):
     
     # Would use NodePath.findAllVertexColumns (string name)
     # but that also searchs child nodes
     # And does not require all geoms to have it.
     
     n=node.node()
     if not n.isOfType(GeomNode.getClassType()): return False
     for p in self.requiredPeoperties:
         for g in n.getGeoms():
             found=False
             for a in g.getVertexData().getArrays():
                 if a.hasColumn(p):
                     found=True
                     break
             if not found: return False
     return True
Пример #3
0
def makeBulletCollFromGeoms(rootNode,
                            exclusions=[],
                            enableNow=True,
                            world=None):
    """
    Creates and attaches bullet triangle mesh nodes underneath each GeomNode
    of `rootNode`, which contains the same mesh as the Geoms.
    This can be expensive if the geometry contains lots of triangles or GeomNodes.
    """

    if not world:
        world = base.physicsWorld

    # BulletRigidBodyNode -> triangle index -> surfaceprop
    # (it's so we know which surface we are walking on)
    result = {}

    for faceNp in rootNode.findAllMatches("**"):
        if faceNp.getName() in exclusions:
            continue
        if faceNp.node().getType() != GeomNode.getClassType():
            continue

        # Create a separate list of geoms for each possible face type
        # ( a wall or floor )
        type2geoms = {}
        for i in xrange(faceNp.node().getNumGeoms()):
            geom = faceNp.node().getGeom(i)
            state = faceNp.node().getGeomState(i)
            if not geom.getPrimitive(0).isIndexed():
                continue
            if state.hasAttrib(BSPFaceAttrib.getClassSlot()):
                bca = state.getAttrib(BSPFaceAttrib.getClassSlot())
                facetype = bca.getFaceType()
            else:
                facetype = BSPFaceAttrib.FACETYPE_WALL

            if not type2geoms.has_key(facetype):
                type2geoms[facetype] = [(geom, state)]
            else:
                type2geoms[facetype].append((geom, state))

        # Now create a separate body node to group each face type,
        # and assign the correct bit
        for facetype, geoms in type2geoms.items():
            data = {}
            numGeoms = 0
            mesh = BulletTriangleMesh()
            for i in xrange(len(geoms)):
                geom, state = geoms[i]
                mesh.addGeom(geom, True)
                surfaceprop = "default"
                if state.hasAttrib(BSPMaterialAttrib.getClassSlot()):
                    mat = state.getAttrib(
                        BSPMaterialAttrib.getClassSlot()).getMaterial()
                    if mat:
                        surfaceprop = mat.getSurfaceProp()
                for j in xrange(geom.getNumPrimitives()):
                    prim = geom.getPrimitive(j)
                    prim = prim.decompose()
                    tris = prim.getNumVertices() / 3
                    for tidx in xrange(tris):
                        data[numGeoms] = surfaceprop
                        numGeoms += 1
            shape = BulletTriangleMeshShape(mesh, False)
            rbnode = BulletRigidBodyNode(faceNp.getName() + "_bullet_type" +
                                         str(facetype))
            rbnode.setKinematic(True)
            rbnode.addShape(shape)
            rbnodeNp = NodePath(rbnode)
            rbnodeNp.reparentTo(faceNp)
            if facetype == BSPFaceAttrib.FACETYPE_WALL:
                rbnodeNp.setCollideMask(CIGlobals.WallGroup)
            elif facetype == BSPFaceAttrib.FACETYPE_FLOOR:
                rbnodeNp.setCollideMask(CIGlobals.FloorGroup)
            if enableNow:
                world.attachRigidBody(rbnode)
            result[rbnode] = data

    return result