阅读 491

ARKit3.5 框架学习 (一)核心类简介(上)

@[TOC]

ARKit3.5 框架学习 (一)核心类简介(上)

1. ARKit框架简介

ARKit整合iOS设备摄像头和运动功能,在你的应用程序或游戏中产生增强现实体验。

增强现实(AR)描述了将2D或3D元素添加到设备摄像头的实时视图中的用户体验,以使这些元素看起来像是生活在真实世界中。ARKit结合了设备运动跟踪、摄像机场景捕获、高级场景处理和显示功能,简化了构建AR体验的任务。使用这些技术,你可以使用iOS设备的前置或后置摄像头创建多种AR体验。

1.1 ARKit 3.5 新增功能

ARKit 3.5添加了一个新的Scene Geometry API,该API使用激光雷达扫描仪创建空间的3D地图,以区分地板,墙壁,天花板,窗户,门和座椅。该扫描仪能够在长达五米的距离内快速测量物体的长度,宽度和深度,从而使用户能够快速创建可用于物体遮挡的数字传真机-使数字物体看起来像部分混入了场景中在真实物体后面。得益于“即时AR”支持,这些数字对象可以自动放置在空间中,而无需用户挥动平板电脑并让其相机感觉到空间。

苹果还表示,它在3.5版中改进了ARKit的动作捕捉和人物遮挡,可以更好地估算人物的深度和动作捕捉的高度。以前,ARKit使用iPhone或iPad的2D相机在长度测量方面做得“足够好”,但是激光雷达扫描仪可以进行更精确的3轴测量,从而自动使以前开发的应用程序受益,而无需更改代码。

总的说来, ARKit 3.5 增加了以下三个方面的功能:

  1. 几何场景: 通过“几何场景”,您可以使用标识地板、墙壁、天花板、窗户、门和座椅的标签来创建空间的立体图。对现实世界的深入了解为虚拟对象解锁了对象遮挡和现实世界的物理原理,还为您提供了更多信息来增强您的 AR 工作场景。
  2. 即时AR:iPad Pro 上的 LiDAR 扫描仪可实现难以置信的快速平面检测,从而无需扫描即可在现实世界中即时放置AR对象。iPad Pro 会自动为所有使用 ARKit 构建的应用启用即时AR放置,而无需进行任何代码更改。
  3. 改进的运动捕捉和人物遮挡: 通过 ARKit 3.5 在 iPad Pro 中应用,“人物遮挡”中的深度预测和“运动捕捉”中的高度估计更加准确了。这两个功能在 iPad Pro 上使用 ARKit 生成的所有应用中得到了改进,同样无需更改任何代码。

如下图是一个AR效果图:

在这里插入图片描述

ARKit使用Visual Inertial Odometry(VIO,视觉惯性里程计)来精确跟踪现实世界中的真实场景。相比其它设备平台, ARKit中的VIO可以将传感器数据和CoreMotion的数据融合在一起,从而提供更为精确的信息。 ARKit可以让iOS设备精确感知它如何在房间内移动,而无需外部设备的校准。基于此原理, ARKit可以获取关于iOS设备位置和运动信息的高精度模型,并在场景中使用。

使用 ARKit,iPhone和IPad可以分析来自摄像头视图中的场景,并找到房间的水平平面。 ARKit可以检测到例如桌子和地板之类的平面,还可以检测和跟踪物体。更酷的是, ARKit还可以利用摄像头传感器来估算场景中的光线强度,从而在虚拟物体上提供合适的光照。

在实际的开发中,可以使用点击测试方法(如ARHitTestResult类)来根据摄像头捕捉的图像找到真实世界的表面。如果开发者在配置中启用了planeDetection,ARKit可以检测到摄像头所捕捉图像中的平面,并记录其位置和大小信息。

1.2 ARKit 工作流程简介

如下图,解释的是 ARKit 的工作流程。其中蓝色表示 ARKit 负责的部分,绿色表示 SceneKit 负责的部分:

ARKit工作流程大意图

从上图可以看出,AR工作的大致流程如下:

  • 首先,ARKit 利用摄像头拍摄现实场景的画面,然后 SceneKit 用来建立虚拟世界。
  • 建立好了以后,ARKit 负责将现实世界和虚拟世界的信息融合,并渲染出一个 AR 世界。
  • 在渲染的同时,ARKit 要负责以下三件事:
  1. 维持世界追踪 指的是当你移动摄像头,要去获取新的现实世界的信息。
  2. 进行场景解析 指的是解析现实世界中有无特征点、平面等关键信息。
  3. 处理与虚拟世界的互动 指的是当用户点击或拖动屏幕时,处理有没有点击到虚拟物体或者要不要进行添加/删除物体的操作。
  • 总的来说,ARKit 主要做的事是:捕捉现实世界信息、将现实和虚拟世界混合渲染、并且时刻处理新的信息或者进行互动。

2. ARKit框架类结构

iOS 平台的 AR 应用通常由 ARKit 和渲染引擎两部分构成:

AR 应用通常由 ARKit 和渲染引擎两部分构成

ARKit 的 ARSession 负责管理每一帧的信息。ARSession 做了两件事:拍摄图像并获取传感器数据;对数据进行分析处理后逐帧输出。如下图:

ARKit 的 ARSession 职责

要做AR相关开发肯定首先要熟悉两个框架:

此外还可以使用Unity方案实现跨平台开发。

ARKit是基于3D场景(SceneKit)实现的增强现实,这是主流方式。 ARKit还基于2D场景(SceneKit)实现的增强现实。所以要学习ARKit框架外还有必要学习这两个框架:SceneKitSpriteKit。后续博客会详细讲解这两个框架,尽请期待....

ARKit并不是一个独立就能够运行的框架,而是必须要SceneKit一起用才可以。:

  1. ARKit 实现相机捕捉现实世界图像并恢复三维世界
  2. SceneKit 实现在图像中现实虚拟的3D模型

2.1 SpriteKit框架简介

  • SpriteKit: 在应用程序中添加具有流畅动画的高性能2D内容,或使用一组基于2D游戏的高级工具创建游戏。 SpriteKit是一个通用框架,用于在二维中绘制形状、粒子、文本、图像和视频。它利用Metal来实现高性能的渲染,同时提供一个简单的编程接口,使得创建游戏和其他图形密集型应用程序变得容易。使用一组丰富的动画和物理行为,您可以快速地为您的视觉元素添加生命,并在屏幕之间优雅地转换。 SpriteKit支持iOS、macOS、tvOS和watchOS,并与GameplayKitSceneKit等框架集成良好。
  • SpriteKit框架结构如下:
    SpriteKit框架结构

2.2 SceneKit框架简介

  • SceneKit框架:用来创建3D游戏,并使用高级场景描述将3D内容添加到应用程序中。轻松添加动画,物理模拟,粒子效果,和现实的物理渲染。 SceneKit结合了一个高性能的渲染引擎和一个用于导入、操作和渲染3D资产的描述性API。与底层api(如MetalOpenGL)不同,后者需要您精确地实现显示场景的呈现算法的细节,而SceneKit只需要描述场景的内容以及您希望它执行的操作或动画。
  • SceneKit框架结构如下:

SceneKit框架结构

ARKit 和 SceneKit 的坐标系看起来就像这样:

