Panda Bullet


Hey enn0x, back again - I know what you’re thinking, “When will he leave? >.>” nah just kidding though if you want me to just shush and let you work let me know :wink:

(Does the BulletHeightFieldShape (or it’s node) provide a way to display a visual texture? otherwise I assume that I must build my visual heightmap using panda’s heightfield generator found here, in which case)

When matching a bullet heightfield with a panda visual heightfield, several inconvenient things happen (which I think might be easy-ish to include)

you have to turn the visual map using setH(90) because I guess panda or bullet disagree with the starting rotation or something
after that, the bullet map starts in the center point of the image (image width / 2 image height / 2, basically), the panda visual heightmap starts… in some corner, so you have to set it’s X and Y to offset half the image (which is weird), I wonder if either we could offset the bullet heightfield to match the panda3d one, OR add a way for a texture to be set on the bullet heightfield

these are just idea’s and I’m only hoping to give good feedback, what you’ve done so far is brilliant and I really want to see it go further :wink:
So it’s totally up to you if you think this is important or non important or anything


Here is my code, which will take a height map of any size, and set Pandas terrain to match that of Bullet.

#Set some var's:
        self.height = 250
        self.heightMap = "gfx/terrain/height.png"

        self.heightSize = PNMImage(self.heightMap).getXSize()

        self.terrain = GeoMipTerrain("terrain")


        self.root = self.terrain.getRoot()

        self.textureStage = TextureStage("Texture Stage")
        self.texture = loader.loadTexture('gfx/terrain/texture.jpg')
        self.detailMap = loader.loadTexture('gfx/terrain/detailmap.jpg')



        self.xform = TransformState.makePos((0,0,self.height/2))

        self.shape = BulletHeightfieldTerrainShape(self.heightMap,self.height,BulletHeightfieldTerrainShape.ZUp)

        self.body = BulletRigidBody(0,self.xform,self.shape)


No worries. I might be a bit sarcastic now and then, but I carefully read all suggestions, and I appreciate input.

