Panda Bullet

Return to Panda Features in Development

Postby enn0x » Tue Jan 17, 2012 7:23 am

powerpup118 wrote:Problem I ran into was that BulletWorld.contactTest(..) returns 'const' bodies? and so when trying to remove the body, I get the following error:

Code: Select all
TypeError: BulletWorld.remove_rigid_body() argument 1 may not be const


Or how else can I remove/add the body? I found a small workaround, by searching the scene graph for a node with a name of the body's name (bodyNode.getName()) however this only works if each bodyNode has a unique name, any other way to work around this?

This is the underlying Bullet callback method which gets called when performing a contact test:
Code: Select all
virtual btScalar btCollisionWorld::ContactResultCallback::addSingleResult(
    btManifoldPoint &cp,
    const btCollisionObject *colObj0,
    int partId0,
    int index0,
    const btCollisionObject *colObj1,
    int partId1,
    int index1)

Both collision objects are CONST pointers. This means that the collision objects can not be modified within this method. What I do in BulletContactResult is simply store these const pointers and return the associated Panda3D objects (i. e. BulletRigidBody), as CONST pointers.

Usually there is a reason why an API designer passes or returns const pointers or objects. Since Bullet documentation is a bit spares I can only guess why the Bullet API passes a const pointer here: because it will lead some kind of crash if a user modifies the collision objects from within the callback.

But enough of an explanation - what can be done?

(1) Your solution is probably the best way to go. Identify somehow the panda node within the scene graph, and use this node remove/add it from the world. You can do this either by giving each node a unique name, like you mentioned. Or you can set identifying ids on each node (via setPythonTag) and look up the node in a local dictionary. Maybe you are able to do some magic using NodePath's.

(2) I could try to cast away the const-ness of the Bullet collision object, and then have you test what happens if you modify the returned node. But it is usually not a good idea to cast away const-ness. I'd prefer not to do so.
enn0x
 
Posts: 1386
Joined: Wed Nov 08, 2006 1:39 am
Location: Germany, Munich

Postby enn0x » Tue Jan 17, 2012 4:17 pm

I removed the const-ness of the nodes returned by BulletContactResult.getNode0 and BulletContactResult.getNode1. So far I did not experience any crash or other problem.
enn0x
 
Posts: 1386
Joined: Wed Nov 08, 2006 1:39 am
Location: Germany, Munich

Postby enn0x » Tue Jan 17, 2012 4:20 pm

In order to fix the bug https://bugs.launchpad.net/panda3d/+bug/916732 I have renamed the following two methods:
Code: Select all
BulletCharacterController.setLinearVelocity --> setLinearMovement
BulletCharacterController.setAngularVelocity --> setAngularMovement
enn0x
 
Posts: 1386
Joined: Wed Nov 08, 2006 1:39 am
Location: Germany, Munich

Re: eliminate bulletContact

Postby yedpodtrzitko » Thu Jan 19, 2012 5:15 am

enn0x wrote:Hello, and welcome.
I'm afraid there is very little you can do. The Panda3D Bullet module just exposes the "original" Bullet character controller - it does not implement it's own character controller. And the original character controller which comes with Bullet is quite incomplete. In particular the interaction between the character and other collision objects is not implemented. The lack of this feature is what you experience. The physics engine detects an overlap of two objects and just pushes them away from each other, without regard of mass or other physical properties. We do mention this lack of features in the Panda3D manual already: http://www.panda3d.org/manual/index.php/Bullet_Character_Controller

What we would need to do is to write our own, better character controller. This is quite a lot of work, and so far I don't feel able to approach this task. A second aproach would be to find some reference implementation of a better character controller (based on Bullet) within some other open source engine, and adapt it to our Bullet wrappers.

Right now you hit a limitation of the Panda3D Bullet module. Sorry. Any ideas are welcome.



Hi, thanks for your response. After all I solved it by using BulletRigidNode with a few extra constrainst instead of using BulletCharacterController. Character doesn't bounce away after collision, but only slides on sufrace as I wish: https://www.youtube.com/watch?v=3kAKeF2TltQ
yedpodtrzitko
 
Posts: 2
Joined: Mon Jan 16, 2012 6:14 pm
Location: Prague, Czech republic

