scenekitscnnodescnscene

SceneKit: understanding the pivot property of SCNNode


The goal is to increase the length of a SCNBox such that it only grows in the positive-z direction.

This answer suggests playing with the pivot property.

However, the documentation for the pivot property is sparse on the SCNNode page, and there is nothing on the SCNBox page.

Can someone explain how the pivot property works?


Solution

  • Changing a node's pivot is conceptually the same as inserting an intermediate node between this node and its parent. This can be useful in different cases. One example is when the center of the node's geometry isn't where you expect it to be.

    For instance if you have an SCNBox, it's bounding box is

    If you want the length of the SCNBox to only increase in the positive Z axis, then what you want is

    A geometry's bounding box will never change, but there are ways to arrange nodes and change their bounding boxes.


    Solution 1: Intermediate node

    One common solution when dealing with transforms is to use intermediate nodes to get a better understanding of how the transforms are applied.

    In your case you will want to change the node hierarchy from

    - parentNode
      | - node
      |   * geometry
      |   * transform = SCNMatrix4MakeScale(...)
    

    to

    - parentNode
      | - intermediateNode
      |   * transform = SCNMatrix4MakeScale(...)
      |   | - node
      |   |   * geometry
      |   |   * transform = SCNMatrix4MakeTranslation(0, 0, +0.5 * length)
    

    With this new hierarchy, the center of the bounding box of node is still (0.0, 0.0, 0.0), but the center of the bounding box of intermediateNode is (0.0, 0.0, +0.5 * length).

    By scaling intermediateNode instead of node you'll obtain the wanted result.

    Solution 2: Pivot

    It turns out that's exactly what the pivot property does:

    node.pivot = SCNMatrix4MakeTranslation(0, 0, -0.5 * length);
    

    Once you have mentally figured out the transform of the intermediate node, simply set its inverse to the pivot property.


    You can find more information about the pivot property here: https://developer.apple.com/reference/scenekit/scnnode/1408044-pivot

    This is very similar to Core Animation's anchorPoint property on CALayer, except that in Core Animation the anchor point is specified as relative to the layer's bounding box (goes from 0 to 1 as a percentage of the layer's width and height), while in SceneKit it's absolute.