ARFoundation之路-AR子系统

版权声明:Davidwang原创文章,严禁用于任何商业途径,授权后方可转载。

  在前文中,我们知道,ARFoundation的体系架构是建立在一系列的子系统(subsystem)之上,这个架构的好处类似于接口(Interface),将界面与具体的实现进行分离,用户只需要面向接口编程,而无需关注具体的算法实现(这个具体的算法提供者就叫Provider,Provider这里指实现具体算法的包或者插件)。同时,这种分离的另一个好处是同一个接口可以有两个或多个具体实现,反过来说就是ARFoundation只定义了接口界面,而由Provider提供具体的实现,因此,其具有极强的适应性。如人脸跟踪,ARFoundation定义了FaceTracking 子系统界面,ARCore可以提供Android平台的具体实现,ARKit可以提供iOS平台的具体实现,Hololens可以提供Hololens眼镜的具体实现等等,这样,在同一体系架构下可以提供无限的具体实现可能性,最后,ARFoundation在编译特定平台应用的时候就可以直接调用该特定平台的具体实现,从而现实一次开发,多平台部署的目的。ARFoundation的体系架构如下图所示。
在这里插入图片描述

  类似于继承,当Provider具体实现特定接口(子系统)时,可以根据其平台本身的特性提供优化,并可以提供更多功能。由于硬件或者软件生态的巨大差异,A平台具备的功能B平台不一定提供,为了让开发者了解这种差异,ARFoundation要求Provider提供子系统描述符(SubsystemDescriptor),SubsystemDescriptor描述了Provider对特定子系统提供的能力范围。有了这个描述符,开发人员就可以通过遍历看特定的功能某特定平台是否提供,为功能开发提供依据。

(一)AR子系统的概念

  Subsystem是一个与平台无关的接口,其定义了对特定功能的界面,与AR相关的subsystems隶属于UnityEngine.XR.ARSubsystems命名空间。ARFoundatoin中的subsystem只定义了功能接口而没有具体实现,具体实现由Provider在其他包或者插件中提供。ARFoundation目前提供了以下12种subsystem,具体包括Session、Raycasting、Camera、Plane Detection、Depth、Image Tracking、Face Tracking、Environment Probes、Object Tracking、Human Body Tracking 2D,Human Body Tracking 3D,Human Segmentation Image。

  由于具体的subsystems是由Provider在其他包或者插件中提供,因此,如果不引入相应的包或者插件,应用编译会失败,在编译到具体平台时就一定要在工程中引入相应的包或者插件。同时引入两个或者多个平台的包或插件是没有问题的,因为ARFoudation会根据具体的编译平台选择对应的包或插件。引入插件的方法是在Window > Package Manager中打开“包管理窗口”,然后在左侧的包中选择相应的包或者插件,目前ARFoundation的Provider包括ARCore XR Plugin和ARKit XR Plugin两种(估计很快就会加入SenseAR XR Plugin),如下图所示。
在这里插入图片描述
  对于ARFounation定义的subsystem,Provider可以实现也可以不实现,如Environment Probes ,ARCore XR Plugin目前就没有实现,因此,Android平台Environment Probes功能将不可用。另外,Provider也可以提供比subsystem更多的功能,如Image Tracking,ARFounation目前并不支持动态添加参考图像的功能,但实际上ARCore和ARKit都支持在运行时动态添加参考图像。因此,针对具体平台做开发时一定要关注该平台Provider能够提供的功能,另外,为了对特定平台进行优化,不同的Provider对参数也有要求,如在Image Tracking功能中,ARKit要求提供被检测图像的物理尺寸,而ARCore则没有这个要求,这都需要参阅特定平台Provider相关资料。

