Box2D Forums

It is currently Wed May 22, 2013 2:34 am

All times are UTC - 8 hours [ DST ]




Post new topic Reply to topic  [ 10 posts ] 
Author Message
PostPosted: Sat Jun 28, 2008 3:20 am 
Offline

Joined: Tue Jun 24, 2008 8:25 pm
Posts: 1515
Location: Tokyo
At the moment I'm experimenting with character movement, using a rectangular body to represent a torso, and a 'feeler' extending below the body to check what the character is standing on. The feeler is a b2Segment, which is checked against objects in the world with the b2PolygonShape::TestSegment function.

Occasionally I noticed my character standing on nothing, and eventually narrowed down the problem to the case where the segment is perfectly parallel to one of the sides of the shape. Admittedly this is quite an unlikely occurence, except for at the beginning of the simulation when many objects still have their initial angle of a perfect zero.

To remedy this I added a third case to the if/else block in TestSegment as below. Perhaps there is a better way to address the problem, but it seems to be working well enough for me so far.

Before:
Code:
      if (denominator < 0.0f && numerator < lower * denominator)
      {
         // Increase lower.
         // The segment enters this half-space.
         lower = numerator / denominator;
         index = i;
      }
      else if (denominator > 0.0f && numerator < upper * denominator)
      {
         // Decrease upper.
         // The segment exits this half-space.
         upper = numerator / denominator;
      }

After:
Code:
      if (denominator < 0.0f && numerator < lower * denominator)
      {
         // Increase lower.
         // The segment enters this half-space.
         lower = numerator / denominator;
         index = i;
      }
      else if (denominator > 0.0f && numerator < upper * denominator)
      {
         // Decrease upper.
         // The segment exits this half-space.
         upper = numerator / denominator;
      }
      else if (denominator == 0.0f) {
         // The segment is parallel to this edge
         // Check if it is outside the half-space
         float32 normalDotp1 = b2Dot(m_normals[i], p1);
         float32 normalDotVertex = b2Dot(m_normals[i], m_vertices[i]);
         if ( normalDotp1 > normalDotVertex )
            return false;
      }


Top
 Profile  
 
PostPosted: Sat Jun 28, 2008 3:07 pm 
Offline
Site Admin

Joined: Thu Sep 06, 2007 12:34 am
Posts: 2931
That sounds like a valid robustness problem. I will look into this.

Thanks!


Top
 Profile  
 
PostPosted: Fri Jul 04, 2008 6:01 am 
Offline

Joined: Tue Jun 24, 2008 8:25 pm
Posts: 1515
Location: Tokyo
I think I was wrong about the case simply being "when the segment is parallel to one of the edges of the shape". I noticed that my little man could run along the falsely intersected ground quite happily until he got quite close to it, at which point TestSegment worked correctly again. Here is the original case where I noticed the problem:

Image

Since the segment being parallel to the edge of the shape was what I noticed when stepping through the code, and changing it fixed the problem, I thought that was that. But later I found that when the character got near the shape, there was a point where the test worked ok. As you can see in the image below with little man ver.2 now sporting his new bevelled edge look and an extra 'leg', the leg segment on the right has correctly missed the shape, while the leg on the left has incorrectly intersected with it.

Image

I can't figure out why this is, so considering it might be a harder thing to reproduce than I thought, here's the reproduction:
Code:
   b2AABB worldAABB;
   worldAABB.lowerBound.Set(-500.0f, -500.0f);
   worldAABB.upperBound.Set(500.0f, 500.0f);
   b2World world(worldAABB, b2Vec2(0.0f, -9.8f), true);

   b2Body* pBody = world.CreateBody( &b2BodyDef() );

   b2PolygonDef shapeDef;
   shapeDef.vertexCount = 4;
   shapeDef.vertices[0].Set( 47, 5.95f );
   shapeDef.vertices[1].Set( 53, 5.95f );
   shapeDef.vertices[2].Set( 53, 6.05f );
   shapeDef.vertices[3].Set( 47, 6.05f );
   b2Shape* shape = pBody->CreateShape( &shapeDef );
   
   b2Segment segment;
   segment.p1.Set( 0, 7 );
   segment.p2.Set( 0, 5 );

   float lambda;
   b2Vec2 normal;
   bool shouldBeFalse = shape->TestSegment( pBody->GetXForm(), &lambda, &normal, segment, 1 );



Top
 Profile  
 
PostPosted: Tue Aug 12, 2008 8:28 am 
Offline

Joined: Fri May 16, 2008 10:09 am
Posts: 337
I'm noticing some slightly errant behavior in testSegment as well, when shapes and lines are perfectly perpendicularly aligned or something like that. I would have an intersection with a shape that's not nearby. It would be easy to work around this in my case since I could just apply a miniscule torque or impulse on something, to get rid of the perfect alignment.


Top
 Profile  
 
PostPosted: Wed Aug 13, 2008 7:32 pm 
Offline
Site Admin

Joined: Thu Sep 06, 2007 12:34 am
Posts: 2931
I committed a fix for this to SVN. Let me know if you have any more trouble with it.


Top
 Profile  
 
PostPosted: Wed Aug 13, 2008 8:16 pm 
Offline

Joined: Fri May 16, 2008 10:09 am
Posts: 337
I updated my code to SVN 171. I can confirm that you have fixed this particular testSegment issue. I also notice that the solver and overall physics behavior seems even more robust. As for the change in the b2World::Step function, what should the iterations values be set to? Should there be a preference for different values?


Top
 Profile  
 
PostPosted: Thu Aug 14, 2008 10:28 am 
Offline
Site Admin

Joined: Thu Sep 06, 2007 12:34 am
Posts: 2931
dc443: The manual on SVN discusses this. You can often get good results with only one position iteration. The velocity iteration is the same as the old iteration count.


Top
 Profile  
 
PostPosted: Thu Aug 14, 2008 10:40 am 
Offline

Joined: Fri May 16, 2008 10:09 am
Posts: 337
Oh i see. You hadn't updated the manual on the main box2d site, and that was the one I checked first.

Another quick question, may sound dumb, but does the iterations value affect performance/behavior when joints are not being used?


Top
 Profile  
 
PostPosted: Thu Aug 14, 2008 1:38 pm 
Offline
Site Admin

Joined: Thu Sep 06, 2007 12:34 am
Posts: 2931
The iterations are also used for solving contacts and friction.

The site manual is synced with release versions, not SVN.


Top
 Profile  
 
PostPosted: Wed Aug 20, 2008 2:48 am 
Offline

Joined: Tue Jun 24, 2008 8:25 pm
Posts: 1515
Location: Tokyo
Works great! Thanks Erin.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC - 8 hours [ DST ]


Who is online

Users browsing this forum: No registered users 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:
Powered by phpBB® Forum Software © phpBB Group