Panda Bullet


OK. Do you want me to transfer these or will you do it?

I don’t think you’re allowed to change the CV-qualifiers of a non-static member, sorry.


Thought so. This means that we won’t be able to update to Bullet 2.81 on the release branch, because the Bullet API changed const-ness of some objects from 2.80 to 2.81 (non-const to const), and we need to follow in our wrappers. This is unfortunate, because there have been important bug fixes in Bullet 2.81.

Hmm… is there a way to check ABI compatibility BEFORE check in to the release branch (I’m using Win7/VS2010 Express/Win7 SDK, and currently don’t have any Linux virtual machines set up)? If not I would prefer to build a patch file and send it to you via mail.

makepanda fails with bullet 2.81

We could still support 2.81 without breaking ABI compatibility by typecasting the pointer to the const version in the method itself. It’s not the best practice, but for the sake of compatibility I think it’s definitely justifiable.

There are probably tools out there, but none that I’ve worked with work on Windows. I have a buildbot set up that periodically checks ABI compatibility, though, so I’ll let you know if anything comes up.


would there be a chance of getting btMinkowskiSumShape wrapped by panda? It seems like a minkowski sum of a thin cylinder and a sphere would be a good model of a vehicle’s wheel.
Thanks for your help!


Well, it would be possible to expose the minkowski sum shape to Python users. It is just a bit contrary to the direction I am heading, and the minkowski sum shape is for advanced users. Hmm… try to convice me: why do you think that the minkowski sum of a cylinder and a sphere is a better approach than a convex hull - and for what kind of car game is such an approach suitable?


In my case, I would like to have the dynamics of the wheels really simulated. I tried using cylinders for this, but (probably for some mathematical problems I am not completely aware of) this resulted in strange spontaneous movements of the cart. From what I read, cylindrical collision shapes are kind of difficult to treat in general. Consequently, I replaced the cylinders by spheres. This worked without problem but is not exactly what I wanted to achieve. So I searched the internet and wondered why there is a cylinder with rounded bottom and top ends (capsule) in bullet/ode/… but no cylinder with rounded sides (“wheel”). While doing so, I found a thread where someone recommended to create a “wheel-shape” as the minkowski sum of a disk (or maybe short cylinder) and a sphere. So I wanted to try whether this sum is more stable than a pure cylinder or whether it inherits this spontaneous movement behavior.
As to the comparison to a convex hull: I would expect that the collision detection is much more efficient for a minkowski sum composed of two simple primitives than for a possibly complex convex hull. From my understanding, bullet has special methods for this case.


Ok, I added the BulletMinkowskiSumShape on the trunk. You need to download the current snapshot build. Better would be to get the latest Panda3D source code and compile yourself using Bullet 2.81 (the buildbot servers still use Bullet 2.80 afaik).

One warning: Debug visualisations are provided by Bullet - I just make visible in Panda3D whatever information Bullet provides. And Bullet does not provide a debug visualisation of minkowski sums. This is just fair: While it is easy to determine if a point is inside or outside the minkowski sum it is not easy to get the “surface” of a minkowski sum.


Hi again :slight_smile:

Thanks for including the Minkowski sum!!!

I just updated to the most recent panda cvs version (also the most recent bullet svn version, btw) and I am experiencing a strange problem. Something seems to have changed in the inertia calculation of Spheres:

from panda3d.core import Vec3
from panda3d.bullet import BulletRigidBodyNode, BulletSphereShape

body = BulletRigidBodyNode()
shape = BulletSphereShape(1.0)
print body.get_inertia()


LVector3f(0.666667, 0.666667, 0.666667)

But after all I understand, it should return (0.4, 0.4, 0.4). I tried to find out why this happens but did not succeed. In bullet’s btSphereShape.cpp, it seems to be correct:

void	btSphereShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
	btScalar elem = btScalar(0.4) * mass * getMargin()*getMargin();


Any ideas on this?
Thanks in advance!


Yep, this is a bug, in BulletBodyNode.add_shape.

I created a btCompoundShape even if it is not necessary (i.e. the shape’s local transform is an identity transform). And Bullet uses only an approximation when calculating the inertia of a compound shape (based on the compounds bounding box).

I checked in a fix in the MAIN branch.
The RELEASE branch(es) are not affected.

Thank you for finding out this bug. I would not have found it myself.


I’ve been constantly getting this strange segfault on Windows, in the BulletWorld constructor:

  _info.m_gravity = _world->getGravity();

I’d think that _world is perhaps not initialised, and strangely enough, MSVC debugger confirms that “_world” has a value of NULL. Since it’s allocated slightly above (with a safety assert!) this line, either the debugger is lying, or there’s some sort of stack corruption going on.

For what it’s worth, at that point, _info.m_broadphase is not NULL whereas _broadphase is; though this is not a debug build, and it’s possible that the debugger has it wrong.

It only happens on my local 64-bit build, not on the public 32-bit build. Have you seen this before?


It’s only a few days ago when I made my first 64bit build of Panda3d (using your thirdparty libs - thank you very much for providing them), so not terrible much information yet. I have been able to reproduce the issue. 32bit builds work find, while 64bit build crash.

I think the debugger is providing misleading information here. The issue seems not to be the BulletWorld::_world member, but the assignment “_info.m_gravity = …”. The Bullet vector class (btVector3) does not provide any assignment operators, so I guess something is going wrong with alignment within the btSoftBodyWorldInfo struct… but just random guesses. I still don’t understand the problem. But it’s late here, and I’m already tired.

Anyway, I checked in a fix which solved the problem for me. for me it worked to replace the assignment to m_gravity with calls to btVector3::setValue(x,y,z).


