Panda Bullet

Maybe this article provides some more information: http://www.bulletphysics.org/mediawiki-1.5.8/index.php/Stepping_the_World

I forgot to mention another method to avoid jitter: choosing the linear/angular sleep thresholds is such ways that when a body has only “fine” jitter it will be put to sleep.

Experimental. You can give it a try, but if you don’t get what you expect/want you should still set up you collision shapes by hand. Loading content is one of the most important topics in my opinion, but current state is that I play around with different options.

By hand.

No worries. Playing around with libpandabullet and giving feedback is probably the best help I can get. I might not be happy about some comments, but I do read them carefully and sooner or later try to realize the suggestions.

I want to make simple pong like game, to get feel on how everything works in bullet (one player surrounded by walls should work), and i have some questions :slight_smile:

http://tinypic.com/r/ade2js/7
Gameplay is 2d

How can i make an object not affected by physics?
Blue sphere is player, gray ones with “x” inside are pillars.
Player and pillars are capsules, black lines are walls. red circle is ball.
red line in right side is goal which only triggers event (thats ghost?)

Ball should collide with everything, but nothing besides ball should be affected with physics (ball cant push player or pillar or wall but it should be reflected from them).
I will probably hardcode limits for players movement, or put them inside boxes to limit their movement.

Not sure if I understand this right, but you are probably looking for plain static rigid bodies for walls and pillars. Simply set the bodies mass to zero (or don’t set it at all).

A ghost object would be ok for the goal. You can check each frame if the ball is inside the goal. But in your case it might be enough to just check each frame if the x-coordinate of the ball is larger than some value.

For tuning how the ball bounces off the walls or pillars have a look at the restitution and friction properties.

Ok, i am making some progress, setting friction and restitution is very nice, i will tune that later.

I made walls and pillars non movable, and gave them friction and restitution.

Now, problem is that i am using BulletCharacterControllerNode (capsule)for player (later on, i will replace walls with other players).
When ball hits player, it stops/slows down, and player is pushed by ball.

Character doesnt support setFriction or restitution.

I tried to cheat by adding “ordinary” BulletRigidBodyNode (parenting it under Character) but Rigid node doesnt follow Character.

The character being nuged around by dynnamic objects (and nudging other dynamic objects) is actually a bug in Bullet itself:
http://code.google.com/p/bullet/issues/detail?id=475

Interaction between kineamtic character controllers and dynamic objects is reponsibility of users. Bullert so far doesn’t offer any API for this, like for example PhysX does.

So far I don’t know any workarounds. Sorry.

Oh, dont worry, i am very grateful for your work, dont say sorry to me please :slight_smile:

And thanks for filling me with info.

Hmm, looks like i will have to use some other physics system for that game, if that is case…

Yes, either this or you try to do the same that coppertop has done for ODE, and write you own character controller in Python on top of a kinematic body. I think all the required stuff is exposed to Python.

Different games usually have different requirements for how a character controller behaves, and thus it is usual for a game to write it’s own controller. The one provided by the physics engine is usually only meant as an example how it could be done. Even PhysX, which is closed source, has the source code for the NxCharacterControllers as part of the SDK, so users can modify or extend the code.

So sooner or later we anyway have to write our own (Panda3D) character controller for Bullet. But first I want to have the “core” features of Bullet done in a satifying way.

I wrote my own character controller. I used a sphere for collision, and then only copy the position over to my Panda object.

Another realease. I would call it ‘feature release’ this time, since a completely reworked version of the softbody system is included.

http://enn0x.p3dp.com/libpandabullet-r15.zip

New in libpandabullet-r15:

  • Using Bullet-r2379
  • Using Panda3d-1.7.1
  • Improvements to waf configuration, e. g. checking for required libs.
  • BulletRigidBody.setDamping(lin, ang) split into two methods.
  • Fixed a bug in character controller CTOR
  • Exposed additional damping for rigid bodies via config options.
  • Redesigned and improved softbody subsystem.
  • New softbody samples (pressure, aero, …)

