convexSweepTest returning incorrect normals.

funkyman
Posts: 3
Joined: Thu Mar 25, 2010 7:18 pm

convexSweepTest returning incorrect normals.

Post by funkyman »

Hi, I hope someone can help me out. I'm in the initial phases of testing bullet in my iPhone engine. I'm currently only using it for collision, but will implement physics later. Everything was working great until I attempted to allow my player character to Slide along a wall. I'm only using convexSweepTests currently, and I'm using a box shape for the player and a btBvhTriangleMeshShape for the walls. The problem is that the normals returned from the convexSweepTest() aren't always correct. Anytime the box comes close to a poly edge, it always says the collision hit the edge, and has a weird normal. This happens on every poly edge and seems to get worse in release (o3 optimization). My guess is the optimization is speeding up the simulation so it happens more reliably. I've attached a few pictures of the normals at the bottom.

Here is how I'm initializing everything:

Code: Select all

    btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
    btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
    btVector3	worldAabbMin(-1000,-1000,-1000);
    btVector3	worldAabbMax(1000,1000,1000);

    btAxisSweep3*	broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax);

    // Create the collision world.
    collisionWorld = new btCollisionWorld(dispatcher,broadphase,collisionConfiguration);
I'm setting up the btBvhTriangleMeshShape like this:

Code: Select all

        // Convert AABB to extents.
        btVector3 aabbMin(BBox->Min.x - Pos.x, BBox->Min.y - Pos.y, BBox->Min.z - Pos.z), 
                    aabbMax(BBox->Max.x - Pos.x, BBox->Max.y - Pos.y, BBox->Max.z - Pos.z);

        btTriangleMesh *m_indexVertexArrays= new btTriangleMesh(TRUE, FALSE);

        // Add triangles to Mesh Shape.
        for (int i=0; i<Mesh.nNumFaces; i++)
        {
            btVector3 v1= btVector3(pVertex->x, pVertex->y, pVertex->z);
            pVertex = (PVRTVECTOR3*)( (unsigned char*)(pVertex) + Mesh.sVertex.nStride);
            btVector3 v2= btVector3(pVertex->x, pVertex->y, pVertex->z);
            pVertex = (PVRTVECTOR3*)( (unsigned char*)(pVertex) + Mesh.sVertex.nStride);
            btVector3 v3= btVector3(pVertex->x, pVertex->y, pVertex->z);
            pVertex = (PVRTVECTOR3*)( (unsigned char*)(pVertex) + Mesh.sVertex.nStride);
            
            m_indexVertexArrays->addTriangle(v1,v2,v3, TRUE);
        }

        // Create new mesh shape from triangles
        *hullShape  = new btBvhTriangleMeshShape(m_indexVertexArrays,useQuantizedAabbCompression,aabbMin,aabbMax);
I thought that this could have been something that btInternalEdgeUtility could fix, however, since I'm using convexSweepTest I never get the addContactPoint() call. Is that normal?

Something I thought of that might cause it could be that I'm using addTriangle to add them to btBvhTriangleMeshShape instead of btTriangleIndexVertexArray. Maybe that causes spacing between each triangle?

Any help would be appreciated!

Thanks!!
You do not have the required permissions to view the files attached to this post.
funkyman
Posts: 3
Joined: Thu Mar 25, 2010 7:18 pm

Re: convexSweepTest returning incorrect normals.

Post by funkyman »

I guess no one else has run into this issue with the normals? I was able to find why I wasn't getting any contact points. It was because I was correcting the penetration directly after the convexSweepTest, so I guess by the next frame there wasn't any overlapping pairs? Does anyone know if that sounds plausible?

I'm basically trying to find the right method to handling character collision. The CharacterDemo is clunky and seems a bit redundant in how it was detecting collision. For instance, it seems odd that it's running through the recoverFromPenetration() function 4 times, then also doing a convexSweepTest for the stepUp call, then up to 10 addition convexSweepTests for the stepForwardAndStrafe() call, then finally another convexSweepTest for the stepDown call. This seems like you would need just 2 convexSweepTests for the stepForwardAndStrafe. One for the initial movement, then another if we're sliding along a wall to test if the new position was valid. Also, why are we solving for the recoverFromPenetration() if we're going to do a convexSweepTest during the movement anyway? When using contact points you would certainly get failed checks if an object is moving quick enough to step over each other. This is where convexSweepTests work great, but I don't think I have to tell anyone here that! ;)

My initial problem still is my concern, If I can not get a valid normal back from the ClosestConvexResultCallback, then I can not smoothly slide along a surface.
funkyman
Posts: 3
Joined: Thu Mar 25, 2010 7:18 pm

Re: convexSweepTest returning incorrect normals.

Post by funkyman »

FIXED UPDATE!!!!!!!!!!!

Well this one was odd, but I tracked it down to I was compiling with GCC 4.0 instead of GCC 4.2. I'm not sure what the exact cause was, but maybe it had to do with how it was optimizing the code. This only happened when the optimization level was above 0 (-O1 through -O3). Now that I've switched to GCC 4.2, everything seems stable and the normals are correct that it's getting back.

Very odd, but at least this is working now!
jhurliman
Posts: 5
Joined: Thu Mar 25, 2010 8:03 am

Re: convexSweepTest returning incorrect normals.

Post by jhurliman »

I believe I'm seeing this same issue or something that behaves similarly, although I compiled Bullet 2.76 .lib files with Visual Studio 2008 (Release build). I haven't done any debug visualization yet, but from some manual debugging and console output it seems like incorrect normals will be reported from a capsule->mesh (GImpact) collision. It depends on what angle I approach the mesh from with my capsule. Approach from one angle and it works perfectly, approach from another angle and I get a normal back that is almost parallel to my sweep direction, even though it goes straight through a face of the mesh. I can consistently reproduce the issue by approaching from two different angles with my character. I switched the sweep test to a raycast and although I lose the benefits of doing a full capsule sweep, this problem went away without changing any other code and I can no longer walk through walls.

Since you received different results from different versions/flags of GCC and my project is intended to be an open source project compiled on many different compilers, I'm changing my character controller to use multiple raycasts instead of a sweep test. If anyone has any more information on this topic I would like to switch back to sweep tests at some point.
Eric_A
Posts: 6
Joined: Wed May 06, 2009 4:42 am

Re: convexSweepTest returning incorrect normals.

Post by Eric_A »

Hmmm, I've actually been having a lot of problems with capsule->mesh sweep tests and collisions myself. It seems sweep tests with a capsule will every so often miss a contact, and capsules will often penetrate a face of a triangle mesh when the capsule's axis is parallel to the plane of the triangle. This is causing pretty huge problems in our game as the player's bounding volume capsule is often parallel to the triangle mesh when they're crawling around on the ground, resulting in sporatic missed contacts followed by a contact parallel to the face of the triangle, which causes the player to temporarily get caught up when trying to crawl.
jhurliman
Posts: 5
Joined: Thu Mar 25, 2010 8:03 am

Re: convexSweepTest returning incorrect normals.

Post by jhurliman »

Thanks to the new contact test in Bullet 2.76 I was able to confirm that the convex sweep test in Bullet really is broken and it's not just my code. When walking, my character always moves less than the radius of the capsule in a single frame so I replaced the sweep test with a simple contact test, using the deepest collision normal to resolve the penetration just like I did with the sweep test. Now the character works perfectly and will never walk through a wall or get sucked into a colliding object (missing or incorrect collision normals). Only problem is I can't move too fast :).