New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Physics Body Collision and Contact Issues #8399

Open
minggo opened this Issue Sep 30, 2014 · 4 comments

Comments

Projects
None yet
5 participants
@minggo
Contributor

minggo commented Sep 30, 2014

Note

This issue is migrated from here. It was created at 2014/04/06 18:34:49 +0000

Description

Having an issue where physics body collisions/contacts aren't working the way I anticipate. I may be misinterpreting how they're supposed to work. My understanding is that if physicsBodyA has a category bitmask of 0x1, and physicsBodyB has a contact test bitmask of 0x1, contact tests should evaluate to true and I should be getting a callback from the event dispatcher.

This isn't working, however. The only way that I get a contact evaluating to true is of I also set physicsBodyA's contact bitmask to match the category bitmask of physicsBodyB. Basically, the category and contact test bitmasks must mirror one another. In practice it looks something like this:

// Bitmasks
int BITMASK_A = 0x1 << 0;
int BITMASK_B = 0x1 << 1;

// Set category bitmasks
bodyA->setCategoryBitmask(BITMASK_A);
bodyB->setCategoryBitmask(BITMASK_B);

// Set BOTH contact test bitmasks (expected to only have to set one)
bodyA->setContactTestBitmask(BITMASK_B);
bodyB->setContactTestBitmask(BITMASK_A);

Based on the docs and other engines that I've used, this seems wrong, but maybe I'm confused. Any help would be greatly appreciated. Thanks!

  • Thruxton added comment:
    Update: wanted to specify that I'm using Cocos2d v3.0rc1, and also attach a small code sample of an init() method to better illustrate my point:

// Call super init
if (!Layer::init()) {
return false;
}

// Get screen size
Size visibleSize = Director::getInstance()->getVisibleSize();

// Bitmasks
int BITMASK_BOUNDARY = 0x1 << 0;
int BITMASK_HERO = 0x1 << 1;

// Boundary node
Node *boundaryNode = Node::create();
boundaryNode->setAnchorPoint(Point(0.5, 0.5));
boundaryNode->setPosition(Point(visibleSize.width/2.0, visibleSize.height/2.0));

// Physics body for boundary node
PhysicsBody *boundaryBody = PhysicsBody::createEdgeBox(visibleSize);
boundaryBody->setCategoryBitmask(BITMASK_BOUNDARY);
boundaryBody->setContactTestBitmask(BITMASK_HERO);
boundaryBody->setDynamic(false);

// Set boundary body and add to scene
boundaryNode->setPhysicsBody(boundaryBody);
this->addChild(boundaryNode);

// Hero node
Sprite *hero = Sprite::create("hero_ship.png");
hero->setPosition(Point(visibleSize.width/2.0, visibleSize.height - 30.0));

// Physics body for hero node
PhysicsBody *heroBody = PhysicsBody::createBox(hero->getContentSize());
heroBody->setCategoryBitmask(BITMASK_HERO);

// Set hero body and add to scene
hero->setPhysicsBody(heroBody);
this->addChild(hero);

/*

  • NOTICE: If I don't set the contact test bitmask on my hero
  • body, the event listener's onContactBegin callback will not
  • be called.
    */

heroBody->setContactTestBitmask(BITMASK_BOUNDARY);

// Create an event listener
EventListenerPhysicsContact *listener = EventListenerPhysicsContact::create();

// Use lambda for listener callback
listener->onContactBegin = [](PhysicsContact &contact) {
CCLOG("Physics contact began.");
return true;
};

// Register listener with event dispatcher
this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);

// Everything worked out on init, return true
return true;

@minggo minggo added the type:bug label May 7, 2015

@minggo minggo added this to the unconfirmed milestone May 7, 2015

@youlanhai

This comment has been minimized.

youlanhai commented Dec 8, 2015

I have meet this issue too.
the document says that in CCPhysicsBody.h,either comparison results is non-zero, the event will be dispatched:

    /** 
     * A mask that defines which categories of bodies cause intersection notifications with this physics body.
     *
     * When two bodies share the same space, each body's category mask is tested against the other body's contact mask by performing a logical AND operation. If either comparison results in a non-zero value, an PhysicsContact object is created and passed to the physics world’s delegate. For best performance, only set bits in the contacts mask for interactions you are interested in.
     * @param bitmask An integer number, the default value is 0x00000000 (all bits cleared).
     */
    void setContactTestBitmask(int bitmask);

But the implement code in CCPhysicsWorld.cp, either the comparison results is zero, the event will be disabled:

    int PhysicsWorld::collisionBeginCallback(PhysicsContact& contact) {
    ...
    // bitmask check  
    if ((shapeA->getCategoryBitmask() & shapeB->getContactTestBitmask()) == 0  
        || (shapeA->getContactTestBitmask() & shapeB->getCategoryBitmask()) == 0)  
    {  
        contact.setNotificationEnable(false);  
    }  

I guess this is the bug,the code should be write like this:

    if ((shapeA->getCategoryBitmask() & shapeB->getContactTestBitmask()) == 0  
        && (shapeA->getContactTestBitmask() & shapeB->getCategoryBitmask()) == 0)  
    {  
        contact.setNotificationEnable(false);  
    }  

change || to &&

@jgcoded

This comment has been minimized.

jgcoded commented Dec 28, 2015

@youlanhai, I just faced the exact same problem and your solution worked. I can't believe this bug has been there for the past two years. It makes you wonder what else is wrong with cocos2d-x. I'm going to switch over to Box2D to avoid any more of these headaches.

@TheSachin

This comment has been minimized.

TheSachin commented Jan 21, 2016

@minggo - I was just baffling around this. Any idea when this bug will be smashed?

@shauket

This comment has been minimized.

shauket commented Mar 18, 2016

one body should be setDynamic true

body->setDynamic(true);

@minggo minggo removed this from the unconfirmed milestone Aug 19, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment