Velocity not applied to growing circle

General Box2D issues or C++ specific issues
Dingo Games
Posts: 4
Joined: Tue Dec 22, 2009 9:16 pm

Velocity not applied to growing circle

Postby Dingo Games » Sun Apr 25, 2010 12:37 am

Let me first say that Box2D is great. Thanks very much to all the contributors.

In my game the player controls a ball that can grow and shrink. I implemented this scaling by repeatedly deleting and recreating the b2Body every frame at the new size. So, over the course of say 30 frames, the ball will appear to scale up. But from Box2D's perspective it is actually being deleted and recreated. In order to keep the ball moving and rotating while it is being scaled, I store the old angle, position, and velocity, before deleting the b2Body and then set the new b2Body to those values.

This generally works very well, and it used to work perfectly (when I was using r32). However, I'm having a bit of a problem now (latest revision). If the ball is touching another body while scaling, its position and rotation freeze. The AngularVelocity and LinearVelocity have a value you in them, but the body behaves as if they are 0. I don't know enough about Box2D to speculate as to what the problem might be.

I created a Test (see below) that shows my problem in action. It creates a circle and sends it off moving to the right. Then, every frame, it deletes and creates a new circle, growing it a little bit at a time. The circle should move quickly off to the right, but instead it just sits there. Set a breakpoint in the Step and you'll see that LinearVelocity stays large. Notably, if I create a box instead of a circle the problem doesn't occur.

Any ideas?

Cheers,
James

Code: Select all

#ifndef SCALE_SLIDE_H
#define SCALE_SLIDE_H

class ScaleSlide : public Test
{
public:

   b2Body* tempBody ;
   float scalingRadius ;

   virtual void Step(Settings* settings)
   {
      Test::Step( settings ) ;


      float32 oldAngle = tempBody->GetAngle( ) ;
      float32 oldAngularVelocity = tempBody->GetAngularVelocity( ) ;
      b2Vec2 oldPos = tempBody->GetPosition( ) ;
      b2Vec2 oldVelocity = tempBody->GetLinearVelocity( ) ;
      m_world->DestroyBody( tempBody ) ;
      
      scalingRadius += 0.01f ;
      b2CircleShape shape ;
      shape.m_radius = scalingRadius ;
      //b2PolygonShape shape;
      //shape.SetAsBox(scalingRadius, scalingRadius);

      b2BodyDef bd;
      bd.type = b2_dynamicBody;
      tempBody = m_world->CreateBody(&bd);
      tempBody->CreateFixture(&shape, 5.0f);
      tempBody->SetLinearVelocity( oldVelocity ) ;
      tempBody->SetAngularVelocity( oldAngularVelocity ) ;
      tempBody->SetTransform( oldPos, oldAngle ) ;
   }

