ARKit CocoaPod —门户

我相信ARKit开发人员生态系统中目前最大的遗漏是可重用代码。 通常,iOS开发使用了许多令人赞叹的Pod,但还没有专门用于ARKit的Pod。

这是我在这篇文章中将要解释的CocoaPod,请随时报告问题,分叉并做出贡献!

maxxfrazer / SceneKit-PortalMask

清理类以在SceneKit中创建一个门户,以在ARKit中使用。 – maxxfrazer / SceneKit-PortalMask

github.com


当我在增强现实领域开始我的职业生涯时,我主要使用类似于Vuforia的工具基于标记的AR。 很多客户都希望有一种趋势,而我可以看到这是ARKit中一种趋势。 想法是遮盖跟踪图像本身之外的所有内容,但允许您通过图像所在的孔查看。

这是使用此Pod可以实现的两个简单示例,其中一个仅包含几行代码:

这是一个代码示例,用于创建类似于左侧示例的内容。

仅向Portal馈送physicalSize ,它在对象周围创建掩码。

  func renderer(_ renderer:SCNSceneRenderer,didAdd节点:SCNNode,锚点:ARAnchor){ 
如果让imageAnchor =锚定为? ARImageAnchor {
让nodeRotated = SCNNode()
// ARImageAnchors上的节点需要旋转-90度
nodeRotated.eulerAngles.x = -.pi / 2让imageSize = imageAnchor.referenceImage.physicalSize
//接下来的两行添加门户
让门户= PortalMask(frameSize:imageSize)
nodeRotated.addChildNode(portal) //接下来的5行会在图像区域内添加一个多维数据集
让width = imageAnchor.referenceImage.physicalSize.width
let boxNode = SCNNode(几何:SCNBox(宽度:宽度,高度:宽度,长度:宽度,倒角半径:0))
//将方框推到标记后面
boxNode.position.z = -boxNode.width
nodeRotated.addChildNode(boxNode)node.addChild(nodeRotated)
}
}

这也可以在没有跟踪图像的情况下创建,并放置在场景图中的任何表面,锚点或其他位置。

如果您的跟踪图像是球形的,则可以通过两种不同的方法来实现。 一种是使用PortalMask.tube(radius:)PortalMask(radius:) 。 第一个创建一个带有圆形遮罩的圆形内孔,后者有效地创建一个带有圆形孔的长方体。 对于大多数用例,后者是首选的,因为它使用的顶点少得多。 在此处在线记录的函数上还有其他参数。

这是一个简单的示例,在空中添加一个圆形门户,背后有一些物体,从而创建了一个场景。

   HoleNode = PortalMask(半径:0.5) 
holeNode.position = SCNVector3(0,0,-2)//为了获得更好的效果,我在门户周围添加了边框
HoleEdge = SCNNode(geometry:
SCNTube(内部半径:0.5,外部半径:0.55,高度:0.05)

holeEdge.eulerAngles.x = .pi / 2 ///在门户中添加构成场景的节点
insideChild = BeachScene() self .sceneView.scene.rootNode.addChildNode(holeNode)
holeNode.addChildNode(holeEdge)
holeNode.addChildNode(insideChild)

在这种情况下,海滩场景只有2个平面,一个球体和一个灯光,且门户区域内有一个父节点。

最后,我认为PortalMask类的最有用的初始化程序使您可以仅使用CGPoints的集合来创建门户。 这使您可以创建任何形状和大小的门户,我能想到的最好的示例是使用从表面检测收集的点来创建门户,如以下视频所示:

初始化此门户网站的函数是init(path: [CGPoint]) ,然后更新几何,如下文所示。

在下面的代码中, planeAnchor的类型为ARPlaneAnchornode是该锚点的相应根节点,该节点来自renderer(_:didAdd:for:)

  点= planeAnchor.geometry.boundaryVertices 
.map {(point)-> CGPoint in
返回 CGPoint(x:CGFloat(point.x),y:CGFloat(point.z))
}
let portalNode = PortalMask(path:points) //默认情况下,门户将是水平的,以使其垂直
portalNode.eulerAngles.x = -.pi / 2 //在门户内部添加内容
portalNode.addChildNode(BeachScene())
//将门户网站添加到锚点
node.addChildNode(portalNode)

然后将门户添加到要扫描的墙上,我们只需要使用renderer(_:didUpdate:for:)进行更新,如下所示:

 让updatedPoints = planeAnchor.geometry.boundaryVertices.map { 
(点)-> CGPoint
返回 CGPoint(x:CGFloat(point.x),y:CGFloat(point.z))
}
portalNode.updateGeometry(with:UpdatedPoints)

在执行此操作之前,您只需要找到ARAnchor节点中的PortalMask类的节点。

您可以通过简单地将node.childNodes.first as? PortalMask node.childNodes.first as? PortalMask ,或者如果有多个子代则遍历node.childNodes.first as? PortalMask ,或者为锚点的根节点分配一个名称,然后在哈希图中查找它。


这涵盖了到目前为止我对存储库所做的大部分工作,我希望其他人会发现它很有用,当ARKit有任何相关更新或我有其他任何想法时,我将继续为它做贡献。 请查看我的GitHub以及我正在使用的其他一些库。

·GitHub

增强现实工程师。 maxxfrazer有12个可用的存储库。 在GitHub上遵循他们的代码。

github.com