def makeBulletCollFromPandaColl(rootNode, exclusions=[]): """ Replaces all of the CollisionNodes underneath `rootNode` with static BulletRigidBodyNodes/GhostNodes which contain the shapes from the CollisionNodes. Applies the same transform as the node it is replacing, goes underneath same parent, has same name, has same collide mask. If the Panda CollisionNode is intangible, a BulletGhostNode is created. Else, a BulletRigidBodyNode is created. """ # First combine any redundant CollisionNodes. optimizePhys(rootNode) for pCollNp in rootNode.findAllMatches("**"): if pCollNp.getName() in exclusions: continue if pCollNp.node().getType() != CollisionNode.getClassType(): continue if pCollNp.node().getNumSolids() == 0: continue mask = pCollNp.node().getIntoCollideMask() group = CIGlobals.WallGroup if mask == CIGlobals.FloorBitmask: group = CIGlobals.FloorGroup elif mask == CIGlobals.EventBitmask: group = CIGlobals.LocalAvGroup elif mask == CIGlobals.CameraBitmask: group = CIGlobals.CameraGroup isGhost = not pCollNp.node().getSolid(0).isTangible() if isGhost: rbnode = BulletGhostNode(pCollNp.getName()) group = CIGlobals.LocalAvGroup else: rbnode = BulletRigidBodyNode(pCollNp.getName()) rbnode.addShapesFromCollisionSolids(pCollNp.node()) for shape in rbnode.getShapes(): if shape.isOfType(BulletTriangleMeshShape.getClassType()): shape.setMargin(0.1) rbnode.setKinematic(True) rbnodeNp = NodePath(rbnode) rbnodeNp.reparentTo(pCollNp.getParent()) rbnodeNp.setTransform(pCollNp.getTransform()) rbnodeNp.setCollideMask(group) # Now that we're using bullet collisions, we don't need the panda collisions anymore. pCollNp.removeNode()
def optimizePhys(root): colls = 0 npc = NodePathCollection() for child in root.getChildren(): if child.node().isOfType(CollisionNode.getClassType()): colls += 1 npc.addPath(child) if colls > 1: collide = root.attachNewNode("__collide__") npc.wrtReparentTo(collide) collide.clearModelNodes() collide.flattenStrong() # Move the possibly combined collisionNodes back to the root. collide.getChildren().wrtReparentTo(root) collide.removeNode() for child in root.getChildren(): if child.getName() != '__collide__': optimizePhys(child)