New issue with gContactAddedCallback in Bullet 2.75

User avatar
Erwin Coumans
Site Admin
Posts: 4183
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: New issue with gContactAddedCallback in Bullet 2.75

Post by Erwin Coumans » Sun Dec 13, 2009 2:49 pm

sparkprime wrote:I thought it was the other way round. In fact, why is there two params in the first place?
There are two shape identifiers (params) because triangle meshes can have multiple mesh parts, and triangles are indexed within each part. This allows to store multiple disconnected meshes (possibly with different memory layout/striding) to be combined in a single btBvhTriangleMeshShape.

So for triangle meshes, the partID refers to the part/submesh, and indexId to the triangle (within that part/submesh). For compound shapes, we used the index to identify the child shapes.
See http://code.google.com/p/bullet/source/ ... hm.cpp#146

Cheers,
Erwin

sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York
Contact:

Re: New issue with gContactAddedCallback in Bullet 2.75

Post by sparkprime » Mon Dec 14, 2009 5:21 am

Ah seems I was just hopelessly confused then. Thanks for the clarification That has solved the problem but there is still a nasty case with gimpact vs compound where the compound gets -1 for both index and part.

User avatar
Erwin Coumans
Site Admin
Posts: 4183
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: New issue with gContactAddedCallback in Bullet 2.75

Post by Erwin Coumans » Mon Dec 14, 2009 5:02 pm

sparkprime wrote:there is still a nasty case with gimpact vs compound where the compound gets -1 for both index and part.
GImpact isn't well supported, you better move to using btCompoundShape for better performance and stability, or perhaps look into fixing it and provide a patch?

Just search for setShapeIdentifiers and try adding some conditionals around it in this file:
Bullet\src\BulletCollision\Gimpact\btGImpactCollisionAlgorithm.cpp

Thanks,
Erwin

sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York
Contact:

Re: New issue with gContactAddedCallback in Bullet 2.75

Post by sparkprime » Mon Dec 14, 2009 11:10 pm

OK I'll take a look

sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York
Contact:

Re: New issue with gContactAddedCallback in Bullet 2.75

Post by sparkprime » Mon Dec 21, 2009 5:00 pm

I had a read through the code and it seemed like the most logical thing to do was this:

Code: Select all

Index: BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp
===================================================================
--- BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp     (revision 1838)
+++ BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp     (working copy)
@@ -701,12 +701,16 @@
        int i = shape1->getNumChildShapes();
        while(i--)
        {
+               assert(i >= 0);
+               assert(i < shape1->getNumChildShapes());
 
                btCollisionShape * colshape1 = shape1->getChildShape(i);
                btTransform childtrans1 = orgtrans1*shape1->getChildTransform(i);
 
                body1->setWorldTransform(childtrans1);
 
+               (swapped ? m_triface0 : m_triface1) = i;
+
                //collide child shape
                gimpact_vs_shape(body0, body1,
                                          shape0,colshape1,swapped);
However I am guessing about the 'swapped' bit, I don't understand when and why they would need to be swapped. This works for me at least.

Note that first I tried using a reference to the appropriate triface var as the loop variable, but i found that gimpact_vs_shape would actually change it so that it would not decrement neatly each iteration. However using the separate var seems to work.

sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York
Contact:

Re: New issue with gContactAddedCallback in Bullet 2.75

Post by sparkprime » Tue Dec 29, 2009 1:20 am

OK I was cut off from the net for a while. I have read more of the code now and I understand most of what's going on.

What I have done though is started using this change in the same file (the members of btManifoldResult have to be public as well but that is a trivial change)

This allows a gimpact triangle mesh shape to be used inside a compound (only at 0,0,0 with unit orientation tested). Otherwise you get invalid indexes.

Code: Select all

@@ -838,16 +842,31 @@
 }


