【发布时间】:2017-07-22 22:42:30
【问题描述】:
目标是增加 SCNBox 的长度,使其仅在正 z 方向上增长。
This answer 建议使用pivot 属性。
但是,pivot 属性的文档在 SCNNode 页面上是稀疏的,在 SCNBox 页面上什么都没有。
有人可以解释pivot 属性的工作原理吗?
【问题讨论】:
目标是增加 SCNBox 的长度,使其仅在正 z 方向上增长。
This answer 建议使用pivot 属性。
但是,pivot 属性的文档在 SCNNode 页面上是稀疏的,在 SCNBox 页面上什么都没有。
有人可以解释pivot 属性的工作原理吗?
【问题讨论】:
更改节点的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)
如果你想让SCNBox的length只在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 中,锚点被指定为相对于图层的边界框(从0 到1 的百分比为层的宽度和高度),而在 SceneKit 中它是绝对的。
【讨论】:
假设你有一个这样创建的盒子:
SCNBox(width: 1, height: 1, length: 1, chamferRadius: 0)
轴心点将位于该框的中心,您现在要将其移动到边缘之一。这可以通过将枢轴节点平移 0.5 来完成。 (这是盒子宽度的一半或中心和边缘之间的距离。)
boxNode.pivot = SCNMatrix4MakeTranslation(0, 0, -0.5)
轴心点现在将位于对象的中心 X、中心 Y 和零 Z。如果你现在缩放盒子,它只会在 Z 正方向上增长。
【讨论】:
听起来你想增加 SCNBox(几何)的长度。所以你可以简单地增加长度属性。您提到的答案是关于 pivot 属性。从文档中可以看出:
节点位置、旋转和缩放的轴心点。
例如,通过将枢轴设置为平移变换,您可以将包含球体几何形状的节点相对于球体放置在地板上的位置而不是相对于其中心定位。
【讨论】: