SceneKit:了解 SCNNode 的枢轴 属性

SceneKit: understanding the pivot property of SCNNode

目标是增加 SCNBox 的长度,使其仅在正 z 方向增长。

This answer 建议使用 pivot 属性.

然而,pivot 属性 的文档在 SCNNode 页面上是稀疏的,并且在 SCNBox 页面上没有任何内容。

谁能解释一下 pivot 属性 是如何工作的?

听起来您想增加 SCNBox(一个几何体)的长度。所以你可以简单地增加长度属性。你提到的答案是关于 pivot 属性。从文档中可以看出:

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

例如,通过将枢轴设置为平移变换,您可以将包含球体几何体的节点定位到相对于球体在地板上的位置而不是相对于其中心的位置。

假设您创建了一个这样的盒子:

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

枢轴点将位于该框的中心,您现在要将其移至其中一条边。这可以通过将枢轴节点平移 0.5 来完成。 (这是盒子宽度的一半或中心与边缘之间的距离。)

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

轴心点现在将位于对象的中心 X、中心 Y 和零 Z。如果现在缩放框,它只会在正 Z 方向增长。

更改节点的 pivot 在概念上与在此节点与其父节点之间插入中间节点相同。这在不同情况下很有用。一个例子是当节点的几何中心不在您期望的位置时。

例如,如果你有一个 SCNBox,它的边界框是

  • 分钟:(-0.5 * width, -0.5 * height, -0.5 * length)
  • 最大值:(+0.5 * width, +0.5 * height, +0.5 * length)
  • 中心:(0.0, 0.0, 0.0)

如果你想让SCNBoxlength只在Z轴正方向增加,那么你要的是

  • 分钟:(-0.5 * width, -0.5 * height, 0.0)
  • 最大值:(+0.5 * width, +0.5 * height, length)
  • 中心:(0.0, 0.0, +0.5 * length)

几何体的边界框永远不会改变,但可以通过多种方式排列节点并更改它们的边界框。


方案一:中间节点

处理转换时的一个常见解决方案是使用中间节点来更好地理解如何应用转换。

在您的情况下,您需要更改节点层次结构

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

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

有了这个新的层次结构,node 的边界框中心仍然是 (0.0, 0.0, 0.0),但是 intermediateNode 的边界框中心是 (0.0, 0.0, +0.5 * length)

通过缩放 intermediateNode 而不是 node,您将获得想要的结果。

解决方案 2:旋转

事实证明,这正是 pivot 属性 所做的:

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

一旦你在脑海中想出了中间节点的变换,只需将其 inverse 设置为 pivot 属性.


您可以在此处找到有关 pivot 属性 的更多信息:https://developer.apple.com/reference/scenekit/scnnode/1408044-pivot

这与 CALayer 上的 Core Animation 的 anchorPoint 属性 非常相似,除了在 Core Animation 中锚点被指定为相对于层的边界框(来自 01 作为图层宽度和高度的百分比),而在 SceneKit 中它是绝对值。