SceneKit:理解 SCNNode 的 pivot 属性

Posted

技术标签:

【中文标题】SceneKit:理解 SCNNode 的 pivot 属性【英文标题】:SceneKit: understanding the pivot property of SCNNode 【发布时间】:2017-07-22 22:42:30 【问题描述】:

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

This answer 建议使用pivot 属性。

但是,pivot 属性的文档在 SCNNode 页面上是稀疏的,在 SCNBox 页面上什么都没有。

有人可以解释pivot 属性的工作原理吗?

【问题讨论】:

【参考方案1】:

更改节点的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)

几何体的边界框永远不会改变,但有一些方法可以排列节点并改变它们的边界框。


解决方案 1:中间节点

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

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

- 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 中它是绝对的。

【讨论】:

非常感谢您的详细解释。 SceneKit 很棒,但令人沮丧,因为文档太差了,我知道这不是你的错。而且由于它是如此新,如果您遇到困难,周围没有多少专家可以提供帮助。 Apple 是否计划在未来投入更多资源来完善 SceneKit 文档?【参考方案2】:

假设你有一个这样创建的盒子:

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

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

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

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

【讨论】:

酷,这看起来棒极了。会试试的。最重要的是,您在哪里找到此文档?再次感谢! 我没有,我只是在您链接的答案的帮助下进行了实验并查看了结果。 顺便说一句,您有兴趣咨询 SceneKit 吗?像制作光环/波纹动画这样的非常微小的工作? 谢谢,但我是 SceneKit 的初学者,目前只是在尝试。 那么微咨询可以使我们双方都受益:您提供折扣价,因此我们可以从较低的成本中受益,而您也可以从获得报酬中受益,从而用我们的一角钱学习。你怎么看?【参考方案3】:

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

节点位置、旋转和缩放的轴心点。

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

【讨论】:

谢谢,但是增加长度会增加正 z 轴和负 z 轴的框大小。我们只希望在正 z 轴上增加。

以上是关于SceneKit:理解 SCNNode 的 pivot 属性的主要内容,如果未能解决你的问题,请参考以下文章

SceneKit - 在另一个 SCNNode 上添加 SCNNode

在 SceneKit 中缩放 SCNNode

SceneKit - 如何知道带有 MDLObject 的 SCNNode 是不是已加载并可见?

如何在 SceneKit 中移动旋转的 SCNNode?

SceneKit:缩放 SCNNode 不会按预期量改变大小

将 collada (dae) 文件加载到 SCNNode (Swift - SceneKit)