如何将 SCNFloor 放置在真实的地板上?

How to place SCNFloor on real floor?

我想在真正的地板所在的地方添加一个scnfloor,但它出现在上面,当添加一个childNode时,对象并没有躺在地板上,而是看起来像在飞。

在记录添加的节点或平面锚点的位置时,无论我是扫描地板还是 table,我总是得到 y = 0

我错过了什么?还是不可能改变 scnfloor 的 y?但是在文档中写着

"...of its local coordinate space"

,所以我认为这是可能的。

谢谢

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    guard let planeAnchor = anchor as? ARPlaneAnchor else {return}
    let anchorX = planeAnchor.center.x
    let anchorY = planeAnchor.center.y
    let anchorZ = planeAnchor.center.z

    print("planeAnchor.center %@", planeAnchor.center) //y always 0
    print("node.position %@", node.position) //y always 0
    print("convert %@", node.convertPosition(SCNVector3(anchorX, anchorY, anchorZ), to: nil)) //y always 0

    let floor = SCNFloor()
    let floorNode = SCNNode(geometry: floor)
    floorNode.position = SCNVector3(anchorX, anchorY, anchorZ)
    let floorShape = SCNPhysicsShape(geometry: floor, options: nil)
    floorNode.physicsBody = SCNPhysicsBody(type: .static, shape: floorShape)
    node.addChildNode(floorNode)
    let childNode = createChildNode()
    floorNode.addChildNode(childNode)
}

锚点的 center.y 值将始终为零,这里有更多信息:https://developer.apple.com/documentation/arkit/arplaneanchor/2882056-center

基本上锚点变换会给出检测到的平面的正确位置。因此,您只需将 SCNFloor 实例添加为传入节点的子节点,它就会呈现在正确的位置,无需像上面那样显式设置位置。

随着 ARKit 细化平面边界,ARPlaneAnchor 的范围发生变化,您将需要更新几何尺寸。此处提供更多信息:https://developer.apple.com/documentation/arkit/tracking_and_visualizing_planes

例如,下面的代码对我有用,以最初检测到的平面大小渲染 SCNFloor,并渲染一个恰好位于其顶部的框。飞机准确地放在地板上(或您检测到的任何水平表面):

  func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    guard let planeAnchor = anchor as? ARPlaneAnchor else {
      return
    }

    let floor = SCNFloor()
    let floorNode = SCNNode(geometry: floor)
    floor.length = CGFloat(planeAnchor.extent.z)
    floor.width = CGFloat(planeAnchor.extent.x)
    node.addChildNode(floorNode)

    let box = SCNBox(width: 0.05, height: 0.05, length: 0.05, chamferRadius: 0)
    box.materials[0].diffuse.contents = UIColor.red
    let boxNode = SCNNode(geometry: box)
    boxNode.position = SCNVector3(0, 0.025, 0)

    node.addChildNode(boxNode)
  }