How to load any shape of model using TriangleMesh

I want to import a race track model using BulletTriangleMesh, but when I load the shape of the model and the shape of the triangle mesh is not the same they are in different sizes

    self.track = loader.loadModel('trk_new')
    geom = self.track.findAllMatches('**/+GeomNode').getPath(0).node().getGeom(0)
    mesh = BulletTriangleMesh()
    mesh.addGeom(geom)
    shape = BulletTriangleMeshShape(mesh, dynamic=True)
    body = BulletRigidBodyNode('track')
    bodyNP = self.worldNP.attachNewNode(body)
    bodyNP.node().addShape(shape)
    bodyNP.node().setDeactivationEnabled(False)
    self.track.reparentTo(bodyNP)
    self.world.attachRigidBody(bodyNP.node())
    bodyNP.setCollideMask(BitMask32.allOn())

I’m doing something wrong?
I’m new to panda 3d can anyone help me

Have you applied a scaling factor to any part of the model being loaded? If so, perhaps try removing that (perhaps by “applying” it in the modelling program).

1 Like

no, i didn’t apply any scale on this model in code , but I scale it in the blender before exporting it

This is what I was referring to. I’d suggest that you try “applying” the scale in Blender before re-exporting.

1 Like

The second point, it is better to always call the method:

node.clear_model_nodes()
node.flatten_strong()

This will reset any transformation on the node.

2 Likes

Another possibility, by the way, is to export the (unscaled) mesh as Panda collision geometry, and then use “BulletHelper.fromCollisionSolids” to convert the mesh into Bullet collision geometry.

In general, I recommend avoiding the use of scaling when dealing with collision geometry; if it’s left in at run-time, it can result in unexpected behaviour, I believe.

2 Likes

I have a mostly completed project that needed to do this very same thing. I used the method suggested by Thaumaturge a moment ago. Here is my code.

def loadTrack(self):
  
  visNP = loader.loadModel('models/Hill_Track8') 
  visNP.reparentTo(render)
  visNP.setTransparency(TransparencyAttrib.MAlpha)
  visNP.setDepthOffset(1)
  self.track = visNP
  
  bodyNPs = BulletHelper.fromCollisionSolids(visNP, True);
  for bodyNP in bodyNPs:
    bodyNP.reparentTo(render)
      if isinstance(bodyNP.node(), BulletRigidBodyNode):
        bodyNP.node().setMass(0.0)
        bodyNP.setCollideMask(BitMask32.allOn())
        self.world.attachRigidBody(bodyNP.node())

Also if you go the route you are going your mesh should not be dynamic as it is terrain so it has no mass and isn’t going to move (unless of course for some reason it is going to move and needs mass)

2 Likes

thanks for sharing the information
now the problem is solved by just replacing -

BulletTriangleMeshShape(mesh, dynamic=True)
to
BulletTriangleMeshShape(mesh, dynamic=False)

2 Likes