ARKit入门

Stella981
• 阅读 959

ARKit介绍

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

ARKit的强悍功能都是基于海量的计算,因此目前只支持Apple A9和A10处理器。从硬件设备上来看,目前搭载了Apple A9和A10处理器的只有iPhone 6s, iPhone 6s Plus, iPhone SE,iPhone7,iPhone 7 Plus,两代iPad Pro和最新的iPad。

ARKit目前已经支持Unity、Unreal Engine和Scenekit,由于目前正在做Unity开发,故下面就简单介绍一下Unity下的ARKit开发。

工具版本要求

  • 开发IDE:Unity 5.6.1p1 或以上版本
  • 运行系统:iOS 11 或以上版本
  • 编译工具:XCode 9 beta 或以上版本
  • 运行设备:支持ARKit的iOS设备

Unity插件介绍

插件的下载地址:https://oc.unity3d.com/index.php/s/3hfM9T05P9vOpCf

该Unity插件将让开发者们可以轻松访问ARKit的功能,例如世界追踪(World Tracking)、实时视频渲染(Live Video Rendering)、平面预测与更新(Plane Estimation and Updates)、碰撞检测API(Hit-testing API)、环境光预测(Ambient Light Estimation)以及原点云数据(Raw Point Cloud Data)

其基本使用方法可以参考此文,这里不做重复叙述。

将该插件导入到Unity中,有几个重要文件需要做一下说明:

"/Assets/Plugins/iOS/UnityARKit/NativeInterface/ARSessionNative.mm" - OC文件,ARKit SDK的本地接口文件

"/Assets/Plugins/iOS/UnityARKit/NativeInterface/UnityARSessionNativeInterface.cs" - C#版本的ARKit SDK接口文件 这两个文件完成了C#对OC跨语言调用ARKit功能的工作

UnityARSessionNativeInterface 包含下面几个重要方法:

  • public void RunWithConfigAndOptions(ARKitWorldTackingSessionConfiguration config, UnityARSessionRunOption runOptions)
  • public void RunWithConfig(ARKitWorldTackingSessionConfiguration config) public void Pause()
  • public List HitTest(ARPoint point, ARHitTestResultType types)
  • public ARTextureHandles GetARVideoTextureHandles()
  • public float GetARAmbientIntensity()
  • public int GetARTrackingQuality()

还包含几个重要事件

  • public delegate void ARFrameUpdate(UnityARCamera camera)
  • public delegate void ARAnchorAdded(ARPlaneAnchor anchorData)
  • public delegate void ARAnchorUpdated(ARPlaneAnchor anchorData)
  • public delegate void ARAnchorRemoved(ARPlaneAnchor anchorData)
  • public delegate void ARSessionFailed(string error)

"/Assets/Plugins/iOS/UnityARKit/NativeInterface/AR*.cs" - ARKit用到的数据结构脚本

"/Assets/Plugins/iOS/UnityARKit/Utility/UnityARAnchorManager.cs" - 一个实用程序,可以跟踪ARKit的锚更新,并可以为其创建相应的Unity游戏对象 (具体可以参看在 GeneratePlanes.cs 组件里查看使用方法)

"/Assets/Plugins/iOS/UnityARKit/Editor/UnityARBuildPostprocessor.cs” - 编译时用到的编辑脚本,对导出工程做一些相应的操作,例如添加ARKit库文件等

ARKit有用的组件 "/Assets/Plugins/iOS/UnityARKit/UnityARCameraManager.cs" - 这个组件应该放置在通过ARKit引用的摄像机的场景中的一个游戏对象,并且它将定位和旋转相机,并提供基于ARKit更新的正确投影矩阵。该组件还具有初始化ARKit的功能

"/Assets/Plugins/iOS/UnityARKit/UnityARVideo.cs" - 该组件应放置在相机上,并抓取渲染视频所需的纹理,并将其设置为对后缓冲区进行拼接所需的材质,并设置命令缓冲区以进行实际布局

ARKit使用说明

  1. 首先给Camera挂上UnityARCameraNearFar和UnityARVideo这两个脚本并为UnityARVideo的ClearMaterial设置上YUVMaterial材质,其中UnityARCameraNearFar脚本将Camera的nearClipPlane和farClipPlane提供给ARKit使用,UnityARVideo则将摄像头拍摄到的真实世界组合到Camera呈现的背景中去。
  2. 通过UnityARSessionNativeInterface.GetARSessionNativeInterface()拿到ARKit的会话接口,暂且叫它m_session。
  3. 调用m_session.RunWithConfig(config)或m_session.RunWithConfigAndOption(config,option)可以创建一个ARSession,这也代表着ARKit的启动。
  4. 通过m_session.GetCameraPose()可以获取ARKit所认为的Camera当前姿态,例如位置和旋转,将其设置给Camera。
  5. 通过m_session.GetCameraProjection()可以获取ARKit所认为的Camera当前投影矩阵,将其设置给Camera。(以上2-5步可以参考UnityARCameraManager.cs中的使用)
  6. 通过以上步骤,一个基本的AR场景就算搭建好了,你可以通过m_session.HitTest(point,resultTypes)来确定摄像头中的该位置在ARKit理解中是虚拟世界的什么位置和形态。(参考UnityARHitTestExample.cs)
  7. 也可以通过m_session的配置进行平面检测,通过设置UnityARSessionNativeInterface.ARAnchorAddedEvent,UnityARSessionNativeInterface.ARAnchorUpdatedEvent和UnityARSessionNativeInterface.ARAnchorRemovedEvent来获得ARkit对摄像头中平面的理解。(参考UnityARAnchorManager.cs)
  8. 同样的,如果想获取ARKit理解的特征点数据,可以通过设置UnityARSessionNativeInterface.ARFrameUpdatedEvent来及时获取。(参考PointCloudParticleExample.cs)
  9. 还可以通过m_session.GetARAmbientIntensity()来获取对光线强度的估算(参考UnityARAmbient.cs)
  10. 最后需要注意的是,ARKit的各种方法的回调速度和Unity的更新速度是不一样的。

总结

ARKit的功能非常强大,但使用却如此简单,使用不难,只能说苹果牛逼呀!

本文来自网易云社区,经作者张志明授权发布。

原文地址:ARKit入门

更多网易研发、产品、运营经验分享请访问网易云社区

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Karen110 Karen110
2年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
Wesley13 Wesley13
2年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
Java日期时间API系列30
  实际使用中,经常需要使用不同精确度的Date,比如保留到天2020042300:00:00,保留到小时,保留到分钟,保留到秒等,常见的方法是通过格式化到指定精确度(比如:yyyyMMdd),然后再解析为Date。Java8中可以用更多的方法来实现这个需求,下面使用三种方法:使用Format方法、 使用Of方法和使用With方法,性能对比,使用
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这