Using a model file as a collision object in Bullet3D

Hello,

What is the current best way of using a model as a collision object? I have tried to use the method that is shown in the Ball in Maze example, however the nodeCollection it returned by BulletHelper.fromCollisionSolids is empty, so attempting to take the object in the first index to add to render and change position fails.

I am also currently trying to use a .bam file while the example uses a .egg file (model link: Road ML TT1Sb2b.bam - Google Drive)

Thank you for reading!

It seems you are confused, this method currently creates a body from the geometry.

https://docs.panda3d.org/1.10/python/programming/physics/bullet/collision-shapes#triangle-mesh-shape

from panda3d.bullet import BulletTriangleMesh
mesh = BulletTriangleMesh()
mesh.addGeom(geom)

The panda collision system is not needed.

Perhaps not entirely: translating Panda collision geometry–such as exported automatically by YABEE–is something that BulletHelper can do. Indeed, I use that approach in one of my own games.

However…

Looking quickly at the model in question via PView, it doesn’t seem to have collision geometry. Thus attempting to use “fromCollisionSolids” doesn’t work here–there are no collision-solids to convert from!

Now, one could use the approach given by serega, above.

But if so, I would like to give a word of caution: the model in question is presumably not intended to be used as collision geometry. As a result, it may not be optimised for it, and/or may be a little over-detailed for the purpose. Perhaps this won’t be a problem in this specific case–and perhaps it will; I don’t know. I would say to try serega’s approach–but to be aware that it may or may not work out well.

Hello again!

After alot of messing around with correctly attaching the nodes (this is the first 3d engine i hjave used, so the closest experience I have is blender), the track does now collide properly, however the performance of it is not great (Not a surprise since it essentially is a small object duplicated around a spline).

Would I be correct in saying that the performance drop is from the pure amount of vertices in the mesh? And in addition, what would be the best way of making a more efficient model in that sense? Is it a manual job of trying to make larger models to attach to simplify it, or is it another method that I need to know?

After making a smaller track with much less vertices to use, I found that in both cases the model seems to be warped using the TriangleMesh method (the width of the road is changed and the corners are much different).

although the track model isn’t lit, this shows what I mean by the warp then the model is also shown in the same window.

Code i used to show the track here:

        geomNodes = loader.loadModel((globals.rel_path(None, path="/src/models/tracks/Road ML TT1SSb2b.bam"))).findAllMatches('**/+GeomNode')
        geomNode = geomNodes.getPath(0).node()
        geom = geomNode.getGeom(0)

        mesh1 = BulletTriangleMesh()
        mesh1.addGeom(geom)

        mesh = BulletTriangleMeshShape(mesh1, False)

        # mesh.reparentTo(render)
        self.trackNode = BulletRigidBodyNode('Track')

        self.trackNP = self.worldNP.attachNewNode(self.trackNode)
        # self.trackNP.attachNewNode(geomNode)
        self.trackNP.setPos(Vec3(0, 0, -2))

        # mesh.reparentTo(self.trackNP)
        # self.trackNP.s
        # geometry
        loader.loadModel(globals.rel_path(None, path="/src/models/tracks/Road ML TT1SSb2b.bam")).reparentTo(
            self.trackNP)
        
        self.debugNode = BulletDebugNode('Debug')
        # self.debugNode.showWireframe(True)

        self.debugNP = self.worldNP.attachNewNode(self.debugNode)
        self.debugNP.show()
        self.world = BulletWorld()
        self.world.setDebugNode(self.debugNP.node())

        self.mapNP = self.worldNP.attachNewNode(self.trackNode)
        self.mapNP.node().addShape(mesh)

        self.world.attachRigidBody(self.mapNP.node())
        self.world.setGravity(Vec3(0, 0, -9.81))