+template<class T> static void swap(T &a, T &b) { T tmp = a; a = b; b = tmp; }

 void btGImpactCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
 {
     clearCache();

     m_resultOut = resultOut;
+   m_triface0 = m_resultOut->m_index0;
+   m_part0 = m_resultOut->m_partId0;
+   m_triface1 = m_resultOut->m_index1;
+   m_part1 = m_resultOut->m_partId1;
    m_dispatchInfo = &dispatchInfo;
     btGImpactShapeInterface * gimpactshape0;
     btGImpactShapeInterface * gimpactshape1;

+    // if the gimpact shape is nested in a compound shape, we can be given a swapped body0 and body1
+    // so ensure this is not the case
+    if (m_resultOut->getBody0Internal() == body1)
+    {
+        swap(body0, body1);
+        swap(m_triface0, m_triface1);
+        swap(m_part0, m_part1);
+    }
+
+
    if (body0->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE)
    {
        gimpactshape0 = static_cast<btGImpactShapeInterface *>(body0->getCollisionShape());
@@ -868,6 +887,10 @@
    {
        gimpactshape1 = static_cast<btGImpactShapeInterface *>(body1->getCollisionShape());

+        // hack: swap the original values, they get swapped back again later
+        swap(m_triface0, m_triface1);
+        swap(m_part0, m_part1);
+
        gimpact_vs_shape(body1,body0,gimpactshape1,body0->getCollisionShape(),true);
    }
 }

edl
Posts: 16
Joined: Tue Jul 08, 2008 7:28 am

Re: New issue with gContactAddedCallback in Bullet 2.75

Post by edl » Mon Jan 04, 2010 5:52 am

i use Gimpact shape in my game too,and, after download the bullet-svn code,and combine all the code above, it seems still have some problem...
my compound shape structure is :
index 0 : Convex shape,1~5 :GImpact shape

when i collide my compound shape with a Gimpact shape / static BVh triangle Mesh, the btManifoldResult return a lot of strangle number.(it seems wrong)
but when i made all the child shape as Convex shape, btManifoldResult 's index value is between 0~5...(it seems right)

sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York
Contact:

Re: New issue with gContactAddedCallback in Bullet 2.75

Post by sparkprime » Mon Jan 04, 2010 5:13 pm

I haven't tested it with more than 1 gimpact shape per compound so that could be a problem. There is also another patch further up this thread (not from me) that I had to use but maybe Erwin applied it already.

I find this code very unmaintainable though, it was a hard slog to get it to work even for my use cases. Many times I made changes that seemed obvious but had unexpected side-effects in e.g. compound vs compound and compound vs static trimesh collisions. That's why I put it here instead of the issues tracker, in the hope of getting some discussion going.

It seems to me that all of this is far too complicated -- wouldn't Bullet work just as well if every rigid body simply had an array of shapes at various local transforms, all held in a bvh? Then there would be no need for the static triangle meshes and gimpact meshes and such -- the only midphase is the compound itself and all you need for triangle meshes is to have a lot of triangle primitives in the compound. Same goes for hulls and tetrahedra.

Of course you can do this already and everyone does. But having a compound inside another compound is pretty meaningless, and having one bvh-based structure inside a compound doesn't make much sense either. Especially when there is a transform involved. When you want to start dynamically changing the shape, and disabling children in order to open gaps or fracture, then it really starts to look messy.

I expect someone will try and claim that dynamic triangle meshes are unnecessary and a compound of hulls is always sufficient. But hulls are a pain in the art pipeline and automatic decomposition always produces very poor shapes that have tunneling and stability problems. At least with triangles you can use decent modelling software to build your meshes, with careful attention given to the size and position of every triangle. It's also very convenient to add solid shapes like boxes and spheres and even hulls to the mesh, to give a bit more depth or to allow a shape to roll.

ola
Posts: 169
Joined: Sun Jan 14, 2007 7:56 pm
Location: Norway
Contact:

Re: New issue with gContactAddedCallback in Bullet 2.75

Post by ola » Mon Jan 04, 2010 10:05 pm

But having a compound inside another compound is pretty meaningless
Just to comment on that, I sometimes find this quite useful. I use it when simulating objects where the centre of gravity moves. For example, an aircraft model using a compound of several convex hulls (wings, fuselage, etc). When updating the centre of gravity (due to fuel consumption, or dropping some payload), I can either then update each sub-shape, or just put the whole compound shape into another one, and move its transform.

Note that I have NOT done any benchmarks on which method is quicker in real life :-)

Cheers,
Ola

edit: forgot the "NOT" in the last sentence...

User avatar
Erwin Coumans
Site Admin
Posts: 4183
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: New issue with gContactAddedCallback in Bullet 2.75

Post by Erwin Coumans » Mon Jan 04, 2010 11:27 pm

