ARKit3.5 框架学习 (二)核心类简介(中)

3.4 ARCamera

  • ARCamera: 关于给定帧的摄像机位置和成像特性的信息。
class ARCamera : NSObject

您可以从ARFrame ARKit交付的每个相机属性中获得相机信息。

3.5 ARHitTestResult

  • ARHitTestResult: 通过检查屏幕上的一个点发现的关于真实世界表面的信息。

如果你使用SceneKitSpriteKit作为你的渲染器,你可以使用以下命令在屏幕上搜索真实世界的表面:
ARSCNView hitTest(_:types:): 在捕获的摄像机图像中搜索与SceneKit视图中某个点对应的真实对象或AR锚点

ARSKView hitTest(_:types:): 在捕获的相机图像中搜索与 SpriteKit视图中某个点相对应的真实对象或AR锚点。

Hit测试通过AR会话对摄像机图像的处理来搜索现实世界中的物体或表面。在视图的坐标系统中,2D点可以指从设备摄像机开始并沿着由设备方向和摄像机投影决定的方向延伸的3D线上的任何点。这个方法沿着这条线搜索,返回所有与它相交的物体,按与摄像机的距离排序。

class ARHitTestResult : NSObject

3.6 ARLightEstimate

  • ARLightEstimate:AR会话中与捕获的视频帧相关的估计场景照明信息。
class ARLightEstimate : NSObject

3.7 ARPointCloud

  • ARPointCloud: AR会话的世界坐标空间中的点的集合。
class ARPointCloud : NSObject

使用ARFrame rawFeaturePoints属性获得一个点云,表示ARKit用于执行世界跟踪的场景分析的中间结果。

3.8 ARReferenceImage

class ARReferenceImage : NSObject

为了在真实世界中准确地检测二维图像的位置和方向,ARKit需要预处理的图像数据和图像的真实世界尺寸的知识。ARReferenceImage类封装了这些信息。要在AR会话中启用图像检测,请将一组参考图像传递到会话配置的detectionImages属性。

3.9 ARReferenceObject

class ARReferenceObject : NSObject

ARKit中的对象检测允许您在会话识别已知的3D对象时触发AR内容。例如,您的应用程序可以检测艺术博物馆中的雕塑并提供一个虚拟馆长,或检测桌面游戏人物并为游戏创建视觉效果。

要提供一个已知的3D对象检测,你扫描一个现实世界的对象使用ARKit:

  1. 使用ARObjectScanningConfiguration运行AR会话,以启用高保真空间映射数据的收集。
  2. 在这个过程中,将设备摄像头从不同的角度对准真实世界的物体,这样ARKit就可以建立物体及其周围环境的内部地图。有关引导用户交互生成良好扫描数据的示例,请参见扫描和检测3D对象

3.10 ARVideoFormat

  • ARVideoFormat: 一个视频大小和帧速率规格,用于AR会话。
@interface ARVideoFormat : NSObject

这个类是不可变的;要设置AR会话的帧速率和视频分辨率,请将配置的videoFormat属性设置为supportedVideoFormats数组中的一种格式。

3.11 ARCollaborationData

@interface ARCollaborationData : NSObject

要创建多用户增强现实体验,您可以在世界跟踪会话上启用协作。ARKit会定期输出用户之间共享的 ARCollaborationData,这使得每个人都可以从自己的角度查看相同的虚拟内容。有关更多信息,请参见启用collaborationEnabled

3.12 ARWorldMap

  • ARWorldMap: 空间映射状态和一组来自世界跟踪AR会话的锚点。
class ARWorldMap : NSObject

会话状态的世界地图包括ARKit意识的物理空间的用户移动设备(ARKit用于确定设备的位置和方向),以及任何ARAnchor对象添加到会话(可以表示检测到现实世界的特性或虚拟内容的应用程序)。

3.12.2 ARWorldMap序列化和反序列化世界地图:

当您的应用程序退出时,您可以保存当前的世界地图(使用getCurrentWorldMap(completionHandler:)获取)。因为ARWorldMap符合NSSecureCoding,所以您使用NSKeyedArchiver序列化它。

func writeWorldMap(_ worldMap: ARWorldMap, to url: URL) throws {
    let data = try NSKeyedArchiver.archivedData(withRootObject: worldMap, requiringSecureCoding: true)
    try data.write(to: url)
}

要在应用程序下次启动时恢复世界地图,请使用NSKeyedUnarchiver

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
}

如果应用程序在相同的物理环境中启动,您可以使用恢复的世界地图中的锚来将相同的虚拟内容放在保存的会话中的相同位置。
有关更多信息,请参见保存和加载世界数据

3.12.3 ARWorldMap共享保存的世界地图

有了两个跟踪相同世界地图的设备,您就可以构建一个网络体验,两个用户都可以看到相同的虚拟内容并与之交互。将ARWorldMap发送到另一个设备,为多用户AR体验创建一个共享的参考框架:

