(ARKit 2 Room Scanner) Как использовать UIBezierPath & featurePoints для создания узла с геометрией вашего окружения с помощью ARKit 2 и ARWorldMap - PullRequest
0 голосов
/ 30 декабря 2018

Я работаю с ARKit 2 и ARWorldMapData Я создал AR-мир, который распознает ваше окружение с помощью картографических данных и т. Д. ссылка здесь .Теперь я пытаюсь выяснить , как взять все характерные точки и затем соединиться, чтобы создать сетку моего окружения / ARWorldMap (что никогда не было предпринято ранее с ARKit 2, я думаю) .Хотя я уверен, что вы можете сделать это, соединив характерные точки с UIBezierPath.Так что вы можете затем использовать форму, которую путь создает в качестве геометрии ваших узлов.

После тестирования следующий код ничего не выводит на экран, или, по крайней мере, я его не вижу.Так что сейчас это проблема.Хотя я уверен, что с этим могут быть и другие проблемы.

Я просто использовал пример из этого вопроса здесь , чтобы посмотреть, может ли он работать удаленно.

Код:

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 голосов
/ 30 декабря 2018

ARWorldMap может хранить характерные точки, но что более интересно для вас, он также сохраняет ARPlaneAnchors, которые по сути являются сетками, уже созданными для вас.результат не будет идеальным, но ближе к тому, что вы пытаетесь достичь, и намного проще.Я работал над этим раньше и показал видео в твиттере, чтобы представить визуальную ARWorldMap в парке, которая расширяется (улучшается) каждый раз, когда вы запускаете приложение в этом месте.ARKit может обнаруживать плоскости из характерных точек, математика для вас уже сделана, поэтому используйте ее вместо того, чтобы пытаться связать характерные точки вместе.https://twitter.com/londonrom/status/1010150386848628736

...