my compound shape structure is :
index 0 : Convex shape,1~5 :GImpact shape
It is best to avoid adding triangle meshes (GIMPACT or btBvhTriangleMeshShape) as child to btCompoundShape. We should have prevented this in the first place, and only allow convex shapes or compound shapes as child shapes of a btCompoundShape.
sparkprime wrote:I haven't tested it with more than 1 gimpact shape per compound so that could be a problem. There is also another patch further up this thread (not from me) that I had to use but maybe Erwin applied it already.
Can you check latest svn trunk? If there is no issue in the google tracker it won't get fixed.
wouldn't Bullet work just as well if every rigid body simply had an array of shapes at various local transforms, all held in a bvh?
We'll take this into account as an option for Bullet 3.x, but I like the flexibility of Bullet 2.x.
It's also very convenient to add solid shapes like boxes and spheres and even hulls to the mesh, to give a bit more depth or to allow a shape to roll.
If it is convenient to add those solid shapes to the mesh, why can't you just get rid of the original mesh afterwards?

It seems the issues you are having is mainly because you are using GIMPACT, and GIMPACT has issues including a wrong index/part ID.
Can you help fixing the index/part ID issues with GIMPACT shapes?

Thanks,
Erwin

sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York
Contact:

Re: New issue with gContactAddedCallback in Bullet 2.75

Post by sparkprime » Tue Jan 05, 2010 2:25 am

ola wrote: Just to comment on that, I sometimes find this quite useful. I use it when simulating objects where the centre of gravity moves. For example, an aircraft model using a compound of several convex hulls (wings, fuselage, etc). When updating the centre of gravity (due to fuel consumption, or dropping some payload), I can either then update each sub-shape, or just put the whole compound shape into another one, and move its transform.
Being able to define groups of children and operate on those would be useful, but my instinct is telling me you want to concatenate those transforms (by flattening the tree) when the change is made, whereas by setting up a tree of compounds it will end up happening in every subsequent collision as the recursion proceeds. Graphics APIs sometimes have scenegraphs where there is a logical tree, but the actual transforms are always flattened and the result re-used. The tree only exists to make it easier for the programmer. The implementation has to keep the flattened version around for performance.

sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York
Contact:

Re: New issue with gContactAddedCallback in Bullet 2.75

Post by sparkprime » Tue Jan 05, 2010 2:34 am

Erwin Coumans wrote:
my compound shape structure is :
index 0 : Convex shape,1~5 :GImpact shape
It is best to avoid adding triangle meshes (GIMPACT or btBvhTriangleMeshShape) as child to btCompoundShape. We should have prevented this in the first place, and only allow convex shapes or compound shapes as child shapes of a btCompoundShape.
sparkprime wrote:I haven't tested it with more than 1 gimpact shape per compound so that could be a problem. There is also another patch further up this thread (not from me) that I had to use but maybe Erwin applied it already.
Can you check latest svn trunk? If there is no issue in the google tracker it won't get fixed.
Just checked, the other patch I referred to is indeed in svn now.

The rest are still work in progress.
wouldn't Bullet work just as well if every rigid body simply had an array of shapes at various local transforms, all held in a bvh?
We'll take this into account as an option for Bullet 3.x, but I like the flexibility of Bullet 2.x.
I'm not sure the flexibility provides any benefit though, and it certainly comes at a huge cost in terms of complexity. It might be better to allow a compound to efficiently contain a large number of triangles -- if this was as fast and as stable as gimpact then gimpact could be dropped.
It's also very convenient to add solid shapes like boxes and spheres and even hulls to the mesh, to give a bit more depth or to allow a shape to roll.
If it is convenient to add those solid shapes to the mesh, why can't you just get rid of the original mesh afterwards?
They don't replace the triangle mesh, they just augment it in a few key places. It's a dark art -- if there is some artifact in the collision behaviour of a shape, you first try playing with the triangles, and if that doesn't work, stick a big box or sphere there. GTA San Andreas used this extensively -- everything is a trimesh + set of spheres + set of boxes.
It seems the issues you are having is mainly because you are using GIMPACT, and GIMPACT has issues including a wrong index/part ID.
Can you help fixing the index/part ID issues with GIMPACT shapes?