Postby Vincent22 » Thu Jan 26, 2012 3:15 pm

Hi, I'm using Bullet to create collision polygon and check collisions in my simple application.

How can I handle collisions? Can I use Panda Collision Handler and Traverser to check collisions among Bullet collision shapes?
There's a Bullet method to catch collision events (similar to Panda's CollisionHandlerEvent)? The only method I've found at this time is contactTest
thank you
Vincent22
 
Posts: 14
Joined: Mon Apr 04, 2011 5:03 am

Postby enn0x » Fri Jan 27, 2012 3:48 pm

What do you mean when you say "handling"?

If you mean to get events whenever collisions are detected, then yes, this is possible. Or you can explicitly test for contacts (contactTest). It you want to modify the contact properties then no, this is not exposed.

To get contact notification events you first have to enable this feature via a config option, e. g. like this
Code: Select all
from pandac.PandaModules import loadPrcFileData
loadPrcFileData('', 'bullet-enable-contact-events true')

Then you have to activate the creation of contact events for particular nodes, and you have to listen for the created events:
Code: Select all
    self.accept('bullet-contact-added', self.onContactAdded)
    self.accept('bullet-contact-destroyed', self.onContactDestroyed)

    boxNP.node().notifyCollisions(True)

The methods which get called must have this signature:
Code: Select all
def onContactAdded(self, node1, node2):
enn0x
 
Posts: 1386
Joined: Wed Nov 08, 2006 1:39 am
Location: Germany, Munich

Postby powerpup118 » Thu Feb 09, 2012 10:08 pm

Hi Enn0x,

I have a question in general about Bullet, and thought perhaps you would know the answer (or at least be able to share your knowledge)

is Bullet physics predictable? Or does Bullet use random numbers somewhere?

Example: If I set up a scene with boulders falling off a hill, and I ran that at the same exact point in time, on one thousand different computers, would the boulders fall exactly the same way, assuming that they started at the same time?

Would I need to pass specific parameters into BulletWorld.doPhysics(), in that case?

I only ask as I am interested in using Bullet physics are artificial intelligence (monsters 'running' towards players etc) and having all monsters synced across every client using a timestamp, for instance.

if you could shed any knowledge on this,

Thank you,
~powerpup118
User avatar
powerpup118
 
Posts: 325
Joined: Sat Apr 17, 2010 11:59 pm

Postby enn0x » Fri Feb 10, 2012 3:58 am

powerpup118 wrote:is Bullet physics predictable? Or does Bullet use random numbers somewhere?

I am not aware of any random numbers used within the Bullet source code. But I can not tell for sure, since I just *use* the Bullet library and don't know it's sources by heart. So yes, Bullet can be deterministic.

Here are a few tips to get as much determinism as possible (not specific to Bullet, but any physics engine we support):
1.) The biggest problem with determinism is that you have to completely decouple the physics simulation from the game loop.
2.) Fixed timesteps are mandatory for determinism!
3.) Never use the computers time - not even if you have a secure time server (e.g. IEEE 1588 Precise Time Protocol) in your network. In other words: feed only constants to BulletWorld.doPhysics, and never variables.
4.) Don't sync between clients using a timestamp - use the integral count of the simulation frame.

All the samples I have written so far do not care about determinism or decoupling physics from framerate. I even do not bother to some time slip because of user input handling. It's probably a question of how much determinism you really need.
enn0x
 
Posts: 1386
Joined: Wed Nov 08, 2006 1:39 am
Location: Germany, Munich

Postby powerpup118 » Fri Feb 10, 2012 3:31 pm

enn0x wrote:Here are a few tips to get as much determinism as possible (not specific to Bullet, but any physics engine we support):
1.) The biggest problem with determinism is that you have to completely decouple the physics simulation from the game loop.
2.) Fixed timesteps are mandatory for determinism!
3.) Never use the computers time - not even if you have a secure time server (e.g. IEEE 1588 Precise Time Protocol) in your network. In other words: feed only constants to BulletWorld.doPhysics, and never variables.
4.) Don't sync between clients using a timestamp - use the integral count of the simulation frame.

All the samples I have written so far do not care about determinism or decoupling physics from framerate. I even do not bother to some time slip because of user input handling. It's probably a question of how much determinism you really need.