步骤如下:

  1. 在一个设备上,使用NSKeyedArchiver 将世界地图转换为数据对象。(你不需要把数据写到一个文件中,然后通过网络发送。)
  2. 使用您选择的网络技术将结果数据发送到另一个设备。(例如,在一个MultipeerConnectivity会话中,调用send(_:toPeers:with:)来发送数据,并在另一个设备上实现MCSessionDelegate方法来接收数据。)
  3. 在接收设备上,使用NSKeyedUnarchiver 从数据中反序列化一个ARWorldMap

有关更多信息,请参见创建多用户增强现实体验

3.12.4 ARWorldMap运行反序列化的世界地图

要从现有的ARWorldMap开始新会话,请设置一个世界跟踪配置的initialWorldMap属性并使用run(_:options:)。这将启动一个新的会话,使用相同的空间感知和从保存的世界地图加载的锚。

3.12.4.1 ARWorldMap相关函数介绍
  • run(_:options:): 是ARSession的一个实例方法,用来使用指定的配置和选项启动会话的AR处理。它的定义如下:
func run(_ configuration: ARConfiguration, 
 options: ARSession.RunOptions = [])

参数说明:

  1. configuration:为会话定义运动和场景跟踪行为的对象。
  2. options: 影响现有会话状态(如果有的话)如何转换到新配置的选项。
    如果会话是第一次运行,则此参数无效。

会话跟踪设备运动,捕获并处理来自设备摄像头的场景图像,并仅在运行时与您的委托对象或ARSCNViewARSKView视图进行协调。

在已经立即开始过渡到新会话配置的会话上调用此方法。options参数确定现有会话状态如何转换到新配置。默认情况下,会话从最后一个已知状态恢复设备位置跟踪,并保留会话中已经包含的所有锚点(那些您使用add(anchor:)手动添加的锚点,以及那些由ARKit特性(如平面检测或人脸跟踪)自动添加的锚点)。

3.13 ARRaycastQuery

  • ARRaycastQuery: 一种数学射线,你可以用它来找到真实世界表面的三维位置。
class ARRaycastQuery : NSObject

您可以通过提供3D向量和起始位置来创建一个raycast查询。
要使用2D屏幕位置和用户向z方向投射的默认向量来创建一个raycast查询,可以使用ARView上的 makeRaycastQuery(from:allowing:alignment:)ARSCNView上的raycastQuery(from:allowing:alignment:)这两个方便的函数。
光线投射可以与平面(平面)或网格(不平整的表面)相交。若要与平面相交,请参见ARRaycastQuery.Target。若要与网格相交,请参见ARRaycastQuery.Target.estimatedPlane

3.14 ARTrackedRaycast

  • ARTrackedRaycast:ARKit会连续重复一个raycast查询,从而随着时间的推移提供更精确的结果。
class ARTrackedRaycast : NSObject

跟踪射线投射通过连续地重复3D位置的查询来改进命中测试技术。ARKit为您提供了一个更新的位置,随着时间的推移,它完善了它对世界的理解。
要启动一个被跟踪的raycast,你需要在你的应用程序的当前ARSession上调用trackedRaycast(_:updateHandler:)

3.15 ARRaycastResult

  • ARRaycastResult:通过检查屏幕上的一个点发现的关于真实世界表面的信息。
class ARRaycastResult : NSObject

如果您使用ARViewARSCNView作为您的渲染器,您可以分别使用 raycast(from:allowing:alignment:)raycastQuery(from:allowing:alignment:)函数在屏幕上搜索真实世界的表面。
如果你使用自定义渲染器,你可以找到现实世界的位置使用屏幕点:
ARFrame的 raycastQuery(from:allowing:alignment:)函数。
ARSessionraycast(_:)函数。
对于被跟踪的光线投射,你在你的应用程序的当前ARSession上调用trackedRaycast(_:updateHandler:)

3.16 ARAnchor

  • ARAnchor: 物理环境中某物的位置和方向。
class ARAnchor : NSObject

要跟踪真实或虚拟对象相对于摄像机的静态位置和方向,请创建锚对象并使用add(anchor:)方法将它们添加到AR会话中。

在会话中添加一个锚点可以帮助ARKit优化该锚点周围区域的世界跟踪精度,从而使虚拟对象看起来与真实世界保持一致。如果虚拟对象移动,则从旧位置移除相应的锚,并在新位置添加一个锚。

一些ARKit特性会自动向会话添加特殊的锚。如果启用了相应的功能,世界跟踪会话可以添加ARPlaneAnchorARObjectAnchorARImageAnchor对象;面部跟踪会话添加ARFaceAnchor对象。

3.16.1 子类简介

除了创建自己的ARAnchor实例来跟踪虚拟内容的实际位置之外,还可以子类化ARAnchor来将自定义数据与创建的锚关联起来。确保你的锚类在ARKit更新帧或保存并加载ARWorldMap中的锚时行为正确:

  • 锚子类必须满足ARAnchorCopying协议的要求。ARKit调用init(锚:)(在一个后台线程上)来将锚类的实例从一个ARFrame复制到下一个ARFrame。此初始化器的实现应复制子类添加的任何自定义属性的值。
  • 锚子类也必须采用NSSecureCoding协议。重写encode(with:)和init(coder:)来保存和恢复您的子类自定义属性的值,当ARKit将它们保存并加载到一个世界地图中时。
  • 锚点根据其标识符属性被认为是相等的。
  • 当您保存世界地图时,只有不采用可跟踪的锚点(ARTrackable )才会被包括在内。

3.16.2 ARTrackable

  • ARTrackable: 一个真实世界的对象,在一个场景中,ARKit跟踪位置和方向的变化。
protocol ARTrackable

这个协议被ARKit类所采用,比如ARFaceAnchor类,它表示场景中移动的对象。

ARKit在一个活动的AR会话中自动管理这些对象的表示,确保真实世界中对象的位置和方向(锚的transform属性)的变化反映在相应的ARKit对象中。isTracked属性指示当前转换对于实际对象的移动是否有效。

可跟踪的锚类影响其他ARKit行为:

  • getCurrentWorldMap(completionHandler:)方法自动在其创建的ARWorldMap中只包含不可跟踪的锚点。(创建世界地图后,可以选择添加其他锚点。)
  • ARSCNViewARSKView自动隐藏isTracked属性为false的锚节点。
  • World-tracking会话使用不可跟踪的锚点来优化每个锚点周围区域的跟踪质量。可跟踪的锚不影响世界跟踪。

3.17 AREnvironmentProbeAnchor

class AREnvironmentProbeAnchor : ARAnchor

环境纹理描述了场景中特定点的各个方向的视图。在三维资产渲染中,环境纹理是基于图像的照明算法的基础,其中表面可以真实地反射来自其周围环境的光。ARKit可以在AR会话期间使用摄像机图像生成环境纹理,允许SceneKit或自定义渲染引擎为AR体验中的虚拟对象提供基于真实图像的照明。
若要为AR会话启用纹理映射生成,请设置environmentTexturing属性:

  1. ARWorldTrackingConfiguration.EnvironmentTexturing。手动环境纹理,你可以通过创建 AREnvironmentProbeAnchor 对象并将它们添加到会话中来识别场景中你想要的光探测纹理映射点。
  2. ARWorldTrackingConfiguration.EnvironmentTexturing。自动环境纹理,ARKit自动创建,定位,并添加 AREnvironmentProbeAnchor 对象到会话。

在这两种情况下,ARKit在会话收集摄像机图像时自动生成环境纹理。使用诸如session(_:didUpdate:)这样的委托方法来找出一个纹理何时可用,并从锚的environmentTexture属性访问它。
如果您使用ARSCNViewautomaticallyUpdatesLighting选项来显示AR内容,SceneKit会自动检索AREnvironmentProbeAnchor纹理映射并使用它们来照亮场景。

3.18 ARFaceAnchor

  • ARFaceAnchor: 关于姿态、拓扑结构和面部表情的信息,ARKit在前置摄像头中检测到。
class ARFaceAnchor : ARAnchor

当会话在前置摄像头提要中检测到一个唯一的人脸时,它会自动将一个ARFaceAnchor:对象添加到它的锚点列表中。
当你使用ARFaceTrackingConfiguration跟踪面时,ARKit可以同时跟踪多个面。

  • 跟踪面部位置和方向

继承的变换属性在世界坐标中描述人脸当前的位置和方向;也就是说,在与会话配置的worldAlignment属性指定的坐标空间中。使用这个变换矩阵来定位你想要“附加”到AR场景中的虚拟内容。
这个变换矩阵创建了一个面坐标系统,用于定位相对于面而言的其他元素。面坐标空间单位以米为单位,原点在面后居中,如下图所示。

跟踪面部位置和方向

坐标系是右向的——正的x方向指向观察者的右边(也就是脸自己的左边),正的y方向指向上(相对于脸本身,而不是世界),正的z方向指向外(指向观察者)。

  • 使用面拓扑:
    几何属性提供了一个ARFaceGeometry对象,该对象表示面部的详细拓扑结构,该对象符合一个通用的面部模型,以匹配检测到的面部的尺寸、形状和当前表达式。
    您可以使用这个模型作为基础,根据用户的面部形状覆盖内容—例如,应用虚拟化妆或纹身。你也可以使用这个模型来创建遮挡几何——一个不渲染任何可见内容的3D模型(允许摄像机图像通过),但是它会阻碍摄像机在场景中看到其他虚拟内容。

  • 跟踪面部表情:
    blendShapes属性提供了当前面部表情的高级模型,该模型通过一系列指定的系数进行描述,这些系数表示特定面部特征相对于其中性配置的移动。您可以使用混合形状系数使2D或3D内容(如角色或阿凡达)具有动画效果,并遵循用户的面部表情。

3.19 ARFaceGeometry

  • ARFaceGeometry:描述人脸拓扑结构的三维网格,用于人脸跟踪AR会话。
class ARFaceGeometry : NSObject

