Physics Simulation Forum

 

All times are UTC




Post new topic Reply to topic  [ 72 posts ]  Go to page 1, 2, 3, 4, 5  Next
Author Message
 Post subject: Bumpy triangle meshes
PostPosted: Sat Jan 10, 2009 1:17 am 
Offline

Joined: Fri May 30, 2008 2:51 am
Posts: 508
Location: Ossining, New York
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


Top
 Profile  
 
PostPosted: Sun Jan 11, 2009 1:44 pm 
Offline

Joined: Sun Sep 30, 2007 7:58 am
Posts: 228
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.


Top
 Profile  
 
PostPosted: Sun Jan 11, 2009 10:35 pm 
Offline

Joined: Fri May 30, 2008 2:51 am
Posts: 508
Location: Ossining, New York
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.


Top
 Profile  
 
PostPosted: Mon Jan 12, 2009 12:44 pm 
Offline

Joined: Sun Sep 30, 2007 7:58 am
Posts: 228
Hi again,

you can also try to increase the number of substeps. For me 4 substeps cure ~80% of false triangle edge collisions.


Top
 Profile  
 
PostPosted: Mon Jan 12, 2009 3:40 pm 
Offline

Joined: Mon Jul 02, 2007 5:12 pm
Posts: 145
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


Top
 Profile  
 
PostPosted: Mon Jan 12, 2009 4:27 pm 
Offline

Joined: Fri May 30, 2008 2:51 am
Posts: 508
Location: Ossining, New York
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...


Top
 Profile  
 
PostPosted: Mon Jan 12, 2009 4:36 pm 
Offline

Joined: Mon Jul 02, 2007 5:12 pm
Posts: 145
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


Top
 Profile  
 
PostPosted: Mon Jan 12, 2009 7:12 pm 
Offline
Site Admin
User avatar

Joined: Sun Jun 26, 2005 6:43 pm
Posts: 4055
Location: California, USA
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


Top
 Profile  
 
PostPosted: Mon Jan 12, 2009 8:53 pm 
Offline

Joined: Mon Jul 02, 2007 5:12 pm
Posts: 145
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:
//////////////////////////////////////////////////////////////
// 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;
}


Top
 Profile  
 
PostPosted: Tue Jan 13, 2009 8:47 am 
Offline

Joined: Sun Sep 30, 2007 7:58 am
Posts: 228
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.


Top
 Profile  
 
PostPosted: Tue Jan 13, 2009 1:01 pm 
Offline

Joined: Mon Jul 02, 2007 5:12 pm
Posts: 145
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


Top
 Profile  
 
PostPosted: Tue Jan 13, 2009 1:45 pm 
Offline

Joined: Sun Sep 30, 2007 7:58 am
Posts: 228
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.


Top
 Profile  
 
PostPosted: Tue Jan 13, 2009 5:07 pm 
Offline

Joined: Mon Jul 02, 2007 5:12 pm
Posts: 145
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:
//////////////////////////////////////////////////////////////
// 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


Top
 Profile  
 
PostPosted: Wed Jan 14, 2009 12:19 am 
Offline

Joined: Fri May 30, 2008 2:51 am
Posts: 508
Location: Ossining, New York
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.


Top
 Profile  
 
PostPosted: Wed Jan 14, 2009 1:09 am 
Offline

Joined: Fri May 30, 2008 2:51 am
Posts: 508
Location: Ossining, New York
Ah the wiki explains how to set up the callback but the other questions remain

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


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 72 posts ]  Go to page 1, 2, 3, 4, 5  Next

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group