将Scenekit节点附加到ARAnchor只是将节点的变换设置为锚点的变换吗?

时间:2018-12-10 10:05:22

标签: scenekit arkit

我读到要在AR场景中使“虚拟对象似乎相对于现实世界保持原状”,应该使用ARAnchors。

  • 除了仅将节点的变换设置为锚的变换值外,我是否可以将Scenekit节点附加到我创建的锚上?对我来说,这看起来并不像将其附加到锚点上,而是将它们放置在相同的3D位置上。
  • 这不会告诉ARKit在锚的变换发生变化时更新节点变换。我对吗?在这种情况下,我真的看不到使用锚点的意义。

1 个答案:

答案 0 :(得分:0)

ARKit管理锚的位置,并通过任何必要的转换来扩展连接到锚的节点。因此,附着节点的相对位置基本上保持不变,但是锚的位置可能会发生变化。您还可以设置约束,以使朝向相机或其他节点的旋转始终相同。

因此,问题1:相对于锚定转换,它可以是任何转换。 问题2:请参阅上面的说明,节点到锚点的相对转换保持不变,但是锚点位置可能会发生变化。

在固定位置添加球体并在其上方始终将始终面向摄像机的文本标签的示例:

func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {

    guard let featureAnchor = anchor as? FeatureAnchor else {
        return nil
    }
    let feature = featureAnchor.feature

    let billboardConstraint = SCNBillboardConstraint()
    billboardConstraint.freeAxes = SCNBillboardAxis.Y

    let sphere = SCNSphere(radius: Global.dotRadius)
    sphere.firstMaterial?.transparency = Global.annotationTransparency
    sphere.firstMaterial?.diffuse.contents = UIColor.yellow
    sphere.firstMaterial?.specular.contents = UIColor.white
    let node = SCNNode(geometry: sphere)
    node.constraints = [billboardConstraint]

    let text = SCNText(string: feature.description, extrusionDepth: Global.textDepth)
    text.chamferRadius = Global.textDepth
    text.firstMaterial?.transparency = Global.annotationTransparency
    text.firstMaterial?.diffuse.contents = UIColor.green
    text.firstMaterial?.specular.contents = UIColor.white
    text.firstMaterial?.isDoubleSided = true
    text.font = Global.textFont
    text.alignmentMode = kCAAlignmentCenter

    let (min, max) = text.boundingBox
    let dx: Float = (max.x - min.x) / 2.0 // x = center
    let dy: Float = min.y // y = bottom
    let dz: Float = Float(Global.textDepth) / 2.0 // z = center

    let textNode = SCNNode(geometry: text)
    textNode.pivot = SCNMatrix4MakeTranslation(dx, dy, dz)
    textNode.scale = SCNVector3Make(Global.textScale, Global.textScale, Global.textScale)

    node.addChildNode(textNode)

    return node
}