这个类以3D网格的形式为面部的详细拓扑提供了一个通用模型,适合用于各种呈现技术或导出3D资产。(使用SceneKit查看人脸几何图形的快速方法,请参见ARSCNFaceGeometry类。)

在人脸跟踪AR会话中,当您从ARFaceAnchor对象获取人脸几何形状时,该模型将与被检测到的人脸的尺寸、形状和当前表达式相匹配。您还可以使用一个名为blend形状系数的字典来创建一个面部网格,它提供了面部当前表情的详细但更有效的描述。

在AR会话中,您可以使用这个模型作为基础,根据用户的面部形状覆盖内容——例如,应用虚拟化妆或纹身。您还可以使用这个模型来创建遮挡几何图形,它将其他虚拟内容隐藏在摄像机图像中检测到的人脸的3D形状之后。

  1. 面网格拓扑在ARFaceGeometry实例中是常量。也就是说,vertexCount、textureCoordinateCount和triangleCount属性的值不会改变,triangleIndices缓冲区总是描述相同的顶点排列,而textureCoordinateCount缓冲区总是将相同的顶点索引映射到相同的纹理坐标。
  2. 只有顶点缓冲了AR会话提供的面网格之间的变化,表明顶点位置的变化,因为ARKit使网格适应用户的脸的形状和表情。

3.20 ARImageAnchor

  • ARImageAnchor: 在世界跟踪AR会话中检测到的图像的位置和方向的信息。
class ARImageAnchor : ARAnchor

当您运行一个world-tracking AR会话并为会话配置的detectionImages属性指定ARReferenceImage对象时,ARKit将在实际环境中搜索这些图像。当会话识别一个图像时,它会自动将每个检测到的图像的 ARImageAnchor 添加到它的锚点列表中。
要查找场景中已识别图像的范围,可以使用继承的transform属性和锚点的referenceImage的物理大小。

3.21 ARObjectAnchor

  • ARObjectAnchor:在世界跟踪AR会话中检测到的真实三维对象的位置和方向信息。
class ARObjectAnchor : ARAnchor

当您运行一个跟踪世界的AR会话并为会话配置的detectionObjects属性指定ARReferenceObject对象时,ARKit将在实际环境中搜索这些对象。当会话识别一个对象时,它会自动将每个检测到的对象的ARObjectAnchor添加到它的锚点列表中。
要放置与被检测对象的位置或大小匹配的虚拟3D内容,请使用锚点的继承transform属性以及锚点的referenceObject的中心和范围。

var detectionObjects: Set<ARReferenceObject> { get set }

detectionObjects属性说明:

  1. detectionObjects是一组用于ARKit尝试在用户环境中检测的3D对象。
  2. 使用此属性可为ARKit选择在用户环境中找到的已知3D对象,并将其呈现为ARObjectAnchor,以供在增强现实体验中使用。
    要创建用于检测的引用对象,请在世界跟踪会话中扫描它们,并使用ARWorldMap来提取ARReferenceObject实例。然后可以将引用对象保存为文件,并将它们打包到使用Xcode资产目录创建的任何ARKit应用程序中。

3.22 ARParticipantAnchor

class ARParticipantAnchor : ARAnchor

当你将isCollaborationEnabled设置为true时,ARKit会调用session(_:didAdd:),并为它在物理环境中检测到的每个用户提供一个ARParticipantAnchor,为你提供他们的世界位置。

3.23 ARPlaneAnchor:

class ARPlaneAnchor : ARAnchor

当你在一个世界追踪会话中启用planeDetection时,ARKit会通知你的应用它通过设备的后摄像头观察到的所有表面。ARKit调用你的委派的session(_:didAdd:) ,为每个独特的表面使用一个ARPlaneAnchor。每一个平面锚都提供了关于表面的细节,比如它在现实世界中的位置和形状。

session(_:didAdd:) 说明:

  1. 根据会话配置,ARKit可以自动向会话添加锚。
  2. 如果你使用SceneKit或SpriteKit来显示AR体验,你可以实现以下方法之一来代替跟踪不仅仅是向会话中添加锚点,还可以跟踪如何将SceneKit或SpriteKit内容添加到相应的场景中:ARSCNView: renderer(_:nodeFor:) or renderer(_:didAdd:for:) ARSKView: node(for:) or view(_:didAdd:for:)

3.24 ARPlaneGeometry

  • ARPlaneGeometry: 在世界跟踪AR会话中描述被探测平面形状的三维网格。
class ARPlaneGeometry : NSObject

在世界跟踪AR会话中描述被探测平面形状的三维网格。这个类提供了被检测平面的大致形状的估计,其形式是一个详细的3D网格,适合与各种渲染技术一起使用或用于导出3D资产。(使用SceneKit查看平面几何图形的快速方法,请参见ARSCNPlaneGeometry课程。)

