Bumpy triangle meshes

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

Bumpy triangle meshes

Post by sparkprime »

If I slide a box along a btBvhTriangleMeshShape there is a 'knock' as the box transitions from one triangle to the next, here is a video

http://uk.youtube.com/watch?v=3hDa746BKD4

You can see it at the beginning just after the box lands and also at the end (if you look carefully). The wireframe matches up with Bullet's triangle mesh.

Is there any way to fix / work around / minimise this? What can I try to experiment with?

(In general I can't use box/plane/etc for the floor as it won't necessarily be flat)

If this is just part+parcel of using a triangle mesh then I can put up with it but it would be nice if it were fixable.

thanks
pico
Posts: 229
Joined: Sun Sep 30, 2007 7:58 am

Re: Bumpy triangle meshes

Post by pico »

Hi,

you can read about this problem here:

(Issue 27: Provide solution to filter out unwanted collisions with internal edges of a triangle mesh.)
http://code.google.com/p/bullet/issues/detail?id=27

Erwin said:
"I'll mark this issue, so we can look at it again before Bullet 2.74 release."

We hope for that fix too. It causes problems in all our games using Bullet.
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York
Contact:

Re: Bumpy triangle meshes

Post by sparkprime »

Thanks, it seems related except I only get the issue at the transition between triangles (I think).

What does "filter out unwanted collisions with internal edges of a triangle mesh" actually mean? Does it mean that the edge between two triangles (as opposed to literally at the edge of the mesh patch) gets treated specially? What about knife edges?

Is this something to do with when a contact breaks away from one triangle and needs to be re-established on the next triangle? Or is it actually caused by the edge 'digging in' and providing a bigger impulse response than a triangle normally would?

This just got a lot more serious for me as I just started doing vehicles and at the moment they're unusable on triangle meshes because if you graze along any surface (happens a lot when driving badly or if the road is a bit uneven) you tend to spin several metres into the air.

I'm using gimpact triangle mesh for the body of the vehicles and i'm unsure what to do with the collision margin.
pico
Posts: 229
Joined: Sun Sep 30, 2007 7:58 am

Re: Bumpy triangle meshes

Post by pico »

Hi again,

you can also try to increase the number of substeps. For me 4 substeps cure ~80% of false triangle edge collisions.
AlexSilverman
Posts: 141
Joined: Mon Jul 02, 2007 5:12 pm

Re: Bumpy triangle meshes

Post by AlexSilverman »

Hi,

Have you written a ContactAddedCallback, in which you set the collision normal to the triangle normal? This worked for me in Bullet 2.70.

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

Re: Bumpy triangle meshes

Post by sparkprime »

I'm already running at 100hz, I doubt I can spare any more CPU power :)

I haven't got a ContactAddedCallback yet but I will probably need one eventually, setting the normal is an interesting idea, why is the normal not that of the face in the first place?

I really need to render the contacts and step each physics iteration to watch what's going on...
AlexSilverman
Posts: 141
Joined: Mon Jul 02, 2007 5:12 pm

Re: Bumpy triangle meshes

Post by AlexSilverman »

sparkprime wrote:...why is the normal not that of the face in the first place?
I'm not sure. The stage that I was in when I found that solution didn't really allow me to go back and digging in to find the actual cause of the problem. I assume though, that the goal for this issue is to find a more transparent solution to this problem than to require a callback, assuming this fixes the issue for you.

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

Re: Bumpy triangle meshes

Post by Erwin Coumans »

AlexSilverman wrote: Have you written a ContactAddedCallback, in which you set the collision normal to the triangle normal? This worked for me in Bullet 2.70.

I assume though, that the goal for this issue is to find a more transparent solution to this problem than to require a callback, assuming this fixes the issue for you.
Indeed, first we need to determine if fixing the normal (and depth?) inside a contact callback is sufficient. Then we can wrap that up in a more easy-to-use solution.

Alex, how is your experience with this fix? Can you share the implementation?
Thanks,
Erwin
AlexSilverman
Posts: 141
Joined: Mon Jul 02, 2007 5:12 pm

Re: Bumpy triangle meshes

Post by AlexSilverman »

Sure thing. What follows is my ContactAddedCallback implementation for combating edge collisions in triangle meshes. I never did get around to profiling the results of adding in a check to determine if the contact normal is already the triangle normal, so that might be worthwhile. In any event, here it is. I noticed this problem during development of a minigolf game, and this took care of it. That said, this was in Bullet 2.70, and hasn't been tested in anything more current.

- Alex

Code: Select all

//////////////////////////////////////////////////////////////
// NotifyOnCollision
// Let an object know it's been collided
//////////////////////////////////////////////////////////////
bool NotifyOnCollision(btManifoldPoint& cp, const btCollisionObject* colObj0, int partId0, int index0, const btCollisionObject* colObj1, int partId1, int index1)
{
    (void)partId0;
    (void)index0;
    (void)partId1;
    (void)index1;

    // Correct the normal
    if (colObj0->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE)
    {
        btTriangleShape * s0 = ((btTriangleShape*)colObj0->getCollisionShape());
        cp.m_normalWorldOnB = (s0->m_vertices1[1] - s0->m_vertices1[0]).cross(s0->m_vertices1[2] - s0->m_vertices1[0]);
        cp.m_normalWorldOnB.normalize();
    }
    else if (colObj1->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE)
    {
        btTriangleShape * s1 = ((btTriangleShape*)colObj1->getCollisionShape());
        cp.m_normalWorldOnB = (s1->m_vertices1[1] - s1->m_vertices1[0]).cross(s1->m_vertices1[2] - s1->m_vertices1[0]);
        cp.m_normalWorldOnB.normalize();
    }
    //this return value is currently ignored, but to be on the safe side: return false if you don't calculate friction
    return true;
}
pico
Posts: 229
Joined: Sun Sep 30, 2007 7:58 am

