为什么 SCNNode.presentation.position 相对较慢,有解决方法吗?

Why is SCNNode.presentation.position so relatively slow, and is there a workaround?

我将我的 SceneKit 应用程序中的一个主要性能瓶颈追溯到 运行 几千次的嵌套循环。在那个循环中,除了这一行之外,还有一堆代码可以非常愉快地缩放:

var scenePos = presentation.position

它比仅询问位置慢 100 多倍,再加上我在同一个循环中进行的许多其他计算、比较、数组查找和方法调用的组合。令我惊讶的是,似乎还没有人对此发表评论,我能找到。

为什么会这样,除了每帧自己复制每个节点的 presentation.position 之外,是否有解决方法,这样您就不必一直向演示节点询问它?谢谢

编辑:presentation.position 只被读取,从未被写入。没有边界框被编辑过。我为一些 SCNNode 使用动态 SCNPhysicsBody,但绝大多数是静态的。

这是我目前正在使用的解决方法(为此,还有一个单独的问题,即如果该节点的物理从未 运行,则 presentation.position 可以为零)。它快了几个数量级,因为我几乎所有的节点都不是动态的。

// When you're not sure if physics has first run yet
func currentScenePos() -> SCNVector3 {
    if physicsBody?.type == .dynamic {
        var scenePos = presentation.position
        if scenePos.isZero() {
            // Looks like the physics hasn't run on this node yet. Use the regular position.
            // If that's zero too, it must really be at the scene origin.
            scenePos = position
        }
        return scenePos
    } else {
        // Non-dynamic physics. Just use position, it's a lot faster.
        return position
    }
}

我目前正在解决对 presentation.transform 的引用永远挂起的错误。文档说对 SceneKit 数据的引用(例如 SCNNodes)是线程安全的。例如。如果另一个进程(或 3D 硬件)正在使用该节点,它们将等待互斥锁。虽然我还没有发现谁在我的情况下持有锁(可能是一个愚蠢的程序错误),但让我震惊的是阅读你的 post 如果 3D 硬件正在使用节点,你可能会等待几毫秒直到它是通过。这可能会导致您的性能问题。