Panda Bullet


#558

Hmmm, this is not good, since I can’t test on Linux right now. I have to setup a virtual machine first, wich is something I won’t be able to do before new weekend (maybe later).

But perhaps we can work around. One idea is that the BulletContactResult object (returned by contactTest) gets cleaned up right after you fetch the contact.

Try to modify the code like this:

def update():
   """ Gets called after each doPhysics call """
   result = world.contactTest(body)
   contacts = result.getContacts()
   for contact in contacts:
      mpt = contact.get_manifold_point()
      print("collide", mpt)
      print("idx", mpt.getIdx0(), mptgetIdx1())
      impact_force = mpt.get_applied_impulse()
      print("impact_force:", impact_force)
   del result

#559

For now I assume that the btManifoldPoint pointer in BulletContact became stale. I checked in fix which replaces the pointer by a concrete object. Since btManifoldPoint is not 16-bit aligned I had to replace the pvector by a btAlignedObjectArray. Well, let’s see if this fixed the Linux crashes.


#560

Hi, im back again with questions regarding with collision mask system:
-is it correct that it is limited to 32 x 32 flags?
-how can i avoid that an agent is hit by his own bullet leaving his gun barrel (if i have more than 32 agents/objects)?


#561

“Solution” that i use is creating a bullet “couple of cm” in front of model/collision body. When you create bullet, first move it forward on y, and then attach physics body.


#562

Well thats the workaround im currently using. But i noticed that the turrets bound by a constraint seems to collide with the body as well which raises collisiontest amount dramatically without benefit. So a more sophisticated approach would save a lot performance in my case. I guess the most flexible approach would be the exposition of the collision callback but a C->Python call is very expensive. Maybe another 2d data storage than a matrix would be a solution.


#563

First, you are right, the bitmasks are 32-bit. I have choosen 32 bit because this is the length used by Panda3D’s CollisionMasks, and because longer masks would mean less performance on 32-bit computers.

A Python callback is of course the most flexible method, but it is also the slowest (by far).

Now, since I know that one size never fits all I have made it possible to extend the collision filter callbacks. In you config settings you choose which collision filter algorithm you want. Currently we have two algorithms implemented. I can easily add another one (or two).

But YOU have to specify how this algorithm should work. I will read you proposal, and check if it is possible to implement and what the impact on the existing code is.


#564

Im aware of two different approaches:

  1. replace the matrix/flag with a 2d list (list within a list). This is only senseful if the number of set flag is much lower than the possible “flags”.

  2. Add a “deny collision with” list to every body. But this implies some ugly object-object dependencies. But if Bullet uses IDs anyway one may use them to speficify the objects. But then one has to deal with the proper cleanup which will results mostlikely in a O(n^2) or a O(n*log n) algo.


#565

Hmm, I was expecting a bit more to work with. Anyway, let’s see.

I don’t get this one. A matrix is a list of lists. But this is not important. what matters is what you want to put into these lists/arrays/matrices.

I guess what you wanted to say is that collision filtering is not done based on masks or groups, but by explicitly specifying which objects collide with which other objects. This means we have to manage and store information wether or not a pair of objects should collide or not. Can be done in (at least) two ways:
(1) on the world we store pairs of objects which should collide.
(2) on each object we store which other objects should collide with the object.

Both are management nightmares when objects get removed or destroyed. However, do you want to pick up from here, maybe specify methods suited for management of the required data in both cases?


#566

Here is just one idea.

Make new filtering algorithm based on new one (collision groups). Add optional variable “tagId” or something like that, and if two nodes have same “tagId”, they do not collide.

Complicate it a bit more:
Add another bitmask to node, if two nodes have same “tagId” they will use that new bitmasks to check whether they should collide. If they have different “tagId” use “ordinary” collision filtering (symmetrical matrix from groups).

tagId would be some int that we provide or that you create from string.

enemy1:1
enemy4:2
player1:3
rudolph:4

so i would call .setCustomMagicTagName(“player1”)
for player capsule,weapon,ammo going out,each body part.
Then i would disable collision between body capsule(used for walking on terrain) and body parts and weapons (close combat or ranged, does not matter).
So player for example would not cut himself with sword , but would be able to hit enemies with same sword :slight_smile:

I used “tagId”, “groupId” is probably better name, but it could lead to some confusion regarding collision groups.

For almost all scenarios i could think of, special handling of collision is needed only for objects in one group. And with this approach you dont need to traverse array of deny objects
So basically its just one “if” on top of current group based system, and some extra stuff in memory.

I am aware of my problem with explaining things, so if you prefer i could write some python (others call it pseudo code :slight_smile: ) its rather simple system.

if obj1.tagId == obj2.tagId:
    #use "secondary" bitmasks of both objects