(二)AR子系统使用

  所有的subsystems都有一样的生命周期:创建(Created)、开始(Started)、停止(Stopped)、销毁(Destroyed),每一个subsystem都有一个对应的SubsystemDescriptor,可以使用SubsystemManager遍历其能够提供的功能,一旦得到可用的subsystemdescriptor后,就可以使用Create()方法创建这个subsystem,这也是构建subsystem的唯一方式(实现使用中,很多时候由SubsystemManager负责了这个过程,但有时我们也需要自己来实现这个过程)。下面以创建一个Plane subsystem为例来说明这个过程,代码如下所示。

XRPlaneSubsystem CreatePlaneSubsystem()
{
    // 得到所有可用的plane subsystems:
    var descriptors = new List<XRPlaneSubsystemDescriptor>();
    SubsystemManager.GetSubsystemDescriptors(descriptors);
    // 遍历获取一个支持boundary vertices的功能
    foreach (var descriptor in descriptors)
    {
        if (descriptor.supportsBoundaryVertices)
        {
            // 创建plane subsystem
            return descriptor.Create();
        }
    }
    return null;
}

  在这个例子中,我们首先得到PlaneSubsystemDescriptor,然后遍历这个描述符检测其支持不支持BoundaryVertices,如果支持则说明满足我们的需求,那么就创建它,而且这是个单例模式的创建,即保证系统中只有一个该类型的subsystem,我们可以再次调用Create()方法,但是还是返回原创建的实例。
一旦我们创建成功subsystem后,我们就可以通过调用Start()、Stop()方法来启动这个subsystem,但需要注意的是,对不用的subsystem,Start()、Stop()方法行为方式也会有所差异,但通常都是启用与停用的操作。并且一个subsystem可以调用Start()、Stop()方法多次。在用完该subsystem后,应该调用Destroy()方法销毁该subsystem以避免无谓的性能消耗,在销毁subsystem后,如果再次需要则需要再次创建,示例代码如下所示。

var planeSubsystem = CreatePlaneSubsystem();
if (planeSubsystem != null)
{
    // 开始平面检测
    planeSubsystem.Start();
}

if (planeSubsystem != null)
{
    // 停止平面检测,但这并不会影响到已检测到的平面
    planeSubsystem.Stop();
}

if (planeSubsystem != null)
{
    // 销毁该subsystem
    planeSubsystem.Destroy();
    planeSubsystem = null;
}

  再次提醒,针对特定平台的特定功能,在需要时应该查阅该Provider的资料以获取更详尽的信息。

(三)可跟踪子系统

  跟踪子系统(Tracking subsystem)是在物理环境中检测和跟踪某类信息的subsystem,如平面跟踪和图像跟踪。跟踪子系统跟踪的事物被称为可跟踪对象(Trackable),如平面子系统检测平面,因此平面是可跟踪对象。

  在ARFoundation中,每一类跟踪子系统都提供一个名为getchanges()的方法,此方法的目的是检索有关它所管理的可跟踪对象的信息数据,getchanges()获取自上次调用getchanges()以来添加、更新和移除的所有可跟踪对象信息,通过该方法可以获取到发生变化的可跟踪对象相关信息并进行后续操作。

每个可跟踪对象都由标识符ID(TrackableId,一个128位的GUID值)唯一标识,即所有的可跟踪对象都是独立可辨识的,我们可以通过这个TrackableId获取到该可跟踪对象。

  subsystem可以添加、更新或移除可跟踪对象。只有添加到subsystem中的可跟踪对象才可以被更新或移除,因此在移除可跟踪对象时需要先检查该对象是否在subsystem的跟踪中,如果尝试更新或移除尚未添加的可跟踪对象则会引发一个运行时错误。同样,未添加或已移除的可跟踪对象无没更新也无法再次移除。

  为方便使用,在ARFoundation中,每一类跟踪子系统的Manager类(如ARPlaneManager)通常都提供一个xxxChanged(如planesChanged)事件,我们可以通过其xxxChangedEventArgs(如ARPlanesChangedEventArgs)参数获取到added、updated、removed可跟踪对象进行后续处理。

参考文献

About AR Subsystems About AR Subsystems

发布了89 篇原创文章 · 获赞 104 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/yolon3000/article/details/96692997