65.9K
CodeProject 正在变化。 阅读更多。
Home

ARKit 的增强现实应用程序( 实用指南)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.69/5 (4投票s)

2018年2月5日

CPOL

4分钟阅读

viewsIcon

13060

增强现实业务应用程序的实用指南。

引言

这是一份增强现实商业应用的实用指南。文章着重于三个主要方面:如何在平面上放置物体、如何进行3D绘画以及如何在周围区域实现物体。

背景 - 什么是ARKit?

ARKit由苹果公司于2017年推出。它是一个增强现实框架,旨在简化AR应用的创建。ARKit使用户能够将2D/3D数字对象和信息与现实世界融合,从而将应用程序远远超出屏幕范围,并使其能够以全新的方式与周围环境交互。通过iOS11.3中提供的最新更新,该应用程序可以识别垂直表面,并在其上看到、识别和放置虚拟对象。所有这些特性使得ARKit的应用在许多行业的业务中真正变得无穷无尽,尤其是:游戏、商业、建筑和教育。我们在Perfectial正在试验VR/AR,并很高兴分享我们的经验。

ARKit的应用1:在平面上放置物体

可能使用ARKit框架最著名的应用之一是“IKEA Place”,用户可以在周围区域选择并虚拟“放置”宜家产品。嗯,我们想向您展示它是如何开发的。

让我们从基础开始——为ARKit制作3D模型。首先,我们需要一个可以使用的实际3D模型。值得庆幸的是,它可以使用Blender或任何其他3D建模软件轻松渲染。只需确保它支持.DAE扩展名。(您可以使用一个小提示:SpriteKit支持AR的2D图形,SceneKit支持3D图形)。

所以我们需要带有3D模型的.SCN SceneKit文件。 .DAE文件应在Xcode中转换为.SCN格式。 要执行此操作,请选择“编辑器”菜单,然后单击“转换为SceneKit场景文件格式(.scn)”。

下一步是确定水平平面以放置3D对象。 您需要为您的ARSCNView确定一个委托:将在其中渲染增强现实的视图。 然后实现委托方法didAdddidUpdatedidRemove。 以下,您可以查看didAdd方法的示例

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    guard let planeAnchor = anchor as? ARPlaneAnchor else { return }
    node.addChildNode(horizontalSurface(planeAnchor: planeAnchor))
}

您需要确保已添加了平面锚点,而不是另一个锚点(使用guard语句)。 现在,让我们看看上面代码中使用的horizontalSurface方法

    func horizontalSurface(planeAnchor: ARPlaneAnchor) -> SCNNode {
    let horizontalSurface = SCNNode(geometry: SCNPlane(
        width: CGFloat(planeAnchor.extent.x),
        height: CGFloat(planeAnchor.extent.z)))
    horizontalSurface.geometry?.firstMaterial?.diffuse.contents =
        UIColor.blue.withAlphaComponent(0.4)
    horizontalSurface.geometry?.firstMaterial?.isDoubleSided = true
    horizontalSurface.position = SCNVector3(
        planeAnchor.center.x,
        planeAnchor.center.y,
        planeAnchor.center.z)
    horizontalSurface.eulerAngles = SCNVector3(90.0.degreesToRadians, 0, 0)
return horizontalSurface
}

由于蓝色的“漫反射”,可以在现实生活中看到平面(如果未定义颜色,它们将是透明的)。 当用户点击AR视图时,应出现新对象。 现在,对于实现,我们需要处理用户的触摸并将手势识别器添加到ARSCNView。 这就是可以实现处理点击的方法

@objc func handleTap(sender: UITapGestureRecognizer) {
    if let tappedSceneView = sender.view as? ARSCNView {
        let tapLocationInView = sender.location(in: tappedSceneView)
        let planeHitTest = tappedSceneView.hitTest(tapLocationInView,
            types: .existingPlaneUsingExtent)
        if !planeHitTest.isEmpty {
            addFurniture(hitTest: planeHitTest)
        }
    }
}

addFurniture方法内部,将使用以下代码添加家具

    if let furnitureNode = SCNScene(named:
    “art.scnassets/\(currentFurniture).scn”)?.rootNode {
    let position = hitTest.first!.worldTransform.columns.3
    furnitureNode.position = SCNVector3(position.x, position.y, position.z)
    sceneView.scene.rootNode.addChildNode(furnitureNode)
}

现在,每次点击屏幕,用户都可以将对象放置在水平表面上。

R&D office Perfectial

ARKit的应用2:3D绘画

使用ARKit还可以做一件更具创意的事情——3D绘画。 您可以绘制这些对象并将它们放置在半空中。 我们的第一步是创建3D版本的Paint。

对于初学者,我们需要在触摸屏幕时在空中悬挂一个小点。 最简单,最快的方法是使用willRenderSceneARSCNViewDelegate方法之一)

let dotNode = SCNNode(geometry: SCNSphere(radius: this.dotRadius))
dotNode.position = currentPositionOfCamera
dotNode.geometry?.firstMaterial?.diffuse.contents = this.selectedColor()
this.sceneView.scene.rootNode.addChildNode(dotNode)

这是识别相机当前位置的方法

    if let pointOfView = sceneView.pointOfView {
    let orientation = SCNVector3(
       -pointOfView.transform.m31,
       -pointOfView.transform.m32,
       -pointOfView.transform.m33)
    let location = SCNVector3(
       pointOfView.transform.m41,
       pointOfView.transform.m42,
       pointOfView.transform.m43)
    return orientation + location
}    

我们甚至可以创建真实的3D涂鸦。 我想,艺术家应该喜欢这个功能!

ARKit的应用3:房间里的太阳系

所以,我们已经知道如何在平面上放置不同的物体,现在是时候学习如何移动物体了。 对于这个实验,我们将使用一个太阳系,其中八个行星围绕太阳及其轴旋转,月亮围绕地球旋转。

首先,我们需要让物体(行星)围绕其轴旋转

    earth.runAction(rotation(time: earthRotationAroundItselfTime))      

这是旋转方法的内容

    func rotation(time: TimeInterval, degrees: CGFloat = 360.0) -> SCNAction {
    let onceRotation = SCNAction.rotateBy(
        x: 0,
        y: degreesToRadians(degrees),
        z: 0,
        duration: time)
return SCNAction.repeatForever(onceRotation)
} 

为了使物体A围绕物体B旋转,我们需要添加一个与B坐标相同的不可见物体C。这将使C旋转,但是我们需要做另一件事——使物体A成为C的子物体。 参见以下示例

marsParent.position = sunPosition
mars.position = marsPosition
marsParent.addChildNode(mars) 

ARKit应用程序确实是无穷无尽的,并且超越了游戏和娱乐。 零售商可以从服装或家具(如宜家)中受益。 医疗保健或教育可以使学习过程更加容易(例如Complete Anatomy 2018)。 而这仅仅是开始。

© . All rights reserved.