Panda Bullet


#821

You called bulletWorld.contactTest with a collider node which is not attached to the world?

I use asserts a lot throughout my code, to catch situations which I don’t expect to happen early. But if I know that un-attached colliders have no proxy then it would be better to change the Panda3D code and log a warning instead of crashing with an assertion.


#822

Accidentally, yes. ^^;

The code in which this test takes place isn’t directly related to process of crouching or standing (and, despite the name, isn’t the code that checks that there’s space to stand), so I presume–I think that it was some time ago that I put this in–that I simply missed the potential problem. Since it seems that my character is usually in the “standing” state when the code in question is executed, it went undiscovered for some time.


#823

enn0x, I made two changes to the Bullet code that I wanted to make you aware of.

(1) is_deactivation_enabled() and set_deactivation_enabled() worked a bit oddly - if deactivation was enabled, but the object was currently active, calling set_deactivation_enabled(true) could actually cause it to become deactivated immediately. I think the current behaviour makes slightly more sense. I ran into this issue when implementing point (2) below.

(2) By user requests, I’ve implemented the TypedWritable interface for some of the Bullet classes. This allows reading and writing Bullet nodes and shapes from/to a .bam file.
Only a few basic things are supported so far (rigid body, box, sphere, plane, convex hull, trimesh), but the hope is that eventually most Bullet functionality will be writable to a .bam file.
Eventually, this will pave the way to being able to load Physics information from model files, which formats like COLLADA and Blender can already do.


#824

Hello,

What is the recommended way to allow collisions between soft body and rigid body (plane). At the moment my soft body ellipsoid is falling through the floor. This doesn’t happen with rigid objects. I’ve tried a combo of:

bodyNode->get_cfg().set_collision_flag(BulletSoftBodyConfig::CF_sdf_rigid_soft,true);
bodyNode->get_cfg().set_collision_flag(BulletSoftBodyConfig::CF_cluster_soft_soft,true);
bodyNode->get_cfg().set_collision_flag(BulletSoftBodyConfig::CF_cluster_self,true);

which some people recommended in the bullet forums to fix collision issues, but with CF_cluster_self enabled I get weird behaviour (the softbody flies away) and the other two don’t seem to change anything.

Cheers,


#825

Hello,

To be honest the bullet softbody stuff has been a bit of a mystery to myself, since Bullet doesn’t provide much documentation what exactly these methods do and what the underlying concepts are. So I restricted myself to exposing the native Bullet functions 1:1 wherever I didn’t understand what is going on.

If something explodes right at the start of the simulation this usually means that the initial setup has some overlaps or other conditions which cause huge forces in the first simulation steps. But what exactly is causing the huge forces… hard to say.

Hmm… working with cluster flags makes only sense if you have clusters. I think you need to create them yourself, e. g. body_node->generate_clusters(16).

Also you could try clearing the current collision flags first: bodyNode->get_cfg().clear_all_collision_flags()


#826

Great, and thank you. The serialisation stuff has been on my mind for some time, but I didn’t know how to start.

On a sidenote: I think I made a big mistake when making the physics objects PandaNodes. Currently we get into performance problems with only a few hundred rigid bodies. Not because of the physics simulation itself (Bullet can handle thousands of rigid bodies without problems), but because of the two-way physics/scene graph synchronisation. Maybe a different design, for example like the native Panda3D physics system, makes more sense. Or I have choosen a clumsy way of syncing. If somebody has an idea here please tell me.


#827

Hi enn0x,

I’ve recently started using Panda3D over Blender Game Engine, and I’ve stumbled across an unusual artifact;
setting the HPR of a bullet nodepath seems to cancel the linear velocity of the body. Is this to be expected?

Angus.

EDIT
Seems that this isn’t an issue in a newer build. Thanks!


#828

Hi enn0x,

Thanks for the help. I still have the same problem, which is annoying because it works initially, but after some movement, falls through the floor plane. I’m considering switching to Physx or something for the reason you mention - poor documentation of bullet. Though I know nothing about Physx I might look into it, unless I manage to get this softbody collision working somehow.

Cheers,
Zobbo


#829

Hello!

