Box2D Forums

It is currently Wed Jul 30, 2014 8:20 pm

All times are UTC - 8 hours [ DST ]




Post new topic Reply to topic  [ 23 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: Contact issue
PostPosted: Mon Mar 05, 2012 7:32 am 
Offline

Joined: Mon Mar 05, 2012 7:18 am
Posts: 26
Location: Sevilla
Hi all! Here a new box2d's noob ^^

I have a problem with contact results.

I have a doll in my game (fixedrotation = true) and I need to know which face is in contact in the current frame (so if below edge is in contact with ground, he can jump). To do this, I use BeginContact and EndContact to add a contact list to my doll. Jéj, so with contact's normals I can know if he is standing over his foots and let him jump!

My problem is this: I apply Impulse to the doll if he has a contact below, he will jump in the next world->step. Then he will be separated from the ground (flying), But!, EndContact doesn't call the callback function in the same frame where he is flying for the very first time. So I have one frame where the doll is flying (he is not touching the ground), but the contact is still alive (and IsTouching() returning 'true'!!) I tried everything, to do it with pre and post-solve, to do it by myself in the world update (checking all contacts, looking for the body and checking if it touch), playing with TOI values... and i get always the same problem. I get contact before the doll touch ground (if he is falling) and in the next frame after the jump (where IsTouching() should return 'false').

Some idea of what im doing wrong? Should I use another method?

Thanks a lot!!!
Regards.


Top
 Profile  
 
 Post subject: Re: Contact issue
PostPosted: Mon Mar 05, 2012 12:31 pm 
Offline

Joined: Tue Jun 24, 2008 8:25 pm
Posts: 1904
Location: Tokyo
Depending on what else is happening with the body, it may take more than one frame for it to clear the ground after you apply the jump impulse. If EndContact is not called after the first frame where the two fixtures separate it would be a big bug... maybe something about the contact list you are managing is not right.

It might help if you tell us the end goal of what you are trying to do here. My guess is you want to let the guy jump, but you don't want to give him two (or more) impulses if he is already doing a jump. If so, one crude way you could deal with that problem is just not let him jump until a certain time has expired, for example count down 15 frames until he can jump again (that's 0.25 seconds if you are running at 60fps).