ARKit 和 SceneKit 的坐标系

ARKit 和 SceneKit 关系图如下:

ARKit 和 SceneKit 关系图

2.3 ARKit框架

  • ARKit对开发环境要求:

Xcode版本:Xcode9及以上 iOS系统:iOS11及以上 iOS设备要求:处理器A9及以上(iPhone6s 、iPhone6sPlus、iPhone7 iPhone7Plus、iPhoneSE、iPad Pro(9.7、10.5、12.9)、iPad(2017)) MacOS系统:10.12.4及以上 (安装Xcode9对Mac系统版本有要求)

  • ARKit框架类结构汇总:

ARKit框架类结构汇总

2.3.1 ARKit框架与其他框架关联

ARKit框架与其他框架关联
如上图可以看出ARKit并不是一个独立就能够运行的框架,而是必须要SceneKit一起用才可以,换一句话说,如果只有ARKit,而没有SceneKit,那么ARKit和一般的相机没有任何区别。相机捕捉现实世界图像,由ARKit来实现;在图像中显示虚拟3D模型,由SceneKit来实现。

其中ARKit框架中中显示3D虚拟增强现实的视图ARSCNView继承于SceneKit框架中的SCNView,而SCNView又继承于UIKit框架中的UIView。

UIView的作用是将视图显示在iOS设备的window中,SCNView的作用是显示一个3D场景,ARSCNView的作用也是显示一个3D场景,只不过这个3D场景是由摄像头捕捉到的现实世界图像构成。

ARSCNView只是一个视图容器,它的作用是管理一个ARSession

在一个完整的虚拟增强现实体验中,ARKit框架只负责将真实世界画面转变为一个3D场景,这一个转变的过程主要分为两个环节:由ARCamera负责捕捉摄像头画面,由ARSession负责搭建3D场景。

ARKit3D现实场景中添加虚拟物体使用的是父类SCNView的功能,这个功能早在iOS8时就已经添加(SceneKit是iOS8新增),ARSCNView所有跟场景和虚拟物体相关的属性及方法都是自己父类SCNView的。

2.3.2 ARKit框架工作原理

ARKit提供两种虚拟增强现实视图,他们分别是3D效果的ARSCNView2D效果的ARSKView。无论是使用哪一个视图都是用了相机图像作为背景视图,而这一个相机的图像就是由框架中的相机类ARCamera来捕捉的。

然而 ARSCNViewARCamera两者之间并没有直接的关系,它们之间是通过AR会话,也就是ARKit框架中非常重量级的一个类ARSession来搭建沟通桥梁的。

如果我们要想运行一个ARSession会话,我们必须要指定一个称之为ARSessionConfiguration(会话追踪配置)的对象,ARSessionConfiguration的主要目的就是负责追踪相机在3D世界中的位置以及一些特征场景的捕捉(例如平面捕捉)。

ARSessionConfiguration是一个父类,为了更好的看到增强现实的效果,苹果官方建议我们使用它的子类ARWorldTrackingSessionConfiguration,该类只支持A9芯片之后的机型,也就是iPhone6s之后的机型。

如下图是ARSession会话扮演的角色:

ARSession的关系

ARSession搭建沟通桥梁的参与者主要有两个ARWorldTrackingSessionConfiguration与ARFrame。

ARWorldTrackingSessionConfiguration(会话追踪配置)的作用是跟踪设备的方向和位置,以及检测设备摄像头看到的现实世界的表面。它的内部实现了一系列非常庞大的算法计算以及调用了你的iPhone必要的传感器来检测手机的移动及旋转甚至是翻滚。

当ARWorldTrackingSessionConfiguration计算出相机在3D世界中的位置时,它本身并不持有这个位置数据,而是将其计算出的位置数据交给ARSession去管理,而相机的位置数据对应的类就是ARFrame。

我们可以看到ARSession类一个属性叫做currentFrame,维护的就是ARFrame这个对象。

其中ARCamera只负责捕捉图像,不参与数据的处理。它属于3D场景中的一个环节,每一个3D Scene都会有一个Camera,它觉得了我们看物体的视野。

如下图是ARSession和ARFrame的关系:

ARSession和ARFrame的关系

2.3.3 ARKit框架工作流程

  • ARKit框架工作流程:
  1. ARSCNView加载场景SCNScene
  2. SCNScene启动相机ARCamera开始捕捉场景
  3. 捕捉场景后ARSCNView开始将场景数据交给Session
  4. Session通过管理ARSessionConfiguration实现场景的追踪并且返回一个ARFrame
  5. ARSCNView的scene添加一个子节点(3D物体模型)

ARKit框架工作流程图如下:

ARKit框架工作流程图

  • ARKit框架中一下类关系说明:
  1. ARKit框架中中显示3D虚拟增强现实的视图ARSCNView继承于SceneKit框架中的SCNView,而SCNView又继承于UIKit框架中的UIView。
  2. 在一个完整的虚拟增强现实体验中,ARKit框架只负责将真实世界画面转变为一个3D场景,这一个转变的过程主要分为两个环节:由 ARCamera负责捕捉摄像头画面,由ARSession负责搭建3D场景。
  3. ARSCNViewARCamera两者之间并没有直接的关系,它们之间是通过AR会话,也就是ARKit框架中非常重量级的一个类ARSession来搭建沟通桥梁的。
  4. 要想运行一个ARSession会话,你必须要指定一个称之为会话追踪配置的对象:ARSessionConfiguration, ARSessionConfiguration的主要目的就是负责追踪相机在3D世界中的位置以及一些特征场景的捕捉(例如平面捕捉),这个类本身比较简单却作用巨大。

3. ARKit核心类

VRKit核心类头文件

  • 头文件定义如下:
#import <ARKit/ARError.h>

#import <ARKit/ARSession.h>
#import <ARKit/ARConfiguration.h>
#import <ARKit/ARFrame.h>
#import <ARKit/ARCamera.h>
#import <ARKit/ARHitTestResult.h>
#import <ARKit/ARLightEstimate.h>
#import <ARKit/ARPointCloud.h>
#import <ARKit/ARReferenceImage.h>
#import <ARKit/ARReferenceObject.h>
#import <ARKit/ARVideoFormat.h>
#import <ARKit/ARCollaborationData.h>
#import <ARKit/ARWorldMap.h>
#import <ARKit/ARRaycastQuery.h>
#import <ARKit/ARTrackedRaycast.h>
#import <ARKit/ARRaycastResult.h>

#import <ARKit/ARAnchor.h>
#import <ARKit/AREnvironmentProbeAnchor.h>
#import <ARKit/ARFaceAnchor.h>
#import <ARKit/ARFaceGeometry.h>
#import <ARKit/ARImageAnchor.h>
#import <ARKit/ARObjectAnchor.h>
#import <ARKit/ARParticipantAnchor.h>
#import <ARKit/ARPlaneAnchor.h>
#import <ARKit/ARPlaneGeometry.h>

#import <ARKit/ARSkeleton.h>
#import <ARKit/ARSkeletonDefinition.h>
#import <ARKit/ARBody2D.h>
#import <ARKit/ARBodyAnchor.h>

#import <ARKit/ARCoachingOverlayView.h>
#import <ARKit/ARSCNView.h>
#import <ARKit/ARSKView.h>
#import <ARKit/ARMatteGenerator.h>