Thanks,
Erwin
I fixed it enough for me, other than making those members public the changes are limited to the gimpact code. I'd like to hear more about the problems edl was having before anything gets committed though.

sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York
Contact:

Re: New issue with gContactAddedCallback in Bullet 2.75

Post by sparkprime » Tue Jan 05, 2010 2:38 am

edl: oh of course if you have more than one gimpact triangle mesh in a compound then there is no way to identify which one it is -- currently the part/index is for the mesh -- there is no way to get the index that defines the position of the gimpact shape within the compound. It's a hack, basically.

Can you not fuse the meshes?

edl
Posts: 16
Joined: Tue Jul 08, 2008 7:28 am

Re: New issue with gContactAddedCallback in Bullet 2.75

Post by edl » Tue Jan 05, 2010 3:31 am

sparkprime wrote:edl: oh of course if you have more than one gimpact triangle mesh in a compound then there is no way to identify which one it is -- currently the part/index is for the mesh -- there is no way to get the index that defines the position of the gimpact shape within the compound. It's a hack, basically.

Can you not fuse the meshes?
no, i can't fuse the meshes,my work is build a car ,then crash it,the car body is convex mesh(i don't kown why,when i use GImpact mash as my car body,the car act like a balloon,it flies~ :o ,i need some time to check why it act like that), and the door/engineCover and other components was build as Gimpact mash, In order to better fit the carbody,i think gimact mesh is better,but it .... :x have lots of problems...

for now,if this problems exist,my schedule don't have time to study and fix it this days(due to the post,it seems not easy...), i construct a list,contain the car components,and use btManifoldResult to get the car crash point and impulse(it seems that,btManifoldResult.m_appliedImpulse looks strange, this time i use m_distance1 instead,its very ugly.. :? ),then identify the child chape,and remove it from compound.

i use convex as child shape before,and it works right,but ,when remove it from compound,it is not stable(i think it is not fit the car body shape).

my options now
1. use gimpact mesh,and build a shape list to identify it myself
2. re-mesh my car, and use convex mesh,(but it will seems ugly)
3. fix the bug....(God help me... :roll: )

any idea to help me?
Attachments
10.210.8.79_20100104_160609.jpg
10.210.8.79_20100104_160609.jpg (93.85 KiB) Viewed 3220 times

User avatar
Erwin Coumans
Site Admin
Posts: 4183
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: New issue with gContactAddedCallback in Bullet 2.75

Post by Erwin Coumans » Tue Jan 05, 2010 4:02 am

sparkprime wrote:The implementation has to keep the flattened version around for performance.
The matrix multiple is not likely a performance bottleneck, unless there are other issues.
I'm not sure the flexibility provides any benefit though, and it certainly comes at a huge cost in terms of complexity
The flexibility of Bullet's collision detection is important as a general purpose library for games and movie special effects. I don't agree that its complexity is 'huge' at all.

Just avoid GIMPACT and use convex shapes only as child shapes in a btCompoundShape. The btCompoundShape dynamic AABB tree acceleration structure, btDbvt, is fast enough to allow adding, changing and removing child shapes on-the-fly, for basic fracture effects.

For static world geometry, concave polygon soups, use btBvhTriangleMeshShape. Note that this btQuantizedBvh/btOptimizedBvh AABB tree used in btBvhTriangleMeshShape is optimized for non-changing topology: the AABB tree cannot deal with adding or removing nodes, but there is a basic 'refit' operation. So both the optimized quantized AABB tree (btQuantizedBvh) and the dynamic AABB tree (btDbvt) have their specific benefits, and they should not be merged.
edl wrote: my options now
1. use gimpact mesh,and build a shape list to identify it myself
2. re-mesh my car, and use convex mesh,(but it will seems ugly)
3. fix the bug....(God help me... )
What is the issue of approximating the car with multiple convex hulls (btConvexHullShape) in a btCompoundShape?

That is similar to what was used for vehicle collision in the GTA IV game. You should be able to determine the index of the child shape involved in a collision, add and remove convex hulls to the btCompoundShape, and deform vertices in each btConvexHullShape and update the btCompoundShape. Of course you cannot add and remove child shapes during the collision detection update, but you should be able to safely add/remove child shapes from a btCompoundShape during a tick callback, or before/after the stepSimulation.

Cheers,
Erwin

Post Reply