Possible Bug in changing physics masks when in contact?

aside: [edit: I finally watched the clip you shared and realize you’re running in debug mode]

While I’m almost certainly wrong, my thinking is that when the player hasn’t collided yet with the ground it’s still awake because gravity is still acting on it, but after it’s collided and not moving for some time period t it goes to sleep, then you remove the ground (or set bits to 0) and physics isn’t being simulated for the player because it’s asleep:

  1. Player is above ground and falling
  2. Player contacts ground and stops moving
  3. Player physics object goes to sleep
  4. Ground bit mask is reset to not apply to player collisions (expecting player to now fall through)
  5. Player doesn’t move because it’s asleep and physics (even gravity) is not applying to it

You could at least debug or print out the body’s various state, such as bool awake or 'bool allowSleep`.

Not sure whether you need to investigate @panor’s reply about (continuous collision detection (CCD), or something else like setting a category filter?

maybe check iforce2d’s docs (though coco2d may default to Chipmunk?):

  1. Anatomy of a collision - Box2D tutorials - iforce2d
  2. Collision callbacks - Box2D tutorials - iforce2d
  3. Collision filtering - Box2D tutorials - iforce2d

again, I don’t often use 2d physics (only in unity games) so I’m not well versed in the Box2d or Chipmunk (both are supported in Cocos2D, but I don’t know the default as I write non-physics-based collisions and gravity when needed, which hasn’t been often for the games I’ve worked on).

Nobody want use an example code which isn’t running out of the box.
Can you adapt one of the example code (test-cpp) to copy/past it easy?

In a platform game I did I had problems getting the bitmask stuff to work correctly in Chipmunk too (I wanted player to occasionally fall through the platform. I recall changing the bitmask to temporarily ignore player and floor, but it did not work well.

What I did instead was to handle the precontract, contactbegin and contactseperate events, and return true / false depending on whether I wanted the engine to consider event, events like “standing on the floor”. This made gravity temporarily affect player making him fall through the floor.

If I recall correctly, once an object has been in contact with stationary object and not moved for awhile it goes into a “dormant” sleep state of not moving, which purges it from the list of stuff calculated in each physics cycle for efficiency. So try “poking” your object when needed to wake it up, this may make it re-evaluate based on bitmaps. On the other hand, the engine may be making a map of objects that can interact, based on bitmaps. This could mean a later change may not be respected. I don’t quite recall, but I think there was a way to force physics engine to basically re-evaluate, and “trigger” the changes, but manipulating the contact function’s returns worked for me.

Perhaps this may work in contact functions:

return contact.getShapeA()->getCollisionBitmask() & contact.getShapeB()->getCollisionBitmask()
// there are 3 bitmasks, may need to experiment with how interaction work: CategoryBitmask, CollisionBitmask, ContactTestBitmask

It seems changes to bitmasks are ignored by the Chipmunk physics engine during run time, at least when I used an event to set an objects collision mask to 0 during play nothing happened.
I can confirm that adding this seems to “fix” problem, i.e. if A or B collision mask currently makes for no Collison, my player falls through the floor.

bool HelloWorld::onPreContact(cocos2d::PhysicsContact& contact)
    auto A = contact.getShapeA();
    auto B = contact.getShapeB();
    return (A->getCategoryBitmask() & B->getCollisionBitmask()) && (B->getCategoryBitmask() & A->getCollisionBitmask()); // not sure if we have to test both ways, but Chipmunk seems to ignore collisions if A and B do not both agree to collide (which seems to contradict the comment for setCollisionBitmask()), so I'll follow same limitation.

Thanks, that makes a lot of sense, and sounds exactly like what I was trying to demonstrate in the video. Sounds like the same situation. After reading your explanation I can understand what SteveTranby was suggesting.

I have not yet tried the approach of changing the behavior in the presolve/ begin contact and end contact events yet.

At present I just destroy the physics body and recreate a new one with different bitmasks.

Thanks, I understand your suggestion now. I will what you suggest.

I understand your suggestion now. Thanks.

I’m glad if it helps you chumbyfuzz :slight_smile:

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.