#import <ARKit/ARQuickLookPreviewItem.h>
复制代码

3.1 ARError

  • ARError: ARKit方法抛出错误的类型。 ARError它是一个结构体类型,如果:
struct ARError
复制代码

ARError 的错误码如下:

  • cameraUnauthorized: 一个错误代码,表明该应用程序没有使用相机的用户权限。
  • fileIOFailed: 一个错误代码,表明ARKit无法读取或写入所需的文件。
  • insufficientFeatures: 错误代码表明ARKit没有完成任务所需的特性。
  • invalidCollaborationData: 一个错误代码,指示ARKit无法使用特定的协作数据对象更新应用程序的会话。
  • invalidConfiguration: 指示配置包含不明确或错误数据的错误代码。
  • invalidReferenceImage: 指示参考图像不可用的错误代码。
  • invalidReferenceObject: 指示引用对象不可用的错误代码。
  • invalidWorldMap: 表示世界地图不可用的错误代码。
  • microphoneUnauthorized: 一个错误代码,表明该应用程序没有使用麦克风的用户权限。
  • objectMergeFailed: 一个错误代码,表明ARKit无法合并检测到的对象。
  • sensorFailed: 指示传感器未能提供所需输入的错误代码。
  • sensorUnavailable: 指示运行会话所需传感器的错误代码不可用。
  • unsupportedConfiguration: 一个错误代码,表明您运行的配置在iOS设备上不受支持。
  • worldTrackingFailed: 一个错误代码,表明世界跟踪遇到了一个致命的错误。

3.2 ARSession

  • ARSession:用于控制增强现实体验的主要对象。

ARSession对象协调ARKit代表您执行的主要进程,以创建增强现实体验。这些过程包括从设备的运动感知硬件读取数据,控制设备的内置摄像头,并对捕获的摄像头图像进行图像分析。该会话综合了所有这些结果,从而在设备所在的真实空间和建模AR内容的虚拟空间之间建立了一种对应关系。

class ARSession : NSObject
复制代码
ARSession类定义
ARSession属性方法

3.2.1 ARSessionObserver

protocol ARSessionObserver
复制代码

该协议定义了ARSessionDelegateARSCNViewDelegateARSKViewDelegate协议通用的可选方法。您可以在采用这些协议之一时实现此协议的方法。

3.2.2 ARSessionDelegate

  • ARSessionDelegate: 提供方法可以实现从AR会话接收捕获的视频帧图像和跟踪状态。
protocol ARSessionDelegate
复制代码

如果您需要直接处理会话捕获的ARFrame对象,或者直接跟踪会话的已跟踪ARAnchor对象集的更改,请实现此协议。通常,您在构建用于显示AR内容的自定义视图时采用此协议—如果您使用SceneKit或SpriteKit显示内容,则ARSCNViewDelegateARSKViewDelegate协议提供类似的信息并与这些技术集成。 该协议扩展了ARSessionObserver协议,因此您的会话委托也可以实现那些方法来响应会话状态的更改。

3.3 ARConfiguration

  • ARConfiguration:一个对象,它定义在给定时间内在会话中启用的特定ARKit特性。
class ARConfiguration : NSObject
复制代码

ARConfiguration为您可以在AR体验中配置的不同选项定义了一个基类。你自己不分配配置;而是实例化它的一个子类。

要实现AR体验的特性,您需要创建以下子类之一,并通过run(with:)在您的会话中运行它。一个会话一次只能运行一种配置,所以选择一种最能促进所需AR体验的配置。ARConfiguration提供了以下一些配置:

ARConfiguration子类

ARConfiguration 类结构

ARConfiguration类结构

具体定义如下:

/**
 一个对象来描述和配置增强现实技术,以在ARSession中使用。
 */
API_AVAILABLE(ios(11.0))
@interface ARConfiguration : NSObject <NSCopying>

/**
 确定此设备是否支持ARConfiguration。
 */
@property (class, nonatomic, readonly) BOOL isSupported;

/**
此配置和设备支持的视频格式列表。
 @discussion 列表中的第一个元素是会话输出的默认格式。
 */
@property (class, nonatomic, readonly) NSArray<ARVideoFormat *> *supportedVideoFormats API_AVAILABLE(ios(11.3));

/**
 视频格式的会话输出。
 */
@property (nonatomic, strong) ARVideoFormat *videoFormat API_AVAILABLE(ios(11.3));

/**
 决定了坐标系应该如何与世界保持一致。
 @discussion 默认是 ARWorldAlignmentGravity.
 */
@property (nonatomic, assign) ARWorldAlignment worldAlignment;

/**
 启用或禁用光估计。
 @discussion 默认开启
 */
@property (nonatomic, assign, getter=isLightEstimationEnabled) BOOL lightEstimationEnabled;

/**
 确定是否捕获和提供音频数据。
 @discussion 默认禁止.
 */
@property (nonatomic, assign) BOOL providesAudioData;

/**
为每个框架提供的语义理解类型。

 @discussion 使用“supportsFrameSemantics”类方法检查要运行的配置类型是否支持框架语义集。例如,当运行一个会话时
一个ARWorldTrackingConfiguration类型的配置需要使用“+[ARWorldTrackingConfiguration supportsFrameSemantics:]”来执行上述检查。
如果该选项,则引发异常
不支持。默认为ARFrameSemanticNone。
 @see ARFrameSemantics
 @see +[ARConfiguration supportsFrameSemantics:]
*/
@property (nonatomic, assign) ARFrameSemantics frameSemantics API_AVAILABLE(ios(13.0));

/**
 确定设备和ARConfiguration类是否支持帧语义的类型。

 @discussion 并非所有设备都支持语义框架理解。使用“supportsFrameSemantics”类方法检查要运行的配置类型是否支持
框架语义集。例如,当运行一个配置类型为ARWorldTrackingConfiguration的会话时,就需要使用它
+[ARWorldTrackingConfiguration supportsFrameSemantics:]来执行上述检查。
 @see ARFrameSemantics
*/
+ (BOOL)supportsFrameSemantics:(ARFrameSemantics)frameSemantics API_AVAILABLE(ios(13.0));


/** Unavailable */
- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;

@end
复制代码

3.3.1 ARObjectScanningConfiguration

class ARObjectScanningConfiguration : ARConfiguration
复制代码

ARObjectScanningConfiguration类结构

ARObjectScanningConfiguration类定义:

/**
 扫描对象的配置。
 
 @discussion 对象扫描配置运行世界跟踪,捕获额外的细节以创建引用对象。
运行对象扫描将消耗额外的能量,以提供更详细的功能。
可以在会话中调用createReferenceObject方法来捕获世界中对象的扫描。
 */
API_AVAILABLE(ios(12.0))
@interface ARObjectScanningConfiguration : ARConfiguration

/**
 启用或禁用连续自动对焦。
 @discussion 默认开启.
 */
@property (nonatomic, assign, getter=isAutoFocusEnabled) BOOL autoFocusEnabled;

/**
 场景中要检测的飞机类型。
 @discussion 如果设置,新的飞机将继续被检测和更新的时间。检测到的平面将被添加到会话中
ARPlaneAnchor对象。如果两个平面合并,则新平面将被删除。默认为ARPlaneDetectionNone。
 */
@property (nonatomic, assign) ARPlaneDetection planeDetection;