ARPlaneAnchor中心和范围属性不同,后者仅对检测到的平面的矩形区域进行估计,而平面锚的几何属性提供了对该平面覆盖的二维区域的更详细的估计。例如,如果ARKit检测到一个圆形桌面,得到的ARPlaneGeometry对象大致匹配表的一般形状。随着会话的继续运行,ARKit提供了更新的平面锚点,其相关的几何形状改进了飞机的估计形状。

您可以使用此模型更精确地放置3D内容,这些内容应该只出现在检测到的平面上。例如,确保虚拟对象不会从表的边缘掉落。您还可以使用这个模型来创建遮挡几何图形,它将摄像机图像中检测到的表面后面隐藏其他虚拟内容。

平面几何的形状总是凸的。也就是说,平面几何的边界多边形是一个最小的凸包,它包围了ARKit识别或估计的所有点,这些点都是平面的一部分。

3.25 ARSkeleton

class ARSkeleton : NSObject

作为关节的集合,本协议描述了ARKit可以跟踪的人体运动状态。
ARSkeleton3D子类为您提供了3D空间中被跟踪的人体关节的位置,特别是它的jointLocalTransformsjointModelTransforms属性。
ARSkeleton2D子类通过它的jointLandmarks属性为您提供了一个二维空间中被跟踪物体关节的位置。

3.26 ARSkeletonDefinition

class ARSkeletonDefinition : NSObject

骨架定义建立了构成3D或2D身体骨架的关节之间的关系,其中关节连接到其他关节,在父-子层次结构中构成单个骨架。使用parentIndices来标识给定框架定义的层次结构。
ARKit指定了对身体跟踪至关重要的特定关节。可以通过调用index(forJointName:)并传入一个可用的联名标识符来访问指定的联名。

3.27 ARBody2D

  • ARBody2D: 屏幕空间表示ARKit在摄像机提要中识别的人员。
class ARBody2D : NSObject

当ARKit在摄像头提示中识别一个人时,它会估计身体关节的屏幕空间位置,并通过当前帧的detectedBody向您提供该位置。

3.28 ARBodyAnchor

  • ARBodyAnchor: 一个物体,它在三维空间中跟踪一个物体的运动,ARKit可以在摄像头中识别它。
class ARBodyAnchor : ARAnchor

这个ARAnchor子类跟踪单个人的移动。通过使用ARBodyTrackingConfiguration运行会话,您可以启用身体跟踪。
当ARKit在后台摄像头feed中识别一个人时,它会用ARBodyAnchor调用你的委托的session(_:didAdd:)函数。身体锚点的变换位置定义了身体髋关节的世界位置。
你也可以在框架的锚中检查ARKit正在跟踪的物体。

  • 把骨架放在表面上

因为身体锚点的原点映射到髋关节,所以您可以计算脚到髋关节的当前偏移量,从而将身体的骨骼放置在一个表面上。通过将脚关节索引传递给jointModelTransforms,您可以得到脚与骨骼原点的偏移量。

static var hipToFootOffset: Float {
    // Get an index for a foot. 
    let footIndex = ARSkeletonDefinition.defaultBody3D.index(forJointName: .leftFoot)
    // Get the foot's world-space offset from the hip. 
    let footTransform = ARSkeletonDefinition.defaultBody3D.neutralBodySkeleton3D!.jointModelTransforms[footIndex]
    // Return the height by getting just the y-value. 
    let distanceFromHipOnY = abs(footTransform.columns.3.y) 
    return distanceFromHipOnY
}

3.29 ARCoachingOverlayView

  • ARCoachingOverlayView: 在会话初始化和恢复期间为用户提供指导的可视化指令的视图。
class ARCoachingOverlayView : UIView

此视图为您的用户提供了标准化的登录例程。您可以配置此视图,使其在会话初始化期间和有限的跟踪情况下自动显示,同时为用户提供特定的指令,以最方便地跟踪ARKit的世界。
这些插图显示了具有水平和垂直平面目标的叠加视图,表明用户应该开始移动设备:

ARCoachingOverlayView 图1

这些插图显示了叠加视图,表明用户应该继续移动手机或改变移动速度:

ARCoachingOverlayView 图2

当你启动你的应用程序时,coaching overlay会要求用户以帮助ARKit建立追踪的方式移动设备。当你选择一个特定的目标时,比如找到一架飞机,视图会相应地调整它的指令。当coaching overlay确定目标已经达到并且不再需要coaching之后,它就会从用户的视图中隐藏起来。
有关使用coaching overlay的示例应用程序,请参见放置对象和处理3D交互

  • 支持自动辅导:

默认情况下,activatesautomatic是启用的,因此您应该覆盖coachingOverlayViewWillActivate(_:)来确定教练是否在进行中。协调您的操作以帮助用户关注这些指令,例如,通过隐藏会话重新初始化时不需要的任何UI。

  • 在中断后重新定位:
    如果启用了重新本地化(请参阅sessionShouldAttemptRelocalization(_:)),如果任何中断降低了应用程序的跟踪状态,ARKit将尝试恢复您的会话。在这种情况下,coaching overlay会自动出现,并向用户提供帮助ARKit进行重新定位的指令。
