对象方向的平滑插值以跟踪相机

Smooth interpolation of object orientation to track the camera

我有一个 SCNNode 表示玩家在第一人称游戏(使用 ARKit)中持有的物品。

我将节点设为相机的子节点,以便它始终在观察者面前漂浮一小段距离。但是这个简单的设置使项目非常静态,只是粘在屏幕上。

更现实地说,如果我在我面前拿着一个物体,然后转向另一个方向,我的手的动作会稍微落后于我的脑袋。如果我把头向上或向下倾斜,我对物体的视角也会发生轻微的变化。

我如何在 SceneKit 中模拟它?

This question 有一些关于延迟追逐节点的相机的想法,并且可能会反向工作。对于倾斜,也许我必须考虑加速度计,但要对其进行约束,以免物体旋转太多。

我没有将项目设为相机的子节点,而是将项目设为名为 arms 的新不可见节点的子节点。 arms 节点不是 camera 的子节点,但我使用 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 方向但是不是它的位置。

我发现虽然 距离 约束是完美的,但在方向上使用分数 influenceFactor 会导致 arms 发狂,旋转隔着屏幕疯狂!如果它是 1.0arms 节点严格跟随相机但没有故障。

原来,在SCNConstraint.influenceFactor的文档中,它说:

This property has no effect on SCNTransformConstraint objects.

嗯,我想知道为什么——节点的 transformpositionorientation 是可动画的,所以看起来它们可以顺利插值,没有问题。

原来有一种叫做Slerp的技术,它是一种在四元数之间进行插值的方法。因此,每次调用 SCNTransformConstraint 时,我都可以在 arms 的当前位置和相机的位置之间进行插值,而不是使用 influenceFactor。这是可以接受的平滑度。