3.0-beta2 convertToNodeSpace giving bad Y values in child of scaled layer

All,

I’m having an issue where convertToNoceSpace is giving me odd results when the node is the child of a scaled layer.



    //GamePiece inherits from CCSprite and is a child of a layer which zooms and pans.
    bool GamePiece::overlaps(Point target){
        //First do quick test against bounding box then check actual area
        Point inParent = getParent()->convertToNodeSpace(target);
  
        //Debug code. Normally area->overlaps gets passed world-space pt and 
        //  calls convertToNodeSpace on it. That's what broke initially, this 
        //  is a simplified case.
        Point inThis   = convertToNodeSpace(target);
        Point inThis2  = PointApplyTransform(inParent, getParentToNodeTransform());
        if (_id == 1){
            log("(%f,%f)\n Parent->(%f,%f)\n Piece-->(%f,%f)\n area--->(%f, %f) %d", 
                target.x, target.y,
                inParent.x, inParent.y,
                inThis.x, inThis.y,
                inThis2.x, inThis2.y,
                area->overlaps(target, true));
        }//end - skip if not the piece #1
        //end debug 
    
        if (!getBoundingBox().containsPoint(inParent)){
            return false; 
        }
        return area->overlaps(target, false);
    }//end overlaps()`

My understanding is that the variable inThis and inThis2 should be identical since the process by which they are generated is really the same thing (it looks like convertToNodeSpace just builds up ParentToNode transforms for all the parents and then applies it).

This function gets called on a click so I clicked my sprite twice. Once with no zoom and once zoomed out 10%. I get the following [other random statments edited out].

(175.422424,439.042419)
Parent->(992.243103,950.259644)
Piece–>(24.740387,22.243103)
area—>(24.740356, 22.243103) 0
(197.796066,434.259644)
Parent->(994.018677,950.529846)
Piece–>(24.470184,219.773422)
area—>(24.470154, 24.018677) 0

The slightly different world space coordinates make sense since the sprite I’m clicking on moved as I zoomed and I didn’t move it back to quite the exact same spot. As expected the layer coordinates and the two step convert to node space don’t change. (The position withing the object which I could see was much more accurate) However, the Y value using the first method is dramatically different.

A few other observations which I have not triple checked but which seem to be the case.
1.) The values appear to be correct (no issue) when the sprite is on the right half of the screen.
2.) The Y value error does not appear to be related to the amount of scaling (it gets bigger then smaller then bigger again as I continually zoom out).
3.) I tried both the released beta2 version and the current development branch (as of 8pm today) both behaved the same.
4.) I did not try this with the alpha. And convertToNodespace did work the way I expected in v2.2.2. (I’m moving to 3.0 for the fancy network support :slight_smile:

Am I correct in assuming that they both methods should yield the same result? If so any ideas what might be going on?

I think there is a bug in getNodeToParentTransform. Check out my pull request for the solution
https://github.com/cocos2d/cocos2d-x/pull/5030

Oleg,
Thanks!

The bad news is that a simple switch of the kmMat4Multiply parameters in getNodeToWorldTransform in didn’t fix the problem (made it a bit worse actually).

The good news is that after reading that and poking around CCNode.cpp I figured out that the Affine version of the same thing appears to work correctly. So I now have a much simpler workaround.

inThis = convertToNodeSpace(target); //Doesn’t work when scaled
inThis = PointApplyAffineTransform(target, getWorldToNodeAffineTransform()); // works just fine when scaled.

How should I proceed with what looks to be a bug? Should I submit it as a bug (and where would I do that)? Should I comment on that pull request (in case my observation helps locate the root cause issue)? Should I just keep my mouth shut and let the experts handle it :wink:
I’m not familiar with how cocos generally operates (and in general I’m new to contributing in a community like this) so a (gentle) shove in the right direction would be appreciated.

Finally, a lot of this matrix math is a bit out of my league but I’m interested in learning. I’d like to understand what the difference between the Affine and non-Affine versions of the transforms functions are. It appears that the regular convertToNodeSpace operates on a transform that is a sub-set of the Affine transform, but at the root they are doing the same thing (both contain the data from getNodeToParentTransform()).
If information on exactly what’s going on here exists I’d love to read through it.

Thanks again for pointing me in the right direction!

Endercroft,
I am not an expert too :slight_smile:
I might be wrong as well, but please don’t keep your mouth shut.
If you think something works not how it should work report about that at
http://www.cocos2d-x.org/projects/native/issues/new