版权声明:Davidwang原创文章,严禁用于任何商业途径,授权后方可转载。
MRTK(Mixed Reality Toolkit)是微软公司为加速AR/MR/VR应用程序开发而设计开发的开源工具集,提供Unity和Unreal两种版本,MRTK提供了一系列的组件与功能集,支持AR(ARCore、ARKit)、MR(HoloLens)、VR(HTC Vive、Oculus Rift、Oculus Quest)、混合现实头盔(Windows Mixed Reality Headsets)各类平台,是一个跨平台、可扩展、模块化框架,并配套提供编辑器内模拟器,能极大的方便应用程序开发调试,允许开发人员快速进行原型设计与应用迭代。简而言之,MRTK是一个统一、跨平台、支持AR/MR/VR开发的灵活框架工具集,它既有公共的共享功能部分,也有相互独立的与特定硬件相关的组件,能适应不同的目标设备,而且很容易使用。
(一)、MRKT概述
MR应用需求千差万别,每一个应用都对HoloLens2设备的功能特性有特定的要求[ 由于MRTK是跨平台框架,对不同设备的不同功能特性进行配置更加复杂,更需要有良好设计的配置管理方法。], 组织和管理不同应用的配置是底层框架必须要面对的问题。MRTK利用Unity可编程对象(Scriptable Object)配置MR应用的所有功能特性(可用功能),使用配置文件(Profiles)进行管理[ 在MRTK中,配置文件是一个非常重要的概念,它一个功能清单,定义了MR应用可以使用的功能及使用这些功能的方式。],为方便开发者使用,MRTK默认定义了若干通用的配置文件,也针对特定硬件平台定义了优化的配置文件,同时也允许开发者定制所有的功能特性以满足开发需求或针对特定应用进行优化。
除此之外,通过配置文件,我们还可以定制所有功能的执行方式,即可以替换掉默认的执行并代之以自定义的逻辑。由于在设计之初就考虑了开发者的自定义需求,定制功能执行流程也非常简单,只需要在主业务逻辑中实现特定的接口,然后在配置文件中指定功能处理逻辑为自定义的实现脚本即可。MRTK中的所有功能都具备高度的可定制化能力,包括摄像机(Camera)、输入系统(Input System)、输入处理(Handling Input)、指针(Pointer)、光标(Cursor)、语音命令(Speech Command)等等。
由上可知,MRTK不仅仅是一个现有功能集,而且是一个具备高度可伸缩性的功能框架,可以非常方便的对其支持的硬件设备和功能进行扩展。
(二)、MRTK体系架构
MRTK是一个Unity工具包,因此讨论MRTK的体系架构必须先从Unity的游戏循环(Game Loop)引入。在Unity中,游戏引擎负责管理所有游戏对象(Game Objects)的初始化、更新、销毁等全生命周期,也负责所有事件消息循环,开发者通过其暴露的事件函数(典型的如Awake()、Start()、Update()等)将应用逻辑嵌入到游戏引擎循环中。在代码执行层面上,Unity希望所有用户脚本继承自MonoBehaviour(只有继承自MonoBehaviour的脚本才可以挂载到游戏对象上),并且在有限的暴露函数中实现应用逻辑。通过这种方式,Unity能完全控制应用程序生命周期,降低了开发者使用难度,但这种过于紧凑的设计耦合了界面、逻辑、数据,而且对扩展非常不友好(开发者无法独立得到事件消息的通知),更严重的是开发者对游戏对象没有完全控制权(游戏引擎负责处理游戏对象的生命周期,开发者无法控制游戏对象初始化时机,也无法控制不同游戏对象中函数执行的先后顺序),MVC/MVVM等流行的设计思想也很难在Unity中实现。
对简单工程而言,Unity的工作流设计可以加速开发、提高迭代速率,但对那些期望绝对控制脚本执行的复杂应用就产生了明显约束,特别是在应用中需要全局共享一个运行组件的时候,这种约束就会带来很多问题。通常,我们会使用单例模式(Singleton Pattern)来解决单一实例运行的问题,单例模式可以跟踪全局变量、延迟初始化,是一种控制共享运行组件的很好选择,但单例模式强化了组件依赖,也无法控制组件的全生命周期,如果开发者将这种模式直接应用于游戏对象,至少会带来两个方面问题:一是游戏对象停止运行则脚本也停止运行;二是当有其他运行组件依赖于该脚本时,有可能该游戏对象并没有完成初始化(挂载于其上的脚本就更不可能初始化)。
MRTK为解决这个问题,把所有需要共享运行的组件改成了服务(Service),充分运用了控制反转(Inversion of Control)、依赖注入(Dependency Injection)、依赖反转(Dependency Inversion Principle)等设计思想,构建了一个服务容器,对上提供服务,对下解耦具体实现,不仅能完全控制服务全生命周期,也极大的提高了框架灵活性和可扩展性。
在最上层,MRTK也采用了事件驱动的编程思想,通过在场景中MixedRealityToolkit游戏对象上挂载继承自MonoBehaviour的脚本,利用该脚本中事件处理接口处理来自Unity分发的事件消息,获取了与Unity消息的通信能力,并充分利用了Unity内建的事件系统(Built-in Event System),使MRTK能高效的分发处理各种类型的事件消息,MRTK整体架构如图1所示。

服务定位器(Service Locator)负责查询并提供上层模块所需要的服务,服务定位器了解所有注册的服务及其类型,因此可以在运行时动态的确定上层模块所需要的服务,充当一个动态连接器。
MRTK的架构设计非常符合主流的软件工程思想:一是模块化,解耦所有依赖,特定的模块只处理特定的任务;二是面向接口,高可扩展,数据驱动特性;三是松耦合,模块间没有依赖关系。
基于跨平台需求,MRTK在设计时并不是只针对某一类硬件,而是可以同时适应AR/MR/VR不同的硬件底层,由于这些硬件平台硬件种类、特性、功能都相差甚远,即便是MR平台,HoloLens1代与HoloLens2代硬件差异也非常明显。为适应不同底层,MRTK架构在设计时便选择了分层处理,如图2所示,通过配置文件定制功能特性,在运行时,MRTK就知道注册、启动哪些服务,而这些服务又有相应的数据提供者提供,同层之间各功能模块相互独立,不同层之间通过统一的策略进行管理(运行时通过服务定位器连接所需服务,而服务层通过接口调用数据层中的功能)。这种架构设计可扩展性、可维护性大大提高,如果需要更换输入系统的底层数据提供者,开发者只需要重写继承特定接口的数据提供类即可,所有上层服务都不会发生变化。

参考文献
1、MRTK官方文档 MRTK官方文档

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/29477.html