On any one node, rotation, translation, and scale transforms are independent of each other. They are each applied to the rest pose of the node, and are not accummulative with each other. This is so that interaction appears natural and expected by the developer controlling the node. In other words, during gameplay, rotating a character after it has been moved, rotates the character in place, not around a translated location. Similarly, translating a node translates it regardless of how the node has previously been rotated.
This is different control than taking a single matrix and accumulating transforms into it, which is how the matrix-based rotate-around-a-distant-point technique works.
However, you can effectively rotate a node around a location that is not its origin by:
- Transforming the local rotation location to the global coordinate space.
- Rotating the node as normal.
- Transforming the (now rotated) local rotation location to the global coordinate space.
- Align the rotation locations found in steps 1 & 3 by translating the node by the difference between the two locations.
You can perform steps 1 & 3 using the node's globalTransformMatrix
. Code for the steps above is as follows:
CC3Vector gblRotLocBefore = [aNode.globalTransformMatrix transformLocation: rotationLoc];
[aNode rotateByAngle: angle aroundAxis: kCC3VectorUnitYPositive];
CC3Vector gblRotLocAfter = [aNode.globalTransformMatrix transformLocation: rotationLoc];
[aNode translateBy: CC3VectorDifference(gblRotLocBefore, gblRotLocAfter)];
Using this technique, you do not need to involve the node's parent.