如何保持 ARKit SCNNode 到位 [英] How to keep ARKit SCNNode in place

查看:28
本文介绍了如何保持 ARKit SCNNode 到位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嘿,我想弄清楚.如何保持一个简单的节点就位.当我在 ARKit 中四处走动时

Hey I'm trying to figure out. How to keep a simple node in place. As I walk around it in ARKit

代码:

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

    if let planeAnchor = anchor as? ARPlaneAnchor {

    if planeDetected == false { // Bool only allows 1 plane to be added
            planeDetected = true
        self.addPlane(node: node, anchor: planeAnchor)
    }

    }
}

这会添加 SCNNode

This adds the SCNNode

    func addPlane(node: SCNNode, anchor: ARPlaneAnchor) {

    // We add the anchor plane here

    let showDebugVisuals = Bool()
    let plane = Plane(anchor, showDebugVisuals)
    planes[anchor] = plane
    node.addChildNode(plane)



    // We add our custom SCNNode here 

    let scene = SCNScene(named: "art.scnassets/PlayerModel.scn")!
    let Body = scene.rootNode.childNode(withName: "Body", recursively: true)!

    Body.position = SCNVector3.positionFromTransform(anchor.transform)
    Body.movabilityHint = .movable
    wrapperNode.position = SCNVector3.positionFromTransform(anchor.transform)

    wrapperNode.addChildNode(Body)

    scnView.scene.rootNode.addChildNode(wrapperNode)

我尝试添加一个平面/锚节点并将身体"节点放入其中,但它仍然会移动.我想可能和更新功能有关.

Ive tried adding a Plane/Anchor Node and putting the "Body" node in that but it still moves. I thought maybe it has something to do with the update function.

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

或者很可能是位置设置

wrapperNode.position = SCNVector3.positionFromTransform(anchor.transform)

我浏览了互联网上的每个源/项目文件/视频,但没有人对这个简单的问题有简单的解决方案.

Iv'e looked through every source / project file / video on the internet and nobody has a simple solution to this simple problem.

推荐答案

这里可能会发生两种四处走动".

There are two kinds of "moving around" that could be happening here.

一个是 ARKit 不断完善其对设备在现实世界中的位置如何映射到您放置虚拟内容的抽象坐标空间的估计.例如,假设您将一个虚拟对象放在 (0, 0, -0.5),然后将您的设备向左移动 10 厘米.只有当 ARKit 精确跟踪移动时,虚拟对象才会出现在物理空间中.但是视觉惯性里程计并不是一门精确的科学,所以 ARKit 可能认为你向左移动了 10.5 厘米——在这种情况下,你的虚拟物体看起来会向右滑动"5 毫米,即使它ARKit/SceneKit 坐标空间中的位置保持不变.

One is that ARKit is continuously refining its estimate of how the device's position in the real world maps to the abstract coordinate space you're placing virtual content in. For example, suppose you put a virtual object at (0, 0, -0.5), and then move your device to the left by exactly 10 cm. The virtual object will appear to be anchored in physical space only if ARKit tracks the move precisely. But visual-inertial odometry isn't an exact science, so it's possible that ARKit thinks you moved to the left by 10.5 cm — in that case, your virtual object will appear to "slip" to the right by 5 mm, even though its position in the ARKit/SceneKit coordinate space remains constant.

除了希望 Apple 制造具有更好传感器、更好摄像头或更好 CPU/GPU 的设备并改进世界跟踪科学之外,您对此无能为力.(在时间充足的情况下,这可能是一个安全的赌注,尽管这可能对您当前的项目没有帮助.)

You can't really do much about this, other than hope Apple makes devices with better sensors, better cameras, or better CPUs/GPUs and improves the science of world tracking. (In the fullness of time, that's probably a safe bet, though that probably doesn't help with your current project.)

由于您还要处理平面检测,所以还有一个问题.ARKit 不断完善其对检测到的平面位置的估计.所以,即使飞机的真实世界位置没有改变,它在 ARKit/SceneKit 坐标空间中的位置也是.

Since you're also dealing with plane detection, there's another wrinkle. ARKit is continuously refining its estimates of where a detected plane is. So, even though the real-world position of the plane isn't changing, its position in ARKit/SceneKit coordinate space is.

这种运动通常是一件好事 - 如果您希望虚拟对象看起来锚定在现实世界的表面上,您需要确定该表面的位置.随着平面检测更加确定表面的位置,您会看到一些移动,但是在很短的时间之后,当您为平面锚定的虚拟对象移动相机时,您应该看到的滑动"比那些只是漂浮在世界中的虚拟对象更少空间.

This kind of movement is generally a good thing — if you want your virtual object to appear anchored to the real-world surface, you want to be sure of where that surface is. You'll see some movement as plane detection gets more sure of the surface's position, but after a short time, you should see less "slip" as you move the camera around for plan-anchored virtual objects than those that are just floating in world space.

但是,在您的代码中,您没有利用平面检测来使您的自定义内容(来自PlayerModel.scn")坚持平面锚点:

In your code, though, you're not taking advantage of plane detection to make your custom content (from "PlayerModel.scn") stick to the plane anchor:

wrapperNode.position = SCNVector3.positionFromTransform(anchor.transform)
wrapperNode.addChildNode(Body)
scnView.scene.rootNode.addChildNode(wrapperNode)

此代码使用平面锚点的初始位置在世界空间中定位wrapperNode(因为您将其设为根节点的子节点).如果您改为使 wrapperNode 成为平面锚节点的子节点(您在 renderer(_:didAdd:for:) 中收到的那个),它会保持附加到平面作为 ARKit 改进其对平面位置的估计.最初您会获得更多运动,但随着平面检测稳定",您的虚拟对象将减少滑动".

This code uses the initial position of the plane anchor to position wrapperNode in world space (because you're making it a child of the root node). If you instead make wrapperNode a child of the plane anchor's node (the one you received in renderer(_:didAdd:for:)), it'll stay attached to the plane as ARKit refines its estimate of the plane's position. You'll get a little bit more movement initially, but as plane detection "settles", your virtual object will "slip" less.

(当你让节点成为平面的子节点时,你不需要设置它的位置——位置为零意味着它就在平面所在的位置.无论如何,你只需要设置它相对于平面的位置平面——即在它上面/下面/沿着它多远.)

(When you make the node a child of the plane, you don't need to set its position — a position of zero means it's right where the plane is. Inf anything, you need to set its position only relative to the plane — i.e. how far above/below/along it.)

这篇关于如何保持 ARKit SCNNode 到位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