ARKit介绍

Apple在WWDC17上宣布了一个名为ARKit的新iOS框架。它是一个“允许您轻松为iPhone和iPad创建无与伦比的增强现实体验”的框架。该框架随iOS 11一起发布(目前处于测试阶段),并且仅由Apple的A9或A10芯片驱动的iOS设备支持。这意味着它不适用于iPhone 5S或iPad Mini等旧设备。此外,您无法在模拟器中使用它,因此您必须使用最新的测试版更新您的iPhone / iPad(iOS 11 SDK仅适用于Xcode 9)。

AR - 使用相机创建虚拟对象放置在物理世界中的错觉。

我们知道增强现实并不是新的,但由于Apple的新框架,AR现在正受到很多关注。Pokemon Go是第一个也许是最着名的应用程序之一,它向我们展示了应用程序中AR的强大功能。实现与Pokemon Go具有相同交互性的应用程序并不容易,这就是为什么我认为ARKit会有所作为。

通过这个新框架,通过为iOS提供本机AR支持,开发人员可以更方便地访问AR。它使用相机传感器进行照明估算,它可以分析相机视图所呈现的内容,并找到像桌子和地板一样的水平平面,它可以在锚点上放置和跟踪物体。您甚至可以使用Metal,SceneKit和Unity和虚幻引擎等第三方工具渲染3D对象。ARKit以卓越的性能完成所有这一切,并且有很好的文档记录。

需要一些想法才能使用ARKit?您可以查看madewitharkit,并通过在您的应用上加入此框架来了解可能实现的目标。

使用ARKit测量对象

我真正喜欢的项目之一是“AR Measure App Demo”:

他们创造了一个精确的虚拟标尺,与真实标尺相比,我惊呆了。我心想:“我需要试试这个!”,所以我决定使用ARKit创建自己的测量应用程序。

我开始观看介绍ARKit:来自WWDC17的iOS增强现实视频。然后我阅读文档并使用演示应用程序(在增强现实中放置对象)。在那之后,我了解了我可以使用什么以及如何工作。从演示中,我了解到场景单元映射到ARKit中的米,所以这是一个很好的提示。

两个节点之间的距离

我想要一个基本的应用程序,只需点击屏幕选择点并计算最后一个点击与前一个点的距离。所以,我使用Swift和SceneKit创建了一个新项目:

创建项目步骤1

创建项目步骤1

创建项目步骤2

创建项目步骤2

“增强现实应用程序”模板为我们提供了一个基本代码。有一个ViewController实现AR场景视图delegate(ARSCNViewDelegate),它已经有一个ARSCNView很好的IB出口,因为这是用于使用相机显示带有3D SceneKit内容的AR的视图。

免责声明:我使用SceneKit玩过一次,所以我对它有一些基本的了解。如果您没有这些知识或任何3D渲染,如Metal,OpenGL或Unity,那么我建议您在使用ARKit之前查看其中一个,因为它将帮助您理解我将呈现的代码(例如,矢量和矩阵等3D概念以及可以对它们执行的一般操作。

我删除了加载ship.scn资源的当前场景,viewDidLoad因为我想从干净的环境开始(在摄像机视图中没有任何内容)。

然后我UITapGestureRecognizer在主视图中添加了一个以识别用于添加节点的轻击手势。A SCNNode是“场景图的结构元素,表示3D坐标空间中的位置和变换”,其中可以附加几何图形,灯光,相机或其他可显示内容。我决定使用球体作为几何体。我希望节点位于摄像机前方10厘米处,因此我需要当前帧才能访问摄像机在世界坐标空间中的位置和方向。

红色是“x”轴,绿色是“y”轴,蓝色是“z”轴。

红色是“x”轴,绿色是“y”轴,蓝色是“z”轴。

为了实现10厘米的平移,我需要在第四列上应用转换z。正值定义为更接近相机,负值更远。因此,如果使用0,对象位置将位于当前相机框架的正前方。

@objc func handleTapGesture(sender: UITapGestureRecognizer) {
    if sender.state != .ended {
        return
    }
    guard let currentFrame = sceneView.session.currentFrame else {
        return
    }
    // Create a transform with a translation of 0.1 meters (10 cm) in front of the camera
    var translation = matrix_identity_float4x4
    translation.columns.3.z = -0.1
    // Add a node to the session
    let sphere = SCNSphere(radius: 0.005)
    sphere.firstMaterial?.diffuse.contents = UIColor.red
    sphere.firstMaterial?.lightingModel = .constant
    sphere.firstMaterial?.isDoubleSided = true
    let sphereNode = SCNNode(geometry: sphere)
    sphereNode.simdTransform = matrix_multiply(currentFrame.camera.transform, translation)
    sceneView.scene.rootNode.addChildNode(sphereNode)
}

translation是一个包含4行和4列的矩阵。这就是3D点的表示方式,可以应用平移,缩放,旋转,反射,倾斜等变换(通过搜索可以更好地理解OpenGL Matrices)。

最后一步是计算两个节点之间的距离。使用三维欧氏距离公式可以实现两点的距离

image.png

3D中的欧几里德距离公式

我用结束节点位置(两个3D矢量)减去起始节点位置,得到一个新的矢量,然后我应用了公式|a| = sqrt((ax * ax) + (ay * ay) + (az * az))。这将给出结果向量的长度,它与说明相同:距节点A和节点B的距离。

func distance(startNode: SCNNode, endNode: SCNNode) -> Float {  
    let vector = SCNVector3Make(startNode.position.x - endNode.position.x, startNode.position.y - endNode.position.y, startNode.position.z - endNode.position.z)
    // Scene units map to meters in ARKit.
    return sqrtf(vector.x * vector.x + vector.y * vector.y + vector.z * vector.z)
}

self.distanceLabel.text = String(format: "%.2f", distance(startNode: nodeA, endNode: nodeB)) + "m"  

您可以在此处查看此实施。

增强测量

在第一次实现之后,我注意到测量不准确,因为您不能保证节点A和节点B在同一表面中。在那种情况下,我需要平面检测功能。垂直平面检测不是一个特征(但是),但可以用一行代码激活水平平面检测configuration.planeDetection = .horizontal然后ARKit将自动添加,更改或删除当前会话中的平面锚点。您可以观察通过实施这些变化session(_:didAdd:)session(_:didUpdate:)并且session(_:didRemove:)方法从ARSessionDelegate委托(请确保您验证是否锚参数是ARPlaneAnchor)。用户应该知道水平面何时可用,以便开始添加测量点。在苹果公司的ARKit演示实现了一个方形指示器,我认为它可以使用该sceneView.debugOptions属性,但事实并非如此。

平面检测在行动中

平面检测在行动中

所以,我FocusSquare从Apple的演示中借用了这个课程。

最后,最后一个问题:如何将节点放在最近的平面上?我已经知道如何将节点放置在摄像机所在的位置,但我如何获得距离最近的平面的距离。答案是:hitTest(_:types:)。此方法在摄像机图像中搜索视图坐标中指定点的有效曲面,并返回一个列表,其中命中测试结果的排序距离最近(距离摄像机的距离)。

let planeHitTestResults = sceneView.hitTest(view.center, types: .existingPlaneUsingExtent)  
if let result = planeHitTestResults.first {  
    let hitPosition = SCNVector3.positionFromTransform(result.worldTransform)
    let sphere = SCNSphere(radius: 0.005)
    sphere.firstMaterial?.diffuse.contents = UIColor.red
    sphere.firstMaterial?.lightingModel = .constant
    sphere.firstMaterial?.isDoubleSided = true
    let node = SCNNode(geometry: sphere)
    node.position = hitPosition //<--
    sceneView.scene.rootNode.addChildNode(node)
}

我假设主视图的中心作为目标,并且作为默认平面,我使用了列表的第一项(最近的平面)。

最后,我实现了session(_:cameraDidChangeTrackingState:) 可以观察设备位置跟踪状态的方法。

func session(_ session: ARSession, cameraDidChangeTrackingState camera: ARCamera) {  
    switch camera.trackingState {
    case .notAvailable:
        trackingStateLabel.text = "Tracking not available"
        trackingStateLabel.textColor = .red
    case .normal:
        trackingStateLabel.text = "Tracking normal"
        trackingStateLabel.textColor = .green
    case .limited(let reason):
        switch reason {
        case .excessiveMotion:
            trackingStateLabel.text = "Tracking limited: excessive motion"
        case .insufficientFeatures:
            trackingStateLabel.text = "Tracking limited: insufficient features"
        case .none:
            trackingStateLabel.text = "Tracking limited"
        case .initializing:
            trackingStateLabel.text = "Tracking limited: initializing"
        }
        trackingStateLabel.textColor = .yellow
    }
}

您可以检查整个项目并在您的设备上进行测试。

我对AR的力量印象深刻。有很多用例可以探索。如果您有任何我们可以帮助您使用AR的项目,请不要犹豫,并与我们联系。

作者:Ricardo Pereira 2017-07-19

原文:https://www.whitesmith.co/blog/arkit-introduction/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,635评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,628评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,971评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,986评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,006评论 6 394
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,784评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,475评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,364评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,860评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,008评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,152评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,829评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,490评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,035评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,156评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,428评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,127评论 2 356

推荐阅读更多精彩内容

  • A view for displaying AR experiences that augment the cam...
    loveFBI阅读 2,434评论 0 0
  • AR技术叫做虚拟增强现实,也就是在相机捕捉到的现实世界的图像中显示一个虚拟的3D模型。 一.框架说明 1:相机捕捉...
    流年易逝_李阅读 1,183评论 0 2
  • ARKit ARKit框架通过集成iOS设备摄像头和运动功能,在您的应用程序或游戏中产生增强现实体验。 概述 增强...
    暗夜夜夜行路阅读 5,801评论 0 17
  • 场景: 开发中事件的传递(响应者链)相关问题是不可避免的,本文是作者在开发中所遇到的问题和解决方案的集合,希望对每...
    小弱鸡阅读 291评论 0 0