【问题标题】:Why is SCNNode.presentation.position so relatively slow, and is there a workaround?为什么 SCNNode.presentation.position 相对较慢,有解决方法吗?
【发布时间】:2019-07-03 13:11:51
【问题描述】:

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

var scenePos = presentation.position

它比我在同一个循环中执行的仅询问位置加上数十种其他计算、比较、数组查找和方法调用相结合要慢 100 倍以上。我很惊讶似乎没有人对此发表评论,但我能找到。

为什么会这样,除了复制每个节点的演示文稿之外,还有其他解决方法吗?在每个帧中定位自己,这样您就不必一直询问演示文稿节点了吗?谢谢。

编辑:presentation.position 只会被读取,不会被写入。从未编辑过boundingBox。我正在为一些 SCNNode 使用动态 SCNPhysicsBody,但绝大多数是静态的。

【问题讨论】:

  • 您如何使用presentation.position?你在改变它吗? Apple 的文档说,如果您尝试更改 presentation.position,可能会导致一些未定义的行为。
  • 我刚刚检查并确认 - 在整个应用程序中显示。位置只是被读取,从未被写入。
  • 我的猜测是多次调用表示节点不会返回完全相同的对象。文档说它返回节点的副本,看起来几何形状每次都在变化。只需按照您的建议进行操作,然后在循环之外创建一个副本。
  • @JamesP 所以每次查询演示文稿时它都会以非常昂贵的方式创建对象?这太糟糕了,但我不会把它放在 SceneKit 之外!请把这个放在答案中,如果这是最好的猜测,我可以赏金你:)

标签: ios performance scenekit scnnode


【解决方案1】:

这是我目前正在使用的解决方法(为此,如果从未为该节点运行物理,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
    }
}

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2011-11-13
      • 1970-01-01
      • 1970-01-01
      • 2016-07-08
      • 2020-11-11
      • 1970-01-01
      • 1970-01-01
      • 2017-10-23
      • 2012-02-28
      相关资源
      最近更新 更多