ARkit连载一之初识ARkit

AR技术

增强现实(Augmented Reality,简称 AR),是一种实时地计算摄影机影像的位置及角度并加上相应图像的技术,这种技术的目标是在屏幕上把虚拟世界套在现实世界并进行互动。

一个最简单地AR场景实现所需要的技术以及步骤包含如下
1.多媒体捕捉现实图像:如摄像头
2.三维建模:3D立体模型
3.传感器追踪:主要追踪现实世界动态物体的六轴变化,这六轴分别是X、Y、Z轴位移及旋转。其中位移三轴决定物体的方位和大小,旋转三周决定物体显示的区域。
4.坐标识别及转换:3D模型显示在现实图像中不是单纯的frame坐标点,而是一个三维的矩阵坐标。这基本上也是学习AR最难的部分,好在ARKit帮助我们大大简化了这一过程。
5.除此之外,AR还可以与虚拟物体进行一些交互。

ARKit概述

1.ARKit是2017年6月6日,苹果发布iOS11系统所新增框架,它能够帮助我们以最简单快捷的方式实现AR技术功能。
2.ARKit框架提供了两种AR技术,一种是基于3D场景(SceneKit)实现的增强现实,一种是基于2D场景(SpriktKit)实现的增强现实
3.要想显示AR效果,必须要依赖于苹果的游戏引擎框架(3D引擎SceneKit,2D引擎SpriktKit),主要原因是游戏引擎才可以加载物体模型。
目前ARKit框架本身只包含相机追踪,不能直接加载物体模型
4.ARKit虽然是iOS11新出的框架,但并不是所有的iOS11系统都可以使用,而是必须要是处理器A9及以上才能够使用,苹果从iPhone6s开始使用A9处理器,也就是iPhone6及以前的机型无法使用ARKit

ARkit连载一之初识ARkit_第1张图片
ARKit-app.png

ARkit连载一之初识ARkit_第2张图片
ARKit-capture.png
ARkit连载一之初识ARkit_第3张图片
ARKit-session.png

初识ARKit

1, 我们先创建一个AR3D项目

ARkit连载一之初识ARkit_第4张图片
CreateApp1.png
ARkit连载一之初识ARkit_第5张图片
CreateApp2.png

2, 项目中的代码

    @IBOutlet var sceneView: ARSCNView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Set the view's delegate
        sceneView.delegate = self
        
        // Show statistics such as fps and timing information
        sceneView.showsStatistics = true
        
        // Create a new scene
        let scene = SCNScene(named: "art.scnassets/ship.scn")!
        
        // Set the scene to the view
        sceneView.scene = scene
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        // Create a session configuration
        let configuration = ARWorldTrackingConfiguration()

        // Run the view's session
        sceneView.session.run(configuration)
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        
        // Pause the view's session
        sceneView.session.pause()
    }

3, 代码中用到了哪些类

// 该视图可以绘制相机背景,提供和更新相机,管理锚点的节点,并更新照明
ARSCNView

// 该类用于描述3d场景。 它封装了一个节点层次结构
SCNScene

/* 
继承自ARConfiguration。ARConfiguration用于描述和配置在ARSession中使用的增强现实技术。
不过苹果建议使用ARWorldTrackingConfiguration。
世界跟踪提供设备的6个自由度跟踪(X、Y、Z轴位移及旋转)
通过在场景中查找特征点,世界跟踪可以对框架执行命中测试(hitTest)。
会话暂停后,无法继续追踪。
*/
ARWorldTrackingConfiguration

/*
在设备上配置并运行不同的增强现实技术。在视图中用于更新场景。
*/
ARSession

这些类都非常重要,需要特别指出的是SCNScene并不是ARKit中的类,而是SceneKit中的类。

4, 归类总结与实战
ARKit主要跟设备有关,主要作用是跟踪摄像头,【获取现实中的图像与3D建模应该也是该框架完成的】。而整个3D场景由SceneKit解决。
下面给出两张图,再做一个demo应该就差不多能达到初识程度了。


ARkit连载一之初识ARkit_第6张图片
ARKit-api.png

ARkit连载一之初识ARkit_第7张图片
ARKit & SceneKit-api.png

demo:在现实中添加一个星球。通过手指点击,可切换星球,通过手指移动能移动星球。代码详情:https://github.com/taoGod/ARKit1.git

demo.gif
    override func viewDidLoad() {
        super.viewDidLoad()

        // 1、创建scene
        let scene = SCNScene()
        
        // 4、创建几何形
        let sphere = SCNSphere(radius: 0.1)
        
        // 5、制作几何形的材料
        let material = SCNMaterial()
        material.diffuse.contents = UIImage(named: "earth")
        sphere.materials = [material]
        
        // 3、创建节点,设置节点位置,添加进scene
        node = SCNNode(geometry: sphere)
        node.position = SCNVector3(0, -0.05, -0.5)
        scene.rootNode.addChildNode(node)
        
        // 2、将scene设置为sceneView的scene
        sceneView.scene = scene

        // 添加手势
        let tapGes = UITapGestureRecognizer(target: self, action: #selector(tapGesAction(_:)))
        sceneView.addGestureRecognizer(tapGes)
    }

    @objc fileprivate func tapGesAction(_ tapGes: UITapGestureRecognizer) {
        let sceneView = tapGes.view as! ARSCNView
        let touchLocation = tapGes.location(in: sceneView)
        let hitResults = sceneView.hitTest(touchLocation, options: [:])
        
        if !hitResults.isEmpty {
            if currentIndex == imageNames.count {
                currentIndex = 0
            }
            
            guard let hitResult = hitResults.first else {return}
            
            let node = hitResult.node
            node.geometry?.firstMaterial?.diffuse.contents = UIImage(named: imageNames[currentIndex])
            
            currentIndex += 1
        }      
    }

    override func touchesMoved(_ touches: Set, with event: UIEvent?) {
        // 平面移动
        guard let touch = touches.first else {
            return
        }
        let preLocation = touch.previousLocation(in: sceneView)
        let location = touch.location(in: sceneView)

        let x = Float(location.x - preLocation.x)
        let y = Float(location.y - preLocation.y)

        let position = node.position
        node.position = SCNVector3(position.x + x/1000, position.y - y/1000, -0.5) // 垂直方向是反的
    }

ARSCNView.hitTest:可通过获取屏幕的一个点所在一条线上的所有节点
SCNVector3:三分量矢量的表示。在这里描述节点的3D位置。
SceneKit使用三分量向量用于各种目的,例如描述节点或顶点位置,表面法线,缩放或平移变换。 应该根据使用向量的上下文来解释不同的向量组件。

ARkit连载一之初识ARkit_第8张图片
坐标系,原点为摄像头.png

你可能感兴趣的:(ARkit连载一之初识ARkit)