8

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?

Community
  • 1
  • 1
Crashalot
  • 33,605
  • 61
  • 269
  • 439

3 Answers3

20

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

  • min: (-0.5 * width, -0.5 * height, -0.5 * length)
  • max: (+0.5 * width, +0.5 * height, +0.5 * length)
  • center: (0.0, 0.0, 0.0)

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

  • min: (-0.5 * width, -0.5 * height, 0.0)
  • max: (+0.5 * width, +0.5 * height, length)
  • center: (0.0, 0.0, +0.5 * length)

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.

mnuages
  • 13,049
  • 2
  • 23
  • 40
  • 2
    Thanks so much for this detailed explanation. SceneKit is awesome, but it is frustrating because the documentation is so poor, which I know is not your fault. And since it's so new, there aren't many experts around to help if you get stuck. Does Apple plan on dedicating more resources to beefing up SceneKit documentation in the future? – Crashalot Mar 05 '17 at 21:59
6

Say you have a box created like this:

SCNBox(width: 1, height: 1, length: 1, chamferRadius: 0)

The pivot point will be in the center of that box, you now want to move it to one of the edges. This can be done by translating the pivot node by 0.5. (This is half the width of the box or the distance between the center and the edge.)

boxNode.pivot = SCNMatrix4MakeTranslation(0, 0, -0.5)

The pivot point will now be located at center X, center Y, and zero Z of the object. If you now scale the box it will only grow in the positive Z direction.

James P
  • 4,786
  • 2
  • 35
  • 52
  • Cool, this looks awesome. Will try it. Most importantly, where did you find this documentation? Thanks again! – Crashalot Mar 03 '17 at 13:43
  • I didn't, I just experimented with the help of the answer you linked and looked at the results. – James P Mar 03 '17 at 13:49
  • BTW would you be interested in consulting on SceneKit? Very micro-jobs like creating a halo/ripple animation? – Crashalot Mar 05 '17 at 21:53
  • Thanks, but I'm very much a beginner with SceneKit, I'm only experimenting with it at the moment. – James P Mar 06 '17 at 09:42
  • Then micro-consulting could benefit us both: you offer a discounted rate so we benefit from lower cost and you benefit from getting paid to learn on our dime. What do you think? – Crashalot Mar 07 '17 at 00:15
0

Sounds like you want to increase the length of the SCNBox(a geometry). So you can simply increase the length property. The answer you mentioned is about the pivot property. As you can see from the doc:

The pivot point for the node’s position, rotation, and scale.

For example, by setting the pivot to a translation transform you can position a node containing a sphere geometry relative to where the sphere would rest on a floor instead of relative to its center.

HaoDong
  • 339
  • 1
  • 10
  • Thanks, but increasing the length increases the box size in both the positive-z axis and the negative-z axis. We only want increases on the positive-z axis. – Crashalot Mar 03 '17 at 10:06