本文介绍了如何将已知的位置和方向设置为ARKit的起点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始使用ARKit,并且有一个用例,我想知道从已知位置到另一个位置的运动.

I am starting to use ARKit and I have a use case where I want to know the motion from a known position to another one.

所以我想知道是否有可能(像每个跟踪解决方案一样)在ARKit中设置已知的位置和方向作为跟踪的起点?

So I was wondering if it is possible (like every tracking solution) to set a known position and orientation a starting point of the tracking in ARKit?

致谢

推荐答案

至少有六种方法可让您设置模型的起点.但是在您的ARS场景中完全不使用锚定被认为是不良的AR体验(尽管Apple的增强现实"应用模板的代码中没有任何ARAnchors.

There are at least six approaches allowing you set a starting point for a model. But using no ARAnchors at all in your ARScene is considered as bad AR experience (although Apple's Augmented Reality app template has no any ARAnchors in a code).

这是Apple工程师在Xcode的 Augmented Reality应用程序模板中向我们推荐的方法.这种方法不使用锚定,因此您要做的就是将模型容纳在具有(x:0,y:0,z:-0.5)等坐标的空中,换句话说,模型距离相机50厘米.

This is the approach that Apple engineers propose us in Augmented Reality app template in Xcode. This approach doesn't use anchoring, so all you need to do is to accommodate a model in air with coordinates like (x: 0, y: 0, z: -0.5) or in other words your model will be 50 cm away from camera.

override func viewDidLoad() {
    super.viewDidLoad()
    
    sceneView.scene = SCNScene(named: "art.scnassets/ship.scn")!
    let model = sceneView.scene.rootNode.childNode(withName: "ship", 
                                                recursively: true)
    model?.position.z = -0.5
    sceneView.session.run(ARWorldTrackingConfiguration())
}


第二种方法与第一种方法几乎相同,除了它使用ARKit的锚点:

Second approach is almost the same as the first one, except it uses ARKit's anchor:

guard let sceneView = self.view as? ARSCNView 
else { return }

if let currentFrame = sceneView.session.currentFrame {
        
    var translation = matrix_identity_float4x4
    translation.columns.3.z = -0.5
    let transform = simd_mul(currentFrame.camera.transform, translation)
        
    let anchor = ARAnchor(transform: transform)
    sceneView.session.add(anchor: anchor)
}


您还可以使用第三种方法来创建使用ARAnchor固定的预定义模型位置,在该位置还需要导入RealityKit模块:

You can also create a pre-defined model's position pinned with ARAnchor using third approach, where you need to import RealityKit module as well:

func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
            
    let model = ModelEntity(mesh: MeshResource.generateSphere(radius: 1.0))

    // ARKit's anchor
    let anchor = ARAnchor(transform: simd_float4x4(diagonal: [1,1,1]))
    
    // RealityKit's anchor based on position of ARAnchor
    let anchorEntity = AnchorEntity(anchor: anchor)

    anchorEntity.addChild(model)
    arView.scene.anchors.append(anchorEntity)
}


如果打开了飞机检测功能,则可以使用射线投射或命中测试方法.作为目标对象,您可以使用一个小的球体(位于 0,0,0 ),该球体将进行射线投射.

If you turned on a plane detection feature you can use Ray-casting or Hit-testing methods. As a target object you can use a little sphere (located at 0, 0, 0) that will be ray-casted.

let query = arView.raycastQuery(from: screenCenter,
                            allowing: .estimatedPlane,
                           alignment: .any)

let raycast = session.trackedRaycast(query) { results in

    if let result = results.first {
        object.transform = result.transform
    } 
}


此方法的重点是保存和共享ARKit的 worldMaps .

This approach is focused to save and share ARKit's worldMaps.

func writeWorldMap(_ worldMap: ARWorldMap, to url: URL) throws {

    let data = try NSKeyedArchiver.archivedData(withRootObject: worldMap, 
                                         requiringSecureCoding: true)
    try data.write(to: url)
}

func loadWorldMap(from url: URL) throws -> ARWorldMap {

    let mapData = try Data(contentsOf: url)
    guard let worldMap = try NSKeyedUnarchiver.unarchivedObject(ofClass: ARWorldMap.self, 
                                                                   from: mapData) 
    else { 
        throw ARError(.invalidWorldMap) 
    }
    return worldMap
}


在ARKit 4.0中,借助MapKit模块实现了新的 ARGeoTrackingConfiguration .因此,现在您可以使用预定义的GPS数据.

In ARKit 4.0 a new ARGeoTrackingConfiguration is implemented with the help of MapKit module. So now you can use a pre-defined GPS data.

func session(_ session: ARSession, didAdd anchors: [ARAnchor]) {
   
    for geoAnchor in anchors.compactMap({ $0 as? ARGeoAnchor }) {

        arView.scene.addAnchor(Entity.placemarkEntity(for: geoAnchor)
    }
}

这篇关于如何将已知的位置和方向设置为ARKit的起点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-12 15:04