在中断后重新定位1

在此期间,coaching overlay包含一个按钮,让用户指示他们希望重新开始而不是恢复会话。

在中断后重新定位2

ARKit通过调用你的委托的coachingOverlayViewDidRequestSessionReset(_:)函数在用户按下Start时通知你。实现这个回调,如果你的应用程序需要任何自定义动作来重新启动AR体验。

func coachingOverlayViewDidRequestSessionReset(_ coachingOverlayView: ARCoachingOverlayView) {    

    // Reset the session.
    let configuration = ARWorldTrackingConfiguration()
    configuration.planeDetection = [.horizontal, .vertical]
    session.run(configuration, options: [.resetTracking])

    // Custom actions to restart the AR experience. 
    // ...
}

如果你没有实现coachingOverlayViewDidRequestSessionReset(_:), coaching overlay会通过重置跟踪来响应Start Over按钮,这也会移除任何现有的锚点。
有关重新本地化的更多信息,请参见管理会话生命周期和跟踪质量

3.30 ARSCNView

class ARSCNView : SCNView

ARSCNView类提供了创建增强现实体验的最简单方法,这种体验将虚拟3D内容与真实世界的设备摄像头视图混合在一起。当你运行视图提供的ARSession对象:

  1. 该视图自动将来自设备摄像机的实时视频提要呈现为场景背景。
  2. 视图的SceneKit场景的世界坐标系统直接响应由会话配置建立的AR世界坐标系统。
  3. 视图会自动移动它的SceneKit摄像头,以匹配设备在真实世界中的移动。

因为ARKit会自动将SceneKit空间与现实世界相匹配,所以放置一个虚拟对象,使其看起来能够保持一个真实世界的位置,只需要适当地设置该对象的SceneKit位置。(参见使用SceneKit提供3D虚拟内容。)

您不一定需要使用ARAnchor类来跟踪添加到场景中的对象的位置,但是通过实现ARSCNViewDelegate方法,您可以将SceneKit内容添加到ARKit自动检测到的任何锚中。

3.30.1 ARSCNView 类定义

3.30.2 ARSCNViewDelegate

  • ARSCNViewDelegate:代理方法您可以实现将SpriteKit内容的自动同步与AR会话进行协调。
    实现这个协议来提供与视图的AR会话跟踪的ARAnchor对象相对应的SpriteKit内容,或者管理视图对这些内容的自动更新。
    该协议扩展了ARSessionObserver协议,因此您的会话委托也可以实现那些方法来响应会话状态的更改。
  • 处理内容更新:
//要求委托提供一个与新添加的锚点相对应的SpriteKit节点。
func view(ARSKView, nodeFor: ARAnchor) -> SKNode?

//告诉代理,与一个新的AR锚相对应的SpriteKit节点已经被添加到场景中。
func view(ARSKView, didAdd: SKNode, for: ARAnchor)

//告诉代理,SpriteKit节点的属性将被更新,以匹配其相应锚点的当前状态。
func view(ARSKView, willUpdate: SKNode, for: ARAnchor)

//告诉代理,SpriteKit节点的属性已经更新,以匹配其相应锚的当前状态。
func view(ARSKView, didUpdate: SKNode, for: ARAnchor)

//告诉代理,与AR锚对应的SpriteKit节点已经从场景中移除。
func view(ARSKView, didRemove: SKNode, for: ARAnchor)

3.30.3 ARSCNView 属性和方法

//用于管理视图内容的运动跟踪和摄像机图像处理的AR会话。
var session: ARSession

//将在视图中显示的SceneKit场景。
var scene: SCNScene

  • 响应AR更新
//一个对象,你提供的中介同步视图的AR场景信息与SceneKit内容。
var delegate: ARSCNViewDelegate?

//方法可以实现将SceneKit内容的自动同步与AR会话进行协调。
protocol ARSCNViewDelegate

  • 发现真实的表面
在捕获的摄像机图像中搜索与SceneKit视图中某个点对应的真实对象或AR锚点。
func hitTest(CGPoint, types: ARHitTestResult.ResultType) -> [ARHitTestResult]

//创建一个光线投射查询,该查询源于视图上与摄像机视场中心对齐的一个点。
func raycastQuery(from: CGPoint, allowing: ARRaycastQuery.Target, alignment: ARRaycastQuery.TargetAlignment) -> ARRaycastQuery?

  • 将内容映射到实际位置
//返回与指定SceneKit节点关联的AR锚点(如果有的话)。
func anchor(for: SCNNode) -> ARAnchor?

//返回与指定AR锚关联的SceneKit节点(如果有的话)。
func node(for: ARAnchor) -> SCNNode?

//在ARKit检测到的三维世界空间中,返回从2D视图到平面上的点的投影。
func unprojectPoint(CGPoint, ontoPlane: simd_float4x4) -> simd_float3?

  • 管理光照
//一个布尔值,指定ARKit是否在视图的场景中创建和更新SceneKit灯光。
var automaticallyUpdatesLighting: Bool

  • 调试基于“增大化现实”技术的展示