This is great news to me!

I knew about all of your points (decouple the physics simulation from the game loop... fixed timesteps.. no using computer's time..)

Very good idea about using integral count of the simulation frames vs a timestamp, I would have never thought of that.

Thank you again,
~powerpup118

P.S. will try to get a sample going at some point in case anyone else is interested in the same idea
User avatar
powerpup118
 
Posts: 325
Joined: Sat Apr 17, 2010 11:59 pm

Postby red15 » Mon Feb 13, 2012 6:43 am

Hi,

I'm having issues with the bullet implementation, when my physics driven object gets around 15000 units away from the origin point the object starts to jitter. It seems as if it's some sort of floating point precision issue.

My question is, is the build of bullet in panda a double precision build or is there any other way you know I could handle these large worlds ?

I've tried making sure no other bullet enabled objects is further than ~4k units in order to try to minimize the floating point "stretching" but it seems to have no effect.

I'd rather not try to move the bullet world origin because I think this would create a lot of messy situations that are hard to debug.

I've heard plenty of good things where scaling the bulletworld and it's occupants can solve plenty of issues. http://bulletphysics.org/mediawiki-1.5. ... _The_World
But would this also imply you cannot make an "infinite" world within bullet ?

Regards
Red15
red15
 
Posts: 8
Joined: Thu Dec 22, 2011 7:13 am

Postby enn0x » Mon Feb 13, 2012 9:36 am

red15 wrote:My question is, is the build of bullet in panda a double precision build or is there any other way you know I could handle these large worlds ?

The default build settings are - afaik - single precision. You can compile with double precision too, but you have to compile both Bullet AND Panda3D wird double precision.

red15 wrote:But would this also imply you cannot make an "infinite" world within bullet ?

Infinite is a tricky word when dealing with computers. If a floating point value is to be kept in on CPU register then there is a limit for it's size. On the other hand, when using arbitrary size/precision numbers performance drops to inaceptable values. In other words: out of the box no physics engine supports infinite worlds. By the way: infinite worlds also imply infinite objects! If the number of objects is finite then the size is also finite.

Even more problematic than huge scales are huge differences is size, i. e. very small objects and very large objects in one scene. You should keep rations below a few decades, or you will become unstable results.

I don't know a real scenario where you need an infinite world. If you have large objects at large distances you could use another scale: maybe 1000 meter per unit, or 1 lightyear if you want (default is 1 meter per unit).

If you can't scale your world then think about particioning your universe. Attach only those objects to a particion which CAN interact with eachother. If you have a starship fighting in the asteriod belt of one solar system then obviously the next solar system is of no importance.

Besides this non-Bullet specific advide you should have a look at the config variables "bullet-broadphase-algorithm" and "bullet-sap-extents".
enn0x
 
Posts: 1386
Joined: Wed Nov 08, 2006 1:39 am
Location: Germany, Munich

Postby red15 » Tue Feb 14, 2012 7:35 am

enn0x wrote:The default build settings are - afaik - single precision. You can compile with double precision too, but you have to compile both Bullet AND Panda3D wird double precision.


Is there a specific reason only single precision is chosen for panda / bullet compilation ? Does it yield more performance or less memory usage when using only single precision?

enn0x wrote:Even more problematic than huge scales are huge differences is size, i. e. very small objects and very large objects in one scene. You should keep rations below a few decades, or you will become unstable results.


This I understand, apparently bullet by default works best with objects scaled from 0.05 to 100,

enn0x wrote:I don't know a real scenario where you need an infinite world. If you have large objects at large distances you could use another scale: maybe 1000 meter per unit, or 1 lightyear if you want (default is 1 meter per unit).


The problem with scaling my world up is that it makes me scale the moving objects to ridiculously small scales, for example 1 object is about 3m³ on my current scale of 1 unit = 1m, scaling the unit to say 1 lightyear would make my object something along the scale of 3.0e-100 which would bring again the floating point precision problem back.

enn0x wrote:If you can't scale your world then think about particioning your universe. Attach only those objects to a particion which CAN interact with eachother. If you have a starship fighting in the asteriod belt of one solar system then obviously the next solar system is of no importance.


So this means I could make a different world "partition" per sector ? Would there be problems when these worlds would "overlap" and thus objects could be attached to 2 (similar) worlds when transitioning from one world to another ?

enn0x wrote:Besides this non-Bullet specific advide you should have a look at the config variables "bullet-broadphase-algorithm" and "bullet-sap-extents".


Thanks for your swift reply and accurate assessment of my problem.
red15
 
Posts: 8
Joined: Thu Dec 22, 2011 7:13 am

Postby enn0x » Wed Feb 15, 2012 11:46 am

red15 wrote:Is there a specific reason only single precision is chosen for panda / bullet compilation ? Does it yield more performance or less memory usage when using only single precision?

Both, better performance (in most cases) and less memory. Also consider that the transforms passed to Bullet come from Panda3D nodes and Panda3D is compiled with single precision by default. It does not make sense to have double precision computation for physics if all input is delivered in single precision.
-> Default is single precision Panda3D and single precision physics
-> If you need you can compile yourself and SETUP both Panda3D and Bullet for double precision.

red15 wrote:The problem with scaling my world up is that it makes me scale the moving objects to ridiculously small scales, for example 1 object is about 3m³ on my current scale of 1 unit = 1m, scaling the unit to say 1 lightyear would make my object something along the scale of 3.0e-100 which would bring again the floating point precision problem back.

Huh? As far as I know one lightyear is 10e11 meters and not 10e100. Anyway, I didn't say you should scale to 1 unit = 1 ly. I said you should choose a reasonable scale, which depends on the sizeof your objects AND the spacing between your objects.

I don't think you have 3 meter large objects which are separated by 1 lightyear. Consider that at a distance of 100 km your 3-meter-object would be less than one pixel on your screen. 3D graphics simply don't make sense at such scales.

So please disclose how large your objects are and what the distances between your objects are.

red15 wrote:So this means I could make a different world "partition" per sector ? Would there be problems when these worlds would "overlap" and thus objects could be attached to 2 (similar) worlds when transitioning from one world to another ?

I think there is a bit of a misunderstanding here. sure, you can have multiple worlds at the same time, and these worlds can overlap. But there won't be interaction BETWEEN the worlds, i. e. objects from one world colliding with objects of another world.
Sidenote: PhysX offer such a feature.

What I meant is to divid your universe into smaller areas, and do physics simulation only for the local area. When moving on to another area stop simulating the first area and continue with the next area. There can be overlap between areas, of course. The main difficulty is to write a manager which activates/deactivates areas.

It's up to you if you use one BulletWorld instance for each area, or re-use a single BulletWord instance.
enn0x
 
Posts: 1386
Joined: Wed Nov 08, 2006 1:39 am
Location: Germany, Munich

Postby red15 » Wed Feb 15, 2012 12:35 pm

enn0x wrote:I don't think you have 3 meter large objects which are separated by 1 lightyear. Consider that at a distance of 100 km your 3-meter-object would be less than one pixel on your screen. 3D graphics simply don't make sense at such scales.


I'm planning on using the bullet engine not only for graphics but for a dedicated server which will need to simulate all active areas so

enn0x wrote:So please disclose how large your objects are and what the distances between your objects are.


It is the worst case scenario, I will have human size objects to building size objects seperated maximally by some 2 ** 32 units

enn0x wrote:I think there is a bit of a misunderstanding here. sure, you can have multiple worlds at the same time, and these worlds can overlap. But there won't be interaction BETWEEN the worlds, i. e. objects from one world colliding with objects of another world.


Not even if an object is attached to both worlds ?

enn0x wrote:What I meant is to divid your universe into smaller areas, and do physics simulation only for the local area. When moving on to another area stop simulating the first area and continue with the next area. There can be overlap between areas, of course. The main difficulty is to write a manager which activates/deactivates areas.


I have tried removing all objects from the BulletWorld instance (except my player) but when my player goes beyond that ~15.000 unit mark the shaking still happens, would that mean I would have to 'recenter' the bullet world to avoid having big numbers ?

This would cause serious trouble if I was to try to implement the different worlds which overlap because they would all have to become centered around 0.0 and thus an object would be at 0,0,-1000 in the old zone while in the new zone it would be at 0,0,1000

Again this would only be on the server side which needs to do validation of all players / objects moving around (client side I guess I could cheat a bit more with only having one BulletWorld etc)
red15
 
Posts: 8
Joined: Thu Dec 22, 2011 7:13 am

Postby enn0x » Wed Feb 15, 2012 5:10 pm

red15 wrote:It is the worst case scenario, I will have human size objects to building size objects seperated maximally by some 2 ** 32 units

Since you didn't tell me how many units a "human" is I am going to assume that a human is 2 units tall. In other words, 1 unit is 1 meter.

Now come on, 2**32 meters (=4294967296) is 700 times the radius of our planet. And this is just one dimension of extent! Assuming your world has not much z-extent you have an area of 18446741531089 square kilometers!

Even if you have only one collision primitive or triangles per square kilometer you won't find a server which has enough memory to hold all these objects, let alone CPU power.

red15 wrote:Not even if an object is attached to both worlds ?

No. I don't know what would happen if you do so, but most likely nothing useful. One object should be part of only one world.

red15 wrote:I have tried removing all objects from the BulletWorld instance (except my player) but when my player goes beyond that ~15.000 unit mark the shaking still happens, would that mean I would have to 'recenter' the bullet world to avoid having big numbers ?

This is strange. I modified both my basic and my character sample in such a way that the objects are located around (17000, 0, 0), and I get no shaking at all. Can you post a working sample which reproduces your problem?
enn0x
 
Posts: 1386
Joined: Wed Nov 08, 2006 1:39 am
Location: Germany, Munich

Postby red15 » Thu Feb 16, 2012 9:33 am

enn0x wrote:Since you didn't tell me how many units a "human" is I am going to assume that a human is 2 units tall. In other words, 1 unit is 1 meter.


Correct

enn0x wrote:Now come on, 2**32 meters (=4294967296) is 700 times the radius of our planet. And this is just one dimension of extent! Assuming your world has not much z-extent you have an area of 18446741531089 square kilometers!


Actually the world would be (2**32) ** 3 in size but will not contain an awful lot (space is mostly empty you know :)

However it does contain some stuff and when users are zipping through this massive space at a relative high speed I would still like to have correct collision handling. I'm not expecting the user to cover more than 1000m (or units) per second though so this is why I'd like my world to be roughly 2000-3000 units across to make sure they at least "enter" a world instead of zipping over it without "landing" in one of the intermediate worlds.

enn0x wrote:Even if you have only one collision primitive or triangles per square kilometer you won't find a server which has enough memory to hold all these objects, let alone CPU power.


Not every zone has to be activated at the same time, only if players are near the zone in question, similar like minecraft chunks for instance.

enn0x wrote:No. I don't know what would happen if you do so, but most likely nothing useful. One object should be part of only one world.


So you would suggest creating an intermediate world in between 2 worlds which would contain the transitioning objects ? This seems rather counter-productive, means even more worlds in memory: 3 worlds for one object transitioning from world A to world B in zone AB_transition or something.

I would rather attach the object to both worlds and as long as nothing is hindering it's path it will be a smooth ride. I will try writing a small proof of concept soon.

enn0x wrote:This is strange. I modified both my basic and my character sample in such a way that the objects are located around (17000, 0, 0), and I get no shaking at all. Can you post a working sample which reproduces your problem?


Will combine this with my effort of transitioning worlds concept.

Again enn0x, thanks for all the time you've put into reading/answering my posts. If you're ever in Belgium stop by and let me at least get you a beer or something :)
red15
 