I need some help/clarification on nodes vs. nodepaths in Bullet.
From what I understand, the Bullet engine for Panda only uses BulletRigidBodyNodes for simulation? E.g. you only add the BulletRigidBodyNode to the BulletWorld. Does that mean that there is no way to get to the NodePath object? My particular case is this: I want to do a world.rayTestClosest() query from the user’s point of view and change the color of the hit object, but the result only contains the pointer to the RigidBodyNode and not the NodePath, which prohibits me from doing anything useful. Am I missing something or is it really the current state of the API? If I cannot get the nodepath from the raytest, one idea I had is to use the CollisionSolid collision mechanism just for doing this raycast, but I would prefer to avoid being forced to put additional CollisionNodes inside BulletRigidBodyNodes just for this…


#830

Hmm… You could use “Python tags” (i.e. PandaNode. -“setPythonTag”, -“getPythonTag”, -“hasPythonTag”, and -“clearPythonTag”) to store a reference to the NodePath in the Node–but that does call for being careful to clean up your tags once you’re done with the nodes, I believe.


#831

Thanks for your answer Thaumaturge… Eventually I solved it with additional CollisionNodes, as the CollisionEntries have a reference to the “from” and “into” NodePaths.

Out of curiosity (maybe this is more of a question to enn0x) is there some limitation in the mechanism that makes supplying a reference to the colliding NodePaths in the raytest results impossible? For now, I cannot get my head around the inner mechanism of collisions in Bullet - if it’s the NodePaths (and not PandaNodes) that have position in the world, then how is it possible that only BulletRigidBodyNodes are added to the BulletWorld? What if, for example, one BulletRigidBodyNode is instanced under several NodePaths? I would understand that some kind of link to the NodePaths is required anyway (correct me if I’m wrong) so then there would be no problem with supplying the colliding NodePaths in the raytest results.
I appreciate all your answers - they will let me understand the system better :slight_smile:

EDIT: Also, one more question - with a BulletNode, I can addShape() with a TransformState translating the shape to a point different than (0,0,0). Any ideas on how to achieve a similar thing with the BulletCharacterController? The controller only takes the BulletShape as a constructor argument but it doesn’t inherit from BulletBody so doesn’t have addShape(). My particular case is: in my game, I want the point (0, 0, 0) of my player NodePath (and all other objects as a matter of fact) to be the point at the “feet” of the object - so that when I set the position of the player to (0, 0, 0) in the render frame of reference, the player will appear standing at x:0 y:0 with their feet on the ground - and not half buried in the ground. For that, all models and physics bodies have to be translated half of the object’s height upwards. I could use a BulletTriangleMeshShape for that, but I was wondering if it is possible to use a BulletCapsuleShape and translate it upwards.


#832

There is a way to get a NodePath for any node returned by the Panda3D API. It is not specific to the Bullet module, but applies to all Panda3D nodes:

np = NodePath(node)

For clarification: a NodePath is just a handle to a scene graph node, which provides a few convenience methods. There can be several NodePath instances pointing to the same node. The NodePath does not store any relevant information itself - all the information about the scene graph is within the nodes.


#833

I’ve discovered an issue in my character controller, and while I think that I may have a solution (I have yet to properly test it), I’m not enormously confident regarding game-physics, and so would like to check that what I’m doing isn’t a bad idea.

As I gather is standard for these things, my character controller doesn’t use dynamic physics; its velocity in particular is stored in a Panda “Vec3”, and its position is updated in my game-logic.

In order to then have my character controller respond to collisions with external objects (such as walls), I have a dynamic (not kinematic, I believe) rigid body attached to it, providing basic prevention of penetration. However, this alone doesn’t work, as the controller’s velocity remains unaffected. To remedy this, on each game-update I add the linear velocity of the dynamic body to my controller’s velocity, then zero the dynamic body’s velocity; this results in the dynamic body effectively producing a “reaction velocity” in response to collisions.

All of this seems to work fairly well–on my development machine, which is a little slow and in running my game seldom reaches sixty frames per second.

When I run the game on a faster test-machine, walls offer a little resistance, but I can nevertheless walk through them.

I think that I’ve traced this to my call to “doPhysics”, which I had been giving a maximum of one sub-step, and a sub-step size of 1/60.0–I think that I got these parameters from the forum, in a post responding to an issue in Panda 1.9’s handling of the default parameters. From my subsequent reading, I gather that this means that on a computer running at significantly faster than sixty frames per second the physics will not be updated every frame, and thus some logical movement-updates will happen without corresponding physics checks, and hence result in the ability to walk through walls.