//在SceneKit视图中绘制覆盖内容以帮助调试AR跟踪的选项
typealias ARSCNDebugOptions

  • 管理渲染效果
、、确定视图是否呈现运动模糊。
var rendersMotionBlur: Bool
//一个确定SceneKit是否将图像噪声特征应用于应用程序的虚拟内容的标志。
var rendersCameraGrain: Bool

3.31 ARSKView

class ARSKView : SKView

使用ARSKView:类来创建增强现实体验,将2D元素放置在3D空间中的设备摄像机视图中。当你运行视图提供的ARSession对象:

  1. 该视图自动将来自设备摄像机的实时视频提要呈现为场景背景。
  2. 当您实现ARSKViewDelegate方法来将 SpriteKit内容与真实世界的位置相关联时,视图会自动缩放和旋转那些 SpriteKit节点,以便它们看起来能够跟踪摄像机看到的真实世界。

3.31.1 ARSKViewDelegate

  • ARSKViewDelegate: 提供方法您可以实现将SpriteKit内容的自动同步与AR会话进行协调。
protocol ARSKViewDelegate
  1. 方法您可以实现将SpriteKit内容的自动同步与AR会话进行协调。
  2. 实现这个协议来提供与视图的AR会话跟踪的ARAnchor对象相对应的SpriteKit内容,或者管理视图对这些内容的自动更新。
  3. 该协议扩展了ARSessionObserver协议,因此您的会话委托也可以实现那些方法来响应会话状态的更改。
  • 处理内容更新的回调代理:
//要求委托提供一个与新添加的锚点相对应的SpriteKit节点。
func view(ARSKView, nodeFor: ARAnchor) -> SKNode?

//告诉委派,与一个新的AR锚相对应的SpriteKit节点已经被添加到场景中。
func view(ARSKView, didAdd: SKNode, for: ARAnchor)

//告诉委托,SpriteKit节点的属性将被更新,以匹配其相应锚点的当前状态。
func view(ARSKView, willUpdate: SKNode, for: ARAnchor)

//告诉委托,SpriteKit节点的属性已经更新,以匹配其相应锚的当前状态。
func view(ARSKView, didUpdate: SKNode, for: ARAnchor)

//告诉委托,与AR锚对应的SpriteKit节点已经从场景中移除。
func view(ARSKView, didRemove: SKNode, for: ARAnchor)

3.32 ARMatteGenerator

  • ARMatteGenerator:一个创建哑光纹理的对象,你可以用它来遮挡你的应用程序的虚拟内容
class ARMatteGenerator : NSObject

当你想要完全控制你的应用程序的虚拟内容时,使用这个类,基于ARKit在摄像头feed中识别的人。

使用标准渲染器(ARViewARSCNView)的应用程序不需要这个类来影响人们的遮挡。有关更多信息,请参见frameSemantics

为了帮助你的自定义渲染器与人遮挡,matte生成器处理alpha和深度信息在帧的分段缓冲和估计的深度数据,为你提供matte和深度纹理。你使用这些纹理在你的应用程序的虚拟内容上分层

3.33 ARQuickLookPreviewItem

当您想要控制背景,指定共享表格共享的内容,或者在不允许用户缩放特定模型的情况下禁用缩放时,使用这个类。

3.34 ARFrame

  • ARFrame: 位置跟踪信息作为会话的一部分而捕获的视频图像

当ARKit分析视频帧以估计用户在世界中的位置时,一个正在运行的会话不断地从设备摄像头捕获视频帧。 ARKit还以ARFrame的形式向您提供这些信息,并以您的应用程序的帧速率的频率提供这些信息。

你的应用程序有两种接收ARFrame的方式:

  1. 如果你的应用程序维护了自己的渲染循环,或者你需要在ARSCNViewDelegateARSKViewDelegate回调中获取帧信息,那么从ARSession中请求currentFrame
  2. 让你的一个对象成为ARSession的委托,当 ARKit捕获新帧时自动接收它们。

3.34.1 ARFrame 类定义

3.34.2 ARFrame 属性方法

  • 访问捕获的视频帧
//包含摄像机捕获的图像的像素缓冲区。
var capturedImage: CVPixelBuffer

//帧被捕获的时间。
var timestamp: TimeInterval

//深度图(如果有的话)与视频帧一起捕获。
var capturedDepthData: AVDepthData?

//帧(如果有)的深度数据被捕获的时间。
var capturedDepthDataTimestamp: TimeInterval

  • 检查世界地图状态
//为该框架生成或重新定位世界地图的可行性。
var worldMappingStatus: ARFrame.WorldMappingStatus

//可能的值,描述ARKit如何彻底地映射给定帧中可见的区域。
enum ARFrame.WorldMappingStatus

  • 检查现场参数
//有关用于捕获帧的摄像机位置、方向和成像参数的信息。
var camera: ARCamera

//基于摄像机图像的照明条件的估计。
var lightEstimate: ARLightEstimate?