Posts: 8
Joined: Thu Dec 22, 2011 7:13 am

Postby red15 » Fri Feb 24, 2012 5:20 am

First of all enn0x: congrats on 1000 posts :)

Secondly, I've upgrade to 1.8.0 release and have found a bug, I've been able to confirm that it happens on ubuntu 64 bit but not on Windows platform.

The problem occurs when I attempt to do following (simplified) code:

Code: Select all
world = BulletWorld()
body = BulletRigidBodyNode()
world.attachRigidBody(body)

body.set_mass( 100 )
body.set_angular_damping(0)
body.set_linear_damping(0)

mesh = BulletTriangleMesh()
mesh.addGeom(...)
body.add_shape( BulletTriangleMeshShape(mesh, dynamic=True) )

def update():
   """ Gets called after each doPhysics call """
   contacts = world.contactTest(body).getContacts()
   for contact in contacts:
      mpt = contact.get_manifold_point()
      collide(mpt)

def collide(manifoldpoint):
   print("collide", manifoldpoint)
   impact_force = manifoldpoint.get_applied_impulse()
   print("impact_force:", impact_force)


The error occurs in the call manifoldpoint.get_applied_impulse() it just segfaults out. Ofcourse this only happens when a contact was happening with this body and it does not seem to crash at the first touch either, the print statements get called a few dozen times usually before it crashes.
red15
 