- (instancetype)init;
+ (instancetype)new NS_SWIFT_UNAVAILABLE("Use init() instead");

@end
复制代码

要创建一个识别物理环境中的对象的应用程序,首先要在开发期间使用ARObjectScanningConfiguration 扫描它们。扫描对象之后,调用createReferenceObject(transform:center:extent:completionHandler:) 将其转换为一个可以在运行时再次检测它的ARReferenceObject。当用户运行你的应用程序时,你要求ARKit通过运行一个世界跟踪配置来寻找你扫描的objects,并将引用对象分配给它的detectionObjects属性。

func createReferenceObject(transform: simd_float4x4, 
                    center: simd_float3, 
                    extent: simd_float3, 
         completionHandler: @escaping (ARReferenceObject?, Error?) -> Void)
复制代码

这个函数会返回一个表示世界地图的指定区域的一个ARReferenceObject。 参数说明:

  1. transform:定义要提取区域的局部坐标系统的原点和方向的变换矩阵。
  2. center:相对于transform指定的原点的一个点,它定义要提取的区域的边界框的中心。
  3. extent:要提取的区域的宽度、高度和深度,以中心点为中心并指向变换指定的本地坐标系统。
  4. completionHandler:在ARKit完成创建引用对象后异步调用的处理程序。处理程序有两个参数:
  5. referenceObject: 生成的ARReferenceObject,如果不能创建引用对象,则为nil。 6 error: 如果referenceObject为nil,则会出现一个ARError来描述失败。

注意:此方法仅在使用ARObjectScanningConfiguration运行会话时有效,该配置支持扫描引用对象所需的高保真空间数据收集。在具有不同配置的会话上调用此方法将立即调用带有错误的completionHandler。

要使用提取的参考对象进行3D对象检测,请将其分配给世界跟踪配置的detectionObjects属性。您可以将引用对象保存到文件中,并将它们添加到Xcode资产目录中,从而将它们绑定到应用程序中。

当ARKit检测到一个引用图像时,结果ARObjectAnchor的转换基于引用对象的坐标系统的组织——在提取引用对象时指定的转换。例如,如果引用对象表示位于水平面上的物理项,则虚拟内容应该出现在物理对象所做的任何表面上。要在提取后调整引用对象的原点,请使用applyingTransform()方法。

  • applyingTransform()方法说明: 这个方法返回一个将指定的转换应用于此引用对象的几何数据而创建的新引用对象。
func applyingTransform(_ transform: simd_float4x4) -> ARReferenceObject
复制代码

传入参数transform: 参考对象的局部坐标空间中的变换矩阵。

ARWorldMap中提取引用对象时,要定义它的本地坐标空间。如果现有的引用对象具有与对象的预期用途不匹配的局部坐标原点,则调用此方法来更改引用对象相对于其所表示的物理对象的原点。

ARKit检测到一个引用对象时,结果ARObjectAnchor的转换基于引用对象的坐标系统的组织。例如,如果引用对象表示位于水平面上的物理项,则虚拟内容应该出现在物理对象所做的任何表面上。因此,将引用对象的坐标原点与物理对象的底部对齐通常很有用。

3.3.2 ARBodyTrackingConfiguration

class ARBodyTrackingConfiguration : ARConfiguration
复制代码

当ARKit在后摄像头提要中识别一个人时,它调用session(_:didAdd:),并向您传递一个ARBodyAnchor,您可以使用它来跟踪身体的运动。 启用了平面检测和图像检测。如果使用body锚来显示虚拟字符,则可以在选择的表面或图像上设置该字符。 默认情况下,ARConfiguration.FrameSemantics类型的bodyDetection是启用的,它允许你访问一个人的关节位置,ARKit通过帧的detectedBody在摄像头反馈中检测到这个人。

3.3.2.1 ARBodyTrackingConfiguration 类定义

ARBodyTrackingConfiguration类结构

/**
 用于运行身体跟踪的配置。
 
 @discussion 身体跟踪提供了6个自由度的跟踪被检测的身体在现场。默认情况下,ARFrameSemanticBodyDetection是
启用。
 @see ARBodyAnchor
 @see -[ARFrame detectedBody]
 */
API_AVAILABLE(ios(13.0))
@interface ARBodyTrackingConfiguration : ARConfiguration

/**
 启用或禁用连续自动对焦。
 @discussion 默认开启.
 */
@property (nonatomic, assign, getter=isAutoFocusEnabled) BOOL autoFocusEnabled;

/**
 世界跟踪将定位和跟踪的物理空间的初始地图。
 @discussion 如果设置了,会话将尝试本地化到提供的映射
在本地化成功或再次运行之前,将调用有限的跟踪状态
指定了不同的(或没有)初始映射。一旦本地化,地图将被扩展
并且可以在会话中使用' getCurrentWorldMap '方法再次保存。
 */
@property (nonatomic, strong, nullable) ARWorldMap *initialWorldMap;

/**
 运行环境纹理的模式。
 @discussion 如果设置,纹理信息将被积累和更新。向会话添加一个AREnvironmentProbeAnchor
将获得当前环境纹理从探测器的角度可以用来照明
场景中的虚拟对象。默认为AREnvironmentTexturingNone。
 */
@property (nonatomic, assign) AREnvironmentTexturing environmentTexturing;

/**
 确定环境纹理是否具有高动态范围。默认启用。
 */
@property (nonatomic, assign) BOOL wantsHDREnvironmentTextures;

/**
 场景中要检测的飞机类型。
 @discussion 如果设置,新的飞机将继续被检测和更新的时间。检测到的平面将被添加到会话中
ARPlaneAnchor对象。如果两个平面合并,则新平面将被删除。默认为ARPlaneDetectionNone。
 */
@property (nonatomic, assign) ARPlaneDetection planeDetection;

/**
在场景中检测图像。
@discussion 如果设置,会话将尝试检测指定的图像。当检测到一个图像时,ARImageAnchor将被添加到会话中。
*/
@property (nonatomic, copy) NSSet<ARReferenceImage *> *detectionImages;

/**
 启用可用于校正图像的物理大小的比例因子的估计。
 @discussion 如果设置为true ARKit,将尝试使用计算过的摄像机位置来计算给定物理大小所对应的比例
与估计的不同。关于估计比例尺的信息可以在ARImageAnchor上找到estimatedScaleFactor属性。
 @note 当设置为true时,返回的ARImageAnchor的转换将使用估计的比例因子来修正转换。默认值是NO。
 */
@property (nonatomic, assign) BOOL automaticImageScaleEstimationEnabled;

/**
 允许估计比例因子,该比例因子可用于在3D中纠正骨骼的物理大小。
 @discussion 如果设置为true ARKit,将尝试使用计算过的摄像机位置来计算给定物理大小所对应的比例
与默认值不同。关于估计比例尺的信息可以在ARBodyAnchor上找到estimatedScaleFactor属性。
 @note 当设置为true时,返回的ARBodyAnchor的转换将使用估计的比例因子来修正转换。默认值是NO。
 */
@property (nonatomic, assign) BOOL automaticSkeletonScaleEstimationEnabled;
/**
 同时跟踪的最大图像数。
 @discussion 设置跟踪图像的最大数量将限制给定帧中可以跟踪的图像的数量。
如果看到的图像超过最大值,则只有已经被跟踪的图像将继续跟踪,直到丢失跟踪或删除另一个图像为止。
不管跟踪的图像是什么,图像都将继续被检测到。默认值为0。
 */