smaller map model (it’s made using the same method, so the same lack of optimisation will be there:
Road ML TT1SSb2b.bam (1.3 MB)

That’s hard to say based only on what we have here, I think.

For one thing, are you applying a scaling factor to the collision-geometry? (Even if indirectly, via a node located above the collision-geometry in the scene-hierarchy.) If I recall correctly, scaling can cause problems for collision.

Another thing worth noting is that the Bullet debug renderer may be slow: do you still get poor performance if you disable debug rendering?

Finally, what happens if you break up your track into large chunks? Perhaps doing so will help Bullet to better cull away parts that are distant from a potential collision.

Hmm… Conversely to the mention of scaling above, are you applying a scaling factor–in code or in the modelling program–to the track itself? Perhaps when the geometry is given to the TriangleMesh some such scaling factor is lost.

[edit] In fact, looking at your bam-file, it does look like there’s a scaling factor applied. I would suggest removing that–specifically, by applying it in the modelling package. If you’re using Blender, then–going by the version that I use, at least; yours may differ–this is done in the 3D window by selecting the object, then opening the “Object” menu, from there selecting the “Apply” sub-menu, and from that clicking on the “Scale” menu-item.

Applying the scale in blender fixed the warping issue. My best guess is that since the scale applies around a path which is used to make the model follow, but gets thrown away in conversion, panda tries to replicate the scale by doing so around the origin instead since the path doesn’t exist.

As for splitting the larger track, as of yet i have not tried it. Once I get the time to later on today, I will and reply with if/how much it improves the performance.

1 Like

For progress on the chunking solution, i have tried using the start of the track on its own and using that to see how it runs, and it does run much better, so i will have to see how it runs with the entire track in place in pieces.

However, I now have another question (which I apologise for making this into a makeshift Q&A). For the tracks currently being used, they are exported from blender with a basic material which have a blue base colour and metallic increased to try and make it obvious for shadows. In Pview this works perfectly, but in the app the only light that affects the track is the ambient light in the scene, with the directional light on its own node, and point lights connected to the car having no effect on the track, when set to render or directly to the track’s Node (Noting that they do affect the car with no noticable issues). Do I need to add something to the material in blender before exporting with blend2bam? (The car was exported with the updated version of YABEE which I then edited materials for to get the metallic effect, but YABEE does not export the track correctly, so i switched to blend2bam)

There is no concept of an updated YABEE, it’s just someone’s personal exporter for their own project. You should ask questions to the author of the YABEE modification if you have these problems with the exporter.

What type of lighting do you use?

If it is based on vertices, without a setShaderAuto(). Then you may not have enough vertices for lighting.

1 Like

I have used setShaderAuto at the end of the init statement for the class of the window.

I am unsure of what you mean by type of lighting, but I will try to elaborate on where and what class of lights are used.

The first two lights are a dim ambient light, and a directional light with Hpr set at (0, 20, -10).

There are then 3 pointLights. One is near directly above the origin, and 2 others are parented to the chassis of the car, at the front of the body.

In the case that this isn’t the info that’s needed, I’ll link the repo that the issue pertains to: GitHub - SSteers126/APRG: Another Python Racing Game is a python racing game using the Panda3D Engine.

Loading again the bam-file that you posted previously, I discovered something: In PView, if I activate lighting but leave per-pixel lighting (i.e. shader-use) deactivated, then the track is lit as expected. However, as soon as I activate per-pixel lighting (with lighting activated), the track becomes a uniform dark blue.

Based on a bit of experimentation, I think that the problem may be related to a texture that’s being applied to the model–calling “setTextureOff(1)” on the model after loading seems to result in lighting working again.

Looking through the textures applied, it seems that there are three: a “normal-fallback”, a “pbr-fallback”, and an “emission-fallback”. Perhaps one or more of those is causing the problem.

Do you have the latest version of the panda3d-blend2bam and panda3d-gltf packages installed?

For installations of blend2bam and gltf, pip cannot find any newer versions for them so I believe the answer is yes (0.18 and 0.12 respectively). As for the textures, I can only assume that these are automatically given during conversion, since the material for the model only uses the default BDSF shader, which is supported by the fact that the blue it has in per pixel lighting matches that of the material. I’ll attach the blender file here: Road ML TT1SSNM.blend (757.2 KB)

Are there any specific requirements for materials in blender that I need to abide by to be fully compatible with the conversion process? I can’t see anything outlined in the readme, so I presume not.

Thank you for helping me with this!