Posts: 8
Joined: Thu Dec 22, 2011 7:13 am

Postby enn0x » Sun Feb 26, 2012 4:53 pm

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:
Code: Select all
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
enn0x
 
Posts: 1386
Joined: Wed Nov 08, 2006 1:39 am
Location: Germany, Munich

Postby enn0x » Mon Feb 27, 2012 5:52 pm

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<BulletContact> by a btAlignedObjectArray<BulletContact>. Well, let's see if this fixed the Linux crashes.
enn0x
 
Posts: 1386
Joined: Wed Nov 08, 2006 1:39 am
Location: Germany, Munich

Postby Nox_firegalaxy » Fri Mar 02, 2012 7:39 am

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)?
Nox_firegalaxy
 
Posts: 120
Joined: Wed Jun 23, 2010 2:16 pm

Postby GrizzLyCRO » Fri Mar 02, 2012 6:39 pm

Nox_firegalaxy wrote: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)?


"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.
User avatar
GrizzLyCRO
 
Posts: 301
Joined: Tue Dec 16, 2008 4:03 pm
Location: Croatia

Postby Nox_firegalaxy » Sat Mar 03, 2012 9:31 am

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.
Nox_firegalaxy
 
Posts: 120
Joined: Wed Jun 23, 2010 2:16 pm