else:
    #use "normal" bitmasks for both objects

#567

Ok, thank you for your input. So far I have no idea where we will go in the end, and I really consider providing a Python callback now. Further ideas are always welcome.


#568

to idea 2 some pseudocode:
collisioncallback(bt_obj1,bt_obj2)
if bt_obj1 in bt_obj2.ignorecollisionwith or bt_obj2 in bt_obj1.ignorecollisionwith:
return
[…]

Assuming that bullet uses ids there would be no problem with cycle references but im not in the bullet internas.


#569

Just wanted to drop a note that I did not forget about you. I currently have a bunch of bullet source code files modified, because I try something, and would like to finish this and check in before I start working on something else.


#570

Ok, I added a third collision filtering algorithm: a Python callback function. This is probably the most flexible one, but also slower than the others.

In oder to have this collision filteirng algorithm installed you have to set the config variable

bullet-filter-algorithm python-callback

Setting the callback function is simple:

self.world.setPythonFilterCallback(self.filter)

The callback itself is called with two PandaNodes, and should return a bool value (True if the objects should collide, False otherwise):

def filter(self, node1, node2):
  ...
  return True

I updated the Bullet samples archive - a new sample for this collision filter algorithm is added.


#571

Using Panda Bullet, how can I set the CFM/ERP parameters of BulletConstraint()'s?

In C++ code

constraint->setParam(BT_CONSTRAINT_STOP_CFM, myCFMvalue, index)
constraint->setParam(BT_CONSTRAINT_STOP_ERP, myERPvalue, index)

How would one set those parameters in Panda Bullet? I looked at BulletConstraint’s API, as well as those who inherit from it (BulletHingeConstraint) and found no method to.

Thank you,
~powerpup118


#572

These parameters are not exposed so far. I have just added them.


#573

Thank you Enn0x, I really appreciate all of your work.

Thank you :smiley:

~powerpup118


#574

Hello,
I’ve tried to use an egg file as a map for a test, and … look at the screen shots:

The code i used for the map is:

	# Load the environment model.
		self.map = self.loader.loadModel("models/map")
		geom = self.map.findAllMatches('**/+GeomNode').getPath(0).node().getGeom(0)
		mesh = BulletTriangleMesh()
		mesh.addGeom(geom)
		shape = BulletTriangleMeshShape(mesh, dynamic=False)
		body = BulletRigidBodyNode('map')
		bodyNP = self.worldNP.attachNewNode(body)
		bodyNP.node().addShape(shape)
		bodyNP.setCollideMask(BitMask32.allOn())
		self.world.attachRigidBody(bodyNP.node())
		self.map.reparentTo(bodyNP)

Where is the problem ? Blender 2.63 don’t export (with Yabee) the blend file, but with export directx and x2egg, i can use it with panda. But is it possible that there is a problem with the geom ?

Here is the blend and egg files : http://www.benicourt.com/bullet/models.rar


#575

The problem ist that the geom you pick from the loaded model has a transform, which you not regard when creating the collision mesh:

...
<Group> Root {
  <Transform> {
    <Matrix4> {
      1 0 0 0
      0 0 1 0
      0 1 0 0
      0 0 0 1
    }
  }
  <Group> Root1 {
...

Good luck that you .egg file only contains one geom, because you only regard the very first geom found inside the .egg file.

This is a more complete ways of creating collision meshes from models:

    np = loader.loadModel('map.egg')
    mesh = BulletTriangleMesh()
    for geomNP in np.findAllMatches('**/+GeomNode'):
      geomNode = geomNP.node()
      ts = geomNP.getTransform(np)
      for geom in geomNode.getGeoms():
        mesh.addGeom(geom, ts)
    shape = BulletTriangleMeshShape(mesh, False)
    ...

Anyway, it might be very convenient to simply create collision meshes from visible models. And Bullet and PhysX can do collision detection with triangle meshes quite fast, but I still recommend using simplified meshes for collisions.


#576

@ enn0x, thank you very much, i’ve modified the egg file, only the transformation matrix, and it’s good. In the panda manual, i’ve read that the model must not have a scale transformation, not a rotation… now, i know.
I’ve noticed also the code if there is more than one geom. Thank you again.


#577

I tried to compile a c++ panda program wishing to use bullet.

I get

1>C:\Panda3D-1.8.0\include\bullet_includes.h(20): catastrophic error: cannot open source file "btBulletDynamicsCommon.h"
1>  #include "btBulletDynamicsCommon.h"

So what are the bullet include files needed for use in a c++ panda app, and where are they located. Grazie.

Another concern: I tried to compile a complete Panda3D version including the latest Bullet svn (2.8?) (from bullet svn repository).
Here is what I get.

Zonzagolo