- Code: https://github.com/levantAJ/Measure
- UIViewController
final class ViewController: UIViewController { override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { resetValues() isMeasuring = true targetImageView.image = UIImage(named: "targetGreen") } override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { isMeasuring = false targetImageView.image = UIImage(named: "targetWhite") if let line = currentLine { lines.append(line) currentLine = nil resetButton.isHidden = false resetImageView.isHidden = false } } }
- compute distance
extension ViewController: ARSCNViewDelegate { func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) { DispatchQueue.main.async { [weak self] in self?.detectObjects() } } } extension ViewController { fileprivate func detectObjects() { guard let worldPosition = sceneView.realWorldVector(screenPosition: view.center) else { return } targetImageView.isHidden = false meterImageView.isHidden = false if lines.isEmpty { messageLabel.text = "Hold screen & move your phone…" } loadingView.stopAnimating() if isMeasuring { if startValue == vectorZero { startValue = worldPosition currentLine = Line(sceneView: sceneView, startVector: startValue, unit: unit) } endValue = worldPosition currentLine?.update(to: endValue) messageLabel.text = currentLine?.distance(to: endValue) ?? "Calculating…" } } } extension ARSCNView { func realWorldVector(screenPosition: CGPoint) -> SCNVector3? { let results = self.hitTest(screenPosition, types: [.featurePoint]) guard let result = results.first else { return nil } return SCNVector3.positionFromTransform(result.worldTransform) } } final class Line { func distance(to vector: SCNVector3) -> String { return String(format: "%.2f%@", startVector.distance(from: vector) * unit.fator, unit.unit) } }