记录真实世界对象的空间特征,然后使用结果在用户环境中查找这些对象并触发AR内容。
构建令人信服的AR体验的一种方法是识别用户环境的特征并使用它们触发虚拟内容的外观。 例如,当用户将他们的设备指向显示的雕塑或工件时,博物馆应用可以添加交互式3D可视化。
在iOS 12中,您可以通过在ARKit中启用对象检测来创建此类AR体验:您的应用程序提供参考对象,它可以对已知真实世界对象的三维空间要素进行编码,并且在AR session过程中,ARKit会告诉您的应用何时何地检测到相应的真实世界对象。
This sample code project provides multiple ways to make use of object detection:
此示例代码项目提供了多种方式来使用对象检测:
ARObjectScanningConfiguration
和 ARReferenceObject
类将引用对象记录为您自己的资产生产管道的一部分。detectionObjects
来识别参考对象并创建AR交互。扫描和定义ARKit可用于检测的参考对象的编程步骤非常简单。 (请参阅下面的“在AR会话中创建参考对象”。)但是,创建的参考对象的保真度以及您在自己的应用程序中检测参考对象的成功取决于扫描时与物体的物理交互。 在您的iOS设备上构建并运行此应用程序,以便通过一系列获取高质量扫描数据的步骤,从而生成可用于在自己的应用程序中进行检测的参考对象文件。
ARReferenceObject
并重新配置了会话以检测它。在不同的环境和光照条件下,从不同角度观察真实世界的物体,以验证ARKit能够可靠地识别其位置和方向。点击导出按钮打开分享表以保存完成的 .arobject
文件。例如,您可以使用AirDrop轻松将其发送到您的开发Mac,或将其发送到“文件”应用程序以将其保存到iCloud Drive。注意:参考对象仅包含ARKit识别现实世界对象所需的空间特征信息,并不是该对象的可显示3D重建。
您可以使用Xcode资产目录在应用程序中捆绑引用对象以用于检测:
注意:将想要在同一个会话中查找的所有对象放入资源组中,并使用单独的资源组来保存一组对象以在单独的会话中使用。 例如,博物馆应用程序可能会使用单独的会话(并因此分开资源组)来识别博物馆不同侧翼的显示。
要在AR会话中启用对象检测,请将要检测的引用对象加载为 ARReferenceObject
实例,将这些对象提供给ARWorldTrackingConfiguration
的 detectionObjects
属性,然后使用该配置运行ARSession:
let configuration = ARWorldTrackingConfiguration()
configuration.detectionObjects = ARReferenceObject.referenceObjects(inGroupNamed: "gallery", bundle: nil)
sceneView.session.run(configuration)
当ARKit检测到您的一个参考对象时,会话会自动将相应的 ARObjectAnchor
添加到其锚点列表中。 要响应正在识别的对象,请实施一个适当的 ARSessionDelegate
,ARSCNViewDelegate
或 ARSKViewDelegate
方法,以报告添加到会话的新锚点。 例如,在基于SceneKit的应用程序中,您可以实现 renderer:didAddNode:forAnchor:
向场景添加3D资产,自动匹配锚点的位置和方向
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
if let objectAnchor = anchor as? ARObjectAnchor {
node.addChildNode(self.model)
}
}
为了获得对象扫描和检测的最佳效果,请遵循以下提示:
此示例应用程序提供了一种创建参考对象的方法。 您还可以在自己的应用中扫描引用对象,例如,构建资产管理工具以定义进入其他应用的AR内容。
参考对象对ARKit用于跟踪设备位置和方向的内部空间映射数据进行编码。 要启用对象扫描所需的高质量数据收集,请使用ARObjectScanningConfiguration
运行会话:
let configuration = ARObjectScanningConfiguration()
configuration.planeDetection = .horizontal
sceneView.session.run(configuration, options: .resetTracking)
在对象扫描AR会话期间,从各个角度扫描对象以确保收集足够的空间数据以识别它。 (如果您正在构建自己的对象扫描工具,请帮助用户完成本示例应用程序提供的相同步骤。)
扫描完成后,调用createReferenceObjectWithTransform:center:extent:completionHandler:
从会话映射的用户环境区域生成一个ARReferenceObject:
// Extract the reference object based on the position & orientation of the bounding box.
sceneView.session.createReferenceObject(
transform: boundingBox.simdWorldTransform,
center: float3(), extent: boundingBox.extent,
completionHandler: { object, error in
if let referenceObject = object {
// Adjust the object's origin with the user-provided transform.
self.scannedReferenceObject =
referenceObject.applyingTransform(origin.simdTransform)
self.scannedReferenceObject!.name = self.scannedObject.scanName
creationFinished(self.scannedReferenceObject)
} else {
print("Error: Failed to create reference object. \(error!.localizedDescription)")
creationFinished(nil)
}
})
当检测到参考对象时,ARKit根据参考对象定义的原点报告其位置。 如果要放置看起来与真实世界对象位于同一表面上的虚拟内容,请确保将参照对象的原点放置在现实世界对象所在的位置。 要在捕获 ARReferenceObject
之后调整原点,请使用referenceObjectByApplyingTransform:
方法。
获取ARReferenceObject
之后,可以立即使用它来检测(请参阅上面的“在AR Experience中检测参考对象”),或将其另存为 .arobject
文件,以便在稍后的会话或其他基于ARKit的应用程序中使用。 要将对象保存到文件,请使用exportObjectToURL:previewImage:error:
方法。 在该方法中,您可以提供Xcode的真实世界对象的图片以用作预览图像。