No. The Bullet shapes are pure collision objects, without any visible geom. I want to keep it this way. Users should be able to choose whatever visible geometry they need (including whatever way of texturing/shaders they want to have.

The intended way is to create a BulletRigidBodyNode, reparent it to e. g. “render”, and then place nodes with visible geometry BELOW this node. If the body node’s transform changes then the visual geoms move together with the body node.

Hmmm… good point. Having the same conventions about orientation and origin in GeoMipTerrain and BulletTerrainShape would be convenient. However, there might be other ways of creating a terrain geometry, for example a simple static mesh, which won’t follow the GeoMipTerrain conventions. I have to thing about it, but I guess I will align both conventions.

Until then the best way would be to place the GeoMipTerrain below the BulletRigidBody, and just offset it’s transform and scale. For example Like Sothh has done (thanks for the code).


A mod needs to make this sticky!

Mod edit: your wish is granted.


Next version:

What’s new:

  • BulletHeightfieldShape is now by default oriented in the same way as GeoMipTerrain. However, the shape is still centered around the node’s position (unlike GeoMipTerrain).
  • Renamed the method BulletRigidBodyNode.attachShape to addShape.
  • Convenience functions for creating rigid bodies and ghosts from CollisionNodes, e. g. loaded from an .egg file (see maze sample).
  • Linux (32 bit) support. There are still some glitches - the slider and hinge constraints don’t work on Linux yet.


Hey enn0x,

Some useless random babbling here, I wanted to say that your Bullet implimentation in Panda is…
A. Amazing.
B. Has already surpassed the ODE implementation in panda IMO (excluding the whole platform dependence thing, which appear’s to be slowly waddling away… by that I mean I’ve no idea how to compile things or use the linux 32 version)
C. Should be included in panda ASAP

Obviously the platform dependency thing has to work out slowly, because it takes a while to support multiple OS’s, and I know people use Mac though it’s hard to compile on there when you have none (Idk if you do, I’ve never had one)

This work is simply amazing and I encourage people to look into using this in place of ODE or Physx, the wrappers are VERY nice and it seems like you’ve put alot of work into this enn0x

P.S. (the height field orientation correction I thank you for, it works wonders :smiley:)


I still dont know how to build this with waf. Ive never used waf. Installed it in Windows. Now what? This page says I shoud execute these 3 commands:

waf configure
waf build
waf install

Is that how I should do it? Or with the bat file in the libpandabullet folder?


Hi, I just built it on Linux (32) and I built it (after compile bullet) I ran:

python waf configure
python waf build

And then I just copied built/ (in your case .dll) to the test directory…

You may have to rename the dll to a .pyd on windows.

Enn0x, I dunno if it works for you, the (or whatever the character controller test is named) segmentation faults for me.
I used the latest bullet SVN revision… and it compiled without doubt… any luck for me?




Now you do exactly as this page says: you open a command shell, change directory to wherever you unpacked libpandabullet, and run the three commands.

I don’t know what you mean when you say you have installed waf. You don’t need to install waf! The complete build system is contained in one single file: “waf”.

The .bat file is there for just one purpose: because Windows doesn’t support the so called shebang. This is nothing obscene - look it up on wikipedia. The .bat file does nothing but call "python waf ".

Please not that you have to adjust the path setting withing the file “wscript”. You have to set the path to your Panda3d 1.7.1 installation, to your VS2008 & Windows SDK, and the path to where you have compiled Bullet libs.

Oh, and no grantee that it will compile or run on 64 bit Windows. I don’t have a 64 bit Windows, so I can’t test or fix anything.



Thank you very much, and glad you like it so far.
About integrating with Panda3D source code, well, original plans have been to introduce Bullet support with Panda3D 2.0. I am still not sure if the code is stable already, and there might be one more complete rewrite. so I’m afraid it will be too late for 1.7.1. The odd releases usually don’t introduce new features, so maybe 1.7.2 or 1.8.0.

About the issue with the character demo: This is a bug in Bullet itself. If you compile Bullet yourself you should patch the source code. See … 6858#66858 for a link to the Bullet forums (yes, it’s a know bug in Bullet).

Basically you edit one file, src/BulletDynamics/Character/btKinematicCharacterController.cpp. In line 87 you add “convexResult”, changing the line from

hitNormalWorld = m_hitCollisionObject->getWorldTransform().getBasis()...


hitNormalWorld = convexResult.m_hitCollisionObject->getWorldTransform().getBasis()...

Then compile Bullet and libpandabullet, and the character demo should work well too. I hope this bug will be fixed soon within Bullet source code, since it is quite annoying to patch the code each time I get a new revision of the Bullet source code. But I’m afraid the character controller doesn’t have high priority for Bullet developers.


@enn0x: okay, doesnt sound that hard, but wouldnt a README in the archive help?

As for adding it to Panda 2.0, rdb and drwr both said it is in years to come, so I dont see any logic in not adding anything to the current Panda versions.
Its like if Blender Foundation wouldnt add any new features to Blender since 2007 because they started working on a rewrite ( 2.5).
From what I know, if its added to the svn, its added to the snapshot builds.


1.8.0 might sound like a nice release to put this in. In general, we try to only bring major new features like these in x.x.0 releases.


I think in the mean time we could…

A. Compile it for Mac, or maybe we just leave this to whoever packages 1.8.0?

B. Perhaps the Bullet development team will accept a unix patch file if we gen one?

C. Maybe we could package this into OS-dependant p3d files (so that it’d work in the runtime for 1.7.1), in fact I will probably begin to try and do this

@Enn0x: Thank you for the tip on how to fix the segmentation fault! I will test it asap and see if I still have problems


A. That’d probably be me. I’ll definitely look into compiling it for the Mac when it gets integrated into Panda3D, if nobody else did it before then.

C. As soon as it gets integrated into Panda3D, there will be a bullet package on the official runtime distribution hosts.


About the 64 bit thing, I run 64 bit Windows 7, and it works perfectly fine for me.


Hey, what would be the best way of getting the class instance that a collision ray is colliding with?

I need this so I can call a function on this instance when ever someone clicks it with the mouse.


problem! what did i do wrong?

c:\Panda3D-1.7.0\bullet\libpandabullet>python waf configure
Setting top to                           : c:\Panda3D-1.7.0\bullet\libpandabulle
Setting out to                           : c:\Panda3D-1.7.0\bullet\libpandabulle
Checking for 'msvc' (c++ compiler)       : ok
'configure' finished successfully (0.440s)

c:\Panda3D-1.7.0\bullet\libpandabullet>python waf build install clean
Waf: Entering directory `c:\Panda3D-1.7.0\bullet\libpandabullet\built'
[1/6] libbullet_igate.cxx src\bulletAllHitsRayResult.h src\bulletB
ody.h src\bulletBoxShape.h src\bulletCapsuleShape.h src\bulletCharacterControlle
rNode.h src\bulletClosestHitRayResult.h src\bulletClosestHitSweepResult.h src\bu
lletConeShape.h src\bulletConeTwistConstraint.h src\bulletConstraint.h src\bulle
tContactCallbacks.h src\bulletContactResult.h src\bulletConvexHullShape.h src\bu
lletConvexPointCloudShape.h src\bulletCylinderShape.h src\bulletDebugNode.h src\
bulletDistanceConstraint.h src\bulletGenericConstraint.h src\bulletGhostNode.h s
rc\bulletHeightfieldShape.h src\bulletHelper.h src\bulletHingeConstraint.h src\b
ulletManager.h src\bulletManifoldPoint.h src\bulletPersistentManifold.h src\bull
etPlaneShape.h src\bulletRigidBodyNode.h src\bulletShape.h src\bulletSliderConst
raint.h src\bulletSoftBodyConfig.h src\bulletSoftBodyHelper.h src\bulletSoftBody
Node.h src\bulletSoftBodyShape.h src\bulletSoftBodyWorldInfo.h src\bulletSphereS
hape.h src\bulletTriangleMesh.h src\bulletTriangleMeshShape.h src\bulletVehicle.
h src\bulletWheel.h src\bullet_includes.h src\bullet_symbols.h src\bullet_utils.
h src\config_bullet.h -> built\libbullet_igate.cxx built\
    *** Error in bullet_utils.h near line 31, column 73:
    parse error
Error parsing file: 'bulletAllHitsRayResult.h'
Waf: Leaving directory `c:\Panda3D-1.7.0\bullet\libpandabullet\built'
Build failed
 -> task failed (exit status 1):
        {task 45373456: libbullet_igate.cxx bulletAllHitsRayResult.
et_utils.h,config_bullet.h -> libbullet_igate.cxx,}
' interrogate -srcdir ../src -I../src -Dvolatile -Dmutable -DCPPPARSER -D__STDC_
_=1 -D__cplusplus -D__inline -longlong __int64 -D_X86_ -DWIN32_VC -D_WIN32 -D_MS
C_VER=1500 -D"_declspec(param)=" -D_near -D_far -D__near -D__far -D__stdcall -DF
ORCE_INLINING -oc libbullet_igate.cxx -od -fnames -string -refcount
 -assert -python-native -S"../src/parser-inc" -S"C:\\Program Files/Panda3D-1.7.1
/include" -S"C:\\Program Files/Panda3D-1.7.1/include/parser-inc" -DBUILDING_PAND
ABULLET -module pandabullet -library libbullet bulletAllHitsRayResult.h bulletBo
dy.h bulletBoxShape.h bulletCapsuleShape.h bulletCharacterControllerNode.h bulle
tClosestHitRayResult.h bulletClosestHitSweepResult.h bulletConeShape.h bulletCon
eTwistConstraint.h bulletConstraint.h bulletContactCallbacks.h bulletContactResu
lt.h bulletConvexHullShape.h bulletConvexPointCloudShape.h bulletCylinderShape.h
 bulletDebugNode.h bulletDistanceConstraint.h bulletGenericConstraint.h bulletGh
ostNode.h bulletHeightfieldShape.h bulletHelper.h bulletHingeConstraint.h bullet
Manager.h bulletManifoldPoint.h bulletPersistentManifold.h bulletPlaneShape.h bu
lletRigidBodyNode.h bulletShape.h bulletSliderConstraint.h bulletSoftBodyConfig.
h bulletSoftBodyHelper.h bulletSoftBodyNode.h bulletSoftBodyShape.h bulletSoftBo
dyWorldInfo.h bulletSphereShape.h bulletTriangleMesh.h bulletTriangleMeshShape.h
 bulletVehicle.h bulletWheel.h bullet_includes.h bullet_symbols.h bullet_utils.h
 config_bullet.h bullet_composite.cxx '



I had that problem, I think I had to download and install bullet onto my PC… google it, lemme know if it works


The object which has been hit by the ray can be accessed via “getNode”. When testing for a single hit (rayTestClosest):

result = mgr.rayTestClosest(...)
node = result.getNode()

And when testing for all hits (rayTestAll):

result = mgr.rayTestAll(...)
for hit in result:
    node = hit.getNode()

The returned object is one of the libpandabullet nodes, e. g. BulletRigidBodyNode.

To get the type of this node you can use the standard Python “type()” method, and you can also use the PandaNode tags or python tags to store additional information on the node when creating it.


Impossible to say with the few information provided. But, like powerpup118 suggested, the most likely reason is that you forgot to download and compile Bullet. Open the “wscript” file and make sure that all paths are valid on your computer, especially the ones who point to your Bullet libraries:

    # Bullet

If not modify them to match your needs.

By the way: Is there a particular reason why you try to compile yourself? Oh, and if you download the Bullet sources yourself make sure you apply the above mentioned fix to src/BulletDynamics/Character/btKinematicCharacterController.cpp.