Postby enn0x » Sat Mar 03, 2012 5:43 pm

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.
enn0x
 
Posts: 1386
Joined: Wed Nov 08, 2006 1:39 am
Location: Germany, Munich

Postby Nox_firegalaxy » Mon Mar 05, 2012 7:29 am

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.
Nox_firegalaxy
 
Posts: 120
Joined: Wed Jun 23, 2010 2:16 pm

Postby enn0x » Wed Mar 07, 2012 7:00 am

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

Nox_firegalaxy wrote: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".

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.

Nox_firegalaxy wrote: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.

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?
enn0x
 
Posts: 1386
Joined: Wed Nov 08, 2006 1:39 am
Location: Germany, Munich

Postby GrizzLyCRO » Wed Mar 07, 2012 5:12 pm

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.

Code: Select all
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 :)

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 :) ) its rather simple system.

Code: Select all
if obj1.tagId == obj2.tagId:
    #use "secondary" bitmasks of both objects
else:
    #use "normal" bitmasks for both objects
User avatar
GrizzLyCRO
 
Posts: 301
Joined: Tue Dec 16, 2008 4:03 pm
Location: Croatia

Postby enn0x » Sat Mar 10, 2012 1:12 pm

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.
enn0x
 
Posts: 1386
Joined: Wed Nov 08, 2006 1:39 am
Location: Germany, Munich

Postby Nox_firegalaxy » Sun Mar 11, 2012 11:59 am

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.
Nox_firegalaxy
 
Posts: 120
Joined: Wed Jun 23, 2010 2:16 pm

Postby enn0x » Thu Mar 15, 2012 4:25 pm

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.
enn0x
 
Posts: 1386
Joined: Wed Nov 08, 2006 1:39 am
Location: Germany, Munich

Postby enn0x » Mon Mar 26, 2012 3:25 pm

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
Code: Select all
bullet-filter-algorithm python-callback


Setting the callback function is simple:
Code: Select all
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):
Code: Select all
def filter(self, node1, node2):
  ...
  return True


I updated the Bullet samples archive - a new sample for this collision filter algorithm is added.
enn0x
 
Posts: 1386
Joined: Wed Nov 08, 2006 1:39 am
Location: Germany, Munich

PreviousNext

Return to Panda Features in Development

Who is online

Users browsing this forum: No registered users and 0 guests

cron