我开始使用 ARKit,并且我有一个用例,我想知道从已知位置到另一个位置的运动。
所以我想知道是否有可能(就像每个跟踪解决方案一样)在 ARKit 中设置一个已知的位置和方向作为跟踪的起点?
问候
我开始使用 ARKit,并且我有一个用例,我想知道从已知位置到另一个位置的运动。
所以我想知道是否有可能(就像每个跟踪解决方案一样)在 ARKit 中设置一个已知的位置和方向作为跟踪的起点?
问候
至少有六种方法可以让您为模型设置起点。但是在你的 ARScene 中完全不使用ARAnchors被认为是糟糕的 AR 体验(尽管 Apple 的增强现实应用程序模板在代码中没有任何 ARAnchors)。
这是 Apple 工程师Augmented Reality app
在 Xcode 中的模板中向我们建议的方法。这种方法不使用锚定,因此您需要做的就是将模型放置在空中,其坐标类似于(x: 0, y: 0, z: -0.5)
,或者换句话说,您的模型将距离相机 50 厘米。
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 的锚点:
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 模块:
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
),该球体将进行射线投射。
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。
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 数据。
func session(_ session: ARSession, didAdd anchors: [ARAnchor]) {
for geoAnchor in anchors.compactMap({ $0 as? ARGeoAnchor }) {
arView.scene.addAnchor(Entity.placemarkEntity(for: geoAnchor)
}
}