And here some short clips from some of the new softbody samples:
http://enn0x.p3dp.com/libpandabullet-r15-sample13.mpg
http://enn0x.p3dp.com/libpandabullet-r15-sample14.mpg
http://enn0x.p3dp.com/libpandabullet-r15-sample15.mpg
http://enn0x.p3dp.com/libpandabullet-r15-sample17.mpg

Hi, Just want to ask (possibly) dumb questions:

(1) Is there any way to use your PandaBullet in a Panda C++ program (instead of Python)?

(2) if yes how

(3) if not: what kind of effort should be done to integrate it (since most of the engine is C++ anyway)?

Thanks

JC

Enn0x, great work! The soft-bodies look very rich and the aero simulation is amazing! :stuck_out_tongue:

Again I congratulate you, this is some amazing work here.

@jean-claude:
If I am correct, (I could be very off) most of panda is compiled using interrogate. Which really only generates wrappers for C++ code.

As far as I would guess, you can simply include Enn0x’s code, using a C++ include statement, and use everything without problems.

Of course you’d have to look a little deeper, as there are no technical C++ examples. You could probably port the Python ones simplistically however.

@Enn0x:
Does Bullet/panda/the wrapper provide any support for rays that shoot into ‘infinity’ as many would put it?

For instance, in the ray casting example, I see that to cast a ray you must use

pFrom = Point3(-4, 0, 0.5)
pTo = Point3(4, 0, 0.5)

a from and two point, which makes the math very hard (for a non-math-savvy person like myself) to shoot a ray out of the mouse (for clicking on 3d objects, etc…)

Do you have any suggestions and or places/examples I could look at that do shoot the ray out to infinity in one direction? (or a way to push one of the vectors out using an angle from the lens projection?)
I know this is more my fault than anything else, math should be a strong suit for anyone who builds games… soo no worries.

Also, I’d like to ask if it’s possible to set an object (the character controller)'s rotation to a specific set of degrees? (for instance the NodePath method setH)

The only thing I’ve seen so far was setAngularVelocity, and I was able to get some help with the math to convert the degree rotation to the omega…
(this, if anyone wants it)

def setPlayerH(self, playerNP, dt, desiredDegrees):
    current = self.playerNP.getH()
    difference = desired - current
    vel = difference / dt
    return vel

Basically you pass in the NodePath object of the character controller, also the delta (from globalClock.getDt()) and the desired degrees that you would like the player to end up at, and it returns the velocity (omega) that you can feed into self.player.setAngularVelocity

Perhaps two convenience methods for setting the character controllers rotation, as well as casting a ray out in one single direct, would be of use within the wrapper? I am only one to guess though. I really really appreciate and congratulate you on the work you’ve done and are doing.

Very nice work,
~powerpup118

@jean-claude
libpandabullet is written in C++, and it follows the same structure as every other Panda3D “module”. You should be able to include the headers and link against the library.
Is this question about general setup/compiling of a C++ project? Or do you have something different different in mind?

However, if you are using C++ you might want to use Bullet directly in your code. It’s not difficult, and you can peek at the libpandabullet source code and copy a few methods from there, like for example transforms between Panda3D and Bullet vectors/transforms.

The class BulletCharacterControllerNode is a PandaNode, and it implements the transform_changed callback (among others). This means you can use playerNode.setTransform(ts) with ts being a TransformState. Or even better you can get a NodePath to this node, and use setH:

self.playerNP.setH(desiredDegrees)

However, the character controller is restrained in it’s rotation to the up/down-axis. Panda3D’s default up/down axis is Z_up, but is can be changed using prc options. This means the character can no “lean forward/backward” or “lean to the side”. It can just rotate around it’s vertical axis.

EDIT: fixed a typo: setH and not getH of course…

Both the “to” and the “from” point are in world coordinates. To create an infinite ray you could substitude such code

pFrom = Point3(x, y, z)
pTo = Point3(x+10, y, z)

… with something like this (+x direction in this case)

