Automatic Collision Generation for Bullet from Preloaded Models

Here is my own technique for automatically generating a Bullet collision mesh from a preloaded model inside Panda3D. The code produces tristrip meshes, which may or may not be ideal for your use case. I believe this code should work the same with .egg, .gltf, and .bam models.

Obviously, this is not the most efficient way to do basic collision modeling, but it has saved me hundreds of hours doing rapid development. The performance penalty is not too bad considering the workflow gains.

Known issue: The fit of the tristrip mesh to the model geometry may change after the original model file changes or is re-exported. I do not have a clean solution for this yet.

        def make_collision_from_model(input_model, world):
            # tristrip generation from static models
            # generic tri-strip collision generator begins
            geom_nodes = input_model.findAllMatches('**/+GeomNode')
            geom_nodes = geom_nodes.getPath(0).node()
            # print(geom_nodes)
            geom_target = geom_nodes.getGeom(0)
            # print(geom_target)
            output_bullet_mesh = BulletTriangleMesh()
            output_bullet_mesh.addGeom(geom_target)
            tri_shape = BulletTriangleMeshShape(output_bullet_mesh, dynamic=False)
            print(output_bullet_mesh)

            body = BulletRigidBodyNode('input_model_tri_mesh')
            np = self.render.attachNewNode(body)
            np.node().addShape(tri_shape)
            np.node().setMass(0)
            np.node().setFriction(0.5)
            # np.setPos(0, 0, 0)
            np.setScale(1)
            np.setCollideMask(BitMask32.allOn())
            world.attachRigidBody(np.node())
        
        make_collision_from_model(access_deck_1, world)  # world = BulletWorld()

Edit: I wrapped the logic into a function def for modularity.

1 Like

Hi, I am getting a problem when trying to execute this code. it is telling me on this line np.node().setMass(0) that 'builtin_function_or_method' has no attribute setMass

That’s a very strange error, are you sure you didn’t accidentally write np.node.setMass?

You are correct. I have been staring at my IDE for hours now so everything is looking like a blur. Thank you for the help! This code does not seem to add the colliders though?

Are you using the Bullet Debugger to verify your collision boundaries? Sometimes the collision mesh will be placed somewhat away from your model on the scene graph.

I would suggest testing with the default Cube primitive object in Blender to see if your export process is working right.

It’s also worth mentioning that if your Blender model is separated into multiple objects, IE “door”, “handle”, “jamb”, these will be referenced as different geom nodes, which you select with the input:

            geom_nodes = geom_nodes.getPath(0).node()
            # print(geom_nodes)
            geom_target = geom_nodes.getGeom(0)

where the inputs are modified from 0 → however many paths your model file has.