   ScaleSlide()
   {
      {
         b2BodyDef bd;
         b2Body* ground = m_world->CreateBody(&bd);

         b2PolygonShape shape;
         shape.SetAsEdge(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
         ground->CreateFixture(&shape, 0.0f);
      }

      scalingRadius = 1.0f ;
      b2CircleShape shape ;
      shape.m_radius = scalingRadius ;
      //b2PolygonShape shape;
      //shape.SetAsBox(scalingRadius, scalingRadius);

      b2Vec2 pos(-7.0f, 0.75f);
      
      b2BodyDef bd;
      bd.type = b2_dynamicBody;
      bd.position = pos;
      tempBody = m_world->CreateBody(&bd);
      tempBody->CreateFixture(&shape, 5.0f);
      tempBody->SetLinearVelocity( b2Vec2( 100.0, 0.0 ) ) ;



   }

   static Test* Create()
   {
      return new ScaleSlide;
   }
};

#endif


Erin Catto
Site Admin
Posts: 2948
Joined: Thu Sep 06, 2007 12:34 am

Re: Velocity not applied to growing circle

Postby Erin Catto » Sun Apr 25, 2010 10:02 am

You are scaling the circle into the static ground. This is confusing the continuous collision system. Your example works if I disable continuous simulation.

Dingo Games
Posts: 4
Joined: Tue Dec 22, 2009 9:16 pm

Re: Velocity not applied to growing circle

Postby Dingo Games » Sun Apr 25, 2010 3:00 pm

Thanks Erin.

Yes, I realize that the circle is being scaled into the ground. However, the problem isn't limited to that case, it also happens when I am shrinking the circle (which would actually cause a gap between the circle and the ground), but only when a sufficient force or velocity is being applied to it so that it would be pushed into the ground.

After some digging around through the docs and code I believe that my problem is caused by this limitation listed in the manual, "Continuous collision is processed sequentially. In a time of impact event, the body is moved back and held there for the rest of the time step. This may make fast moving objects appear to move in a non-smooth manner." I am simply experiencing an extreme form of this because it is happening many frames in a row for me, thereby locking my object in place.

If I'm understanding correctly, this limitation was introduced in r33 when the continuous simulation was heavily revised. Which would explain why I wasn't having the problem in r32.

In my ideal solution, there would be a way to turn on the sub-steps that used to be performed, instead of just doing the position correction. Maybe that would benefit other people who want more accurate collisions for fast moving objects. Being able to turn it on for only certain bodies would allow us to keep the performance benefits for objects that don't need it. At present I don't understand the code well enough to attempt to add such features for myself - actually, I don't even know if this is a realistic solution.

Does anyone have any other ideas on how to solve my problem? Disabling CCD is not an option because I need it.

(btw, it's great that limitations are listed in the manual, instead of leaving them as surprises for users to discover)

Erin Catto
Site Admin
Posts: 2948
Joined: Thu Sep 06, 2007 12:34 am

Re: Velocity not applied to growing circle

Postby Erin Catto » Sun Apr 25, 2010 3:21 pm

Version 2.0 had really ambitious continuous simulation but it was slow and could break in some cases, leading to dynamic bodies tunneling through static bodies.

For 2.1 I tried to improve performance and eliminate dynamic-static tunneling completely, and it seems to succeed on that so far. However, some features of 2.0 were lost, namely sub-stepping. I think sub-stepping could be added back in, but I need to find a way to do this without reducing the tunneling robustness. This is an open area of research for me and there are no good references out there.

I plan to revisit sub-stepping soon, but bug fixing and smooth edges shapes are the priority now.

Dingo Games
Posts: 4
Joined: Tue Dec 22, 2009 9:16 pm

Re: Velocity not applied to growing circle

Postby Dingo Games » Sun Apr 25, 2010 7:58 pm

Ah, I see. I didn't realize that you removed the sub-stepping because it caused tunneling problems, I was thinking that it was just for speed. That would be awesome if you could figure out how to get sub-stepping back in, but I understand that other things have priority.

That said, I'm trying to ship a game so I needed to come up with a work-a-round. I think I have something that works.

I added the ability to toggle CCD on a per body basis. To do this, I gave b2Body a boolean variable called useCCD. Then, in b2World::SolveTOI() I added a check for it:

Code: Select all

// Kinematic, and static bodies will not be affected by the TOI event.
// If a body was not in an island then it did not move.
if ((body->m_flags & b2Body::e_islandFlag) == 0 || body->GetType() == b2_kinematicBody || body->GetType() == b2_staticBody || !body->useCCD )
{
   body->m_flags |= b2Body::e_toiFlag;
}
else
{
   body->m_flags &= ~b2Body::e_toiFlag;
}

This seemed to work, but please tell me if you think this is an insane hack that is going to cause everything to explode.

I still want CCD to be used as often as possible, so I only turn it off while the ball is growing/shrinking and contacting a static body at the same time. So the vast majority of the time CCD will be on, it only turns off in the cases that I am having the problem.

The solution works well when the ball is growing, but movement stutters a bit when it is shrinking. Fortunately, the ball rarely shrinks, so it's not a big deal.

Cheers,
James

Erin Catto
Site Admin
Posts: 2948
Joined: Thu Sep 06, 2007 12:34 am

Re: Velocity not applied to growing circle

Postby Erin Catto » Sun Apr 25, 2010 8:03 pm

That sounds like a fine work-around.


Return to “Bugs, Requests, and Feedback”



Who is online

Users browsing this forum: No registered users and 2 guests