@property (nonatomic, assign) NSInteger maximumNumberOfTrackedImages;

- (instancetype)init;
+ (instancetype)new NS_SWIFT_UNAVAILABLE("Use init() instead");

@end
复制代码
3.3.2.1 ARBodyTrackingConfiguration 属性和方法
  • 创建一个配置
//创建一个新的身体跟踪配置。
init()
//试图使用此会话配置恢复前一个AR会话的状态。
var initialWorldMap: ARWorldMap?

复制代码
  • 估计身体比例
//一个标志,它决定ARKit是否估计它所跟踪的物体的高度。
var automaticSkeletonScaleEstimationEnabled: Bool

复制代码
  • 支持自动对焦
//一个布尔值,用于确定设备摄像头是使用固定焦距还是自动焦距。
var isAutoFocusEnabled: Bool

复制代码
  • 使飞机检测
//一个值,指定会话是否以及如何尝试自动检测摄像机捕获的图像中的平面。
var planeDetection: ARWorldTrackingConfiguration.PlaneDetection

//选择是否和如何检测捕获的图像平面
struct ARWorldTrackingConfiguration.PlaneDetection

复制代码
  • 使图像跟踪
//一个标志,指示ARKit估计和设置跟踪图像的规模代表您。
var automaticImageScaleEstimationEnabled: Bool

//ARKit试图在用户环境中检测的一组图像。
var detectionImages: Set<ARReferenceImage>

//检测图像的最大数目,为其同时跟踪运动。
var maximumNumberOfTrackedImages: Int

复制代码
  • 增加了现实的反射
//一个标志,指示ARKit创建HDR格式的环境纹理。
var wantsHDREnvironmentTextures: Bool

//用于生成环境纹理。
var environmentTexturing: ARWorldTrackingConfiguration.EnvironmentTexturing

复制代码

3.3.3 ARFaceTrackingConfiguration

class ARFaceTrackingConfiguration : ARConfiguration
复制代码

人脸跟踪配置检测可以在设备的前置摄像头中看到的人脸。当ARKit检测到人脸时,它会创建一个ARFaceAnchor对象,该对象提供关于人脸的位置和方向、拓扑结构以及描述面部表情的特征的信息。

面部跟踪只能在带有前置TrueDepth摄像头的iOS设备上使用(参见iOS设备兼容性参考资料)。在为用户提供任何需要面部跟踪的功能之前,使用ARFaceTrackingConfiguration isSupported属性来确定当前设备上是否可以进行面部跟踪。

ARFaceTrackingConfiguration类不提供方法或属性,但是支持从它的超类ARConfiguration继承的所有属性。此外,当您启用isLightEstimationEnabled设置时,面部跟踪配置将检测到的面部用作光探测器,并提供定向或环境照明的估计(一个ARDirectionalLightEstimate对象)。

面部跟踪为您的应用程序提供个人面部信息。如果你使用ARKit面部跟踪功能,你的应用程序必须包括一个隐私政策,向用户描述你打算如何使用面部跟踪和面部数据。有关详细信息,请参见苹果开发者程序许可协议

3.3.3.1 ARFaceTrackingConfiguration 类定义

ARFaceTrackingConfiguration类定义

/**
 运行面部跟踪的配置.
 
 @discussion 面部跟踪使用前置摄像头在3D中跟踪面部,提供关于面部拓扑结构和表情的细节。
检测到的人脸将作为ARFaceAnchor对象添加到会话中,该对象包含关于头部姿态、网格、眼睛姿态和混合形状的信息
系数。如果光估计是启用的,被检测的脸将被视为一个光探针,用来估计入射光的方向。
 */
API_AVAILABLE(ios(11.0))
@interface ARFaceTrackingConfiguration : ARConfiguration

/**
 可以同时跟踪的最大面数。
 */
@property (class, nonatomic, readonly) NSInteger supportedNumberOfTrackedFaces API_AVAILABLE(ios(13.0));

/**
 同时跟踪的最大面数。
 @discussion 设置最大跟踪面数将限制给定帧中可以跟踪的面数。
如果超过最大值可见,只有已经被跟踪的面孔将继续跟踪,直到跟踪丢失或另一个面孔被删除。
默认值为1。
 */
@property (nonatomic, assign) NSInteger maximumNumberOfTrackedFaces API_AVAILABLE(ios(13.0));

/**
 指示是否可以在此设备上启用世界跟踪。
 */
@property (class, nonatomic, readonly) BOOL supportsWorldTracking API_AVAILABLE(ios(13.0));

/**
 启用或禁用世界跟踪。默认情况下禁用。
 
 @discussion 启用后,ARSession使用后置摄像头来跟踪设备在世界上的方位和位置。摄像机变换和ARFaceAnchor变换将在世界坐标空间中。
 */
@property (nonatomic, assign, getter=isWorldTrackingEnabled) BOOL worldTrackingEnabled API_AVAILABLE(ios(13.0));

- (instancetype)init;
+ (instancetype)new NS_SWIFT_UNAVAILABLE("Use init() instead");

@end
复制代码
3.3.3.2 ARFaceTrackingConfiguration 属性和方法
  • 创建一个配置
//创建一个新的面部跟踪配置。
init()

复制代码
  • 开启世界跟踪
//iOS设备是否支持世界跟踪与面部跟踪。
class var supportsWorldTracking: Bool


//使世界跟踪与脸跟踪是否开启。
var isWorldTrackingEnabled: Bool

复制代码
  • 跟踪多个面孔
//同时跟踪的最大面数。
var maximumNumberOfTrackedFaces: Int

//ARKit可以同时跟踪的最大面数。
class var supportedNumberOfTrackedFaces: Int

复制代码

3.3.4 ARWorldTrackingConfiguration

  • ARWorldTrackingConfiguration : 跟踪设备相对于任何表面,人,或已知的图像和对象的位置和方向,ARKit可能会发现和跟踪使用设备的后摄像头。
class ARWorldTrackingConfiguration : ARConfiguration
复制代码

所有AR配置都建立了设备所在的真实世界与虚拟3d坐标空间之间的对应关系,在虚拟坐标空间中,您可以对内容进行建模。当您的应用程序将虚拟内容与实时摄像机图像混合时,用户会产生一种错觉,认为您的虚拟内容是真实世界的一部分。

创建和维护空间之间的这种对应关系需要跟踪设备的移动。ARWorldTrackingConfiguration类使用六个自由度(6DOF)跟踪设备的移动:三个旋转轴(滚动、俯仰和偏航)和三个平移轴(xyz中的移动)。

这种跟踪可以创造身临其境的基于“增大化现实”技术的游戏体验:虚拟对象可以呆在同一个地方出现相对于现实世界,即使用户倾斜设备高于或低于该对象,或移动周围的设备对象的两侧和背部。

六个自由度跟踪

ARWorldTrackingConfiguration 提供 6DoF(Six Degree of Freedom)的设备追踪。包括三个姿态角 Yaw(偏航角)、Pitch(俯仰角)和 Roll(翻滚角),以及沿笛卡尔坐标系中 XYZ 三轴的偏移量,如下图:

在这里插入图片描述
不仅如此,ARKit 还使用了 VIO(Visual-Inertial Odometry)来提高设备运动追踪的精度。在使用惯性测量单元(IMU)检测运动轨迹的同时,对运动过程中摄像头拍摄到的图片进行图像处理。将图像中的一些特征点的变化轨迹与传感器的结果进行比对后,输出最终的高精度结果。

3.3.4.1 ARWorldTrackingConfiguration 类定义

ARWorldTrackingConfiguration还提供了几种方法,让你的应用程序识别或与相机可见的真实世界场景的元素进行交互:

  1. 使用planeDetection查找真实世界的水平或垂直表面,将它们作为ARPlaneAnchor对象添加到会话中。
  2. 使用detectionImages识别和跟踪已知的2D图像的移动,将它们作为ARImageAnchor对象添加到场景中。
  3. 使用detectionObjects来识别已知的3D对象,将它们作为ARObjectAnchor对象添加到场景中。
  4. ARFrameARViewARSCNViewARSKView上使用光线投射函数来查找与摄像机视图中的2D点相关的真实世界特征的3D位置。

ARWorldTrackingConfiguration 类结构

ARWorldTrackingConfiguration类定义:

/**
 运行世界跟踪的配置.
 
 @discussion 世界跟踪提供6个自由度的跟踪设备。
通过在场景中寻找特征点,世界跟踪可以对帧执行命中测试。
 一旦会话暂停,跟踪将不能再继续。
 */
API_AVAILABLE(ios(11.0))
@interface ARWorldTrackingConfiguration : ARConfiguration

/**
 启用或禁用连续自动对焦。
 @discussion 默认开启.
 */
@property (nonatomic, assign, getter=isAutoFocusEnabled) BOOL autoFocusEnabled API_AVAILABLE(ios(11.3));

/**
 运行环境纹理的模式。
 @discussion 如果设置,纹理信息将被积累和更新。向会话添加一个AREnvironmentProbeAnchor
将获得当前环境纹理从探测器的角度可以用来照明
场景中的虚拟对象。默认为AREnvironmentTexturingNone。
 */
@property (nonatomic, assign) AREnvironmentTexturing environmentTexturing API_AVAILABLE(ios(12.0));

/**
 确定环境纹理是否具有高动态范围。
 默认启用。
 */
@property (nonatomic, assign) BOOL wantsHDREnvironmentTextures API_AVAILABLE(ios(13.0));

/**
 场景中要检测的飞机类型。
 @discussion 如果设置,新的飞机将继续被检测和更新的时间。检测到的平面将被添加到会话中
ARPlaneAnchor对象。如果两个平面合并,则新平面将被删除。默认为ARPlaneDetectionNone。
 */
@property (nonatomic, assign) ARPlaneDetection planeDetection;

/**
 世界跟踪将定位和跟踪的物理空间的初始地图。
 @discussion 如果设置了,会话将尝试本地化到提供的映射
在本地化成功或再次运行之前,将调用有限的跟踪状态
指定了不同的(或没有)初始映射。一旦本地化,地图将被扩展
并且可以在会话中使用' getCurrentWorldMap '方法再次保存。
 */
@property (nonatomic, strong, nullable) ARWorldMap *initialWorldMap API_AVAILABLE(ios(12.0));

/**
 在场景中检测图像。
 @discussion 如果设置,会话将尝试检测指定的图像。当检测到一个图像时,ARImageAnchor将被添加到会话中。
 */
@property (nonatomic, copy, null_resettable) NSSet<ARReferenceImage *> *detectionImages API_AVAILABLE(ios(11.3));

/**
 启用可用于校正图像的物理大小的比例因子的估计。
 @discussion 如果设置为true, ARKit将尝试使用计算过的摄像机位置来计算给定物理大小所对应的比例
与估计的不同。关于估计比例尺的信息可以在ARImageAnchor上找到estimatedScaleFactor属性。
 @note 当设置为true时,返回的ARImageAnchor的转换将使用估计的比例因子来修正转换。默认值是NO。
  */
@property (nonatomic, assign) BOOL automaticImageScaleEstimationEnabled API_AVAILABLE(ios(13.0));

/**
 同时跟踪的最大图像数。
 @discussion 设置跟踪图像的最大数量将限制给定帧中可以跟踪的图像的数量。
如果看到的图像超过最大值,则只有已经被跟踪的图像将继续跟踪,直到丢失跟踪或删除另一个图像为止。
不管跟踪的图像是什么,图像都将继续被检测到。默认值为0。
 */
@property (nonatomic, assign) NSInteger maximumNumberOfTrackedImages API_AVAILABLE(ios(12.0));

/**
 要在场景中检测的对象。
 @discussion 如果设置,会话将尝试检测指定的对象。当检测到一个对象时,ARObjectAnchor将被添加到会话中。
 */
@property (nonatomic, copy) NSSet<ARReferenceObject *> *detectionObjects API_AVAILABLE(ios(12.0));

/**
 启用/禁用协作会话。默认情况下禁用。
 
 @discussion 当启用时,ARSession将使用其委托didOutputCollaborationData为其他参与者输出协作数据。
调用者的职责是将数据发送给每个参与者。当一个参与者接收到数据时,它
应该通过调用updateWithCollaborationData传递给ARSession。
 */
@property (nonatomic, assign, getter=isCollaborationEnabled) BOOL collaborationEnabled API_AVAILABLE(ios(13.0));

/**
 指示是否可以在此设备上启用使用前置摄像头的用户脸部跟踪。
 */
@property (class, nonatomic, readonly) BOOL supportsUserFaceTracking API_AVAILABLE(ios(13.0));

/**
 启用或禁用运行面部跟踪使用前置摄像头。默认情况下禁用。
当启用时,ARSession会检测人脸(如果在前置摄像头图像中可见),并将其添加到锚点列表中,
表示每个面的ARFaceAnchor对象。
 
 @discussion ARFaceAnchor对象的变换将在世界坐标空间中进行。
 @see ARFaceAnchor
 */
@property (nonatomic, assign, getter=userFaceTrackingEnabled) BOOL userFaceTrackingEnabled API_AVAILABLE(ios(13.0));

- (instancetype)init;
+ (instancetype)new NS_SWIFT_UNAVAILABLE("Use init() instead");

