如何将ARKit SCNNode保持在原位 [英] How to keep ARKit SCNNode in place

查看:158
本文介绍了如何将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.

除了希望苹果公司生产的设备具有更好的传感器,更好的摄像头或更好的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.

(当您将节点设为平面的子级时,无需设置其位置-零位置表示它正好位于平面所在的位置.inf任何东西,您都只需要相对于平面设置其位置即可.平面-即飞机在上方/下方/下方的距离.)

(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天全站免登陆