-----Edit 12/03/12-----
This statement was false, sorry :( "If EndContact is not called after the first frame where the two fixtures separate it would be a big bug"


Last edited by irresistible force on Sun Mar 11, 2012 8:35 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Contact issue
PostPosted: Tue Mar 06, 2012 1:44 am 
Offline

Joined: Mon Mar 05, 2012 7:18 am
Posts: 26
Location: Sevilla
Thanks, great force.

You are right in everything, the problem is that we are making a standard model with no issues, because it is a layer over the box2d to be used in our own games engine and develop any kind of videogame, so we are trying to avoid this kind of issues. That's why im trying to avoid the use of 'tricks' ike that of not to jump in the next X frames.

I will explain step by step what i get from Box2D.

The moving box is a width=0.4f, height=1.0f, density=0.5f, restitution=0.0f, friction=0.6f, isSensor=false. The size is quite short, in this way we avoid some issues of velocity and gravity (with a bigger box, if it is moving fast horizontally in the air, the gravity seems not to affect it until we stop aplying that horizontal force).

Here wonderful graphics (each step is what i see after world->step. Forces are applied before world->step): Image

Step1: The body is falling. There's no b2Contact.

Step2: The body is near to the ground, and not touching it. A new b2Contact is returned by BeginContact callback. IsTouching=true. TOI flag=true.

Step3: The body touch the ground for the very first time. The b2Contact is alive, IsTouching=true, TOI flag=true. TOI flag will keep true for 5 or 6 frames.

Step4: The body is lying over the ground. The b2Contact is alive, IsTouching=true, TOI flag=false. If I apply a horizontal force in this moment, TOI flag will be true, so I can't use it to determine if the body is 'really' touching the ground.

Step5: I applied vertical impulse before word->step. Then the body gets the power and it separates itself from the ground. The b2Contact is still alive, nothing has been returned to EndContact callback. IsTouching=true, TOI flag=true. And the body is not touching the ground :/

Step6: Second frame after apply jump impulse. Body farer from the ground, EndContact callback has been called. b2Contact is destroyed.


Some idea about what is happening?


Top
 Profile  
 
 Post subject: Re: Contact issue
PostPosted: Tue Mar 06, 2012 3:38 am 
Offline

Joined: Tue Jun 24, 2008 8:25 pm
Posts: 1904
Location: Tokyo
Are you looking at Box2D's debug draw display, or your own graphics?


Top
 Profile  
 
 Post subject: Re: Contact issue
PostPosted: Tue Mar 06, 2012 3:44 am 
Offline

Joined: Mon Mar 05, 2012 7:18 am
Posts: 26
Location: Sevilla
irresistible force wrote:
Are you looking at Box2D's debug draw display, or your own graphics?


The both, I have the same problem with Box2D debug draw and in my game where I draw own sprites accordant to bodies's positions. In fact, if i check position before the jump impulse, after it I apply jump impulse, then world-step, then I check position, and it is moved and not touching ground, but b2Contact still alive..

Im using last release Box2D_v2.2.1.zip, ground is a static box. Both box and ground are polygon shape.


Top
 Profile  
 
 Post subject: Re: Contact issue
PostPosted: Tue Mar 06, 2012 4:09 am 
Offline

Joined: Tue Jun 24, 2008 8:25 pm
Posts: 1904
Location: Tokyo
I still think you must be getting something wrong with the rendering... if you have a contact between two fixtures with IsTouching returning true while the debug draws shows them separated (or vice-versa) it would be a pretty bad bug.


Top
 Profile  
 
 Post subject: Re: Contact issue
PostPosted: Tue Mar 06, 2012 4:13 am 
Offline

Joined: Mon Mar 05, 2012 7:18 am
Posts: 26
Location: Sevilla
It is right sure, give me some minutes and I'll upload a screenshot with debug info from VC++, position, sizes and contact info.

EDIT: Here it is:

Jump impulse was applied before this update. As you see, tracer goes inside "if (_phy2dcontact->IsTouching())". CheckCol_GetBody(_index) returns the body whom we pretend to check side collision (to detect if his feet are over the ground). Phy2DBody is my own body class, GetB2Body returns *b2Body. Phy2DContact inherit from b2Contact.

Code:
void Phy2DSystem::Update()
{
   for (int i = 0; i < num_scenes; i++)
   {
      Phy2DScene* _s = scene[i];

      // Update del world
      _s->GetB2World()->Step(time_step, 10, 8);

      // Procesa los contactos existentes
      for (int j = 0; j < _s->CheckCol_GetListSize(); j++)
      {
         Phy2DBody* _phy2dbody = _s->CheckCol_GetBody(j);
         _phy2dbody->Col_DelAllB2Contact();

         for (b2ContactEdge *ce = _phy2dbody->GetB2Body()->GetContactList(); ce; ce = ce->next)
         {
            Phy2DContact *_phy2dcontact = (Phy2DContact *)ce->contact;
            // This contact has a valid TOI in m_toi
            //e_toiFlag         = 0x0020 // Dice si hubo tiempo de impacto o no (por tanto si habrá IMPACTO, el cuerpo no está en contacto. No válido ya que al aplicar cualquier otra fuerza, el cuerpo recibirá impacto aunque toque el suelo)
            //if (!(_phy2dcontact->GetFlags() & 0x0020))
            if (_phy2dcontact->IsTouching())
            {
               _phy2dbody->Col_AddB2Contact(_phy2dcontact);
            }
         }

         _phy2dbody->Col_CheckSides();
      }
   }
}


In this frame, the contact info is right this: Image

The box position BEFORE this world->Step (when it is lying over the ground) is x=300; y=614. The box position AFTER this world->step (in the moment of this trace) is x=300; y=596. (Both got by b2_body->GetPosition()) We dont need to check the size, body has moved upside after he was lying over the ground box.

Is it a bug? :? Maybe Box2D return contacts before and after touching each other, but surely IsTouching shouldn't return 'true' :/


Top
 Profile  
 
 Post subject: Re: Contact issue
PostPosted: Tue Mar 06, 2012 5:32 am 
Offline

Joined: Tue Jun 24, 2008 8:25 pm
Posts: 1904
Location: Tokyo
What does the debug draw look like after that world step?


Top
 Profile  
 
 Post subject: Re: Contact issue
PostPosted: Tue Mar 06, 2012 5:37 am 
Offline

Joined: Mon Mar 05, 2012 7:18 am
Posts: 26
Location: Sevilla
The box separated from the ground, like in step 5 (the pict I posted above in my first reply).


Top
 Profile  
 
 Post subject: Re: Contact issue
PostPosted: Tue Mar 06, 2012 6:29 am 
Offline

Joined: Tue Jun 24, 2008 8:25 pm
Posts: 1904
Location: Tokyo
Just to be sure, there are only two bodies in the world right?
By the way I think it would be more efficient to catch BeginContact/EndContact callbacks to maintain a list of contacts like this because Box2D will tell you when something has changed, instead of deleting and re-creating the list every frame, and you don't need to use IsTouching at all. There is an example here, check out the section titled 'Preventing jumping depending on ground type': http://www.iforce2d.net/b2dtut/jumpability


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

All times are UTC - 8 hours [ DST ]


Who is online

Users browsing this forum: No registered users and 5 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