Page 1 of 1

Collision only (no dynamics/kinematics)?

Posted: Tue Feb 19, 2013 12:49 am
by seeplusplus
Hi all,

I'm trying to implement simple collision detection using Bullet, where the world contains static objects, and the collision query is also a static object. I'm very new to using physics engines, so I'm not well versed on the terminologies and techniques of such engines. I do have a working demo using Bullet, however I'd like to know if I'm doing it correctly, and also if there is a better way to go about it. Apologies if this has been covered before; I tried following the wiki and the demos to get to my current situation.

This is what I have so far:
1) The world is a btCollisionWorld with a btAxisSweep3 broadphase and a btDefaultCollisionConfiguration
2) New btCollisionObjects that are added to the world AS WELL AS the collision query btCollisionObject are either:
- btBoxShape
- btGImpactMeshShape (This represents a bag of triangles. I tried using btBvhTriangleMeshShape, but apparently btBvhTriangleMeshShape vs. btBvhTriangleMeshShape does not work. I followed the advice in this thread: http://code.google.com/p/bullet/issues/detail?id=682)
3) btGImpactCollisionAlgorithm::registerAlgorithm(dispatcher); - so that GImpact shapes worked
4) All btCollisionObjects are set to btCollisionObject::CF_STATIC_OBJECT
5) Collision querying is done using a btCollisionWorld::ContactResultCallback

I don't perform any explicit ticking/processing of the world. What I listed is *it*.

Also regarding the btCollisionWorld::ContactResultCallback's addSingleResult callback, I have the following questions:
1) What exactly does the return value do?
2) Why would there be a pair if btManifoldPoint::getDistance() > 0? I am under the assumption that a value < 0 means that there is overlap, thus a collision.
3) Is colObj0Wrap always the collision query btCollisionObject? It seems that way so far..

All I really care (currently) is whether the collision query is colliding with other objects in the world, not the collision points. Is there an easier method, or am I expected to use btCollisionWorld::ContactResultCallback?

When building a contiguous path and adding each piece to the btCollisionWorld, I noticed that right after I add a btCollisionObject (GImpact shape) for a new piece and test against a new query, the previous btCollisionObject added is returned in addition to the new one - even though logically only the new piece's btCollisionObject should be returned via the btCollisionWorld::ContactResultCallback. (The collision query is a ghost object that is connected to the end of the last piece of the path). But this anomaly only shows up in the query right after the addition, but subsequent queries return the expected values - just the new btCollisionObject that was added. I don't understand what's happening here.. The only thing I can theorize is that I am not updating the collision pairs in the world right after the addition. If so, what exactly do I need to call to update the world?

Thanks in advance.

Re: Collision only (no dynamics/kinematics)?

Posted: Tue Feb 19, 2013 7:25 pm
by MaxDZ8
About btCollisionWorld::ContactResultCallback::addSingleResult
  1. What exactly does the return value do?
  2. Why would there be a pair if btManifoldPoint::getDistance() > 0? I am under the assumption that a value < 0 means that there is overlap, thus a collision.
  3. Is colObj0Wrap always the collision query btCollisionObject? It seems that way so far..
  1. Believe it or not, sometimes it's just dropped (btCollisionWorld.cpp:323, 618, 713 1106 appears extremely important). There are other places in which it is used in a way I cannot fully understand in a few minutes (mainly dealing with triangle shapes). The wiki page notes: "not actually sure if return value is used for anything". I recall reading a note saying it was supposed to cut off computation... if .0 is returned? Or perhaps it was 1.0? I'm sorry. I don't remember. I'm inclined to think it used to be important but somehow lost its status.
  2. It's a bit more complicated. First: manifolds will be created if two objects cannot be rejected by broadphase, which means they might collide. Two objects can collide with distance >0 or <0, depending whatever you're looking at A->B collision or B->A. Manifolds are generated anyway because they help with stability and (I think I've read somewhere) performance as well.
  3. I'm not sure I understand your english here. In the previous bullet version, the callbacks got btCollisionObject directly.
As far as I understand, you're supposed to call performDiscreteCollisionDetection(). I'm surprised it actually works without ticking!

Re: Collision only (no dynamics/kinematics)?

Posted: Wed Feb 20, 2013 2:11 am
by seeplusplus
Thanks for the reply!
Is colObj0Wrap always the collision query btCollisionObject? It seems that way so far..
What I meant: Does the colObj0Wrap parameter in the callback always represent the collision query object? I have yet to not see it to be the case.

Adding performDiscreteCollisionDetection() after adding/removing objects from the world doesn't seem to make any difference (the long-winded problem I mentioned is still there). Am I supposed to call it continuously? I was under the assumption that since there is no dynamics/kinematics then ticking the world won't have any effect..

While I'm here, I also noticed that a btGImpactMeshShape with very long triangles seem to produce unexpected collision results - as if the collision boundary is bigger than the shape itself. I had to break the long triangles in to smaller segments for it to work correctly. I'm not sure if this is expected or if this a potential bug.

Re: Collision only (no dynamics/kinematics)?

Posted: Wed Feb 20, 2013 7:20 am
by MaxDZ8
seeplusplus wrote:What I meant: Does the colObj0Wrap parameter in the callback always represent the collision query object? I have yet to not see it to be the case.
Yes, I observed the same. It clearly makes some sense after all.
seeplusplus wrote:Adding performDiscreteCollisionDetection() after adding/removing objects from the world doesn't seem to make any difference (the long-winded problem I mentioned is still there). Am I supposed to call it continuously? I was under the assumption that since there is no dynamics/kinematics then ticking the world won't have any effect..
This is incorrect, it is still necessary to update collision manifolds. Which admittedly is only useful if you change something in state.
So let me understand: the query with the collision object returns 1 hit on first poll, 2 on second and so on.
Or perhaps the object just keeps growing its pool? If that's the case then this won't work. I'm surprised however it starts to work as expected "after a while". If you can share some code maybe I'll take a look at it.
seeplusplus wrote:While I'm here, I also noticed that a btGImpactMeshShape with very long triangles seem to produce unexpected collision results - as if the collision boundary is bigger than the shape itself. I had to break the long triangles in to smaller segments for it to work correctly. I'm not sure if this is expected or if this a potential bug.
Very elongated triangles have a ton of issues in general, I'm not surprised they screw up, they have been historically a source of constant trouble! If the GIMPACT team dealt with them this way, I'm afraid you'll have to bite the bullet (pun not intended).