pFrom = Point3(x, y, z)
pTo = pFrom + Vec3(1, 0, 0) * 99999

The ray is not really infinite, but it is always possible to choose the length of the ray larger than your world size.

For picking objects fwith your mouse you could use something like this:

pMouse = base.mouseWatcherNode.getMouse()
pFrom = Point3()
pTo = Point3()
base.camLens.extrude(pMouse, pFrom, pTo)

pFrom = render.getRelativePoint(base.cam, pFrom)
pTo = render.getRelativePoint(base.cam, pTo)

Hi enn0x, Thanks for your advice.

Since the libpandabullet is a pyd python dll, I guess I need anyway to recompile most of the stuff into a regular c++ dll, right?

Nothing special, the aim is simply to replace ODE in my C++ panda code and switch to Bullet.

This is what I started to do, but then was wondering if I wasn’t on my way to re-invent the wheel. :confused:
I had compiled the “standard” Bullet_Physics from svn distribution and had in mind to use it directly into my c++ code. But doing so I’d definitively miss some form of “integration” into Panda, ie some specific modules you developped.
The question is what is the gap between btxxxx.cpp files and your composite source code. Can I merely use yours (with the original bullet code) to generate libpandabullet.dll?

No.I just rename libpandabullet.dll (created by compiling and linking my C++ code) into libpandabullet.pyd when copying it into the “test” folder. You can change the name back to .dll. But compiling yourself never hurts. If you have a C++ environment then you just need to compile the original bullet libs, and then modify some paths in wscript, and you should be able to compile yourself.

Quite a lot actually. Most wrapper objects are reference counted, and many objects (rigid body, soft body, ghost, character) are derived from PandaNode for seamless integration with the Panda3D scene graph. Also there is code for synchronization between visual and physical objects. And helpers for rendering soft bodies. Not an all inclusive list.

However, this way to integrate Bullet with Panda3D is certainly not optimal in all use cases. No approach is optimal in all cases.
It’s like vehicle axles: a rigid axis is good for offroad, but because of the large unsprung mass bad for driving on roads. Independent suspension if good for driving on roads, but hardly usable in heavy terrain. So there is no car which is a perfect high-speed sports car and a perfect offroader at the same time.

great job

Thank you Enn0x (Vielen Danke)
Based on your recommendation, I rebuilt the dll.

For those that could be interested in doing so here is the detailed process.

Ok, as discusssed, I regenerated libpandabullet.dll from scratch

(1) I downloaded bullet code from svn and compiled bullet

(2) Using your code, I modified wscript in order to refer to correct directories

BTW. I changed some performance flags for speed and use of SSE

ctx.env.append_unique('CXXFLAGS',
  ['/TP', '/MD', '/Zi', '/EHa', '/Zm300', '/O2', '/Oi', '/Ot', '/arch:SSE2', '/Ob2', '/W3',
   '/wd4005', '/wd4275', '/wd4996'])

(3) Then ran python waf configure

C:\Users\jc\Desktop\LIB_BUILDER\libpandabullet-r15>python waf configure
Setting top to                           : C:\Users\jc\Desktop\LIB_BUILDER\libpandabullet-r15
Setting out to                           : C:\Users\jc\Desktop\LIB_BUILDER\libpandabullet-r15\built
Checking for program python              : C:\Panda3D-1.7.1\python\python.exe
Checking for python version              : (2, 6, 4, 'final', 0)
Checking for waf version in 1.6.1-1.7.0  : ok
Checking for 'msvc' (c++ compiler)       : ok
('32bit', 'WindowsPE')
Checking for library libpanda            : yes
Checking for library libpandaegg         : yes
Checking for library libpandaexpress     : yes
Checking for library libp3dtool          : yes
Checking for library libp3dtoolconfig    : yes
Checking for library LinearMath          : yes
Checking for library BulletCollision     : yes
Checking for library BulletDynamics      : yes
Checking for library BulletSoftBody      : yes
Checking for library BulletMultiThreaded : yes
Checking for program interrogate         : C:\Panda3D-1.7.1\bin\interrogate.exe
Checking for program interrogate_module  : C:\Panda3D-1.7.1\bin\interrogate_module.exe
'configure' finished successfully (8.798s)

