【问题标题】:didAddNode vs SceneKit Collision DetectiondidAddNode 与 SceneKit 碰撞检测
【发布时间】:2023-04-09 13:22:01
【问题描述】:

我正在构建一个小型演示,其中两个对象可以相互碰撞。基本上,一个对象将被放置在一个平面上。我有以下代码用于将物理体添加到飞机。

 func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {

        if anchor is ARPlaneAnchor {


            let plane = SCNPlane(width: 0.5, height: 0.5)
            let material = SCNMaterial()
            material.isDoubleSided = true
            material.diffuse.contents = UIImage(named: "overlay_grid")
            plane.firstMaterial = material

            let planeNode = SCNNode(geometry: plane)
            planeNode.physicsBody = SCNPhysicsBody(type: .static, shape: nil)
            planeNode.physicsBody?.categoryBitMask = BodyType.plane.rawValue

            planeNode.eulerAngles.x = .pi/2

            node.addChildNode(planeNode)

}

即使添加了飞机,它也不会参与任何物理碰撞。如果我试图在上面放置物体,它会直接穿过它。但是,如果我将最后一行更改为以下内容,则可以:

// node.addChildNode(planeNode) // INSTEAD OF THIS
   planeNode.position = SCNVector3(anchor.transform.columns.3.x, anchor.transform.columns.3.y, anchor.transform.columns.3.z)
 self.sceneView.scene.rootNode.addChildNode(planeNode) // THIS WORKS

我的理解是,所有与碰撞相关的东西都由 SceneView 维护,为了参与碰撞,我需要将其添加到 SceneView 层次结构而不是 ARSCNView 层次结构。

问题:

// node.addChildNode(planeNode) // WHY THIS DOES NOT WORK
   planeNode.position = SCNVector3(anchor.transform.columns.3.x, anchor.transform.columns.3.y, anchor.transform.columns.3.z)

 self.sceneView.scene.rootNode.addChildNode(planeNode) // WHY THIS WORKS

【问题讨论】:

  • 有什么问题?
  • 请参阅上面的更新问题。

标签: ios scenekit arkit


【解决方案1】:

static 物理物体之所以如此命名是因为它们不应该移动(相对于全局/世界/场景坐标空间)。物理引擎内部工作的许多优化都依赖于此,因此更改具有附加静态物理主体的节点的位置可能会导致不正确的行为。

ARKit 不断移动平面检测产生的ARPlaneAnchors - 它从更多不同的角度观察真实世界平面表面的时间越长,它就越能知道该平面的位置和大小。

当您将子节点添加到renderer(_:didAdd:for:) 中的ARSCNView 托管节点时,子节点的position 可能不会改变...但该位置相对于其父节点,ARKit 会自动移动父节点节点匹配 ARPlaneAnchor 它。因此,每当 ARKit 更新平面锚点时,子节点都会相对于世界移动。如果你在那个节点上有一个静态物理体,你会觉得很奇怪。

当您直接添加一个节点作为场景的rootNode 的子节点并设置其位置基于平面锚的初始时,该节点保持静止 - 你是唯一一个设置它的世界空间位置的人,而且你只做了一次。所以给它一个静态物理体是安全的。

(请注意,如果您想要“静态”物理体行为随着时间的推移而变化,可以删除物理体并在新位置重新创建它。只是不要太频繁或您可能正在击败物理引擎中的其他优化。)

【讨论】:

  • 我没有添加完整的场景。静止的身体是地板,我正趴在地板上。物体刚刚穿过地板。但是当我将它们添加到 SceneKit rootNode 时,它​​们开始发生碰撞。
猜你喜欢
  • 1970-01-01
  • 2017-01-07
  • 2019-07-16
  • 2021-02-01
  • 2015-02-06
  • 2018-06-09
  • 2018-02-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多