Re: Bumpy triangle meshes

Post by pico »

Hi,

i tested Alex' above code in the recent trunk with a moving box and a static mesh. The result was that the bodies no more touch. The box simply falls through the mesh.
AlexSilverman
Posts: 141
Joined: Mon Jul 02, 2007 5:12 pm

Re: Bumpy triangle meshes

Post by AlexSilverman »

Hi,

The vectors in the cross product are probably swapped. Reversing them will most likely fix it, but I'm not sure what to make of this, since I'm computing the normal the same way as the btTriangleShape::calcNormal() does.

- Alex
pico
Posts: 229
Joined: Sun Sep 30, 2007 7:58 am

Re: Bumpy triangle meshes

Post by pico »

Hi Alex,

i swapped the cross products like this:

// cp.m_normalWorldOnB = (s0->m_vertices1[1] - s0->m_vertices1[0]).cross(s0->m_vertices1[2] - s0->m_vertices1[0]);
cp.m_normalWorldOnB = (s0->m_vertices1[2] - s0->m_vertices1[0]).cross(s0->m_vertices1[1] - s0->m_vertices1[0]);

and

// cp.m_normalWorldOnB = (s1->m_vertices1[1] - s1->m_vertices1[0]).cross(s1->m_vertices1[2] - s1->m_vertices1[0]);
cp.m_normalWorldOnB = (s1->m_vertices1[2] - s1->m_vertices1[0]).cross(s1->m_vertices1[1] - s1->m_vertices1[0]);

Now the box goes through walls instead of falling through the floor.
AlexSilverman
Posts: 141
Joined: Mon Jul 02, 2007 5:12 pm

Re: Bumpy triangle meshes

Post by AlexSilverman »

Hi pico,

Interesting. I guess this solution worked across the board for us because our artists maintained the winding order of our collision meshes, so we never had these problems once we straightened it out initially.

This leads me to think that Bullet doesn't care about the actual normal of the triangles in a mesh when it collides? I'm not sure how the simplex solver returns the points that determine the contact normal, but it certainly doesn't seem to have anything to do with the triangle normal. Is this correct? If so, perhaps we can compare the normal computed from the simplex solver points with the triangle normal, and set the contact normal to the triangle normal, but reversed if it isn't in the same direction as the current contact normal. Something like this...

Code: Select all

//////////////////////////////////////////////////////////////
// NotifyOnCollision
// Let an object know it's been collided
//////////////////////////////////////////////////////////////
bool NotifyOnCollision(btManifoldPoint& cp, const btCollisionObject* colObj0, int partId0, int index0, const btCollisionObject* colObj1, int partId1, int index1)
{
    // Correct the normal
    if (colObj0->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE)
    {
        btVector3 tempNorm;
        ((btTriangleShape*)colObj0->getCollisionShape())->calcNormal(tempNorm);
        if(tempNorm.dot(cp.m_normalWorldOnB) < 1)
            cp.m_normalWorldOnB = tempNorm * -1;
        else
            cp.m_normalWorldOnB = tempNorm;
    }
    else if (colObj1->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE)
    {
        btVector3 tempNorm;
        ((btTriangleShape*)colObj1->getCollisionShape())->calcNormal(tempNorm);
        if(tempNorm.dot(cp.m_normalWorldOnB) < 1)
            cp.m_normalWorldOnB = tempNorm * -1;
        else
            cp.m_normalWorldOnB = tempNorm;
    }
}
One problem with this solution is that I don't know (perhaps due again to my lack of knowledge with the simplex solver) what the "incorrect" normals will be in those cases where the edges cause collisions, so I don't know if the dot product test will be sufficient, or appropriate.

Hope this helps.

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

Re: Bumpy triangle meshes

Post by sparkprime »

Can someone fill in the gaps in my understanding. I understand that contacts persist long enough for a number of them to accumulate (3?) -- enough for e.g. a box to rest on a surface and be stable. This callback is presumably called when the contact is first created.

Does its normal remain constant during its lifetime?

What about its other attributes?

How do I register the callback?

Is the only way to keep tabs on contacts during their full life time to iterate through all the contacts every frame?


About the winding, as far as I understand it, bullet doesn't care about the winding, and the triangles are essentially two-sided. I wonder, if it were possible to filter out contacts on triangles to make them 'one way', whether this would solve some problems with objects getting jammed in walls, etc.
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York
Contact:

Re: Bumpy triangle meshes

Post by sparkprime »

Ah the wiki explains how to set up the callback but the other questions remain

http://www.bulletphysics.com/mediawiki- ... d_Triggers
Post Reply