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






4.69/5 (4投票s)
增强现实业务应用程序的实用指南。
引言
这是一份增强现实商业应用的实用指南。文章着重于三个主要方面:如何在平面上放置物体、如何进行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
确定一个委托:将在其中渲染增强现实的视图。 然后实现委托方法didAdd
,didUpdate
和didRemove
。 以下,您可以查看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)
}
现在,每次点击屏幕,用户都可以将对象放置在水平表面上。
ARKit的应用2:3D绘画
使用ARKit还可以做一件更具创意的事情——3D绘画。 您可以绘制这些对象并将它们放置在半空中。 我们的第一步是创建3D版本的Paint。
对于初学者,我们需要在触摸屏幕时在空中悬挂一个小点。 最简单,最快的方法是使用willRenderScene
(ARSCNViewDelegate
方法之一)
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)。 而这仅仅是开始。