@end
复制代码
3.3.4.2 ARWorldTrackingConfiguration 属性, 方法说明
  • 创建一个配置:
  1. init() : 初始化一个新的世界跟踪配置。
  2. var initialWorldMap: ARWorldMap?: 试图使用此会话配置恢复前一个AR会话的状态。
  • 跟踪表面:
  1. var planeDetection: ARWorldTrackingConfiguration.PlaneDetection :一个值,指定会话是否以及如何自动尝试检测摄像机捕获的图像中的平面。
  2. struct ARWorldTrackingConfiguration.PlaneDetection: 选择是否和如何检测捕获的图像平面。
  3. var sceneReconstruction: ARConfiguration.SceneReconstruction: 使场景重建成为可能的标志。
  4. class func supportsSceneReconstruction(ARConfiguration.SceneReconstruction) -> Bool: 检查设备是否支持场景重建。
  • 检测或跟踪图像:
  1. var detectionImages: Set<ARReferenceImage>!: ARKit试图在用户环境中检测的一组图像。
  2. var maximumNumberOfTrackedImages: Int : 用于同时跟踪运动的检测图像的最大数目。
  3. var automaticImageScaleEstimationEnabled: Bool : 一个标志,指示ARKit估计和设置一个检测或跟踪图像的规模代表您。
  • 检测3D对象:
  1. var detectionObjects: Set<ARReferenceObject>: 一组用于ARKit尝试在用户环境中检测的3D对象。
  • 跟踪用户的脸:
  1. var userFaceTrackingEnabled: Bool: 一个标志,它决定ARKit是否在一个世界跟踪会话中跟踪用户的脸。
  2. class var supportsUserFaceTracking: Bool:一个布尔值,告诉你iOS设备是否支持在世界跟踪会话期间跟踪用户的脸。
  • 创建现实反射:
  1. var environmentTexturing: ARWorldTrackingConfiguration.EnvironmentTexturing: 行为ARKit用于生成环境纹理。
  2. enum ARWorldTrackingConfiguration.EnvironmentTexturing: 在世界跟踪AR会话中生成环境纹理的选项。
  3. class AREnvironmentProbeAnchor : 在世界跟踪AR会话中为特定空间区域提供环境照明信息的对象。
  4. var wantsHDREnvironmentTextures: Bool : 一个标志,指示ARKit创建HDR格式的环境纹理。
  • 管理设备摄像头行为:
  1. var isAutoFocusEnabled: Bool : 一个布尔值,用于确定设备摄像头是使用固定焦距还是自动焦距。
  • 允许多用户协作:
  1. var isCollaborationEnabled: Bool: 一个标志,选择你在一个点对点多用户增强现实的经验。

3.3.5 AROrientationTrackingConfiguration

class AROrientationTrackingConfiguration : ARConfiguration
复制代码

所有AR配置都建立了设备所在的真实世界与虚拟3D坐标空间之间的对应关系,在虚拟3D坐标空间中可以对内容进行建模。当你的应用程序将这些内容与实时的摄像头图像一起显示时,用户会产生一种错觉,认为你的虚拟内容是现实世界的一部分。

创建和维护空间之间的这种对应关系需要跟踪设备的移动。AROrientationTrackingConfiguration类使用三个自由度(3DOF)来跟踪设备的移动:具体来说,就是三个旋转轴(滚动、俯仰和偏航)。

三个自由度

这种基本级别的运动跟踪可以创建有限的AR体验:一个虚拟对象可以看起来是现实世界的一部分,即使用户旋转设备查看该对象的上面、下面或旁边。然而,这种配置不能跟踪设备的移动:非琐碎地改变设备的位置会打破AR错觉,导致虚拟内容相对于真实世界出现漂移。例如,用户不能四处走动查看虚拟对象的侧面和背面。此外,3DOF跟踪不支持平面检测或命中测试。

因为3DOF跟踪创建有限的AR体验,你通常不应该直接使用AROrientationTrackingConfiguration类。相反,使用ARWorldTrackingConfiguration进行6自由度的平面检测和命中测试。仅在6DOF跟踪暂时不可用的情况下,使用3DOF跟踪作为备份。

3.3.5.1 AROrientationTrackingConfiguration 类定义

AROrientationTrackingConfiguration类定义
AROrientationTrackingConfiguration 类定义

/**
 用于运行方向跟踪的配置。
 
 @discussion 定位跟踪提供了3个自由度的设备跟踪。
 */
API_AVAILABLE(ios(11.0))
@interface AROrientationTrackingConfiguration : ARConfiguration

/**
 启用或禁用连续自动对焦。
 @discussion 默认启用
 */
@property (nonatomic, assign, getter=isAutoFocusEnabled) BOOL autoFocusEnabled API_AVAILABLE(ios(11.3));

- (instancetype)init;
+ (instancetype)new NS_SWIFT_UNAVAILABLE("Use init() instead");

@end
复制代码
3.3.5.2 AROrientationTrackingConfiguration 属性方法说明
  • 创建一个配置:
  1. init() : 初始化一个新的方向跟踪配置。
  • 管理设备摄像头行为:
  1. var isAutoFocusEnabled: Bool: 一个布尔值,用于确定设备摄像头是使用固定焦距还是自动焦距。

3.3.6 ARImageTrackingConfiguration

class ARImageTrackingConfiguration : ARConfiguration
复制代码

所有AR配置都建立了设备所在的真实世界与虚拟3D坐标空间之间的对应关系,在虚拟3D坐标空间中可以对内容进行建模。当你的应用程序将这些内容与实时的摄像头图像一起显示时,用户会产生一种错觉,认为你的虚拟内容是现实世界的一部分。

通过ARImageTrackingConfiguration , ARKit不是通过跟踪设备相对于世界的运动来建立一个3D空间,而是仅仅通过检测和跟踪已知的二维图像在摄像机中的运动。ARWorldTrackingConfiguration也可以检测图像,但每种配置都有自己的优势。ARImageTrackingConfiguration 的特点如下 :

  • 与只跟踪图像相比,世界跟踪具有更高的性能成本,因此您的会话可以使用ARImageTrackingConfiguration一次可靠地跟踪更多的图像。
  • 只跟踪图像,让您锚虚拟内容到已知的图像,只有当这些图像是在相机的视野。世界跟踪与图像检测允许您使用已知的图像添加虚拟内容到3D世界,并继续跟踪该内容在世界空间的位置,即使图像不再在视图中。
  • 世界跟踪在稳定、静止的环境中效果最好。您可以在更多的情况下使用图像跟踪将虚拟内容添加到已知的图像中——例如,在移动的地铁车厢内的广告。

当图像跟踪配置检测到已知的图像时,它将以6个自由度(6DOF)跟踪它们的移动:具体来说,就是3个旋转轴(滚动、俯仰和偏航)和3个平移轴(xyz的移动)。

要使用ARImageTrackingConfiguration,请定义ARReferenceImage对象(在运行时或通过将它们绑定到Xcode资产目录中),并将它们分配给配置的trackingImages属性。然后,与任何AR配置一样,将配置传递给会话的run(_:options:)方法。

3.3.6.1 ARImageTrackingConfiguration 类定义

ARImageTrackingConfiguration类结构

ARImageTrackingConfiguration 类定义:

/**
 运行图像跟踪的配置。
 
 @discussion 图像跟踪提供6个自由度的跟踪已知图像。可以同时跟踪四幅图像。
 */
API_AVAILABLE(ios(12.0))
@interface ARImageTrackingConfiguration : ARConfiguration

/**
 启用或禁用连续自动对焦。
 @discussion 默认启用
 */
@property (nonatomic, assign, getter=isAutoFocusEnabled) BOOL autoFocusEnabled;

/**
 在场景中跟踪图像。
 */
@property (nonatomic, copy) NSSet<ARReferenceImage *> *trackingImages;

/**
 同时跟踪的最大图像数。
 @discussion 设置跟踪图像的最大数量将限制给定帧中可以跟踪的图像的数量。
如果看到的图像超过最大值,则只有已经被跟踪的图像将继续跟踪,直到丢失跟踪或删除另一个图像为止。
默认值为1。
 */
@property (nonatomic, assign) NSInteger maximumNumberOfTrackedImages;