My solution, then–the bit that I’m most unsure about–is to simply give “doPhysics” a maximum of “zero” sub-steps–which I gather instructs it to use the whole delta-time in a single updated, regardless of that delta-time–and to pass the delta-time as its sub-step size. (Come to that, does a specified sub-step size have any effect when “zero” sub-steps are indicated?)

This, I hope, produces variable physics steps, and a physics step on each game-update. My game isn’t intended to have physics puzzles, with the physics engine primarily providing penetration-prevention, the detection of objects and environment, and other such functions. As a result, I’m not terribly bothered about the loss of determinism–as long as the physics remain stable.

So, is my approach reasonable? Are there any issues that I should be aware of?


#834

You are right, the example implementation that comes with bullet (I just wrap this example implementation) is a so-called “kinematic character controller” (KCC). This means that the collision tube of the controller is a kinematic object and thus not affected by physics, just detects collisions. Kinematic controller are by far the most common ones. As far as I know Havok is the only physics engine which has a good dynamic controller.

With KCC it’s up to the implementation of the KCC to implement reasonable resonses. Reasonable is defined by the particular game and it’s logic (e. g. how to handle slopes, how exactly a player pushes objects (which direction, how forcefully…), friction between player and ground, bumping against object from below, players on conveyor belts or inside vehicles…). This means it is impossible to provide a single implementation which fits all games.

With Panda3D/Bullet it is possbile to implementy your own KCC, by deriving from BulletBaseCharacterControllerNode interface.

I think your approach (connecting a dynamic object) is quite interesting, but I’m sceptical. I would expect unwanted responses from the dynamic body. It I would start developing my own KCC I would probably start with very basic, self computed response forces to collision events. But… so far I never dared to do this, because I fear that I will fail.


#835

Interesting, and thank you. :slight_smile:

(For what it’s worth, my controller doesn’t descend from the Bullet/Panda controller, but is rather one of my own creation.)

For the moment I think that I’m inclined to continue to test my dynamic collider: aside from the aforementioned update issue, it’s actually worked fairly well for me thus far, I believe.

What about my use of a variable time-step? Should I expect problems there?


#836

Might be that you run into tunneling problems, in particular if there is a high load / low FPS.


#837

Hmm… That could be a problem, but I’m not sure that my character-controller generally moves fast enough that anything beyond a significant spike in delta-time or a ruinously low frame-rate, with corresponding effects on general gameplay, would be likely to incur it–at which point the spike or frame-rate is the main problem, I feel. Am I missing something?


#838

After experimenting a lot with Panda’s Bullet stuff I hit a pretty big roadblock.
I just can’t figure out how to set stiffnes(springy-thingy), and damping for constraints, especially the 6dof joint.
Simmilar goes for pretty much every other constraint,too.
Even detouring via ERP and CFM would be acceptable for me but I couldn’t really get to those either.

Is this stuff missing from Panda’s bindings or just super-well hidden?


#839

Hello Thomas,
and sorry for the late answer. It is super-well hidden, since it follows one-by-one the original Bullet API.
The Bullet way of modelling constraints is a bit unusual. This post explains the background a bit, even though it is for a newer version of Bullet: github.com/bulletphysics/bullet3/issues/345

Damping and restitution are hidden in the constraint limits and motors. In the case of the generic constraint you have to get the following objects:

  • constraint.get_rotational_limit_motor(int axis)
  • constraint.get_translational_limit_motor()

github.com/panda3d/panda3d/blob … mitMotor.h
github.com/panda3d/panda3d/blob … mitMotor.h

Might be that you are the first to test these functions :slight_smile:


#840

Hi enn0x,

meanwhile I stumbled across those settings but a had given up on finding anything useful at that point so I didn’t bother to try.
Apparently I really am the first one to use such deep-down parameter fun as i stumbled over a typo in an assertion test which caused only negative axis to get past the assertion (rdb fixed it already).
I’ll give it a another try as soon as i get back on the initial problem. And thanks for that explanation about how to translate damping/stiffness into bullet. It’s really useful comming from an engineering background.