Pixel Perfect Collision Detection in Cocos2dx
Asked Answered
K

2

6

I am trying to port the pixel perfect collision detection in Cocos2d-x the original version was made for Cocos2D and can be found here: http://www.cocos2d-iphone.org/forums/topic/pixel-perfect-collision-detection-using-color-blending/

Here is my code for the Cocos2d-x version

bool CollisionDetection::areTheSpritesColliding(cocos2d::CCSprite *spr1, cocos2d::CCSprite *spr2, bool pp, CCRenderTexture* _rt) {
    bool isColliding = false;
    CCRect intersection;
    CCRect r1 = spr1->boundingBox();
    CCRect r2 = spr2->boundingBox();
    intersection = CCRectMake(fmax(r1.getMinX(),r2.getMinX()), fmax( r1.getMinY(), r2.getMinY()) ,0,0);
    intersection.size.width = fmin(r1.getMaxX(), r2.getMaxX() - intersection.getMinX());
    intersection.size.height = fmin(r1.getMaxY(), r2.getMaxY() - intersection.getMinY());

    // Look for simple bounding box collision
    if ( (intersection.size.width>0) && (intersection.size.height>0) ) {
        // If we're not checking for pixel perfect collisions, return true
        if (!pp) {
            return true;
        }

        unsigned int x = intersection.origin.x;
        unsigned int y = intersection.origin.y;
        unsigned int w = intersection.size.width;
        unsigned int h = intersection.size.height;
        unsigned int numPixels = w * h;
        //CCLog("Intersection X and Y %d, %d", x, y);
        //CCLog("Number of pixels %d", numPixels);

        // Draw into the RenderTexture
        _rt->beginWithClear( 0, 0, 0, 0);

        // Render both sprites: first one in RED and second one in GREEN
        glColorMask(1, 0, 0, 1);
        spr1->visit();
        glColorMask(0, 1, 0, 1);
        spr2->visit();
        glColorMask(1, 1, 1, 1);

        // Get color values of intersection area
        ccColor4B *buffer = (ccColor4B *)malloc( sizeof(ccColor4B) * numPixels );
        glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

        _rt->end();

        // Read buffer
        unsigned int step = 1;
        for(unsigned int i=0; i 0 && color.g > 0) {
                isColliding = true;
                break;
            }
        }

        // Free buffer memory
        free(buffer);
    }


    return isColliding;
}

My code is working perfectly if I send the "pp" parameter as false. That is if I do only a bounding box collision but I am not able to get it working correctly for the case when I need Pixel Perfect collision. I think the opengl masking code is not working as I intended.

Here is the code for "_rt"

    _rt = CCRenderTexture::create(visibleSize.width, visibleSize.height);
    _rt->setPosition(ccp(origin.x + visibleSize.width * 0.5f, origin.y + visibleSize.height * 0.5f));
    this->addChild(_rt, 1000000);
    _rt->setVisible(true); //For testing

I think I am making a mistake with the implementation of this CCRenderTexture

Can anyone guide me with what I am doing wrong ?

Thank you for your time :)

Kerouac answered 31/8, 2013 at 8:16 Comment(1)
Now that iOS uses metal, were you able to port cocos2d-x v4 ?Valvule
K
3

Finally solved the problem. Had to use custom opengl fragment shaders to shade one of the sprites completely RED and the other completely BLUE and then looping through glReadPixels values to find any pixel having both RED and BLUE pixels. (Blending has to be considered as well, we do not want to replace one pixel value by the other)

In-Depth information can be found on my blog post http://blog.muditjaju.infiniteeurekas.in/?p=1

Kerouac answered 27/9, 2013 at 7:48 Comment(0)
R
1

You are not stepping through the buffer properly.

// Read buffer
unsigned int step = 1;
for(unsigned int i=0; i<numPixels; i+=step)
{
    ccColor4B color = buffer;

    if (color.r > 0 && color.g > 0)
    {
        isCollision = YES;
        break;
    }
}

source: http://www.cocos2d-iphone.org/forums/topic/pixel-perfect-collision-detection-using-color-blending/#post-337907

Rosemare answered 2/9, 2013 at 3:13 Comment(1)
I am sorry .. I made a wrong copy paste. I changed that in the question above now .. But the problem still remainsKerouac

© 2022 - 2024 — McMap. All rights reserved.