Thanks for the quick fix! Greatly appreciated. It seems to work just fine now. I’ve grafted these fixes onto the 1.8 branch.


You’re welcome. I still try to understand what happened.


I wish to download bullet samples, but this link doesn’t work.
Is there another link for them?
Thanks for help


The Panda3D projects server ( seem to have some technical trouble. Any ideas for a replacement?


I’ve got a copy in my dropbox: …

But a more permanent solution would be good :slight_smile:


Thanks for sharing your copy.



I originally posted this in the c++ dev forum but now realise it should probably be added here. I tried to build the C++ Bullet samples with Panda3D 1.8.1 and Bullet 2.8.2 r2704, but I get a linker error. This is in VS2008 Win32 build release. I believe I have all the correct libs and headers included in my project:

1>F:\Panda3D-1.8.1\include\bulletWorld.h(132) : error C2259: 'BulletContactResult' : cannot instantiate abstract class
1>        due to following members:
1>        'btScalar btCollisionWorld::ContactResultCallback::addSingleResult(btManifoldPoint &,const btCollisionObjectWrapper *,int,int,const btCollisionObjectWrapper *,int,int)' : is abstract
1>        F:\Bullet\bullet-2.82-r2704\bullet-2.82-r2704\src\BulletCollision/CollisionDispatch/btCollisionWorld.h(433) : see declaration of 'btCollisionWorld::ContactResultCallback::addSingleResult'
1>F:\Panda3D-1.8.1\include\bulletWorld.h(133) : error C2259: 'BulletContactResult' : cannot instantiate abstract class
1>        due to following members:
1>        'btScalar btCollisionWorld::ContactResultCallback::addSingleResult(btManifoldPoint &,const btCollisionObjectWrapper *,int,int,const btCollisionObjectWrapper *,int,int)' : is abstract
1>        F:\Bullet\bullet-2.82-r2704\bullet-2.82-r2704\src\BulletCollision/CollisionDispatch/btCollisionWorld.h(433) : see declaration of 'btCollisionWorld::ContactResultCallback::addSingleResult'
1>Build log was saved at "file://c:\Users\me\Documents\Visual Studio 2008\Projects\PandaHelloWorld\PandaHelloWorld\Release\BuildLog.htm"

This is the sample code I’m trying to get to work:

// Bullet Physics Example.
// The following example is done from Python sources, Panda Reference and Panda Manual,
// for more information, visit Panda3D and/or Bullet physics web site.
// Compiling and Linking documentation and notes are not 
// covered in this file, check manual for more information.
#include "pandaFramework.h"
#include "windowFramework.h"
#include "nodePath.h"
#include "clockObject.h"
#include "asyncTask.h"
#include "genericAsyncTask.h"
#include "bulletWorld.h"
#include "bulletPlaneShape.h"
#include "bulletBoxShape.h"
BulletWorld *get_physics_world() {
    // physics_world is supposed to be an global variable,
    // but declaring global variables is not cool
    // for good programmers lol, instead, should use static keyword.
    static BulletWorld *physics_world = new BulletWorld();
    return physics_world;
AsyncTask::DoneStatus update_scene(GenericAsyncTask* task, void* data) {
    // Get dt (from Python example) and apply to do_physics(float, int, int);
    ClockObject *co = ClockObject::get_global_clock();
    get_physics_world()->do_physics(co->get_dt(), 10, 1.0 / 180.0);
    return AsyncTask::DS_cont;
int main(int argc, char *argv[]) {
    // All variables.
    PandaFramework framework;
    WindowFramework *window;
    NodePath camera;
    PT(AsyncTaskManager) task_mgr;
    // Init everything :D
    framework.open_framework(argc, argv);
    framework.set_window_title("Bullet Physics");
    window = framework.open_window();
    camera = window->get_camera_group();
    task_mgr = AsyncTaskManager::get_global_ptr();
    // Make physics simulation.
    // Static world stuff.
    get_physics_world()->set_gravity(0, 0, -9.8);
    BulletPlaneShape *floor_shape = new BulletPlaneShape(*new LVecBase3f(0, 0, 1), 1);
    BulletRigidBodyNode *floor_rigid_node = new BulletRigidBodyNode("Ground");
    NodePath np_ground = window->get_render().attach_new_node(floor_rigid_node);
    np_ground.set_pos(0, 0, -2);
    // Dynamic world stuff.
    BulletBoxShape *box_shape = new BulletBoxShape(*new LVecBase3f(0.5, 0.5, 0.5));
    BulletRigidBodyNode *box_rigid_node = new BulletRigidBodyNode("Box");
    box_rigid_node->set_mass(1.0); // Gravity affects this rigid node.
    NodePath np_box = window->get_render().attach_new_node(box_rigid_node);
    np_box.set_pos(0, 0, 2);
    NodePath np_box_model = window->load_model(framework.get_models(), "models/box");
    PT(GenericAsyncTask) task;
    task = new GenericAsyncTask("Scene update", &update_scene, (void*) NULL);
    return (0);

Any ideas?



Hello zobbo,

we have not yet updated our wrappers to the new Bullet release (2.8.2). There have been several changes in the Bullet API from 2.8.1 to 2.8.2, leading to the compiler errors you see. You should be fine if you use the same Version of Bullet which we use (2.8.1 I think).

I will try to update our code around end of the year.


Hi enn0x,

Thanks, I wondered if it was something like that. I’ll roll back to 2.8.1 because it doesn’t make any difference to me. I just downloaded the latest version by default. Thought I better check in the (quite likely) event that I was missing something.