//返回一个仿射变换,用于在规格化图像坐标和用于在屏幕上呈现摄像机图像的坐标空间之间进行转换。
func displayTransform(for: UIInterfaceOrientation, viewportSize: CGSize) -> CGAffineTransform

  • 跟踪和查找对象
//表示场景中被跟踪的位置或检测到的对象的锚点列表。
var anchors: [ARAnchor]

//在捕获的摄像机图像中搜索真实世界的对象或AR锚。
func hitTest(CGPoint, types: ARHitTestResult.ResultType) -> [ARHitTestResult]

  • 调试现场检测
//目前,场景分析的中间结果ARKit用于执行世界跟踪。
var rawFeaturePoints: ARPointCloud?

//AR会话的世界坐标空间中的点的集合。
class ARPointCloud

  • 发现真实的表面
//获取一个屏幕点的光线投射查询。
func raycastQuery(from: CGPoint, allowing: ARRaycastQuery.Target, alignment: ARRaycastQuery.TargetAlignment) -> ARRaycastQuery

  • 2D追踪人体
//ARKit在相机图像中识别的身体的屏幕位置信息。
var detectedBody: ARBody2D?

//屏幕空间表示ARKit在摄像机提要中识别的人员。
class ARBody2D

  • detectedBody: ARBody2D类型, 用于ARKit在相机图像中识别的身体的屏幕位置信息
var detectedBody: ARBody2D? { get }

要启用2D体检测,您可以将体检测帧语义添加到配置的frameSemantics属性中,或者使用ARBodyTrackingConfiguration运行会话,在默认情况下,体检测是启用的。

  • class ARBody2D : 屏幕空间表示ARKit在摄像机提要中识别的人员。

当ARKit在摄像头提示中识别一个人时,它会估计身体关节的屏幕空间位置,并通过当前帧的detectedBody向您提供该位置。

  • 将虚拟内容与人隔离
//一个包含像素信息的缓冲区,该像素信息识别来自用于遮挡虚拟内容的摄像机提要的对象的形状。
var segmentationBuffer: CVPixelBuffer?

//一个缓冲区,表示用于遮挡虚拟内容的摄像机提要的估计深度值。
var estimatedDepthData: CVPixelBuffer?

//一个像素的分类,它定义了你用来遮挡应用程序虚拟内容的内容类型。
enum ARFrame.SegmentationClass

  • segmentationBuffer : CVPixelBuffer类型,标识一个包含像素信息的缓冲区,该像素信息识别来自用于遮挡虚拟内容的摄像机提要的对象的形状。

  • estimatedDepthData :CVPixelBuffer类型,深度数据缓冲区,表示用于遮挡虚拟内容的摄像机提要的估计深度值。

  • enum ARFrame.SegmentationClass :枚举类型,它定义了你用来遮挡应用程序虚拟内容的内容类型

enum SegmentationClass : UInt8

ARKit根据它对摄像机提要像素数据的解释应用这个类中定义的类别。只有人在摄像机提要中被识别,因此可用的像素分类是ARFrame.SegmentationClass.personARFrame.SegmentationClass.none

  1. ARFrame.SegmentationClass.person: 将分割缓冲区中的像素作为人的一部分进行分类。
  2. ARFrame.SegmentationClass.none: 将分割缓冲区中的像素分类为未识别的。
  • 开启相机纹理
//一个值,用于指定相机纹理纹理中出现的纹理数量。
var cameraGrainIntensity: Float

//由ARKit创建的可平铺的金属纹理,以匹配当前视讯流的视觉特性。
var cameraGrainTexture: MTLTexture?

  • cameraGrainIntensity: 用于指定相机纹理纹理中出现的纹理数量。
var cameraGrainIntensity: Float { get }

此属性在[0..1],其中0表示没有粮食,1表示粮食的最大数量。
当您将此值应用于cameraGrainTexture的深度组件时,您将从存储在金属纹理中的各种视觉图像噪声数据中选择概念上与此强度级别匹配的数据。

  • cameraGrainTexture: 由ARKit创建的可平铺的金属纹理,以匹配当前视讯流的视觉特性。
var cameraGrainTexture: MTLTexture? { get }

摄像头纹理增强了用户体验的真实和增强方面的视觉凝聚力,使你的应用程序的虚拟内容具有类似的图像噪声特征,这些特征自然会出现在摄像头feed中。

如下图:

摄像头纹理

如果ARSCNView是你的渲染器,SceneKit默认会将相机纹理应用到你的应用的虚拟内容中。有关更多信息,请参见rendersCameraGrain

  • rendersCameraGrain: 一个确定SceneKit是否将图像噪声特征应用于应用程序的虚拟内容的标志。rendersCameraGrain是ARSCNView的一个属性。
var rendersCameraGrain: Bool { get set }

默认启用。设置好后,SceneKit会在你的应用程序的虚拟内容中添加一个相机纹理效果,该效果与ARKit在相机反馈中观察到的图像噪声特征相匹配。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容