(4) so far, so good. So launched : python waf build install clean

At this point the linker screamed about trying to link x64

[6/6] cxxshlib: built\src\bullet_composite.cxx.2.o built\libpandabullet.lib
libpanda.lib(libpanda.dll) : fatal error LNK1112: module machine type ‘X86’ conflicts with target machine type ‘x64’

(5) Digging into the problem, it happened that if you’re under Windows 7/x64, and use Visual Studio
Waf is per default trying compile and link x64 … And this is not what was expected…

So the turn around I found is :

loaded waf_1.6.3 version ( code.google.com/p/waf/downloads/ … 3&can=2&q= )
modify again the wscript

 #ctx.check_tool('compiler_cxx')
  
 ctx.env['MSVC_VERSIONS'] = ['msvc 9.0'] # , 'intel 11']
 ctx.env['MSVC_TARGETS'] = ['x86']
 ctx.load('msvc')

and commented out :

 #   if platform.architecture()[0] == '64bit':
 #     ctx.env.append_unique('CXXFLAGS', ['/favor:blend'])
 #     ctx.env.append_unique('LINKFLAGS', ['/MACHINE:X64'])

(6) rerun: python waf build install clean

[i]Waf: Leaving directory C:\Users\jc\Desktop\LIB_BUILDER\libpandabullet-r15\built' 'build' finished successfully (30.340s) Waf: Entering directory C:\Users\jc\Desktop\LIB_BUILDER\libpandabullet-r15\built’

  • install test/libpandabullet.pyd (from built\libpandabullet.dll)
  • install test/libpandabullet.pyd.manifest (from built\libpandabullet.dll.manifest)
    Waf: Leaving directory `C:\Users\jc\Desktop\LIB_BUILDER\libpandabullet-r15\built’
    ‘install’ finished successfully (0.370s)
    ‘clean’ finished successfully (0.120s)[/i]

C:\Users\jc\Desktop\LIB_BUILDER\libpandabullet-r15>

so at this point libpandabullet.pyd has been generated
the test programs run ok!
and I rename libpandabullet.pyd into libpandabullet.dll for c++ direct use

et voila!

Thanks again Enn0x for your superb job in integrating Bullet into Panda3D!

One more thing, in order to allow the c++ app to use libpandabullet.dll, I grabbed your libpandabullet.lib (the import library to be used for link) from your built directory.

Everything is fine, except there is only one missing symbol when I generate the app

jctut.obj : error LNK2019: unresolved external symbol "void __cdecl btAlignedFreeInternal(void *)" (?btAlignedFreeInternal@@YAXPAX@Z) referenced in function "public: __thiscall btSoftBodyWorldInfo::~btSoftBodyWorldInfo(void)" (??1btSoftBodyWorldInfo@@QAE@XZ)

Apparently this is tied to a destructor of aligned allocated memory…

The code of this function merely appears in btAlignedAllocator.cpp as :

void	btAlignedFreeInternal	(void* ptr)
{
	if (!ptr) return;
	gNumAlignedFree++;
//	printf("btAlignedFreeInternal %x\n",ptr);
	sAlignedFreeFunc(ptr);
}

Any idea on how to fix this missing external in libpandabullet?
Is this coming from the bullet_physics main libraries compile or from your added code?

You already found where this methods comes from: btAlignedAllocator.h/.cpp, located in Bullet’s source code (bullet-r2379\src\LinearMath). So this is a symbol coming from Bullet itself, not from my code.

Hint: all classes starting with “btXyz” are Bullet itself, while classes starting with “BulletXyz” are libpandabullet.

So you have an own C++ application using classes from libpandabullet, and thus linking against libpandabullet.lib. Did you link again the orignal Bullet libs too, e. g. in this case LinearMath.lib? (located in bullet-r2379\msvc\2008\lib\Release if you are using VC2008)