我没有让该项目成为相机的子项,而是让该项目成为一个名为arms 的新不可见节点的子项。 arms 节点不是相机的子节点,但我使用了 SCNTransformConstraint 来约束其转换,如下所示:
// ~~ Not the final code ~~ Do not use ~~
// Set up the viewer's "arms" to follow the camera using a dampened constraint
arms = SCNNode()
let armconstraint = SCNTransformConstraint.init(inWorldSpace: false) {
(node: SCNNode, _) -> SCNMatrix4 in
// Bind the arm's transformation to the camera's
return self.sceneView.pointOfView!.convertTransform(SCNMatrix4Identity, to: node)
}
armconstraint.influenceFactor = 0.5
arms!.constraints = [ armconstraint ]
sceneView.scene.rootNode.addChildNode(arms!)
使用较低的influenceFactor 的想法,这样arms 就不会被固定在镜头前,而是稍微延迟一下。
效果一般;它可能会很生涩。因此,我尝试将其拆分为两个单独的约束:SCNDistanceConstraint 保持相机和arms 之间的距离为 0,SCNTransformConstraint 同步 arms 方向但不同步其位置。
我发现虽然 distance 约束完美无缺,但在方向上使用分数 influenceFactor 会导致 arms 发狂,在屏幕上疯狂旋转!如果是1.0,则arms 节点会严格地跟随相机,但不会出现故障。
事实证明,在SCNConstraint.influenceFactor 的文档中,它说:
此属性对SCNTransformConstraint 对象没有影响。
嗯,我想知道为什么 - 一个节点的 transform、position 和 orientation 是可动画的,所以看起来它们可以平滑地插值没有问题。
事实证明有一种称为Slerp 的技术,它是一种在四元数之间进行插值的方法。因此,每次调用我的SCNTransformConstraint 时,我都可以在arms 的当前位置和相机的位置之间进行插值,而不是使用influenceFactor。这是可以接受的平滑。