iOS11 ARKit技术漫谈(1)-基础

iOS11出来也有一段时间了,其中ARKit框架还是比较有吸引力的。就想用点时间学习一下,来做点好玩的东西。毕竟有难度必有所得嘛。
既然有方向了,那就给自己一个目标吧,这样学习起来才有动力和目的。我的目标就是使用ARKit框架实现类似于汤姆猫说话,在我们公司移动办公平台智能语音聊天的基础上,实现虚拟现实中和一个小人进行聊天。

这一章主要讲基础知识,来实现一个简单的AR中添加一个正方形。

参考文章:
跨越屏幕的界限,苹果 ARKit 初探
良心教程:用户交互的黑科技ARKit

设备要求

要运行ARKit,在硬件上需要具备A9及以上的处理器,也就是iPhone6s以上的手机才可以支持AR。

我们在做程序时,最好判断是否支持ARKit,如果你的项目就是基于ARKit的,可以在Required Device capabilities中添加如下UIRequiredDeviceCapabilities:

EE8D3B58-0C37-4E85-B3F4-BC4F90C28A86.png

如果设备不支持的话就会显示这个:


iOS11 ARKit技术漫谈(1)-基础_第1张图片
88E35776-D309-4472-8C47-A30A2AFA04D4.png

如果ARKit只是程序的一部分,就要使用isSupport来判断加载。

//在viewDidAppear中添加
 guard ARWorldTrackingConfiguration.isSupported else {
            fatalError("""
                ARKit is not available on this device. For apps that require ARKit for core functionality, use the `arkit` key in the key in the `UIRequiredDeviceCapabilities` section of the Info.plist to prevent the app from installing. (If the app can't be installed, this error can't be triggered in a production scenario.)  In apps where AR is an additive feature, use `isSupported` to determine whether to show UI for launching AR experiences. """) // For details, see https://developer.apple.com/documentation/arkit
        }

软件要求

需要运行xcode 9.0 和 IOS 11 SDK

1. AR工作流程

iOS11 ARKit技术漫谈(1)-基础_第2张图片
1506653219921683.jpeg

其中蓝色表示 ARKit 负责的部分,绿色表示 SceneKit 负责的部分。当然,建立虚拟世界也可以使用其他的框架,比如 SpriteKit、Metal,本文将以 SceneKit 为例子进行讲解。

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

2. ARKit 和 SceneKit 关系图

1506653305405397.png

这些类可以查看第一个参考文章,我也是记录一下,方便以后查看

3 实现一个简单的demo

  1. 创建一个ARDemo的project, 基于swift语言
  2. 在Info.plist中添加Camera Usage Description的相机权限。
  3. 点击main.storyboard 中,在Object Library中选择ARKit SceneKit View,如下:
iOS11 ARKit技术漫谈(1)-基础_第3张图片
71554825-4D5C-4E06-B649-4DE583E29713.png
  1. 把ARKit SceneKit View拖到ViewController中,如下图:
iOS11 ARKit技术漫谈(1)-基础_第4张图片
FB0790CB-87B3-49E3-943A-BE051C45EF93.png
  1. 在ViewController.m中,添加 import ARKit , 代码如下:
class ViewController: UIViewController {

    @IBOutlet weak var sceneView: ARSCNView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        addBox()  //添加一个立方体
        addTapGestureToSceneView() //添加一个点击手势,可以根据手势的坐标来进行立方体的拖动
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        let configuration = ARWorldTrackingConfiguration() //初始化一个名为AR的配置,进行世界跟踪的配置,用来跟踪设备的方向和位置。也可以通过设备的相机检测现实世界的表面。
        sceneView.session.run(configuration)
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        sceneView.session.pause()   //停止跟踪视图内容的运动和处理图像
    }
 
    func addBox(x: Float = 0, y: Float = 0, z: Float = -0.2){   // 这里x,y,z中1就代表1米
        let box = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
        
        //1. 创建一个节点,把box加入到geomety(几何结构)中
        let boxNode = SCNNode()
        boxNode.geometry = box
        boxNode.position = SCNVector3(x, y, z) //正x在右边,负x在左边。正y是向上,负y是向下。正z是向后,负z是向前的。我们是设置的向前0.2米
        
       //2. 初始化SCNScene对象,把上面的节点加入到scene的根节点上
        let scene = SCNScene()
        scene.rootNode.addChildNode(boxNode)
        //3. 把scene对象加入到我们的sceneView的scene上
        sceneView.scene = scene
    }
    
    func addTapGestureToSceneView() {
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.didTap(withGestureRecognizer:)))
        sceneView.addGestureRecognizer(tapGestureRecognizer)
    }
    
    @objc func didTap(withGestureRecognizer recognizer: UITapGestureRecognizer) {
        let tapLocation = recognizer.location(in: sceneView)
        let hitTestResults = sceneView.hitTest(tapLocation)
        
        guard let node = hitTestResults.first?.node else {
            let hitTestResultsWithFeaturePoints = sceneView.hitTest(tapLocation, types: .featurePoint)
            if let hitTestResultWithFeaturePoints = hitTestResultsWithFeaturePoints.first {
                let translation = hitTestResultWithFeaturePoints.worldTransform.translation
                addBox(x: translation.x, y:translation.y, z:translation.z)
            }
            return
        }
        node.removeFromParentNode()
    }
}

extension float4x4 {
    var translation: float3  {
        let translation = self.columns.3
        return float3(translation.x, translation.y, translation.z)
    }
    
}

GitHub代码

就可以实现一个简单的VR程序。



知行办公,专业移动办公平台https://zx.naton.cn/
【总监】十二春秋之,[email protected]
【Master】zelo,[email protected]
【运营】运维艄公,[email protected];****
【产品设计】流浪猫,[email protected]
【体验设计】兜兜,[email protected]
【iOS】淘码小工,[email protected]iMcG33K,[email protected]
【Android】人猿居士,[email protected];思路的顿悟,[email protected]
【java】首席工程师MR_W,[email protected]
【测试】土镜问道,[email protected]
【数据】fox009521,[email protected]

你可能感兴趣的:(iOS11 ARKit技术漫谈(1)-基础)