(ARKit 2 Room Scanner)如何通过ARKit 2和ARWorldMap使用UIBezierPath和featurePoints创建具有周围环境几何形状的节点

时间:2018-12-29 22:53:19

标签: ios swift xcode scenekit arkit

我正在使用ARKit 2和 ARWorldMapData ,我创建了一个AR世界,该世界可以识别来自link here的地图数据等。现在,我试图找出如何获取所有特征点并进行连接,然后创建我的周围环境/ ARWorldMap 的网格(我认为从未尝试过使用ARKit 2)< / em>。尽管我确定您可以通过将特征点与UIBezierPath连接来实现。这样您便可以将路径创建的形状用作节点的几何形状。

测试后,以下代码在屏幕上没有产生任何东西,或者至少我看不到它。所以现在就是问题所在。尽管我敢肯定这可能还会有更多问题。

我几乎只使用了问题here中的示例来查看它是否可以远程工作。

代码:

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {

guard !(anchor is ARPlaneAnchor) else { return }

let testNode = bezierNode.clone()

DispatchQueue.main.async {
    node.addChildNode(testNode)
}

}


func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {

// take the current frame/views features points and create an array out of them

guard let currentFrame = self.sceneView.session.currentFrame,
    let featurePointsArray = currentFrame.rawFeaturePoints?.points else { return }

// Create STROKE BezierPath

let strokeBezierPath = UIBezierPath()
strokeBezierPath.lineWidth = 0.1

 // Start the BezierPath at the first feature points on the screen

strokeBezierPath.move(to: CGPoint(x: CGFloat(featurePointsArray.first!.x), y: CGFloat(featurePointsArray.first!.y)))

// iterate through all feature pints and add then to the path

featurePointsArray.forEach { (pointLocation) in
    strokeBezierPath.addLine(to: CGPoint(x: CGFloat(pointLocation.x), y: CGFloat(pointLocation.y)))
}

// Close the Stroke BezierPath

strokeBezierPath.close()

// Do fancy work, not sure what this does

let cgPath = strokeBezierPath.cgPath.copy(
    strokingWithWidth: strokeBezierPath.lineWidth,
    lineCap: strokeBezierPath.lineCapStyle,
    lineJoin: strokeBezierPath.lineJoinStyle,
    miterLimit: strokeBezierPath.miterLimit)

// Create the actually bezierpath that were going to use to create the nodes geometry

let bezierPath = UIBezierPath(cgPath: cgPath)
let shape = SCNShape(path: bezierPath, extrusionDepth: 0.1)
shape.firstMaterial?.diffuse.contents = UIColor.blue
let node = SCNNode(geometry: shape)

// Add newly created node to the reference that gets passed to the didAdd delegate


bezierNode = node

// Then anchor gets added when we touch the screen with a tap gesture temporary that call the didAdd delegate

}

因此几乎可以容纳一个这样的房间并填充墙/点以创建网格:

enter image description here

结果看起来像这样,但是很明显,它的寿命和实际站在房间的角度:

enter image description here

如果那里有天才可以帮助重构我的代码,拥有比这更好的代码,或者知道如何真正实现这一目标。太神奇了!。谢谢

1 个答案:

答案 0 :(得分:1)

ARWorldMap可以存储特征点,但对您来说更有趣的是,它还将保存ARPlaneAnchors,它实际上是已经为您组成的网格。结果将不是完美的,而是更接近您要实现的目标,并且容易得多。我之前对此进行过研究,并在Twitter上播放了一个视频,以在公园中呈现可视的ARWorldMap,每次在该位置启动该应用程序时,该地图都会得到扩展(改进)。 ARKit可以从特征点检测平面,数学已经为您完成,因此可以使用它而不是尝试将特征点链接在一起。   https://twitter.com/londonrom/status/1010150386848628736