- (instancetype)init;
+ (instancetype)new NS_SWIFT_UNAVAILABLE("Use init() instead");

@end
复制代码
3.3.6.2 ARImageTrackingConfiguration 属性说明
  • 创建一个配置:
  1. init(): 初始化一个新的图像跟踪配置。
  • 选择图像进行跟踪:
  1. var trackingImages: Set<ARReferenceImage> : ARKit试图在用户环境中检测和跟踪的一组图像。
  2. var maximumNumberOfTrackedImages: Int : 要同时跟踪运动的图像的最大数目。
  • 管理设备摄像头行为:
  1. var isAutoFocusEnabled: Bool: 一个布尔值,用于确定设备摄像头是使用固定焦距还是自动焦距。

3.3.7 ARObjectScanningConfiguration

class ARObjectScanningConfiguration : ARConfiguration
复制代码

要创建一个识别物理环境中的对象的应用程序:

  1. 首先要在开发期间使用ARObjectScanningConfiguration扫描它们。
  2. 扫描对象之后,调用 createReferenceObject(transform:center:extent:completionHandler:) 其转换为一个可以在运行时再次检测它的ARReferenceObject
  3. 当用户运行你的应用程序时,你要求ARKit通过运行一个世界跟踪配置来寻找你扫描的物体,并将引用对象分配给它的detectionObjects属性。

ARObjectScanningConfiguration仅用于开发场景。由于对象扫描所需的高保真空间映射具有较高的性能和能量消耗,因此禁用了许多对象扫描不需要的ARKit特性。

3.3.7.1 ARObjectScanningConfiguration 类定义

ARObjectScanningConfiguration类定义

ARPositionalTrackingConfiguration 类定义:

ARObjectScanningConfiguration

/**
 扫描对象的配置。
 
 @discussion 对象扫描配置运行世界跟踪,捕获额外的细节以创建引用对象。
运行对象扫描将消耗额外的能量,以提供更详细的功能。
可以在会话中调用createReferenceObject方法来捕获世界中对象的扫描。
 */
API_AVAILABLE(ios(12.0))
@interface ARObjectScanningConfiguration : ARConfiguration

/**
 启用或禁用连续自动对焦。
 @discussion 默认开启.
 */
@property (nonatomic, assign, getter=isAutoFocusEnabled) BOOL autoFocusEnabled;

/**
 场景中要检测的飞机类型。
 @discussion 如果设置,新的飞机将继续被检测和更新的时间。检测到的平面将被添加到会话中
ARPlaneAnchor对象。如果两个平面合并,则新平面将被删除。默认为ARPlaneDetectionNone。
 */
@property (nonatomic, assign) ARPlaneDetection planeDetection;

- (instancetype)init;
+ (instancetype)new NS_SWIFT_UNAVAILABLE("Use init() instead");

@end
复制代码
3.3.7.1 ARObjectScanningConfiguration 属性说明
  • 创建一个配置:
  1. init() : 初始化一个新的对象扫描配置。
  • 使飞机检测:
  1. var planeDetection: ARWorldTrackingConfiguration.PlaneDetection : 一个值,指定会话是否以及如何尝试自动检测摄像机捕获的图像中的平面。
  2. struct ARWorldTrackingConfiguration.PlaneDetection : 选择是否和如何检测捕获的图像平面。
  • 管理设备摄像头行为:
  1. var isAutoFocusEnabled: Bool : 一个布尔值,用于确定设备摄像头是使用固定焦距还是自动焦距。

3.3.8 ARPositionalTrackingConfiguration

class ARPositionalTrackingConfiguration : ARConfiguration
复制代码

通过以尽可能低的分辨率和帧速率运行摄像头,支持iOS设备的6个自由度跟踪。当您不需要解析摄像机提要(例如,虚拟现实场景)时,请使用此配置。

3.3.8.1 ARPositionalTrackingConfiguration 类定义

ARPositionalTrackingConfiguration类结构

/**
 用于运行位置跟踪的配置。
 
 @discussion 通过以尽可能低的分辨率和帧速率运行摄像机,位置跟踪提供了6个自由度的设备跟踪。
 */
API_AVAILABLE(ios(13.0))
@interface ARPositionalTrackingConfiguration : ARConfiguration

/**
 场景中要检测的飞机类型。
 @discussion 如果设置,新的飞机将继续被检测和更新的时间。检测到的平面将被添加到会话中
ARPlaneAnchor对象。如果两个平面合并,则新平面将被删除。默认为ARPlaneDetectionNone。
 */
@property (nonatomic, assign) ARPlaneDetection planeDetection;

/**
 世界跟踪将定位和跟踪的物理空间的初始地图。
 @discussion 如果设置了,会话将尝试本地化到提供的映射
在本地化成功或再次运行之前,将调用有限的跟踪状态
指定了不同的(或没有)初始映射。一旦本地化,地图将被扩展
并且可以在会话中使用' getCurrentWorldMap '方法再次保存。
 */
@property (nonatomic, strong, nullable) ARWorldMap *initialWorldMap;

- (instancetype)init;
+ (instancetype)new NS_SWIFT_UNAVAILABLE("Use init() instead");

@end
复制代码
3.3.8.2 ARPositionalTrackingConfiguration 属性
  • 创建一个配置:
  1. init():创建一个新的位置跟踪配置。
  2. var initialWorldMap: ARWorldMap?: 试图使用此会话配置恢复前一个AR会话的状态。
  • 检测真实的表面:
  1. var planeDetection: ARWorldTrackingConfiguration.PlaneDetection : 一个值,指定会话是否以及如何自动尝试检测摄像机捕获的图像中的平面。

3.3.9 ARKit 坐标系

ARKit 使用笛卡尔坐标系度量真实世界。ARSession 开启时的设备位置即是坐标轴的原点。而 ARSessionConfiguration 的 worldAlignment 属性决定了三个坐标轴的方向,该属性有三个枚举值:

  • ARWorldAlignmentCamera
  • ARWorldAlignmentGravity
  • ARWorldAlignmentGravityAndHeading

三种枚举值对应的坐标轴如下图所示:

三种枚举值对应的坐标轴
对于 ARWorldAlignmentCamera 来说,设备的姿态决定了三个坐标轴的方向。这种坐标设定适用于以设备作为参考系的坐标计算,与真实地理环境无关,比如用 AR 技术丈量真实世界物体的尺寸。

对于 ARWorldAlignmentGravity 来说,Y 轴方向始终与重力方向平行,而其 X、Z 轴方向仍然由设备的姿态确定。这种坐标设定适用于计算拥有重力属性的物体坐标,比如放置一排氢气球,或者执行一段篮球下落的动画。

对于 ARWorldAlignmentGravityAndHeading 来说,X、Y、Z 三轴固定朝向正东、正上、正南。在这种模式下 ARKit 内部会根据设备偏航角的朝向与地磁真北(非地磁北)方向的夹角不断地做出调整,以确保 ARKit 坐标系中 -Z 方向与我们真实世界的正北方向吻合。有了这个前提条件,真实世界位置坐标才能够正确地映射到虚拟世界中。

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在相机反馈中观察到的图像噪声特征相匹配。

参考:

  1. 美团的这篇写的很好:ARKit:增强现实技术在美团到餐业务的实践
  2. juejin.im/post/5a308b…
关注下面的标签,发现更多相似文章
评论