diff --git a/.DS_Store b/.DS_Store index 3c28e61..8c7455d 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/RulAR.xcodeproj/project.pbxproj b/RulAR.xcodeproj/project.pbxproj index 2569b49..76c3e76 100644 --- a/RulAR.xcodeproj/project.pbxproj +++ b/RulAR.xcodeproj/project.pbxproj @@ -463,13 +463,13 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = 76S5M4U4NF; + DEVELOPMENT_TEAM = 5A6FMYBMJ4; INFOPLIST_FILE = RulAR/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = mcang.RulAR; + PRODUCT_BUNDLE_IDENTIFIER = justin.RulAR; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -481,13 +481,13 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = 76S5M4U4NF; + DEVELOPMENT_TEAM = 5A6FMYBMJ4; INFOPLIST_FILE = RulAR/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = mcang.RulAR; + PRODUCT_BUNDLE_IDENTIFIER = justin.RulAR; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/RulAR.xcodeproj/project.xcworkspace/xcuserdata/justinamwijaya.xcuserdatad/UserInterfaceState.xcuserstate b/RulAR.xcodeproj/project.xcworkspace/xcuserdata/justinamwijaya.xcuserdatad/UserInterfaceState.xcuserstate index 56265cd..ec2e101 100644 Binary files a/RulAR.xcodeproj/project.xcworkspace/xcuserdata/justinamwijaya.xcuserdatad/UserInterfaceState.xcuserstate and b/RulAR.xcodeproj/project.xcworkspace/xcuserdata/justinamwijaya.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/RulAR.xcodeproj/project.xcworkspace/xcuserdata/marvincangcianno.xcuserdatad/UserInterfaceState.xcuserstate b/RulAR.xcodeproj/project.xcworkspace/xcuserdata/marvincangcianno.xcuserdatad/UserInterfaceState.xcuserstate index d01242d..6cd859d 100644 Binary files a/RulAR.xcodeproj/project.xcworkspace/xcuserdata/marvincangcianno.xcuserdatad/UserInterfaceState.xcuserstate and b/RulAR.xcodeproj/project.xcworkspace/xcuserdata/marvincangcianno.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/RulAR/Base.lproj/Main.storyboard b/RulAR/Base.lproj/Main.storyboard index cfca3f4..f9d010c 100644 --- a/RulAR/Base.lproj/Main.storyboard +++ b/RulAR/Base.lproj/Main.storyboard @@ -1,5 +1,5 @@ - + @@ -93,7 +93,7 @@ - + diff --git a/RulAR/InputController.swift b/RulAR/InputController.swift index 33802d8..624139b 100644 --- a/RulAR/InputController.swift +++ b/RulAR/InputController.swift @@ -11,6 +11,38 @@ import UIKit class InputController : UIViewController{ + override func viewDidLoad() { +// let imageView = UIImageView(image: UIImage(named: "grid.png")) +// imageView.frame = view.bounds +// imageView.contentMode = UIViewContentMode.scaleAspectFill +// view.addSubview(imageView) +// +// let shape = CAShapeLayer() +// view.layer.addSublayer(shape) +// shape.opacity = 0.5 +// shape.lineWidth = 2 +// shape.lineJoin = kCALineJoinMiter +// shape.strokeColor = UIColor(hue: 0.786, saturation: 0.79, brightness: 0.53, alpha: 1.0).cgColor +// shape.fillColor = UIColor(hue: 0.786, saturation: 0.15, brightness: 0.89, alpha: 1.0).cgColor +// +// let path = UIBezierPath() +// path.move(to: CGPoint(x: 120, y: 20)) +// path.addLine(to: CGPoint(x: 230, y: 90)) +// path.addLine(to: CGPoint(x: 240, y: 250)) +// path.addLine(to: CGPoint(x: 40, y: 280)) +// path.addLine(to: CGPoint(x: 100, y: 150)) +// path.close() +// shape.path = path.cgPath +// +// +// var myTextLayer = CATextLayer() +// myTextLayer.string = "My text" +// myTextLayer.foregroundColor = UIColor.black.cgColor +// myTextLayer.frame = imageView.bounds +// myTextLayer.position = CGPoint(x:200,y: 400) +// print(myTextLayer.frame) +// imageView.layer.addSublayer(myTextLayer) + } var textValue : String! diff --git a/RulAR/ViewController.swift b/RulAR/ViewController.swift index 8d86304..e71cc27 100644 --- a/RulAR/ViewController.swift +++ b/RulAR/ViewController.swift @@ -9,18 +9,40 @@ import UIKit import ARKit +extension CGPoint : Codable { + enum CodingKeys: String, CodingKey { + case x + case y + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(x,forKey:.x) + try container.encode(y,forKey:.y) + } + + public init(from decoder:Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + x = try values.decode(CGFloat.self, forKey: .x) + y = try values.decode(CGFloat.self, forKey: .y) + } +} + class MyARCamera: UIViewController, ARSCNViewDelegate { + var isVertical = true + @IBOutlet weak var PreviewImage: UIImageView! @IBOutlet weak var sceneView: ARSCNView! + // planes var dictPlanes = [ARPlaneAnchor: Plane]() // distance label -// @IBOutlet weak var lblMeasurementDetails : UILabel! var coordinates: [SCNVector3] = [] var areaValue: Float = 0 + var lengths: [Float] = [] override func viewDidLoad() { super.viewDidLoad() @@ -53,6 +75,7 @@ class MyARCamera: UIViewController, ARSCNViewDelegate { var endNode: SCNVector3? var beginningPoint: SCNVector3? var measuringMode: Bool = true + //MARK: - Action @IBOutlet weak var areaText: UILabel! @IBAction func resetMeasure(_ sender: UIButton) { @@ -63,9 +86,35 @@ class MyARCamera: UIViewController, ARSCNViewDelegate { sceneView.scene.rootNode.enumerateChildNodes { (node, stop) in node.removeFromParentNode() } measuringMode = true + coordinates = [] + lengths = [] + PreviewImage.layer.sublayers?.forEach { $0.removeFromSuperlayer() } } @IBAction func FinishedMeasuring(_ sender: UIButton) { measuringMode = false + self.lineToEnd?.removeFromParentNode() + self.line_node?.removeFromParentNode() + guard let start = self.startNode, + let endingNode = self.beginningPoint else { + return + } + + self.line_node = self.getDrawnLineFrom(pos1: endingNode, + toPos2: start.position) + self.sceneView.scene.rootNode.addChildNode(self.line_node!) + let firstPointToPrev = start.position + let toBeMadePoint = endingNode + + let position = SCNVector3Make(toBeMadePoint.x - firstPointToPrev.x, toBeMadePoint.y - firstPointToPrev.y, toBeMadePoint.z - firstPointToPrev.z) + + let result = sqrt(position.x*position.x + position.z*position.z) + + let centerPoint = SCNVector3((firstPointToPrev.x+toBeMadePoint.x)/2,(firstPointToPrev.y+toBeMadePoint.y)/2,(firstPointToPrev.z+toBeMadePoint.z)/2) + + self.display(distance: result, position: centerPoint) + self.lengths.append(result) + print("here!", self.lengths) + // self.drawPreview() } @IBAction func onAddButtonClick(_ sender: UIButton) { let startPoint = startNode @@ -86,34 +135,15 @@ class MyARCamera: UIViewController, ARSCNViewDelegate { return } - //trying to make preview - let minX = coordinates.min { a, b in a.x < b.x }?.x - let minY = coordinates.min { a, b in a.z < b.z }?.z - let maxX = (coordinates.max { a, b in a.x < b.x }?.x)! - minX! - let maxY = (coordinates.max { a, b in a.z < b.z }?.z)! - minY! - - PreviewImage.layer.sublayers?.forEach { $0.removeFromSuperlayer() } - - let shape = CAShapeLayer() - PreviewImage.layer.addSublayer(shape) - shape.opacity = 0.5 - shape.lineWidth = 2 - shape.lineJoin = kCALineJoinMiter - shape.strokeColor = UIColor(hue: 0.786, saturation: 0.79, brightness: 0.53, alpha: 1.0).cgColor - shape.fillColor = UIColor(hue: 0.786, saturation: 0.15, brightness: 0.89, alpha: 1.0).cgColor - - let path = UIBezierPath() - - path.move(to: CGPoint(x: (Int(((coordinates[0].x - minX!) * 138 / maxX).rounded())), y: Int(((coordinates[0].z - minY!) * 128 / maxY).rounded()))) - - for coordinate in coordinates { - print("x: \((Int(((coordinate.x - minX!) * 138 / maxX).rounded()))), y: \((Int(((coordinate.z - minY!) * 128 / maxY).rounded())))") - path.addLine(to: CGPoint(x: (Int(((coordinate.x - minX!) * 138 / maxX).rounded())), y: (Int(((coordinate.z - minY!) * 128 / maxY).rounded())))) - + if (isVertical) { + createPreviewVertical() + areaValue = calculateAreaVertical(coordinates) + } else { + createPreviewHorizontal() + areaValue = calculateAreaHorizontal(coordinates) } - path.close() - shape.path = path.cgPath - + + areaText.text = "Area: \(((areaValue*10000).rounded())/10000)m2" // line-node self.line_node = self.getDrawnLineFrom(pos1: currentPosition, @@ -126,15 +156,22 @@ class MyARCamera: UIViewController, ARSCNViewDelegate { let position = SCNVector3Make(toBeMadePoint.x - firstPointToPrev.x, toBeMadePoint.y - firstPointToPrev.y, toBeMadePoint.z - firstPointToPrev.z) - let result = sqrt(position.x*position.x + position.z*position.z) + let length = sqrt(powf(position.x, 2.0) + powf(position.z, 2.0)) + + let centerPoint = SCNVector3((firstPointToPrev.x + toBeMadePoint.x)/2,(firstPointToPrev.y + toBeMadePoint.y)/2,(firstPointToPrev.z + toBeMadePoint.z)/2) + + self.displayText(distance: length, position: centerPoint) - let centerPoint = SCNVector3((firstPointToPrev.x+toBeMadePoint.x)/2,(firstPointToPrev.y+toBeMadePoint.y)/2,(firstPointToPrev.z+toBeMadePoint.z)/2) - self.display(distance: result, position: centerPoint) + //trying to make preview + // self.drawPreview() - areaValue = calculateArea(coordinates) - areaText.text = "Area: \(((areaValue*10000).rounded())/10000)m2" + // line-node + self.line_node = self.getDrawnLineFrom(pos1: currentPosition, + toPos2: start.position) + + sceneView.scene.rootNode.addChildNode(self.line_node!) } else { beginningPoint = startNode?.position @@ -146,7 +183,67 @@ class MyARCamera: UIViewController, ARSCNViewDelegate { } } - func calculateArea(_ coordinates: [SCNVector3]) -> Float { + func createPreviewHorizontal() { + let minX = coordinates.min { a, b in a.x < b.x }?.x + let minY = coordinates.min { a, b in a.z < b.z }?.z + let maxX = (coordinates.max { a, b in a.x < b.x }?.x)! - minX! + let maxY = (coordinates.max { a, b in a.z < b.z }?.z)! - minY! + + PreviewImage.layer.sublayers?.forEach { $0.removeFromSuperlayer() } + + let shape = CAShapeLayer() + PreviewImage.layer.addSublayer(shape) + shape.opacity = 0.5 + shape.lineWidth = 2 + shape.lineJoin = kCALineJoinMiter + shape.strokeColor = UIColor(hue: 0.786, saturation: 0.79, brightness: 0.53, alpha: 1.0).cgColor + shape.fillColor = UIColor(hue: 0.786, saturation: 0.15, brightness: 0.89, alpha: 1.0).cgColor + + let path = UIBezierPath() + + path.move(to: CGPoint(x: (Int(((coordinates[0].x - minX!) * 138 / maxX).rounded())), y: Int(((coordinates[0].z - minY!) * 128 / maxY).rounded()))) + + for coordinate in coordinates { + print("x: \((Int(((coordinate.x - minX!) * 138 / maxX).rounded()))), y: \((Int(((coordinate.z - minY!) * 128 / maxY).rounded())))") + path.addLine(to: CGPoint(x: (Int(((coordinate.x - minX!) * 138 / maxX).rounded())), y: (Int(((coordinate.z - minY!) * 128 / maxY).rounded())))) + + } + + path.close() + shape.path = path.cgPath + } + + func createPreviewVertical() { + let minX = coordinates.min { a, b in a.x < b.x }?.x + let minY = coordinates.min { a, b in a.y < b.y }?.y + let maxX = (coordinates.max { a, b in a.x < b.x }?.x)! - minX! + let maxY = (coordinates.max { a, b in a.y < b.y }?.y)! - minY! + + PreviewImage.layer.sublayers?.forEach { $0.removeFromSuperlayer() } + + let shape = CAShapeLayer() + PreviewImage.layer.addSublayer(shape) + shape.opacity = 0.5 + shape.lineWidth = 2 + shape.lineJoin = kCALineJoinMiter + shape.strokeColor = UIColor(hue: 0.786, saturation: 0.79, brightness: 0.53, alpha: 1.0).cgColor + shape.fillColor = UIColor(hue: 0.786, saturation: 0.15, brightness: 0.89, alpha: 1.0).cgColor + + let path = UIBezierPath() + + path.move(to: CGPoint(x: Int(((coordinates[0].x - minX!) * 138 / maxX).rounded()), y: 128 - Int(((coordinates[0].y - minY!) * 128 / maxY).rounded()))) + + for coordinate in coordinates { + print("x: \((Int(((coordinate.x - minX!) * 138 / maxX).rounded()))), y: \((Int(((coordinate.y - minY!) * 128 / maxY).rounded())))") + path.addLine(to: CGPoint(x: Int(((coordinate.x - minX!) * 138 / maxX).rounded()), y: 128 - Int(((coordinate.y - minY!) * 128 / maxY).rounded()))) + + } + + path.close() + shape.path = path.cgPath + } + + func calculateAreaHorizontal(_ coordinates: [SCNVector3]) -> Float { var area: Float = 0 var coordinateTwo: SCNVector3 = coordinates.last! @@ -159,6 +256,19 @@ class MyARCamera: UIViewController, ARSCNViewDelegate { return abs(area * 100 / 2) } + func calculateAreaVertical(_ coordinates: [SCNVector3]) -> Float { + var area: Float = 0 + var coordinateTwo: SCNVector3 = coordinates.last! + + for coordinate in coordinates { + area += (coordinate.x * coordinateTwo.y) + area -= (coordinate.y * coordinateTwo.x) + coordinateTwo = coordinate + } + + return abs(area * 100 / 2) + } + func doHitTestOnExistingPlanes() -> SCNVector3? { // hit-test of view's center with existing-planes let results = sceneView.hitTest(view.center, @@ -232,7 +342,12 @@ class MyARCamera: UIViewController, ARSCNViewDelegate { let configuration = ARWorldTrackingConfiguration() // set to detect horizontal planes - configuration.planeDetection = [.vertical, .horizontal] + + if (isVertical) { + configuration.planeDetection = .vertical + } else { + configuration.planeDetection = .horizontal + } // run the configuration self.sceneView.session.run(configuration) @@ -273,32 +388,10 @@ class MyARCamera: UIViewController, ARSCNViewDelegate { self.sceneView.scene.rootNode.addChildNode(self.lineToEnd!) } - } else { - self.lineToEnd?.removeFromParentNode() - self.line_node?.removeFromParentNode() - guard let start = self.startNode, - let endingNode = self.beginningPoint else { - return - } - - self.line_node = self.getDrawnLineFrom(pos1: endingNode, - toPos2: start.position) - self.sceneView.scene.rootNode.addChildNode(self.line_node!) - let firstPointToPrev = start.position - let toBeMadePoint = endingNode - - let position = SCNVector3Make(toBeMadePoint.x - firstPointToPrev.x, toBeMadePoint.y - firstPointToPrev.y, toBeMadePoint.z - firstPointToPrev.z) - - let result = sqrt(position.x*position.x + position.z*position.z) - - let centerPoint = SCNVector3((firstPointToPrev.x+toBeMadePoint.x)/2,(firstPointToPrev.y+toBeMadePoint.y)/2,(firstPointToPrev.z+toBeMadePoint.z)/2) - - self.display(distance: result, position: centerPoint) - } } - private func display(distance: Float,position :SCNVector3) { + private func displayText(distance: Float,position :SCNVector3) { let roundedDist = ((distance*100).rounded())/100 @@ -306,9 +399,17 @@ class MyARCamera: UIViewController, ARSCNViewDelegate { textGeo.firstMaterial?.diffuse.contents = UIColor.black let textNode = SCNNode(geometry: textGeo) + textNode.position = position - textNode.rotation = SCNVector4(1,0,0,Double.pi/(-2)) + + if (isVertical) { + textNode.rotation = SCNVector4(0,0,0,Double.pi) + } else { + textNode.rotation = SCNVector4(1,0,0,-Double.pi/2) + } + textNode.scale = SCNVector3(0.002,0.002,0.002) + for material in (textNode.geometry?.materials)! { material.lightingModel = .constant material.diffuse.contents = UIColor.white @@ -318,6 +419,91 @@ class MyARCamera: UIViewController, ARSCNViewDelegate { self.sceneView.scene.rootNode.addChildNode(textNode) } + //creating preview + func drawPreview() { + let minX = coordinates.min { a, b in a.x < b.x }?.x + let minY = coordinates.min { a, b in a.z < b.z }?.z + let maxX = (coordinates.max { a, b in a.x < b.x }?.x)! - minX! + let maxY = (coordinates.max { a, b in a.z < b.z }?.z)! - minY! + + PreviewImage.layer.sublayers?.forEach { $0.removeFromSuperlayer() } + + let shape = CAShapeLayer() + PreviewImage.layer.addSublayer(shape) + shape.opacity = 0.5 + shape.lineWidth = 2 + shape.lineJoin = kCALineJoinMiter + shape.strokeColor = UIColor(hue: 0.786, saturation: 0.79, brightness: 0.53, alpha: 1.0).cgColor + shape.fillColor = UIColor(hue: 0.786, saturation: 0.15, brightness: 0.89, alpha: 1.0).cgColor + + let path = UIBezierPath() + + path.move(to: CGPoint(x: (Int(((coordinates[0].x - minX!) * 138 / maxX).rounded())), y: Int(((coordinates[0].z - minY!) * 128 / maxY).rounded()))) + + var centerCoor: CGPoint + var centerXText: Float + var centerYText: Float + + centerXText = (((coordinates[0].x - minX!) + (coordinates[1].x - minX!))) * 128 + centerYText = (((coordinates[0].z - minY!) + (coordinates[1].z - minY!))) * 138 + + centerCoor = CGPoint(x: Int((centerXText / maxX)+50)/2, y: Int((centerYText / maxY)+5)/2) + + + let myTextLayer = CATextLayer() + myTextLayer.string = "\((lengths[0]*100).rounded()/100)m" + myTextLayer.foregroundColor = UIColor.cyan.cgColor + myTextLayer.frame = CGRect(x:0.0,y:0.0,width:100,height:10) + myTextLayer.position = centerCoor + print(myTextLayer.frame) + myTextLayer.fontSize = 10.0 + print(myTextLayer.position) + PreviewImage.layer.addSublayer(myTextLayer) + + for (index, coordinate) in coordinates.enumerated() { + print("x: \((Int(((coordinate.x - minX!) * 138 / maxX).rounded()))), y: \((Int(((coordinate.z - minY!) * 128 / maxY).rounded())))") + path.addLine(to: CGPoint(x: (Int(((coordinate.x - minX!) * 138 / maxX).rounded())), y: (Int(((coordinate.z - minY!) * 128 / maxY).rounded())))) + + if coordinates.count > 2 && index > 1 { + + centerXText = (((coordinate.x - minX!) + (coordinates[index-1].x - minX!))) * 138 + centerYText = (((coordinate.z - minY!) + (coordinates[index-1].z - minY!))) * 128 + + centerCoor = CGPoint(x: Int((centerXText / maxX)+50)/2, y: Int((centerYText / maxY)+5)/2) + + print("center", centerCoor) + + let myTextLayer = CATextLayer() + myTextLayer.string = "\((lengths[index-1]*100).rounded()/100)m" + myTextLayer.foregroundColor = UIColor.cyan.cgColor + myTextLayer.frame = CGRect(x:0.0,y:0.0,width:100,height:10) + myTextLayer.position = centerCoor + myTextLayer.fontSize = 10.0 + PreviewImage.layer.addSublayer(myTextLayer) + } + + if index == coordinates.count-1 && measuringMode == false { + centerXText = (((coordinates[0].x - minX!) + (coordinates[coordinates.count-1].x - minX!))) * 138 + centerYText = (((coordinates[0].z - minY!) + (coordinates[coordinates.count-1].z - minY!))) * 128 + + centerCoor = CGPoint(x: Int((centerXText / maxX)+50)/2, y: Int((centerYText / maxY)+5)/2) + print("center",centerCoor) + let myTextLayer = CATextLayer() + myTextLayer.string = "\((lengths[index]*100).rounded()/100)m" + myTextLayer.foregroundColor = UIColor.cyan.cgColor + myTextLayer.frame = CGRect(x:0.0,y:0.0,width:100,height:10) + myTextLayer.position = centerCoor + myTextLayer.fontSize = 10.0 + PreviewImage.layer.addSublayer(myTextLayer) + } + + + } + path.close() + shape.path = path.cgPath + + } + // draw line-node between two vectors func getDrawnLineFrom(pos1: SCNVector3, toPos2: SCNVector3) -> SCNNode { @@ -331,7 +517,6 @@ class MyARCamera: UIViewController, ARSCNViewDelegate { } let lineInBetween1 = SCNNode(geometry: line) - return lineInBetween1 }